automation and ai and some planning and fixes adn docs reorg
This commit is contained in:
@@ -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:
|
||||
<SiteSetupChecklist
|
||||
siteId={site.id}
|
||||
siteName={site.name}
|
||||
hasIndustry={!!site.industry}
|
||||
hasSectors={site.sectors_count > 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)
|
||||
@@ -87,7 +87,7 @@ 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]:
|
||||
"""
|
||||
@@ -102,6 +102,7 @@ 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:
|
||||
@@ -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'
|
||||
|
||||
@@ -307,10 +307,11 @@ 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
|
||||
@@ -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)}"
|
||||
|
||||
@@ -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__)
|
||||
@@ -36,6 +36,113 @@ class PromptRegistry:
|
||||
'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,
|
||||
@@ -61,48 +168,8 @@ class PromptRegistry:
|
||||
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)
|
||||
|
||||
|
||||
@@ -123,6 +123,36 @@ class Tasks(SoftDeletableModel, SiteSectorBaseModel):
|
||||
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):
|
||||
"""
|
||||
|
||||
@@ -121,7 +121,7 @@ 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]:
|
||||
"""
|
||||
@@ -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', ''),
|
||||
|
||||
193
docs/fixes/footer-widget-pagination-fix.md
Normal file
193
docs/fixes/footer-widget-pagination-fix.md
Normal file
@@ -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
|
||||
<ThreeWidgetFooter
|
||||
pageProgress={{
|
||||
metrics: [
|
||||
{ label: 'Total', value: totalCount },
|
||||
{ label: 'Status 1', value: totalWithStatus1, percentage: `${totalCount > 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.
|
||||
311
docs/plans/flexible-model-configuration-plan.md
Normal file
311
docs/plans/flexible-model-configuration-plan.md
Normal file
@@ -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
|
||||
@@ -38,6 +38,10 @@ export default function Clusters() {
|
||||
const [clusters, setClusters] = useState<Cluster[]>([]);
|
||||
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={{
|
||||
|
||||
@@ -41,6 +41,10 @@ export default function Ideas() {
|
||||
const [clusters, setClusters] = useState<Cluster[]>([]);
|
||||
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={{
|
||||
|
||||
@@ -46,6 +46,11 @@ export default function Keywords() {
|
||||
const [clusters, setClusters] = useState<Cluster[]>([]);
|
||||
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={{
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
<SiteSetupChecklist
|
||||
siteId={site.id}
|
||||
siteName={site.name}
|
||||
hasIndustry={!!site.industry}
|
||||
hasSectors={site.sectors_count > 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
|
||||
@@ -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/<pk>/` 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)
|
||||
|
||||
@@ -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
|
||||
@@ -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`
|
||||
@@ -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
|
||||
@@ -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 `<Breadcrumb />` 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 `<NextStepCTA />` 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
|
||||
<Route path="/account/content-settings" element={<Navigate to="/account/content-settings/generation" />} />
|
||||
<Route path="/account/content-settings/generation" element={<ContentSettingsGeneration />} />
|
||||
<Route path="/account/content-settings/publishing" element={<ContentSettingsPublishing />} />
|
||||
<Route path="/account/content-settings/images" element={<ContentSettingsImages />} />
|
||||
```
|
||||
|
||||
### 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
---
|
||||
Reference in New Issue
Block a user