# Sag Module - Case Management ## Oversigt Sag-modulet implementerer en universel sag-håndtering system hvor tickets, opgaver og ordrer er blot sager med forskellige tags og relationer. **Kerneidé:** Der er kun én ting: en Sag. Alt andet er metadata, tags og relationer. ## Database Schema ### sag_sager (Hovedtabel) - `id` - Primary key - `titel` - Case title - `beskrivelse` - Detailed description - `type` - Case type (ticket, opgave, ordre, etc.) - `status` - Status (åben, i_gang, afsluttet, on_hold) - `customer_id` - Foreign key to customers table - `ansvarlig_bruger_id` - Assigned user - `deadline` - Due date - `created_at` - Creation timestamp - `updated_at` - Last update (auto-updated via trigger) - `deleted_at` - Soft-delete timestamp (NULL = active) ### sag_relationer (Relations) - `id` - Primary key - `kilde_sag_id` - Source case - `målsag_id` - Target case - `relationstype` - Relation type (forælder, barn, afledt_af, blokkerer, udfører_for) - `created_at` - Creation timestamp - `deleted_at` - Soft-delete timestamp ### sag_tags (Tags) - `id` - Primary key - `sag_id` - Case reference - `tag_navn` - Tag name (support, urgent, vip, ompakning, etc.) - `created_at` - Creation timestamp - `deleted_at` - Soft-delete timestamp ## API Endpoints ### Cases CRUD **List cases** ``` GET /api/v1/sag?status=åben&tag=support&customer_id=1 ``` **Create case** ``` POST /api/v1/sag Content-Type: application/json { "titel": "Skærm mangler", "beskrivelse": "Kunde har brug for ny skærm", "type": "ticket", "customer_id": 1, "status": "åben" } ``` **Get case** ``` GET /api/v1/sag/1 ``` **Update case** ``` PATCH /api/v1/sag/1 Content-Type: application/json { "status": "i_gang", "ansvarlig_bruger_id": 5 } ``` **Delete case (soft)** ``` DELETE /api/v1/sag/1 ``` ### Relations **Get relations** ``` GET /api/v1/sag/1/relationer ``` **Add relation** ``` POST /api/v1/sag/1/relationer Content-Type: application/json { "målsag_id": 2, "relationstype": "afledt_af" } ``` **Delete relation** ``` DELETE /api/v1/sag/1/relationer/5 ``` ### Tags **Get tags** ``` GET /api/v1/sag/1/tags ``` **Add tag** ``` POST /api/v1/sag/1/tags Content-Type: application/json { "tag_navn": "urgent" } ``` **Delete tag** ``` DELETE /api/v1/sag/1/tags/3 ``` ## Frontend Routes - `GET /sag` - List all cases with filters - `GET /sag/{id}` - View case details - `GET /sag/new` - Create new case (future) - `GET /sag/{id}/edit` - Edit case (future) ## Features ✅ Soft-delete with data preservation ✅ Nordic Top design with dark mode support ✅ Responsive mobile-friendly UI ✅ Case relations (parent/child) ✅ Dynamic tagging system ✅ Full-text search ✅ Status filtering ✅ Customer tracking ## Example Workflows ### Support Ticket 1. Customer calls → Create Sag with type="ticket", tag="support" 2. Urgency high → Add tag="urgent" 3. Create order for new hardware → Create related Sag with type="ordre", relation="afledt_af" 4. Pack and ship → Create related Sag with type="opgave", tag="ompakning" ### Future Integrations - Activity logging (who changed what when) - e-conomic integration (auto-create orders) - SLA tracking (response/resolution times) - Workflow automation (auto-tags based on conditions) - Dependency management (can't start case B until case A done) ## Soft-Delete Safety All DELETE operations use soft-delete: - Data is preserved in database - `deleted_at` is set to current timestamp - All queries filter `WHERE deleted_at IS NULL` - Data can be recovered if module is disabled - Audit trail is maintained ## Development Notes - All queries use `execute_query()` from `app.core.database` - Parameterized queries with `%s` placeholders (SQL injection prevention) - `RealDictCursor` for dict-like row access - Triggers maintain `updated_at` automatically - Relations are first-class citizens (not just links)