automation and ai and some planning and fixes adn docs reorg

This commit is contained in:
IGNY8 VPS (Salman)
2025-12-29 01:41:36 +00:00
parent 748de099dd
commit 53fdebf733
20 changed files with 927 additions and 4288 deletions

View File

@@ -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 Inarticle 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)

View File

@@ -87,13 +87,13 @@ class AICore:
response_format: Optional[Dict] = None,
api_key: Optional[str] = None,
function_name: str = 'ai_request',
function_id: Optional[str] = None,
prompt_prefix: Optional[str] = None,
tracker: Optional[ConsoleStepTracker] = None
) -> Dict[str, Any]:
"""
Centralized AI request handler with console logging.
All AI text generation requests go through this method.
Args:
prompt: Prompt text
model: Model name (required - must be provided from IntegrationSettings)
@@ -102,12 +102,13 @@ class AICore:
response_format: Optional response format dict (for JSON mode)
api_key: Optional API key override
function_name: Function name for logging (e.g., 'cluster_keywords')
prompt_prefix: Optional prefix to add before prompt (e.g., '##GP01-Clustering')
tracker: Optional ConsoleStepTracker instance for logging
Returns:
Dict with 'content', 'input_tokens', 'output_tokens', 'total_tokens',
'model', 'cost', 'error', 'api_id'
Raises:
ValueError: If model is not provided
"""
@@ -184,16 +185,16 @@ class AICore:
else:
tracker.ai_call("Using text response format")
# Step 4: Validate prompt length and add function_id
# Step 4: Validate prompt length and add prompt_prefix
prompt_length = len(prompt)
tracker.ai_call(f"Prompt length: {prompt_length} characters")
# Add function_id to prompt if provided (for tracking)
# Add prompt_prefix to prompt if provided (for tracking)
# Format: ##GP01-Clustering or ##CP01-Clustering
final_prompt = prompt
if function_id:
function_id_prefix = f'function_id: "{function_id}"\n\n'
final_prompt = function_id_prefix + prompt
tracker.ai_call(f"Added function_id to prompt: {function_id}")
if prompt_prefix:
final_prompt = f'{prompt_prefix}\n\n{prompt}'
tracker.ai_call(f"Added prompt prefix: {prompt_prefix}")
# Step 5: Build request payload
url = 'https://api.openai.com/v1/chat/completions'

View File

@@ -306,12 +306,13 @@ class AIEngine:
ai_core = AICore(account=self.account)
function_name = fn.get_name()
# Generate function_id for tracking (ai-{function_name}-01)
# Normalize underscores to hyphens to match frontend tracking IDs
function_id_base = function_name.replace('_', '-')
function_id = f"ai-{function_id_base}-01-desktop"
# Generate prompt prefix for tracking (e.g., ##GP01-Clustering or ##CP01-Clustering)
# This replaces function_id and indicates whether prompt is global or custom
from igny8_core.ai.prompts import get_prompt_prefix_for_function
prompt_prefix = get_prompt_prefix_for_function(function_name, account=self.account)
logger.info(f"[AIEngine] Using prompt prefix: {prompt_prefix}")
# Get model config from settings (requires account)
# This will raise ValueError if IntegrationSettings not configured
try:
@@ -349,7 +350,7 @@ class AIEngine:
temperature=model_config.get('temperature'),
response_format=model_config.get('response_format'),
function_name=function_name,
function_id=function_id # Pass function_id for tracking
prompt_prefix=prompt_prefix # Pass prompt prefix for tracking (replaces function_id)
)
except Exception as e:
error_msg = f"AI call failed: {str(e)}"

View File

@@ -3,7 +3,7 @@ Prompt Registry - Centralized prompt management with override hierarchy
Supports: task-level overrides → DB prompts → GlobalAIPrompt (REQUIRED)
"""
import logging
from typing import Dict, Any, Optional
from typing import Dict, Any, Optional, Tuple
from django.db import models
logger = logging.getLogger(__name__)
@@ -16,10 +16,10 @@ class PromptRegistry:
2. DB prompt for (account, function)
3. GlobalAIPrompt (REQUIRED - no hardcoded fallbacks)
"""
# Removed ALL hardcoded prompts - GlobalAIPrompt is now the ONLY source of default prompts
# To add/modify prompts, use Django admin: /admin/system/globalaiprompt/
# Mapping from function names to prompt types
FUNCTION_TO_PROMPT_TYPE = {
'auto_cluster': 'clustering',
@@ -35,7 +35,114 @@ class PromptRegistry:
'generate_service_page': 'service_generation',
'generate_taxonomy': 'taxonomy_generation',
}
# Mapping of prompt types to their prefix numbers and display names
# Format: {prompt_type: (number, display_name)}
# GP = Global Prompt, CP = Custom Prompt
PROMPT_PREFIX_MAP = {
'clustering': ('01', 'Clustering'),
'ideas': ('02', 'Ideas'),
'content_generation': ('03', 'ContentGen'),
'image_prompt_extraction': ('04', 'ImagePrompts'),
'site_structure_generation': ('05', 'SiteStructure'),
'optimize_content': ('06', 'OptimizeContent'),
'product_generation': ('07', 'ProductGen'),
'service_generation': ('08', 'ServiceGen'),
'taxonomy_generation': ('09', 'TaxonomyGen'),
'image_prompt_template': ('10', 'ImageTemplate'),
'negative_prompt': ('11', 'NegativePrompt'),
}
@classmethod
def get_prompt_prefix(cls, prompt_type: str, is_custom: bool) -> str:
"""
Generate prompt prefix for tracking.
Args:
prompt_type: The prompt type (e.g., 'clustering', 'ideas')
is_custom: True if using custom/account-specific prompt, False if global
Returns:
Prefix string like "##GP01-Clustering" or "##CP01-Clustering"
"""
prefix_info = cls.PROMPT_PREFIX_MAP.get(prompt_type, ('00', prompt_type.title()))
number, display_name = prefix_info
prefix_type = 'CP' if is_custom else 'GP'
return f"##{prefix_type}{number}-{display_name}"
@classmethod
def get_prompt_with_metadata(
cls,
function_name: str,
account: Optional[Any] = None,
task: Optional[Any] = None,
context: Optional[Dict[str, Any]] = None
) -> Tuple[str, bool, str]:
"""
Get prompt for a function with metadata about source.
Priority:
1. task.prompt_override (if task provided and has override)
2. DB prompt for (account, function) - marked as custom if is_customized=True
3. GlobalAIPrompt (REQUIRED - no hardcoded fallbacks)
Args:
function_name: AI function name (e.g., 'auto_cluster', 'generate_ideas')
account: Account object (optional)
task: Task object with optional prompt_override (optional)
context: Additional context for prompt rendering (optional)
Returns:
Tuple of (prompt_string, is_custom, prompt_type)
- prompt_string: The rendered prompt
- is_custom: True if using custom/account prompt, False if global
- prompt_type: The prompt type identifier
"""
# Step 1: Get prompt type
prompt_type = cls.FUNCTION_TO_PROMPT_TYPE.get(function_name, function_name)
# Step 2: Check task-level override (always considered custom)
if task and hasattr(task, 'prompt_override') and task.prompt_override:
logger.info(f"Using task-level prompt override for {function_name}")
prompt = task.prompt_override
return cls._render_prompt(prompt, context or {}), True, prompt_type
# Step 3: Try DB prompt (account-specific)
if account:
try:
from igny8_core.modules.system.models import AIPrompt
db_prompt = AIPrompt.objects.get(
account=account,
prompt_type=prompt_type,
is_active=True
)
# Check if prompt is customized
is_custom = db_prompt.is_customized
logger.info(f"Using {'customized' if is_custom else 'default'} account prompt for {function_name} (account {account.id})")
prompt = db_prompt.prompt_value
return cls._render_prompt(prompt, context or {}), is_custom, prompt_type
except Exception as e:
logger.debug(f"No account-specific prompt found for {function_name}: {e}")
# Step 4: Try GlobalAIPrompt (platform-wide default) - REQUIRED
try:
from igny8_core.modules.system.global_settings_models import GlobalAIPrompt
global_prompt = GlobalAIPrompt.objects.get(
prompt_type=prompt_type,
is_active=True
)
logger.info(f"Using global default prompt for {function_name} from GlobalAIPrompt")
prompt = global_prompt.prompt_value
return cls._render_prompt(prompt, context or {}), False, prompt_type
except Exception as e:
error_msg = (
f"ERROR: Global prompt '{prompt_type}' not found for function '{function_name}'. "
f"Please configure it in Django admin at: /admin/system/globalaiprompt/. "
f"Error: {e}"
)
logger.error(error_msg)
raise ValueError(error_msg)
@classmethod
def get_prompt(
cls,
@@ -46,63 +153,23 @@ class PromptRegistry:
) -> str:
"""
Get prompt for a function with hierarchical resolution.
Priority:
1. task.prompt_override (if task provided and has override)
2. DB prompt for (account, function)
3. GlobalAIPrompt (REQUIRED - no hardcoded fallbacks)
Args:
function_name: AI function name (e.g., 'auto_cluster', 'generate_ideas')
account: Account object (optional)
task: Task object with optional prompt_override (optional)
context: Additional context for prompt rendering (optional)
Returns:
Prompt string ready for formatting
"""
# Step 1: Check task-level override
if task and hasattr(task, 'prompt_override') and task.prompt_override:
logger.info(f"Using task-level prompt override for {function_name}")
prompt = task.prompt_override
return cls._render_prompt(prompt, context or {})
# Step 2: Get prompt type
prompt_type = cls.FUNCTION_TO_PROMPT_TYPE.get(function_name, function_name)
# Step 3: Try DB prompt (account-specific)
if account:
try:
from igny8_core.modules.system.models import AIPrompt
db_prompt = AIPrompt.objects.get(
account=account,
prompt_type=prompt_type,
is_active=True
)
logger.info(f"Using account-specific prompt for {function_name} (account {account.id})")
prompt = db_prompt.prompt_value
return cls._render_prompt(prompt, context or {})
except Exception as e:
logger.debug(f"No account-specific prompt found for {function_name}: {e}")
# Step 4: Try GlobalAIPrompt (platform-wide default) - REQUIRED
try:
from igny8_core.modules.system.global_settings_models import GlobalAIPrompt
global_prompt = GlobalAIPrompt.objects.get(
prompt_type=prompt_type,
is_active=True
)
logger.info(f"Using global default prompt for {function_name} from GlobalAIPrompt")
prompt = global_prompt.prompt_value
return cls._render_prompt(prompt, context or {})
except Exception as e:
error_msg = (
f"ERROR: Global prompt '{prompt_type}' not found for function '{function_name}'. "
f"Please configure it in Django admin at: /admin/system/globalaiprompt/. "
f"Error: {e}"
)
logger.error(error_msg)
raise ValueError(error_msg)
prompt, _, _ = cls.get_prompt_with_metadata(function_name, account, task, context)
return prompt
@classmethod
def _render_prompt(cls, prompt_template: str, context: Dict[str, Any]) -> str:
@@ -219,3 +286,61 @@ def get_prompt(function_name: str, account=None, task=None, context=None) -> str
"""Get prompt using registry"""
return PromptRegistry.get_prompt(function_name, account=account, task=task, context=context)
def get_prompt_with_prefix(function_name: str, account=None, task=None, context=None) -> Tuple[str, str]:
"""
Get prompt with its tracking prefix.
Args:
function_name: AI function name
account: Account object (optional)
task: Task object with optional prompt_override (optional)
context: Additional context for prompt rendering (optional)
Returns:
Tuple of (prompt_string, prefix_string)
- prompt_string: The rendered prompt
- prefix_string: The tracking prefix (e.g., '##GP01-Clustering' or '##CP01-Clustering')
"""
prompt, is_custom, prompt_type = PromptRegistry.get_prompt_with_metadata(
function_name, account=account, task=task, context=context
)
prefix = PromptRegistry.get_prompt_prefix(prompt_type, is_custom)
return prompt, prefix
def get_prompt_prefix_for_function(function_name: str, account=None, task=None) -> str:
"""
Get just the prefix for a function without fetching the full prompt.
Useful when the prompt was already fetched elsewhere.
Args:
function_name: AI function name
account: Account object (optional)
task: Task object with optional prompt_override (optional)
Returns:
The tracking prefix (e.g., '##GP01-Clustering' or '##CP01-Clustering')
"""
prompt_type = PromptRegistry.FUNCTION_TO_PROMPT_TYPE.get(function_name, function_name)
# Check for task-level override (always custom)
if task and hasattr(task, 'prompt_override') and task.prompt_override:
return PromptRegistry.get_prompt_prefix(prompt_type, is_custom=True)
# Check for account-specific prompt
if account:
try:
from igny8_core.modules.system.models import AIPrompt
db_prompt = AIPrompt.objects.get(
account=account,
prompt_type=prompt_type,
is_active=True
)
return PromptRegistry.get_prompt_prefix(prompt_type, is_custom=db_prompt.is_customized)
except Exception:
pass
# Fallback to global (not custom)
return PromptRegistry.get_prompt_prefix(prompt_type, is_custom=False)

