Guidance for Claude when working in this repo (JSConf Brasil landing page).
Three pieces, one repo:
- Website — Docusaurus 3 + React 19, static, deployed to GitHub Pages (
jsconf.com.br). Source insrc/website/. File-based routes undersrc/website/pages/. i18n ini18n/(pt-BR default, en-US, es-419) via Docusaurus<Translate>/code.json. - Server — a single Cloudflare Worker (
src/server/index.ts), custom domainapi.jsconf.com.br. No framework: afetchhandler with a manualswitchrouter. Helpers, routes, repositories, configs split undersrc/server/. - Database — Cloudflare D1 (SQLite), bound as
DB. Schema inresources/schema.sql(idempotentCREATE TABLE IF NOT EXISTS). Apply withnpm run db:init(local) /db:init:remote.
Deploy: push to main → .github/workflows/cd_deploy.yml builds both, deploys the worker
via wrangler and the site to the website branch.
npm start # site (pt-BR) + worker via wrangler dev, concurrently
npm run server # worker only (wrangler dev)
npm run db:init # apply resources/schema.sql to local D1
npm test # poku (-r=compact)
npm run typecheck # tsc
npm run lint # prettier --check (lint:fix to write)
npm run build # worker + docusaurus
npm run images # regenerate the responsive image variants (commit the output)Run npm ci first if node_modules is missing (typecheck/test need deps).
Images: every photo the shared Image wrapper renders ships as a srcset ladder
(200/400/800 + the file's own width, WebP). The variants are generated by
tools/generate-image-variants.ts and committed — no build hook — so run
npm run images after adding or replacing anything under the paths listed at the top
of that script. src/website/configs/images.ts holds the naming/width rules that the
script and the wrapper both read; changing one without the other means 404s.
- Style: no
else(early-return + guard clauses), avoidlet, preferfor..ofover.forEach, keep it simple over clever. TS:switchdefaultx satisfies never,Record<Enum, T>. - Server shape: routes in
src/server/routes/, registered inroutes.ts+ theindex.tsswitch (METHOD /path). DB access inrepositories/, validated withzod. Responses viahelpers/response.ts. Reuse the existing helpers (request.ts,session.ts, etc.). - Validation is the trust boundary server-side; the frontend schemas are UX only.
- Tests:
poku, files*.test.tsundertest/mirroringsrc/. Mock D1 with a plain object implementingprepare().bind().run()/all()(seetest/server/routes/c4p/__utils__.tsandtest/server/routes/vote.test.ts). - Secrets:
wrangler secret put(seenpm run secret); never commit them..env.examplelists what exists.
- Conventional commits, single
-m, no Claude attribution. Never push tomain— branch first. No gitmoji. githere needs a clean env to avoid shell-hook hangs:env -i HOME=$HOME PATH=/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin /usr/bin/git --no-pager …
The voting-system branch adds attendee voting on C4P talks (guild.host OAuth identity,
manager-token-based ticket-tier lookup, D1-backed vote casting with budget limits) and is
built and verified end-to-end against a real guild.host login. See DEVELOPMENT.md for the
technical deep-dive (architecture, OAuth flow, DB schema) and TODO.md for the remaining
deploy steps and known caveats.
Auto-generated by headroom learn on 2026-06-26 — do not edit manually
~1,500 tokens/session saved
- Server session/JWT uses
jose(^6.x). Thecookiepackage was tried and removed — it is NOT a dependency; don't re-add it. - To check an installed package version,
grep -E '"version"' node_modules/<pkg>/package.json. Do NOT usenode -e "require('<pkg>/package.json')"— packages likejosedefineexportsand throwERR_PACKAGE_PATH_NOT_EXPORTED.