# Product Requirements Document: Enhanced Tag System ## Overview Upgrade the current JSON-based tag system to a relational database model with advanced tagging features including tag filtering, related posts, tag management, and an improved tag input UI with typeahead functionality. ## Goals - Enable efficient querying and filtering of posts by tags - Provide tag management capabilities for content curation - Show related posts based on shared tags - Implement intuitive tag input with typeahead and keyboard shortcuts - Build analytics and insights around tag usage - Maintain backward compatibility during migration ## Technical Constraints - **Framework**: SvelteKit with Svelte 5 runes mode - **Database**: PostgreSQL with Prisma ORM - **Hosting**: Railway (existing infrastructure) - **Design System**: Use existing admin component library - **Performance**: Tag operations should be sub-100ms ## Current State vs Target State ### Current Implementation - Tags stored as JSON arrays: `tags: ['announcement', 'meta', 'cms']` - Simple display-only functionality - No querying capabilities - Manual tag input with Add button ### Target Implementation - Relational many-to-many tag system - Full CRUD operations for tags - Advanced filtering and search - Typeahead tag input with keyboard navigation - Tag analytics and management interface ## Database Schema Changes ### New Tables ```sql -- Tags table CREATE TABLE tags ( id SERIAL PRIMARY KEY, name VARCHAR(100) UNIQUE NOT NULL, slug VARCHAR(100) UNIQUE NOT NULL, description TEXT, color VARCHAR(7), -- Hex color for tag styling created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Post-Tag junction table CREATE TABLE post_tags ( id SERIAL PRIMARY KEY, post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE, tag_id INTEGER REFERENCES tags(id) ON DELETE CASCADE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(post_id, tag_id) ); -- Tag usage analytics (optional) CREATE TABLE tag_analytics ( id SERIAL PRIMARY KEY, tag_id INTEGER REFERENCES tags(id) ON DELETE CASCADE, usage_count INTEGER DEFAULT 1, last_used TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); ``` ### Prisma Schema Updates ```prisma model Tag { id Int @id @default(autoincrement()) name String @unique @db.VarChar(100) slug String @unique @db.VarChar(100) description String? @db.Text color String? @db.VarChar(7) // Hex color createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // Relations posts PostTag[] @@index([name]) @@index([slug]) } model PostTag { id Int @id @default(autoincrement()) postId Int tagId Int createdAt DateTime @default(now()) // Relations post Post @relation(fields: [postId], references: [id], onDelete: Cascade) tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade) @@unique([postId, tagId]) @@index([postId]) @@index([tagId]) } // Update existing Post model model Post { // ... existing fields tags PostTag[] // Replace: tags Json? } ``` ## Core Features ### 1. Tag Management Interface #### Admin Tag Manager (`/admin/tags`) - **Tag List View** - DataTable with tag name, usage count, created date - Search and filter capabilities - Bulk operations (delete, merge, rename) - Color coding and visual indicators - **Tag Detail/Edit View** - Edit tag name, description, color - View all posts using this tag - Usage analytics and trends - Merge with other tags functionality #### Tag Analytics Dashboard - **Usage Statistics** - Most/least used tags - Tag usage trends over time - Orphaned tags (no posts) - Tag co-occurrence patterns - **Tag Insights** - Suggested tag consolidations - Similar tags detection - Tag performance metrics ### 2. Enhanced Tag Input Component (`TagInput.svelte`) #### Features - **Typeahead Search**: Real-time search of existing tags - **Keyboard Navigation**: Arrow keys to navigate suggestions - **Instant Add**: Press Enter to add tag without button click - **Visual Feedback**: Highlight matching text in suggestions - **Tag Validation**: Prevent duplicates and invalid characters - **Quick Actions**: Backspace to remove last tag #### Component API ```typescript interface TagInputProps { tags: string[] | Tag[] // Current tags suggestions?: Tag[] // Available tags for typeahead placeholder?: string // Input placeholder text maxTags?: number // Maximum number of tags allowNew?: boolean // Allow creating new tags size?: 'small' | 'medium' | 'large' disabled?: boolean onTagAdd?: (tag: Tag) => void onTagRemove?: (tag: Tag) => void onTagCreate?: (name: string) => void } ``` #### Svelte 5 Implementation ```svelte ``` ### 3. Post Filtering by Tags #### Frontend Components - **Tag Filter Bar**: Multi-select tag filtering - **Tag Cloud**: Visual tag representation with usage counts - **Search Integration**: Combine text search with tag filters #### API Endpoints ```typescript // GET /api/posts?tags=javascript,react&operation=AND // GET /api/posts?tags=design,ux&operation=OR interface PostsQueryParams { tags?: string[] // Tag names or IDs operation?: 'AND' | 'OR' // How to combine multiple tags page?: number limit?: number status?: 'published' | 'draft' } // GET /api/tags/suggest?q=java interface TagSuggestResponse { tags: Array<{ id: number name: string slug: string usageCount: number }> } ``` ### 4. Related Posts Feature #### Implementation - **Algorithm**: Find posts sharing the most tags - **Weighting**: Consider tag importance and recency - **Exclusions**: Don't show current post in related list - **Limit**: Show 3-6 related posts maximum #### Component (`RelatedPosts.svelte`) ```svelte ``` ## API Specification ### Tag Management APIs ```typescript // GET /api/tags - List all tags interface TagsResponse { tags: Tag[] total: number page: number limit: number } // POST /api/tags - Create new tag interface CreateTagRequest { name: string description?: string color?: string } // PUT /api/tags/[id] - Update tag interface UpdateTagRequest { name?: string description?: string color?: string } // DELETE /api/tags/[id] - Delete tag // Returns: 204 No Content // POST /api/tags/merge - Merge tags interface MergeTagsRequest { sourceTagIds: number[] targetTagId: number } // GET /api/tags/[id]/posts - Get posts for tag interface TagPostsResponse { posts: Post[] tag: Tag total: number } // GET /api/tags/analytics - Tag usage analytics interface TagAnalyticsResponse { mostUsed: Array<{ tag: Tag; count: number }> leastUsed: Array<{ tag: Tag; count: number }> trending: Array<{ tag: Tag; growth: number }> orphaned: Tag[] } ``` ### Enhanced Post APIs ```typescript // GET /api/posts/related?postId=123&tagIds=1,2,3&limit=4 interface RelatedPostsResponse { posts: Array<{ id: number title: string slug: string excerpt?: string publishedAt: string tags: Tag[] sharedTagsCount: number // Number of tags in common }> } // PUT /api/posts/[id]/tags - Update post tags interface UpdatePostTagsRequest { tagIds: number[] } ``` ## User Interface Components ### 1. TagInput Component Features #### Visual States - **Default**: Clean input with placeholder - **Focused**: Show suggestions dropdown - **Typing**: Filter and highlight matches - **Selected**: Navigate with keyboard - **Adding**: Smooth animation for new tags - **Full**: Disable input when max tags reached #### Accessibility - **ARIA Labels**: Proper labeling for screen readers - **Keyboard Navigation**: Full keyboard accessibility - **Focus Management**: Logical tab order - **Announcements**: Screen reader feedback for actions ### 2. Tag Display Components #### TagPill Component ```svelte {tag.name} {#if showCount} ({tag.usageCount}) {/if} {#if removable} {/if} ``` #### TagCloud Component ```svelte ``` ### 3. Admin Interface Updates #### Posts List with Tag Filtering - **Filter Bar**: Multi-select tag filter above posts list - **Tag Pills**: Show tags on each post item - **Quick Filter**: Click tag to filter by that tag - **Clear Filters**: Easy way to reset all filters #### Posts Edit Form Integration - **Replace Current**: Swap existing tag input with new TagInput - **Preserve UX**: Maintain current metadata popover - **Tag Management**: Quick access to create/edit tags ## Migration Strategy ### Phase 1: Database Migration (Week 1) 1. **Create Migration Script** - Create new tables (tags, post_tags) - Migrate existing JSON tags to relational format - Create indexes for performance 2. **Data Migration** - Extract unique tags from existing posts - Create tag records with auto-generated slugs - Create post_tag relationships - Validate data integrity 3. **Backward Compatibility** - Keep original tags JSON field temporarily - Dual-write to both systems during transition ### Phase 2: API Development (Week 1-2) 1. **Tag Management APIs** - CRUD operations for tags - Tag suggestions and search - Analytics endpoints 2. **Enhanced Post APIs** - Update post endpoints for relational tags - Related posts algorithm - Tag filtering capabilities 3. **Testing & Validation** - Unit tests for all endpoints - Performance testing for queries - Data consistency checks ### Phase 3: Frontend Components (Week 2-3) 1. **Core Components** - TagInput with typeahead - TagPill and TagCloud - Tag management interface 2. **Integration** - Update MetadataPopover - Add tag filtering to posts list - Implement related posts component 3. **Admin Interface** - Tag management dashboard - Analytics views - Bulk operations interface ### Phase 4: Features & Polish (Week 3-4) 1. **Advanced Features** - Tag merging functionality - Usage analytics - Tag suggestions based on content 2. **Performance Optimization** - Query optimization - Caching strategies - Load testing 3. **Cleanup** - Remove JSON tags field - Documentation updates - Final testing ## Success Metrics ### Performance - Tag search responses under 50ms - Post filtering responses under 100ms - Page load times maintained or improved ### Usability - Reduced clicks to add tags (eliminate Add button) - Faster tag input with typeahead - Improved content discovery through related posts ### Content Management - Ability to merge duplicate tags - Insights into tag usage patterns - Better content organization capabilities ### Analytics - Track tag usage growth over time - Identify content gaps through tag analysis - Measure impact on content engagement ## Technical Considerations ### Performance - **Database Indexes**: Proper indexing on tag names and relationships - **Query Optimization**: Efficient joins for tag filtering - **Caching**: Cache popular tag lists and related posts - **Pagination**: Handle large tag lists efficiently ### Data Integrity - **Constraints**: Prevent duplicate tag names - **Cascading Deletes**: Properly handle tag/post deletions - **Validation**: Ensure tag names follow naming conventions - **Backup Strategy**: Safe migration with rollback capability ### User Experience - **Progressive Enhancement**: Graceful degradation if JS fails - **Loading States**: Smooth loading indicators - **Error Handling**: Clear error messages for users - **Responsive Design**: Works well on all device sizes ## Future Enhancements ### Advanced Features (Post-MVP) - **Hierarchical Tags**: Parent/child tag relationships - **Tag Synonyms**: Alternative names for the same concept - **Auto-tagging**: ML-based tag suggestions from content - **Tag Templates**: Predefined tag sets for different content types ### Integrations - **External APIs**: Import tags from external sources - **Search Integration**: Enhanced search with tag faceting - **Analytics**: Deep tag performance analytics - **Content Recommendations**: AI-powered related content ## Risk Assessment ### High Risk - **Data Migration**: Complex migration of existing tag data - **Performance Impact**: New queries might affect page load times - **User Adoption**: Users need to learn new tag input interface ### Mitigation Strategies - **Staged Rollout**: Deploy to staging first, then gradual production rollout - **Performance Monitoring**: Continuous monitoring during migration - **User Training**: Clear documentation and smooth UX transitions - **Rollback Plan**: Ability to revert to JSON tags if needed ## Success Criteria ### Must Have - ✅ All existing tags migrated successfully - ✅ Tag input works with keyboard-only navigation - ✅ Posts can be filtered by single or multiple tags - ✅ Related posts show based on shared tags - ✅ Performance remains acceptable (< 100ms for most operations) ### Should Have - ✅ Tag management interface for admins - ✅ Tag usage analytics and insights - ✅ Ability to merge duplicate tags - ✅ Tag color coding and visual improvements ### Could Have - Tag auto-suggestions based on post content - Tag trending and popularity metrics - Advanced tag analytics and reporting - Integration with external tag sources ## Timeline **Total Duration**: 4 weeks - **Week 1**: Database migration and API development - **Week 2**: Core frontend components and basic integration - **Week 3**: Advanced features and admin interface - **Week 4**: Polish, testing, and production deployment ## Conclusion This enhanced tag system will significantly improve content organization, discoverability, and management capabilities while providing a modern, intuitive user interface built with Svelte 5 runes. The migration strategy ensures minimal disruption while delivering substantial improvements in functionality and user experience.