# SAG MODULE IMPLEMENTATION PLAN
## Professional Sub-Agent Task Breakdown

**Document Version:** 2.0  
**Created:** 2026-01-30  
**Module Location:** `/app/modules/sag/`  
**API Path:** `/api/v1/cases`  
**Database Prefix:** `sag_`

---

## EXECUTIVE SUMMARY

The Sag (Case) Module is the **process backbone** of BMC Hub. It implements a universal entity model where tickets, tasks, and (eventually) orders are all represented as Cases differentiated by:
- **Relations** (directional, transitive connections between cases)
- **Tags** (workflow state and categorization)
- **Attached modules** (billing, hardware, etc.)

This plan provides a phased, task-based approach to complete the implementation with architectural constraints preserved.

---

## 1️⃣ CURRENT STATE ASSESSMENT

### ✅ What's Already Implemented

#### Database Schema (COMPLETE)
- ✅ `sag_sager` table (cases) - `/migrations/001_init.sql`
  - Binary status: `åben` / `lukket` (constraint enforced)
  - `template_key` as nullable field (creation-time only)
  - `deleted_at` for soft-deletes
  - Proper indexes on customer_id, status, ansvarlig_bruger_id
  - Auto-update trigger for `updated_at`

- ✅ `sag_relationer` table (relations)
  - Directional: `kilde_sag_id` → `målsag_id`
  - `relationstype` for categorization
  - Soft-delete support
  - Constraint preventing self-relations

- ✅ `sag_tags` table (tags)
  - `tag_navn` for categorization
  - `state` field: `open` / `closed` (constraint enforced)
  - `closed_at` timestamp
  - Soft-delete support

- ✅ `sag_kontakter` table (case-contact links) - `/migrations/002_sag_contacts_relations.sql`
  - Many-to-many with roles

- ✅ `sag_kunder` table (case-customer links)
  - Many-to-many with roles

#### Backend API (MOSTLY COMPLETE)
✅ **Cases CRUD** - `router.py` lines 1-671
  - `GET /api/v1/cases` - List with filters (status, tag, customer_id, ansvarlig)
  - `POST /api/v1/cases` - Create case
  - `GET /api/v1/cases/{id}` - Get case details
  - `PATCH /api/v1/cases/{id}` - Update case
  - `DELETE /api/v1/cases/{id}` - Soft-delete

✅ **Relations CRUD**
  - `GET /api/v1/cases/{id}/relations` - List relations with titles
  - `POST /api/v1/cases/{id}/relations` - Create relation
  - `DELETE /api/v1/cases/{id}/relations/{relation_id}` - Soft-delete

✅ **Tags CRUD**
  - `GET /api/v1/cases/{id}/tags` - List tags
  - `POST /api/v1/cases/{id}/tags` - Add tag (with state support)
  - `DELETE /api/v1/cases/{id}/tags/{tag_id}` - Soft-delete

✅ **Contact/Customer Links**
  - `POST /api/v1/cases/{id}/contacts` - Link contact
  - `GET /api/v1/cases/{id}/contacts` - List contacts
  - `DELETE /api/v1/cases/{id}/contacts/{contact_id}` - Remove contact
  - `POST /api/v1/cases/{id}/customers` - Link customer
  - `GET /api/v1/cases/{id}/customers` - List customers
  - `DELETE /api/v1/cases/{id}/customers/{customer_id}` - Remove customer

✅ **Search**
  - `GET /api/v1/search/cases` - Full-text search
  - `GET /api/v1/search/customers` - Customer search
  - `GET /api/v1/search/contacts` - Contact search

#### Frontend Views (MOSTLY COMPLETE)
✅ **List View** - `frontend/views.py`
  - `/cases` and `/sag` routes (dual paths)
  - Filter by status, tag, customer_id
  - Fetches statuses and tags for filters

✅ **Detail View**
  - `/cases/{id}` and `/sag/{id}` routes
  - Shows case, tags, relations, customer
  - Fetches contacts and customers (partially implemented)

✅ **Create Form**
  - `/cases/new` and `/sag/new` routes
  - Template exists (`create.html`)

❌ **Edit Form** - Template exists (`edit.html`) but no backend route

#### Templates (COMPLETE)
✅ All four templates exist:
  - `index.html` - Case list with Nordic Top design, filters, dark mode
  - `detail.html` - Case details with relations, tags, info sections
  - `create.html` - Create form with customer search, validation
  - `edit.html` - Edit form (needs backend route)