View File

@@ -119,10 +119,40 @@ class Tasks(SoftDeletableModel, SiteSectorBaseModel):
objects = SoftDeleteManager()
all_objects = models.Manager()
def __str__(self):
return self.title
def soft_delete(self, user=None, reason=None, retention_days=None):
"""
Override soft_delete to cascade to related models.
This ensures Images and ContentClusterMap are also deleted when a Task is deleted.
"""
import logging
logger = logging.getLogger(__name__)
# Soft-delete related Images (which are also SoftDeletable)
related_images = self.images.filter(is_deleted=False)
images_count = related_images.count()
for image in related_images:
image.soft_delete(user=user, reason=f"Parent task deleted: {reason or 'No reason'}")
# Hard-delete ContentClusterMap (not soft-deletable)
cluster_maps_count = self.cluster_mappings.count()
self.cluster_mappings.all().delete()
# Hard-delete ContentAttribute (not soft-deletable)
attributes_count = self.attribute_mappings.count()
self.attribute_mappings.all().delete()
logger.info(
f"[Tasks.soft_delete] Task {self.id} '{self.title}' cascade delete: "
f"{images_count} images, {cluster_maps_count} cluster maps, {attributes_count} attributes"
)
# Call parent soft_delete
super().soft_delete(user=user, reason=reason, retention_days=retention_days)
class ContentTaxonomyRelation(models.Model):
"""Through model for Content-Taxonomy many-to-many relationship"""
@@ -326,6 +356,61 @@ class Content(SoftDeletableModel, SiteSectorBaseModel):
logger = logging.getLogger(__name__)
logger.error(f"Error incrementing word usage for content {self.id}: {str(e)}")
def soft_delete(self, user=None, reason=None, retention_days=None):
"""
Override soft_delete to cascade to related models.
This ensures Images, ContentClusterMap, ContentAttribute are also deleted.
"""
import logging
logger = logging.getLogger(__name__)
# Soft-delete related Images (which are also SoftDeletable)
related_images = self.images.filter(is_deleted=False)
images_count = related_images.count()
for image in related_images:
image.soft_delete(user=user, reason=f"Parent content deleted: {reason or 'No reason'}")
# Hard-delete ContentClusterMap (not soft-deletable)
cluster_maps_count = self.cluster_mappings.count()
self.cluster_mappings.all().delete()
# Hard-delete ContentAttribute (not soft-deletable)
attributes_count = self.attributes.count()
self.attributes.all().delete()
# Hard-delete ContentTaxonomyRelation (through model for many-to-many)
taxonomy_relations_count = ContentTaxonomyRelation.objects.filter(content=self).count()
ContentTaxonomyRelation.objects.filter(content=self).delete()
logger.info(
f"[Content.soft_delete] Content {self.id} '{self.title}' cascade delete: "
f"{images_count} images, {cluster_maps_count} cluster maps, "
f"{attributes_count} attributes, {taxonomy_relations_count} taxonomy relations"
)
# Call parent soft_delete
super().soft_delete(user=user, reason=reason, retention_days=retention_days)
def hard_delete(self, using=None, keep_parents=False):
"""
Override hard_delete to cascade to related models.
Django CASCADE should handle this, but we explicitly clean up for safety.
"""
import logging
logger = logging.getLogger(__name__)
# Hard-delete related Images (including soft-deleted ones)
images_count = Images.all_objects.filter(content=self).count()
Images.all_objects.filter(content=self).delete()
logger.info(
f"[Content.hard_delete] Content {self.id} '{self.title}' hard delete: "
f"{images_count} images removed"
)
# Call parent hard_delete (Django CASCADE will handle the rest)
return super().hard_delete(using=using, keep_parents=keep_parents)
class ContentTaxonomy(SiteSectorBaseModel):
"""

View File

@@ -121,14 +121,14 @@ class AIProcessor:
temperature: float = 0.7,
response_format: Optional[Dict] = None,
api_key: Optional[str] = None,
function_id: Optional[str] = None,
prompt_prefix: Optional[str] = None,
response_steps=None
) -> Dict[str, Any]:
"""
Internal method to call OpenAI API.
EXACT match to reference plugin's igny8_call_openai() function.
Endpoint: https://api.openai.com/v1/chat/completions
Returns:
Dict with 'content', 'input_tokens', 'output_tokens', 'total_tokens', 'model', 'cost', 'error', 'api_id'
"""
@@ -159,12 +159,12 @@ class AIProcessor:
'Content-Type': 'application/json',
}
# Add function_id to prompt if provided (for tracking)
# Add prompt_prefix to prompt if provided (for tracking)
# Format: ##GP01-Clustering or ##CP01-Clustering
final_prompt = prompt
if function_id:
function_id_prefix = f'function_id: "{function_id}"\n\n'
final_prompt = function_id_prefix + prompt
logger.info(f"Added function_id to prompt: {function_id}")
if prompt_prefix:
final_prompt = f'{prompt_prefix}\n\n{prompt}'
logger.info(f"Added prompt prefix: {prompt_prefix}")
# EXACT request format from reference plugin (openai-api.php line 402-404)
body_data = {
@@ -463,13 +463,15 @@ class AIProcessor:
Returns:
Dict with 'content', 'tokens_used', 'model', 'cost', 'error'
"""
# Generate function_id for tracking (ai-generate-content-03 for AIProcessor path)
function_id = "ai-generate-content-03"
# Generate prompt prefix for tracking (e.g., ##GP03-ContentGen or ##CP03-ContentGen)
from igny8_core.ai.prompts import get_prompt_prefix_for_function
prompt_prefix = get_prompt_prefix_for_function('generate_content', account=self.account)
# Get response_format from settings for generate_content
from igny8_core.ai.settings import get_model_config
model_config = get_model_config('generate_content')
model_config = get_model_config('generate_content', account=self.account)
response_format = model_config.get('response_format')
result = self._call_openai(prompt, model, max_tokens, temperature, response_format=response_format, function_id=function_id)
result = self._call_openai(prompt, model, max_tokens, temperature, response_format=response_format, prompt_prefix=prompt_prefix)
return {
'content': result.get('content', ''),

View 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.

View 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

View File

@@ -37,7 +37,11 @@ export default function Clusters() {
// Data state
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={{

View File

@@ -40,7 +40,11 @@ export default function Ideas() {
const [ideas, setIdeas] = useState<ContentIdea[]>([]);
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={{

View File

@@ -45,7 +45,12 @@ export default function Keywords() {
const [keywords, setKeywords] = useState<Keyword[]>([]);
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={{

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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 Inarticle Image Prompts" → "Writing Inarticle 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

View File

@@ -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`

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
---