Files
chicken_babies_site/.gitignore
Phillip Tarrant 9a8506970c feat: phase 4 admin CMS — dashboard, editor, media, CSRF
Head Hen CMS end-to-end: dashboard lists all posts (drafts + published),
Markdown editor with live preview + drag-drop image upload, Pillow media
pipeline re-encoding every upload to JPEG, post CRUD + publish toggle +
hard delete, About page edit, and double-submit CSRF cookie enforced on
every admin mutating endpoint (Phase 3's TODO markers resolved).

Slug auto-generated on create and server-locked once a post has been
published. Unpublish preserves `published_at` so re-publish keeps
original date ordering. Every admin write invalidates the read-side
Post/Page TTL caches and records an `auth_events` audit row.

CSRF middleware is narrow by design — issues/refreshes the `cb_csrf`
cookie only on `GET /admin*`, and mutating endpoints opt in via
`require_csrf_form` or `require_csrf_header` Depends. Public routes,
healthz, and pre-auth login stay untouched.

64 new tests cover slugs, CSRF, media, admin posts/pages services, and
end-to-end CMS routes. Tests never mock the DB — real temp SQLite files
per the CLAUDE.md mandate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 20:42:01 -05:00

49 lines
662 B
Plaintext

# Python
__pycache__/
*.py[cod]
*$py.class
*.egg-info/
.pytest_cache/
.mypy_cache/
.ruff_cache/
# Virtual environments
venv/
.venv/
env/
# Secrets / local config
.env
.env.*
!.env.example
# SQLite runtime
*.sqlite
*.sqlite3
*.db
*.db-journal
*.db-wal
*.db-shm
# Runtime data (DB + media uploads live here in prod).
# Ignore everything inside data/ except the .gitkeep markers; negating a
# path whose *directory* is ignored does not work, so we ignore the
# contents with a trailing glob instead.
data/*
!data/.gitkeep
!data/media/
data/media/*
!data/media/.gitkeep
# Editors / IDE
.vscode/
.idea/
*.swp
*.swo
.DS_Store
# Build / Docker
build/
dist/
*.log