### 🔴 Architectural Violations Found

#### VIOLATION 1: Duplicate API Paths
**Issue:** Router has both `/sag/*` and `/cases/*` endpoints doing identical things.
- Lines 14-157: `/sag` prefix endpoints
- Lines 327-671: `/cases` prefix endpoints (duplicates)

**Fix Required:** Remove `/sag/*` endpoints, keep only `/cases/*` (architectural standard).

#### VIOLATION 2: Missing Tag State Management
**Issue:** Tag closing endpoint missing.
- `PATCH /api/v1/cases/{id}/tags/{tag_id}` should allow closing tags (set `state='closed'`, `closed_at=NOW()`)
- Currently only delete (soft) exists

**Fix Required:** Add tag state update endpoint.

#### VIOLATION 3: Missing Edit Route
**Issue:** `edit.html` template exists but no backend route to serve it.

**Fix Required:** Add `GET /cases/{id}/edit` view route.

### ⚠️ What Needs Enhancement

1. **Tag State Workflow** - Endpoint to close tags (not delete)
2. **Edit View Route** - Backend route for edit form
3. **Relation Type Validation** - Should validate allowed relation types
4. **Bulk Operations** - Close multiple tags, archive cases
5. **Activity Log** - Track who changed what (future phase)
6. **Order Integration** - Link cases to orders (future phase)

---

## 2️⃣ PHASE OVERVIEW

### Phase 1: Database Schema Validation (30 min)
- Verify all tables match architectural constraints
- Add any missing indexes
- Validate soft-delete coverage

### Phase 2: Backend API Enhancement (2-3 hours)
- Remove duplicate `/sag/*` endpoints
- Add tag state management endpoint
- Add edit view route
- Improve error handling
- Add relation type validation

### Phase 3: Frontend Enhancement (2-3 hours)
- Wire up edit form
- Add tag closing UI
- Improve relation visualization
- Add bulk operations UI
- Enhance mobile responsiveness

### Phase 4: Order Integration Planning (1 hour)
- Define order-case relation types
- Document order creation workflow
- Plan order table schema
- Define API contract

### Phase 5: Documentation (1 hour)
- Update module README
- Create API documentation
- Document relation types
- Create workflow examples

### Phase 6: QA & Testing (1-2 hours)
- Unit tests for CRUD operations
- Integration tests for relations
- Frontend E2E tests
- Soft-delete verification
- Module disable/enable test

**Total Estimate:** 8-12 hours

---

## 3️⃣ SUB-AGENT TASK BREAKDOWN

---

### PHASE 1: DATABASE SCHEMA VALIDATION

#### DB-001: Schema Compliance Audit
**Assigned:** DB-Agent  
**Estimated Time:** 30 minutes  
**Dependencies:** None

**Description:**
Audit all `sag_*` tables against architectural constraints. Verify:
- Binary status constraint on `sag_sager`
- Tag state constraint on `sag_tags`
- Soft-delete columns present
- No missing indexes
- Trigger functions working

**Inputs:**
- `/migrations/001_init.sql`
- `/migrations/002_sag_contacts_relations.sql`
- Database connection

**Outputs:**
- Validation report (pass/fail for each constraint)
- SQL script for any missing indexes/constraints

**Done Criteria:**
- All constraints match architectural rules
- All soft-delete columns present
- All indexes exist and performant

---

### PHASE 2: BACKEND API ENHANCEMENT

#### BE-001: Remove Duplicate `/sag/*` Endpoints
**Assigned:** Backend-Agent  
**Estimated Time:** 45 minutes  
**Dependencies:** None

**Description:**
Remove duplicate endpoints with `/sag` prefix (lines 14-330). Keep only `/cases` prefix endpoints. Update any internal references.

**Inputs:**
- `/app/modules/sag/backend/router.py`

**Outputs:**
- Modified `router.py` with only `/cases` endpoints
- Updated imports if needed

**Done Criteria:**
- No `/sag` prefix endpoints remain
- All functionality preserved under `/cases`
- No broken internal references

---

#### BE-002: Add Tag State Management Endpoint
**Assigned:** Backend-Agent  
**Estimated Time:** 45 minutes  
**Dependencies:** BE-001

**Description:**
Add `PATCH /api/v1/cases/{id}/tags/{tag_id}` endpoint to close tags without deleting. Should:
- Accept `{"state": "closed"}` payload
- Set `closed_at = NOW()`
- NOT set `deleted_at` (tags are closed, not deleted)
- Return updated tag

