457 lines
13 KiB
Markdown
457 lines
13 KiB
Markdown
# Implementation Audit - Reality Check
|
|
**Based on Actual Codebase Analysis**
|
|
|
|
**Date:** December 15, 2025
|
|
**Status:** Code-Verified Action Plan
|
|
**Purpose:** Ground implementation in what actually exists, not assumptions
|
|
|
|
---
|
|
|
|
## Executive Summary
|
|
|
|
### What Actually Works (Code-Verified)
|
|
|
|
✅ **PageHeader Component** (`frontend/src/components/common/PageHeader.tsx`, 170 lines)
|
|
- Handles site/sector selectors, badges, navigation tabs, last updated timestamp
|
|
- Used consistently across all Planner/Writer pages
|
|
- **No changes needed**
|
|
|
|
✅ **ProgressModal Component** (`frontend/src/components/common/ProgressModal.tsx`, 822 lines)
|
|
- Shows step-by-step progress for AI operations
|
|
- Has visual step indicators, handles all AI functions
|
|
- Extracts success messages with counts
|
|
- **Works well, but has fragile regex parsing**
|
|
|
|
✅ **useProgressModal Hook** (`frontend/src/hooks/useProgressModal.ts`, 815 lines)
|
|
- Polls Celery task status every 2 seconds
|
|
- Has elaborate `getStepInfo()` function (146 lines) that uses regex to extract counts
|
|
- **Problem**: Relies on message format, not structured data
|
|
|
|
✅ **Backend ProgressTracker** (`backend/igny8_core/ai/tracker.py`, 347 lines)
|
|
- Has `update(phase, percentage, message, current, total, current_item, meta)` method
|
|
- **Supports structured data via `meta` dict**
|
|
- **Problem**: AI functions don't actually use `meta` to pass structured details
|
|
|
|
✅ **Model Status Fields Work Fine**
|
|
- Keywords: `status` = `('new', 'New'), ('mapped', 'Mapped')`
|
|
- Clusters: `status` = `('new', 'New'), ('mapped', 'Mapped')`
|
|
- ContentIdeas: `status` = `('new', 'New'), ('queued', 'Queued'), ('completed', 'Completed')`
|
|
- Tasks: `status` = `('queued', 'Queued'), ('completed', 'Completed')`
|
|
- Content: `status` = `('draft', 'Draft'), ('review', 'Review'), ('published', 'Published')`
|
|
- **These work for workflow state tracking - don't need to change**
|
|
|
|
### The Actual Problems
|
|
|
|
❌ **Problem 1: Fragile Progress Data Extraction**
|
|
- Frontend uses regex to parse counts from messages: `/(\d+)\s+keyword/i`, `/(\d+)\s+cluster/i`
|
|
- **146 lines** of extraction logic in `getStepInfo()` function
|
|
- Breaks if message wording changes
|
|
- **Solution**: Backend should pass structured details, frontend reads directly
|
|
|
|
❌ **Problem 2: Missing Workflow Guidance**
|
|
- Users don't know where they are in the workflow (no "Step 2 of 3")
|
|
- No contextual help for first-time users
|
|
- No quick metrics summary visible
|
|
- **Solution**: Add StepBanner, HelperNotification, MetricsPanel components
|
|
|
|
❌ **Problem 3: Automation Progress Parsing Issues**
|
|
- AutomationPage tries to parse `stage_X_result` JSON
|
|
- Queue item display incorrect
|
|
- Progress bar doesn't reflect actual progress
|
|
- **Solution**: Fix stage result structure and parsing logic
|
|
|
|
---
|
|
|
|
## Action Plan (Reality-Based)
|
|
|
|
### Phase 1: Backend - Emit Structured Progress Details (Week 1)
|
|
|
|
**Goal**: Make AI functions pass structured data instead of just messages
|
|
|
|
**Files to Update:**
|
|
1. `backend/igny8_core/ai/functions/auto_cluster.py` (347 lines)
|
|
2. `backend/igny8_core/ai/functions/generate_ideas.py`
|
|
3. `backend/igny8_core/ai/functions/generate_content.py`
|
|
4. `backend/igny8_core/ai/functions/generate_image_prompts.py`
|
|
5. `backend/igny8_core/ai/functions/generate_images.py`
|
|
|
|
**Change Pattern:**
|
|
|
|
**Before:**
|
|
```python
|
|
tracker.update(
|
|
phase='SAVE',
|
|
percentage=90,
|
|
message=f"Creating {len(clusters)} clusters"
|
|
)
|
|
```
|
|
|
|
**After:**
|
|
```python
|
|
tracker.update(
|
|
phase='SAVE',
|
|
percentage=90,
|
|
message=f"Creating {len(clusters)} clusters",
|
|
meta={
|
|
'items_total': len(keywords),
|
|
'items_processed': processed_count,
|
|
'items_created': len(clusters),
|
|
'current_item_name': current_cluster.name if current_cluster else None
|
|
}
|
|
)
|
|
```
|
|
|
|
**Effort:** ~3-4 hours per function = 15-20 hours total
|
|
|
|
---
|
|
|
|
### Phase 2: Frontend - Simplify Progress Modal (Week 1-2)
|
|
|
|
**Goal**: Remove regex parsing, read structured details directly
|
|
|
|
**Files to Update:**
|
|
1. `frontend/src/hooks/useProgressModal.ts` (815 lines)
|
|
- **Remove**: Lines 96-242 (146 lines of regex extraction)
|
|
- **Add**: Simple `details` accessor from `state.meta.details`
|
|
|
|
2. `frontend/src/components/common/ProgressModal.tsx` (822 lines)
|
|
- **Simplify**: `getSuccessMessage()` to read from backend
|
|
- **Remove**: Regex patterns for extracting counts
|
|
|
|
**Before (useProgressModal.ts, ~146 lines):**
|
|
```typescript
|
|
const getStepInfo = (stepName: string, message: string, allSteps: any[]) => {
|
|
// Extract keyword count
|
|
let keywordCount = extractNumber(/(\d+)\s+keyword/i, message);
|
|
// ... 140 more lines of extraction logic
|
|
};
|
|
```
|
|
|
|
**After (~20 lines):**
|
|
```typescript
|
|
const getStepInfo = (state: any): ProgressDisplay => {
|
|
const details = state.meta?.details || {};
|
|
|
|
return {
|
|
percentage: state.meta?.percentage || 0,
|
|
message: state.meta?.message || 'Processing...',
|
|
itemsTotal: details.items_total,
|
|
itemsProcessed: details.items_processed,
|
|
itemsCreated: details.items_created,
|
|
currentItemName: details.current_item_name,
|
|
};
|
|
};
|
|
```
|
|
|
|
**Effort:** ~6-8 hours
|
|
|
|
---
|
|
|
|
### Phase 3: Create Missing UX Components (Week 2)
|
|
|
|
#### 3.1 StepBanner Component
|
|
|
|
**File:** `frontend/src/components/workflow/StepBanner.tsx` (NEW)
|
|
|
|
**Purpose:** Show "Step 2 of 3: Organize Clusters" with clickable progress
|
|
|
|
**Interface:**
|
|
```typescript
|
|
interface StepBannerProps {
|
|
currentStep: number;
|
|
totalSteps: number;
|
|
steps: Array<{
|
|
label: string;
|
|
href: string;
|
|
completed: boolean;
|
|
}>;
|
|
}
|
|
```
|
|
|
|
**Usage:**
|
|
```tsx
|
|
// In Clusters.tsx
|
|
<StepBanner
|
|
currentStep={2}
|
|
totalSteps={3}
|
|
steps={[
|
|
{ label: 'Extract Keywords', href: '/planner/keywords', completed: true },
|
|
{ label: 'Organize Clusters', href: '/planner/clusters', completed: false },
|
|
{ label: 'Generate Ideas', href: '/planner/ideas', completed: false },
|
|
]}
|
|
/>
|
|
```
|
|
|
|
**Effort:** ~4 hours
|
|
|
|
---
|
|
|
|
#### 3.2 HelperNotification Component
|
|
|
|
**File:** `frontend/src/components/helper/HelperNotification.tsx` (NEW)
|
|
|
|
**Purpose:** Dismissible contextual help (stored in localStorage)
|
|
|
|
**Interface:**
|
|
```typescript
|
|
interface HelperNotificationProps {
|
|
type: 'welcome' | 'info' | 'tip' | 'warning' | 'success';
|
|
title: string;
|
|
message: string;
|
|
actions?: Array<{ label: string; onClick?: () => void; }>;
|
|
dismissible?: boolean;
|
|
pageKey: string; // For localStorage persistence
|
|
}
|
|
```
|
|
|
|
**Storage:** `localStorage.setItem('helper_dismissed_keywords', 'true')`
|
|
|
|
**Usage:**
|
|
```tsx
|
|
// In Keywords.tsx
|
|
<HelperNotification
|
|
type="welcome"
|
|
title="Welcome to Keywords"
|
|
message="Import keywords or add manually to get started"
|
|
pageKey="keywords"
|
|
actions={[
|
|
{ label: 'Import CSV', onClick: handleImport },
|
|
{ label: 'Learn More', onClick: () => window.open('/docs/keywords') }
|
|
]}
|
|
/>
|
|
```
|
|
|
|
**Effort:** ~4 hours
|
|
|
|
---
|
|
|
|
#### 3.3 MetricsPanel Component
|
|
|
|
**File:** `frontend/src/components/dashboard/MetricsPanel.tsx` (NEW)
|
|
|
|
**Purpose:** Collapsible metrics summary (alternative to ModuleMetricsFooter)
|
|
|
|
**Interface:**
|
|
```typescript
|
|
interface MetricsPanelProps {
|
|
title: string;
|
|
metrics: Array<{
|
|
label: string;
|
|
value: string | number;
|
|
subtitle?: string;
|
|
tooltip?: string;
|
|
}>;
|
|
collapsible?: boolean;
|
|
defaultCollapsed?: boolean;
|
|
}
|
|
```
|
|
|
|
**Usage:**
|
|
```tsx
|
|
// In Keywords.tsx
|
|
<MetricsPanel
|
|
title="Keyword Metrics"
|
|
metrics={[
|
|
{ label: 'Total', value: totalCount, subtitle: 'All keywords' },
|
|
{ label: 'New', value: newCount, subtitle: 'Unmapped' },
|
|
{ label: 'Mapped', value: mappedCount, subtitle: 'In clusters' },
|
|
]}
|
|
collapsible={true}
|
|
/>
|
|
```
|
|
|
|
**Effort:** ~6 hours
|
|
|
|
---
|
|
|
|
### Phase 4: Update Pages with New Components (Week 2-3)
|
|
|
|
#### Planner Module
|
|
|
|
**Keywords.tsx** (998 lines)
|
|
- Add StepBanner (currentStep=1, totalSteps=3)
|
|
- Add HelperNotification for first-time guidance
|
|
- Add MetricsPanel (or keep existing ModuleMetricsFooter)
|
|
- **Effort:** 2-3 hours
|
|
|
|
**Clusters.tsx**
|
|
- Add StepBanner (currentStep=2, totalSteps=3)
|
|
- Add HelperNotification
|
|
- Add MetricsPanel
|
|
- **Effort:** 2-3 hours
|
|
|
|
**Ideas.tsx**
|
|
- Add StepBanner (currentStep=3, totalSteps=3)
|
|
- Add HelperNotification
|
|
- Add MetricsPanel
|
|
- **Effort:** 2-3 hours
|
|
|
|
#### Writer Module
|
|
|
|
**Tasks.tsx**
|
|
- Add StepBanner (currentStep=1, totalSteps=3)
|
|
- Add HelperNotification
|
|
- Add MetricsPanel
|
|
- **Effort:** 2-3 hours
|
|
|
|
**Content.tsx**
|
|
- Add StepBanner (currentStep=2, totalSteps=3)
|
|
- Add HelperNotification
|
|
- Add MetricsPanel
|
|
- **Effort:** 2-3 hours
|
|
|
|
**Images.tsx**
|
|
- Add StepBanner (currentStep=3, totalSteps=3)
|
|
- Add HelperNotification
|
|
- Add MetricsPanel
|
|
- **Effort:** 2-3 hours
|
|
|
|
**Total Page Updates:** 12-18 hours
|
|
|
|
---
|
|
|
|
### Phase 5: Fix Automation Progress Issues (Week 3)
|
|
|
|
**File:** `frontend/src/pages/Automation/AutomationPage.tsx` (995 lines)
|
|
|
|
**Current Issues:**
|
|
1. Stage progress cards show wrong/missing queue items
|
|
2. Progress bar calculation inaccurate
|
|
3. Stage metrics don't add up
|
|
|
|
**Root Cause:** Stage result JSON structure not being parsed correctly
|
|
|
|
**Fix:**
|
|
1. Add HelperNotification for automation guidance
|
|
2. Fix stage result parsing logic
|
|
3. Fix progress bar calculation: `(completed_stages * 100 / 7) + (current_stage_progress / 7)`
|
|
4. Ensure stage metrics accurately reflect backend counts
|
|
|
|
**Effort:** 8-10 hours
|
|
|
|
---
|
|
|
|
## Total Effort Estimate
|
|
|
|
| Phase | Description | Hours | Duration |
|
|
|-------|-------------|-------|----------|
|
|
| Phase 1 | Backend structured details | 15-20h | Week 1 |
|
|
| Phase 2 | Frontend simplification | 6-8h | Week 1-2 |
|
|
| Phase 3 | New UX components | 14h | Week 2 |
|
|
| Phase 4 | Update pages | 12-18h | Week 2-3 |
|
|
| Phase 5 | Fix automation | 8-10h | Week 3 |
|
|
| **TOTAL** | **55-70 hours** | **~2-3 weeks** |
|
|
|
|
---
|
|
|
|
## What NOT To Do
|
|
|
|
❌ **Don't add `generation_status` field to models**
|
|
- Current status fields work fine for workflow tracking
|
|
- No need for DB migrations
|
|
|
|
❌ **Don't create status enum files**
|
|
- Models already have STATUS_CHOICES inline
|
|
- No need for centralized enums
|
|
|
|
❌ **Don't refactor ProgressModal completely**
|
|
- It works well, just needs to read structured data instead of parsing messages
|
|
- Keep existing step visualization logic
|
|
|
|
❌ **Don't change Celery task structure**
|
|
- Task state updates work fine
|
|
- Just need to pass more structured data in `meta`
|
|
|
|
---
|
|
|
|
## Testing Strategy
|
|
|
|
### Phase 1-2 Testing (Progress System)
|
|
|
|
**Test Each AI Function:**
|
|
1. Keywords → Clustering (auto_cluster.py)
|
|
- Verify `details.items_total`, `details.items_processed`, `details.items_created` appear in state
|
|
- Verify frontend displays counts without regex
|
|
- **Expected:** "50 keywords processed → 8 clusters created"
|
|
|
|
2. Clusters → Ideas (generate_ideas.py)
|
|
- Verify cluster names in `details.current_item_name`
|
|
- Verify idea counts
|
|
- **Expected:** "3 clusters processed → 12 ideas created"
|
|
|
|
3. Tasks → Content (generate_content.py)
|
|
- Verify task title and word count in details
|
|
- **Expected:** "Task: How to Train Your Dog → 1500 words generated"
|
|
|
|
4. Content → Image Prompts (generate_image_prompts.py)
|
|
- Verify prompt counts (featured + in-article)
|
|
- **Expected:** "1 featured + 5 in-article prompts created"
|
|
|
|
5. Image Prompts → Images (generate_images.py)
|
|
- Verify image generation progress
|
|
- **Expected:** "Generating image 3/6"
|
|
|
|
### Phase 3-4 Testing (UX Components)
|
|
|
|
**Test Each New Component:**
|
|
1. **StepBanner**
|
|
- Verify workflow position shown correctly
|
|
- Verify completed steps clickable, navigate correctly
|
|
- Verify current step highlighted
|
|
|
|
2. **HelperNotification**
|
|
- Verify dismissal persists in localStorage
|
|
- Verify actions work
|
|
- Verify doesn't show again after dismissal
|
|
|
|
3. **MetricsPanel**
|
|
- Verify collapse/expand works
|
|
- Verify tooltips show on hover
|
|
- Verify metrics update in real-time
|
|
|
|
### Phase 5 Testing (Automation)
|
|
|
|
**Test Automation Pipeline:**
|
|
1. Start automation run
|
|
2. Verify each stage shows accurate pending/processing/completed counts
|
|
3. Verify progress bar advances correctly
|
|
4. Pause and verify state persists
|
|
5. Resume and verify continues from correct stage
|
|
6. Verify stage result JSON contains all expected fields
|
|
|
|
---
|
|
|
|
## Success Criteria
|
|
|
|
### Backend
|
|
✅ All AI functions emit structured details via `tracker.update(meta={...})`
|
|
✅ Details include: `items_total`, `items_processed`, `items_created`, `current_item_name`
|
|
✅ Celery task state includes details in `meta.details`
|
|
|
|
### Frontend
|
|
✅ useProgressModal reads details directly from `state.meta.details`
|
|
✅ No regex parsing in useProgressModal or ProgressModal
|
|
✅ Progress messages show accurate counts
|
|
✅ All new UX components created and working
|
|
|
|
### UX
|
|
✅ Users see workflow step via StepBanner
|
|
✅ Users get contextual help via HelperNotification
|
|
✅ Users see metrics summary via MetricsPanel
|
|
✅ Automation progress accurate and transparent
|
|
|
|
---
|
|
|
|
## Implementation Notes
|
|
|
|
1. **Backwards Compatibility**: New `meta.details` is additive, doesn't break existing code
|
|
2. **No DB Changes**: All changes are in application layer (tracker, frontend)
|
|
3. **localStorage Management**: Consider adding "Reset all helpers" in settings
|
|
4. **Performance**: MetricsPanel uses existing data, no extra API calls
|
|
5. **Dark Mode**: All new components must have dark mode styles
|
|
6. **Accessibility**: All new components must support keyboard navigation
|
|
|
|
---
|
|
|
|
**End of Reality-Based Action Plan**
|