Spaces:
Running
Publishing Operations — Phase 9
Status
Publishing operations are implemented in the current working tree with durable unified jobs, calendar/queue/draft flows, retries, idempotency, and SDK/MCP/n8n transport coverage. PostgreSQL/RLS runtime verification, Docker, FFmpeg, Hugging Face startup, live provider certification, and final production certification remain deferred until all planned product phases are complete.
Audit
The Phase 8 audit found one authoritative publishing domain under
app/social/. SocialPost is already the canonical draft/post record, a
post owns multiple SocialPostTarget rows, SocialSchedule stores UTC
timestamps plus the requested IANA timezone, and SocialJob is the durable
per-target queue consumed by the existing scheduler and publisher workers.
Provider adapters, OAuth/TokenService, capability discovery, asset ownership,
RLS, retries, cancellation requests, reconciliation, partial success, SDK,
MCP, n8n, Copilot, project provenance, and Content Studio integration are
reused. No duplicate post, account, asset, or job tables were introduced.
Phase 9 adds revision-safe draft mutation and rescheduling, queue/calendar
read models, and durable bounded bulk orchestration. revision on posts and
schedules is additive and is checked server-side for updates, duplication, and
rescheduling. social_publishing_batches and
social_publishing_batch_items are additive, workspace-isolated orchestration
records; individual posts/jobs retain their own state and idempotency.
State and APIs
Existing /v1/social/posts, /publish, /schedule, /cancel, validation,
jobs, accounts, and provider routes remain canonical. Phase 9 adds:
GET /v1/social/draftsPATCH/DELETE /v1/social/drafts/{post_id}PATCH /v1/social/posts/{post_id}POST /v1/social/posts/{post_id}/duplicatePOST /v1/social/posts/{post_id}/rescheduleGET /v1/social/publishing-contextGET /v1/social/calendarGET /v1/social/queuePOST /v1/social/bulk
The batch operation is schedule, reschedule, cancel, duplicate, or
delete. Batch items are claimed with FOR UPDATE SKIP LOCKED by the existing
Social scheduler boundary and report independent completion/failure.
Drafts remain draft until server validation. validating and ready are
reserved state vocabulary for future asynchronous validation materialization;
provider execution continues to use the existing queued → preparing →
processing → uploading → publishing → terminal transitions. No frontend
can arbitrarily mutate execution state.
Calendar and timezone model
The calendar accepts an aware UTC range and returns scheduled posts with the stored schedule timezone and schedule revision. Workspace timezone is read from authoritative workspace metadata, defaulting to UTC only when no workspace timezone has been configured. UI date-time inputs are explicitly labelled with that timezone and converted to an instant before mutation. Invalid, past, unordered, or excessively broad ranges are rejected.
Queue and bulk behavior
Queue filtering supports provider, account, project, status, search, bounded
pagination, and live polling through TanStack Query. Bulk requests are
bounded to 100 posts, idempotent at batch level, and never clone provider job
IDs or provider references. Batch processing runs through the existing worker
loop; partial item failure produces partial_success at the batch level.
Security, permissions, RLS, and audit
Existing Social scopes are reused: social:posts:read/write/publish,
social:schedules:read/write, and account scopes. The BFF continues to enforce
same-origin and session permission checks before forwarding authenticated
requests. Migration 0009_publishing_operations.sql enables and forces RLS
for batch tables, adds workspace checks, foreign keys, indexes, and revision
columns without destructive changes. Audit events use bounded
publishing.* names alongside legacy Social event names; credentials, signed
URLs, provider payloads, and binary media are never recorded.
Integrations
The Composer, Calendar, Queue, and Drafts routes use the existing Workspace shell, design system, Social hooks, canonical project assets, and provider capabilities. TypeScript and Python SDK Social resources expose draft, duplicate, reschedule, calendar, queue, and bulk methods. MCP exposes narrowly scoped queue/calendar/reschedule/duplicate/bulk tools through the shared service. The official n8n Social node exposes deterministic queue/calendar, duplicate, reschedule, and bulk operations through the SDK credential.
Runtime limitations
Local validation is limited by the available Termux environment. PostgreSQL RLS runtime checks, Docker, FFmpeg, Hugging Face startup, live provider credentials, provider certification, production OpenAPI verification, and final production hardening remain intentionally deferred until all MediaRouter product phases are complete.