**Inputs:**
- `/app/modules/sag/backend/router.py`
- `sag_tags` table schema

**Outputs:**
- New endpoint in `router.py`
- Proper error handling

**Done Criteria:**
- Endpoint closes tag (state='closed', closed_at set)
- Returns 404 if tag not found
- Doesn't soft-delete
- Logs action with emoji prefix

---

#### BE-003: Add Edit View Route
**Assigned:** Backend-Agent  
**Estimated Time:** 30 minutes  
**Dependencies:** BE-001

**Description:**
Add `GET /cases/{id}/edit` route in `frontend/views.py` to serve the edit form. Should fetch case and render `edit.html` template.

**Inputs:**
- `/app/modules/sag/frontend/views.py`
- `/app/modules/sag/templates/edit.html`

**Outputs:**
- New route in `views.py`
- Template receives case data

**Done Criteria:**
- Route returns edit form
- Form pre-populated with case data
- Returns 404 if case not found

---

#### BE-004: Add Relation Type Validation
**Assigned:** Backend-Agent  
**Estimated Time:** 45 minutes  
**Dependencies:** BE-001

**Description:**
Add validation for allowed relation types when creating relations. Define allowed types:
- `derived` (spawned from)
- `blocks` (prevents progress)
- `executes` (performs work for)
- `relates_to` (generic link)

Reject other types with 400 error.

**Inputs:**
- `/app/modules/sag/backend/router.py` (relation creation endpoint)

**Outputs:**
- Updated `POST /api/v1/cases/{id}/relations` with validation
- Error message listing allowed types

**Done Criteria:**
- Only allowed types accepted
- 400 error with clear message for invalid types
- Logged validation failures

---

#### BE-005: Improve Error Handling
**Assigned:** Backend-Agent  
**Estimated Time:** 45 minutes  
**Dependencies:** BE-001, BE-002, BE-003, BE-004

**Description:**
Standardize error responses across all endpoints:
- Use consistent HTTPException format
- Include helpful error messages
- Log all errors with context
- Return proper status codes

**Inputs:**
- All endpoint functions in `router.py` and `views.py`

**Outputs:**
- Consistent error handling pattern
- Improved logging

**Done Criteria:**
- All errors return proper status codes
- Error messages are user-friendly
- All errors logged with context
- No uncaught exceptions

---

### PHASE 3: FRONTEND ENHANCEMENT

#### FE-001: Wire Up Edit Form Backend Connection
**Assigned:** Frontend-Agent  
**Estimated Time:** 45 minutes  
**Dependencies:** BE-003

**Description:**
Complete the edit form JavaScript to:
- Load case data into form
- Submit to `PATCH /api/v1/cases/{id}`
- Handle success/error responses
- Redirect to detail view on success

**Inputs:**
- `/app/modules/sag/templates/edit.html`
- Backend edit route
- PATCH endpoint

**Outputs:**
- Functional edit form with submission
- Success/error feedback
- Redirect on success

**Done Criteria:**
- Form loads case data
- Submission calls PATCH endpoint
- Success redirects to `/cases/{id}`
- Errors displayed to user

---

#### FE-002: Add Tag Closing UI
**Assigned:** Frontend-Agent  
**Estimated Time:** 60 minutes  
**Dependencies:** BE-002

**Description:**
Add UI to close tags (not delete) in detail view:
- Add "Close Tag" button next to each open tag
- Call `PATCH /api/v1/cases/{id}/tags/{tag_id}` with `state='closed'`
- Update UI to show closed state (greyed out, strikethrough)
- Keep closed tags visible in UI

**Inputs:**
- `/app/modules/sag/templates/detail.html`
- Tag closing endpoint

**Outputs:**
- Close button on each open tag
- Visual distinction for closed tags
- AJAX call to close endpoint

**Done Criteria:**
- Closed tags remain visible
- Visual feedback on state change
- No page reload needed
- Error handling for failures

---

#### FE-003: Improve Relation Visualization
**Assigned:** Frontend-Agent  
**Estimated Time:** 90 minutes  
**Dependencies:** None

**Description:**
Enhance relation display in detail view:
- Group relations by type (derived, blocks, executes, relates_to)
- Show directionality clearly (this case → target vs. source → this case)
- Add visual indicators (arrows, colors)
- Make relation targets clickable links

**Inputs:**
- `/app/modules/sag/templates/detail.html`
- Relation data from backend

