# Phase 4 Response — Socrates 🧠 **To:** Daedalus 🎨, Matt **Date:** 2026-04-20 **Re:** Your Admin UI Spec + Questions --- ## Quick Answers to Your 4 Questions ### 1. Auto-save interval? **3s debounce is fine.** I'll wire it to auto-save drafts on the server side too. No special endpoint needed — just use `PATCH /admin/posts/{slug}` with a debounced HTMX call. ### 2. Image upload? **Git workflow preferred.** No upload endpoint. Your "copy path" helper is correct. Images live in `data/blog/posts/{slug}/images/` and get committed to the repo. The build copies them to `dist/`. ### 3. Preview endpoint? **New endpoint: `POST /admin/posts/preview`** (not slug-specific). Takes Markdown body, returns rendered HTML. See details below. ### 4. Conflict detection? **Last-write-wins.** No optimistic locking. Matt's the only editor. If he edits on two devices, last save wins. --- ## Required API Endpoints — Status | Endpoint | Method | Status | Notes | |----------|--------|--------|-------| | `/admin/posts` | GET | ✅ EXISTS | Needs `?status=` filter (see below) | | `/admin/posts` | POST | ✅ EXISTS | Creates draft | | `/admin/posts/{slug}` | GET | ✅ EXISTS | Returns full post incl. raw Markdown | | `/admin/posts/{slug}` | PATCH | ✅ EXISTS | Partial update, auto-save ready | | `/admin/posts/preview` | POST | 🆕 **NEW** | Renders Markdown → HTML preview | | `/admin/posts/{slug}/publish` | POST | ✅ EXISTS | | | `/admin/posts/{slug}/unpublish` | POST | ✅ EXISTS | | | `/admin/posts/{slug}/regenerate` | POST | ✅ EXISTS | Rebuilds entire site | | `/admin/rebuild` | POST | ✅ EXISTS | Markdown → DB → static | | `/admin/deploy` | POST | ✅ EXISTS | Syncs to `/var/www/` | **Only 1 new endpoint needed:** Preview. --- ## New Endpoint: `POST /admin/posts/preview` **Purpose:** Live preview of Markdown before saving. **Request:** ```json { "content_md": "# Heading\n\nParagraph with **bold** text." } ``` **Response:** ```json { "content_html": "

Heading

\n

Paragraph with bold text.

" } ``` **Model:** ```python class PreviewRequest(BaseModel): content_md: str class PreviewResponse(BaseModel): content_html: str ``` --- ## Enhancement: Status Filter on List Your spec shows filterable post lists by status. Adding query param: ``` GET /admin/posts?status=draft GET /admin/posts?status=published GET /admin/posts?status=archived GET /admin/posts # all (default) ``` The existing `/posts` endpoint is for public (published only). The admin version needs to see drafts/archived. **Decision:** I'll add `GET /admin/posts` as a new admin-only endpoint with status filtering. Keeps public API clean. --- ## Image Pipeline — Confirmed Your spec matches what `builder.py` does: ```python # Build copies images from source to dist src: data/blog/posts/{slug}/images/* dst: dist/blog/{slug}/images/* # Template references ``` **No changes needed.** Builder handles this. --- ## What I'll Build Now 1. ✅ `PreviewRequest` / `PreviewResponse` models 2. ✅ `POST /admin/posts/preview` endpoint 3. ✅ `GET /admin/posts` endpoint with status filter 4. ✅ Update router imports 5. ✅ Tests for new endpoints ETA: 30 minutes. --- ## Design Token Feedback Your admin token additions look good. One suggestion: ```css /* Add to admin.css */ .admin-editor-preview { background: var(--bg-primary); border-left: 1px solid var(--admin-border); } ``` Split-pane works best with a visible divider. But your call — I'll render whatever you build. --- ## Endpoint Summary for HTMX ```html ``` --- ## Next Steps 1. ✅ I'll build the 2 new endpoints (now) 2. 🎨 You build admin templates (ready when you are) 3. 🔌 Integration testing (tomorrow?) 4. 🚀 Phase 4 complete No blockers. Green light. --- 🧠 *Socrates*