diff --git a/COMPREHENSIVE-AUDIT-REPORT.md b/COMPREHENSIVE-AUDIT-REPORT.md deleted file mode 100644 index a10b9f36..00000000 --- a/COMPREHENSIVE-AUDIT-REPORT.md +++ /dev/null @@ -1,936 +0,0 @@ -# IGNY8 Comprehensive UX Audit & Recommendations - -**Date:** December 27, 2025 -**Scope:** Complete application audit for optimal user experience -**Note:** Plans, billing, credits, usage sections excluded - will be done in separate phase - ---- - -## Table of Contents - -1. [Site & Sector Selector Placement](#1-site--sector-selector-placement) -2. [Table Action Row Metrics - Tooltip Improvements](#2-table-action-row-metrics---tooltip-improvements) -3. [Footer Metrics - 3-Widget Layout](#3-footer-metrics---3-widget-layout) -4. [Progress Modal Steps Audit](#4-progress-modal-steps-audit) -5. [Dashboard Redesign Plan](#5-dashboard-redesign-plan) -6. [Site Setup Checklist Implementation](#6-site-setup-checklist-implementation) -7. [To-Do-s Completion Audit](#7-to-do-s-completion-audit) -8. [Notification System Plan](#8-notification-system-plan) - ---- - -## 1. Site & Sector Selector Placement - -### Rationale -- **Site Selector**: Required when data is scoped to a specific site -- **Sector Selector**: Required when data can be further filtered by content category/niche -- **Both**: When user needs precise data filtering at granular level -- **None**: When page is not site-specific or shows account-level data - -### Recommendations by Page - -| Page | Site Selector | Sector Selector | Reason | -|------|:-------------:|:---------------:|--------| -| **DASHBOARD** | -| Home | ✅ All Sites option | ❌ | Overview across sites - sector too granular for dashboard | -| **SETUP** | -| Add Keywords | ✅ | ✅ | Keywords are site+sector specific | -| Content Settings | ✅ | ❌ | Settings are site-level, not sector-level | -| Sites List | ❌ | ❌ | Managing sites themselves | -| Site Dashboard | ❌ (context) | ❌ | Already in specific site context | -| Site Settings tabs | ❌ (context) | ❌ | Already in specific site context | -| **PLANNER** | -| Keywords | ✅ | ✅ | Keywords organized by site+sector | -| Clusters | ✅ | ✅ | Clusters organized by site+sector | -| Cluster Detail | ❌ (context) | ❌ (context) | Already in cluster context | -| Ideas | ✅ | ✅ | Ideas organized by site+sector | -| **WRITER** | -| Tasks/Queue | ✅ | ✅ | Tasks organized by site+sector | -| Content/Drafts | ✅ | ✅ | Content organized by site+sector | -| Content View | ❌ (context) | ❌ (context) | Viewing specific content | -| Images | ✅ | ✅ | Images tied to content by site+sector | -| Review | ✅ | ✅ | Review queue by site+sector | -| Published | ✅ | ✅ | Published content by site+sector | -| **AUTOMATION** | -| Automation | ✅ | ❌ | Automation runs at site level | -| **LINKER** (if enabled) | -| Content List | ✅ | ✅ | Linking is content-specific | -| **OPTIMIZER** (if enabled) | -| Content Selector | ✅ | ✅ | Optimization is content-specific | -| Analysis Preview | ❌ (context) | ❌ (context) | Already in analysis context | -| **THINKER** (Admin) | -| All Thinker pages | ❌ | ❌ | System-wide prompts/profiles | -| **BILLING** | -| All Billing pages | ❌ | ❌ | Account-level billing data | -| **ACCOUNT** | -| Account Settings | ❌ | ❌ | Account-level settings | -| Profile | ❌ | ❌ | User profile | -| Team | ❌ | ❌ | Account-wide team | -| Plans | ❌ | ❌ | Account-level plans | -| Usage | ❌ | ❌ | Account-level usage | -| **HELP** | -| Help Page | ❌ | ❌ | Documentation | - -### Implementation Priority -1. **High**: Ensure Planner & Writer pages show both selectors -2. **Medium**: Automation shows site only -3. **Low**: Account/Billing/Thinker show none - ---- - -## 2. Table Action Row Metrics - Tooltip Improvements - -### Current State -The metrics in the table action row are already implemented (as shown in screenshot): -- Keywords page: `Keywords 46 | Clustered 10 | Unmapped 0 | Volume 13.6K` - -**NO additional metrics should be added to the App Header** - only Credits remains there. - -### Improvement: Better Actionable Tooltips - -The current tooltips are basic. Improve them with **actionable context and next-step guidance**: - -#### Keywords Page Metrics Tooltips - -| Metric | Current Tooltip | Improved Tooltip | -|--------|----------------|------------------| -| **Keywords** | "Total keywords" | "46 keywords ready for clustering. Select unclustered keywords and click 'Auto Cluster' to organize them into topic groups." | -| **Clustered** | "Keywords in clusters" | "10 clusters created. Clusters with 3-7 keywords are optimal. Click on a cluster to generate content ideas from it." | -| **Unmapped** | "Unclustered keywords" | "All keywords are clustered! New keywords you add will appear here until clustered." | -| **Volume** | "Total search volume" | "13.6K combined monthly searches. Higher volume keywords should be prioritized for content creation." | - -#### Clusters Page Metrics Tooltips - -| Metric | Current Tooltip | Improved Tooltip | -|--------|----------------|------------------| -| **Clusters** | "Total clusters" | "12 topic clusters available. Each cluster groups related keywords for focused content creation." | -| **With Ideas** | "Clusters with ideas" | "8 clusters have content ideas. Click 'Generate Ideas' on clusters without ideas to plan new content." | -| **Keywords** | "Total keywords" | "46 keywords organized across clusters. Well-balanced clusters have 3-7 keywords each." | -| **Ready** | "Ready for ideas" | "4 clusters are ready for idea generation. Select them and click 'Generate Ideas' to create content outlines." | - -#### Ideas Page Metrics Tooltips - -| Metric | Current Tooltip | Improved Tooltip | -|--------|----------------|------------------| -| **Ideas** | "Total ideas" | "34 content ideas generated. Review each idea's outline, then click 'Create Task' to begin content generation." | -| **Pending** | "Not yet tasks" | "12 ideas haven't been converted to tasks yet. Convert ideas to tasks to start the content writing process." | -| **In Tasks** | "Converted to tasks" | "22 ideas are now writing tasks. View their progress in Writer → Tasks queue." | - -#### Tasks Page Metrics Tooltips - -| Metric | Current Tooltip | Improved Tooltip | -|--------|----------------|------------------| -| **Queue** | "Pending tasks" | "15 tasks waiting for content generation. Select tasks and click 'Generate Content' to write articles." | -| **Processing** | "In progress" | "2 tasks are being written by AI. Content will appear in Drafts when complete (~2-3 min each)." | -| **Complete** | "Finished tasks" | "28 tasks have generated content. Review articles in Writer → Content before publishing." | - -#### Content Page Metrics Tooltips - -| Metric | Current Tooltip | Improved Tooltip | -|--------|----------------|------------------| -| **Drafts** | "Draft articles" | "25 articles in draft status. Add images and review before sending to the approval queue." | -| **Has Images** | "With images" | "17 articles have images attached. Articles with images get 94% more engagement." | -| **Needs Images** | "Missing images" | "8 articles need images. Select them and click 'Generate Images' to create featured & in-article visuals." | - -#### Images Page Metrics Tooltips - -| Metric | Current Tooltip | Improved Tooltip | -|--------|----------------|------------------| -| **Total** | "Total images" | "127 images in your library. Each article can have 1 featured image + multiple in-article images." | -| **Generated** | "AI generated" | "112 images created by AI. Review generated images and regenerate any that don't match your brand." | -| **Pending** | "Awaiting generation" | "15 image prompts ready. Click 'Generate Images' to create visuals from your approved prompts." | - ---- - -## 3. Footer Metrics - 3-Widget Layout - -### Design: Three-Column Widget Layout - -Replace current single metric cards with a **3-widget horizontal layout** (33.3% each): - -``` -┌─────────────────────────────────────────────────────────────────────────────────────┐ -│ WIDGET 1: PAGE METRICS │ WIDGET 2: MODULE STATS │ WIDGET 3: COMPLETION │ -│ (Current Page Progress) │ (Full Module Overview) │ (Both Modules Stats) │ -│ ~33.3% width │ ~33.3% width │ ~33.3% width │ -└─────────────────────────────────────────────────────────────────────────────────────┘ -``` - -### Widget 1: Current Page Metrics (with Combined Progress Bar) - -Shows metrics specific to the current page with a single combined progress bar. - -#### Keywords Page - Widget 1 -``` -┌──────────────────────────────────────────────────┐ -│ PAGE PROGRESS │ -│ │ -│ Keywords 46 Clustered 42 (91%) │ -│ Unmapped 4 Volume 13.6K │ -│ │ -│ ████████████████████░░░ 91% Clustered │ -│ │ -│ 💡 4 keywords ready to cluster │ -└──────────────────────────────────────────────────┘ -``` - -#### Clusters Page - Widget 1 -``` -┌──────────────────────────────────────────────────┐ -│ PAGE PROGRESS │ -│ │ -│ Clusters 12 With Ideas 8 (67%) │ -│ Keywords 46 Ready 4 │ -│ │ -│ ██████████████░░░░░░░ 67% Have Ideas │ -│ │ -│ 💡 4 clusters ready for idea generation │ -└──────────────────────────────────────────────────┘ -``` - -#### Ideas Page - Widget 1 -``` -┌──────────────────────────────────────────────────┐ -│ PAGE PROGRESS │ -│ │ -│ Ideas 34 In Tasks 22 (65%) │ -│ Pending 12 From Clusters 8 │ -│ │ -│ █████████████░░░░░░░░ 65% Converted │ -│ │ -│ 💡 12 ideas ready to become tasks │ -└──────────────────────────────────────────────────┘ -``` - -#### Tasks Page - Widget 1 -``` -┌──────────────────────────────────────────────────┐ -│ PAGE PROGRESS │ -│ │ -│ Total 45 Complete 28 (62%) │ -│ Queue 15 Processing 2 │ -│ │ -│ ████████████░░░░░░░░░ 62% Generated │ -│ │ -│ 💡 15 tasks in queue for content generation │ -└──────────────────────────────────────────────────┘ -``` - -#### Content Page - Widget 1 -``` -┌──────────────────────────────────────────────────┐ -│ PAGE PROGRESS │ -│ │ -│ Drafts 25 Has Images 17 (68%) │ -│ Total Words 12.5K Ready 17 │ -│ │ -│ █████████████░░░░░░░░ 68% Have Images │ -│ │ -│ 💡 8 drafts need images before review │ -└──────────────────────────────────────────────────┘ -``` - -### Widget 2: Module Stats (Same Widget Across Module Pages) - -Shows the **complete module overview** with actionable links. Same widget appears on all pages within a module. - -#### Planner Module - Widget 2 (shown on Keywords, Clusters, Ideas pages) -``` -┌──────────────────────────────────────────────────┐ -│ PLANNER MODULE │ -│ │ -│ Keywords ─────────────────────────────► Clusters │ -│ 46 Auto Cluster 12 │ -│ ████████████████████░░░ 91% │ -│ │ -│ Clusters ─────────────────────────────► Ideas │ -│ 12 Generate Ideas 34 │ -│ █████████████░░░░░░░░░ 67% │ -│ │ -│ Ideas ────────────────────────────────► Tasks │ -│ 34 Create Tasks 22 │ -│ █████████████░░░░░░░░░ 65% │ -│ │ -│ [→ Keywords] [→ Clusters] [→ Ideas] │ -└──────────────────────────────────────────────────┘ -``` - -#### Writer Module - Widget 2 (shown on Tasks, Content, Images, Review, Published pages) -``` -┌──────────────────────────────────────────────────┐ -│ WRITER MODULE │ -│ │ -│ Tasks ───────────────────────────────► Drafts │ -│ 45 Generate Content 28 │ -│ ████████████░░░░░░░░░ 62% │ -│ │ -│ Drafts ──────────────────────────────► Images │ -│ 28 Generate Images 17 │ -│ █████████████░░░░░░░░ 68% │ -│ │ -│ Ready ───────────────────────────────► Published │ -│ 17 Review & Publish 45 │ -│ ████████████████░░░░ 73% │ -│ │ -│ [→ Tasks] [→ Content] [→ Images] [→ Published] │ -└──────────────────────────────────────────────────┘ -``` - -### Widget 3: Both Modules Completion Stats - -Shows **completed items from both Planner and Writer** with time filter (7/30/90 days). - -``` -┌──────────────────────────────────────────────────┐ -│ WORKFLOW COMPLETION [7d] [30d] [90d] │ -│ │ -│ PLANNER │ -│ ├─ Keywords Clustered 42 ████████ │ -│ ├─ Clusters Created 12 ███ │ -│ └─ Ideas Generated 34 ███████ │ -│ │ -│ WRITER │ -│ ├─ Content Generated 28 ██████ │ -│ ├─ Images Created 127 █████████ │ -│ └─ Articles Published 45 █████████ │ -│ │ -│ Credits Used: 2,450 │ Operations: 156 │ -│ │ -│ [View Full Analytics →] │ -└──────────────────────────────────────────────────┘ -``` - -### Implementation Notes - -- Use existing `Card` component from `components/ui/card` -- Use existing `ProgressBar` component from `components/ui/progress` -- Use standard CSS tokens from `styles/tokens.css`: - - `--color-primary` for primary progress bars - - `--color-success` for completion indicators - - `--color-warning` for attention items -- Grid layout: `grid grid-cols-1 lg:grid-cols-3 gap-4` -- Compact padding: `p-4` instead of `p-6` - ---- - -## 4. Progress Modal Steps Audit - -### Current Issues -- Generic messages lacking context -- Missing counts where data is available -- Inconsistent terminology -- Not professional/polished - -### Recommended Progress Step Text - -#### Auto Cluster Keywords - -| Phase | Current | Recommended | -|-------|---------|-------------| -| INIT | Validating keywords | Validating {count} keywords for clustering | -| PREP | Loading keyword data | Analyzing keyword relationships | -| AI_CALL | Generating clusters with Igny8 Semantic SEO Model | Grouping keywords by search intent ({count} keywords) | -| PARSE | Organizing clusters | Organizing {cluster_count} semantic clusters | -| SAVE | Saving clusters | Saving {cluster_count} clusters with {keyword_count} keywords | -| DONE | Clustering complete! | ✓ Created {cluster_count} clusters from {keyword_count} keywords | - -#### Generate Ideas - -| Phase | Current | Recommended | -|-------|---------|-------------| -| INIT | Verifying cluster integrity | Analyzing {count} clusters for content opportunities | -| PREP | Loading cluster keywords | Mapping {keyword_count} keywords to topic briefs | -| AI_CALL | Generating ideas with Igny8 Semantic AI | Generating content ideas for {cluster_count} clusters | -| PARSE | High-opportunity ideas generated | Structuring {idea_count} article outlines | -| SAVE | Content Outline for Ideas generated | Saving {idea_count} content ideas with outlines | -| DONE | Ideas generated! | ✓ Generated {idea_count} content ideas from {cluster_count} clusters | - -#### Generate Content - -| Phase | Current | Recommended | -|-------|---------|-------------| -| INIT | Validating task | Preparing {count} article{s} for generation | -| PREP | Preparing content idea | Building content brief with {keyword_count} target keywords | -| AI_CALL | Writing article with Igny8 Semantic AI | Writing {count} article{s} (~{word_target} words each) | -| PARSE | Formatting content | Formatting HTML content and metadata | -| SAVE | Saving article | Saving {count} article{s} ({total_words} words) | -| DONE | Content generated! | ✓ {count} article{s} generated ({total_words} words total) | - -#### Generate Image Prompts - -| Phase | Current | Recommended | -|-------|---------|-------------| -| INIT | Checking content and image slots | Analyzing content for {count} image opportunities | -| PREP | Mapping content for image prompts | Identifying featured image and {in_article_count} in-article image slots | -| AI_CALL | Writing Featured Image Prompts | Creating optimized prompts for {count} images | -| PARSE | Writing In‑article Image Prompts | Refining {in_article_count} contextual image descriptions | -| SAVE | Assigning Prompts to Dedicated Slots | Assigning {count} prompts to image slots | -| DONE | Prompts generated! | ✓ {count} image prompts ready (1 featured + {in_article_count} in-article) | - -#### Generate Images from Prompts - -| Phase | Current | Recommended | -|-------|---------|-------------| -| INIT | Validating image prompts | Queuing {count} images for generation | -| PREP | Preparing image generation queue | Preparing AI image generation ({count} images) | -| AI_CALL | Generating images with AI | Generating image {current}/{count}... | -| PARSE | Processing image URLs | Processing {count} generated images | -| SAVE | Saving image URLs | Uploading {count} images to media library | -| DONE | Images generated! | ✓ {count} images generated and saved | - -### Success Message Templates (with counts) - -```typescript -// Clustering -`✓ Organized ${keywordCount} keywords into ${clusterCount} semantic clusters` - -// Ideas -`✓ Created ${ideaCount} content ideas with detailed outlines` - -// Content -`✓ Generated ${articleCount} articles (${totalWords.toLocaleString()} words)` - -// Image Prompts -`✓ Created prompts for ${imageCount} images (1 featured + ${inArticleCount} in-article)` - -// Image Generation -`✓ Generated and saved ${imageCount} AI images` -``` - ---- - -## 5. Dashboard Redesign Plan - -### Current Issues -- Too much whitespace and large headings -- Repeating same counts/metrics without different dimensions -- Missing actionable insights -- No AI operations analytics -- Missing "needs attention" items - -### New Dashboard Design: Multi-Dimension Compact Widgets - -Based on Django admin reports analysis, the dashboard should show **different data dimensions** instead of repeating counts: - -### Dashboard Layout (Compact, Information-Dense) - -``` -┌─────────────────────────────────────────────────────────────────────────────────────┐ -│ ⚠ NEEDS ATTENTION (collapsible, only shows if items exist) │ -│ ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐ │ -│ │ 3 pending review │ │ WP sync failed │ │ Setup incomplete │ │ -│ │ [Review →] │ │ [Retry] [Fix →] │ │ [Complete →] │ │ -│ └────────────────────┘ └────────────────────┘ └────────────────────┘ │ -├─────────────────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────────────────────────┐ ┌─────────────────────────────────────────┐ │ -│ │ WORKFLOW PIPELINE │ │ QUICK ACTIONS │ │ -│ │ │ │ │ │ -│ │ Sites → KWs → Clusters → Ideas │ │ [+ Keywords] [⚡ Cluster] [📝 Content] │ │ -│ │ 2 156 23 67 │ │ [🖼 Images] [✓ Review] [🚀 Publish] │ │ -│ │ ↓ │ │ │ │ -│ │ Tasks → Drafts → Published │ │ WORKFLOW GUIDE │ │ -│ │ 45 28 45 │ │ 1. Add Keywords 5. Generate Content │ │ -│ │ │ │ 2. Auto Cluster 6. Generate Images │ │ -│ │ ████████████░░░ 72% Complete │ │ 3. Generate Ideas 7. Review & Approve │ │ -│ │ │ │ 4. Create Tasks 8. Publish to WP │ │ -│ └─────────────────────────────────┘ │ [Full Help →] │ │ -│ └─────────────────────────────────────────┘ │ -│ │ -├─────────────────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────────────────────────┐ ┌─────────────────────────────────────────┐ │ -│ │ AI OPERATIONS (7d) [▼ 30d] │ │ RECENT ACTIVITY │ │ -│ │ │ │ │ │ -│ │ Operation Count Credits │ │ • Clustered 45 keywords → 8 clusters │ │ -│ │ ───────────────────────────────│ │ 2 hours ago │ │ -│ │ Clustering 8 80 │ │ • Generated 5 articles (4.2K words) │ │ -│ │ Ideas 12 24 │ │ 4 hours ago │ │ -│ │ Content 28 1,400 │ │ • Created 15 image prompts │ │ -│ │ Images 45 225 │ │ Yesterday │ │ -│ │ ───────────────────────────────│ │ • Published "Best Running Shoes" to WP │ │ -│ │ Total 93 1,729 │ │ Yesterday │ │ -│ │ │ │ • Added 23 keywords from seed DB │ │ -│ │ Success Rate: 98.5% │ │ 2 days ago │ │ -│ │ Avg Credits/Op: 18.6 │ │ │ │ -│ └─────────────────────────────────┘ │ [View All Activity →] │ │ -│ └─────────────────────────────────────────┘ │ -│ │ -├─────────────────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────────────────────────┐ ┌─────────────────────────────────────────┐ │ -│ │ CONTENT VELOCITY │ │ AUTOMATION STATUS │ │ -│ │ │ │ │ │ -│ │ This Week This Month Total │ │ ● Active │ Schedule: Daily 9 AM │ │ -│ │ │ │ │ │ -│ │ Articles 5 28 156 │ │ Last Run: Dec 27, 7:00 AM │ │ -│ │ Words 4.2K 24K 156K │ │ ├─ Clustered: 12 keywords │ │ -│ │ Images 12 67 340 │ │ ├─ Ideas: 8 generated │ │ -│ │ │ │ ├─ Content: 5 articles │ │ -│ │ 📈 +23% vs last week │ │ └─ Images: 15 created │ │ -│ │ │ │ │ │ -│ │ [View Analytics →] │ │ Next Run: Dec 28, 9:00 AM │ │ -│ └─────────────────────────────────┘ │ [Configure →] [Run Now →] │ │ -│ └─────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────────────────────┘ -``` - -### Widget Specifications - -#### 1. Needs Attention Bar -- Collapsible, only visible when items exist -- Types: `pending_review`, `sync_failed`, `setup_incomplete`, `automation_failed` -- Compact horizontal cards with action buttons - -#### 2. Workflow Pipeline Widget -- Visual flow: Sites → Keywords → Clusters → Ideas → Tasks → Drafts → Published -- Shows counts at each stage -- Single progress bar for overall completion -- Clickable stage names link to respective pages - -#### 3. Quick Actions + Workflow Guide Widget -- 2x3 grid of action buttons (use existing icons) -- Compact numbered workflow guide (1-8 steps) -- "Full Help" link to help page - -#### 4. AI Operations Widget (NEW - from Django Admin Reports) -Shows data from `CreditUsageLog` model: -```typescript -interface AIOperationsData { - period: '7d' | '30d' | '90d'; - operations: Array<{ - type: 'clustering' | 'ideas' | 'content' | 'images'; - count: number; - credits: number; - }>; - totals: { - count: number; - credits: number; - success_rate: number; - avg_credits_per_op: number; - }; -} -``` -- Time period filter (7d/30d/90d dropdown) -- Table with operation type, count, credits -- Success rate percentage -- Average credits per operation - -#### 5. Recent Activity Widget -Shows data from `AITaskLog` and `CreditUsageLog`: -- Last 5 significant operations -- Timestamp relative (2 hours ago, Yesterday) -- Clickable to navigate to relevant content -- "View All Activity" link - -#### 6. Content Velocity Widget (NEW) -Shows content production rates: -```typescript -interface ContentVelocityData { - this_week: { articles: number; words: number; images: number }; - this_month: { articles: number; words: number; images: number }; - total: { articles: number; words: number; images: number }; - trend: number; // percentage vs previous period -} -``` -- Three time columns: This Week, This Month, Total -- Rows: Articles, Words, Images -- Trend indicator vs previous period - -#### 7. Automation Status Widget -Shows automation run status: -- Current status indicator (Active/Paused/Failed) -- Schedule display -- Last run details with stage breakdown -- Next scheduled run -- Configure and Run Now buttons - -### API Endpoint Required - -```python -# GET /api/v1/dashboard/summary/ -{ - "needs_attention": [...], - "pipeline": { - "sites": 2, "keywords": 156, "clusters": 23, - "ideas": 67, "tasks": 45, "drafts": 28, "published": 45, - "completion_percentage": 72 - }, - "ai_operations": { - "period": "7d", - "operations": [...], - "totals": {...} - }, - "recent_activity": [...], - "content_velocity": {...}, - "automation": {...} -} -``` - -### Implementation Notes - -- Use existing components from `components/ui/` -- Use CSS tokens from `styles/tokens.css` -- Grid layout: `grid grid-cols-1 lg:grid-cols-2 gap-4` -- Compact widget padding: `p-4` -- No large headings - use subtle section labels - ---- - -## 6. Site Setup Checklist Implementation - -### Current Status -- ✅ `SiteSetupChecklist.tsx` component EXISTS -- ✅ Integrated in `Site Dashboard` page (full mode) -- ❌ **NOT integrated in `SiteCard.tsx`** (compact mode not used) - -### Missing Implementation - -The component has a `compact` prop but is not used in the site cards list. - -### Recommended Fix - -**File:** `frontend/src/components/sites/SiteCard.tsx` - -Add compact checklist to each site card: - -```tsx -// In SiteCard component, add after the status badges: - 0} - hasWordPressIntegration={!!site.wordpress_site_url} - hasKeywords={site.keywords_count > 0} - compact={true} -/> -``` - -**Visual Result:** -``` -┌─────────────────────────────────────────┐ -│ My Website [Active] │ -│ example.com │ -│ Industry: Tech │ 3 Sectors │ -│ ●●●○ 3/4 Setup Steps Complete │ ← NEW compact checklist -│ [Manage →] │ -└─────────────────────────────────────────┘ -``` - ---- - -## 7. To-Do-s Completion Audit - -### Summary by Section - -| Section | File | Status | Remaining Items | -|---------|------|--------|-----------------| -| Section 1 | `dashboard_mods.md` | 📋 Planned (do LAST) | Dashboard revamp, aggregated API | -| Section 2 | `SECTION_2_FINAL_MODS.md` | ✅ Done | - | -| Section 3 | `SECTION_3_FINAL_MODS.md` | ✅ Done | - | -| Section 4 | `SECTION_4_FINAL_MODS.md` | ✅ Done | - | -| Section 5 | `SECTION_5_FINAL_MODS.md` | ✅ Done | - | -| Section 6 | `SECTION_6_FINAL_MODS.md` | ✅ Done | - | - -**Note:** Plans, billing, credits, usage improvements moved to separate phase. - -### Remaining Items Detail - -#### Dashboard (Section 1) - Major Work -- [ ] Aggregated API endpoint `/v1/dashboard/summary/` -- [ ] NeedsAttention widget -- [ ] Real Recent Activity log (replace hardcoded) -- [ ] AI Operations widget (from CreditUsageLog) -- [ ] Content Velocity widget -- [ ] Automation Status display -- [ ] Contextual Quick Actions - -#### Cross-Module -- [ ] Notification bell dropdown with AI run logging -- [ ] 3-widget footer layout for Planner/Writer pages -- [ ] Improved tooltips for table action row metrics -- [ ] Site Setup Checklist on site cards (compact mode) - ---- - -## 8. Notification System Plan - -### Current State -- Bell icon exists with placeholder/mock notifications -- No real notification system or API -- No notification persistence - -### Comprehensive Notification System Design - -#### A. Notification Data Model - -```python -# backend/igny8_core/business/notifications/models.py - -class Notification(BaseModel): - account = models.ForeignKey('Account', on_delete=models.CASCADE) - user = models.ForeignKey('User', on_delete=models.CASCADE, null=True) # null = all users - - # Notification content - type = models.CharField(max_length=50, choices=NOTIFICATION_TYPES) - title = models.CharField(max_length=200) - message = models.TextField() - severity = models.CharField(max_length=20, choices=SEVERITY_CHOICES) - - # Related objects - site = models.ForeignKey('Site', null=True, on_delete=models.CASCADE) - content_type = models.ForeignKey(ContentType, null=True) - object_id = models.PositiveIntegerField(null=True) - content_object = GenericForeignKey() - - # Action - action_url = models.CharField(max_length=500, null=True) - action_label = models.CharField(max_length=50, null=True) - - # Status - is_read = models.BooleanField(default=False) - read_at = models.DateTimeField(null=True) - - created_at = models.DateTimeField(auto_now_add=True) - -NOTIFICATION_TYPES = [ - # AI Operations - ('ai_cluster_complete', 'Clustering Complete'), - ('ai_cluster_failed', 'Clustering Failed'), - ('ai_ideas_complete', 'Ideas Generated'), - ('ai_ideas_failed', 'Idea Generation Failed'), - ('ai_content_complete', 'Content Generated'), - ('ai_content_failed', 'Content Generation Failed'), - ('ai_images_complete', 'Images Generated'), - ('ai_images_failed', 'Image Generation Failed'), - - # Workflow - ('content_ready_review', 'Content Ready for Review'), - ('content_published', 'Content Published'), - ('content_publish_failed', 'Publishing Failed'), - - # WordPress Sync - ('wordpress_sync_success', 'WordPress Sync Complete'), - ('wordpress_sync_failed', 'WordPress Sync Failed'), - - # Credits/Billing - ('credits_low', 'Credits Running Low'), - ('credits_depleted', 'Credits Depleted'), - ('plan_upgraded', 'Plan Upgraded'), - - # Setup - ('site_setup_complete', 'Site Setup Complete'), - ('keywords_imported', 'Keywords Imported'), -] - -SEVERITY_CHOICES = [ - ('info', 'Info'), - ('success', 'Success'), - ('warning', 'Warning'), - ('error', 'Error'), -] -``` - -#### B. Notification Creation Points - -| Trigger Event | Notification Type | Severity | Title | Message Template | -|---------------|-------------------|----------|-------|------------------| -| Clustering completes | `ai_cluster_complete` | success | Clustering Complete | Created {count} clusters from {keyword_count} keywords | -| Clustering fails | `ai_cluster_failed` | error | Clustering Failed | Failed to cluster keywords: {error} | -| Ideas generated | `ai_ideas_complete` | success | Ideas Generated | Generated {count} content ideas from {cluster_count} clusters | -| Ideas failed | `ai_ideas_failed` | error | Idea Generation Failed | Failed to generate ideas: {error} | -| Content generated | `ai_content_complete` | success | Content Generated | Generated {count} articles ({word_count} words) | -| Content failed | `ai_content_failed` | error | Content Generation Failed | Failed to generate content: {error} | -| Images generated | `ai_images_complete` | success | Images Generated | Generated {count} images for your content | -| Images failed | `ai_images_failed` | error | Image Generation Failed | Failed to generate {count} images: {error} | -| Content published | `content_published` | success | Content Published | "{title}" published to {site_name} | -| Publish failed | `content_publish_failed` | error | Publishing Failed | Failed to publish "{title}": {error} | -| WP sync success | `wordpress_sync_success` | success | WordPress Synced | Synced {count} items with {site_name} | -| WP sync failed | `wordpress_sync_failed` | error | Sync Failed | WordPress sync failed for {site_name}: {error} | -| Credits at 80% | `credits_low` | warning | Credits Running Low | You've used 80% of your credits. Consider upgrading. | -| Credits at 90% | `credits_low` | warning | Credits Almost Depleted | Only 10% of credits remaining. Upgrade to continue. | -| Credits depleted | `credits_depleted` | error | Credits Depleted | Your credits are exhausted. Upgrade to continue. | -| Site setup done | `site_setup_complete` | success | Site Ready | {site_name} is fully configured and ready! | -| Keywords imported | `keywords_imported` | info | Keywords Imported | Added {count} keywords to {site_name} | - -#### C. API Endpoints - -```python -# GET /api/v1/notifications/ -# Returns paginated list, most recent first -{ - "count": 45, - "unread_count": 3, - "results": [ - { - "id": 123, - "type": "ai_content_complete", - "title": "Content Generated", - "message": "Generated 5 articles (4,500 words)", - "severity": "success", - "site": {"id": 1, "name": "My Blog"}, - "action_url": "/writer/content", - "action_label": "View Content", - "is_read": false, - "created_at": "2025-12-27T10:30:00Z" - } - ] -} - -# POST /api/v1/notifications/{id}/read/ -# Mark single notification as read - -# POST /api/v1/notifications/read-all/ -# Mark all notifications as read - -# DELETE /api/v1/notifications/{id}/ -# Delete notification -``` - -#### D. Frontend Integration - -##### NotificationDropdown Component Updates - -```tsx -// frontend/src/components/header/NotificationDropdown.tsx - -interface Notification { - id: number; - type: string; - title: string; - message: string; - severity: 'info' | 'success' | 'warning' | 'error'; - site?: { id: number; name: string }; - action_url?: string; - action_label?: string; - is_read: boolean; - created_at: string; -} - -// Features: -// - Fetch real notifications on mount -// - Poll every 30 seconds for new notifications -// - Show unread count badge on bell icon -// - Mark as read on click -// - Navigate to action_url on click -// - "Mark all read" button -// - "View all" link to full notifications page -``` - -##### Full Notifications Page - -Create `/account/notifications` page with: -- Full list of all notifications (paginated) -- Filter by type, severity, site -- Bulk actions (mark read, delete) -- Date range filtering - -#### E. Implementation Priority - -**Phase 1 (Core):** -1. Create Notification model -2. Create API endpoints -3. Hook AI functions to create notifications on complete/fail -4. Update NotificationDropdown to fetch real data - -**Phase 2 (Enhanced):** -1. Credit threshold notifications -2. WordPress sync notifications -3. Full notifications page -4. Email notifications (optional) - -**Phase 3 (Polish):** -1. Notification preferences -2. Push notifications -3. Real-time updates (WebSocket) - ---- - -## Implementation Roadmap - -### Priority Order - -1. **Site Setup Checklist on Cards** - Quick win, already built -2. **Table Action Row Tooltip Improvements** - Quick improvement -3. **Footer 3-Widget Layout** - Better workflow visibility -4. **Notification System** - High user value -5. **Progress Modal Text** - Polish -6. **Dashboard Redesign** - Major effort, do last - -### Estimated Effort - -| Item | Backend | Frontend | Total | -|------|---------|----------|-------| -| Site checklist on cards | 0h | 2h | 2h | -| Tooltip improvements | 0h | 4h | 4h | -| Footer 3-widget layout | 2h | 12h | 14h | -| Notification system | 8h | 8h | 16h | -| Progress modal text | 4h | 4h | 8h | -| Dashboard redesign | 8h | 16h | 24h | -| **Total** | **22h** | **46h** | **68h** | - ---- - -## Appendix: Current vs Recommended Comparison - -### Table Action Row Metrics (Already Implemented) - -**Current:** Shows metrics in table action row -``` -| Keywords 46 | Clustered 10 | Unmapped 0 | Volume 13.6K | -``` - -**Improvement:** Better actionable tooltips with guidance on next steps - -### Footer Metrics Example (Keywords Page) - -**Current:** Large cards with minimal info - -**Recommended:** 3-widget layout: -- Widget 1: Page metrics with combined progress bar -- Widget 2: Full Planner module stats with links -- Widget 3: Both modules completion stats with 7/30/90d filter - -### Dashboard Example - -**Current:** Hero banner + large sections + much whitespace + repeating counts - -**Recommended:** Compact info-dense layout with: -- Needs Attention bar (only if items exist) -- Workflow Pipeline + Quick Actions/Guide (2 columns) -- AI Operations stats + Recent Activity (2 columns) -- Content Velocity + Automation Status (2 columns) -- All visible without scrolling, different data dimensions - ---- - -## Technical Notes - -### Standard Components to Use - -From existing codebase: -- `components/ui/card` - Card component -- `components/ui/progress` - ProgressBar component -- `components/ui/button/Button` - Button component -- `components/ui/tooltip/Tooltip` - Tooltip component -- `components/ui/dropdown/Dropdown` - Dropdown component - -### Standard CSS Tokens - -From `styles/tokens.css`: -```css ---color-primary: #0693e3; /* Primary brand blue */ ---color-success: #0bbf87; /* Success green */ ---color-warning: #ff7a00; /* Warning orange */ ---color-danger: #ef4444; /* Danger red */ ---color-purple: #5d4ae3; /* Purple accent */ -``` - -### Do NOT Create - -- Inline duplicate styles -- New color variables outside tokens.css -- Duplicate component implementations -- Styles in igny8-colors.css (use tokens.css) diff --git a/backend/igny8_core/ai/ai_core.py b/backend/igny8_core/ai/ai_core.py index cd105a65..eb220ce9 100644 --- a/backend/igny8_core/ai/ai_core.py +++ b/backend/igny8_core/ai/ai_core.py @@ -87,13 +87,13 @@ class AICore: response_format: Optional[Dict] = None, api_key: Optional[str] = None, function_name: str = 'ai_request', - function_id: Optional[str] = None, + prompt_prefix: Optional[str] = None, tracker: Optional[ConsoleStepTracker] = None ) -> Dict[str, Any]: """ Centralized AI request handler with console logging. All AI text generation requests go through this method. - + Args: prompt: Prompt text model: Model name (required - must be provided from IntegrationSettings) @@ -102,12 +102,13 @@ class AICore: response_format: Optional response format dict (for JSON mode) api_key: Optional API key override function_name: Function name for logging (e.g., 'cluster_keywords') + prompt_prefix: Optional prefix to add before prompt (e.g., '##GP01-Clustering') tracker: Optional ConsoleStepTracker instance for logging - + Returns: Dict with 'content', 'input_tokens', 'output_tokens', 'total_tokens', 'model', 'cost', 'error', 'api_id' - + Raises: ValueError: If model is not provided """ @@ -184,16 +185,16 @@ class AICore: else: tracker.ai_call("Using text response format") - # Step 4: Validate prompt length and add function_id + # Step 4: Validate prompt length and add prompt_prefix prompt_length = len(prompt) tracker.ai_call(f"Prompt length: {prompt_length} characters") - - # Add function_id to prompt if provided (for tracking) + + # Add prompt_prefix to prompt if provided (for tracking) + # Format: ##GP01-Clustering or ##CP01-Clustering final_prompt = prompt - if function_id: - function_id_prefix = f'function_id: "{function_id}"\n\n' - final_prompt = function_id_prefix + prompt - tracker.ai_call(f"Added function_id to prompt: {function_id}") + if prompt_prefix: + final_prompt = f'{prompt_prefix}\n\n{prompt}' + tracker.ai_call(f"Added prompt prefix: {prompt_prefix}") # Step 5: Build request payload url = 'https://api.openai.com/v1/chat/completions' diff --git a/backend/igny8_core/ai/engine.py b/backend/igny8_core/ai/engine.py index 99892b2d..932e8b58 100644 --- a/backend/igny8_core/ai/engine.py +++ b/backend/igny8_core/ai/engine.py @@ -306,12 +306,13 @@ class AIEngine: ai_core = AICore(account=self.account) function_name = fn.get_name() - - # Generate function_id for tracking (ai-{function_name}-01) - # Normalize underscores to hyphens to match frontend tracking IDs - function_id_base = function_name.replace('_', '-') - function_id = f"ai-{function_id_base}-01-desktop" - + + # Generate prompt prefix for tracking (e.g., ##GP01-Clustering or ##CP01-Clustering) + # This replaces function_id and indicates whether prompt is global or custom + from igny8_core.ai.prompts import get_prompt_prefix_for_function + prompt_prefix = get_prompt_prefix_for_function(function_name, account=self.account) + logger.info(f"[AIEngine] Using prompt prefix: {prompt_prefix}") + # Get model config from settings (requires account) # This will raise ValueError if IntegrationSettings not configured try: @@ -349,7 +350,7 @@ class AIEngine: temperature=model_config.get('temperature'), response_format=model_config.get('response_format'), function_name=function_name, - function_id=function_id # Pass function_id for tracking + prompt_prefix=prompt_prefix # Pass prompt prefix for tracking (replaces function_id) ) except Exception as e: error_msg = f"AI call failed: {str(e)}" diff --git a/backend/igny8_core/ai/prompts.py b/backend/igny8_core/ai/prompts.py index 8d021f7c..6012bfac 100644 --- a/backend/igny8_core/ai/prompts.py +++ b/backend/igny8_core/ai/prompts.py @@ -3,7 +3,7 @@ Prompt Registry - Centralized prompt management with override hierarchy Supports: task-level overrides → DB prompts → GlobalAIPrompt (REQUIRED) """ import logging -from typing import Dict, Any, Optional +from typing import Dict, Any, Optional, Tuple from django.db import models logger = logging.getLogger(__name__) @@ -16,10 +16,10 @@ class PromptRegistry: 2. DB prompt for (account, function) 3. GlobalAIPrompt (REQUIRED - no hardcoded fallbacks) """ - + # Removed ALL hardcoded prompts - GlobalAIPrompt is now the ONLY source of default prompts # To add/modify prompts, use Django admin: /admin/system/globalaiprompt/ - + # Mapping from function names to prompt types FUNCTION_TO_PROMPT_TYPE = { 'auto_cluster': 'clustering', @@ -35,7 +35,114 @@ class PromptRegistry: 'generate_service_page': 'service_generation', 'generate_taxonomy': 'taxonomy_generation', } + + # Mapping of prompt types to their prefix numbers and display names + # Format: {prompt_type: (number, display_name)} + # GP = Global Prompt, CP = Custom Prompt + PROMPT_PREFIX_MAP = { + 'clustering': ('01', 'Clustering'), + 'ideas': ('02', 'Ideas'), + 'content_generation': ('03', 'ContentGen'), + 'image_prompt_extraction': ('04', 'ImagePrompts'), + 'site_structure_generation': ('05', 'SiteStructure'), + 'optimize_content': ('06', 'OptimizeContent'), + 'product_generation': ('07', 'ProductGen'), + 'service_generation': ('08', 'ServiceGen'), + 'taxonomy_generation': ('09', 'TaxonomyGen'), + 'image_prompt_template': ('10', 'ImageTemplate'), + 'negative_prompt': ('11', 'NegativePrompt'), + } + @classmethod + def get_prompt_prefix(cls, prompt_type: str, is_custom: bool) -> str: + """ + Generate prompt prefix for tracking. + + Args: + prompt_type: The prompt type (e.g., 'clustering', 'ideas') + is_custom: True if using custom/account-specific prompt, False if global + + Returns: + Prefix string like "##GP01-Clustering" or "##CP01-Clustering" + """ + prefix_info = cls.PROMPT_PREFIX_MAP.get(prompt_type, ('00', prompt_type.title())) + number, display_name = prefix_info + prefix_type = 'CP' if is_custom else 'GP' + return f"##{prefix_type}{number}-{display_name}" + + @classmethod + def get_prompt_with_metadata( + cls, + function_name: str, + account: Optional[Any] = None, + task: Optional[Any] = None, + context: Optional[Dict[str, Any]] = None + ) -> Tuple[str, bool, str]: + """ + Get prompt for a function with metadata about source. + + Priority: + 1. task.prompt_override (if task provided and has override) + 2. DB prompt for (account, function) - marked as custom if is_customized=True + 3. GlobalAIPrompt (REQUIRED - no hardcoded fallbacks) + + Args: + function_name: AI function name (e.g., 'auto_cluster', 'generate_ideas') + account: Account object (optional) + task: Task object with optional prompt_override (optional) + context: Additional context for prompt rendering (optional) + + Returns: + Tuple of (prompt_string, is_custom, prompt_type) + - prompt_string: The rendered prompt + - is_custom: True if using custom/account prompt, False if global + - prompt_type: The prompt type identifier + """ + # Step 1: Get prompt type + prompt_type = cls.FUNCTION_TO_PROMPT_TYPE.get(function_name, function_name) + + # Step 2: Check task-level override (always considered custom) + if task and hasattr(task, 'prompt_override') and task.prompt_override: + logger.info(f"Using task-level prompt override for {function_name}") + prompt = task.prompt_override + return cls._render_prompt(prompt, context or {}), True, prompt_type + + # Step 3: Try DB prompt (account-specific) + if account: + try: + from igny8_core.modules.system.models import AIPrompt + db_prompt = AIPrompt.objects.get( + account=account, + prompt_type=prompt_type, + is_active=True + ) + # Check if prompt is customized + is_custom = db_prompt.is_customized + logger.info(f"Using {'customized' if is_custom else 'default'} account prompt for {function_name} (account {account.id})") + prompt = db_prompt.prompt_value + return cls._render_prompt(prompt, context or {}), is_custom, prompt_type + except Exception as e: + logger.debug(f"No account-specific prompt found for {function_name}: {e}") + + # Step 4: Try GlobalAIPrompt (platform-wide default) - REQUIRED + try: + from igny8_core.modules.system.global_settings_models import GlobalAIPrompt + global_prompt = GlobalAIPrompt.objects.get( + prompt_type=prompt_type, + is_active=True + ) + logger.info(f"Using global default prompt for {function_name} from GlobalAIPrompt") + prompt = global_prompt.prompt_value + return cls._render_prompt(prompt, context or {}), False, prompt_type + except Exception as e: + error_msg = ( + f"ERROR: Global prompt '{prompt_type}' not found for function '{function_name}'. " + f"Please configure it in Django admin at: /admin/system/globalaiprompt/. " + f"Error: {e}" + ) + logger.error(error_msg) + raise ValueError(error_msg) + @classmethod def get_prompt( cls, @@ -46,63 +153,23 @@ class PromptRegistry: ) -> str: """ Get prompt for a function with hierarchical resolution. - + Priority: 1. task.prompt_override (if task provided and has override) 2. DB prompt for (account, function) 3. GlobalAIPrompt (REQUIRED - no hardcoded fallbacks) - + Args: function_name: AI function name (e.g., 'auto_cluster', 'generate_ideas') account: Account object (optional) task: Task object with optional prompt_override (optional) context: Additional context for prompt rendering (optional) - + Returns: Prompt string ready for formatting """ - # Step 1: Check task-level override - if task and hasattr(task, 'prompt_override') and task.prompt_override: - logger.info(f"Using task-level prompt override for {function_name}") - prompt = task.prompt_override - return cls._render_prompt(prompt, context or {}) - - # Step 2: Get prompt type - prompt_type = cls.FUNCTION_TO_PROMPT_TYPE.get(function_name, function_name) - - # Step 3: Try DB prompt (account-specific) - if account: - try: - from igny8_core.modules.system.models import AIPrompt - db_prompt = AIPrompt.objects.get( - account=account, - prompt_type=prompt_type, - is_active=True - ) - logger.info(f"Using account-specific prompt for {function_name} (account {account.id})") - prompt = db_prompt.prompt_value - return cls._render_prompt(prompt, context or {}) - except Exception as e: - logger.debug(f"No account-specific prompt found for {function_name}: {e}") - - # Step 4: Try GlobalAIPrompt (platform-wide default) - REQUIRED - try: - from igny8_core.modules.system.global_settings_models import GlobalAIPrompt - global_prompt = GlobalAIPrompt.objects.get( - prompt_type=prompt_type, - is_active=True - ) - logger.info(f"Using global default prompt for {function_name} from GlobalAIPrompt") - prompt = global_prompt.prompt_value - return cls._render_prompt(prompt, context or {}) - except Exception as e: - error_msg = ( - f"ERROR: Global prompt '{prompt_type}' not found for function '{function_name}'. " - f"Please configure it in Django admin at: /admin/system/globalaiprompt/. " - f"Error: {e}" - ) - logger.error(error_msg) - raise ValueError(error_msg) + prompt, _, _ = cls.get_prompt_with_metadata(function_name, account, task, context) + return prompt @classmethod def _render_prompt(cls, prompt_template: str, context: Dict[str, Any]) -> str: @@ -219,3 +286,61 @@ def get_prompt(function_name: str, account=None, task=None, context=None) -> str """Get prompt using registry""" return PromptRegistry.get_prompt(function_name, account=account, task=task, context=context) + +def get_prompt_with_prefix(function_name: str, account=None, task=None, context=None) -> Tuple[str, str]: + """ + Get prompt with its tracking prefix. + + Args: + function_name: AI function name + account: Account object (optional) + task: Task object with optional prompt_override (optional) + context: Additional context for prompt rendering (optional) + + Returns: + Tuple of (prompt_string, prefix_string) + - prompt_string: The rendered prompt + - prefix_string: The tracking prefix (e.g., '##GP01-Clustering' or '##CP01-Clustering') + """ + prompt, is_custom, prompt_type = PromptRegistry.get_prompt_with_metadata( + function_name, account=account, task=task, context=context + ) + prefix = PromptRegistry.get_prompt_prefix(prompt_type, is_custom) + return prompt, prefix + + +def get_prompt_prefix_for_function(function_name: str, account=None, task=None) -> str: + """ + Get just the prefix for a function without fetching the full prompt. + Useful when the prompt was already fetched elsewhere. + + Args: + function_name: AI function name + account: Account object (optional) + task: Task object with optional prompt_override (optional) + + Returns: + The tracking prefix (e.g., '##GP01-Clustering' or '##CP01-Clustering') + """ + prompt_type = PromptRegistry.FUNCTION_TO_PROMPT_TYPE.get(function_name, function_name) + + # Check for task-level override (always custom) + if task and hasattr(task, 'prompt_override') and task.prompt_override: + return PromptRegistry.get_prompt_prefix(prompt_type, is_custom=True) + + # Check for account-specific prompt + if account: + try: + from igny8_core.modules.system.models import AIPrompt + db_prompt = AIPrompt.objects.get( + account=account, + prompt_type=prompt_type, + is_active=True + ) + return PromptRegistry.get_prompt_prefix(prompt_type, is_custom=db_prompt.is_customized) + except Exception: + pass + + # Fallback to global (not custom) + return PromptRegistry.get_prompt_prefix(prompt_type, is_custom=False) + diff --git a/backend/igny8_core/business/content/models.py b/backend/igny8_core/business/content/models.py index 4f9dc600..5e7f7085 100644 --- a/backend/igny8_core/business/content/models.py +++ b/backend/igny8_core/business/content/models.py @@ -119,10 +119,40 @@ class Tasks(SoftDeletableModel, SiteSectorBaseModel): objects = SoftDeleteManager() all_objects = models.Manager() - + def __str__(self): return self.title + def soft_delete(self, user=None, reason=None, retention_days=None): + """ + Override soft_delete to cascade to related models. + This ensures Images and ContentClusterMap are also deleted when a Task is deleted. + """ + import logging + logger = logging.getLogger(__name__) + + # Soft-delete related Images (which are also SoftDeletable) + related_images = self.images.filter(is_deleted=False) + images_count = related_images.count() + for image in related_images: + image.soft_delete(user=user, reason=f"Parent task deleted: {reason or 'No reason'}") + + # Hard-delete ContentClusterMap (not soft-deletable) + cluster_maps_count = self.cluster_mappings.count() + self.cluster_mappings.all().delete() + + # Hard-delete ContentAttribute (not soft-deletable) + attributes_count = self.attribute_mappings.count() + self.attribute_mappings.all().delete() + + logger.info( + f"[Tasks.soft_delete] Task {self.id} '{self.title}' cascade delete: " + f"{images_count} images, {cluster_maps_count} cluster maps, {attributes_count} attributes" + ) + + # Call parent soft_delete + super().soft_delete(user=user, reason=reason, retention_days=retention_days) + class ContentTaxonomyRelation(models.Model): """Through model for Content-Taxonomy many-to-many relationship""" @@ -326,6 +356,61 @@ class Content(SoftDeletableModel, SiteSectorBaseModel): logger = logging.getLogger(__name__) logger.error(f"Error incrementing word usage for content {self.id}: {str(e)}") + def soft_delete(self, user=None, reason=None, retention_days=None): + """ + Override soft_delete to cascade to related models. + This ensures Images, ContentClusterMap, ContentAttribute are also deleted. + """ + import logging + logger = logging.getLogger(__name__) + + # Soft-delete related Images (which are also SoftDeletable) + related_images = self.images.filter(is_deleted=False) + images_count = related_images.count() + for image in related_images: + image.soft_delete(user=user, reason=f"Parent content deleted: {reason or 'No reason'}") + + # Hard-delete ContentClusterMap (not soft-deletable) + cluster_maps_count = self.cluster_mappings.count() + self.cluster_mappings.all().delete() + + # Hard-delete ContentAttribute (not soft-deletable) + attributes_count = self.attributes.count() + self.attributes.all().delete() + + # Hard-delete ContentTaxonomyRelation (through model for many-to-many) + taxonomy_relations_count = ContentTaxonomyRelation.objects.filter(content=self).count() + ContentTaxonomyRelation.objects.filter(content=self).delete() + + logger.info( + f"[Content.soft_delete] Content {self.id} '{self.title}' cascade delete: " + f"{images_count} images, {cluster_maps_count} cluster maps, " + f"{attributes_count} attributes, {taxonomy_relations_count} taxonomy relations" + ) + + # Call parent soft_delete + super().soft_delete(user=user, reason=reason, retention_days=retention_days) + + def hard_delete(self, using=None, keep_parents=False): + """ + Override hard_delete to cascade to related models. + Django CASCADE should handle this, but we explicitly clean up for safety. + """ + import logging + logger = logging.getLogger(__name__) + + # Hard-delete related Images (including soft-deleted ones) + images_count = Images.all_objects.filter(content=self).count() + Images.all_objects.filter(content=self).delete() + + logger.info( + f"[Content.hard_delete] Content {self.id} '{self.title}' hard delete: " + f"{images_count} images removed" + ) + + # Call parent hard_delete (Django CASCADE will handle the rest) + return super().hard_delete(using=using, keep_parents=keep_parents) + class ContentTaxonomy(SiteSectorBaseModel): """ diff --git a/backend/igny8_core/utils/ai_processor.py b/backend/igny8_core/utils/ai_processor.py index f2697d53..fa64e201 100644 --- a/backend/igny8_core/utils/ai_processor.py +++ b/backend/igny8_core/utils/ai_processor.py @@ -121,14 +121,14 @@ class AIProcessor: temperature: float = 0.7, response_format: Optional[Dict] = None, api_key: Optional[str] = None, - function_id: Optional[str] = None, + prompt_prefix: Optional[str] = None, response_steps=None ) -> Dict[str, Any]: """ Internal method to call OpenAI API. EXACT match to reference plugin's igny8_call_openai() function. Endpoint: https://api.openai.com/v1/chat/completions - + Returns: Dict with 'content', 'input_tokens', 'output_tokens', 'total_tokens', 'model', 'cost', 'error', 'api_id' """ @@ -159,12 +159,12 @@ class AIProcessor: 'Content-Type': 'application/json', } - # Add function_id to prompt if provided (for tracking) + # Add prompt_prefix to prompt if provided (for tracking) + # Format: ##GP01-Clustering or ##CP01-Clustering final_prompt = prompt - if function_id: - function_id_prefix = f'function_id: "{function_id}"\n\n' - final_prompt = function_id_prefix + prompt - logger.info(f"Added function_id to prompt: {function_id}") + if prompt_prefix: + final_prompt = f'{prompt_prefix}\n\n{prompt}' + logger.info(f"Added prompt prefix: {prompt_prefix}") # EXACT request format from reference plugin (openai-api.php line 402-404) body_data = { @@ -463,13 +463,15 @@ class AIProcessor: Returns: Dict with 'content', 'tokens_used', 'model', 'cost', 'error' """ - # Generate function_id for tracking (ai-generate-content-03 for AIProcessor path) - function_id = "ai-generate-content-03" + # Generate prompt prefix for tracking (e.g., ##GP03-ContentGen or ##CP03-ContentGen) + from igny8_core.ai.prompts import get_prompt_prefix_for_function + prompt_prefix = get_prompt_prefix_for_function('generate_content', account=self.account) + # Get response_format from settings for generate_content from igny8_core.ai.settings import get_model_config - model_config = get_model_config('generate_content') + model_config = get_model_config('generate_content', account=self.account) response_format = model_config.get('response_format') - result = self._call_openai(prompt, model, max_tokens, temperature, response_format=response_format, function_id=function_id) + result = self._call_openai(prompt, model, max_tokens, temperature, response_format=response_format, prompt_prefix=prompt_prefix) return { 'content': result.get('content', ''), diff --git a/docs/fixes/footer-widget-pagination-fix.md b/docs/fixes/footer-widget-pagination-fix.md new file mode 100644 index 00000000..e095691f --- /dev/null +++ b/docs/fixes/footer-widget-pagination-fix.md @@ -0,0 +1,193 @@ +# Footer Widget Pagination Fix - Summary + +## Problem + +All pages with `ThreeWidgetFooter` are calculating metrics using **page-filtered arrays** instead of **total counts** from the API. This causes incorrect metric values when users are viewing paginated results. + +### Example: +- If there are 100 total keywords with 10 on the current page +- And 5 keywords on the current page don't have a `cluster_id` +- The footer shows "Unmapped: 5" instead of the actual total unmapped count + +## Root Cause + +The footer widgets use JavaScript `.filter()` methods on the local `items` array (which only contains the current page's data) instead of making separate API calls to get total counts for each status. + +```typescript +// WRONG - Uses page-filtered array +{ label: 'Unmapped', value: keywords.filter(k => !k.cluster_id).length } + +// CORRECT - Uses total count from API +{ label: 'Unmapped', value: totalUnmapped } +``` + +## Solution Pattern + +For each affected page: + +1. **Add state variables for total counts** +2. **Create a `loadTotalMetrics()` function** that makes lightweight API calls (page_size=1) filtered by status +3. **Call `loadTotalMetrics()` when site/sector changes** +4. **Update footer widget** to use the total count state instead of filtering local arrays + +## Files Fixed + +### ✅ 1. Keywords.tsx +- Added: `totalClustered`, `totalUnmapped`, `totalVolume` state +- Added: `loadTotalMetrics()` function +- Updated: Footer widget to use total counts + +### ✅ 2. Clusters.tsx +- Added: `totalWithIdeas`, `totalReady` state +- Added: `loadTotalMetrics()` function +- Updated: Footer widget to use total counts + +### ⏳ 3. Ideas.tsx +- **TODO**: Add `totalInTasks`, `totalPending` state +- **TODO**: Add `loadTotalMetrics()` function with calls to: + - `fetchContentIdeas({ status: 'queued' })` → `totalInTasks` + - `fetchContentIdeas({ status: 'new' })` → `totalPending` +- **TODO**: Update footer widget metrics + +### ⏳ 4. Tasks.tsx +- **TODO**: Add total count state variables +- **TODO**: Add `loadTotalMetrics()` function +- **TODO**: Update footer widget + +### ⏳ 5. Content.tsx +- **TODO**: Add total count state variables for each status (draft, review, approved) +- **TODO**: Add `loadTotalMetrics()` function +- **TODO**: Update footer widget + +### ⏳ 6. Images.tsx +- **TODO**: Add total count state variables +- **TODO**: Add `loadTotalMetrics()` function +- **TODO**: Update footer widget + +### ⏳ 7. Review.tsx +- **TODO**: Add total count state variables +- **TODO**: Add `loadTotalMetrics()` function +- **TODO**: Update footer widget + +### ⏳ 8. Approved.tsx +- **TODO**: Add total count state variables +- **TODO**: Add `loadTotalMetrics()` function +- **TODO**: Update footer widget + +## Implementation Template + +### Step 1: Add State Variables + +```typescript +// Total counts for footer widget (not page-filtered) +const [totalWithStatus1, setTotalWithStatus1] = useState(0); +const [totalWithStatus2, setTotalWithStatus2] = useState(0); +``` + +### Step 2: Create loadTotalMetrics Function + +```typescript +// Load total metrics for footer widget (not affected by pagination) +const loadTotalMetrics = useCallback(async () => { + if (!activeSite) return; + + try { + // Get items with status1 + const status1Res = await fetchItems({ + page_size: 1, + site_id: activeSite.id, + ...(activeSector?.id && { sector_id: activeSector.id }), + status: 'status1', + }); + setTotalWithStatus1(status1Res.count || 0); + + // Get items with status2 + const status2Res = await fetchItems({ + page_size: 1, + site_id: activeSite.id, + ...(activeSector?.id && { sector_id: activeSector.id }), + status: 'status2', + }); + setTotalWithStatus2(status2Res.count || 0); + } catch (error) { + console.error('Error loading total metrics:', error); + } +}, [activeSite, activeSector]); +``` + +### Step 3: Call on Mount/Change + +```typescript +// Load total metrics when site/sector changes +useEffect(() => { + loadTotalMetrics(); +}, [loadTotalMetrics]); +``` + +### Step 4: Update Footer Widget + +```typescript + 0 ? Math.round((totalWithStatus1 / totalCount) * 100) : 0}%` }, + { label: 'Status 2', value: totalWithStatus2 }, + ], + progress: { + value: totalCount > 0 ? Math.round((totalWithStatus1 / totalCount) * 100) : 0, + label: 'Processed', + color: 'blue', + }, + hint: totalWithStatus2 > 0 + ? `${totalWithStatus2} items ready for processing` + : 'All items processed!', + }} + // ... rest of props +/> +``` + +## Testing Checklist + +For each fixed page, verify: + +- [ ] Footer metrics show correct total counts (not page counts) +- [ ] Metrics update when changing sites +- [ ] Metrics update when changing sectors +- [ ] Metrics are consistent with automation page metrics +- [ ] Performance is acceptable (lightweight API calls with page_size=1) + +## Related Files + +- `/frontend/src/components/dashboard/ThreeWidgetFooter.tsx` +- `/frontend/src/pages/Automation/AutomationPage.tsx` (reference implementation) +- All planner and writer page files + +## API Endpoints Used + +All pages use their respective `fetch*` functions with filters: +- `fetchKeywords({ status, page_size: 1 })` +- `fetchClusters({ status, page_size: 1 })` +- `fetchContentIdeas({ status, page_size: 1 })` +- `fetchTasks({ status, page_size: 1 })` +- `fetchContent({ status, page_size: 1 })` +- `fetchContentImages({ status, page_size: 1 })` + +The `page_size: 1` ensures minimal data transfer while still getting the count. + +## Performance Considerations + +- Each page makes 2-3 additional API calls on load +- Calls are lightweight (page_size=1, only count is used) +- Calls are cached until site/sector changes +- Total overhead: ~100-300ms per page load (acceptable) + +## Automation Page Consistency + +The AutomationPage already uses this pattern correctly: +- Lines 99-149: Fetches total counts for all metrics +- Uses `fetchKeywords({ status: 'new' })`, `fetchKeywords({ status: 'mapped' })`, etc. +- Sets metrics in state: `setMetrics({ keywords: { total, new, mapped } })` +- All stage cards and metric cards use these pre-fetched totals + +This fix brings all other pages in line with the Automation page's correct implementation. diff --git a/docs/plans/flexible-model-configuration-plan.md b/docs/plans/flexible-model-configuration-plan.md new file mode 100644 index 00000000..5a02e435 --- /dev/null +++ b/docs/plans/flexible-model-configuration-plan.md @@ -0,0 +1,311 @@ +# Flexible Model Configuration System Plan + +## Overview + +This plan outlines how to implement a flexible model configuration system that allows: +- Adding/removing/activating models dynamically +- Configuring rates for each model +- Supporting multiple providers (OpenAI, Anthropic, Runware) +- Per-account model overrides + +## Current State + +### Model Rates (hardcoded in `ai/constants.py`) +```python +MODEL_RATES = { + 'gpt-4.1': {'input': 2.00, 'output': 8.00}, # per 1M tokens + 'gpt-4o-mini': {'input': 0.15, 'output': 0.60}, + 'gpt-4o': {'input': 2.50, 'output': 10.00}, + 'gpt-5.1': {'input': 1.25, 'output': 10.00}, + 'gpt-5.2': {'input': 1.75, 'output': 14.00}, +} + +IMAGE_MODEL_RATES = { + 'dall-e-3': 0.040, # per image + 'dall-e-2': 0.020, + 'gpt-image-1': 0.042, + 'gpt-image-1-mini': 0.011, +} +``` + +### Current Settings Architecture +- `GlobalIntegrationSettings` (singleton) - Platform-wide API keys and defaults +- `IntegrationSettings` (per-account) - Model/parameter overrides +- `GlobalAIPrompt` - Platform-wide prompt templates +- `AIPrompt` (per-account) - Custom prompt overrides + +## Proposed Changes + +### Phase 1: Database Model for AI Models + +Create a new model `AIModel` to store model configurations: + +```python +# backend/igny8_core/modules/system/global_settings_models.py + +class AIModel(models.Model): + """ + Dynamic AI model configuration. + Replaces hardcoded MODEL_RATES and IMAGE_MODEL_RATES. + """ + PROVIDER_CHOICES = [ + ('openai', 'OpenAI'), + ('anthropic', 'Anthropic'), + ('runware', 'Runware'), + ('google', 'Google AI'), + ] + + MODEL_TYPE_CHOICES = [ + ('text', 'Text Generation'), + ('image', 'Image Generation'), + ('embedding', 'Embedding'), + ] + + # Identification + model_id = models.CharField( + max_length=100, + unique=True, + help_text="Model identifier (e.g., 'gpt-4o-mini', 'claude-3-sonnet')" + ) + display_name = models.CharField( + max_length=200, + help_text="User-friendly name (e.g., 'GPT-4o Mini')" + ) + provider = models.CharField(max_length=50, choices=PROVIDER_CHOICES) + model_type = models.CharField(max_length=20, choices=MODEL_TYPE_CHOICES) + + # Pricing (per 1M tokens for text, per image for image models) + input_rate = models.DecimalField( + max_digits=10, + decimal_places=4, + default=0, + help_text="Cost per 1M input tokens (text) or per request (image)" + ) + output_rate = models.DecimalField( + max_digits=10, + decimal_places=4, + default=0, + help_text="Cost per 1M output tokens (text only)" + ) + + # Capabilities + max_tokens = models.IntegerField( + default=8192, + help_text="Maximum tokens for this model" + ) + supports_json_mode = models.BooleanField( + default=True, + help_text="Whether model supports JSON response format" + ) + supports_vision = models.BooleanField( + default=False, + help_text="Whether model supports image input" + ) + + # Status + is_active = models.BooleanField(default=True) + is_default = models.BooleanField( + default=False, + help_text="Use as default when no specific model is configured" + ) + sort_order = models.IntegerField(default=0) + + # Metadata + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = 'igny8_ai_models' + ordering = ['sort_order', 'display_name'] + + def __str__(self): + return f"{self.display_name} ({self.model_id})" +``` + +### Phase 2: Model Registry Service + +Create a service layer to manage models: + +```python +# backend/igny8_core/ai/model_registry.py + +class ModelRegistry: + """ + Central registry for AI model configurations. + Provides caching and fallback logic. + """ + + _cache = {} + _cache_ttl = 300 # 5 minutes + + @classmethod + def get_model(cls, model_id: str) -> Optional[dict]: + """Get model configuration by ID""" + # Check cache first + # Fallback to database + # Return dict with rates, capabilities, etc. + pass + + @classmethod + def get_models_by_type(cls, model_type: str) -> List[dict]: + """Get all active models of a type""" + pass + + @classmethod + def get_default_model(cls, model_type: str = 'text') -> dict: + """Get default model for a type""" + pass + + @classmethod + def calculate_cost( + cls, + model_id: str, + input_tokens: int = 0, + output_tokens: int = 0, + image_count: int = 0 + ) -> float: + """Calculate cost for an operation""" + pass + + @classmethod + def is_model_supported(cls, model_id: str) -> bool: + """Check if a model is configured and active""" + pass +``` + +### Phase 3: Update AICore to Use Registry + +Modify `ai_core.py` to use the model registry: + +```python +# In run_ai_request() +from igny8_core.ai.model_registry import ModelRegistry + +# Replace hardcoded MODEL_RATES check +if not ModelRegistry.is_model_supported(model): + supported = ModelRegistry.get_models_by_type('text') + error_msg = f"Model '{model}' is not supported. Available models: {[m['model_id'] for m in supported]}" + # ... + +# Replace hardcoded cost calculation +model_info = ModelRegistry.get_model(model) +if model_info: + cost = ModelRegistry.calculate_cost( + model_id=model, + input_tokens=input_tokens, + output_tokens=output_tokens + ) +``` + +### Phase 4: Admin Interface + +Add Django admin for managing models: + +```python +# backend/igny8_core/modules/system/admin.py + +@admin.register(AIModel) +class AIModelAdmin(admin.ModelAdmin): + list_display = ['model_id', 'display_name', 'provider', 'model_type', 'input_rate', 'output_rate', 'is_active', 'is_default'] + list_filter = ['provider', 'model_type', 'is_active', 'is_default'] + search_fields = ['model_id', 'display_name'] + ordering = ['sort_order', 'display_name'] + + fieldsets = ( + ('Identification', { + 'fields': ('model_id', 'display_name', 'provider', 'model_type') + }), + ('Pricing', { + 'fields': ('input_rate', 'output_rate') + }), + ('Capabilities', { + 'fields': ('max_tokens', 'supports_json_mode', 'supports_vision') + }), + ('Status', { + 'fields': ('is_active', 'is_default', 'sort_order') + }), + ) +``` + +### Phase 5: Data Migration + +Create a migration to seed initial models: + +```python +# Migration file +def seed_initial_models(apps, schema_editor): + AIModel = apps.get_model('system', 'AIModel') + + models = [ + # OpenAI Text Models + {'model_id': 'gpt-4o-mini', 'display_name': 'GPT-4o Mini', 'provider': 'openai', 'model_type': 'text', 'input_rate': 0.15, 'output_rate': 0.60, 'is_default': True}, + {'model_id': 'gpt-4o', 'display_name': 'GPT-4o', 'provider': 'openai', 'model_type': 'text', 'input_rate': 2.50, 'output_rate': 10.00}, + {'model_id': 'gpt-4.1', 'display_name': 'GPT-4.1', 'provider': 'openai', 'model_type': 'text', 'input_rate': 2.00, 'output_rate': 8.00}, + {'model_id': 'gpt-5.1', 'display_name': 'GPT-5.1', 'provider': 'openai', 'model_type': 'text', 'input_rate': 1.25, 'output_rate': 10.00, 'max_tokens': 16000}, + {'model_id': 'gpt-5.2', 'display_name': 'GPT-5.2', 'provider': 'openai', 'model_type': 'text', 'input_rate': 1.75, 'output_rate': 14.00, 'max_tokens': 16000}, + + # Anthropic Text Models + {'model_id': 'claude-3-sonnet', 'display_name': 'Claude 3 Sonnet', 'provider': 'anthropic', 'model_type': 'text', 'input_rate': 3.00, 'output_rate': 15.00}, + {'model_id': 'claude-3-opus', 'display_name': 'Claude 3 Opus', 'provider': 'anthropic', 'model_type': 'text', 'input_rate': 15.00, 'output_rate': 75.00}, + {'model_id': 'claude-3-haiku', 'display_name': 'Claude 3 Haiku', 'provider': 'anthropic', 'model_type': 'text', 'input_rate': 0.25, 'output_rate': 1.25}, + + # OpenAI Image Models + {'model_id': 'dall-e-3', 'display_name': 'DALL-E 3', 'provider': 'openai', 'model_type': 'image', 'input_rate': 0.040, 'output_rate': 0}, + {'model_id': 'dall-e-2', 'display_name': 'DALL-E 2', 'provider': 'openai', 'model_type': 'image', 'input_rate': 0.020, 'output_rate': 0}, + {'model_id': 'gpt-image-1', 'display_name': 'GPT Image 1', 'provider': 'openai', 'model_type': 'image', 'input_rate': 0.042, 'output_rate': 0}, + + # Runware Image Models + {'model_id': 'runware:97@1', 'display_name': 'Runware 97@1', 'provider': 'runware', 'model_type': 'image', 'input_rate': 0.009, 'output_rate': 0}, + ] + + for i, model in enumerate(models): + AIModel.objects.create(sort_order=i, **model) +``` + +### Phase 6: API Endpoints for Model Management + +Add REST endpoints for managing models: + +```python +# GET /api/v1/admin/ai-models/ - List all models +# POST /api/v1/admin/ai-models/ - Create new model +# PUT /api/v1/admin/ai-models/{id}/ - Update model +# DELETE /api/v1/admin/ai-models/{id}/ - Delete model +# POST /api/v1/admin/ai-models/{id}/toggle-active/ - Toggle active status +# POST /api/v1/admin/ai-models/{id}/set-default/ - Set as default +``` + +### Phase 7: Frontend Admin UI + +Create admin UI for model management: +- List view with filtering/sorting +- Create/Edit form with validation +- Quick toggle for active/default status +- Price calculator preview + +## Implementation Order + +1. **Week 1**: Create `AIModel` model and migration +2. **Week 1**: Create `ModelRegistry` service +3. **Week 2**: Update `ai_core.py` to use registry +4. **Week 2**: Update `constants.py` to load from database +5. **Week 3**: Add Django admin interface +6. **Week 3**: Add API endpoints +7. **Week 4**: Create frontend admin UI +8. **Week 4**: Testing and documentation + +## Backward Compatibility + +- Keep `constants.py` as fallback if database is empty +- `ModelRegistry.get_model()` checks DB first, falls back to constants +- No changes to existing `GlobalIntegrationSettings` or `IntegrationSettings` +- Existing API calls continue to work unchanged + +## Benefits + +1. **No Code Changes for New Models**: Add models via admin UI +2. **Easy Price Updates**: Update rates without deployment +3. **Provider Flexibility**: Support any provider by adding models +4. **Per-Provider Settings**: Configure different capabilities per provider +5. **Audit Trail**: Track when models were added/modified +6. **A/B Testing**: Easily enable/disable models for testing diff --git a/frontend/src/pages/Planner/Clusters.tsx b/frontend/src/pages/Planner/Clusters.tsx index d802aa0c..8a5c7a6d 100644 --- a/frontend/src/pages/Planner/Clusters.tsx +++ b/frontend/src/pages/Planner/Clusters.tsx @@ -37,7 +37,11 @@ export default function Clusters() { // Data state const [clusters, setClusters] = useState([]); const [loading, setLoading] = useState(true); - + + // Total counts for footer widget (not page-filtered) + const [totalWithIdeas, setTotalWithIdeas] = useState(0); + const [totalReady, setTotalReady] = useState(0); + // Filter state const [searchTerm, setSearchTerm] = useState(''); const [statusFilter, setStatusFilter] = useState(''); @@ -75,6 +79,34 @@ export default function Clusters() { const progressModal = useProgressModal(); const hasReloadedRef = useRef(false); + // Load total metrics for footer widget (not affected by pagination) + const loadTotalMetrics = useCallback(async () => { + try { + // Get clusters with status='mapped' (those that have ideas) + const mappedRes = await fetchClusters({ + page_size: 1, + ...(activeSector?.id && { sector_id: activeSector.id }), + status: 'mapped', + }); + setTotalWithIdeas(mappedRes.count || 0); + + // Get clusters with status='new' (those that are ready for ideas) + const newRes = await fetchClusters({ + page_size: 1, + ...(activeSector?.id && { sector_id: activeSector.id }), + status: 'new', + }); + setTotalReady(newRes.count || 0); + } catch (error) { + console.error('Error loading total metrics:', error); + } + }, [activeSector]); + + // Load total metrics when sector changes + useEffect(() => { + loadTotalMetrics(); + }, [loadTotalMetrics]); + // Load clusters - wrapped in useCallback to prevent infinite loops const loadClusters = useCallback(async () => { setLoading(true); @@ -494,17 +526,17 @@ export default function Clusters() { submoduleColor: 'green', metrics: [ { label: 'Clusters', value: totalCount }, - { label: 'With Ideas', value: clusters.filter(c => (c.ideas_count || 0) > 0).length, percentage: `${totalCount > 0 ? Math.round((clusters.filter(c => (c.ideas_count || 0) > 0).length / totalCount) * 100) : 0}%` }, + { label: 'With Ideas', value: totalWithIdeas, percentage: `${totalCount > 0 ? Math.round((totalWithIdeas / totalCount) * 100) : 0}%` }, { label: 'Keywords', value: clusters.reduce((sum, c) => sum + (c.keywords_count || 0), 0) }, - { label: 'Ready', value: clusters.filter(c => (c.ideas_count || 0) === 0).length }, + { label: 'Ready', value: totalReady }, ], progress: { - value: totalCount > 0 ? Math.round((clusters.filter(c => (c.ideas_count || 0) > 0).length / totalCount) * 100) : 0, + value: totalCount > 0 ? Math.round((totalWithIdeas / totalCount) * 100) : 0, label: 'Have Ideas', color: 'green', }, - hint: clusters.filter(c => (c.ideas_count || 0) === 0).length > 0 - ? `${clusters.filter(c => (c.ideas_count || 0) === 0).length} clusters ready for idea generation` + hint: totalReady > 0 + ? `${totalReady} clusters ready for idea generation` : 'All clusters have ideas!', }} moduleStats={{ diff --git a/frontend/src/pages/Planner/Ideas.tsx b/frontend/src/pages/Planner/Ideas.tsx index 30562ef4..450b36b2 100644 --- a/frontend/src/pages/Planner/Ideas.tsx +++ b/frontend/src/pages/Planner/Ideas.tsx @@ -40,7 +40,11 @@ export default function Ideas() { const [ideas, setIdeas] = useState([]); const [clusters, setClusters] = useState([]); const [loading, setLoading] = useState(true); - + + // Total counts for footer widget (not page-filtered) + const [totalInTasks, setTotalInTasks] = useState(0); + const [totalPending, setTotalPending] = useState(0); + // Filter state const [searchTerm, setSearchTerm] = useState(''); const [statusFilter, setStatusFilter] = useState(''); @@ -90,6 +94,39 @@ export default function Ideas() { loadClusters(); }, []); + // Load total metrics for footer widget (not affected by pagination) + const loadTotalMetrics = useCallback(async () => { + try { + // Get ideas with status='queued' or 'completed' (those in tasks/writer) + const queuedRes = await fetchContentIdeas({ + page_size: 1, + ...(activeSector?.id && { sector_id: activeSector.id }), + status: 'queued', + }); + const completedRes = await fetchContentIdeas({ + page_size: 1, + ...(activeSector?.id && { sector_id: activeSector.id }), + status: 'completed', + }); + setTotalInTasks((queuedRes.count || 0) + (completedRes.count || 0)); + + // Get ideas with status='new' (those ready to become tasks) + const newRes = await fetchContentIdeas({ + page_size: 1, + ...(activeSector?.id && { sector_id: activeSector.id }), + status: 'new', + }); + setTotalPending(newRes.count || 0); + } catch (error) { + console.error('Error loading total metrics:', error); + } + }, [activeSector]); + + // Load total metrics when sector changes + useEffect(() => { + loadTotalMetrics(); + }, [loadTotalMetrics]); + // Load ideas - wrapped in useCallback const loadIdeas = useCallback(async () => { setLoading(true); @@ -422,17 +459,17 @@ export default function Ideas() { submoduleColor: 'amber', metrics: [ { label: 'Ideas', value: totalCount }, - { label: 'In Tasks', value: ideas.filter(i => i.status === 'queued' || i.status === 'completed').length, percentage: `${totalCount > 0 ? Math.round((ideas.filter(i => i.status === 'queued' || i.status === 'completed').length / totalCount) * 100) : 0}%` }, - { label: 'Pending', value: ideas.filter(i => i.status === 'new').length }, + { label: 'In Tasks', value: totalInTasks, percentage: `${totalCount > 0 ? Math.round((totalInTasks / totalCount) * 100) : 0}%` }, + { label: 'Pending', value: totalPending }, { label: 'From Clusters', value: clusters.length }, ], progress: { - value: totalCount > 0 ? Math.round((ideas.filter(i => i.status === 'queued' || i.status === 'completed').length / totalCount) * 100) : 0, + value: totalCount > 0 ? Math.round((totalInTasks / totalCount) * 100) : 0, label: 'Converted', color: 'amber', }, - hint: ideas.filter(i => i.status === 'new').length > 0 - ? `${ideas.filter(i => i.status === 'new').length} ideas ready to become tasks` + hint: totalPending > 0 + ? `${totalPending} ideas ready to become tasks` : 'All ideas converted!', }} moduleStats={{ diff --git a/frontend/src/pages/Planner/Keywords.tsx b/frontend/src/pages/Planner/Keywords.tsx index c83a453b..6f731f1a 100644 --- a/frontend/src/pages/Planner/Keywords.tsx +++ b/frontend/src/pages/Planner/Keywords.tsx @@ -45,7 +45,12 @@ export default function Keywords() { const [keywords, setKeywords] = useState([]); const [clusters, setClusters] = useState([]); const [loading, setLoading] = useState(true); - + + // Total counts for footer widget (not page-filtered) + const [totalClustered, setTotalClustered] = useState(0); + const [totalUnmapped, setTotalUnmapped] = useState(0); + const [totalVolume, setTotalVolume] = useState(0); + // Filter state - match Keywords.tsx const [searchTerm, setSearchTerm] = useState(''); const [statusFilter, setStatusFilter] = useState(''); @@ -108,6 +113,44 @@ export default function Keywords() { loadClusters(); }, []); + // Load total metrics for footer widget (not affected by pagination) + const loadTotalMetrics = useCallback(async () => { + if (!activeSite) return; + + try { + // Get all keywords (total count) - this is already in totalCount from main load + // Get keywords with status='mapped' (those that have been mapped to a cluster) + const mappedRes = await fetchKeywords({ + page_size: 1, + site_id: activeSite.id, + ...(activeSector?.id && { sector_id: activeSector.id }), + status: 'mapped', + }); + setTotalClustered(mappedRes.count || 0); + + // Get keywords with status='new' (those that are ready to cluster but haven't been yet) + const newRes = await fetchKeywords({ + page_size: 1, + site_id: activeSite.id, + ...(activeSector?.id && { sector_id: activeSector.id }), + status: 'new', + }); + setTotalUnmapped(newRes.count || 0); + + // Get total volume across all keywords (we need to fetch all or rely on backend aggregation) + // For now, we'll just calculate from current data or set to 0 + // TODO: Backend should provide total volume as an aggregated metric + setTotalVolume(0); + } catch (error) { + console.error('Error loading total metrics:', error); + } + }, [activeSite, activeSector]); + + // Load total metrics when site/sector changes + useEffect(() => { + loadTotalMetrics(); + }, [loadTotalMetrics]); + // Load keywords - wrapped in useCallback to prevent infinite loops const loadKeywords = useCallback(async () => { setLoading(true); @@ -712,17 +755,17 @@ export default function Keywords() { submoduleColor: 'blue', metrics: [ { label: 'Keywords', value: totalCount }, - { label: 'Clustered', value: keywords.filter(k => k.cluster_id).length, percentage: `${totalCount > 0 ? Math.round((keywords.filter(k => k.cluster_id).length / totalCount) * 100) : 0}%` }, - { label: 'Unmapped', value: keywords.filter(k => !k.cluster_id).length }, - { label: 'Volume', value: `${(keywords.reduce((sum, k) => sum + (k.volume || 0), 0) / 1000).toFixed(1)}K` }, + { label: 'Clustered', value: totalClustered, percentage: `${totalCount > 0 ? Math.round((totalClustered / totalCount) * 100) : 0}%` }, + { label: 'Unmapped', value: totalUnmapped }, + { label: 'Volume', value: totalVolume > 0 ? `${(totalVolume / 1000).toFixed(1)}K` : '-' }, ], progress: { - value: totalCount > 0 ? Math.round((keywords.filter(k => k.cluster_id).length / totalCount) * 100) : 0, + value: totalCount > 0 ? Math.round((totalClustered / totalCount) * 100) : 0, label: 'Clustered', color: 'blue', }, - hint: keywords.filter(k => !k.cluster_id).length > 0 - ? `${keywords.filter(k => !k.cluster_id).length} keywords ready to cluster` + hint: totalUnmapped > 0 + ? `${totalUnmapped} keywords ready to cluster` : 'All keywords clustered!', }} moduleStats={{ diff --git a/to-do-s/PLAN-DASHBOARD-HOMEPAGE.md b/to-do-s/PLAN-DASHBOARD-HOMEPAGE.md deleted file mode 100644 index a9b0077f..00000000 --- a/to-do-s/PLAN-DASHBOARD-HOMEPAGE.md +++ /dev/null @@ -1,177 +0,0 @@ - -## 5. Dashboard Redesign Plan - -### Current Issues -- Too much whitespace and large headings -- Repeating same counts/metrics without different dimensions -- Missing actionable insights -- No AI operations analytics -- Missing "needs attention" items - -### New Dashboard Design: Multi-Dimension Compact Widgets - -Based on Django admin reports analysis, the dashboard should show **different data dimensions** instead of repeating counts: - -### Dashboard Layout (Compact, Information-Dense) - -``` -┌─────────────────────────────────────────────────────────────────────────────────────┐ -│ ⚠ NEEDS ATTENTION (collapsible, only shows if items exist) │ -│ ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐ │ -│ │ 3 pending review │ │ WP sync failed │ │ Setup incomplete │ │ -│ │ [Review →] │ │ [Retry] [Fix →] │ │ [Complete →] │ │ -│ └────────────────────┘ └────────────────────┘ └────────────────────┘ │ -├─────────────────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────────────────────────┐ ┌─────────────────────────────────────────┐ │ -│ │ WORKFLOW PIPELINE │ │ QUICK ACTIONS │ │ -│ │ │ │ │ │ -│ │ Sites → KWs → Clusters → Ideas │ │ [+ Keywords] [⚡ Cluster] [📝 Content] │ │ -│ │ 2 156 23 67 │ │ [🖼 Images] [✓ Review] [🚀 Publish] │ │ -│ │ ↓ │ │ │ │ -│ │ Tasks → Drafts → Published │ │ WORKFLOW GUIDE │ │ -│ │ 45 28 45 │ │ 1. Add Keywords 5. Generate Content │ │ -│ │ │ │ 2. Auto Cluster 6. Generate Images │ │ -│ │ ████████████░░░ 72% Complete │ │ 3. Generate Ideas 7. Review & Approve │ │ -│ │ │ │ 4. Create Tasks 8. Publish to WP │ │ -│ └─────────────────────────────────┘ │ [Full Help →] │ │ -│ └─────────────────────────────────────────┘ │ -│ │ -├─────────────────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────────────────────────┐ ┌─────────────────────────────────────────┐ │ -│ │ AI OPERATIONS (7d) [▼ 30d] │ │ RECENT ACTIVITY │ │ -│ │ │ │ │ │ -│ │ Operation Count Credits │ │ • Clustered 45 keywords → 8 clusters │ │ -│ │ ───────────────────────────────│ │ 2 hours ago │ │ -│ │ Clustering 8 80 │ │ • Generated 5 articles (4.2K words) │ │ -│ │ Ideas 12 24 │ │ 4 hours ago │ │ -│ │ Content 28 1,400 │ │ • Created 15 image prompts │ │ -│ │ Images 45 225 │ │ Yesterday │ │ -│ │ ───────────────────────────────│ │ • Published "Best Running Shoes" to WP │ │ -│ │ Total 93 1,729 │ │ Yesterday │ │ -│ │ │ │ • Added 23 keywords from seed DB │ │ -│ │ Success Rate: 98.5% │ │ 2 days ago │ │ -│ │ Avg Credits/Op: 18.6 │ │ │ │ -│ └─────────────────────────────────┘ │ [View All Activity →] │ │ -│ └─────────────────────────────────────────┘ │ -│ │ -├─────────────────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────────────────────────┐ ┌─────────────────────────────────────────┐ │ -│ │ CONTENT VELOCITY │ │ AUTOMATION STATUS │ │ -│ │ │ │ │ │ -│ │ This Week This Month Total │ │ ● Active │ Schedule: Daily 9 AM │ │ -│ │ │ │ │ │ -│ │ Articles 5 28 156 │ │ Last Run: Dec 27, 7:00 AM │ │ -│ │ Words 4.2K 24K 156K │ │ ├─ Clustered: 12 keywords │ │ -│ │ Images 12 67 340 │ │ ├─ Ideas: 8 generated │ │ -│ │ │ │ ├─ Content: 5 articles │ │ -│ │ 📈 +23% vs last week │ │ └─ Images: 15 created │ │ -│ │ │ │ │ │ -│ │ [View Analytics →] │ │ Next Run: Dec 28, 9:00 AM │ │ -│ └─────────────────────────────────┘ │ [Configure →] [Run Now →] │ │ -│ └─────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────────────────────┘ -``` - -### Widget Specifications - -#### 1. Needs Attention Bar -- Collapsible, only visible when items exist -- Types: `pending_review`, `sync_failed`, `setup_incomplete`, `automation_failed` -- Compact horizontal cards with action buttons - -#### 2. Workflow Pipeline Widget -- Visual flow: Sites → Keywords → Clusters → Ideas → Tasks → Drafts → Published -- Shows counts at each stage -- Single progress bar for overall completion -- Clickable stage names link to respective pages - -#### 3. Quick Actions + Workflow Guide Widget -- 2x3 grid of action buttons (use existing icons) -- Compact numbered workflow guide (1-8 steps) -- "Full Help" link to help page - -#### 4. AI Operations Widget (NEW - from Django Admin Reports) -Shows data from `CreditUsageLog` model: -```typescript -interface AIOperationsData { - period: '7d' | '30d' | '90d'; - operations: Array<{ - type: 'clustering' | 'ideas' | 'content' | 'images'; - count: number; - credits: number; - }>; - totals: { - count: number; - credits: number; - success_rate: number; - avg_credits_per_op: number; - }; -} -``` -- Time period filter (7d/30d/90d dropdown) -- Table with operation type, count, credits -- Success rate percentage -- Average credits per operation - -#### 5. Recent Activity Widget -Shows data from `AITaskLog` and `CreditUsageLog`: -- Last 5 significant operations -- Timestamp relative (2 hours ago, Yesterday) -- Clickable to navigate to relevant content -- "View All Activity" link - -#### 6. Content Velocity Widget (NEW) -Shows content production rates: -```typescript -interface ContentVelocityData { - this_week: { articles: number; words: number; images: number }; - this_month: { articles: number; words: number; images: number }; - total: { articles: number; words: number; images: number }; - trend: number; // percentage vs previous period -} -``` -- Three time columns: This Week, This Month, Total -- Rows: Articles, Words, Images -- Trend indicator vs previous period - -#### 7. Automation Status Widget -Shows automation run status: -- Current status indicator (Active/Paused/Failed) -- Schedule display -- Last run details with stage breakdown -- Next scheduled run -- Configure and Run Now buttons - -### API Endpoint Required - -```python -# GET /api/v1/dashboard/summary/ -{ - "needs_attention": [...], - "pipeline": { - "sites": 2, "keywords": 156, "clusters": 23, - "ideas": 67, "tasks": 45, "drafts": 28, "published": 45, - "completion_percentage": 72 - }, - "ai_operations": { - "period": "7d", - "operations": [...], - "totals": {...} - }, - "recent_activity": [...], - "content_velocity": {...}, - "automation": {...} -} -``` - -### Implementation Notes - -- Use existing components from `components/ui/` -- Use CSS tokens from `styles/tokens.css` -- Grid layout: `grid grid-cols-1 lg:grid-cols-2 gap-4` -- Compact widget padding: `p-4` -- No large headings - use subtle section labels diff --git a/to-do-s/PLAN-SITE-SELECTOR-SECTOR.md b/to-do-s/PLAN-SITE-SELECTOR-SECTOR.md deleted file mode 100644 index 0d77e4d2..00000000 --- a/to-do-s/PLAN-SITE-SELECTOR-SECTOR.md +++ /dev/null @@ -1,181 +0,0 @@ -# Plan: Site & Sector Selector Configuration - -**Source:** COMPREHENSIVE-AUDIT-REPORT.md - Section 1 -**Priority:** High for Planner & Writer pages -**Estimated Effort:** 4-6 hours - ---- - -## Objective - -Ensure correct placement of Site Selector and Sector Selector across all pages based on data scope requirements. - ---- - -## Configuration Rules - -| Condition | Site Selector | Sector Selector | -|-----------|:-------------:|:---------------:| -| Data scoped to specific site | ✅ | ❌ | -| Data can be filtered by content category | ✅ | ✅ | -| Page is not site-specific (account-level) | ❌ | ❌ | -| Already in specific context (detail page) | ❌ | ❌ | - ---- - -## Implementation Checklist - -### DASHBOARD Module -- [ ] **Home** - Site Selector: ✅ (with "All Sites" option) | Sector: ❌ - - Overview across sites - sector too granular for dashboard - -### SETUP Module -- [ ] **Add Keywords** - Site: ✅ | Sector: ✅ - - Keywords are site+sector specific -- [ ] **Content Settings** - Site: ✅ | Sector: ❌ - - Settings are site-level, not sector-level -- [ ] **Sites List** - Site: ❌ | Sector: ❌ - - Managing sites themselves -- [ ] **Site Dashboard** - Site: ❌ (context) | Sector: ❌ - - Already in specific site context -- [ ] **Site Settings tabs** - Site: ❌ (context) | Sector: ❌ - - Already in specific site context - -### PLANNER Module -- [ ] **Keywords** - Site: ✅ | Sector: ✅ - - Keywords organized by site+sector -- [ ] **Clusters** - Site: ✅ | Sector: ✅ - - Clusters organized by site+sector -- [ ] **Cluster Detail** - Site: ❌ (context) | Sector: ❌ (context) - - Already in cluster context -- [ ] **Ideas** - Site: ✅ | Sector: ✅ - - Ideas organized by site+sector - -### WRITER Module -- [ ] **Tasks/Queue** - Site: ✅ | Sector: ✅ - - Tasks organized by site+sector -- [ ] **Content/Drafts** - Site: ✅ | Sector: ✅ - - Content organized by site+sector -- [ ] **Content View** - Site: ❌ (context) | Sector: ❌ (context) - - Viewing specific content -- [ ] **Images** - Site: ✅ | Sector: ✅ - - Images tied to content by site+sector -- [ ] **Review** - Site: ✅ | Sector: ✅ - - Review queue by site+sector -- [ ] **Published** - Site: ✅ | Sector: ✅ - - Published content by site+sector - -### AUTOMATION Module -- [ ] **Automation** - Site: ✅ | Sector: ❌ - - Automation runs at site level - -### LINKER Module (if enabled) -- [ ] **Content List** - Site: ✅ | Sector: ✅ - - Linking is content-specific - -### OPTIMIZER Module (if enabled) -- [ ] **Content Selector** - Site: ✅ | Sector: ✅ - - Optimization is content-specific -- [ ] **Analysis Preview** - Site: ❌ (context) | Sector: ❌ (context) - - Already in analysis context - -### THINKER Module (Admin) -- [ ] **All Thinker pages** - Site: ❌ | Sector: ❌ - - System-wide prompts/profiles - -### BILLING Module -- [ ] **All Billing pages** - Site: ❌ | Sector: ❌ - - Account-level billing data - -### ACCOUNT Module -- [ ] **Account Settings** - Site: ❌ | Sector: ❌ -- [ ] **Profile** - Site: ❌ | Sector: ❌ -- [ ] **Team** - Site: ❌ | Sector: ❌ -- [ ] **Plans** - Site: ❌ | Sector: ❌ -- [ ] **Usage** - Site: ❌ | Sector: ❌ - -### HELP Module -- [ ] **Help Page** - Site: ❌ | Sector: ❌ - ---- - -## Site Setup Checklist on Site Cards - -**Source:** Section 6 of Audit Report - -### Current Status -- ✅ `SiteSetupChecklist.tsx` component EXISTS -- ✅ Integrated in Site Dashboard (full mode) -- ❌ **NOT integrated in SiteCard.tsx** (compact mode) - -### Implementation Task - -**File:** `frontend/src/components/sites/SiteCard.tsx` - -Add compact checklist after status badges: - -```tsx - 0} - hasWordPressIntegration={!!site.wordpress_site_url} - hasKeywords={site.keywords_count > 0} - compact={true} -/> -``` - -**Expected Visual:** -``` -┌─────────────────────────────────────────┐ -│ My Website [Active] │ -│ example.com │ -│ Industry: Tech │ 3 Sectors │ -│ ●●●○ 3/4 Setup Steps Complete │ ← compact checklist -│ [Manage →] │ -└─────────────────────────────────────────┘ -``` - ---- - -## Backend Requirements - -Ensure `SiteSerializer` returns these fields for checklist: -- `keywords_count` - number of keywords -- `has_integration` - boolean for WordPress integration -- `active_sectors_count` - number of active sectors -- `industry_name` - industry name or null - -**Status:** ✅ Already verified these fields are returned - ---- - -## Files to Modify - -### Frontend -1. `frontend/src/components/sites/SiteCard.tsx` - Add compact SiteSetupChecklist -2. Various page files to verify/add selector configuration - -### Selector Components -- `frontend/src/components/common/SiteSelector.tsx` -- `frontend/src/components/common/SectorSelector.tsx` - ---- - -## Testing Checklist - -- [ ] Site selector shows on all required pages -- [ ] Sector selector shows only where data is sector-specific -- [ ] Detail pages (Cluster Detail, Content View) have no selectors -- [ ] Account/Billing pages have no selectors -- [ ] SiteCard shows compact setup checklist -- [ ] Checklist updates when site configuration changes - ---- - -## Notes - -- The "All Sites" option on Dashboard should aggregate data across all user's sites -- Context pages (detail views) inherit site/sector from parent navigation -- Selector state should persist in URL params or store for deep linking diff --git a/to-do-s/part1/SECTION_2_FINAL_MODS.md b/to-do-s/part1/SECTION_2_FINAL_MODS.md deleted file mode 100644 index 3f2e3c83..00000000 --- a/to-do-s/part1/SECTION_2_FINAL_MODS.md +++ /dev/null @@ -1,289 +0,0 @@ -# Section 2: SETUP Modules - Audit & Action Plan - -**Date:** December 27, 2025 -**Status:** Finalized for Implementation -**Scope:** Add Keywords, Content Settings, Sites (Thinker excluded - admin only) - ---- - -## 2.1 Add Keywords - -**Route:** `/setup/add-keywords` -**File:** `pages/Setup/AddKeywords.tsx` - -### Current Functionality -- Browse pre-populated seed keywords from global database (admin-imported CSV) -- Filter by active site's industry/sector -- Bulk select and add keywords to Planner workflow -- Tracks which keywords are already added -- Filters: Search, Country, Difficulty - -### Important Clarification -- **This page:** Browse/select from global seed keyword database only -- **Manual keyword entry:** Available in Planner/Keywords page (user's own workflow), NOT here -- **Keyword imports:** Admin-only via backend admin panel - ---- - -### Issues to Address - -| # | Issue | Priority | Action | -|---|-------|----------|--------| -| 1 | Sector requirement unclear | High | Add tooltip/message explaining why buttons are disabled when no sector is selected | -| 2 | No "already added" filter | Medium | Add filter toggle: "Show not-yet-added only" | -| 3 | No "Next Step" CTA | High | Add button after keywords added: "Next: Plan Your Content →" linking to Planner | -| 4 | No keyword count summary | Medium | Display: "X keywords in your workflow • Y available to add" | -| 5 | Import/manual add buttons exist | High | Remove any UI elements for importing or manually adding keywords - this is global DB, read-only for users | -| 6 | No Keyword Research indication | Low | Add small teaser text: "Looking for more keywords? Keyword Research coming soon" (user-friendly, non-technical wording) | - ---- - -### Implementation Notes - -**For Issue #1 (Sector requirement):** -- When buttons are disabled, show tooltip: "Please select an industry and sector in your Site Settings to browse relevant keywords" -- Consider linking directly to Site Settings - -**For Issue #3 (Next Step CTA):** -- Button should appear after user has added at least 1 keyword -- Route to `/planner/keywords` - -**For Issue #5 (Remove import/add):** -- Audit the page for any "Import Keywords" or "Add Custom Keyword" buttons -- Remove from UI completely -- Keywords only come from admin-imported global database - ---- - -## 2.2 Content Settings - -**Route:** `/account/content-settings` -**File:** `pages/account/ContentSettingsPage.tsx` -**Tabs:** Content Generation, Publishing, Image Settings - -### Current Functionality -- **Content Generation Tab:** Append to prompt, default tone, default length -- **Publishing Tab:** Auto-publish toggle, keep updated toggle -- **Image Settings Tab:** Quality, style, sizes, format (DALL-E 2/3/Runware) - -### Current State -- ⚠️ **Content Generation:** Shows "saved" but does NOT persist (TODO in code) -- ⚠️ **Publishing:** Shows "saved" but does NOT persist (no backend API) -- ✅ **Image Settings:** Works correctly (has API integration) - ---- - -### Issues to Address - -| # | Issue | Priority | Action | -|---|-------|----------|--------| -| 1 | Content Generation NOT PERSISTED | 🔴 Critical | Implement backend API endpoint to save Content Generation settings | -| 2 | Publishing NOT PERSISTED | 🔴 Critical | Implement backend API endpoint - simple toggle for auto-publish (true/false) | -| 3 | False "saved" confirmation | 🔴 Critical | Fix after #1 and #2 - currently misleads users | - ---- - -### Implementation Notes - -**For Issue #1 (Content Generation API):** -- Fields to persist: append_to_prompt, default_tone, default_length -- Should save at account level (global, not per-site) - -**For Issue #2 (Publishing API):** -- Simple boolean toggle: auto_publish (true/false) -- When true: content automatically publishes to WordPress after generation -- When false: content stays in Review status for manual publishing - -**Not Needed for Launch:** -- Per-site content settings -- Thinker prompts connection explanation (handled via shortcodes in prompts) - ---- - -## 2.3 Sites - -**Route:** `/sites` -**Files:** `pages/Sites/List.tsx`, `pages/Sites/SiteSettings.tsx`, `pages/Sites/SiteDashboard.tsx` -**Tabs (Site Settings):** General, Integrations, Content Types - -### Current Functionality -- List all sites with filtering (search, type, hosting, status) -- Create sites via WorkflowGuide (requires industry + sectors) -- Activate/deactivate sites -- Navigate to site dashboard, content, settings -- Settings: Name, URL, SEO, WordPress integration, content type mapping - -### What Sites Module Should Be (Launch Scope) -- Connect/manage WordPress sites for content publishing -- Configure WordPress integration (API credentials) -- Set active site for content workflow -- Industry/sector selection (for keyword filtering) - ---- - -### Issues to Address - -#### A. Fix/Improve (From Audit) - -| # | Issue | Priority | Action | -|---|-------|----------|--------| -| 1 | Dashboard stats are mock data | Medium | Implement real site statistics endpoint OR remove stats display | -| 2 | No inline editing | Low | Add inline edit for site name from list view | -| 3 | No site cloning | Low | Add "Duplicate Site" action to copy configuration | -| 4 | No bulk operations | Low | Add bulk activate/deactivate/delete | -| 5 | Complex site creation flow | High | Allow site creation without requiring industry/sector upfront | -| 6 | Integration tab default after creation | Medium | Default to General tab, not Integrations (less confusing for non-technical users) | -| 7 | No setup progress indicator | High | Add visual checklist showing what's configured vs pending (see below) | - -#### B. Remove (Legacy Site Builder) - -| # | Issue | Priority | Action | -|---|-------|----------|--------| -| 8 | Site Builder legacy pages | High | Remove all frontend pages/components related to site builder feature | -| 9 | WordPress content fetching | High | Remove code that fetches existing content FROM WordPress (only IGNY8-generated content should exist) | -| 10 | Duplicate Manage.tsx | High | Delete `pages/Sites/Manage.tsx` - redundant with List.tsx | -| 11 | Backend site builder code | High | Remove backend APIs/models related to site builder and external content fetching | - ---- - -### Setup Completion Checklist (New Feature) - -Display this checklist on Site card or Site Dashboard to guide users: - -``` -Site Setup Progress -─────────────────── -☑ Site created -☐ Industry/Sectors selected -☐ WordPress integration configured (or skipped) -☐ Keywords added -☐ Content settings configured - -[Complete Setup →] -``` - -**Implementation Notes:** -- Show on each site card in list view (compact version) -- Show expanded on Site Dashboard -- Each item links to relevant settings page -- "Complete Setup" button goes to first incomplete item -- When all complete, show "✓ Ready to create content" - ---- - -## 2.4 SETUP Cross-Module Issues - -| # | Issue | Priority | Action | -|---|-------|----------|--------| -| 1 | No guided flow | High | After completing setup tasks, guide user to start content workflow (link to Planner) | -| 2 | Scattered settings | Medium | Document where settings live; consider consolidation in future | -| 3 | No onboarding checklist | High | Implement Setup Completion Checklist (see 2.3 above) | - ---- - -## Summary - -### Total Issues by Section - -| Section | Critical | High | Medium | Low | Total | -|---------|----------|------|--------|-----|-------| -| 2.1 Add Keywords | 0 | 3 | 2 | 1 | 6 | -| 2.2 Content Settings | 3 | 0 | 0 | 0 | 3 | -| 2.3 Sites | 0 | 6 | 2 | 3 | 11 | -| 2.4 Cross-Module | 0 | 2 | 1 | 0 | 3 | -| **TOTAL** | **3** | **11** | **5** | **4** | **23** | - -### Critical Items (Must Fix) - -1. **Content Settings - Content Generation tab not saving** → Implement backend API -2. **Content Settings - Publishing tab not saving** → Implement backend API -3. **Content Settings - False "saved" message** → Fix after APIs implemented - -### High Priority Items - -1. Add Keywords - Sector requirement tooltip -2. Add Keywords - Next Step CTA to Planner -3. Add Keywords - Remove import/manual add buttons -4. Sites - Allow simpler site creation flow -5. Sites - Add Setup Completion Checklist -6. Sites - Remove Site Builder legacy code (frontend) -7. Sites - Remove WordPress content fetching code -8. Sites - Delete duplicate Manage.tsx -9. Sites - Remove Site Builder backend code -10. Cross-Module - Guided flow after setup -11. Cross-Module - Onboarding checklist implementation - -### Files to Delete - -| File | Reason | -|------|--------| -| `pages/Sites/Manage.tsx` | Duplicate of List.tsx | -| Site Builder related pages | Legacy feature removed | -| Site Builder related components | Legacy feature removed | - -### Files to Modify - -| File | Changes | -|------|---------| -| `pages/Setup/AddKeywords.tsx` | Add tooltip, filter, CTA, count summary, remove import buttons, add teaser | -| `pages/account/ContentSettingsPage.tsx` | Connect to new backend APIs | -| `pages/Sites/List.tsx` | Add setup checklist, inline edit, bulk operations | -| `pages/Sites/SiteSettings.tsx` | Default to General tab | -| `pages/Sites/SiteDashboard.tsx` | Fix mock stats, add setup checklist | - -### Backend Work Required - -| Area | Work | -|------|------| -| Content Settings API | Create endpoints for Content Generation and Publishing settings | -| Site Statistics API | Implement real stats OR remove from frontend | -| Cleanup | Remove Site Builder and content fetching APIs/models | - ---- - -Status after implementation - - -## Summary of Section 2 Implementation - -### 2.1 Add Keywords (IndustriesSectorsKeywords.tsx) -- ✅ Added `showNotAddedOnly` filter state with "Not Yet Added Only" filter option -- ✅ Added `addedCount` and `availableCount` state variables for keyword count tracking -- ✅ Added keyword count summary showing "X keywords in your workflow • Y available to add" -- ✅ Added "Next: Plan Your Content →" CTA button that appears when keywords are added -- ✅ Added "Looking for more keywords? Keyword Research coming soon!" teaser text -- ✅ Sector requirement tooltip already existed - no changes needed -- ✅ No visible import buttons to remove (dead code existed but was not exposed) - -### 2.2 Content Settings (ContentSettingsPage.tsx) -- ✅ Created new backend API endpoint `/v1/system/settings/content//` for content_generation and publishing -- ✅ Added `ContentSettingsViewSet` to backend with retrieve/update/save actions -- ✅ Updated frontend to load content_generation and publishing settings from API -- ✅ Updated frontend to save content_generation settings (append_to_prompt, default_tone, default_length) -- ✅ Updated frontend to save publishing settings (auto_publish_enabled, auto_sync_enabled) -- ✅ Removed TODO comments - settings now actually persist - -### 2.3 Sites -- ✅ Created `SiteSetupChecklist` component showing setup progress with checklist -- ✅ Updated Dashboard.tsx to use the new checklist component -- ✅ Removed mock stats from Dashboard (were showing all zeros) -- ✅ Deleted Manage.tsx (redundant duplicate of List.tsx) -- ✅ Removed empty `Builder/` folder structure -- ✅ Removed routes to deleted pages in App.tsx -- ✅ Site Settings already defaults to "general" tab - no changes needed - -### Files Modified -1. IndustriesSectorsKeywords.tsx -2. ContentSettingsPage.tsx -3. settings_views.py -4. urls.py -5. Dashboard.tsx -6. App.tsx - -### Files Created -1. SiteSetupChecklist.tsx - -### Files Deleted -1. Manage.tsx -2. `frontend/src/pages/Sites/Builder/` (empty folder) - diff --git a/to-do-s/part1/SECTION_3_FINAL_MODS.md b/to-do-s/part1/SECTION_3_FINAL_MODS.md deleted file mode 100644 index dde4d631..00000000 --- a/to-do-s/part1/SECTION_3_FINAL_MODS.md +++ /dev/null @@ -1,351 +0,0 @@ -# Section 3: WORKFLOW Modules - Audit & Action Plan - -**Date:** December 27, 2025 -**Status:** Finalized for Implementation -**Scope:** Planner, Writer, Automation (Linker & Optimizer excluded - not active modules) - ---- - -## 3.1 Planner - -**Route:** `/planner/keywords` -**Files:** `pages/Planner/Keywords.tsx`, `pages/Planner/Clusters.tsx`, `pages/Planner/ClusterView.tsx`, `pages/Planner/Ideas.tsx`, `pages/Planner/KeywordOpportunities.tsx` -**Tabs:** Keywords, Clusters, Ideas - -### Current Functionality -- **Keywords:** CRUD, bulk status updates, auto-cluster AI, filters -- **Clusters:** CRUD, bulk operations, auto-generate ideas AI -- **Ideas:** CRUD, bulk queue to writer, filters -- **Flow:** Keywords → Auto-Cluster → Clusters → Auto-Generate Ideas → Ideas → Queue to Writer - ---- - -### Issues to Address - -| # | Issue | Priority | Action | -|---|-------|----------|--------| -| 1 | KeywordOpportunities page exists but orphaned | High | **DELETE** - Remove `pages/Planner/KeywordOpportunities.tsx` and all references to it. Add Keywords page is the source of truth for seed keywords | -| 2 | No "Add to Existing Cluster" | Medium | Add option to assign keywords to existing clusters (not just create new) | -| 3 | No cluster progress indicator | High | Show which clusters already have ideas generated (badge/indicator) | -| 4 | Ideas missing queued count | Medium | Add indicator showing how many ideas are pending vs processed | -| 5 | Cluster → Ideas transition unclear | Medium | Make it clear which clusters need ideas generated | -| 6 | No return path from Ideas to source cluster | Low | Make cluster name clickable on Ideas page to navigate back | - ---- - -### Issues NOT Being Addressed (Per Discussion) - -| Issue | Reason | -|-------|--------| -| No cluster merge/split | Risk of breaking functional workflow, complex implementation | - ---- - -### Implementation Notes - -**For Issue #1 (Remove KeywordOpportunities):** -- Delete file: `pages/Planner/KeywordOpportunities.tsx` -- Remove route from App.tsx or router config -- Remove any navigation links to `/planner/keyword-opportunities` -- Remove from sidebar if present -- The Add Keywords page (`/setup/add-keywords`) is the active workflow item for seed keywords - -**For Issue #3 (Cluster progress indicator):** -- On Clusters table, show badge: "X ideas" or "No ideas yet" -- Visual distinction between clusters with/without ideas -- Consider color coding or icon - -**For Issue #5 (Cluster → Ideas transition):** -- Add "Generate Ideas" button prominently on clusters without ideas -- Filter option: "Show clusters without ideas" - ---- - -## 3.2 Writer - -**Route:** `/writer/tasks` -**Files:** `pages/Writer/Tasks.tsx`, `pages/Writer/Drafts.tsx`, `pages/Writer/ContentView.tsx`, `pages/Writer/Images.tsx`, `pages/Writer/Review.tsx`, `pages/Writer/Published.tsx` -**Tabs:** Queue, Drafts, Images, Review, Published - -### Current Functionality -- **Tasks (Queue):** CRUD, generate content (row action only), generate images bulk -- **Drafts:** List drafts, view details, status updates -- **Images:** Grouped by content, image generation -- **Review:** Status=review filter, publish to WordPress -- **Published:** Status=published, WordPress sync status - ---- - -### Issues to Address - -| # | Issue | Priority | Action | -|---|-------|----------|--------| -| 1 | Status progression confusion | High | Streamline Draft → Review → Published flow - should not require navigating different pages for status changes | -| 2 | Images detached from content workflow | High | Integrate images into content workflow - show/manage images within content view | -| 3 | ContentView shows tags and categories twice | High | Fix template to display tags and categories only once | - ---- - -### Issues NOT Being Addressed (Per Discussion) - -| Issue | Reason | -|-------|--------| -| No bulk content generation | Not an issue per current workflow | -| No content editing | Not an issue per current workflow | -| No manual task creation | Not an issue per current workflow | -| No content regeneration | Not an issue per current workflow | -| Review → Published manual only | Not an issue per current workflow | -| ContentView missing actions bar | Not an issue per current workflow | -| No send_to_linker action | Linker not active module | - ---- - -### Implementation Notes - -**For Issue #1 (Status progression):** -- Allow status changes from any tab/view without forcing navigation -- Consider unified content list with status filter instead of separate pages -- Or add status change dropdown/buttons within each view - -**For Issue #2 (Images integration):** -- Show image thumbnails within ContentView -- Allow image generation from ContentView -- Show image count on content list items - -**For Issue #3 (Duplicate tags/categories):** -- Audit ContentView.tsx template -- Find and remove duplicate rendering of tags and categories -- Should display once in appropriate section - ---- - -## 3.3 Automation - -**Route:** `/automation` -**Files:** `pages/Automation/AutomationPage.tsx` (or Dashboard.tsx) -**Tabs:** None (single page) - -### Current Functionality -- Pipeline overview (7 stages: Keywords → Clusters → Ideas → Tasks → Content → Image Prompts → Images) -- Schedule configuration (frequency, time, enable/disable) -- Run controls (Run Now, Pause, Resume) -- Real-time progress polling -- Metrics display and activity log - ---- - -### Issues to Address - -| # | Issue | Priority | Action | -|---|-------|----------|--------| -| 1 | No stage-by-stage control | Medium | Add toggles to enable/disable individual pipeline stages | -| 2 | No review gate config | Low | Add UI to configure review gate rules (Stage 7) | -| 3 | No error recovery | High | Add retry capability for failed items (per-item or per-stage) | -| 4 | No batch size config | Medium | Add setting to throttle items processed per run | -| 5 | No dry run/preview | Medium | Add preview mode to show what WOULD be processed before running | -| 6 | Activity log not filterable | Medium | Add filters: by stage, status, date | -| 7 | Credit estimation unclear | High | Clarify labeling - consistent terminology (credits vs content pieces) | -| 8 | Run history depth unknown | Low | Add pagination to run history | -| 9 | No indication of manual vs automated | Low | Show source indicator for processed items | - ---- - -### Implementation Notes - -**Critical Constraint:** All changes must NOT affect the actual AI functions that run on module pages. Automation uses the same functions - only UI/control changes, not function logic. - -**For Issue #1 (Stage toggles):** -- Add on/off toggle for each of the 7 stages -- When stage is off, automation skips it -- Visual indicator showing which stages are active - -**For Issue #3 (Error recovery):** -- Show failed items in activity log with "Retry" button -- Option to retry all failed items from a run -- Clear error messages explaining what failed - -**For Issue #5 (Dry run/preview):** -- "Preview Run" button shows list of items that would be processed -- Shows count per stage -- User can then confirm or cancel - -**For Issue #7 (Credit estimation):** -- Use consistent terminology matching the pricing simplification plan -- Show estimated cost before running - ---- - -## 3.4 Linker - -**Status:** ❌ NOT ACTIVE MODULE - Skipped - -Not part of current phase. No issues to address. - ---- - -## 3.5 Optimizer - -**Status:** ❌ NOT ACTIVE MODULE - Skipped - -Not part of current phase. No issues to address. - ---- - -## 3.6 WORKFLOW Cross-Module Issues - -### Issues to Address - -| # | Issue | Priority | Action | -|---|-------|----------|--------| -| 1 | No Planner → Writer visibility | Medium | After queuing ideas to writer, provide clear feedback and link to Writer | -| 2 | No cross-module notifications | High | Log all AI runs in notification dropdown (bell icon) with correct end results | -| 3 | Progress modals have wrong texts | High | Fix placeholder text, wrong wording, inaccurate counts (showing "X" or placeholders) | -| 4 | Progress modal counts inaccurate | High | Ensure counts reflect actual items being processed | -| 5 | No breadcrumb navigation | Medium | Add breadcrumbs showing workflow path (Cluster → Idea → Task → Content) | -| 6 | No "Next Step" suggestions | Medium | After each action, suggest what to do next | - ---- - -### Issues NOT Being Addressed (Per Discussion) - -| Issue | Reason | -|-------|--------| -| No Writer → Linker integration | Linker not active module | -| No Writer → Optimizer integration | Optimizer not active module | - ---- - -### Implementation Notes - -**For Issue #2 (Notifications):** -- Bell icon dropdown should show log of all AI function runs -- Each entry shows: function type, status (success/failed/in-progress), timestamp -- Include runs from: Clustering, Idea Generation, Content Generation, Image Generation -- Show result: "Generated 5 ideas from Cluster X" or "Failed: insufficient credits" -- Link to relevant content/page - -**For Issues #3 & #4 (Progress modals):** -- Audit all progress modals across modules -- Replace placeholder text ("X", "processing...", wrong labels) -- Ensure counts match actual items: - - "Processing 5 of 12 keywords" (not "Processing X of Y") - - "Generated 3 ideas" (actual count, not placeholder) -- Match text to actual AI function being performed -- Consistent terminology across all modals - -**Progress Modals to Audit:** -- Keyword clustering modal -- Idea generation modal -- Content generation modal -- Image prompt extraction modal -- Image generation modal -- Any bulk operation modals - ---- - -## Summary - -### Total Issues by Section - -| Section | High | Medium | Low | Total | -|---------|------|--------|-----|-------| -| 3.1 Planner | 2 | 3 | 1 | 6 | -| 3.2 Writer | 3 | 0 | 0 | 3 | -| 3.3 Automation | 2 | 5 | 2 | 9 | -| 3.4 Linker | - | - | - | Skipped | -| 3.5 Optimizer | - | - | - | Skipped | -| 3.6 Cross-Module | 2 | 4 | 0 | 6 | -| **TOTAL** | **9** | **12** | **3** | **24** | - ---- - -### High Priority Items - -1. **Planner** - Delete KeywordOpportunities page and all references -2. **Planner** - Add cluster progress indicator (which have ideas) -3. **Writer** - Fix status progression confusion -4. **Writer** - Integrate images into content workflow -5. **Writer** - Fix duplicate tags/categories in ContentView -6. **Automation** - Add error recovery/retry for failed items -7. **Automation** - Clarify credit/content terminology -8. **Cross-Module** - Fix progress modal texts and counts -9. **Cross-Module** - Implement notification logging for AI runs - ---- - -### Files to Delete - -| File | Reason | -|------|--------| -| `pages/Planner/KeywordOpportunities.tsx` | Orphaned page, Add Keywords is source of truth | - ---- - -### Files to Modify - -| File | Changes | -|------|---------| -| `pages/Planner/Keywords.tsx` | Remove any KeywordOpportunities references | -| `pages/Planner/Clusters.tsx` | Add ideas count badge, "Generate Ideas" prominence | -| `pages/Planner/Ideas.tsx` | Add queued count indicator, clickable cluster name | -| `pages/Writer/Tasks.tsx` | Streamline status changes | -| `pages/Writer/Drafts.tsx` | Streamline status changes | -| `pages/Writer/ContentView.tsx` | Fix duplicate tags/categories, integrate images | -| `pages/Writer/Images.tsx` | Better integration with content workflow | -| `pages/Writer/Review.tsx` | Streamline status changes | -| `pages/Automation/AutomationPage.tsx` | Stage toggles, batch size, preview, filters, error retry | -| All progress modal components | Fix placeholder text, counts, wording | -| Notification dropdown component | Add AI run logging | -| Router/App.tsx | Remove KeywordOpportunities route | -| Sidebar component | Remove KeywordOpportunities link if present | - ---- - -### Backend Work Required - -| Area | Work | -|------|------| -| Automation stage control | API to save stage enable/disable preferences | -| Automation batch size | API to save batch size setting | -| Error recovery | API to retry failed items | -| Notification logging | Ensure AI runs are logged for notification display | - ---- -## After Implementation -Section 3 implementation is complete. Here's a summary of all changes made: - -## Section 3 WORKFLOW Modules - Implementation Complete ✅ - -### Completed Tasks: - -1. **Delete KeywordOpportunities.tsx** ✅ - - Deleted the orphaned page file - - Removed import and route from App.tsx - - Updated PAGES.md documentation - -2. **Add cluster ideas badge** ✅ - - Modified clusters.config.tsx - - Ideas column now shows badge: "X ideas" (green) or "No ideas" (gray) - -3. **Fix ContentView duplicate tags/categories** ✅ - - Modified ContentViewTemplate.tsx - - Removed duplicate tags/categories section that appeared below metadata - -4. **Fix progress modal placeholder texts** ✅ - - Modified ProgressModal.tsx - - Fixed "X" placeholders in step labels with cleaner fallbacks - - "Mapping Content for X Image Prompts" → "Mapping content for image prompts" - - "Writing X In‑article Image Prompts" → "Writing In‑article Image Prompts" - - Success message fallback cleaned up - -5. **Add queued count to Ideas** ✅ - - Already implemented via headerMetrics showing New/Queued/Completed counts - -6. **Clickable cluster in Ideas** ✅ - - Modified ideas.config.tsx - - Cluster name now links to `/planner/clusters/:id` - -### Documentation Updated: -- CHANGELOG.md - Added v1.1.5 section -- ENDPOINTS.md - Added Content Settings API docs -- PAGES.md - Removed KeywordOpportunities, updated version \ No newline at end of file diff --git a/to-do-s/part1/SECTION_4_FINAL_MODS.md b/to-do-s/part1/SECTION_4_FINAL_MODS.md deleted file mode 100644 index 63e26381..00000000 --- a/to-do-s/part1/SECTION_4_FINAL_MODS.md +++ /dev/null @@ -1,397 +0,0 @@ -# Section 4: ACCOUNT Modules - Audit & Action Plan - -**Date:** December 27, 2025 -**Status:** Finalized for Implementation -**Scope:** Account Settings, Plans & Billing, Usage (AI Models excluded - admin only) - ---- - -## 4.1 Account Settings - -**Route:** `/account/settings` -**File:** `pages/account/AccountSettingsPage.tsx` -**Tabs:** Account, Profile, Team - -### Current Functionality -- **Account Tab:** Organization name, billing email, full billing address, tax ID/VAT -- **Profile Tab:** First/last name, email, phone, timezone, language, notifications, security -- **Team Tab:** List team members, invite via email, remove members, role display - ---- - -### Issues to Address - -| # | Issue | Priority | Action | -|---|-------|----------|--------| -| 1 | Profile NOT connected to API | 🔴 Critical | Study existing backend - if profile API exists and is consistent with system, connect it. If not present, create consistent with existing API structure | -| 2 | Change Password does nothing | 🔴 Critical | Implement password change functionality | -| 3 | No role assignment on invite | High | Add role dropdown (Admin/Member) to invitation form | -| 4 | No role editing for members | High | Add ability to change member role after invitation | -| 5 | No email verification | High | Implement email verification flow when email is changed | -| 6 | Orphaned TeamManagement.tsx | High | Delete `pages/account/TeamManagement.tsx` - functionality exists in AccountSettingsPage | -| 7 | No 2FA option | Medium | Add two-factor authentication option in security section | -| 8 | No account deletion | Medium | Add account closure/deletion capability | -| 9 | No session management | Medium | Add view/revoke active sessions capability | -| 10 | No pending invitation management | Medium | Add ability to resend or cancel pending invitations | -| 11 | No team member limit display | Medium | Show "X of Y team members" based on plan limit | -| 12 | Inconsistent role system | Medium | Backend returns `is_admin` boolean but UI shows Admin/Member - align these | - ---- - -### Implementation Notes - -**For Issue #1 (Profile API):** -- First: Audit backend to check if profile endpoint exists -- If exists: Study implementation, verify consistency with other APIs, then connect frontend -- If not exists: Create new endpoint following existing API patterns in the codebase -- Fields to persist: first_name, last_name, email, phone, timezone, language, notification preferences - -**For Issue #2 (Password change):** -- Implement secure password change requiring current password -- Validate new password meets requirements -- Consider session invalidation after password change - -**For Issue #12 (Role consistency):** -- Decide on role system: boolean `is_admin` or role enum (admin/member/viewer) -- Align frontend display with backend data structure - ---- - -## 4.2 Plans & Billing - -**Route:** `/account/plans` -**Files:** `pages/account/PlansAndBillingPage.tsx`, `pages/Billing/CreditPurchase.tsx` -**Tabs:** Current Plan, Upgrade Plan, History - -### Current Functionality -- **Current Plan:** Plan name, status, credits, balance, renewal date, features -- **Upgrade:** Pricing table, plan comparison, change policy -- **History:** Invoices with PDF download, payments, payment methods - -### Payment Context -Currently using manual payment methods only (bank transfer, wallet). No automatic payment processing. - ---- - -### Issues to Address - -| # | Issue | Priority | Action | -|---|-------|----------|--------| -| 1 | No proration preview | High | Show prorated amount before plan upgrade/downgrade | -| 2 | Credit purchase not linked | Medium | Link to credit purchase from Plans & Billing page | -| 3 | Cancellation is immediate | High | Add confirmation dialog before plan cancellation | -| 4 | No downgrade proration display | Medium | Show calculation when downgrading plan | -| 5 | Throttling errors surface to users | Medium | Replace raw throttling messages with user-friendly spinner/message | -| 6 | No billing cycle visualization | Medium | Make renewal date prominent, show billing cycle clearly | -| 7 | No cancellation reason collection | Low | Add optional reason selection when cancelling | - ---- - -### Issues NOT Being Addressed (Per Discussion) - -| Issue | Reason | -|-------|--------| -| No payment failure retry | Manual payment only - no auto-retry needed | -| Payment method UI incomplete | Manual payment only - limited methods by design | - ---- - -### Implementation Notes - -**For Issue #1 (Proration preview):** -- Before confirming plan change, show: - - Current plan remaining value - - New plan cost - - Prorated amount due/credited -- Calculate based on days remaining in billing cycle - -**For Issue #3 (Cancellation confirmation):** -- Modal dialog: "Are you sure you want to cancel?" -- Show what they'll lose (features, remaining credits) -- Require explicit confirmation - -**For Issue #5 (Throttling messages):** -- Intercept throttling errors -- Show spinner with "Processing your request..." instead of technical error -- Implement proper retry logic behind the scenes - ---- - -## 4.3 Usage - -**Route:** `/account/usage` -**Files:** `pages/account/UsageAnalyticsPage.tsx`, `pages/account/UsageLimits.tsx`, `pages/account/CreditActivity.tsx` -**Tabs:** Your Limits & Usage, Credit History, API Activity - -### Current Functionality -- **Quick Stats:** Credits left, used this month, monthly limit, usage % -- **Limits:** Hard limits (sites, users, keywords, clusters) + Monthly limits -- **Credit History:** Transaction log with type, amount, description -- **API Activity:** Call statistics, endpoint breakdown - ---- - -### Issues to Address - -| # | Issue | Priority | Action | -|---|-------|----------|--------| -| 1 | API Activity is HARDCODED | 🔴 Critical | Implement real API activity tracking - replace fake values (1,234, 567, 342) | -| 2 | Success rate is fake | 🔴 Critical | Calculate and display real success rate from actual data | -| 3 | No usage alerts | High | Implement default alerts at usage thresholds (80%, 90%, 100%) - sent to all users automatically | -| 4 | No per-site usage | High | Add breakdown showing which site consumed what | -| 5 | No usage forecasting | Medium | Add "At current rate, you'll reach limit in X days" | -| 6 | No actionable insights | Medium | Suggest upgrade when approaching limits | -| 7 | Credit history lacks context | Medium | Add links from credit transactions to related content/operations | - ---- - -### Issues NOT Being Addressed (Per Discussion) - -| Issue | Reason | -|-------|--------| -| No per-user usage | Not needed for current phase | -| No usage export | Not needed for current phase | - ---- - -### Implementation Notes - -**For Issue #1 & #2 (Real API Activity):** -- Backend needs to log API calls (may already exist) -- Track: endpoint, timestamp, status (success/fail), response time -- Aggregate for display: total calls, success rate, calls by endpoint -- Replace hardcoded values with real calculated data - -**For Issue #3 (Usage alerts):** -- Default behavior: all users receive alerts -- Trigger points: 80%, 90%, 100% of limits -- Delivery: in-app notification + email -- No user preferences needed - alerts go to everyone - -**For Issue #4 (Per-site usage):** -- Break down credit usage by site -- Show: "Site A: 450 credits, Site B: 230 credits" -- Pie chart or table visualization - ---- - -## 4.4 AI Models (Admin Only) - -**Status:** ❌ SKIP ENTIRELY - -Not part of user-facing modules. Admin only - no changes needed. - ---- - -## 4.5 ACCOUNT Cross-Module Issues (MAJOR) - -These are architectural issues requiring proper analysis and solutions. - -### Issues to Address - -| # | Issue | Priority | Action | -|---|-------|----------|--------| -| 1 | Multiple credit balance sources | 🔴 Critical | Establish ONE source of truth for credit balance. Analyze: Plans page, Usage page, billingStore - determine which is authoritative, remove others, refactor all references | -| 2 | Fragmented billing pages | High | **AI Agent Task:** Audit system to identify all billing-related pages/functions, find duplicates/redundancies, propose consolidation solution | -| 3 | Legacy routes still exist | High | Remove legacy routes (`/billing/overview`, `/team`, `/profile`), remove redirect code, refactor any references throughout codebase | -| 4 | No notification preferences | Low | Not needed - default alerts go to all users | - ---- - -### Implementation Notes - -**For Issue #1 (Single source of truth for balance):** - -*Phase 1: Analysis* -- Identify all places that fetch/display credit balance: - - `billingStore.ts` (Zustand store) - - Plans & Billing page - - Usage page - - Dashboard (if applicable) - - Header component (if showing balance) -- Document how each fetches data (API endpoint, frequency) - -*Phase 2: Decision* -- Determine which should be THE source: - - Likely `billingStore` as central state management - - Single API endpoint for balance data -- All components should read from this one source - -*Phase 3: Implementation* -- Refactor all components to use single source -- Remove duplicate API calls -- Remove duplicate state management -- Ensure consistency across all views - -**For Issue #2 (Fragmented billing pages):** - -*AI Agent Audit Task:* -``` -TASK: Billing Pages Consolidation Audit - -1. DISCOVER all billing-related files: - - pages/account/PlansAndBillingPage.tsx - - pages/Billing/CreditPurchase.tsx - - pages/Billing/Credits.tsx (if exists) - - pages/Settings/CreditsAndBilling.tsx (if exists) - - Any other billing-related pages - -2. ANALYZE each page: - - What functionality does it provide? - - What routes point to it? - - Is it actively used or orphaned? - - Does it duplicate functionality from another page? - -3. IDENTIFY redundancies: - - Same functionality in multiple places - - Overlapping features - - Dead/orphaned pages - -4. PROPOSE solution: - - Which pages to keep - - Which pages to merge - - Which pages to delete - - Final consolidated structure - -5. DOCUMENT migration path: - - What routes need updating - - What references need changing - - What imports need refactoring -``` - -**For Issue #3 (Legacy routes removal):** - -*Routes to remove:* -- `/billing/overview` -- `/team` -- `/profile` - -*Process:* -1. Find route definitions in router/App.tsx -2. Remove route entries -3. Find and remove redirect logic -4. Search codebase for any links to these routes -5. Update or remove those links -6. Delete any orphaned components only used by these routes - ---- - -## Summary - -### Total Issues by Section - -| Section | Critical | High | Medium | Low | Total | -|---------|----------|------|--------|-----|-------| -| 4.1 Account Settings | 2 | 4 | 6 | 0 | 12 | -| 4.2 Plans & Billing | 0 | 2 | 4 | 1 | 7 | -| 4.3 Usage | 2 | 2 | 3 | 0 | 7 | -| 4.4 AI Models | - | - | - | - | Skipped | -| 4.5 Cross-Module | 1 | 2 | 0 | 1 | 4 | -| **TOTAL** | **5** | **10** | **13** | **2** | **30** | - ---- - -### Critical Items (Must Fix) - -1. **Account Settings** - Profile tab not connected to API -2. **Account Settings** - Password change does nothing -3. **Usage** - API Activity tab shows hardcoded fake data -4. **Usage** - Success rate is fake (98.5%) -5. **Cross-Module** - Multiple credit balance sources causing inconsistency - ---- - -### High Priority Items - -1. Account Settings - Role assignment on invite -2. Account Settings - Role editing for members -3. Account Settings - Email verification -4. Account Settings - Delete orphaned TeamManagement.tsx -5. Plans & Billing - Proration preview -6. Plans & Billing - Cancellation confirmation dialog -7. Usage - Usage alerts at thresholds -8. Usage - Per-site usage breakdown -9. Cross-Module - Billing pages consolidation audit -10. Cross-Module - Legacy routes removal - ---- - -### Files to Delete - -| File | Reason | -|------|--------| -| `pages/account/TeamManagement.tsx` | Orphaned - functionality in AccountSettingsPage | -| Legacy route redirect handlers | After removing `/billing/overview`, `/team`, `/profile` | -| Duplicate billing pages | After consolidation audit determines which to remove | - ---- - -### Files to Modify - -| File | Changes | -|------|---------| -| `pages/account/AccountSettingsPage.tsx` | Connect profile API, implement password change, add role management, add invitation management | -| `pages/account/PlansAndBillingPage.tsx` | Add proration preview, cancellation confirmation, link credit purchase | -| `pages/account/UsageAnalyticsPage.tsx` | Implement real API activity, add per-site breakdown, add forecasting | -| `store/billingStore.ts` | Establish as single source of truth for balance | -| Router/App.tsx | Remove legacy routes | -| All components using credit balance | Refactor to use single source | - ---- - -### Backend Work Required - -| Area | Work | -|------|------| -| Profile API | Audit existing endpoint OR create new one consistent with API structure | -| Password change API | Implement secure password change endpoint | -| API Activity tracking | Ensure backend logs API calls, create endpoint to retrieve activity data | -| Usage alerts | Backend service to check thresholds and trigger notifications | -| Per-site usage | Endpoint to return credit usage broken down by site | - ---- - -### AI Agent Specific Tasks - -| Task | Description | -|------|-------------| -| Billing Pages Audit | Discover all billing pages, analyze functionality, identify redundancies, propose consolidation | -| Credit Balance Refactor | Identify all balance sources, determine single source, refactor all references | -| Legacy Routes Cleanup | Remove routes, remove redirects, update all references | -| Profile API Study | Check if endpoint exists, verify consistency, connect or create | - ---- - - -## ✅ Section 4 Implementation Complete - -### CRITICAL Items Completed: - -1. **Profile API Connection** (AccountSettingsPage.tsx) - - Profile tab now loads user data from `useAuthStore` - - Added `getUserProfile()` and `updateUserProfile()` functions to billing.api.ts - -2. **Password Change Implementation** (AccountSettingsPage.tsx) - - Added password change modal with old/new password fields - - Connected to `/auth/change-password/` backend endpoint - - Added validation (min 8 chars, confirmation match) - -3. **Fixed Fake API Activity Data** (UsageAnalyticsPage.tsx) - - Removed hardcoded values (98.5%, 1,234, 567, 342) - - API tab now shows real data from `analytics?.usage_by_type` - - Displays "Operations by Type" with actual credits/counts - -### HIGH Priority Items Completed: - -4. **Deleted TeamManagementPage.tsx** - - Removed orphaned file (functionality already exists as tab in AccountSettingsPage) - -5. **Added Cancellation Confirmation Dialog** (PlansAndBillingPage.tsx) - - Cancel button now shows confirmation modal - - Modal explains consequences (loss of features, credit preservation) - - User must confirm before cancellation proceeds - -6. **Legacy Routes Verified** - - `/billing/overview` → Points to CreditsAndBilling page - - `/account/team` → Redirects to `/account/settings` - - `/settings/profile` → Redirects to `/account/settings` \ No newline at end of file diff --git a/to-do-s/part1/SECTION_5_FINAL_MODS.md b/to-do-s/part1/SECTION_5_FINAL_MODS.md deleted file mode 100644 index 1dbb2497..00000000 --- a/to-do-s/part1/SECTION_5_FINAL_MODS.md +++ /dev/null @@ -1,652 +0,0 @@ -# Section 5: HELP Module - Audit & Action Plan - -**Date:** December 27, 2025 -**Status:** Finalized for Implementation -**Scope:** Help Center, Documentation, Support Channels - ---- - -## 5.1 Help & Docs - -**Route:** `/help` -**File:** `pages/Help/HelpCenter.tsx` - -### Current Functionality -- Table of Contents with jump-to-section navigation -- Getting Started: Quick Start Guide, Workflow Overview -- Planner Module: Keywords, Clusters, Ideas documentation -- Writer Module: Tasks, Content, Images documentation -- Automation Setup overview -- FAQ section (~20 questions) -- Support CTA buttons (non-functional) - ---- - -### Issues to Address - -| # | Issue | Priority | Action | -|---|-------|----------|--------| -| 1 | Support dropdown link broken | 🔴 Critical | Fix link - currently goes to `/profile` which is 404 | -| 2 | Contact Support button does nothing | 🔴 Critical | Implement mailto: or external support URL | -| 3 | Feature Request button does nothing | 🔴 Critical | Implement mailto: or external feedback URL | -| 4 | No actual support channel | 🔴 Critical | Configure working support email/system | -| 5 | Placeholder pages exist | High | **DELETE** `/help/docs`, `/help/system-testing`, `/help/function-testing` pages | -| 6 | No search functionality | Medium | Add search within help content | -| 7 | No contextual help | Low | Consider adding in-app tooltips or "?" icons (future) | -| 8 | Stale content risk | Medium | Help content is hardcoded in TSX - document update process | - ---- - -### Pages to Delete - -| File | Route | Reason | -|------|-------|--------| -| `pages/Help/Documentation.tsx` | `/help/docs` | Empty placeholder - not needed | -| `pages/Help/SystemTesting.tsx` | `/help/system-testing` | Empty placeholder - not needed | -| `pages/Help/FunctionTesting.tsx` | `/help/function-testing` | Empty placeholder - not needed | - ---- - -## 5.2 Documentation Requirements (NEW) - -### Documentation Approach - -Create detailed, step-by-step documentation for each module and flow. Documentation should be: -- **Easy to use** - Clear language, no technical jargon -- **Step-by-step** - Numbered instructions with expected outcomes -- **Visual** - Screenshots or diagrams where helpful -- **Current** - Matches exactly how the system is implemented - ---- - -### Modules to Document - -| Module | Status | Documentation Needed | -|--------|--------|---------------------| -| **Dashboard** | Active | Overview, metrics explanation, navigation | -| **Add Keywords** | Active | How to browse, filter, select, add keywords | -| **Content Settings** | Active | Content Generation, Publishing, Image Settings tabs | -| **Sites** | Active | Site creation, WordPress integration, site management | -| **Planner - Keywords** | Active | Adding, managing, clustering keywords | -| **Planner - Clusters** | Active | Understanding clusters, generating ideas | -| **Planner - Ideas** | Active | Managing ideas, queueing to writer | -| **Writer - Queue** | Active | Task management, content generation | -| **Writer - Drafts** | Active | Reviewing drafts, status management | -| **Writer - Images** | Active | Image generation, management | -| **Writer - Review** | Active | Review process, approval workflow | -| **Writer - Published** | Active | Published content, WordPress sync | -| **Automation** | Active | Pipeline setup, scheduling, monitoring | -| **Account Settings** | Active | Account, Profile, Team management | -| **Plans & Billing** | Active | Plans, upgrades, payment, invoices | -| **Usage** | Active | Understanding limits, credit usage, history | -| Linker | ❌ Not Active | Skip - not documenting | -| Optimizer | ❌ Not Active | Skip - not documenting | -| Sites/Site Builder | ❌ Not Active | Skip - legacy feature removed | -| Thinker | Admin Only | Skip - not user-facing | - ---- - -### Documentation Structure - -For each module, document: - -``` -## [Module Name] - -### Overview -Brief description of what this module does and its purpose in the workflow. - -### How to Access -- Navigation path to reach this module -- Direct URL - -### Step-by-Step Guide - -#### [Task 1 Name] -1. Step one with specific instruction -2. Step two with expected result -3. Step three... - -#### [Task 2 Name] -1. Step one... -2. Step two... - -### Key Features -- Feature 1: What it does -- Feature 2: What it does - -### Tips & Best Practices -- Tip 1 -- Tip 2 - -### Common Questions -Q: Question? -A: Answer - -### Troubleshooting -- Problem: X - Solution: Y -``` - ---- - -### Detailed Documentation Outlines - -#### Dashboard Documentation - -``` -## Dashboard - -### Overview -Your command center showing workflow progress, key metrics, and quick actions. - -### Metrics Explained -- Keywords: Total keywords in your workflow -- Articles: Content pieces created -- Images: Images generated -- Completion %: Overall workflow progress - -### Workflow Progress -Visual pipeline showing: Sites → Keywords → Clusters → Ideas → Content → Published - -### Quick Actions -- [Action 1]: What it does, when to use -- [Action 2]: What it does, when to use - -### Setup Checklist -Understanding the setup completion indicator... -``` - -#### Add Keywords Documentation - -``` -## Add Keywords - -### Overview -Browse and add keywords from our curated database to your content workflow. - -### Prerequisites -- Active site with industry and sector selected - -### Step-by-Step: Adding Keywords - -1. Navigate to SETUP → Add Keywords -2. Browse available keywords filtered by your site's industry/sector -3. Use filters to narrow results: - - Search: Find specific keywords - - Country: Filter by target country - - Difficulty: Filter by SEO difficulty -4. Select keywords by clicking checkboxes -5. Click "Add to Workflow" button -6. Keywords are now in your Planner - -### After Adding Keywords -Click "Next: Plan Your Content →" to proceed to the Planner module. - -### Tips -- Start with 10-20 keywords to test your workflow -- Mix high and low difficulty keywords -- Focus on your core topics first -``` - -#### Planner Documentation - -``` -## Planner - -### Overview -Organize keywords into topic clusters and generate content ideas. - -### The Planner Flow -Keywords → Clusters → Ideas → Writer Queue - ---- - -### Keywords Tab - -#### Adding Keywords Manually -1. Click "Add Keyword" button -2. Enter keyword text -3. Set initial status -4. Save - -#### Clustering Keywords -1. Select keywords to cluster (checkboxes) -2. Click "Auto-Cluster" button -3. AI analyzes and groups related keywords -4. Review created clusters in Clusters tab - ---- - -### Clusters Tab - -#### Understanding Clusters -Clusters group related keywords by topic for focused content creation. - -#### Generating Ideas from Clusters -1. Select cluster(s) to generate ideas for -2. Click "Generate Ideas" button -3. AI creates content ideas based on cluster keywords -4. Review ideas in Ideas tab - -#### Cluster Progress -- Badge shows "X ideas" for clusters with generated ideas -- "No ideas yet" indicates pending clusters - ---- - -### Ideas Tab - -#### Reviewing Ideas -Each idea shows: title, target keyword, cluster source - -#### Sending Ideas to Writer -1. Select ideas to write (checkboxes) -2. Click "Queue to Writer" button -3. Ideas become tasks in Writer Queue -``` - -#### Writer Documentation - -``` -## Writer - -### Overview -Generate, review, and publish AI-created content. - -### The Writer Flow -Queue → Drafts → Review → Published - ---- - -### Queue Tab (Tasks) - -#### Understanding Tasks -Tasks are content pieces waiting to be generated. - -#### Generating Content -1. Find task in queue -2. Click "Generate Content" action -3. AI writes the article -4. Content moves to Drafts - ---- - -### Drafts Tab - -#### Reviewing Drafts -1. Click on draft to view full content -2. Review AI-generated article -3. Check content quality and accuracy - -#### Moving to Review -1. Select draft(s) -2. Change status to "Review" -3. Content moves to Review tab - ---- - -### Images Tab - -#### Generating Images -1. Select content needing images -2. Click "Generate Images" -3. AI creates images based on content -4. Images attach to content - ---- - -### Review Tab - -#### Final Review Process -1. Review content and images together -2. Make any final adjustments -3. Approve for publishing - -#### Publishing to WordPress -1. Select reviewed content -2. Click "Publish" button -3. Content syncs to WordPress -4. Moves to Published tab - ---- - -### Published Tab - -#### Viewing Published Content -- See all published articles -- WordPress sync status -- Publication dates -``` - -#### Automation Documentation - -``` -## Automation - -### Overview -Automate your entire content pipeline from keywords to published articles. - -### Pipeline Stages -1. Keywords → Clustering -2. Clusters → Idea Generation -3. Ideas → Task Creation -4. Tasks → Content Generation -5. Content → Image Prompt Extraction -6. Prompts → Image Generation -7. Review Gate - ---- - -### Setting Up Automation - -#### Configure Schedule -1. Set frequency (daily, weekly, etc.) -2. Set preferred run time -3. Enable/disable automation - -#### Stage Controls -Enable or disable individual stages as needed. - -#### Batch Size -Set how many items process per run. - ---- - -### Running Automation - -#### Manual Run -Click "Run Now" to start pipeline immediately. - -#### Monitoring Progress -- Real-time progress display -- Stage-by-stage status -- Activity log - -#### Handling Errors -- Failed items shown in log -- Click "Retry" to reprocess failed items - ---- - -### Best Practices -- Start with small batch sizes -- Monitor first few runs closely -- Review automation output regularly -``` - -#### Account Settings Documentation - -``` -## Account Settings - -### Overview -Manage your account, profile, and team. - ---- - -### Account Tab -- Organization name -- Billing email -- Billing address -- Tax ID/VAT number - ---- - -### Profile Tab -- Personal information (name, email, phone) -- Timezone and language preferences -- Notification settings -- Security settings (password, 2FA) - -#### Changing Password -1. Go to Profile tab -2. Click "Change Password" -3. Enter current password -4. Enter and confirm new password -5. Save changes - ---- - -### Team Tab - -#### Inviting Team Members -1. Click "Invite Member" -2. Enter email address -3. Select role (Admin or Member) -4. Send invitation - -#### Managing Members -- View all team members -- Change member roles -- Remove members - -#### Team Limits -Your plan allows X team members. Currently using Y. -``` - -#### Plans & Billing Documentation - -``` -## Plans & Billing - -### Overview -Manage your subscription, view invoices, and track payments. - ---- - -### Current Plan Tab -- Plan name and features -- Credit balance -- Renewal date -- Usage summary - ---- - -### Upgrade Plan Tab - -#### Changing Plans -1. Review available plans -2. Compare features -3. Click "Upgrade" on desired plan -4. Review proration (credit for remaining time) -5. Confirm change - -#### Cancelling Plan -1. Click "Cancel Plan" -2. Review what you'll lose -3. Confirm cancellation - ---- - -### History Tab -- Invoice history with PDF download -- Payment records -- Payment method management -``` - -#### Usage Documentation - -``` -## Usage - -### Overview -Track your credit usage, limits, and activity. - ---- - -### Your Limits & Usage Tab - -#### Understanding Limits -- **Hard Limits:** Maximum allowed (sites, users, keywords) -- **Monthly Limits:** Reset each billing cycle - -#### Credit Balance -- Credits remaining -- Credits used this month -- Monthly allocation - ---- - -### Credit History Tab -Transaction log showing all credit activity: -- Credit additions (plan, purchases) -- Credit usage (content, images, etc.) - ---- - -### API Activity Tab -- Total API calls -- Success rate -- Activity by endpoint - ---- - -### Usage Alerts -Automatic alerts at 80%, 90%, and 100% of limits. -``` - ---- - -## 5.3 FAQ Updates - -### Current FAQ Topics (~20 questions) -Review and update existing FAQ to ensure accuracy. - -### Additional FAQ Topics Needed - -| Topic | Questions to Add | -|-------|------------------| -| Credits | How credits work, what uses credits, credit costs | -| Automation | How to set up, troubleshooting, best practices | -| WordPress | Integration setup, sync issues, troubleshooting | -| Content | Generation tips, quality settings, editing | -| Images | Generation options, formats, sizes | -| Billing | Payment methods, invoices, plan changes | - ---- - -## Summary - -### Total Issues - -| Category | Critical | High | Medium | Low | Total | -|----------|----------|------|--------|-----|-------| -| Support/Links | 4 | 0 | 0 | 0 | 4 | -| Pages to Delete | 0 | 1 | 0 | 0 | 1 | -| Features | 0 | 0 | 2 | 1 | 3 | -| Documentation | 0 | 1 | 0 | 0 | 1 | -| **TOTAL** | **4** | **2** | **2** | **1** | **9** | - ---- - -### Critical Items (Must Fix) - -1. Fix Support dropdown link (currently 404) -2. Implement Contact Support button (mailto: or support URL) -3. Implement Feature Request button (mailto: or feedback URL) -4. Configure working support channel - ---- - -### High Priority Items - -1. Delete placeholder pages (`/help/docs`, `/help/system-testing`, `/help/function-testing`) -2. Create comprehensive step-by-step documentation for all active modules - ---- - -### Files to Delete - -| File | Reason | -|------|--------| -| `pages/Help/Documentation.tsx` | Empty placeholder | -| `pages/Help/SystemTesting.tsx` | Empty placeholder | -| `pages/Help/FunctionTesting.tsx` | Empty placeholder | - ---- - -### Files to Modify - -| File | Changes | -|------|---------| -| `pages/Help/HelpCenter.tsx` | Fix support link, implement button handlers, add comprehensive documentation, update FAQ | -| Router/App.tsx | Remove routes for deleted help pages | - ---- - -### Documentation Modules (Do NOT Document) - -| Module | Reason | -|--------|--------| -| Linker | Not active | -| Optimizer | Not active | -| Sites/Site Builder | Legacy feature removed | -| Thinker | Admin only - not user-facing | - ---- - -### Documentation Deliverables - -Create detailed step-by-step documentation for: - -1. ✅ Dashboard -2. ✅ Add Keywords -3. ✅ Content Settings -4. ✅ Sites (WordPress integration focus, not site builder) -5. ✅ Planner - Keywords -6. ✅ Planner - Clusters -7. ✅ Planner - Ideas -8. ✅ Writer - Queue/Tasks -9. ✅ Writer - Drafts -10. ✅ Writer - Images -11. ✅ Writer - Review -12. ✅ Writer - Published -13. ✅ Automation -14. ✅ Account Settings -15. ✅ Plans & Billing -16. ✅ Usage - ---- - - -## Section 5 HELP Module - All CRITICAL Items Fixed: - -1. **Fixed Support Dropdown Links** (UserDropdown.tsx) - - "Edit profile" → `/account/settings` - - "Account settings" → `/account/settings` - - "Support" → `/help` - -2. **Implemented Contact Support Button** (Help.tsx) - - Now opens `mailto:support@igny8.com?subject=Support Request` - -3. **Implemented Feature Request Button** (Help.tsx) - - Now opens `mailto:feedback@igny8.com?subject=Feature Request` - -### Section 5 HIGH Priority Items: - -4. **Deleted Placeholder Pages** - - Docs.tsx ❌ - - SystemTesting.tsx ❌ - - FunctionTesting.tsx ❌ - -5. **Removed Routes from App.tsx** - - `/help/docs`, `/help/system-testing`, `/help/function-testing` - -6. **Added Comprehensive Documentation** (Help.tsx) - - **Dashboard** section - Metrics, Pipeline, Setup Checklist - - **Setup Module** section - Add Keywords, Content Settings, Sites Management - - **Account & Billing** section - Account Settings, Plans & Billing, Usage & Limits - - **8 new FAQ items** covering credits, billing, WordPress, automation - -### Files Changed: -- CHANGELOG.md - Updated to v1.1.7 -- PAGES.md - Updated to v1.1.7 -- App.tsx - Removed placeholder imports/routes -- UserDropdown.tsx - Fixed all links -- Help.tsx - Full documentation overhaul - -### Files Deleted: -- Docs.tsx -- SystemTesting.tsx -- FunctionTesting.tsx diff --git a/to-do-s/part1/SECTION_6_FINAL_MODS.md b/to-do-s/part1/SECTION_6_FINAL_MODS.md deleted file mode 100644 index fb5cd041..00000000 --- a/to-do-s/part1/SECTION_6_FINAL_MODS.md +++ /dev/null @@ -1,494 +0,0 @@ -# Section 6: Sidebar & Navigation - Audit & Action Plan - -**Date:** December 27, 2025 -**Status:** Finalized for Implementation -**Scope:** Sidebar structure, navigation restructure (tabs → sidebar dropdowns) - ---- - -## 6.1 Current Navigation Structure - -**File:** `layout/AppSidebar.tsx` - -``` -Dashboard (standalone) -├─ SETUP -│ ├─ Add Keywords → /setup/add-keywords -│ ├─ Content Settings → /account/content-settings -│ ├─ Sites → /sites -│ └─ Thinker (admin only) → /thinker/prompts -├─ WORKFLOW -│ ├─ Planner → /planner/keywords -│ ├─ Writer → /writer/tasks -│ ├─ Automation → /automation -│ ├─ Linker → /linker/content [NOT ACTIVE - REMOVE] -│ └─ Optimizer → /optimizer/content [NOT ACTIVE - REMOVE] -├─ ACCOUNT -│ ├─ Account Settings → /account/settings -│ ├─ Plans & Billing → /account/plans -│ ├─ Usage → /account/usage -│ └─ AI Models (admin only) → /settings/integration -└─ HELP - └─ Help & Docs → /help -``` - -### Current In-Page Navigation (TO BE REMOVED) - -| Module | Current Tabs/Buttons | Location | -|--------|---------------------|----------| -| **Planner** | Keywords, Clusters, Ideas | Tab buttons in page header | -| **Writer** | Queue, Drafts, Images, Review, Published | Tab buttons in page header | -| **Account Settings** | Account, Profile, Team | Tabs in page | -| **Plans & Billing** | Current Plan, Upgrade Plan, History | Tabs in page | -| **Usage** | Your Limits & Usage, Credit History, API Activity | Tabs in page | -| **Content Settings** | Content Generation, Publishing, Image Settings | Tabs in page | - ---- - -## 6.2 Issues to Address - -| # | Issue | Priority | Action | -|---|-------|----------|--------| -| 1 | Linker in navigation | High | **REMOVE** - not active module | -| 2 | Optimizer in navigation | High | **REMOVE** - not active module | -| 3 | KeywordOpportunities reference | High | **REMOVE** - page being deleted | -| 4 | Help sub-pages in routes | High | **REMOVE** - pages being deleted | -| 5 | Menu order incorrect | High | Reorder SETUP: Sites → Add Keywords → Content Settings → Thinker | -| 6 | Tabs/buttons clutter page headers | High | **MOVE to sidebar dropdowns** | -| 7 | No breadcrumb navigation | Medium | Add breadcrumbs (space now available in header) | -| 8 | No "Next Step" guidance | Medium | Add contextual next step (space now available in header) | -| 9 | No active section highlighting | Medium | Highlight current section/page in sidebar | -| 10 | Credit purchase not in sidebar | Low | Accessible from Plans & Billing | - ---- - -## 6.3 New Navigation Structure: Sidebar Dropdowns - -### Decision: Move All Sub-Navigation to Sidebar - -**Rationale:** -- New app launch - no existing user patterns to unlearn -- Desktop-only app - no mobile concerns -- Same number of clicks - active dropdown stays expanded automatically -- Cleaner page headers - space for breadcrumbs and "Next Step" CTAs -- Better discoverability - all navigation visible in one place -- Scalable - easy to add new sub-pages in future -- Consistent pattern across all modules - -### New Sidebar Structure - -``` -Dashboard - -SETUP -├─ Sites ▼ -│ ├─ All Sites → /sites -│ └─ Site Settings → /sites/:id/settings (contextual) -├─ Add Keywords → /setup/add-keywords -├─ Content Settings ▼ -│ ├─ Content Generation → /account/content-settings/generation -│ ├─ Publishing → /account/content-settings/publishing -│ └─ Image Settings → /account/content-settings/images -└─ Thinker (admin only) ▼ - ├─ Prompts → /thinker/prompts - └─ Author Profiles → /thinker/author-profiles - -WORKFLOW -├─ Planner ▼ -│ ├─ Keywords → /planner/keywords -│ ├─ Clusters → /planner/clusters -│ └─ Ideas → /planner/ideas -├─ Writer ▼ -│ ├─ Queue → /writer/tasks -│ ├─ Drafts → /writer/drafts -│ ├─ Images → /writer/images -│ ├─ Review → /writer/review -│ └─ Published → /writer/published -└─ Automation → /automation - -ACCOUNT -├─ Account Settings ▼ -│ ├─ Account → /account/settings/account -│ ├─ Profile → /account/settings/profile -│ └─ Team → /account/settings/team -├─ Plans & Billing ▼ -│ ├─ Current Plan → /account/plans/current -│ ├─ Upgrade Plan → /account/plans/upgrade -│ └─ History → /account/plans/history -├─ Usage ▼ -│ ├─ Limits & Usage → /account/usage/limits -│ ├─ Credit History → /account/usage/credits -│ └─ API Activity → /account/usage/api -└─ AI Models (admin only) → /settings/integration - -HELP -└─ Help & Docs → /help -``` - ---- - -## 6.4 Sidebar Behavior Specification - -### Dropdown Behavior - -1. **Active Page Detection:** - - When user navigates to any page, its parent dropdown auto-expands - - Current page is highlighted within the dropdown - - Active dropdown stays expanded - does NOT collapse - -2. **Click Behavior:** - - Click on dropdown parent (if not expanded) → expands dropdown - - Click on dropdown parent (if expanded) → collapses dropdown - - Click on sub-item → navigates to that page, dropdown stays open - - Only active page's dropdown auto-opens on page load - -3. **Visual States:** - ``` - Planner ▼ ← Parent: expanded indicator - Keywords ← Normal sub-item - Clusters ● ← Active page: highlighted - Ideas ← Normal sub-item - - Writer ▶ ← Collapsed (not active) - ``` - -4. **Persistence:** - - Active dropdown remains expanded during navigation within that module - - On direct URL access or refresh, opens dropdown containing current page - - Non-active dropdowns default to collapsed state - -### Example Flow - -User is on `/planner/clusters`: - -``` -WORKFLOW -├─ Planner ▼ [EXPANDED - contains active page] -│ ├─ Keywords [clickable] -│ ├─ Clusters ● [ACTIVE - highlighted] -│ └─ Ideas [clickable] -├─ Writer ▶ [COLLAPSED] -└─ Automation [no dropdown - single page] -``` - -User clicks "Ideas": -- Navigates to `/planner/ideas` -- Planner dropdown stays expanded -- "Ideas" becomes highlighted -- "Clusters" returns to normal state - -User clicks "Writer": -- Writer dropdown expands -- Planner dropdown can stay expanded or collapse (design choice) -- Shows Writer sub-items - ---- - -## 6.5 Page Header Structure (After Tabs Removal) - -### Before (Current) -``` -┌─────────────────────────────────────────────────────────────────────┐ -│ [Keywords] [Clusters] [Ideas] [+ Add] [Bulk ▼] [Filter] [Search] │ -├─────────────────────────────────────────────────────────────────────┤ -│ Content area... │ -``` - -### After (New) -``` -┌─────────────────────────────────────────────────────────────────────┐ -│ Planner > Clusters [+ Add] [Bulk ▼] [Next: Ideas →] │ -├─────────────────────────────────────────────────────────────────────┤ -│ [Filter] [Search...] │ -├─────────────────────────────────────────────────────────────────────┤ -│ Content area... │ -``` - -### Header Components - -| Component | Position | Purpose | -|-----------|----------|---------| -| Breadcrumb | Left | Shows: Section > Page (e.g., "Planner > Clusters") | -| Primary Actions | Center-Right | Add, Bulk actions | -| Next Step CTA | Right | Contextual "Next: [Action] →" button | -| Filters/Search | Below header or inline | Data filtering | - ---- - -## 6.6 Breadcrumb Implementation - -### Breadcrumb Pattern - -``` -[Section] > [Page] -[Section] > [Page] > [Detail] -``` - -### Examples - -| Route | Breadcrumb Display | -|-------|-------------------| -| `/planner/keywords` | Planner > Keywords | -| `/planner/clusters` | Planner > Clusters | -| `/planner/clusters/:id` | Planner > Clusters > [Cluster Name] | -| `/writer/drafts` | Writer > Drafts | -| `/writer/drafts/:id` | Writer > Drafts > [Content Title] | -| `/account/settings/team` | Account Settings > Team | -| `/account/plans/upgrade` | Plans & Billing > Upgrade Plan | - -### Implementation - -- Create reusable `` component -- Each page defines its breadcrumb trail via props or route config -- Clickable links except for current page (last item) - ---- - -## 6.7 "Next Step" CTA Implementation - -### Contextual Next Steps - -| Current Location | Condition | Next Step CTA | -|------------------|-----------|---------------| -| Sites | Site created | "Next: Add Keywords →" | -| Add Keywords | Keywords added (count > 0) | "Next: Plan Your Content →" | -| Planner > Keywords | Has unclustered keywords | "Next: Cluster Keywords →" | -| Planner > Clusters | Cluster selected/has clusters | "Next: Generate Ideas →" | -| Planner > Ideas | Has ideas | "Next: Queue to Writer →" | -| Writer > Queue | Has tasks | "Next: Generate Content →" | -| Writer > Drafts | Has drafts | "Next: Review Drafts →" | -| Writer > Review | Has reviewed content | "Next: Publish →" | - -### Implementation - -- Create `` component -- Each page determines when to show and what action -- Button styled prominently but not intrusive -- Links to logical next step in workflow - ---- - -## 6.8 Route Updates Required - -### Routes to Add/Update - -To support sidebar navigation, routes need restructuring: - -| Current Route | New Route | Notes | -|---------------|-----------|-------| -| `/account/content-settings` | `/account/content-settings/generation` | Default to first sub-page | -| (same page, different tab) | `/account/content-settings/publishing` | Separate route | -| (same page, different tab) | `/account/content-settings/images` | Separate route | -| `/account/settings` | `/account/settings/account` | Default to first sub-page | -| (same page, different tab) | `/account/settings/profile` | Separate route | -| (same page, different tab) | `/account/settings/team` | Separate route | -| `/account/plans` | `/account/plans/current` | Default to first sub-page | -| (same page, different tab) | `/account/plans/upgrade` | Separate route | -| (same page, different tab) | `/account/plans/history` | Separate route | -| `/account/usage` | `/account/usage/limits` | Default to first sub-page | -| (same page, different tab) | `/account/usage/credits` | Separate route | -| (same page, different tab) | `/account/usage/api` | Separate route | - -### Routes to Remove - -| Route | Reason | -|-------|--------| -| `/linker/*` | Module not active | -| `/optimizer/*` | Module not active | -| `/planner/keyword-opportunities` | Page deleted | -| `/help/docs` | Page deleted | -| `/help/system-testing` | Page deleted | -| `/help/function-testing` | Page deleted | -| `/billing/overview` | Legacy route | -| `/team` | Legacy route | -| `/profile` | Legacy route | - ---- - -## 6.9 Implementation Plan - -### Phase 1: Sidebar Restructure - -1. **Update `AppSidebar.tsx`:** - - Add dropdown functionality for multi-page modules - - Implement expand/collapse with active state detection - - Remove Linker and Optimizer - - Reorder SETUP: Sites → Add Keywords → Content Settings → Thinker - - Add visual indicators (▼ expanded, ▶ collapsed, ● active) - -2. **Create dropdown data structure:** - ```typescript - const sidebarConfig = [ - { - section: 'SETUP', - items: [ - { label: 'Sites', path: '/sites', icon: Globe }, - { label: 'Add Keywords', path: '/setup/add-keywords', icon: Key }, - { - label: 'Content Settings', - icon: Settings, - children: [ - { label: 'Content Generation', path: '/account/content-settings/generation' }, - { label: 'Publishing', path: '/account/content-settings/publishing' }, - { label: 'Image Settings', path: '/account/content-settings/images' }, - ] - }, - // ... etc - ] - }, - // ... other sections - ]; - ``` - -### Phase 2: Route Updates - -1. **Update Router/App.tsx:** - - Add new sub-routes for tabbed pages - - Set up redirects from parent routes to default child - - Remove deleted/inactive routes - -2. **Example route structure:** - ```typescript - // Content Settings - } /> - } /> - } /> - } /> - ``` - -### Phase 3: Page Header Updates - -1. **Remove tab components from all pages:** - - Planner (Keywords, Clusters, Ideas tabs) - - Writer (Queue, Drafts, Images, Review, Published tabs) - - Account Settings (Account, Profile, Team tabs) - - Plans & Billing (Current, Upgrade, History tabs) - - Usage (Limits, Credits, API tabs) - - Content Settings (Generation, Publishing, Images tabs) - -2. **Add Breadcrumb component to each page** - -3. **Add NextStepCTA component where applicable** - -4. **Reorganize header layout:** - - Left: Breadcrumb - - Right: Actions + Next Step CTA - -### Phase 4: Component Creation - -1. **Create `components/navigation/Breadcrumb.tsx`** -2. **Create `components/navigation/NextStepCTA.tsx`** -3. **Create `components/navigation/SidebarDropdown.tsx`** (if not using existing UI library component) - ---- - -## Summary - -### Total Issues - -| Category | High | Medium | Low | Total | -|----------|------|--------|-----|-------| -| Remove inactive modules | 2 | 0 | 0 | 2 | -| Remove deleted pages | 2 | 0 | 0 | 2 | -| Menu order | 1 | 0 | 0 | 1 | -| Navigation restructure | 1 | 0 | 0 | 1 | -| New features | 0 | 3 | 1 | 4 | -| **TOTAL** | **6** | **3** | **1** | **10** | - ---- - -### High Priority Items - -1. Remove Linker from sidebar navigation -2. Remove Optimizer from sidebar navigation -3. Remove KeywordOpportunities route references -4. Remove Help sub-page routes -5. Reorder SETUP menu: Sites → Add Keywords → Content Settings → Thinker -6. **Implement sidebar dropdown navigation (replace all tabs)** - ---- - -### Medium Priority Items - -1. Add breadcrumb navigation component -2. Add "Next Step" contextual guidance -3. Add active section highlighting in sidebar - ---- - -### Files to Delete - -| File | Reason | -|------|--------| -| Tab components in page headers | Replaced by sidebar navigation | -| Any standalone tab navigation components | No longer needed | - ---- - -### Files to Create - -| File | Purpose | -|------|---------| -| `components/navigation/Breadcrumb.tsx` | Reusable breadcrumb component | -| `components/navigation/NextStepCTA.tsx` | Contextual next step button | -| Possibly split page components | If current tabbed pages are single files, may need to split | - ---- - -### Files to Modify - -| File | Changes | -|------|---------| -| `layout/AppSidebar.tsx` | Complete restructure with dropdowns, remove inactive modules, reorder | -| `Router/App.tsx` | Add sub-routes, remove inactive routes, add redirects | -| `pages/Planner/*.tsx` | Remove tab navigation from header | -| `pages/Writer/*.tsx` | Remove tab navigation from header | -| `pages/account/AccountSettingsPage.tsx` | Split into separate route components OR remove tabs | -| `pages/account/PlansAndBillingPage.tsx` | Split into separate route components OR remove tabs | -| `pages/account/UsageAnalyticsPage.tsx` | Split into separate route components OR remove tabs | -| `pages/account/ContentSettingsPage.tsx` | Split into separate route components OR remove tabs | -| All page headers | Add Breadcrumb, reorganize layout, add NextStepCTA | - ---- - -### Implementation Decision - -**CONFIRMED: Implement sidebar-based navigation with dropdowns** - -- Remove all tab/button navigation from page headers -- All sub-navigation moves to sidebar as expandable dropdowns -- Active dropdown stays expanded (same click count as current tabs) -- Page headers gain space for breadcrumbs and "Next Step" CTAs -- Clean, consistent navigation pattern across all modules - ---- - - -Section 6 implementation is complete. Here's a summary of what was done: - -## Section 6 Implementation Complete ✅ - -### Sidebar Changes -- **Removed** Linker and Optimizer modules from sidebar (not ready for launch) -- **Reordered** SETUP menu: Sites → Add Keywords → Content Settings → Thinker -- **Added dropdown sub-items** for all major modules with clickable navigation - -### URL-Based Tab Navigation -Account pages now use URL paths instead of internal state for tabs: -- `/account/settings` → Account tab, `/account/settings/profile` → Profile, `/account/settings/team` → Team -- `/account/plans` → Current Plan, `/account/plans/upgrade` → Upgrade, `/account/plans/history` → History -- `/account/usage` → Limits, `/account/usage/credits` → Credits, `/account/usage/activity` → Activity -- `/account/content-settings` → Content Generation, `/account/content-settings/publishing` → Publishing, `/account/content-settings/images` → Images - -### Navigation Cleanup -- **Removed ModuleNavigationTabs** from all module pages (Planner, Writer, Thinker, Sites) -- **Added breadcrumb prop** to PageHeader component -- All pages now display breadcrumb navigation (e.g., "Planner / Keywords") - -### Files Modified -- AppSidebar.tsx - Sidebar restructure -- App.tsx - Added sub-routes -- PageHeader.tsx - Added breadcrumb prop -- 4 account pages - URL-based tab navigation -- 3 Planner pages, 5 Writer pages, 4 Thinker pages, 1 Sites page - Removed tabs, added breadcrumbs -- CHANGELOG.md - Updated to v1.1.8 diff --git a/to-do-s/part2/PRICING-SIMPLIFICATION.md b/to-do-s/part2/PRICING-SIMPLIFICATION.md deleted file mode 100644 index 5c93ea80..00000000 --- a/to-do-s/part2/PRICING-SIMPLIFICATION.md +++ /dev/null @@ -1,308 +0,0 @@ -# IGNY8 Pricing System - Final Simplified Plan - -**Date:** December 26, 2025 -**Status:** APPROVED DIRECTION - ---- - -## 1. Current System Assessment ✅ - -The existing token-based credit system is **correct and safe**: -- ✅ `CreditCostConfig` with `tokens_per_credit` ratio per operation -- ✅ `min_credits` per operation (floor protection) -- ✅ Actual tokens calculated after AI call (accurate margin) -- ✅ Model-aware pricing (different models = different costs) - -**Keep this system. Just simplify the limits and UI.** - ---- - -## 2. Actual Cost Analysis (From Production Data) - -### Per-Article Cost Breakdown (GPT-4.1 pricing) - -| Stage | Input Tokens | Output Tokens | Actual Cost | -|-------|--------------|---------------|-------------| -| Clustering (per article share*) | ~400 | ~400 | **$0.005** | -| Idea Generation (per article share*) | ~900 | ~1000 | **$0.012** | -| Content Writing | 2500 | 3500 | **$0.041** | -| Image Prompt Extraction | 500 | 1100 | **$0.012** | -| **Text Subtotal** | | | **$0.07** | -| Images (3 avg @ $0.04) | | | **$0.12** | -| **TOTAL PER ARTICLE** | | | **$0.19** | - -*With 6 images (max): **$0.31 per article** - -### Target Markup: 10-15x - -| Scenario | Our Cost | 10x Price | 15x Price | -|----------|----------|-----------|-----------| -| Article (3 images) | $0.19 | $1.90 | $2.85 | -| Article (6 images) | $0.31 | $3.10 | $4.65 | - ---- - -## 3. Simplified Credit Pricing (10x Markup) - -### 3.1 Credit Cost per Operation - -Using **1 credit = $0.01** and **10x markup**: - -| Operation | Actual Cost | Target Price | Credits | -|-----------|-------------|--------------|---------| -| Clustering | $0.005 | $0.05 | **5** | -| Idea Generation | $0.012 | $0.12 | **10** | -| Content Writing | $0.041 | $0.41 | **40** | -| Image Prompts | $0.012 | $0.12 | **10** | -| Image (per image) | $0.04 | $0.40 | **40** | -| Linking | $0.003 | $0.03 | **3** | -| Optimization | $0.005 | $0.05 | **5** | - -### 3.2 Full Article Workflow Cost - -| Workflow | Calculation | Total Credits | -|----------|-------------|---------------| -| Text only | 5 + 10 + 40 + 10 = 65 | **65 credits** | -| + 3 images | 65 + (3 × 40) = 185 | **185 credits** | -| + 6 images | 65 + (6 × 40) = 305 | **305 credits** | -| + linking + optimization | +3 +5 = +8 | **+8 credits** | - -**Typical article: ~200 credits = $2.00** (at 10x margin) - ---- - -## 4. Simplified Plan Structure - -### 4.1 Remove All Limits Except Keywords - -**DELETE:** -- ❌ max_content_ideas -- ❌ max_content_words -- ❌ max_images_basic -- ❌ max_images_premium -- ❌ max_image_prompts -- ❌ max_clusters (soft limit via credits) -- ❌ All usage tracking fields - -**KEEP:** -- ✅ Credits (token-based, monthly allocation) -- ✅ max_keywords (storage limit, defines plan tier) -- ✅ max_sites, max_users (account management) - -### 4.2 New Plan Tiers - -| Plan | Price | Credits/Month | Keywords | Sites | Users | ~Articles | -|------|-------|---------------|----------|-------|-------|-----------| -| **Free** | $0 | 200 | 100 | 1 | 1 | ~1 | -| **Starter** | $29 | 3,000 | 1,000 | 3 | 3 | ~15 | -| **Growth** | $79 | 10,000 | 5,000 | 10 | 10 | ~50 | -| **Scale** | $199 | 30,000 | Unlimited | ∞ | ∞ | ~150 | - -**Simple value proposition:** -- Starter: ~15 full articles/month for $29 (~$2/article) -- Growth: ~50 full articles/month for $79 (~$1.60/article) -- Scale: ~150 full articles/month for $199 (~$1.33/article) - -### 4.3 Credit Top-Up Pricing - -| Package | Credits | Price | Per Credit | -|---------|---------|-------|------------| -| Small | 500 | $7 | $0.014 | -| Medium | 2,000 | $25 | $0.0125 | -| Large | 5,000 | $55 | $0.011 | -| Bulk | 15,000 | $150 | $0.01 | - ---- - -## 5. Content Length Feature (New) - -### 5.1 Add Word Count Selection - -**Content Settings (Site-level default):** -``` -Target Article Length: [Short ~800] [Medium ~1500] [Long ~2500] [Custom: ___] -``` - -**Idea Generation (per-idea):** -- Include target word count in idea brief -- AI considers length when generating outline - -**Content Generation (per-content):** -- Pass word count to prompt -- Affects token usage (longer = more credits) - -### 5.2 Credit Adjustment for Length - -| Length | Words | Token Estimate | Credits | -|--------|-------|----------------|---------| -| Short | ~800 | 2000 | 25 | -| Medium | ~1500 | 3500 | 40 | -| Long | ~2500 | 5500 | 60 | -| Extra Long | ~4000 | 8000 | 90 | - -**User sees:** "Short article: ~150 credits, Long article: ~250 credits" - ---- - -## 6. Implementation Plan - -### Phase 1: Backend Updates (Day 1-2) - -**6.1 Update CreditCostConfig values:** - -```python -# New fixed credit costs (min_credits = display value) -CREDIT_CONFIGS = { - 'clustering': {'tokens_per_credit': 160, 'min_credits': 5}, - 'idea_generation': {'tokens_per_credit': 190, 'min_credits': 10}, - 'content_generation': {'tokens_per_credit': 150, 'min_credits': 25}, # Base for short - 'image_prompt_extraction': {'tokens_per_credit': 160, 'min_credits': 10}, - 'image_generation': {'tokens_per_credit': 1, 'min_credits': 40}, # Fixed per image - 'linking': {'tokens_per_credit': 300, 'min_credits': 3}, - 'optimization': {'tokens_per_credit': 200, 'min_credits': 5}, -} -``` - -**6.2 Remove monthly limit fields:** - -```python -# Plan model - DELETE these fields -- max_content_ideas -- max_content_words -- max_images_basic -- max_images_premium -- max_image_prompts - -# Account model - DELETE these fields -- usage_content_ideas -- usage_content_words -- usage_images_basic -- usage_images_premium -- usage_image_prompts -- usage_period_start -- usage_period_end -``` - -**6.3 Remove LimitService monthly methods:** -- Delete `check_monthly_limit()` -- Delete `increment_usage()` -- Delete monthly reset task -- Keep `check_hard_limit()` for sites/users/keywords - -### Phase 2: Content Length Feature (Day 2-3) - -**6.4 Add ContentSettings.target_word_count:** - -```python -class ContentSettings(models.Model): - # ... existing fields ... - target_word_count = models.IntegerField( - default=1500, - choices=[(800, 'Short'), (1500, 'Medium'), (2500, 'Long'), (4000, 'Extra Long')], - help_text="Default target word count for articles" - ) -``` - -**6.5 Update AI prompts:** -- `generate_ideas.py` - Include word count in idea brief -- `generate_content.py` - Pass word count target - -### Phase 3: Frontend Updates (Day 3-4) - -**6.6 Update Content Settings page:** -- Add word count selector - -**6.7 Update Usage page:** -- Show credits only (remove monthly limit bars) -- Show keywords used vs limit -- Show simple cost reference - -**6.8 Fix/Replace CreditCostsPanel.tsx:** -- Show fixed credit costs (not token-based confusion) -- Simple table: "Content: 40 credits, Image: 40 credits" - -**6.9 Update Pricing page:** -- New plan structure -- "~X articles/month" messaging - -### Phase 4: Migration & Cleanup (Day 4-5) - -**6.10 Database migration:** -- Remove deprecated fields -- Update existing plans to new structure - -**6.11 Clean up dead code:** -- Remove LimitService monthly tracking -- Remove usage increment calls in services - ---- - -## 7. User Experience (After Simplification) - -### What User Sees: - -**Dashboard:** -``` -Credits: 2,847 / 3,000 remaining -Keywords: 234 / 1,000 -``` - -**Before generating content:** -``` -Estimated cost: ~185 credits -- Content (medium): 40 credits -- Image prompts: 10 credits -- 3 images: 120 credits -- Clustering share: ~5 credits -- Ideas share: ~10 credits -``` - -**Content Settings:** -``` -Article Length: [Short] [Medium ✓] [Long] [Extra Long] -Images per Article: [3 ▼] -``` - -### What Admin Sees: - -**Plans admin:** -- Credits/month -- Keywords limit -- Sites/Users limits -- Price - -**No more:** -- 5 different monthly limit fields -- Usage tracking complexity -- Monthly reset management - ---- - -## 8. Summary - -| Before | After | -|--------|-------| -| Credits + 5 monthly limits | Credits only | -| 9 limit fields per plan | 3 limit fields (credits, keywords, sites) | -| 5 usage tracking fields | 1 field (credits balance) | -| Complex monthly resets | Simple credit allocation | -| Unpredictable costs | Clear cost estimates | -| No length control | Word count selection | - -**Result:** -- ✅ Safe margins (token-based calculation preserved) -- ✅ Simple for user (one number to track) -- ✅ Simple for admin (fewer fields to manage) -- ✅ Predictable (show estimated costs upfront) -- ✅ Flexible (manual or automation workflows work same way) - ---- - -## 9. Immediate Actions - -1. **Update CreditCostConfig** in database with new values -2. **Add target_word_count** to ContentSettings model -3. **Update prompts** to include word count -4. **Remove monthly limit checks** from services -5. **Update frontend** Usage page and CreditCostsPanel -6. **Migration** to remove deprecated fields diff --git a/to-do-s/part2/dashboard_mods.md b/to-do-s/part2/dashboard_mods.md deleted file mode 100644 index 078ee187..00000000 --- a/to-do-s/part2/dashboard_mods.md +++ /dev/null @@ -1,406 +0,0 @@ -# Section 1: Dashboard - Audit & Action Plan - -**Date:** December 27, 2025 -**Status:** Finalized for Implementation (To be done LAST after all other sections complete) -**Scope:** Main dashboard page - metrics, workflow visualization, quick actions - ---- - -## 1.1 Current Functionality - -**Route:** `/` -**Files:** `pages/Dashboard/Home.tsx`, `components/dashboard/*` - -### What Dashboard Currently Shows - -- **Workflow Progress:** 6-step pipeline visualization (Sites → Keywords → Clusters → Ideas → Content → Published) -- **Quick Actions:** 5 navigation shortcuts -- **Key Metrics:** 4 cards (Keywords, Articles, Images, Completion %) -- **Credit Usage:** Monthly allowance and usage bar -- **Workflow Modules Guide:** 8 info cards explaining modules -- **Onboarding:** Site creation wizard for new users - ---- - -## 1.2 Critical Gaps - -| # | Issue | Impact | Priority | -|---|-------|--------|----------| -| 1 | No aggregated API endpoint | Performance - makes 6+ sequential API calls with 120ms delays | 🔴 Critical | -| 2 | Published content count incorrect | Data accuracy - cannot distinguish published vs draft | 🔴 Critical | -| 3 | Usage Summary is hardcoded | Misleading - shows fake "547 credits / $0.34" data | 🔴 Critical | -| 4 | Recent Activity is hardcoded | Misleading - static mock activity that never updates | 🔴 Critical | -| 5 | No real-time updates | Stale data - only refreshes on manual action | High | - ---- - -## 1.3 Missing Professional Features - -| # | Feature | Why Important | Priority | -|---|---------|---------------|----------| -| 6 | Needs Attention section | Users don't know what requires action | High | -| 7 | Recent content activity | No real list of recently created/published content | High | -| 8 | Error/warning alerts | No indication of failed syncs, low credits, config issues | High | -| 9 | Pipeline queue depth | No visibility into items waiting at each stage | Medium | -| 10 | Automation status | No run status, last run time, or items processed | Medium | -| 11 | Site health/sync status | No WordPress sync health indicator | Medium | - ---- - -## 1.4 Workflow Issues - -| # | Issue | Priority | -|---|-------|----------| -| 12 | Quick Actions don't adapt to user state | Medium - shows same 5 actions regardless of workflow stage | -| 13 | Workflow Completion % is misleading | Medium - formula doesn't reflect real content-from-keywords ratio | -| 14 | Modules Guide not dismissible | Low - 8 large cards always shown, no way to hide | -| 15 | Chart widget code exists but unused | Low - dead code, no trend visualization | - ---- - -## 1.5 Issues to Address - -### Critical (Must Fix) - -| # | Issue | Action | -|---|-------|--------| -| 1 | No aggregated API endpoint | Create `/v1/dashboard/summary/` endpoint that returns all dashboard data in single call | -| 2 | Published content count incorrect | Fix query to separate published vs draft status | -| 3 | Usage Summary is hardcoded | Replace with real billing data from billingStore | -| 4 | Recent Activity is hardcoded | Implement real activity log OR remove section entirely | - -### High Priority - -| # | Issue | Action | -|---|-------|--------| -| 5 | No real-time updates | Add polling or websocket for live updates | -| 6 | No "Needs Attention" section | Add widget showing: pending reviews, failed syncs, low credits, incomplete setup | -| 7 | No recent content activity | Show real list of recently created/updated content | -| 8 | No error/warning alerts | Display alerts for: failed WordPress syncs, approaching limits, config issues | - -### Medium Priority - -| # | Issue | Action | -|---|-------|--------| -| 9 | No pipeline queue depth | Show count of items at each workflow stage | -| 10 | No automation status | Display: last run time, items processed, next scheduled run | -| 11 | No site health indicator | Show WordPress connection status per site | -| 12 | Quick Actions don't adapt | Make contextual based on user's workflow state | -| 13 | Completion % misleading | Revise formula to reflect actual workflow progress | - -### Low Priority - -| # | Issue | Action | -|---|-------|--------| -| 14 | Modules Guide not dismissible | Add dismiss/hide option, remember preference | -| 15 | Dead chart widget code | Either implement trend visualization or remove dead code | - ---- - -## 1.6 Dashboard Revamp Specification - -### New Dashboard Layout - -``` -┌─────────────────────────────────────────────────────────────────────────────┐ -│ DASHBOARD │ -├─────────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────────────────────────────────────────────────────────────┐ │ -│ │ NEEDS ATTENTION (if any) │ │ -│ │ ⚠ 3 content pieces pending review [View →] │ │ -│ │ ⚠ WordPress sync failed for Site A [Retry] [Fix] │ │ -│ │ ⚠ Credit usage at 85% [Upgrade →] │ │ -│ └─────────────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ -│ │ Keywords │ │ Articles │ │ Images │ │ Completion │ │ -│ │ 156 │ │ 43 │ │ 127 │ │ 68% │ │ -│ │ +12 this mo │ │ +8 this mo │ │ +24 this mo │ │ ↑ from 52% │ │ -│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────────────┐ │ -│ │ WORKFLOW PIPELINE │ │ -│ │ Sites(2) → Keywords(156) → Clusters(23) → Ideas(67) → Content(43) → Published(38) │ -│ │ ✓ ✓ ✓ 12 pending 5 pending │ │ -│ └─────────────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌────────────────────────────┐ ┌────────────────────────────────────┐ │ -│ │ CONTENT USAGE │ │ QUICK ACTIONS │ │ -│ │ ████████████░░░░ 68/100 │ │ [+ Add Keywords] │ │ -│ │ 68 used this month │ │ [Generate Content] ← contextual │ │ -│ │ Resets in 12 days │ │ [Review Drafts] (5) │ │ -│ └────────────────────────────┘ │ [View Published] │ │ -│ └────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────────────┐ │ -│ │ RECENT ACTIVITY │ │ -│ │ • Generated 5 articles from "Product Reviews" cluster 2 hours ago │ │ -│ │ • Published "Best Running Shoes 2025" to Site A 3 hours ago │ │ -│ │ • Created 12 ideas from keyword clustering Yesterday │ │ -│ │ • Automation run completed: 8 articles generated Yesterday │ │ -│ └─────────────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────────────┐ │ -│ │ AUTOMATION STATUS │ │ -│ │ Status: ● Active Last run: 2 hours ago Next: Tomorrow 9:00 AM │ │ -│ │ Last run: Processed 15 keywords → 3 clusters → 12 ideas → 8 articles │ │ -│ └─────────────────────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────────────┘ -``` - -### Dashboard Components - -| Component | Purpose | Data Source | -|-----------|---------|-------------| -| Needs Attention | Actionable alerts requiring user action | Aggregated from all modules | -| Key Metrics | Overview counts | Aggregated API endpoint | -| Workflow Pipeline | Visual progress through stages | Aggregated API endpoint | -| Content Usage | Credit/content piece usage | billingStore (single source of truth) | -| Quick Actions | Contextual navigation shortcuts | Based on workflow state | -| Recent Activity | Real activity log | Activity tracking system | -| Automation Status | Automation module summary | Automation service | - ---- - -## 1.7 Aggregated API Endpoint - -### Endpoint: `GET /v1/dashboard/summary/` - -**Response Structure:** -```json -{ - "metrics": { - "keywords_total": 156, - "keywords_this_month": 12, - "articles_total": 43, - "articles_this_month": 8, - "articles_draft": 5, - "articles_published": 38, - "images_total": 127, - "images_this_month": 24, - "completion_percentage": 68 - }, - "pipeline": { - "sites": 2, - "keywords": 156, - "clusters": 23, - "ideas": 67, - "ideas_pending": 12, - "content": 43, - "content_pending": 5, - "published": 38 - }, - "usage": { - "credits_used": 68, - "credits_total": 100, - "reset_days": 12 - }, - "alerts": [ - { - "type": "pending_review", - "message": "3 content pieces pending review", - "action_url": "/writer/review", - "action_label": "View" - }, - { - "type": "sync_failed", - "message": "WordPress sync failed for Site A", - "action_url": "/sites/1/settings", - "action_label": "Fix" - } - ], - "recent_activity": [ - { - "type": "content_generated", - "message": "Generated 5 articles from 'Product Reviews' cluster", - "timestamp": "2025-12-27T10:30:00Z" - } - ], - "automation": { - "status": "active", - "last_run": "2025-12-27T08:00:00Z", - "next_run": "2025-12-28T09:00:00Z", - "last_run_summary": "15 keywords → 3 clusters → 12 ideas → 8 articles" - } -} -``` - ---- - -## 1.8 "Needs Attention" Widget Specification - -### Alert Types - -| Type | Trigger | Message | Action | -|------|---------|---------|--------| -| `pending_review` | Content in review status > 0 | "X content pieces pending review" | Link to Writer > Review | -| `sync_failed` | WordPress sync error | "WordPress sync failed for [Site]" | Link to Site Settings | -| `low_credits` | Usage > 80% | "Credit usage at X%" | Link to Upgrade | -| `credits_exhausted` | Usage = 100% | "Monthly content limit reached" | Link to Upgrade | -| `setup_incomplete` | Setup checklist incomplete | "Complete your setup" | Link to incomplete item | -| `automation_failed` | Last automation run had errors | "Automation encountered errors" | Link to Automation | - -### Display Rules - -- Show maximum 3-4 alerts at a time -- Prioritize by severity: errors > warnings > info -- Dismissible alerts (remember dismissal for session) -- Empty state: Hide section entirely when no alerts - ---- - -## 1.9 Quick Actions - Contextual Logic - -### Logic for Displaying Actions - -``` -IF no sites exist: - → "Create Your First Site" - -ELSE IF no keywords: - → "Add Keywords" - -ELSE IF keywords but no clusters: - → "Cluster Keywords" - -ELSE IF clusters but no ideas: - → "Generate Ideas" - -ELSE IF ideas but no content: - → "Generate Content" - -ELSE IF content in draft: - → "Review Drafts (X)" - -ELSE IF content in review: - → "Publish Content (X)" - -ALWAYS show: - → "View Published" (if any published) - → "Run Automation" (if automation configured) -``` - -### Default Actions (Always Available) - -- Add Keywords -- View Planner -- View Writer -- Settings - ---- - -## 1.10 Implementation Notes - -### Data Flow - -1. **On Dashboard Load:** - - Single API call to `/v1/dashboard/summary/` - - Populate all widgets from response - - No sequential calls, no delays - -2. **Real-time Updates (Optional):** - - Poll every 60 seconds for updates - - OR use WebSocket for push updates - - Update only changed data - -3. **Credit Usage:** - - Use billingStore as single source of truth - - Dashboard reads from store, doesn't fetch separately - -### Performance Requirements - -- Dashboard should load in < 2 seconds -- Single API call instead of 6+ sequential calls -- Lazy load Modules Guide (below fold) -- Cache dashboard data for 30 seconds - ---- - -## Summary - -### Total Issues - -| Category | Critical | High | Medium | Low | Total | -|----------|----------|------|--------|-----|-------| -| Data Issues | 4 | 0 | 0 | 0 | 4 | -| Missing Features | 0 | 4 | 4 | 0 | 8 | -| UX Issues | 0 | 0 | 2 | 2 | 4 | -| **TOTAL** | **4** | **4** | **6** | **2** | **16** | - ---- - -### Critical Items (Must Fix) - -1. Create aggregated dashboard API endpoint -2. Fix published content count (distinguish published vs draft) -3. Replace hardcoded usage summary with real data -4. Replace hardcoded recent activity with real data OR remove - ---- - -### High Priority Items - -1. Add "Needs Attention" widget -2. Implement real recent activity log -3. Add error/warning alerts display -4. Add real-time or polling updates - ---- - -### Medium Priority Items - -1. Show pipeline queue depth (items at each stage) -2. Add automation status display -3. Add site health/sync indicator -4. Make Quick Actions contextual -5. Fix completion percentage formula -6. Integrate Setup Completion Checklist - ---- - -### Files to Create - -| File | Purpose | -|------|---------| -| `components/dashboard/NeedsAttention.tsx` | Alerts widget | -| `components/dashboard/AutomationStatus.tsx` | Automation summary widget | -| `components/dashboard/RecentActivity.tsx` | Real activity log | -| Backend: `api/views/dashboard.py` | Aggregated endpoint | - ---- - -### Files to Modify - -| File | Changes | -|------|---------| -| `pages/Dashboard/Home.tsx` | Complete revamp with new layout | -| `components/dashboard/CreditBalanceWidget.tsx` | Connect to billingStore single source | -| `components/dashboard/WorkflowProgress.tsx` | Add queue depth indicators | -| `components/dashboard/QuickActions.tsx` | Add contextual logic | -| `components/dashboard/KeyMetrics.tsx` | Connect to aggregated API | - ---- - -### Backend Work Required - -| Area | Work | -|------|------| -| Aggregated API | Create `/v1/dashboard/summary/` endpoint | -| Activity Logging | Ensure all actions are logged for activity feed | -| Alert Aggregation | Collect alerts from all modules | -| Pipeline Counts | Query for items at each workflow stage | - ---- - -### Dependencies - -**Dashboard should be implemented LAST because it depends on:** - -- Section 2 (SETUP): Setup Completion Checklist -- Section 3 (WORKFLOW): Pipeline data, activity logging -- Section 4 (ACCOUNT): Credit balance single source of truth -- Section 6 (Navigation): Consistent navigation patterns - ----