# Blog Admin API Specification **Status:** Awaiting Socrates implementation **Frontend Status:** ✅ Complete (Phase 4 admin UI delivered 2026-04-21) --- ## Overview Admin API endpoints required to power the HoffDesk Blog admin interface. All endpoints return JSON unless otherwise specified. HTMX requests expect HTML partials in response. --- ## Dev Server A standalone dev server is available for local preview: ```bash cd blog/ python3 dev_server.py ``` **Access points:** - Public blog: http://localhost:8080/ - Admin panel: http://localhost:8080/admin/ - Editor: http://localhost:8080/admin/posts/the-night-i-broke-dns/edit The dev server includes mock data for all endpoints so you can preview the UI before Socrates wires the real API. --- ## Authentication All admin endpoints require authentication. Current assumption: session-based auth via FastAPI (same as main HoffDesk app). --- ## Endpoints ### Dashboard #### `GET /api/blog/admin/stats` Returns dashboard statistics for the admin homepage. **Response:** ```json { "total": 12, "published": 8, "drafts": 4, "images": 23, "last_build_time": "2026-04-21T10:30:00Z", "last_build_iso": "2026-04-21T10:30:00+00:00" } ``` #### `GET /api/blog/admin/recent` Returns recent posts for the dashboard activity feed. **Response:** ```json { "posts": [ { "slug": "the-night-i-broke-dns", "title": "The Night I Broke DNS and My Wife Couldn't Reach Facebook", "category": "homelab", "status": "published", "updated_relative": "2 hours ago" } ] } ``` --- ### Posts #### `GET /api/blog/admin/posts` Returns list of posts with filtering. **Query Parameters:** - `status` (optional): `published` | `draft` - `category` (optional): `homelab` | `openclaw` | `ai-news` - `q` (optional): search string - `page` (optional): page number (default: 1) - `per_page` (optional): items per page (default: 20) **Response:** ```json { "posts": [ { "slug": "post-slug", "title": "Post Title", "category": "homelab", "status": "published", "updated_at": "2026-04-21T10:30:00Z", "updated_relative": "2 hours ago", "excerpt": "Brief summary..." } ], "pagination": { "page": 1, "per_page": 20, "total": 12, "pages": 1 } } ``` #### `GET /api/blog/admin/posts/{slug}` Returns full post data for editing. **Response:** ```json { "slug": "post-slug", "title": "Post Title", "category": "homelab", "status": "published", "tags": "dns, homelab, fail", "excerpt": "Brief summary...", "cover_image": "/blog/images/hero.jpg", "content": "# Markdown content...", "rendered_html": "
Content...
" } ``` --- ### Build & Deploy #### `POST /api/blog/admin/rebuild` Triggers static site rebuild. **Response (HTMX):** ```html ``` #### `POST /api/blog/admin/deploy` Triggers deployment to production (Cloudflare Pages). **Response (HTMX):** ```html ``` --- ### Images #### `GET /api/blog/admin/images` Returns list of available images in the blog images directory. **Response:** ```json { "images": [ { "path": "/blog/images/hero.jpg", "filename": "hero.jpg", "relative_path": "images/hero.jpg", "size_bytes": 45000, "dimensions": "1200x600", "modified": "2026-04-21T10:30:00Z" } ] } ``` --- ## HTMX Conventions All endpoints support HTMX requests via the `HX-Request` header: - **Save endpoints:** Return toast message HTML - **Status changes:** Return full component HTML (status widget, post row) - **Rebuild/Deploy:** Return toast confirmation - **Delete:** Return redirect header or toast --- ## Frontend Integration Notes ### Auto-save Behavior - Debounced 3s after input stops - Includes all form fields via `hx-include` - Visual feedback via autosave indicator ### Live Preview - Client-side: markdown-it (500ms debounce) - Server-side: `POST /api/blog/admin/posts/{slug}/preview` (enhancement) ### Status Widget - Dynamic partial swap on publish/unpublish - Green dot = published, amber dot = draft ### Mobile Considerations - Preview pane hidden behind toggle on <768px - Sidebar collapses to hamburger menu - Tables become card layouts --- ## Files Delivered **Templates (Jinja2):** - `admin/templates/admin_base.html.j2` — Base layout with sidebar - `admin/templates/admin_dashboard.html.j2` — Stats + recent activity - `admin/templates/admin_post_list.html.j2` — Filterable post table - `admin/templates/admin_editor.html.j2` — Split-pane editor - `admin/templates/admin_images.html.j2` — Image browser - `admin/templates/components/post_row.html.j2` — HTMX partial - `admin/templates/components/status_widget.html.j2` — HTMX partial - `admin/templates/components/preview_pane.html.j2` — HTMX partial **Stylesheets:** - `admin/static/admin.css` — 28KB, extends blog.css tokens **Scripts:** - Inline JS in admin_editor.html.j2 for client-side preview --- ## Next Steps 1. Socrates implements above endpoints 2. Integration testing on dev environment 3. Matt approves UX flow 4. Deploy to production