Files
gw/AGENT.md
T
ponzischeme89 6d44e05de4 v1
2026-04-18 07:23:55 +12:00

3.8 KiB

Project: CMS API for SvelteKit Marketing Site

Context

I have a public marketing website built with SvelteKit (frontend) and Python (backend). I need a secure, read/write JSON API that:

  • Serves as the data layer between a CMS admin interface and the SvelteKit frontend
  • Allows authenticated CMS users to create, update, and delete content
  • Allows the SvelteKit frontend to read content (public, no auth required for reads)

Tech Stack

  • API: Python (FastAPI)
  • Database: PostgreSQL via SQLAlchemy (async) + Alembic for migrations
  • Auth: JWT bearer tokens for write operations (CMS admin). Read endpoints are public.
  • Validation: Pydantic v2 models for all request/response schemas
  • Frontend consumer: SvelteKit load() functions calling the API server-side

Requirements

Data Models

Scaffold these content types (all with id, created_at, updated_at, published boolean, slug unique index):

  • Pagetitle, slug, body (rich text/HTML string), meta_title, meta_description, og_image_url
  • BlogPosttitle, slug, excerpt, body, author, featured_image_url, tags (array of strings)
  • SiteSettings — singleton row: site_name, tagline, logo_url, footer_text, social_links (JSON object)

API Endpoints

All under /api/v1/:

Public (no auth):

  • GET /pages — list published pages
  • GET /pages/{slug} — single published page by slug
  • GET /posts — list published posts (pagination: ?page=1&per_page=10, ordered by created_at desc)
  • GET /posts/{slug} — single published post by slug
  • GET /settings — site settings singleton

Protected (JWT required):

  • POST / PUT / DELETE for pages and posts
  • PUT /settings
  • POST /auth/login — accepts email + password, returns JWT access + refresh tokens
  • POST /auth/refresh — rotate refresh token

Security

  • Passwords hashed with bcrypt
  • JWT access tokens: 15 min expiry. Refresh tokens: 7 day expiry, stored server-side, revocable.
  • All write endpoints behind Depends(get_current_user) FastAPI dependency
  • CORS: allow the SvelteKit origin only (configurable via env var ALLOWED_ORIGINS)
  • Rate limiting on /auth/* endpoints (e.g. slowapi, 5 req/min per IP)
  • Input sanitisation: strip/reject dangerous HTML in body fields (bleach or nh3)

Project Structure

backend/
├── app/
│   ├── main.py              # FastAPI app, CORS, lifespan
│   ├── config.py             # pydantic-settings BaseSettings from .env
│   ├── database.py           # async engine, sessionmaker, get_db dependency
│   ├── models/               # SQLAlchemy ORM models
│   ├── schemas/              # Pydantic request/response schemas
│   ├── routers/              # pages.py, posts.py, settings.py, auth.py
│   ├── services/             # business logic layer
│   ├── auth/                 # JWT creation, verification, password hashing
│   └── middleware/           # rate limiting, request logging
├── alembic/                  # migrations
├── alembic.ini
├── requirements.txt
├── .env.example
└── Dockerfile

Additional

  • Include a seed.py script that creates a default admin user and sample content
  • Add a Dockerfile and docker-compose.yml (API + Postgres)
  • Include a .env.example with all required env vars documented
  • Write basic pytest tests for auth flow and one CRUD resource
  • Add OpenAPI tags and descriptions so the /docs page is well-organised

Constraints

  • Python 3.12+
  • Do NOT use any ORM magic for auth — keep JWT logic explicit and auditable
  • All database calls must be async
  • Return proper HTTP status codes (201 on create, 204 on delete, 404/422/401/403 as appropriate)
  • Pagination responses must include total, page, per_page, total_pages metadata