537 lines
15 KiB
Markdown
537 lines
15 KiB
Markdown
# Publisher Module
|
|
|
|
**Last Verified:** January 20, 2026
|
|
**Status:** ✅ Active
|
|
**Version:** 1.8.4
|
|
**Backend Path:** `backend/igny8_core/modules/publisher/` + `backend/igny8_core/business/publishing/`
|
|
**Frontend Path:** `frontend/src/pages/Publisher/`
|
|
|
|
---
|
|
|
|
## Quick Reference
|
|
|
|
| What | File | Key Items |
|
|
|------|------|-----------|
|
|
| Views | `modules/publisher/views.py` | `PublishingRecordViewSet`, `DeploymentViewSet`, `PublishContentViewSet` |
|
|
| Models | `business/publishing/models.py` | `PublishingRecord`, `DeploymentRecord` |
|
|
| Integration Models | `modules/integration/models.py` | `PublishingSettings` |
|
|
| **Unified Settings** | `modules/integration/views/unified_settings.py` | **v1.8.0** Consolidated settings API |
|
|
| Services | `business/publishing/services/*.py` | Publishing orchestration |
|
|
| Scheduler Tasks | `igny8_core/tasks/publishing_scheduler.py` | Celery beat tasks |
|
|
| URLs | `modules/publisher/urls.py` | Publisher endpoints |
|
|
| Frontend | `pages/Publisher/ContentCalendar.tsx` | Content calendar view |
|
|
| **Site Settings** | `pages/Sites/AIAutomationSettings.tsx` | **v1.8.0** Unified settings UI |
|
|
|
|
---
|
|
|
|
## Purpose
|
|
|
|
The Publisher module manages:
|
|
- Content publishing pipeline
|
|
- **Publishing scheduler (automated publishing)**
|
|
- Publishing record tracking
|
|
- Deployment management
|
|
- Multi-destination publishing
|
|
- **Content calendar visualization**
|
|
|
|
**Settings Location (v1.8.0):** Site Settings → Automation tab
|
|
|
|
> ⚠️ **v1.8.0 Change:** The standalone `/publisher/settings` page has been removed. Publishing settings are now configured in Site Settings → Automation tab under "Capacity" and "Schedule" sections.
|
|
|
|
---
|
|
|
|
## Data Models
|
|
|
|
### PublishingRecord
|
|
|
|
| Field | Type | Purpose |
|
|
|-------|------|---------|
|
|
| account | FK | Owner account |
|
|
| site | FK | Parent site |
|
|
| content | FK | Source content |
|
|
| destination | CharField | wordpress/ghost/webflow |
|
|
| external_id | CharField | ID on destination platform |
|
|
| external_url | URLField | Published URL |
|
|
| status | CharField | pending/published/failed/retracted |
|
|
| published_at | DateTime | Publication time |
|
|
| metadata | JSON | Additional data |
|
|
| created_at | DateTime | Record creation |
|
|
|
|
### DeploymentRecord
|
|
|
|
| Field | Type | Purpose |
|
|
|-------|------|---------|
|
|
| account | FK | Owner account |
|
|
| site | FK | Target site |
|
|
| deployment_type | CharField | full/incremental |
|
|
| status | CharField | pending/deploying/completed/failed |
|
|
| items_deployed | Integer | Number of items |
|
|
| started_at | DateTime | Start time |
|
|
| completed_at | DateTime | Completion time |
|
|
| error_log | TextField | Errors encountered |
|
|
| metadata | JSON | Deployment details |
|
|
|
|
### PublishingSettings (v1.3.2, updated v1.8.0)
|
|
|
|
Site-level publishing configuration:
|
|
|
|
| Field | Type | Purpose |
|
|
|-------|------|---------|
|
|
| site | OneToOne | Parent site (unique) |
|
|
| auto_approval_enabled | Boolean | Auto-approve content |
|
|
| auto_publish_enabled | Boolean | Auto-publish approved content |
|
|
| daily_publish_limit | Integer | Max publications per day |
|
|
| weekly_publish_limit | Integer | Max publications per week |
|
|
| monthly_publish_limit | Integer | Max publications per month |
|
|
| publish_days | JSON | Days of week for publishing ["mon","wed","fri"] |
|
|
| publish_time_slots | JSON | Time slots for publishing [{"start":"09:00","end":"17:00"}] |
|
|
| **total_items_per_run** | Integer | **v1.8.0** Computed capacity display |
|
|
|
|
### Content Site Status Fields (v1.3.2)
|
|
|
|
Added to Content model for scheduling:
|
|
|
|
| Field | Type | Values |
|
|
|-------|------|--------|
|
|
| site_status | CharField | not_published, scheduled, publishing, published, failed |
|
|
| scheduled_publish_at | DateTime | Future publication time (nullable) |
|
|
| site_status_updated_at | DateTime | Last status change timestamp |
|
|
|
|
---
|
|
|
|
## API Endpoints
|
|
|
|
### Unified Settings API (v1.8.0)
|
|
|
|
| Method | Path | Purpose |
|
|
|--------|------|---------|
|
|
| **GET** | `/api/v1/integration/sites/{site_id}/unified-settings/` | Get all automation + publishing settings |
|
|
| **PATCH** | `/api/v1/integration/sites/{site_id}/unified-settings/` | Update settings |
|
|
|
|
### Publishing & Records
|
|
|
|
| Method | Path | Handler | Purpose |
|
|
|--------|------|---------|---------|
|
|
| GET | `/api/v1/publisher/records/` | `PublishingRecordViewSet.list` | List publishing records |
|
|
| POST | `/api/v1/publisher/records/` | `PublishingRecordViewSet.create` | Create record |
|
|
| GET | `/api/v1/publisher/deployments/` | `DeploymentViewSet.list` | List deployments |
|
|
| POST | `/api/v1/publisher/publish/` | `PublishContentViewSet.publish` | Publish content immediately |
|
|
| GET | `/api/v1/publisher/publish/status/` | `PublishContentViewSet.status` | Get publishing status |
|
|
| GET | `/api/v1/publisher/site-definition/` | `SiteDefinitionViewSet.list` | Public site definitions |
|
|
|
|
### Scheduling Endpoints (v1.3.2+)
|
|
|
|
| Method | Path | Purpose | Request Body | Response |
|
|
|--------|------|---------|--------------|----------|
|
|
| **POST** | `/api/v1/writer/content/{id}/schedule/` | Schedule content for future publishing | `{ "scheduled_publish_at": "2025-01-20T09:00:00Z" }` | `{ "success": true, "scheduled_publish_at": "2025-01-20T09:00:00Z" }` |
|
|
| **POST** | `/api/v1/writer/content/{id}/reschedule/` | Reschedule existing scheduled content | `{ "scheduled_at": "2025-01-21T10:00:00Z" }` | `{ "success": true, "scheduled_publish_at": "2025-01-21T10:00:00Z" }` |
|
|
| **POST** | `/api/v1/writer/content/{id}/unschedule/` | Cancel scheduled publishing | `{}` | `{ "success": true, "message": "Content unscheduled" }` |
|
|
| **POST** | `/api/v1/writer/content/bulk_schedule/` | Bulk schedule with site defaults | `{ "content_ids": [1,2,3], "use_site_defaults": true, "site_id": 5 }` | `{ "success": true, "scheduled_count": 3, "schedule_preview": [...] }` |
|
|
| **POST** | `/api/v1/writer/content/bulk_schedule_preview/` | Preview bulk schedule times | `{ "content_ids": [1,2,3], "site_id": 5 }` | `{ "schedule_preview": [...], "site_settings": {...} }` |
|
|
|
|
### Legacy Publishing Settings (deprecated)
|
|
|
|
> ⚠️ **Deprecated in v1.8.0:** Use unified-settings API instead
|
|
|
|
| Method | Path | Purpose |
|
|
|--------|------|---------|
|
|
| ~~GET~~ | ~~`/api/v1/sites/{site_id}/settings?tab=publishing`~~ | ~~Get site publishing settings~~ |
|
|
| ~~PUT~~ | ~~`/api/v1/sites/{site_id}/publishing-settings/`~~ | ~~Update publishing settings~~ |
|
|
|
|
---
|
|
|
|
## API Usage Examples
|
|
|
|
### Publish Content Immediately
|
|
|
|
**Request:**
|
|
```bash
|
|
POST /api/v1/publisher/publish/
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"content_id": 123,
|
|
"destinations": ["wordpress"] # or ["shopify"], ["custom"]
|
|
}
|
|
```
|
|
|
|
**Success Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"success": true,
|
|
"results": [
|
|
{
|
|
"destination": "wordpress",
|
|
"success": true,
|
|
"external_id": "456",
|
|
"url": "https://mysite.com/article-title/",
|
|
"publishing_record_id": 789,
|
|
"platform_type": "wordpress"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
**Error Response:**
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": "Publishing API error: Invalid credentials"
|
|
}
|
|
```
|
|
|
|
### Schedule Content for Future Publishing
|
|
|
|
**Request:**
|
|
```bash
|
|
POST /api/v1/writer/content/123/schedule/
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"scheduled_publish_at": "2025-01-20T09:00:00Z"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"scheduled_publish_at": "2025-01-20T09:00:00Z",
|
|
"site_status": "scheduled"
|
|
}
|
|
```
|
|
|
|
**Notes:**
|
|
- Content `site_status` changes from `not_published` → `scheduled`
|
|
- Celery task `process_scheduled_publications` will publish at scheduled time
|
|
- Runs every 5 minutes, so publishing happens within 5 min of scheduled time
|
|
|
|
### Reschedule Content
|
|
|
|
**Request:**
|
|
```bash
|
|
POST /api/v1/writer/content/123/reschedule/
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"scheduled_at": "2025-01-21T10:00:00Z"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"scheduled_publish_at": "2025-01-21T10:00:00Z",
|
|
"site_status": "scheduled"
|
|
}
|
|
```
|
|
|
|
**Use Cases:**
|
|
- Reschedule from `site_status='scheduled'` (change time)
|
|
- Reschedule from `site_status='failed'` (retry at new time)
|
|
|
|
### Unschedule Content
|
|
|
|
**Request:**
|
|
```bash
|
|
POST /api/v1/writer/content/123/unschedule/
|
|
Content-Type: application/json
|
|
|
|
{}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Content unscheduled successfully",
|
|
"site_status": "not_published"
|
|
}
|
|
```
|
|
|
|
**Notes:**
|
|
- Removes content from publishing queue
|
|
- Content returns to `site_status='not_published'`
|
|
- Can be rescheduled or published immediately later
|
|
|
|
### Bulk Schedule with Site Defaults
|
|
|
|
**Request:**
|
|
```bash
|
|
POST /api/v1/writer/content/bulk_schedule/
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"content_ids": [123, 124, 125, 126],
|
|
"use_site_defaults": true,
|
|
"site_id": 45
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"scheduled_count": 4,
|
|
"schedule_preview": [
|
|
{
|
|
"content_id": 123,
|
|
"scheduled_at": "2025-01-17T09:00:00Z",
|
|
"title": "First Article"
|
|
},
|
|
{
|
|
"content_id": 124,
|
|
"scheduled_at": "2025-01-17T09:15:00Z",
|
|
"title": "Second Article"
|
|
},
|
|
{
|
|
"content_id": 125,
|
|
"scheduled_at": "2025-01-17T09:30:00Z",
|
|
"title": "Third Article"
|
|
},
|
|
{
|
|
"content_id": 126,
|
|
"scheduled_at": "2025-01-17T09:45:00Z",
|
|
"title": "Fourth Article"
|
|
}
|
|
],
|
|
"site_settings": {
|
|
"base_time": "09:00 AM",
|
|
"stagger_interval": 15,
|
|
"timezone": "America/New_York"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Notes:**
|
|
- Uses site's default publishing schedule from Site Settings
|
|
- Automatically staggers publications (e.g., 15 min intervals)
|
|
- No limit on number of items (unlike direct publish which is limited to 5)
|
|
- All items set to `site_status='scheduled'`
|
|
|
|
### Bulk Schedule Preview (Before Confirming)
|
|
|
|
**Request:**
|
|
```bash
|
|
POST /api/v1/writer/content/bulk_schedule_preview/
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"content_ids": [123, 124, 125],
|
|
"site_id": 45
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"schedule_preview": [
|
|
{"content_id": 123, "scheduled_at": "2025-01-17T09:00:00Z", "title": "Article 1"},
|
|
{"content_id": 124, "scheduled_at": "2025-01-17T09:15:00Z", "title": "Article 2"},
|
|
{"content_id": 125, "scheduled_at": "2025-01-17T09:30:00Z", "title": "Article 3"}
|
|
],
|
|
"site_settings": {
|
|
"base_time": "09:00 AM",
|
|
"stagger_interval": 15,
|
|
"timezone": "America/New_York",
|
|
"publish_days": ["mon", "tue", "wed", "thu", "fri"]
|
|
}
|
|
}
|
|
```
|
|
|
|
**Use Case:**
|
|
- Show user what times items will be scheduled before confirming
|
|
- Allow user to adjust site settings if needed
|
|
- User clicks "Confirm" to execute actual bulk_schedule
|
|
|
|
---
|
|
|
|
## Publishing Scheduler (v1.3.2)
|
|
|
|
### Celery Beat Tasks
|
|
|
|
Located in `igny8_core/tasks/publishing_scheduler.py`:
|
|
|
|
| Task | Schedule | Purpose |
|
|
|------|----------|---------|
|
|
| `schedule_approved_content` | Every 15 minutes | Assigns publish times to approved content |
|
|
| `process_scheduled_publications` | Every 5 minutes | Publishes content when scheduled time arrives |
|
|
| `cleanup_failed_publications` | Daily at midnight | Retries or cleans up failed publications |
|
|
|
|
### Scheduling Flow
|
|
|
|
```
|
|
Approved Content → schedule_approved_content (every 15 min)
|
|
↓
|
|
Check PublishingSettings
|
|
↓
|
|
Assign scheduled_publish_at based on:
|
|
- publish_days configuration
|
|
- publish_time_slots configuration
|
|
- daily/weekly/monthly limits
|
|
↓
|
|
Set site_status = "scheduled"
|
|
↓
|
|
process_scheduled_publications (every 5 min)
|
|
↓
|
|
If scheduled_publish_at <= now:
|
|
- Set site_status = "publishing"
|
|
- Execute publication
|
|
- Set site_status = "published" or "failed"
|
|
```
|
|
|
|
### Site Status State Machine
|
|
|
|
```
|
|
not_published → scheduled → publishing → published
|
|
↓ ↓
|
|
↓ → failed
|
|
↓
|
|
not_published (if unscheduled)
|
|
```
|
|
|
|
---
|
|
|
|
## Frontend Pages (v1.3.2)
|
|
|
|
### Content Calendar (`/publisher/content-calendar`)
|
|
|
|
**Purpose:** Visualize and manage scheduled content
|
|
|
|
**Features:**
|
|
- Calendar view of scheduled publications
|
|
- List view alternative
|
|
- Filter by site
|
|
- Schedule/unschedule actions
|
|
- Drag-and-drop rescheduling (planned)
|
|
|
|
**Components:**
|
|
- `ContentCalendar.tsx` - Main page component
|
|
- `CalendarItemTooltip` - Hover details for calendar items
|
|
- `SiteInfoBar` - Site context header
|
|
|
|
### Publishing Queue (`/publisher/publishing-queue`)
|
|
|
|
**Purpose:** Review upcoming publications
|
|
|
|
**Features:**
|
|
- List of content pending publication
|
|
- Status indicators (scheduled, publishing, failed)
|
|
- Publish now / unschedule actions
|
|
|
|
---
|
|
|
|
## Publishing Flow
|
|
|
|
### Single Content Publish
|
|
|
|
**Trigger:** User clicks "Publish" or API call
|
|
**Flow:**
|
|
1. Validate content is in publishable state
|
|
2. Get site integration credentials
|
|
3. Transform content for destination:
|
|
- Format HTML for platform
|
|
- Process images
|
|
- Map taxonomies
|
|
4. Push to destination API
|
|
5. Create `PublishingRecord` with external ID
|
|
6. Update Content status to `published`
|
|
|
|
### Batch Deployment
|
|
|
|
**Trigger:** Deployment action
|
|
**Flow:**
|
|
1. Create `DeploymentRecord`
|
|
2. Gather all pending content
|
|
3. Process each item:
|
|
- Publish to destination
|
|
- Create publishing record
|
|
- Update content status
|
|
4. Update deployment status
|
|
5. Log any errors
|
|
|
|
---
|
|
|
|
## Destination Adapters
|
|
|
|
### WordPress Adapter
|
|
|
|
- Uses WordPress REST API
|
|
- Supports posts, pages, custom post types
|
|
- Handles media upload
|
|
- Maps categories/tags
|
|
|
|
### Ghost Adapter (Planned)
|
|
|
|
- Ghost Admin API integration
|
|
- Post publishing
|
|
- Image handling
|
|
|
|
### Webflow Adapter (Planned)
|
|
|
|
- Webflow CMS API
|
|
- Collection item publishing
|
|
- Asset management
|
|
|
|
---
|
|
|
|
## Publishing States
|
|
|
|
| Status | Description |
|
|
|--------|-------------|
|
|
| pending | Ready to publish |
|
|
| published | Successfully published |
|
|
| failed | Publishing failed |
|
|
| retracted | Unpublished/removed |
|
|
|
|
---
|
|
|
|
## Site Definition Endpoint
|
|
|
|
**Purpose:** Public endpoint for headless CMS use cases
|
|
|
|
Returns site structure for external consumption:
|
|
- Site metadata
|
|
- Available taxonomies
|
|
- Content types
|
|
- URL structure
|
|
|
|
---
|
|
|
|
## Integration Points
|
|
|
|
| From | To | Trigger |
|
|
|------|----|---------|
|
|
| Writer | Publisher | Publish action |
|
|
| Automation Stage 7 | Publisher | Auto-publish (future) |
|
|
| Publisher | Integrations | Destination APIs |
|
|
| Publisher | Content | Status updates |
|
|
|
|
---
|
|
|
|
## Common Issues
|
|
|
|
| Issue | Cause | Fix |
|
|
|-------|-------|-----|
|
|
| Publish failed | Invalid credentials | Check integration settings |
|
|
| Duplicate posts | Published twice | Check existing publishing record |
|
|
| Images missing | Upload failed | Check media library access |
|
|
| Wrong category | Mapping issue | Verify taxonomy sync |
|
|
|
|
---
|
|
|
|
## Planned Changes
|
|
|
|
| Feature | Status | Description |
|
|
|---------|--------|-------------|
|
|
| Ghost integration | 🔜 Planned | Ghost CMS publishing |
|
|
| Webflow integration | 🔜 Planned | Webflow publishing |
|
|
| ~~Scheduled publishing~~ | ✅ Implemented (v1.3.2) | Future-date publishing |
|
|
| Republish detection | 🔜 Planned | Detect and handle updates |
|
|
| ~~Publishing queue~~ | ✅ Implemented (v1.3.2) | Batch publishing with queue |
|
|
| Drag-and-drop calendar | 🔜 Planned | Reschedule via drag-and-drop |
|