-
Notifications
You must be signed in to change notification settings - Fork 0
feat(voting): attendee talk voting via guild.host OAuth #58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
1827b38
feat(voting): attendee talk voting via guild.host OAuth (wip)
khaosdoctor c08efbe
docs(voting): votable status filter, handover + todo notes (wip)
khaosdoctor 61245f9
docs: add CLAUDE.md
khaosdoctor 44f7b9b
docs(voting): guild login pending + group-ticket resolved (wip)
khaosdoctor 410c9fc
refactor(voting): guild-only, jose sessions, parseRequest + richer ta…
khaosdoctor 52a5e23
feat(voting): wire guild OAuth app scopes + dev.vars template
khaosdoctor a0fc1df
docs(voting): record /ticket refactor plan + live-login verification …
khaosdoctor 452a17f
refactor(voting): budget from per-user /ticket endpoint, drop org-tok…
khaosdoctor 87116a8
feat(voting): add logout endpoint
khaosdoctor 4c70374
feat(voting): add Sair (logout) button to the vote page
khaosdoctor 92f1afa
feat(voting): surface OAuth login errors on the vote page
khaosdoctor 84524d1
feat(account): add account page + /api/vote/me, salvaged from diverge…
khaosdoctor 1a3c5ad
chore: salvage .serena gitignore + headroom notes from divergent branch
khaosdoctor 7184981
feat(voting): handle closed voting + show deadline on the vote page
khaosdoctor 0cbb1a5
i18n(voting): translate the vote and account pages
khaosdoctor 27bf16e
i18n(c4p): translate the entire C4P page tree
khaosdoctor 0dd3774
docs(env): split .env deploy vars from .dev.vars runtime secrets
khaosdoctor 736cac8
feat: voting system
khaosdoctor 0e35939
chore(server): drop ponytail comment markers, remove leftover debug l…
khaosdoctor 2647620
docs(voting): rewrite technical docs with diagrams, remove stale HAND…
khaosdoctor 5cbabba
docs: instructions
khaosdoctor 17248e8
Merge remote-tracking branch 'origin/main' into voting-system
khaosdoctor e792138
fix(voting): reject only unparseable JSON and guard missing worker do…
khaosdoctor b9dd426
fix(voting): fail-closed dev gates, atomic budget check, translate lo…
khaosdoctor bf39af6
chore(deps): drop unused stripe dependency
khaosdoctor c54c730
fix(voting): harden manager-capture response, match cookie-clear attr…
khaosdoctor File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # Copy to `.dev.vars` (gitignored) for `wrangler dev`. Never commit real secrets. | ||
| # These are the Worker secrets the voting flow reads at runtime. | ||
|
|
||
| # guild.host OAuth app (https://guild.host/oauth/authorize) | ||
| GUILD_OAUTH_CLIENT_ID= | ||
| GUILD_OAUTH_CLIENT_SECRET= | ||
| # Must exactly match a redirect URI registered on the OAuth app. | ||
| # Local: http://localhost:8787/api/vote/callback Prod: https://api.jsconf.com.br/api/vote/callback | ||
| GUILD_OAUTH_REDIRECT_URI=http://localhost:8787/api/vote/callback | ||
|
|
||
| # HMAC/JWT session signing key. Any long random string, e.g. `openssl rand -hex 32`. | ||
| SESSION_SECRET= | ||
|
|
||
| # Website origin for credentialed CORS. Must be explicit, never '*'. | ||
| # Local: http://localhost:3000 Prod: https://jsconf.com.br | ||
| ALLOWED_ORIGIN=http://localhost:3000 | ||
|
|
||
| # 'production' disables the X-Dev-User bypass and the dev session shortcut. | ||
| ENVIRONMENT=development | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,6 @@ | ||
| # Build / deploy vars (read by tools/prepare-worker.mts and the CD workflow). | ||
| # Worker runtime secrets (guild.host OAuth, session, ALLOWED_ORIGIN) live in .dev.vars, not here. | ||
| CLOUDFLARE_ACCOUNT_ID='' | ||
| CLOUDFLARE_API_TOKEN='' | ||
| WORKER_D1='' | ||
| WORKER_DOMAIN='' | ||
| ALLOWED_ORIGIN='' | ||
| STRIPE_SECRET_KEY='' | ||
| STRIPE_WEBHOOK_SECRET='' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,3 +9,4 @@ | |
| .env | ||
| .dev.vars | ||
| .npmrc | ||
| /.serena | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| # CLAUDE.md | ||
|
|
||
| Guidance for Claude when working in this repo (JSConf Brasil landing page). | ||
|
|
||
| ## What this is | ||
|
|
||
| Three pieces, one repo: | ||
|
|
||
| - **Website** — Docusaurus 3 + React 19, static, deployed to GitHub Pages (`jsconf.com.br`). | ||
| Source in `src/website/`. File-based routes under `src/website/pages/`. i18n in `i18n/` | ||
| (pt-BR default, en-US, es-419) via Docusaurus `<Translate>` / `code.json`. | ||
| - **Server** — a single Cloudflare Worker (`src/server/index.ts`), custom domain | ||
| `api.jsconf.com.br`. No framework: a `fetch` handler with a manual `switch` router. Helpers, | ||
| routes, repositories, configs split under `src/server/`. | ||
| - **Database** — Cloudflare D1 (SQLite), bound as `DB`. Schema in `resources/schema.sql` | ||
| (idempotent `CREATE TABLE IF NOT EXISTS`). Apply with `npm 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. | ||
|
|
||
| ## Commands | ||
|
|
||
| ```sh | ||
| 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 | ||
| ``` | ||
|
|
||
| Run `npm ci` first if `node_modules` is missing (typecheck/test need deps). | ||
|
|
||
| ## Conventions | ||
|
|
||
| - **Style:** no `else` (early-return + guard clauses), avoid `let`, prefer `for..of` over | ||
| `.forEach`, keep it simple over clever. TS: `switch` default `x satisfies never`, | ||
| `Record<Enum, T>`. | ||
| - **Server shape:** routes in `src/server/routes/`, registered in `routes.ts` + the `index.ts` | ||
| switch (`METHOD /path`). DB access in `repositories/`, validated with `zod`. Responses via | ||
| `helpers/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.ts` under `test/` mirroring `src/`. Mock D1 with a plain | ||
| object implementing `prepare().bind().run()/all()` (see `test/server/routes/c4p/__utils__.ts` | ||
| and `test/server/routes/vote.test.ts`). | ||
| - **Secrets:** `wrangler secret put` (see `npm run secret`); never commit them. `.env.example` | ||
| lists what exists. | ||
|
|
||
| ## Git / PRs | ||
|
|
||
| - Conventional commits, single `-m`, no Claude attribution. Never push to `main` — branch | ||
| first. No gitmoji. | ||
| - `git` here 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 …` | ||
|
|
||
| ## In-flight work | ||
|
|
||
| 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. | ||
|
|
||
| <!-- headroom:learn:start --> | ||
|
|
||
| ## Headroom Learned Patterns | ||
|
|
||
| _Auto-generated by `headroom learn` on 2026-06-26 — do not edit manually_ | ||
|
|
||
| ### Dependencies | ||
|
|
||
| _~1,500 tokens/session saved_ | ||
|
|
||
| - Server session/JWT uses `jose` (^6.x). The `cookie` package 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 use `node -e "require('<pkg>/package.json')"` — packages like `jose` define `exports` and throw `ERR_PACKAGE_PATH_NOT_EXPORTED`. | ||
|
|
||
| <!-- headroom:learn:end --> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.