A single-author TypeScript SvelteKit blog running on Cloudflare Workers.
See AGENTS.md for setup, development, testing, review, and release instructions, and ADR 0001 for the approved architecture.
Published posts are available at / and /posts/[slug], with server-rendered CommonMark/GFM content and sanitized HTML. Draft, archived, and trashed posts are private. Public pages and image responses are not cached.
Sign in through the environment's Cloudflare Access application at /admin. Access is restricted to the configured GitHub author identity and is verified again by the application.
- Manage flat categories at
/admin/categories. Names are trimmed, unique, and limited to 20 characters; referenced categories cannot be deleted, including references from trash. - Create and edit posts at
/admin/posts. Crepe and unsaved-change guards run in the browser on editor routes; native Markdown forms remain usable without JavaScript. Saves are explicit, and validation or concurrent-edit failures retain input. Unsaved navigation uses native confirmation, and reload/tab close uses the browser's warning. - Publish a complete post with a title, Markdown body, category, and directly entered lowercase slug. Slugs are reserved across all states and cannot change after first publication. Tags are optional, with up to 20 per post and 40 characters per name.
- Archive a published post to hide it, or republish an archived post. Trash is read-only; restoring clears trash without publishing. The original publication date is retained.
- Use the rich editor to upload JPEG, PNG, GIF, or WebP images up to 10 MiB each. Uploads remain private until a successful save references them in an undeleted published post. Public access ends when no such post references the image. Uploading does not autosave or create a hidden draft.
Content metadata and saved relations use D1; images use private R2. Preview and production have separate storage and Access applications. SQL is generated by Drizzle and applied by Wrangler during deployment. See ADR 0004 for the domain rules and publication boundary.
Permanent post deletion, automatic abandoned-upload cleanup, and scheduled publication are not included.