**Outputs:**
- Updated relation section with grouping
- Visual indicators for direction
- Clickable links to related cases

**Done Criteria:**
- Relations grouped by type
- Direction clear (outgoing vs incoming)
- All targets are clickable
- Mobile-responsive

---

#### FE-004: Add Bulk Operations UI
**Assigned:** Frontend-Agent  
**Estimated Time:** 90 minutes  
**Dependencies:** BE-002

**Description:**
Add bulk operations to list view:
- Checkboxes to select multiple cases
- "Close Selected" button (set status='lukket')
- "Archive Selected" button (soft-delete)
- Confirmation dialogs

**Inputs:**
- `/app/modules/sag/templates/index.html`
- Update/delete endpoints

**Outputs:**
- Selection UI in list view
- Bulk action buttons
- Confirmation dialogs

**Done Criteria:**
- Multiple cases selectable
- Bulk close works
- Bulk archive works (soft-delete)
- Confirmation required
- Success feedback shown

---

#### FE-005: Enhance Mobile Responsiveness
**Assigned:** Frontend-Agent  
**Estimated Time:** 60 minutes  
**Dependencies:** FE-001, FE-002, FE-003, FE-004

**Description:**
Ensure all views work on mobile:
- Stack filters vertically on small screens
- Make tables scrollable or card-based
- Touch-friendly buttons (min 44px)
- Collapsible sections for detail view

**Inputs:**
- All template files

**Outputs:**
- Updated CSS with media queries
- Mobile-optimized layouts

**Done Criteria:**
- All views usable on 375px width
- No horizontal scroll needed
- Touch targets large enough
- Text readable without zoom

---

### PHASE 4: ORDER INTEGRATION PLANNING

#### INT-001: Define Order-Case Relation Model
**Assigned:** Integration-Agent  
**Estimated Time:** 30 minutes  
**Dependencies:** None

**Description:**
Document how orders integrate with cases:
- Orders CAN be created independently
- Orders MUST be linkable to one or more cases
- When order created from case → create relation
- Define relation type for order links (e.g., `fulfills`, `invoices_for`)

**Inputs:**
- Architectural constraints document
- Current relation types

**Outputs:**
- Design document: `docs/ORDER_CASE_INTEGRATION.md`
- Relation type definitions
- Workflow diagrams

**Done Criteria:**
- Clear definition of order independence
- Relation type defined
- Creation workflow documented
- No violation of "orders are not cases" rule

---

#### INT-002: Plan Order Table Schema
**Assigned:** Integration-Agent  
**Estimated Time:** 45 minutes  
**Dependencies:** INT-001

**Description:**
Design order tables with case linking:
- `orders` table (id, title, description, status, etc.)
- `order_case_relations` table (order_id, case_id, relation_type)
- NO embedding of case logic in orders
- Soft-delete everywhere

**Inputs:**
- Order-case relation model (INT-001)
- Existing `sag_*` schema

**Outputs:**
- SQL migration draft: `migrations/XXX_orders.sql`
- Schema documentation

**Done Criteria:**
- Order table defined
- Many-to-many relation to cases
- No parent/child embedding
- Soft-delete columns present

---

#### INT-003: Define Order API Contract
**Assigned:** Integration-Agent  
**Estimated Time:** 45 minutes  
**Dependencies:** INT-002

**Description:**
Define order API endpoints:
- `GET /api/v1/orders` - List orders
- `POST /api/v1/orders` - Create order (optionally from case)
- `POST /api/v1/orders/{id}/cases` - Link to case
- `GET /api/v1/cases/{id}/orders` - Get orders for case

**Inputs:**
- Order schema (INT-002)
- Case API patterns

**Outputs:**
- API specification document
- Example requests/responses

**Done Criteria:**
- All CRUD operations defined
- Case linking endpoints defined
- Consistent with case API patterns
- Examples provided

---

### PHASE 5: DOCUMENTATION

#### DOC-001: Update Module README
**Assigned:** Docs-Agent  
**Estimated Time:** 30 minutes  
**Dependencies:** BE-001 through BE-005

**Description:**
Update `/app/modules/sag/README.md` with:
- Current implementation status
- All API endpoints with examples
- Relation types and meanings
- Tag workflow explanation
- Architectural constraints summary

**Inputs:**
- Current implementation
- Backend router
- Templates

**Outputs:**
- Updated `README.md`

**Done Criteria:**
- All endpoints documented
- Examples provided
- Architectural rules explained
- Easy to understand for new developers

---

