Parent Epic: #536
Depends on: #537
Objective
Implement tenant-scoped admin API for blog post CRUD and lifecycle actions.
Context
This issue builds on the blog_content schema and permission foundation. It must use existing AWCMS-Mini API, auth, tenant, RBAC/ABAC, idempotency, audit, and response patterns.
Scope
- List posts
- Create post
- Read post detail
- Update post
- Soft-delete post
- Submit post for review
- Publish post
- Schedule post
- Archive post
- Restore post
- Purge post
- Enforce auth, tenant context, RBAC/ABAC, idempotency, audit, and RLS
Out of Scope
- Pages API
- Taxonomy API
- Public blog rendering
- Admin UI
- Template/widget/menu/ads implementation
Routes
GET /api/v1/blog/posts
POST /api/v1/blog/posts
GET /api/v1/blog/posts/{id}
PATCH /api/v1/blog/posts/{id}
DELETE /api/v1/blog/posts/{id}
POST /api/v1/blog/posts/{id}/submit-review
POST /api/v1/blog/posts/{id}/publish
POST /api/v1/blog/posts/{id}/schedule
POST /api/v1/blog/posts/{id}/archive
POST /api/v1/blog/posts/{id}/restore
POST /api/v1/blog/posts/{id}/purge
Permission Mapping
GET list/detail -> blog_content.posts.read
POST create -> blog_content.posts.create
PATCH update -> blog_content.posts.update
DELETE soft-delete -> blog_content.posts.delete
POST submit-review -> blog_content.posts.update
POST publish -> blog_content.posts.publish
POST schedule -> blog_content.posts.schedule
POST archive -> blog_content.posts.archive
POST restore -> blog_content.posts.restore
POST purge -> blog_content.posts.purge
ABAC Rules
Minimum rules:
- Cross-tenant access must always be denied.
- Author may edit own draft post if the post is not published.
- Author may not publish unless granted
blog_content.posts.publish.
- Editor/Admin with permission may edit all tenant posts.
- Restore and purge require explicit restore/purge permission.
- Purge is forbidden for published content unless archived or soft-deleted first.
Idempotency Requirements
Require Idempotency-Key for:
POST /api/v1/blog/posts/{id}/publish
POST /api/v1/blog/posts/{id}/schedule
POST /api/v1/blog/posts/{id}/archive
POST /api/v1/blog/posts/{id}/restore
POST /api/v1/blog/posts/{id}/purge
Recommended for:
POST /api/v1/blog/posts
PATCH /api/v1/blog/posts/{id}
Audit Requirements
Record audit events for:
blog.post.created
blog.post.updated
blog.post.submitted_for_review
blog.post.published
blog.post.scheduled
blog.post.archived
blog.post.deleted
blog.post.restored
blog.post.purged
Audit attributes must use existing redaction patterns. Do not log raw tokens, emails, phone numbers, secrets, or sensitive identifiers.
Acceptance Criteria
Validation Commands
bun run db:migrate
bun run api:spec:check
bun run test
bun run typecheck
Parent Epic: #536
Depends on: #537
Objective
Implement tenant-scoped admin API for blog post CRUD and lifecycle actions.
Context
This issue builds on the
blog_contentschema and permission foundation. It must use existing AWCMS-Mini API, auth, tenant, RBAC/ABAC, idempotency, audit, and response patterns.Scope
Out of Scope
Routes
GET /api/v1/blog/posts POST /api/v1/blog/posts GET /api/v1/blog/posts/{id} PATCH /api/v1/blog/posts/{id} DELETE /api/v1/blog/posts/{id} POST /api/v1/blog/posts/{id}/submit-review POST /api/v1/blog/posts/{id}/publish POST /api/v1/blog/posts/{id}/schedule POST /api/v1/blog/posts/{id}/archive POST /api/v1/blog/posts/{id}/restore POST /api/v1/blog/posts/{id}/purgePermission Mapping
ABAC Rules
Minimum rules:
blog_content.posts.publish.Idempotency Requirements
Require
Idempotency-Keyfor:POST /api/v1/blog/posts/{id}/publish POST /api/v1/blog/posts/{id}/schedule POST /api/v1/blog/posts/{id}/archive POST /api/v1/blog/posts/{id}/restore POST /api/v1/blog/posts/{id}/purgeRecommended for:
POST /api/v1/blog/posts PATCH /api/v1/blog/posts/{id}Audit Requirements
Record audit events for:
Audit attributes must use existing redaction patterns. Do not log raw tokens, emails, phone numbers, secrets, or sensitive identifiers.
Acceptance Criteria
Idempotency-Key.Validation Commands
bun run db:migrate bun run api:spec:check bun run test bun run typecheck