# Epic and Wiki Models - Implementation Summary ## Overview This document summarizes the implementation of Epic and Wiki models for the Kanban application. ## What Was Implemented ### 1. Epic Model (`backend/app/models/epic.py`) - Tracks large features across multiple cards - Hierarchical structure (parent-child epics) - Rich text content support (Slate.js JSON) - Color-coded badges for visual identification - Metrics tracking (card count) **Key Fields:** - `id`, `name`, `description`, `content` (JSONB) - `color` (hex code for epic badge) - `closed`, `pos`, `depth_limit` (default 5) - `board_id`, `parent_epic_id` - `date_last_activity`, `created_at`, `updated_at` - `metrics` (JSONB - stores card_count) **Relationships:** - Board: One-to-many (Board has many Epics) - Cards: One-to-many (Epic has many Cards) - Parent Epic: Self-referential (hierarchical) - File Attachments: Polymorphic (like Cards) ### 2. Wiki Model (`backend/app/models/wiki.py`) - Reusable rich text content within a board - Board-scoped (not global across all boards) - Polymorphic links to entities (Card, Epic, etc.) - Categorization and tagging support **Key Fields:** - `id`, `name`, `slug` (URL-friendly) - `content` (JSONB - rich text) - `summary`, `category`, `tags` (JSONB) - `board_id`, `created_by`, `updated_by` - `created_at`, `updated_at` **Relationships:** - Board: One-to-many (Board has many Wikis) - Entities: Many-to-many polymorphic (via wiki_entity_links) ### 3. Card Model Updates (`backend/app/models/card.py`) - Added `epic_id` foreign key (nullable) - Updated `to_dict()` to include `epic_id` - One-to-one relationship: Card belongs to one Epic ### 4. Association Table (`wiki_entity_links`) - Polymorphic many-to-many table - Links wikis to any entity type - Fields: `wiki_id`, `entity_type`, `entity_id`, `created_at`, `linked_by` ## Database Schema ### New Tables 1. **epics** - Epic records 2. **wikis** - Wiki content records 3. **wiki_entity_links** - Wiki-to-entity associations ### Modified Tables 1. **cards** - Added `epic_id` foreign key ### Relationships Diagram ``` Board (1) ----< (N) Epic Epic (1) ----< (N) Card (each card belongs to one epic) Epic (1) ----< (N) Epic (parent-child hierarchy) Board (1) ----< (N) Wiki Wiki (M) ----> (M) Entity (polymorphic: Card, Epic) ``` ## Database Migration **File:** `backend/migrations/versions/add_epic_and_wiki_models.py` **Creates:** - `epics` table with indexes on `board_id`, `closed`, `name` - `wikis` table with indexes on `board_id`, `name`, `slug` - `wiki_entity_links` table with composite primary key - `epic_id` column in `cards` table with index and foreign key **To apply migration:** ```bash cd backend flask db upgrade ``` **To rollback:** ```bash flask db downgrade ``` ## Model Exports Updated `backend/app/models/__init__.py` to include: - `from app.models.epic import Epic` - `from app.models.wiki import Wiki` Added to `__all__` list: `"Epic"`, `"Wiki"` ## Design Decisions ### Why "Wiki" instead of "Document"? - Avoids confusion with file attachments - Emphasizes reusable knowledge content - Better semantic meaning for rich text resources ### One-to-Many Epic-Card Relationship - Simpler, clearer ownership - Each card belongs to one epic - Easier to query and display ### Board-Scoped Wikis - Wikis belong to a specific board - Not global across all boards - Better organization and access control ### Epic Hierarchy Depth - Default depth limit: 5 levels - Configurable per epic - Backend should enforce when creating child epics ### Simplified Metrics - Currently only tracks `card_count` - Stored in JSONB field: `{"card_count": 10}` - Easy to extend with more metrics later ## Next Steps ### Backend Implementation 1. ✅ Create models - **DONE** 2. ✅ Create database migration - **DONE** 3. ⏭️ Create schemas for serialization 4. ⏭️ Create API routes (CRUD operations) 5. ⏭️ Create services for business logic 6. ⏭️ Add validation for epic depth limit 7. ⏭️ Update epic metrics when cards change 8. ⏭️ Write tests for models and routes ### Frontend Implementation 1. ⏭️ Update TypeScript types 2. ⏭️ Create Epic page/component 3. ⏭️ Create Wiki page/component 4. ⏭️ Add epic dropdown to card detail 5. ⏭️ Create epic list on board detail 6. ⏭️ Implement rich text editor (Slate.js) 7. ⏭️ Add wiki linking UI ### API Endpoints (Future) #### Epic Endpoints ``` GET /api/boards/{board_id}/epics # List all epics for board POST /api/boards/{board_id}/epics # Create epic GET /api/epics/{epic_id} # Get epic details with cards PUT /api/epics/{epic_id} # Update epic DELETE /api/epics/{epic_id} # Delete epic POST /api/epics/{epic_id}/cards # Create card directly in epic GET /api/epics/{epic_id}/tree # Get epic hierarchy tree ``` #### Wiki Endpoints ``` GET /api/boards/{board_id}/wikis # List all wikis for board POST /api/boards/{board_id}/wikis # Create wiki GET /api/wikis/{wiki_id} # Get wiki details PUT /api/wikis/{wiki_id} # Update wiki DELETE /api/wikis/{wiki_id} # Delete wiki POST /api/wikis/{wiki_id}/links # Link wiki to entity DELETE /api/wikis/{wiki_id}/links/{link_id} # Unlink from entity GET /api/{entity_type}/{entity_id}/wikis # Get wikis for entity ``` #### Card Endpoints (Updated) ``` PUT /api/cards/{card_id}/epic # Link card to epic (or null to unlink) GET /api/cards/{card_id}/epic # Get card's epic ``` ## Files Created/Modified ### Created - `backend/app/models/epic.py` - `backend/app/models/wiki.py` - `backend/migrations/versions/add_epic_and_wiki_models.py` ### Modified - `backend/app/models/card.py` (added epic_id) - `backend/app/models/__init__.py` (added Epic, Wiki imports) ## Testing the Implementation 1. **Apply migration:** ```bash cd backend source venv/bin/activate flask db upgrade ``` 2. **Verify tables created:** ```bash flask dbcurrent # Should show: add_epic_and_wiki_models ``` 3. **Test in Python shell:** ```python from app import create_app, db from app.models import Epic, Wiki, Card, Board app = create_app() with app.app_context(): # Create an epic epic = Epic(name="My Epic", board_id=1, color="#3b82f6") db.session.add(epic) db.session.commit() # Create a wiki wiki = Wiki(name="Security Guide", board_id=1, content={}) db.session.add(wiki) db.session.commit() print(f"Epic created: {epic.to_dict()}") print(f"Wiki created: {wiki.to_dict()}") ``` ## Notes - All models follow the existing project patterns - Uses `db` from `app` module (not `flask_sqlalchemy` directly) - Proper foreign key constraints with CASCADE/SET NULL - Timestamps use UTC timezone - JSONB fields for flexible data storage - Indexed for optimal query performance