#### DOC-002: Create API Documentation
**Assigned:** Docs-Agent  
**Estimated Time:** 45 minutes  
**Dependencies:** BE-001 through BE-005

**Description:**
Create OpenAPI-style documentation for all endpoints:
- Request/response schemas
- Status codes
- Error responses
- Example curl commands

**Inputs:**
- Backend router
- Pydantic models (if any)

**Outputs:**
- `docs/SAG_API_REFERENCE.md`

**Done Criteria:**
- All endpoints documented
- Schemas defined
- Examples provided
- Status codes listed

---

#### DOC-003: Document Relation Types
**Assigned:** Docs-Agent  
**Estimated Time:** 30 minutes  
**Dependencies:** BE-004

**Description:**
Create reference guide for relation types:
- `derived` - Target case spawned from source
- `blocks` - Source blocks target from progressing
- `executes` - Target performs work for source
- `relates_to` - Generic association

Include use cases and examples.

**Inputs:**
- Relation type validation (BE-004)
- Existing use patterns

**Outputs:**
- `docs/CASE_RELATION_TYPES.md`

**Done Criteria:**
- All types explained
- Use cases provided
- Examples given
- Directionality clear

---

#### DOC-004: Create Workflow Examples
**Assigned:** Docs-Agent  
**Estimated Time:** 45 minutes  
**Dependencies:** DOC-001, DOC-002, DOC-003

**Description:**
Document common workflows:
1. Customer calls → create support case → derive hardware order case → execute fulfillment case
2. Billing cycle → create invoice case → relate to completed support cases
3. Project → create project case → derive task cases → track via tags

**Inputs:**
- All documentation
- Current implementation

**Outputs:**
- `docs/SAG_WORKFLOWS.md`

**Done Criteria:**
- At least 3 workflows documented
- Step-by-step instructions
- API calls shown
- Relation chains visualized

---

### PHASE 6: QA & TESTING

#### QA-001: Backend CRUD Tests
**Assigned:** QA-Agent  
**Estimated Time:** 90 minutes  
**Dependencies:** BE-001 through BE-005

**Description:**
Write integration tests for all CRUD operations:
- Create case
- Read case
- Update case
- Delete case (soft)
- Verify deleted_at set correctly

**Inputs:**
- Backend router
- Test database

**Outputs:**
- Test file: `tests/test_sag_crud.py`
- At least 20 test cases

**Done Criteria:**
- All CRUD operations tested
- Soft-delete verified
- Error cases tested
- All tests pass

---

#### QA-002: Relation Tests
**Assigned:** QA-Agent  
**Estimated Time:** 60 minutes  
**Dependencies:** BE-001, BE-004

**Description:**
Test relation operations:
- Create relation between cases
- List relations (both directions)
- Validate relation type validation
- Delete relation (soft)
- Prevent self-relations

**Inputs:**
- Relation endpoints
- Test database

**Outputs:**
- Test file: `tests/test_sag_relations.py`
- At least 10 test cases

**Done Criteria:**
- Create/delete tested
- Type validation tested
- Self-relation prevention tested
- Directionality correct

---

#### QA-003: Tag Workflow Tests
**Assigned:** QA-Agent  
**Estimated Time:** 60 minutes  
**Dependencies:** BE-002

**Description:**
Test tag lifecycle:
- Add tag to case
- Close tag (state='closed', closed_at set)
- Verify closed tags not deleted
- Delete tag (soft)
- List tags (filter by state)

**Inputs:**
- Tag endpoints
- Test database

**Outputs:**
- Test file: `tests/test_sag_tags.py`
- At least 8 test cases

**Done Criteria:**
- Add/close/delete tested
- State transitions verified
- Soft-delete vs close distinction tested
- All tests pass

---

#### QA-004: Frontend E2E Tests
**Assigned:** QA-Agent  
**Estimated Time:** 90 minutes  
**Dependencies:** FE-001 through FE-005

**Description:**
Test frontend user flows:
- Navigate to case list
- Filter by status/tag
- Create new case
- View case details
- Edit case
- Add/close tag
- Add relation
- Delete case

**Inputs:**
- All frontend templates
- Browser automation tool (Playwright/Selenium)

**Outputs:**
- Test file: `tests/test_sag_frontend.py`
- At least 10 E2E scenarios

**Done Criteria:**
- All major flows tested
- Form submissions work
- Navigation works
- Error handling tested

---

