Skip to content
This repository was archived by the owner on Aug 11, 2026. It is now read-only.
This repository was archived by the owner on Aug 11, 2026. It is now read-only.

Issue 5: Implement Revisions and Scheduled Publishing #541

Description

@ahliweb

Parent Epic: #536
Depends on: #537, #538, #539

Objective

Add revision history, revision restore, scheduled publishing script, audit events, and AsyncAPI blog domain events.

Context

This issue improves editorial workflow safety. It must preserve append-only revision history, make scheduled publishing idempotent, and emit meaningful audit/domain events without calling external providers inside database transactions.

Scope

  • Create revision on significant post/page changes
  • List revisions
  • Read revision detail
  • Restore revision
  • Add scheduled publishing Bun script
  • Add package script for scheduled publishing
  • Add AsyncAPI events
  • Ensure scheduled publishing is idempotent

Out of Scope

  • Admin UI screens
  • Public route rendering
  • Template/widget/menu/ads implementation
  • External scheduler/provider integration

Routes

GET  /api/v1/blog/posts/{id}/revisions
GET  /api/v1/blog/posts/{id}/revisions/{revisionId}
POST /api/v1/blog/posts/{id}/revisions/{revisionId}/restore

Script

scripts/blog-scheduled-publish.ts

Package script:

"blog:publish:scheduled": "bun scripts/blog-scheduled-publish.ts"

Revision Rules

  • Revision is created when post/page content changes significantly.
  • Revisions are append-only.
  • Revision restore creates a new revision.
  • Revision restore requires explicit permission.
  • Revision restore requires Idempotency-Key.
  • Normal endpoints must not overwrite or delete existing revision history.

Scheduled Publishing Rules

  • Finds due scheduled posts per tenant.
  • Publishes only posts with status = 'scheduled' and scheduled_at <= now().
  • Sets status = 'published'.
  • Sets published_at = now() only if not already set.
  • Ignores future scheduled posts.
  • Ignores already published posts.
  • Must be idempotent.
  • Must write audit events.
  • Must emit domain event if event outbox is used.
  • Must not call external providers inside DB transaction.

Permission Mapping

GET revisions                -> blog_content.revisions.read
POST revision restore        -> blog_content.revisions.restore
Scheduled publish job        -> existing trusted runtime/job execution pattern

Audit Requirements

Record audit events for:

blog.post.revision_restored
blog.post.scheduled_publish_executed
blog.post.scheduled_publish_skipped

Also reuse existing events from post lifecycle where applicable:

blog.post.published
blog.post.updated

AsyncAPI Events

Add meaningful events using existing DomainEvent schema pattern:

awcms-mini.blog-content.post.created
awcms-mini.blog-content.post.updated
awcms-mini.blog-content.post.submitted-for-review
awcms-mini.blog-content.post.published
awcms-mini.blog-content.post.scheduled
awcms-mini.blog-content.post.archived
awcms-mini.blog-content.post.deleted
awcms-mini.blog-content.post.restored
awcms-mini.blog-content.post.purged
awcms-mini.blog-content.revision.created
awcms-mini.blog-content.term.created
awcms-mini.blog-content.term.updated
awcms-mini.blog-content.settings.updated

Acceptance Criteria

  • Revision is created when post/page content changes significantly.
  • Revisions are append-only.
  • Revision restore creates a new revision.
  • Revision restore requires explicit permission.
  • Revision restore requires Idempotency-Key.
  • Revision list/detail routes require authentication and tenant context.
  • Cross-tenant revision access is denied.
  • Scheduled publishing script runs with Bun.
  • Scheduled publishing is idempotent.
  • Due scheduled posts are published.
  • Future scheduled posts are ignored.
  • Already published posts are ignored.
  • Scheduled publish writes audit events.
  • AsyncAPI is updated.
  • Tests cover revision creation.
  • Tests cover revision restore.
  • Tests cover scheduled publishing.
  • Tests cover idempotency.
  • Tests cover audit event behavior.
  • Tests cover event contract behavior where applicable.

Validation Commands

bun run db:migrate
bun run api:spec:check
bun run test
bun run typecheck
bun run blog:publish:scheduled

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions