Document responses carried no CSP, X-Frame-Options, Referrer-Policy, or
Permissions-Policy — leaving clickjacking and zero script-injection defense
in depth (security audit T4).
- svelte.config.js: enable kit.csp hash mode. SvelteKit hashes its own inline
hydration scripts; the inline theme <script> in app.html isn't part of
%sveltekit.head%, so its sha256 is pinned by hand (csp-config.js) and added
to script-src alongside object-src 'none', base-uri 'self', frame-ancestors
'none'. Styles stay unconstrained (Svelte emits dynamic inline style= attrs).
- hooks.server.ts: applySecurityHeaders() sets X-Frame-Options: DENY,
Referrer-Policy: strict-origin-when-cross-origin, X-Content-Type-Options:
nosniff, and a Permissions-Policy locking down unused features, only when the
response hasn't already set them.
- src/csp-theme-hash.test.ts: drift guard against editing the theme script
without updating THEME_SCRIPT_HASH.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Set up Mangalord with a Rust/axum backend, SvelteKit frontend, Postgres,
and Docker Compose deployment. Establishes the architecture and TDD
patterns the project will extend:
- Hexagonal-ish backend layering (domain / repo / storage / api) with
a pluggable Storage trait (LocalStorage today, S3 as a future impl).
- Initial migration: users, mangas, chapters, bookmarks.
- Vertical slice for mangas (list, search, create, get) with
#[sqlx::test] integration coverage and storage unit tests.
- SvelteKit frontend using Svelte 5 runes, typed API client, Vitest
unit tests and Playwright e2e with route mocking.
- CLAUDE.md documenting layering, TDD/git/SemVer workflow rules, and
extension points (tags, fulltext search, OCR, S3, auth).
- Project-scoped .claude/settings.json with permission allowlist for
the toolchain (git, cargo, npm/vite, docker, psql, gh, doc fetches).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>