#### QA-005: Module Disable/Enable Test
**Assigned:** QA-Agent  
**Estimated Time:** 30 minutes  
**Dependencies:** QA-001, QA-002, QA-003, QA-004

**Description:**
Test module deactivation:
1. Create test cases/relations/tags
2. Disable module (enabled=false in module.json)
3. Verify endpoints return 404
4. Verify database data intact
5. Re-enable module
6. Verify data still accessible

**Inputs:**
- Module loader
- Test database

**Outputs:**
- Test file: `tests/test_sag_module_lifecycle.py`

**Done Criteria:**
- Disable prevents access
- Data preserved
- Re-enable restores access
- No data loss

---

## 4️⃣ DEPENDENCY GRAPH

### Sequential Dependencies (Critical Path)

```
DB-001 (30m)
  ↓
BE-001 (45m)  ← MUST complete before any backend work
  ↓
  ├→ BE-002 (45m)
  ├→ BE-003 (30m)
  ├→ BE-004 (45m)
  └→ BE-005 (45m)  ← Touches all other BE tasks
       ↓
  ┌────┴────┐
  ↓         ↓
FE-001   QA-001 (90m)
(45m)       ↓
  ↓      QA-002 (60m)
FE-002     ↓
(60m)   QA-003 (60m)
  ↓         ↓
FE-003   QA-004 (90m)
(90m)       ↓
  ↓      QA-005 (30m)
FE-004
(90m)
  ↓
FE-005
(60m)
```

### Parallel Opportunities

**Wave 1 (after BE-001):**
- BE-002, BE-003, BE-004 can run in parallel
- Saves ~90 minutes

**Wave 2 (after BE-005):**
- FE-001, FE-003, QA-001, QA-002 can run in parallel
- DOC-001, DOC-002, DOC-003 can run in parallel
- Saves ~2 hours

**Wave 3 (after FE-004):**
- FE-005, QA-004, DOC-004 can run in parallel
- Saves ~1 hour

**Wave 4 (order integration):**
- INT-001, INT-002, INT-003 can run in parallel (independent of other work)

### Critical Path Time
If executed sequentially: **~12 hours**  
If parallelized optimally: **~6-7 hours**

### Where Orders Integrate

**Order Integration is PARALLEL to Case Enhancement:**
- INT-001, INT-002, INT-003 can start immediately
- Do NOT block case module completion
- Orders gain meaning when linked to cases via relations
- No architectural changes to cases needed

**Order-Case Interface:**
```
Cases Module (Complete)
    ↓
Orders Module (New)
    ↓
order_case_relations table
    ↓
Relation type: "fulfills" / "invoices_for"
```

---

## 5️⃣ VALIDATION CHECKLIST

### Phase 1: Database Schema
- [ ] Binary status constraint verified (`åben` / `lukket`)
- [ ] Tag state constraint verified (`open` / `closed`)
- [ ] All soft-delete columns present
- [ ] All indexes exist and performant
- [ ] Triggers working (updated_at auto-update)
- [ ] No foreign key errors
- [ ] Relation self-reference prevented

### Phase 2: Backend API
- [ ] No duplicate `/sag/*` endpoints exist
- [ ] Only `/cases` prefix used
- [ ] Tag closing endpoint works (PATCH tags/{id})
- [ ] Edit view route serves form
- [ ] Relation type validation enforces allowed types
- [ ] All endpoints return consistent error format
- [ ] All errors logged with context
- [ ] Soft-deletes set `deleted_at`, not physical delete

### Phase 3: Frontend
- [ ] Edit form loads case data
- [ ] Edit form submits to PATCH endpoint
- [ ] Tag closing UI doesn't delete tags
- [ ] Closed tags remain visible (greyed out)
- [ ] Relations grouped by type
- [ ] Directionality clear (in/out)
- [ ] Bulk operations work
- [ ] All views mobile-responsive (375px)

### Phase 4: Order Integration
- [ ] Order-case relation model documented
- [ ] Orders can be created independently
- [ ] Orders linkable to multiple cases
- [ ] No case logic embedded in orders
- [ ] Order table schema has soft-deletes
- [ ] API contract consistent with case API

### Phase 5: Documentation
- [ ] README updated with current state
- [ ] All endpoints documented
- [ ] Relation types explained
- [ ] Workflows documented
- [ ] Examples provided

### Phase 6: Testing
- [ ] All CRUD operations tested
- [ ] Relation creation/deletion tested
- [ ] Tag state transitions tested
- [ ] Frontend flows tested
- [ ] Module disable/enable tested
- [ ] Data preserved after disable
- [ ] All tests pass

