You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Aug 11, 2026. It is now read-only.
Add static page management, category/tag management, post-term assignment, and PostgreSQL full-text search for admin and public-safe content discovery.
Context
This issue extends the core blog_content module beyond posts. It must follow the same auth, tenant, RBAC/ABAC, audit, idempotency, RLS, and standard response patterns introduced in the blog post API.
Scope
Page CRUD
Category management
Tag management
Post-term relation handling
PostgreSQL full-text search for posts and pages
Admin search with permission enforcement
Public-safe search helper
Out of Scope
Public route rendering
RSS and sitemap generation
Admin UI
Revisions and scheduled publishing
Template/widget/menu/ads implementation
Routes
GET /api/v1/blog/pages
POST /api/v1/blog/pages
GET /api/v1/blog/pages/{id}
PATCH /api/v1/blog/pages/{id}
DELETE /api/v1/blog/pages/{id}
GET /api/v1/blog/terms
POST /api/v1/blog/terms
PATCH /api/v1/blog/terms/{id}
DELETE /api/v1/blog/terms/{id}
GET /api/v1/blog/search
Permission Mapping
GET pages list/detail -> blog_content.pages.read
POST pages create -> blog_content.pages.create
PATCH pages update -> blog_content.pages.update
DELETE pages soft-delete -> blog_content.pages.delete
GET terms -> blog_content.taxonomies.read
POST/PATCH/DELETE terms -> blog_content.taxonomies.configure
GET admin search -> blog_content.search.read
Data Rules
Pages
Pages follow the same core lifecycle model as posts.
Pages support page_type:
standard
landing
legal
system
Pages support parent-child structure through parent_page_id.
Pages support menu_order.
Categories and Tags
Categories support parent-child hierarchy.
Tags must reject parent_id.
Terms are unique by tenant, taxonomy type, and slug where not deleted.
Post-term relation must include tenant_id and be protected by RLS.
Search
Use PostgreSQL full-text search.
Search must be tenant-scoped.
Use tenant-prefixed indexes.
Use bounded or keyset pagination.
Admin search may include draft/review/scheduled/published/archived content according to permission.
Public-safe helper must only return content allowed by the public visibility predicate.
Public Visibility Predicate for Public-Safe Search
status ='published'AND visibility ='public'AND deleted_at IS NULLAND published_at IS NOT NULLAND published_at <= now()
Acceptance Criteria
Page CRUD works with the same auth, tenant, RBAC/ABAC, audit, and RLS pattern as posts.
Categories support parent-child hierarchy.
Tags reject parent_id.
Terms are unique by tenant, taxonomy type, and slug where not deleted.
Post-term relation is tenant-scoped.
Search vector is maintained for posts and pages.
Admin search respects tenant and permissions.
Public-safe search only returns published public content.
Search uses PostgreSQL full-text search.
Search uses bounded or keyset pagination.
OpenAPI is updated.
Tests cover page CRUD.
Tests cover taxonomy rules.
Tests cover search visibility.
Tests cover RLS tenant isolation.
Tests cover ABAC allow/deny behavior.
Validation Commands
bun run db:migrate
bun run api:spec:check
bun run test
bun run typecheck
Parent Epic: #536
Depends on: #537, #538
Objective
Add static page management, category/tag management, post-term assignment, and PostgreSQL full-text search for admin and public-safe content discovery.
Context
This issue extends the core
blog_contentmodule beyond posts. It must follow the same auth, tenant, RBAC/ABAC, audit, idempotency, RLS, and standard response patterns introduced in the blog post API.Scope
Out of Scope
Routes
GET /api/v1/blog/pages POST /api/v1/blog/pages GET /api/v1/blog/pages/{id} PATCH /api/v1/blog/pages/{id} DELETE /api/v1/blog/pages/{id} GET /api/v1/blog/terms POST /api/v1/blog/terms PATCH /api/v1/blog/terms/{id} DELETE /api/v1/blog/terms/{id} GET /api/v1/blog/searchPermission Mapping
Data Rules
Pages
page_type:standardlandinglegalsystemparent_page_id.menu_order.Categories and Tags
parent_id.tenant_idand be protected by RLS.Search
Public Visibility Predicate for Public-Safe Search
Acceptance Criteria
parent_id.Validation Commands
bun run db:migrate bun run api:spec:check bun run test bun run typecheck