15 KiB
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/settingspage 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 |
|---|---|---|
/api/v1/sites/{site_id}/settings?tab=publishing |
||
/api/v1/sites/{site_id}/publishing-settings/ |
API Usage Examples
Publish Content Immediately
Request:
POST /api/v1/publisher/publish/
Content-Type: application/json
{
"content_id": 123,
"destinations": ["wordpress"] # or ["shopify"], ["custom"]
}
Success Response:
{
"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:
{
"success": false,
"error": "Publishing API error: Invalid credentials"
}
Schedule Content for Future Publishing
Request:
POST /api/v1/writer/content/123/schedule/
Content-Type: application/json
{
"scheduled_publish_at": "2025-01-20T09:00:00Z"
}
Response:
{
"success": true,
"scheduled_publish_at": "2025-01-20T09:00:00Z",
"site_status": "scheduled"
}
Notes:
- Content
site_statuschanges fromnot_published→scheduled - Celery task
process_scheduled_publicationswill publish at scheduled time - Runs every 5 minutes, so publishing happens within 5 min of scheduled time
Reschedule Content
Request:
POST /api/v1/writer/content/123/reschedule/
Content-Type: application/json
{
"scheduled_at": "2025-01-21T10:00:00Z"
}
Response:
{
"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:
POST /api/v1/writer/content/123/unschedule/
Content-Type: application/json
{}
Response:
{
"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:
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:
{
"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:
POST /api/v1/writer/content/bulk_schedule_preview/
Content-Type: application/json
{
"content_ids": [123, 124, 125],
"site_id": 45
}
Response:
{
"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 componentCalendarItemTooltip- Hover details for calendar itemsSiteInfoBar- 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:
- Validate content is in publishable state
- Get site integration credentials
- Transform content for destination:
- Format HTML for platform
- Process images
- Map taxonomies
- Push to destination API
- Create
PublishingRecordwith external ID - Update Content status to
published
Batch Deployment
Trigger: Deployment action
Flow:
- Create
DeploymentRecord - Gather all pending content
- Process each item:
- Publish to destination
- Create publishing record
- Update content status
- Update deployment status
- 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 |
| ✅ Implemented (v1.3.2) | Future-date publishing | |
| Republish detection | 🔜 Planned | Detect and handle updates |
| ✅ Implemented (v1.3.2) | Batch publishing with queue | |
| Drag-and-drop calendar | 🔜 Planned | Reschedule via drag-and-drop |