---

## ARCHITECTURAL CONSTRAINT RE-VALIDATION

After each phase, validate these rules:

### Core Entity Rule
- ✅ Only one entity: Case
- ✅ Tickets/tasks are cases with different tags/relations
- ⚠️ Orders are transactional objects, NOT cases (separate table)

### Orders Exception
- ⚠️ Orders can be created independently (INT-002)
- ⚠️ Orders linkable to cases via relations (INT-002)
- ⚠️ No case logic in order workflow (INT-001)

### Template Usage
- ✅ `template_key` only used at creation
- ✅ No business logic depends on it

### Case Status
- ✅ Binary only: `åben` / `lukket`
- ✅ Workflow state via tags

### Tags
- ✅ Represent work to be done
- ✅ Have state: `open` / `closed`
- ✅ Never deleted when completed (closed instead)
- ✅ Closing = completion of responsibility

### Relations
- ✅ First-class data (own table)
- ✅ Directional (kilde → mål)
- ✅ Transitive (chains allowed)
- ✅ No parent/child duality in stored data
- ✅ UI derives parent/child views

### Deletion Policy
- ✅ All deletes are soft-deletes
- ✅ `deleted_at` mandatory everywhere

### Modeling Rule
- ✅ If you think you need a new table → use relations instead
- ⚠️ Exception: Orders (per architectural rule)

---

## TEST SCENARIOS BY PHASE

### Phase 1: Database
1. Insert case with status='other' → constraint violation
2. Insert tag with state='pending' → constraint violation
3. Create relation with kilde_sag_id = målsag_id → constraint violation
4. Soft-delete case → deleted_at set, not physical delete
5. Query cases WHERE deleted_at IS NULL → deleted cases excluded

### Phase 2: Backend
1. Call `/sag/cases` → 404 (removed endpoint)
2. Call `/cases` → 200 with case list
3. PATCH tag state to 'closed' → closed_at set, deleted_at NULL
4. DELETE tag → deleted_at set, state unchanged
5. POST relation with type='invalid' → 400 error
6. POST relation with type='derived' → 201 created

### Phase 3: Frontend
1. Edit case form → loads current values
2. Submit edit form → case updated, redirect to detail
3. Click "Close Tag" → tag state='closed', remains visible, greyed
4. Add relation → dropdown shows allowed types
5. Bulk close cases → all selected closed
6. View on 375px screen → no horizontal scroll

### Phase 4: Order Integration
1. Create order without case → success
2. Link order to case → relation created
3. View case → shows linked orders
4. View order → shows linked cases
5. Delete case → order remains (independent)

### Phase 5: Documentation
1. Developer reads README → understands architecture
2. Developer reads API docs → can call endpoints
3. Developer reads relation types → understands usage
4. Developer reads workflows → can implement feature

### Phase 6: QA
1. All CRUD operations → success
2. Soft-delete case → data preserved
3. Module disabled → endpoints return 404
4. Module re-enabled → data accessible again
5. Tag closed → not deleted
6. Relation created → directionality correct

---

## ANTI-PATTERNS TO AVOID

### DO NOT:
- ❌ Create `tickets` or `tasks` tables (use cases with tags)
- ❌ Embed workflow logic in orders
- ❌ Introduce parent/child trees outside relations
- ❌ Add state machines (use tags)
- ❌ Optimize prematurely (no Redis, no caching yet)
- ❌ Physical delete anything (always soft-delete)
- ❌ Skip validation (enforce constraints)
- ❌ Duplicate endpoints (one path per resource)

### DO:
- ✅ Use relations to express connections
- ✅ Use tags to express workflow state
- ✅ Keep orders independent but relatable
- ✅ Soft-delete everything
- ✅ Log all actions with emoji prefixes
- ✅ Return user-friendly errors
- ✅ Preserve data on module disable

---

## ROLLOUT PLAN

### Development Environment
1. Complete Phases 1-3 in dev
2. Test with test data
3. Verify module disable/enable

### Staging/QA
1. Run full QA suite (Phase 6)
2. Performance test with 10k+ cases
3. Load test endpoints
4. Verify soft-deletes work at scale

### Production
1. Run schema validation (DB-001)
2. Deploy backend changes (Phase 2)
3. Deploy frontend changes (Phase 3)
4. Monitor logs for errors
5. Verify no downtime
6. Roll back if issues (soft-deletes preserve data)

