338 lines
9.2 KiB
Markdown
338 lines
9.2 KiB
Markdown
|
|
# Epic & Wiki Feature Implementation Summary
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
This document summarizes the implementation of the Epic and Wiki features for the Kanban application.
|
||
|
|
|
||
|
|
## What Was Implemented
|
||
|
|
|
||
|
|
### Backend (Flask)
|
||
|
|
|
||
|
|
#### 1. Database Models
|
||
|
|
|
||
|
|
**Epic Model** (`backend/app/models/epic.py`)
|
||
|
|
- Rich text content support (JSON for Slate.js)
|
||
|
|
- Hierarchical structure (parent_epic_id for nesting)
|
||
|
|
- Color coding
|
||
|
|
- Position ordering
|
||
|
|
- Board-level scoping
|
||
|
|
- Soft delete support (closed field)
|
||
|
|
- Depth limit for hierarchy control
|
||
|
|
|
||
|
|
**Wiki Model** (`backend/app/models/wiki.py`)
|
||
|
|
- Rich text content (JSON for Slate.js)
|
||
|
|
- URL-friendly slugs
|
||
|
|
- Summary field
|
||
|
|
- Categories for organization
|
||
|
|
- Tags support
|
||
|
|
- Created by / Updated by tracking
|
||
|
|
- Board-level scoping
|
||
|
|
|
||
|
|
**Card Model Update** (`backend/app/models/card.py`)
|
||
|
|
- Added `epic_id` foreign key to link cards to epics
|
||
|
|
|
||
|
|
**Association Table** (`wiki_entity_links`)
|
||
|
|
- Many-to-many relationship between Wikis and entity types
|
||
|
|
- Supports linking Wikis to Cards, Epics, and future entity types
|
||
|
|
|
||
|
|
#### 2. Database Migration
|
||
|
|
- Created migration file: `6fc439155ced_add_epic_and_wiki_models.py`
|
||
|
|
- Adds all new tables and relationships
|
||
|
|
|
||
|
|
### Frontend (React/TypeScript)
|
||
|
|
|
||
|
|
#### 1. TypeScript Types (`frontend/src/types/epic.ts`)
|
||
|
|
```typescript
|
||
|
|
- Epic interface
|
||
|
|
- Wiki interface
|
||
|
|
- CreateEpicRequest / UpdateEpicRequest
|
||
|
|
- CreateWikiRequest / UpdateWikiRequest
|
||
|
|
- WikiEntityLink interface
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 2. Components
|
||
|
|
|
||
|
|
**RichTextEditor** (`frontend/src/components/RichTextEditor.tsx`)
|
||
|
|
- Slate.js-based rich text editor
|
||
|
|
- Editable with proper styling
|
||
|
|
- Dark mode support
|
||
|
|
- Placeholder support
|
||
|
|
- Read-only mode option
|
||
|
|
|
||
|
|
**RichTextContent** (`frontend/src/components/RichTextContent.tsx`)
|
||
|
|
- Read-only renderer for Slate.js content
|
||
|
|
- Supports paragraphs, lists, blockquotes
|
||
|
|
- Text formatting (bold, italic, underline, code)
|
||
|
|
- Dark mode styling
|
||
|
|
|
||
|
|
#### 3. Custom Hook
|
||
|
|
|
||
|
|
**useEpics** (`frontend/src/hooks/useEpics.ts`)
|
||
|
|
- Fetch all epics for a board
|
||
|
|
- Create new epic
|
||
|
|
- Update existing epic
|
||
|
|
- Delete epic
|
||
|
|
- Integrated with global loader and toast notifications
|
||
|
|
- Error handling with user-friendly messages
|
||
|
|
|
||
|
|
#### 4. API Integration
|
||
|
|
|
||
|
|
Updated `useApi` hook with epic methods:
|
||
|
|
```typescript
|
||
|
|
- getEpics(boardId)
|
||
|
|
- createEpic(boardId, epicData)
|
||
|
|
- getEpic(epicId)
|
||
|
|
- updateEpic(epicId, epicData)
|
||
|
|
- deleteEpic(epicId)
|
||
|
|
- addEpicToCard(cardId, epicId)
|
||
|
|
- removeEpicFromCard(cardId, epicId)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Key Design Decisions
|
||
|
|
|
||
|
|
### 1. Epic Hierarchy
|
||
|
|
- **Decision**: Self-referential foreign key (`parent_epic_id`)
|
||
|
|
- **Rationale**: Allows flexible nesting of epics with arbitrary depth
|
||
|
|
- **Feature**: `depth_limit` field to control maximum nesting depth
|
||
|
|
|
||
|
|
### 2. Rich Text Storage
|
||
|
|
- **Decision**: Store as JSON (compatible with Slate.js)
|
||
|
|
- **Rationale**:
|
||
|
|
- Slate.js natively uses JSON format
|
||
|
|
- No serialization/deserialization overhead
|
||
|
|
- Easy to query and modify content structure
|
||
|
|
|
||
|
|
### 3. Wiki vs Document Naming
|
||
|
|
- **Decision**: Use "Wiki" instead of "Document"
|
||
|
|
- **Rationale**: Avoids confusion with file attachments
|
||
|
|
- **Meaning**: Wiki implies knowledge base / documentation repository
|
||
|
|
|
||
|
|
### 4. Entity Linking Strategy
|
||
|
|
- **Decision**: Polymorphic association table (`wiki_entity_links`)
|
||
|
|
- **Rationale**:
|
||
|
|
- Single table handles all entity types
|
||
|
|
- Easy to add new entity types in future
|
||
|
|
- Avoids circular imports and complex schema changes
|
||
|
|
|
||
|
|
### 5. Epic-Card Relationship
|
||
|
|
- **Decision**: One-way reference (Card → Epic)
|
||
|
|
- **Rationale**:
|
||
|
|
- Simpler than many-to-many (epics contain cards)
|
||
|
|
- Cards can belong to one epic at a time
|
||
|
|
- Consistent with Jira's parent/child pattern
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
### Backend Data Flow
|
||
|
|
|
||
|
|
```
|
||
|
|
Board (1) ───────┬─────── (1) Epic
|
||
|
|
│ │
|
||
|
|
│ │─── (0..*) Card (via epic_id)
|
||
|
|
│
|
||
|
|
└───────────────┬─────── (0..*) Wiki
|
||
|
|
│
|
||
|
|
└─── wiki_entity_links ───┬── Card
|
||
|
|
├── Epic
|
||
|
|
└── (future entities)
|
||
|
|
```
|
||
|
|
|
||
|
|
### Frontend Component Structure
|
||
|
|
|
||
|
|
```
|
||
|
|
BoardEpics (page)
|
||
|
|
├── EpicList
|
||
|
|
│ └── EpicCard
|
||
|
|
└── CreateEpicModal
|
||
|
|
├── EpicForm
|
||
|
|
│ ├── EpicNameInput
|
||
|
|
│ ├── EpicDescriptionInput
|
||
|
|
│ └── RichTextEditor (content)
|
||
|
|
└── ColorPicker
|
||
|
|
```
|
||
|
|
|
||
|
|
## Next Steps
|
||
|
|
|
||
|
|
### Immediate Actions Required
|
||
|
|
|
||
|
|
1. **Run Database Migration**
|
||
|
|
```bash
|
||
|
|
cd backend
|
||
|
|
flask db upgrade
|
||
|
|
```
|
||
|
|
|
||
|
|
2. **Create Backend Routes** (`backend/app/routes/kanban/epics.py`)
|
||
|
|
- CRUD operations for Epics
|
||
|
|
- Epic-Card linking endpoints
|
||
|
|
- Wiki CRUD operations
|
||
|
|
- Wiki-Entity linking endpoints
|
||
|
|
|
||
|
|
3. **Create Backend Schemas** (`backend/app/schemas/epic.py`, `wiki.py`)
|
||
|
|
- Marshmallow schemas for serialization
|
||
|
|
- Input validation
|
||
|
|
|
||
|
|
4. **Update BoardEpics Page** (`frontend/src/pages/BoardEpics.tsx`)
|
||
|
|
- Implement epic list view
|
||
|
|
- Add create epic modal
|
||
|
|
- Add epic detail view
|
||
|
|
- Include RichTextEditor for epic content
|
||
|
|
|
||
|
|
5. **Update Card Detail Page** (`frontend/src/pages/CardDetail.tsx`)
|
||
|
|
- Add epic selector dropdown
|
||
|
|
- Display linked epic information
|
||
|
|
- Add wiki links
|
||
|
|
|
||
|
|
### Future Enhancements
|
||
|
|
|
||
|
|
1. **Wiki Features**
|
||
|
|
- Wiki page with sidebar navigation
|
||
|
|
- Markdown export/import
|
||
|
|
- Wiki search functionality
|
||
|
|
- Version history
|
||
|
|
|
||
|
|
2. **Epic Features**
|
||
|
|
- Epic progress tracking (cards completed vs total)
|
||
|
|
- Epic metrics dashboard
|
||
|
|
- Epic drag-and-drop reordering
|
||
|
|
- Epic timeline view
|
||
|
|
|
||
|
|
3. **UI/UX Improvements**
|
||
|
|
- Epic color picker with presets
|
||
|
|
- Epic hierarchy tree view
|
||
|
|
- Inline card epic assignment
|
||
|
|
- Epic templates
|
||
|
|
|
||
|
|
4. **Analytics**
|
||
|
|
- Epic completion rate
|
||
|
|
- Time spent on epic
|
||
|
|
- Epic size distribution
|
||
|
|
- Wiki usage statistics
|
||
|
|
|
||
|
|
## Database Schema
|
||
|
|
|
||
|
|
### Epic Table
|
||
|
|
```sql
|
||
|
|
CREATE TABLE epics (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
name VARCHAR(200) NOT NULL,
|
||
|
|
description TEXT,
|
||
|
|
content JSONB,
|
||
|
|
color VARCHAR(7),
|
||
|
|
closed BOOLEAN DEFAULT FALSE,
|
||
|
|
pos FLOAT,
|
||
|
|
depth_limit INTEGER,
|
||
|
|
board_id INTEGER REFERENCES boards(id),
|
||
|
|
parent_epic_id INTEGER REFERENCES epics(id),
|
||
|
|
date_last_activity TIMESTAMP,
|
||
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
### Wiki Table
|
||
|
|
```sql
|
||
|
|
CREATE TABLE wikis (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
name VARCHAR(200) NOT NULL,
|
||
|
|
slug VARCHAR(200) UNIQUE,
|
||
|
|
content JSONB NOT NULL,
|
||
|
|
summary TEXT,
|
||
|
|
category VARCHAR(100),
|
||
|
|
board_id INTEGER REFERENCES boards(id),
|
||
|
|
created_by INTEGER REFERENCES users(id),
|
||
|
|
updated_by INTEGER REFERENCES users(id),
|
||
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
### Wiki Entity Links Table
|
||
|
|
```sql
|
||
|
|
CREATE TABLE wiki_entity_links (
|
||
|
|
wiki_id INTEGER REFERENCES wikis(id) ON DELETE CASCADE,
|
||
|
|
entity_type VARCHAR(50) NOT NULL,
|
||
|
|
entity_id INTEGER NOT NULL,
|
||
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
linked_by INTEGER REFERENCES users(id),
|
||
|
|
PRIMARY KEY (wiki_id, entity_type, entity_id)
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
## API Endpoints (To Be Implemented)
|
||
|
|
|
||
|
|
### Epic Endpoints
|
||
|
|
```
|
||
|
|
GET /api/boards/<board_id>/epics
|
||
|
|
POST /api/boards/<board_id>/epics
|
||
|
|
GET /api/epics/<epic_id>
|
||
|
|
PUT /api/epics/<epic_id>
|
||
|
|
DELETE /api/epics/<epic_id>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Epic-Card Linking
|
||
|
|
```
|
||
|
|
POST /api/cards/<card_id>/epics
|
||
|
|
DELETE /api/cards/<card_id>/epics/<epic_id>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Wiki Endpoints
|
||
|
|
```
|
||
|
|
GET /api/boards/<board_id>/wikis
|
||
|
|
POST /api/boards/<board_id>/wikis
|
||
|
|
GET /api/wikis/<wiki_id>
|
||
|
|
PUT /api/wikis/<wiki_id>
|
||
|
|
DELETE /api/wikis/<wiki_id>
|
||
|
|
GET /api/wikis/<wiki_id>/content
|
||
|
|
```
|
||
|
|
|
||
|
|
### Wiki-Entity Linking
|
||
|
|
```
|
||
|
|
POST /api/wikis/<wiki_id>/links
|
||
|
|
DELETE /api/wikis/<wiki_id>/links/<entity_type>/<entity_id>
|
||
|
|
```
|
||
|
|
|
||
|
|
## Testing Considerations
|
||
|
|
|
||
|
|
### Unit Tests
|
||
|
|
- Epic model creation and relationships
|
||
|
|
- Wiki model creation and relationships
|
||
|
|
- Epic hierarchy validation
|
||
|
|
- Wiki slug generation
|
||
|
|
- Rich text content serialization
|
||
|
|
|
||
|
|
### Integration Tests
|
||
|
|
- Epic CRUD operations
|
||
|
|
- Wiki CRUD operations
|
||
|
|
- Epic-Card linking
|
||
|
|
- Wiki-Entity linking
|
||
|
|
- Epic hierarchy operations
|
||
|
|
|
||
|
|
### Frontend Tests
|
||
|
|
- RichTextEditor component
|
||
|
|
- RichTextContent component
|
||
|
|
- useEpics hook
|
||
|
|
- Epic list rendering
|
||
|
|
- Epic creation form
|
||
|
|
|
||
|
|
## Notes
|
||
|
|
|
||
|
|
- **Slate.js Content**: Content is stored as raw Slate.js JSON format, which includes element types, text nodes, and formatting information
|
||
|
|
- **Hierarchical Epics**: While supported, UI for nesting epics is not yet implemented
|
||
|
|
- **Wiki Slugs**: Slugs should be auto-generated from wiki names and checked for uniqueness
|
||
|
|
- **Color Codes**: Epic colors should be valid hex codes (e.g., "#ef4444")
|
||
|
|
- **Position**: Epic positions use float values for flexible reordering (similar to Trello)
|
||
|
|
|
||
|
|
## Related Files
|
||
|
|
|
||
|
|
### Backend
|
||
|
|
- `backend/app/models/epic.py` - Epic model
|
||
|
|
- `backend/app/models/wiki.py` - Wiki model
|
||
|
|
- `backend/app/models/card.py` - Updated Card model
|
||
|
|
- `backend/app/models/__init__.py` - Model imports
|
||
|
|
- `backend/migrations/versions/6fc439155ced_add_epic_and_wiki_models.py` - Migration
|
||
|
|
|
||
|
|
### Frontend
|
||
|
|
- `frontend/src/types/epic.ts` - TypeScript interfaces
|
||
|
|
- `frontend/src/components/RichTextEditor.tsx` - Editor component
|
||
|
|
- `frontend/src/components/RichTextContent.tsx` - Content renderer
|
||
|
|
- `frontend/src/hooks/useEpics.ts` - Epic custom hook
|
||
|
|
- `frontend/src/hooks/useApi.ts` - Updated API methods
|