# Publishing & Onboarding Implementation Plan

**Created:** January 1, 2026  
**Status:** Planning  
**Priority:** High  
**Scope:** App-level changes (IGNY8 Backend + Frontend)

---

> ## ⚠️ CRITICAL: DO NOT BREAK EXISTING FUNCTIONALITY
> 
> **The current "Publish to Site" button in the dropdown menu is WORKING PERFECTLY.**
> 
> This manual publish functionality MUST continue to work throughout ALL implementation phases:
> - Content dropdown → "Publish to Site" button → Successfully publishes content to WordPress
> - This is the core publishing feature that users rely on
> - Each phase of implementation MUST be tested to ensure this functionality remains intact
> - If any change breaks manual publishing, STOP and fix immediately before proceeding
> 
> **Testing Required After EVERY Section:**
> 1. Manual "Publish to Site" button still works
> 2. Content successfully appears on WordPress site
> 3. Status updates correctly after publishing
> 4. No console errors or API failures

---

## Table of Contents

1. [Executive Summary](#1-executive-summary)
2. [Bug Fixes (Immediate)](#2-bug-fixes-immediate)
3. [Status System Redesign](#3-status-system-redesign)
4. [Publishing Settings Relocation](#4-publishing-settings-relocation)
5. [Internal Publishing Scheduler](#5-internal-publishing-scheduler)
6. [Simplified Onboarding Flow](#6-simplified-onboarding-flow)
7. [UI Wording Consistency Audit](#7-ui-wording-consistency-audit)
8. [Platform-Agnostic Terminology](#8-platform-agnostic-terminology)
9. [Metrics Integration](#9-metrics-integration---published-to-site)
10. [Automation Settings Verification](#10-automation-settings-verification)
11. [WordPress Bridge Plugin Changes](#11-wordpress-bridge-plugin-changes-reference-only)
12. [Implementation Order](#12-implementation-order)
13. [Summary Checklist](#13-summary-checklist)

---

## 1. Executive Summary

### Goals

1. **Fix critical bugs** - Sites dashboard error, edit URL issues
2. **Clarify status terminology** - Separate "Approved" (internal) from "Published" (on site)
3. **Site-level publishing settings** - Move from account-wide to per-site configuration
4. **Internal scheduling** - Control when content publishes to external sites
5. **Simplified onboarding** - Defaults-first approach for new users
6. **Platform-agnostic language** - Prepare for Shopify and custom integrations

### Current State Problems

| Problem | Location | Impact |
|---------|----------|--------|
| `ComponentCard` not defined | Sites Dashboard | Page crashes |
| Edit URLs have `undefined` | ContentViewTemplate | Broken navigation |
| "Published" used prematurely | Stage 7, Approved page | User confusion |
| Publishing settings not integrated | /account/content-settings/publishing | Settings do nothing |
| No publishing scheduler | Backend | Content stuck waiting |
| WordPress-specific language | Throughout app | Limits future integrations |
| "Published to Site" metric missing | Planner, Writer, Footer, Dashboard, Automation | Incomplete metrics |
| Auto-publish settings not enforced | Run Now & Scheduled automation | Settings ignored |

---

## 2. Bug Fixes (Immediate)

### 2.1 Sites Dashboard - ComponentCard Error

**File:** `frontend/src/pages/Sites/Dashboard.tsx`

**Issue:** Line 259 uses `ComponentCard` and lines 185, 334 use `Card`, but neither are imported. Also `ArrowUpIcon` is used but not imported.

**Fix:**
- Add import for `ComponentCard` from `../../components/common/ComponentCard`
- Add import for `Card` from `../../components/ui/card`
- Add import for `ArrowUpIcon` from `../../icons`

---

### 2.2 Edit URL - Undefined Site ID

**File:** `frontend/src/templates/ContentViewTemplate.tsx`

**Issue:** Lines 1011 and 1031 use `content.site_id` for edit navigation, but `site_id` is not returned in the Content API response.

**Root Cause:** `ContentSerializer` has `site_id = serializers.IntegerField(write_only=True, required=False)` - the `write_only=True` prevents it from being returned in responses.

**Fix - Backend:**
- File: `backend/igny8_core/modules/writer/serializers.py`
- Line ~166: Change `site_id` from `write_only=True` to `read_only=True`
- Also add `site_id` to the serializer's `fields` list if not already included for reads

**Fix - Frontend (Defensive):**
- File: `frontend/src/services/api.ts`
- Line ~2211: Add `site_id?: number;` to the `Content` interface

---

### 2.3 Approved Page - Edit Action Not Working

**File:** `frontend/src/pages/Writer/Approved.tsx`

**Issue:** Line 222 `handleRowAction` for 'edit' action navigates to `/writer/content?id=${row.id}` which is incorrect format.

**Fix:** Change navigation to proper edit URL format:
```
navigate(`/sites/${row.site_id}/posts/${row.id}/edit`)
```

Note: Requires site_id fix from 2.2 to work properly.

---

## 3. Status System Redesign

### 3.1 Current Status Flow

```
draft → review → published (backend)
                    ↓
              "Approved" (frontend label)
                    ↓
              "Published to Site" (manual action)
```

**Problems:**
- Backend status `published` doesn't mean "on external site"
- Frontend calls it "Approved" but backend calls it "published"
- No distinction between "ready to publish" and "actually published"

### 3.2 Proposed Status Flow

**Option A: Add `approved` Status to Backend (Recommended)**

```
draft → review → approved → published
                    ↓           ↓
              Ready for     Actually on
              publishing    external site
```

**Backend Model Changes:**
- File: `backend/igny8_core/business/content/models.py`
- Line ~271: Add `('approved', 'Approved')` to `STATUS_CHOICES`

**Migration Required:**
- Update existing `status='published'` where `external_id IS NULL` to `status='approved'`

**Option B: Use Existing Status + Site Status Field (Alternative)**

Add new field `site_status` to track external publication status separately:

```python
SITE_STATUS_CHOICES = [
    ('not_published', 'Not Published'),
    ('scheduled', 'Scheduled'),
    ('publishing', 'Publishing'),
    ('published', 'Published'),
    ('failed', 'Failed'),
]
site_status = models.CharField(max_length=50, choices=SITE_STATUS_CHOICES, default='not_published')
```

### 3.3 Files to Update for Status Changes

| File | Changes |
|------|---------|
| `backend/igny8_core/business/content/models.py` | Add `approved` status |
| `backend/igny8_core/business/automation/services/automation_service.py` | Stage 7: Change to `approved` not `published` |
| `backend/igny8_core/tasks/wordpress_publishing.py` | Query for `approved` status |
| `frontend/src/services/api.ts` | Update Content interface status type |
| `frontend/src/pages/Writer/Approved.tsx` | Filter by `approved` status |
| `frontend/src/pages/Writer/Review.tsx` | No change (still filters `review`) |
| `frontend/src/templates/ContentViewTemplate.tsx` | Update status badge labels |

---

## 4. Publishing Settings Relocation

### 4.1 Current State

- Location: `/account/content-settings/publishing`
- File: `frontend/src/pages/Settings/Publishing.tsx`
- Status: **Not integrated with backend** - settings don't persist or work

### 4.2 Proposed State

Move publishing settings to **Site-level** configuration.

**New Location:** `/sites/{id}/settings` → Publishing tab

### 4.3 Backend Changes

**New Model: PublishingSettings**

File: `backend/igny8_core/business/integration/models.py`

```
PublishingSettings
├── site (FK to Site)
├── account (FK to Account)
├── auto_publish_enabled (Boolean, default=True)
├── auto_approval_enabled (Boolean, default=True)
├── daily_publish_limit (Integer, default=3)
├── weekly_publish_limit (Integer, default=15)
├── monthly_publish_limit (Integer, default=50)
├── publish_days (JSONField, default=['mon','tue','wed','thu','fri'])
├── publish_time_slots (JSONField, default=['09:00','14:00','18:00'])
├── created_at (DateTime)
├── updated_at (DateTime)
```

**New API Endpoints:**

File: `backend/igny8_core/modules/integration/views.py`

| Endpoint | Method | Purpose |
|----------|--------|---------|
| `/v1/integration/sites/{site_id}/publishing-settings/` | GET | Get publishing settings for site |
| `/v1/integration/sites/{site_id}/publishing-settings/` | PUT | Update publishing settings |

**New Serializer:**

File: `backend/igny8_core/modules/integration/serializers.py`

- `PublishingSettingsSerializer` with all fields

### 4.4 Frontend Changes

**Remove/Deprecate:**
- File: `frontend/src/pages/Settings/Publishing.tsx`
- Remove from routing in `App.tsx`
- Remove sidebar link if exists

**Add to Site Settings:**

File: `frontend/src/pages/Sites/Settings.tsx`

- Add "Publishing" tab alongside General, Integrations, Content Types
- Create new component: `frontend/src/components/sites/PublishingSettings.tsx`

**New Component Structure:**

```
PublishingSettings.tsx
├── Auto-Approval Toggle (with explanation)
├── Auto-Publish Toggle (with explanation)
├── Daily Limit Input (1-10, default 3)
├── Weekly Limit Input (1-50, default 15)
├── Monthly Limit Input (1-200, default 50)
├── Publish Days Checkboxes (Mon-Sun)
├── Time Slots Input (add/remove times)
└── Save Button
```

---

## 5. Internal Publishing Scheduler

### 5.1 Overview

Content flows: `approved` → `scheduled` → `published`

IGNY8 controls **when** content is sent to external sites based on user's publishing settings.

### 5.2 New Database Fields

**Content Model Updates:**

File: `backend/igny8_core/business/content/models.py`

Add fields:
- `scheduled_publish_at` (DateTimeField, null=True) - When content should publish
- `site_status` (CharField) - External site status (not_published/scheduled/publishing/published/failed)
- `site_status_updated_at` (DateTimeField, null=True) - Last status change

### 5.3 New Celery Task: Publishing Scheduler

**File:** `backend/igny8_core/tasks/publishing_scheduler.py`

**Task:** `schedule_approved_content()`

**Runs:** Every 1 hour via Celery Beat (changed from 5 minutes - less aggressive scheduling)

**Logic:**
1. Find all content with `status='approved'` and `site_status='not_published'`
2. Group by site
3. For each site:
   - Load PublishingSettings
   - Check daily/weekly/monthly limits (how many already published today/this week/this month)
   - If under limits, check if current time matches any publish_time_slot
   - If matches, mark content as `site_status='scheduled'` and set `scheduled_publish_at`
   - Limit batch size per run

**Task:** `process_scheduled_publications()`

**Runs:** Every 5 minutes via Celery Beat (changed from 1 minute - reduced load)

**Logic:**
1. Find content where `site_status='scheduled'` and `scheduled_publish_at <= now()`
2. For each content:
   - Queue `publish_content_to_site.delay(content_id)`
   - Set `site_status='publishing'`

### 5.4 Celery Beat Schedule Updates

**File:** `backend/igny8_core/celery.py`

Add to `beat_schedule`:
```python
'schedule-approved-content': {
    'task': 'igny8_core.tasks.publishing_scheduler.schedule_approved_content',
    'schedule': crontab(minute=0),  # Every hour at :00
},
'process-scheduled-publications': {
    'task': 'igny8_core.tasks.publishing_scheduler.process_scheduled_publications',
    'schedule': crontab(minute='*/5'),  # Every 5 minutes
},
```

### 5.5 Publishing Queue UI

**New Page:** `/sites/{id}/publishing-queue`

**File:** `frontend/src/pages/Sites/PublishingQueue.tsx`

**Features:**
- List of content with `site_status='scheduled'`
- Shows scheduled publish date/time
- Drag-drop to reorder queue (updates `scheduled_publish_at`)
- Pause/unpause individual items
- Calendar view showing distribution

---

## 6. Simplified Onboarding Flow

### 6.1 New User Journey (Defaults-First)

```
Step 1: Create Account (existing)
           ↓
Step 2: Add First Site
         - Name, URL
         - Hosting type (WordPress selected)
         - Skip advanced settings → Use defaults
           ↓
Step 3: Install WordPress Plugin
         - Show API key
         - Test connection
           ↓
Step 4: Add First Keywords
         - Bulk input or CSV import
           ↓
Step 5: Done! Show Dashboard
         - "Your content pipeline is running"
         - First content ETA based on queue
```

### 6.2 Default Settings (Applied Automatically)

| Setting | Default Value | Location |
|---------|---------------|----------|
| Auto-approval | ON | PublishingSettings |
| Auto-publish | ON | PublishingSettings |
| Daily limit | 3 articles | PublishingSettings |
| Weekly limit | 15 articles | PublishingSettings |
| Monthly limit | 50 articles | PublishingSettings |
| Publish days | Mon-Fri | PublishingSettings |
| Publish times | 9am, 2pm, 6pm | PublishingSettings |
| Automation enabled | ON | AutomationConfig |
| Run frequency | Every 6 hours | AutomationConfig |

### 6.3 Onboarding Wizard Component

**File:** `frontend/src/components/onboarding/OnboardingWizard.tsx`

**Steps Component Structure:**
- `Step1Welcome` - Welcome message, value prop
- `Step2AddSite` - Site name, URL, type
- `Step3ConnectIntegration` - API key, plugin install guide, test
- `Step4AddKeywords` - Keyword input, CSV upload
- `Step5Complete` - Success, show dashboard preview

**Triggers:**
- Show wizard on first login (check account has no sites)
- Can be dismissed and accessed later from Help menu

### 6.4 Backend Defaults Service

**File:** `backend/igny8_core/business/integration/services/defaults_service.py`

**Function:** `create_site_with_defaults(account, site_data)`

**Actions:**
1. Create Site
2. Create PublishingSettings with defaults
3. Create AutomationConfig with defaults
4. Return site + settings

---

## 7. UI Wording Consistency Audit

### 7.1 Status Labels Mapping

| Backend Status | Frontend Display | Badge Color |
|----------------|------------------|-------------|
| `draft` | Draft | Gray |
| `review` | Ready for Review | Amber |
| `approved` | Approved | Green |
| `published` | On Site | Blue |

**Contextual Labels:**

| Page | Status Column Header | Values |
|------|---------------------|--------|
| Review Page | Status | Ready for Review, Draft |
| Approved Page | Site Content Status | Approved (Pending), On Site |
| Content View | Badge | Draft, Review, Approved, Published |

### 7.2 Files Requiring Label Updates

| File | Current | New |
|------|---------|-----|
| `frontend/src/pages/Writer/Approved.tsx` | "Content Approved" title | Keep (correct) |
| `frontend/src/templates/ContentViewTemplate.tsx` | Status badge | Map `published` → "On Site" if `external_id`, else "Approved" |
| `frontend/src/config/pages/approved.config.tsx` | Column headers | "Site Content Status" |
| `frontend/src/components/dashboard/*.tsx` | Various metrics | Use consistent terms |

### 7.3 Action Button Labels

| Current | New | Reason |
|---------|-----|--------|
| "Publish to WordPress" | "Publish to Site" | Platform-agnostic |
| "WordPress Status" | "Site Status" | Platform-agnostic |
| "View on WordPress" | "View on Site" | Platform-agnostic |

---

## 8. Platform-Agnostic Terminology

### 8.1 String Replacements

Search and replace across codebase:

| Search | Replace | Scope |
|--------|---------|-------|
| "Publish to WordPress" | "Publish to Site" | UI labels only |
| "WordPress status" | "Site status" | UI labels only |
| "View on WordPress" | "View on Site" | UI labels only |
| "WordPress Publishing" | "Site Publishing" | UI labels only |

**Do NOT replace in:**
- Backend API endpoint paths
- WordPress-specific service classes
- Plugin-related code
- Technical documentation (keep WordPress references)

### 8.2 Files to Update

| File | Changes |
|------|---------|
| `frontend/src/components/WordPressPublish/WordPressPublish.tsx` | Button labels |
| `frontend/src/components/WordPressPublish/ContentActionsMenu.tsx` | Menu item labels |
| `frontend/src/pages/Writer/Review.tsx` | Action menu labels |
| `frontend/src/pages/Writer/Approved.tsx` | Action menu labels |
| `frontend/src/config/pages/table-actions.config.tsx` | Action labels |
| `frontend/src/pages/Settings/Publishing.tsx` | Destination labels |

### 8.3 Future-Proof Architecture

**SiteIntegration Model** already supports multiple platforms via `platform` field:
- `wordpress`
- `shopify` (future)
- `custom` (future)

**Publishing Service** should route to appropriate adapter:
- `WordPressAdapter`
- `ShopifyAdapter` (future)
- `CustomWebhookAdapter` (future)

---

## 9. Metrics Integration - "Published to Site"

### 9.1 Missing Metrics Audit

The "Published to Site" metric is currently **MISSING** from the following locations:

| Location | Component/File | Current State | Required Change |
|----------|----------------|---------------|-----------------|
| Planner Header | `frontend/src/pages/Planner/*.tsx` | No "Published" count | Add metric card |
| Writer Header | Table actions row (above table) | No "Published" count | Add metric in header |
| Footer Widget | `frontend/src/components/FooterWidget.tsx` | Missing from stats | Add "Published to Site" stat |
| Main Dashboard | `frontend/src/pages/Dashboard/` | Incomplete metrics | Add dedicated metric card |
| Automation Page | `frontend/src/pages/Automation/` | Missing from metrics | Add to stage summary |
| Sites Dashboard | `frontend/src/pages/Sites/Dashboard.tsx` | May be missing | Verify and add if needed |

### 9.2 Metric Query Requirements

**Backend API Updates Needed:**

File: `backend/igny8_core/modules/` (various)

Add endpoints or update existing to return:
- `published_to_site_count` - Content with `external_id IS NOT NULL`
- `published_to_site_today` - Published to site in last 24 hours
- `published_to_site_this_week` - Published to site in last 7 days
- `published_to_site_this_month` - Published to site in last 30 days

### 9.3 Frontend Metric Components

**Files to Update:**

| File | Change Required |
|------|-----------------|
| `frontend/src/pages/Planner/Keywords.tsx` | Add Published metric to header row |
| `frontend/src/pages/Planner/Clusters.tsx` | Add Published metric to header row |
| `frontend/src/pages/Writer/Review.tsx` | Add Published metric to header row |
| `frontend/src/pages/Writer/Approved.tsx` | Add Published metric to header row |
| `frontend/src/components/FooterWidget/FooterWidget.tsx` | Add Published stat |
| `frontend/src/pages/Dashboard/Dashboard.tsx` | Add Published metric card |
| `frontend/src/pages/Automation/AutomationPage.tsx` | Add Published to metrics section |

---

## 10. Automation Settings Verification

### 10.1 Run Now & Scheduled Automation Requirements

Both **Manual "Run Now"** and **Automatic Scheduled** runs MUST respect the same settings:

| Setting | Manual Run | Scheduled Run | Location |
|---------|------------|---------------|----------|
| Auto-Approve | ✅ Must check | ✅ Must check | Site PublishingSettings |
| Auto-Publish to Site | ✅ Must check | ✅ Must check | Site PublishingSettings |
| Daily Publish Limit | ✅ Must enforce | ✅ Must enforce | Site PublishingSettings |
| Weekly Publish Limit | ✅ Must enforce | ✅ Must enforce | Site PublishingSettings |
| Monthly Publish Limit | ✅ Must enforce | ✅ Must enforce | Site PublishingSettings |
| Publish Days | N/A (manual) | ✅ Must check | Site PublishingSettings |
| Publish Time Slots | N/A (manual) | ✅ Must check | Site PublishingSettings |

### 10.2 Automation Service Updates Required

**File:** `backend/igny8_core/business/automation/services/automation_service.py`

**Stage 7 Processing Must:**
1. Check if `auto_approval_enabled` in PublishingSettings
   - If YES: Set status to `approved`
   - If NO: Keep status as `review`
2. Check if `auto_publish_enabled` in PublishingSettings
   - If YES AND auto_approval enabled: Queue for site publishing
   - If NO: Leave as `approved` (manual publish required)
3. Respect all publishing limits when auto-publishing

### 10.3 Settings Flow Verification Checklist

```
[Site Settings Page]
        ↓
[PublishingSettings Model]
        ↓
[Automation Service reads settings]
        ↓
[Stage 7 checks auto_approval]
        ↓ (if enabled)
[Sets status='approved']
        ↓
[Stage 7 checks auto_publish]
        ↓ (if enabled)
[Queues for scheduled publishing]
        ↓
[Publishing Scheduler picks up]
        ↓
[Respects daily/weekly/monthly limits]
        ↓
[Publishes to Site]
```

---

## 11. WordPress Bridge Plugin Changes (Reference Only)

**Note:** This section is for reference. A separate plan will be created for plugin-level changes.

### 11.1 Potential Plugin Updates Needed

| Feature | Plugin Change Required |
|---------|----------------------|
| Scheduled posts | Accept `scheduled_at` in publish payload |
| Post update | Handle PUT requests to existing posts |
| Republish | Allow updating posts by content_id |
| Image upload | Download and attach featured images |

### 11.2 New Webhook Events (Future)

| Event | Direction | Purpose |
|-------|-----------|---------|
| `content_scheduled` | App → WP | Notify WP of scheduled content |
| `schedule_changed` | App → WP | Update scheduled time |
| `post_updated` | WP → App | Notify of post edits |

---

## 12. Implementation Order

> **⚠️ IMPORTANT:** After completing EACH section, verify that manual "Publish to Site" button still works before proceeding to the next section.

---

### Section 1: Critical Bug Fixes (Day 1)

| Task # | Task | Files | Priority |
|--------|------|-------|----------|
| 1.1 | Fix ComponentCard import | Sites/Dashboard.tsx | P0 |
| 1.2 | Fix Card import | Sites/Dashboard.tsx | P0 |
| 1.3 | Fix ArrowUpIcon import | Sites/Dashboard.tsx | P0 |
| 1.4 | Fix site_id in API response | writer/serializers.py | P0 |
| 1.5 | Add site_id to Content interface | api.ts | P0 |
| 1.6 | Fix edit URL navigation | Approved.tsx | P0 |
| 1.7 | Fix edit button URLs | ContentViewTemplate.tsx | P0 |

**✅ Section 1 Verification:**
- [ ] Sites Dashboard loads without errors
- [ ] Edit buttons navigate correctly
- [ ] **Manual "Publish to Site" button still works**

---

### Section 2: Status System (Days 2-3)

| Task # | Task | Files | Priority |
|--------|------|-------|----------|
| 2.1 | Add `approved` status to Content model | content/models.py | P1 |
| 2.2 | Create database migration | migrations/ | P1 |
| 2.3 | Run migration on database | Django manage.py | P1 |
| 2.4 | Update Stage 7 to set `approved` | automation_service.py | P1 |
| 2.5 | Update frontend Content interface | api.ts | P1 |
| 2.6 | Update Approved page filter | Approved.tsx | P1 |
| 2.7 | Update status badges | ContentViewTemplate.tsx | P1 |
| 2.8 | Update status config | config files | P1 |

**✅ Section 2 Verification:**
- [ ] New content from automation gets `approved` status
- [ ] Approved page shows correct content
- [ ] Status badges display correctly
- [ ] **Manual "Publish to Site" button still works**

---

### Section 3: Publishing Settings Model (Days 4-5)

| Task # | Task | Files | Priority |
|--------|------|-------|----------|
| 3.1 | Create PublishingSettings model | integration/models.py | P1 |
| 3.2 | Create database migration | migrations/ | P1 |
| 3.3 | Run migration on database | Django manage.py | P1 |
| 3.4 | Create PublishingSettingsSerializer | integration/serializers.py | P1 |
| 3.5 | Create API endpoints | integration/views.py | P1 |
| 3.6 | Add URL routes | integration/urls.py | P1 |

**✅ Section 3 Verification:**
- [ ] API endpoints return 200 for GET/PUT
- [ ] Settings save and retrieve correctly
- [ ] **Manual "Publish to Site" button still works**

---

### Section 4: Publishing Settings Frontend (Day 6)

| Task # | Task | Files | Priority |
|--------|------|-------|----------|
| 4.1 | Create PublishingSettings component | components/sites/PublishingSettings.tsx | P1 |
| 4.2 | Add Publishing tab to Site Settings | Sites/Settings.tsx | P1 |
| 4.3 | Create API service functions | api.ts | P1 |
| 4.4 | Remove/deprecate old Publishing page | Settings/Publishing.tsx | P2 |
| 4.5 | Update routing if needed | App.tsx | P2 |

**✅ Section 4 Verification:**
- [ ] Publishing tab visible in Site Settings
- [ ] Settings UI loads and saves correctly
- [ ] **Manual "Publish to Site" button still works**

---

### Section 5: Automation Integration (Days 7-8)

| Task # | Task | Files | Priority |
|--------|------|-------|----------|
| 5.1 | Update Stage 7 to read PublishingSettings | automation_service.py | P1 |
| 5.2 | Implement auto_approval check | automation_service.py | P1 |
| 5.3 | Implement auto_publish check | automation_service.py | P1 |
| 5.4 | Test with "Run Now" button | Manual testing | P1 |
| 5.5 | Test with scheduled automation | Manual testing | P1 |

**✅ Section 5 Verification:**
- [ ] Run Now respects auto_approval setting
- [ ] Run Now respects auto_publish setting
- [ ] Scheduled run respects all settings
- [ ] **Manual "Publish to Site" button still works**

---

### Section 6: Publishing Scheduler Tasks (Days 9-10)

| Task # | Task | Files | Priority |
|--------|------|-------|----------|
| 6.1 | Add scheduled_publish_at field to Content | content/models.py | P1 |
| 6.2 | Add site_status field to Content | content/models.py | P1 |
| 6.3 | Create database migration | migrations/ | P1 |
| 6.4 | Run migration on database | Django manage.py | P1 |
| 6.5 | Create schedule_approved_content task | tasks/publishing_scheduler.py | P1 |
| 6.6 | Create process_scheduled_publications task | tasks/publishing_scheduler.py | P1 |
| 6.7 | Add tasks to Celery Beat (1 hour, 5 min) | celery.py | P1 |
| 6.8 | Restart Celery Beat | Docker/service restart | P1 |

**✅ Section 6 Verification:**
- [ ] Celery Beat schedules appear in Flower
- [ ] Tasks run at correct intervals
- [ ] Content gets scheduled correctly
- [ ] **Manual "Publish to Site" button still works**

---

### Section 7: Metrics Integration (Days 11-12)

| Task # | Task | Files | Priority |
|--------|------|-------|----------|
| 7.1 | Add published_to_site counts to API | Backend views | P1 |
| 7.2 | Add metric to Planner header | Planner pages | P1 |
| 7.3 | Add metric to Writer header | Writer pages | P1 |
| 7.4 | Add metric to Footer Widget | FooterWidget.tsx | P1 |
| 7.5 | Add metric to Dashboard | Dashboard.tsx | P1 |
| 7.6 | Add metric to Automation page | AutomationPage.tsx | P1 |

**✅ Section 7 Verification:**
- [ ] "Published to Site" metric shows in all locations
- [ ] Counts are accurate
- [ ] **Manual "Publish to Site" button still works**

---

### Section 8: UI Consistency (Days 13-14)

| Task # | Task | Files | Priority |
|--------|------|-------|----------|
| 8.1 | Replace "WordPress" with "Site" in labels | Multiple frontend files | P2 |
| 8.2 | Standardize status labels | Config files, templates | P2 |
| 8.3 | Update tooltips and help text | Various | P2 |
| 8.4 | Update documentation | WORDPRESS-INTEGRATION-FLOW.md | P3 |

**✅ Section 8 Verification:**
- [ ] UI labels are consistent
- [ ] No "WordPress" in user-facing labels (except settings)
- [ ] **Manual "Publish to Site" button still works**

---

### Section 9: Publishing Queue UI (Optional - Day 15)

| Task # | Task | Files | Priority |
|--------|------|-------|----------|
| 9.1 | Create PublishingQueue page | Sites/PublishingQueue.tsx | P2 |
| 9.2 | Add navigation link | Site dashboard/menu | P2 |
| 9.3 | Implement drag-drop reordering | PublishingQueue.tsx | P2 |
| 9.4 | Add calendar view | PublishingQueue.tsx | P3 |

**✅ Section 9 Verification:**
- [ ] Queue page loads correctly
- [ ] Scheduled content displays
- [ ] **Manual "Publish to Site" button still works**

---

### Section 10: Onboarding (Days 16-18)

| Task # | Task | Files | Priority |
|--------|------|-------|----------|
| 10.1 | Create defaults service | defaults_service.py | P2 |
| 10.2 | Create OnboardingWizard component | OnboardingWizard.tsx | P2 |
| 10.3 | Create wizard step components | onboarding/ folder | P2 |
| 10.4 | Integrate wizard trigger | App.tsx or auth flow | P2 |
| 10.5 | Test end-to-end onboarding | Manual testing | P2 |

**✅ Section 10 Verification:**
- [ ] Wizard triggers for new accounts
- [ ] All steps complete successfully
- [ ] Defaults are applied correctly
- [ ] **Manual "Publish to Site" button still works**

---

## 13. Summary Checklist

### ⚠️ Critical: Preserve Working Functionality
- [ ] **Manual "Publish to Site" button works after EVERY section**

### Section 1: Bug Fixes
- [ ] 1.1 Fix ComponentCard import in Sites Dashboard
- [ ] 1.2 Fix Card import in Sites Dashboard
- [ ] 1.3 Fix ArrowUpIcon import in Sites Dashboard
- [ ] 1.4 Make site_id readable in ContentSerializer
- [ ] 1.5 Add site_id to frontend Content interface
- [ ] 1.6 Fix edit action navigation in Approved page
- [ ] 1.7 Fix edit button URLs in ContentViewTemplate
- [ ] **✅ VERIFY: Publish to Site still works**

### Section 2: Status System
- [ ] 2.1 Add `approved` status to Content model
- [ ] 2.2 Create database migration
- [ ] 2.3 Run migration
- [ ] 2.4 Update Stage 7 to set `approved` not `published`
- [ ] 2.5 Update frontend Content interface
- [ ] 2.6 Update Approved page filter
- [ ] 2.7 Update status badges
- [ ] 2.8 Update status config
- [ ] **✅ VERIFY: Publish to Site still works**

### Section 3: Publishing Settings Backend
- [ ] 3.1 Create PublishingSettings model
- [ ] 3.2 Create database migration
- [ ] 3.3 Run migration
- [ ] 3.4 Create serializer
- [ ] 3.5 Create API endpoints
- [ ] 3.6 Add URL routes
- [ ] **✅ VERIFY: Publish to Site still works**

### Section 4: Publishing Settings Frontend
- [ ] 4.1 Create PublishingSettings component
- [ ] 4.2 Add Publishing tab to Site Settings
- [ ] 4.3 Create API service functions
- [ ] 4.4 Remove/deprecate old Publishing page
- [ ] 4.5 Update routing
- [ ] **✅ VERIFY: Publish to Site still works**

### Section 5: Automation Integration
- [ ] 5.1 Update Stage 7 to read PublishingSettings
- [ ] 5.2 Implement auto_approval check
- [ ] 5.3 Implement auto_publish check
- [ ] 5.4 Test "Run Now" button
- [ ] 5.5 Test scheduled automation
- [ ] **✅ VERIFY: Publish to Site still works**

### Section 6: Publishing Scheduler
- [ ] 6.1 Add scheduled_publish_at field to Content
- [ ] 6.2 Add site_status field to Content
- [ ] 6.3 Create database migration
- [ ] 6.4 Run migration
- [ ] 6.5 Create schedule_approved_content task (1 hour)
- [ ] 6.6 Create process_scheduled_publications task (5 min)
- [ ] 6.7 Add tasks to Celery Beat
- [ ] 6.8 Restart Celery Beat
- [ ] **✅ VERIFY: Publish to Site still works**

### Section 7: Metrics Integration
- [ ] 7.1 Add published_to_site counts to API
- [ ] 7.2 Add metric to Planner header
- [ ] 7.3 Add metric to Writer header
- [ ] 7.4 Add metric to Footer Widget
- [ ] 7.5 Add metric to Dashboard
- [ ] 7.6 Add metric to Automation page
- [ ] **✅ VERIFY: Publish to Site still works**

### Section 8: UI Consistency
- [ ] 8.1 Replace "WordPress" with "Site" in labels
- [ ] 8.2 Standardize status labels
- [ ] 8.3 Update tooltips and help text
- [ ] 8.4 Update documentation
- [ ] **✅ VERIFY: Publish to Site still works**

### Section 9: Publishing Queue (Optional)
- [ ] 9.1 Create PublishingQueue page
- [ ] 9.2 Add navigation link
- [ ] 9.3 Implement drag-drop reordering
- [ ] 9.4 Add calendar view
- [ ] **✅ VERIFY: Publish to Site still works**

### Section 10: Onboarding
- [ ] 10.1 Create defaults service
- [ ] 10.2 Create OnboardingWizard component
- [ ] 10.3 Create wizard step components
- [ ] 10.4 Integrate wizard trigger
- [ ] 10.5 Test end-to-end onboarding
- [ ] **✅ VERIFY: Publish to Site still works**

---

**Document Version:** 2.0  
**Last Updated:** January 1, 2026  
**Author:** Development Team
