# Sag Module Documentation ## Overview The Sag Module is a universal case management system where tickets, tasks, and orders are all represented as cases with different tags and relations. The core idea is that there is only one entity: a case. All other attributes are metadata, tags, and relations. ## Database Schema ### `sag_sager` (Main Table for Cases) - **Columns**: - `id`: Primary key - `titel`: `VARCHAR` - Title of the case - `beskrivelse`: `TEXT` - Detailed description - `template_key`: `VARCHAR, NULL` - Used only during creation, no business logic - `status`: `VARCHAR` - Allowed values: `'åben'`, `'lukket'` - `customer_id`: Foreign key, nullable - `ansvarlig_bruger_id`: Foreign key, nullable - `created_by_user_id`: Foreign key, not nullable - `deadline`: `TIMESTAMP`, nullable - `created_at`: `TIMESTAMP` - `updated_at`: `TIMESTAMP` - `deleted_at`: `TIMESTAMP` (soft-delete) ### `sag_relationer` (Relations Between Cases) - **Columns**: - `id`: Primary key - `kilde_sag_id`: Foreign key (source case) - `målsag_id`: Foreign key (target case) - `relationstype`: `VARCHAR` - Examples: `'derived'`, `'blocks'`, `'executes'` - `created_at`: `TIMESTAMP` - `deleted_at`: `TIMESTAMP` ### `sag_tags` (Process and Categorization) - **Columns**: - `id`: Primary key - `sag_id`: Foreign key (case reference) - `tag_navn`: `VARCHAR` - Name of the tag - `state`: `VARCHAR DEFAULT 'open'` - `'open'` (not completed), `'closed'` (completed) - `closed_at`: `TIMESTAMP`, nullable - `created_at`: `TIMESTAMP` - `deleted_at`: `TIMESTAMP` ## API Endpoints ### Cases - `GET /api/v1/cases` - List all cases with optional filters. - `POST /api/v1/cases` - Create a new case. - `GET /api/v1/cases/{id}` - Retrieve a specific case by ID. - `PATCH /api/v1/cases/{id}` - Update a specific case. - `DELETE /api/v1/cases/{id}` - Soft-delete a specific case. ### Relations - `GET /api/v1/cases/{id}/relations` - List all relations for a specific case. - `POST /api/v1/cases/{id}/relations` - Create a new relation for a case. - `DELETE /api/v1/cases/{id}/relations/{relation_id}` - Soft-delete a specific relation. ### Tags - `GET /api/v1/cases/{id}/tags` - List all tags for a specific case. - `POST /api/v1/cases/{id}/tags` - Add a tag to a case. - `DELETE /api/v1/cases/{id}/tags/{tag_id}` - Soft-delete a specific tag. ## Frontend Views ### Case List - **Route**: `/cases` - **Description**: Displays a list of all cases with filters for status and tags. - **Template**: `index.html` ### Case Details - **Route**: `/cases/{case_id}` - **Description**: Displays detailed information about a specific case, including its tags and relations. - **Template**: `detail.html` ## Features 1. **Soft-Delete**: Cases, relations, and tags are not permanently deleted. Instead, they are marked with a `deleted_at` timestamp. 2. **Tag-Based Workflow**: Tags represent tasks or categories and can be marked as `open` or `closed`. 3. **Relations**: Cases can be related to each other with directional and transitive relations. ## Development Notes - All database queries use `execute_query()` from `app.core.database`. - Queries are parameterized with `%s` placeholders to prevent SQL injection. - `RealDictCursor` is used for dict-like row access. - Triggers automatically update the `updated_at` column. - Relations are first-class citizens and are not just links. ## Example Workflows ### Example 1: Support Ticket 1. A customer calls to request a new monitor. 2. A case is created with the tag `support` and marked as `urgent`. 3. The case is assigned to a support agent. ### Example 2: Order Processing 1. A case is created for purchasing a monitor with the tag `indkøb`. 2. The case is related to the support ticket as `derived`. 3. The purchasing manager is assigned to the case. ### Example 3: Shipping 1. A case is created for packaging and shipping the monitor with the tag `ompakning`. 2. The case is related to the order case as `executes`. 3. The shipping department is assigned to the case. ## Module Deactivation - When the module is deactivated, all data is preserved. - Soft-deleted data remains in the database for potential rollback. - Ensure no active cases are left in an inconsistent state before deactivation.