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.

66 lines
3.5 KiB
Markdown

# pages — Planning
## Phases
| Phase | Content | Status |
|---|---|---|
| 0 | Security analysis + design (`plans/2026-07-12-pages-design.md`) | done |
| 1 | v0 implementation on branch `pages-v0` (beans below) | done |
| 2 | Deploy + manual QA against real Cloudflare account | deployed; manual QA (login/upload/delete) pending |
| 3 | v1 candidates: per-page subdomains, page overwrite, Yew UI, OpenAPI | not started |
## v0 tickets (beans, serial)
1. scaffold — crate skeleton, wrangler.toml, hello-world worker builds
2. core — slug/mime/upload/header policy modules + unit tests
3. db — D1 schema + query layer
4. auth — GitHub OAuth, sessions, auth middleware
5. api — pages + users JSON API
6. serve — page content serving from R2
7. frontend — embedded management UI
8. infra — OpenTofu + deployment docs
## Work log
- **2026-07-12** — Project initialized. Security analysis and v0 design
written; beans created; implementation pipeline started (Sonnet
implementation agents, Opus review agents, one commit per ticket).
- **2026-07-13** — infra ticket (pages-ihlp) done: `infra/*.tf` (R2 bucket,
D1 database, DNS placeholder record, rate limiting ruleset) mirroring
`../quotesdb/infra` style, `infra/README.md` deployment guide, `tofu fmt`
+ `tofu validate` passing.
- **2026-07-13** — v0 implementation complete: all 8 beans done on
`pages-v0`, one reviewed commit per ticket (Sonnet implementation, Opus
review). 142 unit tests + 17 doctests; both-target clippy clean. Next:
phase 2 (real deploy + manual QA per `infra/README.md`).
- **2026-07-13** — Deployed. tofu applied R2 + D1 + DNS (rate-limit ruleset
deliberately NOT applied — quotesdb's live http_ratelimit ruleset owns
the zone's single slot; merge required if wanted). Remote schema applied;
GITHUB_CLIENT_SECRET secret set; route pages.elijah.run/* live. Smoke
tests pass (/, /api/me, /auth/login 302, reserved + unknown slugs 404
with sandbox CSP). Pending manual QA: GitHub login as admin, upload,
view, delete.
- **2026-07-13** — pages-shqc: per-page/per-user "trusted" escape hatch from
the CSP sandbox (`pages.trusted OR owner's users.trusted`, computed at
serve time). `migrations/0002-trust.sql` added for the live DB (not yet
applied remotely — manual step); schema.sql, db.rs, api.rs, serve.rs,
core/headers.rs, and the admin UI all updated; 148 unit + 18 doctests,
both-target clippy clean.
- **2026-07-14** — pages-ytau: in-place page updates, retiring the design's
"no page overwrite: delete + re-upload" scope cut. New `PUT
/api/pages/:slug` (design §4.6b) replaces a page's content — owner-or-admin
*and* `can_upload`, new objects written before stale keys are pruned, D1
stats refreshed while `owner_id`/`trusted`/`created_at` are preserved. No
schema change. The UI's always-visible upload card became a modal driven by
a "+ New Page" button and a per-row "Update" button (slug pre-filled,
read-only). 152 unit + 19 doctests, both-target clippy clean. Verified end
to end against `wrangler dev` with local D1/R2 (create → serve → replace →
stale assets 404 → stats/trust/ownership preserved; 401/403/404/400/413
paths) and the UI driven in jsdom (37 assertions).
Local-dev gotcha found while verifying: `wrangler dev` rewrites the request
`Origin` to the `[[routes]]` host (`pages.elijah.run`), so a local
`BASE_URL=http://localhost:8787` makes every mutating route 403 on the
Origin check. Set `BASE_URL=http://pages.elijah.run` in `.dev.vars` when
exercising the API locally.