You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2.1 KiB
2.1 KiB
@../CLAUDE.md
CLAUDE.md — pages
pages is a micro static-site host: upload an .html or .zip, get it
served at pages.elijah.run/<slug>/. One Cloudflare Worker (Rust → wasm via
workers-rs + axum), an R2 bucket for content, a D1 database for
users/sessions/page metadata, GitHub OAuth for login.
Design reference (read first): docs/plans/2026-07-12-pages-design.md
Deviations from repo defaults (deliberate, see design doc §3)
- No SQLx — SQLx cannot run on Cloudflare Workers; D1 access uses the
workercrate bindings directly. - No Yew/Trunk frontend — v0 ships a single
static/index.html(inline CSS/JS) embedded in the Worker viainclude_str!. - Worker deploys via
wrangler deploy, not OpenTofu (Terraform provider can't upload module Workers with wasm). OpenTofu owns R2/D1/DNS/rate limits ininfra/.
Validation (run from pages/, in order)
cargo fmt
cargo check --target wasm32-unknown-unknown # worker code is wasm-only
cargo check # native (pure logic modules)
cargo clippy --all-targets -- -D warnings
cargo clippy --target wasm32-unknown-unknown -- -D warnings
cargo test # native unit tests
For infra changes (from pages/infra/): tofu fmt and tofu validate.
wasm / workers-rs notes
- Follow the
../quotesdbpattern for the#[worker::event(fetch)]+ axum glue (quotesdb/src/lib.rsbottom) and forCargo.tomltarget-gated dependencies (getrandomwasm_js, workerhttpfeature, tower-service). - Keep all policy logic (slug/zip/MIME/cookie parsing) in pure modules that
compile natively so
cargo testcovers them; wasm-only code (cfg(target_arch = "wasm32")) should be thin glue. - Workers wasm is single-threaded:
unsafe impl Send/Syncon Arc-wrapped state wrappers is the accepted pattern (as in quotesdb).