### Post-Deployment
1. Monitor case creation rate
2. Track relation usage patterns
3. Identify most-used tags
4. Plan order integration (Phase 4)

---

## SUCCESS CRITERIA

The Sag Module implementation is COMPLETE when:

✅ **Database**
- All constraints enforced
- Soft-deletes everywhere
- Indexes performant

✅ **Backend**
- No duplicate endpoints
- Tag closing works
- Relations validated
- Edit route exists
- Errors consistent

✅ **Frontend**
- Edit form works
- Tag closing UI works
- Relations visualized
- Bulk operations work
- Mobile responsive

✅ **Order Integration**
- Model documented
- Schema planned
- API defined
- No constraint violations

✅ **Documentation**
- README complete
- API documented
- Relation types explained
- Workflows documented

✅ **Testing**
- All CRUD tested
- Relations tested
- Tags tested
- Frontend tested
- Module lifecycle tested

✅ **Architectural Compliance**
- One entity: Case
- Orders separate but linkable
- Template key not used in logic
- Status binary
- Tags never deleted (closed)
- Relations directional
- Soft-deletes everywhere
- No new tables (except orders)

---

## APPENDIX A: TASK TIME SUMMARY

| Phase | Task Count | Sequential Time | Parallel Time |
|-------|-----------|----------------|---------------|
| Phase 1: Database | 1 | 30m | 30m |
| Phase 2: Backend | 5 | 3h 30m | 1h 45m |
| Phase 3: Frontend | 5 | 5h 45m | 2h 30m |
| Phase 4: Orders | 3 | 2h | 30m (parallel) |
| Phase 5: Docs | 4 | 2h 30m | 45m (parallel) |
| Phase 6: QA | 5 | 4h 30m | 2h |
| **TOTAL** | **23** | **18h 45m** | **~8h** |

---

## APPENDIX B: RELATION TYPE REFERENCE

| Type | Direction | Meaning | Example |
|------|-----------|---------|---------|
| `derived` | A → B | B spawned from A | Support call → hardware order |
| `blocks` | A → B | A prevents B | Missing part → installation task |
| `executes` | A → B | A performs work for B | Packing task → customer order |
| `relates_to` | A ↔ B | Generic association | Related support tickets |

**Validation:** Only these four types allowed in `POST /api/v1/cases/{id}/relations`

---

## APPENDIX C: TAG STATE LIFECYCLE

```
Tag Created (state='open', closed_at=NULL)
    ↓
[Work happens]
    ↓
Tag Closed (state='closed', closed_at=NOW(), deleted_at=NULL)
    ↓
Tag Remains Visible (greyed out in UI)
    ↓
[Optional: Technical cleanup]
    ↓
Tag Soft-Deleted (deleted_at=NOW())
```

**Key Rule:** Closing ≠ Deleting. Tags are closed when work is done, deleted only if added by mistake.

---

## APPENDIX D: ORDER-CASE INTEGRATION EXAMPLE

**Scenario:** Customer needs new laptop

```
1. Support Call (Case ID: 1001)
   - Type: Case
   - Tags: [support, hardware]
   - Status: åben

2. Create Hardware Order (Order ID: 5001)
   - Type: Order (separate table)
   - Items: [Laptop, Charger]
   - Status: pending

3. Link Order to Case
   - POST /api/v1/orders/5001/cases
   - Body: {"case_id": 1001, "relation_type": "fulfills"}
   - Creates entry in order_case_relations

4. Fulfillment Task (Case ID: 1002)
   - Type: Case
   - Tags: [fulfillment]
   - Status: åben
   - Relation: 1002 executes 1001

5. Query Cases for Order
   - GET /api/v1/orders/5001/cases
   - Returns: [Case 1001]

6. Query Orders for Case
   - GET /api/v1/cases/1001/orders
   - Returns: [Order 5001]
```

**Architecture Preserved:**
- Order is NOT a case
- Order is independent (can exist without case)
- Order gains context through case relation
- Cases remain the process backbone

---

## DOCUMENT CONTROL

**Version History:**

| Version | Date | Author | Changes |
|---------|------|--------|---------|
| 1.0 | 2026-01-30 | GitHub Copilot | Initial plan |
| 2.0 | 2026-01-30 | GitHub Copilot | Sub-agent task breakdown added |

**Approval:**
- [ ] Architect Review
- [ ] Technical Lead Review
- [ ] Project Manager Approval

**Next Review Date:** After Phase 2 completion

---

**END OF IMPLEMENTATION PLAN**
