Files
HIPCTF2/docs/database/blog-posts.md
T
2026-07-23 10:17:52 +00:00

45 lines
2.3 KiB
Markdown

---
type: database
title: Blog Post Table
description: blog_post table — draft/published Markdown posts surfaced on the public landing page.
tags: [database, blog, markdown]
timestamp: 2026-07-23T10:12:24Z
---
# Schema
| Column | Type | Description |
|----------------|------------------|--------------------------------------------------------------|
| `id` | TEXT PK | UUID v4 (set by the service, not auto-generated). |
| `title` | TEXT | Post title. |
| `body_md` | TEXT (default `''`) | Markdown body. |
| `status` | TEXT (default `'draft'`) | One of `draft` or `published`. |
| `created_at` | TEXT | ISO 8601 (TypeORM `@CreateDateColumn`). |
| `updated_at` | TEXT | ISO 8601 (TypeORM `@UpdateDateColumn`). |
| `published_at` | TEXT, nullable | ISO 8601 timestamp the post was published (set when status flips). |
# Indexes
| Index | Columns | Purpose |
|------------------------------------|----------------------------------|------------------------------------------------------------|
| `idx_blog_status_published` | `(status, published_at)` | Lets `GET /api/v1/blog/posts` filter to `status='published'` and order by `published_at DESC` cheaply. |
# Behavior
* Only rows with `status = 'published'` are exposed through the public
endpoint `GET /api/v1/blog/posts` (see [Blog API](/api/blog.md)). Drafts
are hidden from the landing page and authenticated `/blog` page.
* The admin CRUD endpoints under `/api/v1/admin/blog/posts` expose both
statuses and all timestamps to administrators.
* First publication sets `published_at`. Later edits, demotion to draft,
and republication preserve that original timestamp.
* `BlogService.listPublished()` orders by `published_at DESC`, falling
back to `created_at` when `published_at` is null.
# See also
- [Database Schema Overview](/database/schema.md)
- [Blog API](/api/blog.md)
- [Blog Publishing and Reading](/guides/blog.md)
- [Landing Page Guide](/guides/landing-page.md)