Skip to content

feat(voting): attendee talk voting via guild.host OAuth#58

Merged
khaosdoctor merged 26 commits into
mainfrom
voting-system
Jul 13, 2026
Merged

feat(voting): attendee talk voting via guild.host OAuth#58
khaosdoctor merged 26 commits into
mainfrom
voting-system

Conversation

@khaosdoctor

Copy link
Copy Markdown
Member

WIP do sistema de votação

…lk cards

Drop Stripe entirely (webhook route, client, STRIPE_* secrets, test) - voting
is guild-only; the attendees API is the sole tier source.

Simplify auth: session cookie is now a jose HS256 JWT (alg-pinned, lib-enforced
exp) instead of hand-rolled HMAC+base64url; cookie parsing deduped into
helpers/cookies.ts. The OAuth flow (helpers/oauth.ts) stays hand-rolled until
the real Log in with Guild flow ships.

Steal from #40: parseRequest() DRYs the 415/413/400/422 gauntlet across the c4p
and vote routes; the /api/vote payload and /vote page now surface duration and
audience_level.
Request profile:read + event_tickets:read + event_attendees:read at authorize
time (matches the registered OAuth app). Rename IDENTITY_SCOPE to OAUTH_SCOPE.
Add .dev.vars.example documenting the worker secrets for local wrangler dev.
…en machinery

Read the voter's tier from their own event_tickets:read token at login and bake
{userId, budget} into the session JWT, instead of fetching the full attendee list
with an organizer token. Removes the userinfo->attendees id-join blocker and unblocks
local testing (no organizer consent needed).

Deletes repositories/oauth-token.ts, repositories/attendees.ts, the oauth_tokens
table, GUILD_ORG_REFRESH_TOKEN, and the event_attendees:read scope. Adds
fetchTicketTier + vote().budgetForTier; getUserId becomes getSession.

Ticket response shape is undocumented; the tier path is a first guess pending one
live login (see TODO.md runbook).
GET /api/vote/logout clears the vote_session cookie (matching Path/SameSite/Secure
attributes so the browser drops it) and redirects back to /vote.
Links to GET /api/vote/logout in the ready state, next to the remaining-votes count.
Read the ?error= param the callback bounces back (denied/state/token/identity/
notattendee), toast a pt-BR message, and strip it from the URL. Guards run inside
useEffect so SSR stays window-free.
…nt branch

The remote voting-system had backed the voting feature out in favor of an account
page; this keeps the voting feature and folds in the still-useful pieces: a /account
page showing the logged-in guild.host user id (GET /api/vote/me, from getSession),
the navbar link, and the i18n strings for all three locales.
khaosdoctor and others added 8 commits July 7, 2026 17:39
closesAt was fetched but never used. Now render the deadline while open, show a
closed notice and disable the checkboxes once past closesAt, and no-op the toggle.
Both pages were hardcoded pt-BR while the site is trilingual. Route all strings
through the shared Text/text helpers, add en-US and es-419 catalog entries, and
format the deadline with the current Docusaurus locale.
Route every user-facing string in the C4P flow through Text/text helpers and add
en-US + es-419 catalog entries (117 keys per locale). definitions.ts options carry a
labelId translation key instead of a literal label (value unchanged), rendered via
Text at each consumer including the vote page. schema.ts zod messages became
translation keys resolved lazily in validateStep to follow the current locale.
Export TranslationId for that cast.
@khaosdoctor khaosdoctor changed the title feat(voting): attendee talk voting via guild.host OAuth (wip) feat(voting): attendee talk voting via guild.host OAuth Jul 11, 2026
@khaosdoctor khaosdoctor marked this pull request as ready for review July 11, 2026 21:59
Copilot AI review requested due to automatic review settings July 11, 2026 21:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements a community talk voting system tied to guild.host OAuth, including a server-side ticket-tier→budget lookup and a D1-backed vote store, plus the corresponding /vote and /account website UIs and i18n work.

Changes:

  • Adds Cloudflare Worker endpoints for guild.host OAuth login/session + vote listing/casting, backed by new D1 tables (ticket_tiers, c4p_votes, manager_oauth).
  • Adds website pages/styles for voting and account UX, plus navbar auth dropdown and login error toast handling.
  • Refactors C4P UI strings + validation messages to use i18n translation keys across locales.

Reviewed changes

Copilot reviewed 46 out of 48 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
TODO.md Deployment checklist + caveats for the voting system rollout.
test/server/routes/vote.test.ts New test coverage for session, budget lookup, and vote route behaviors.
test/server/routes/stripe-webhook.test.ts Removes Stripe webhook tests (feature removed).
src/website/scss/pages/voting.scss Styling for /vote and /account pages.
src/website/scss/pages/partial/_navbar.scss Styles for the new account button + dropdown in the navbar.
src/website/pages/vote/index.tsx Voting UI: fetch session/talks, optimistic vote toggling with debounce, budget/closed state rendering.
src/website/pages/c4p/index.tsx C4P step titles/progress/page title moved to i18n.
src/website/pages/c4p/_components/talk.tsx C4P talk step labels/options moved to i18n; updates aria-labels accordingly.
src/website/pages/c4p/_components/success.tsx Success screen content moved to i18n.
src/website/pages/c4p/_components/introduction.tsx Intro copy + toast strings moved to i18n; topic rendering now uses translation IDs.
src/website/pages/c4p/_components/field-status.tsx Valid/invalid aria-labels moved to i18n.
src/website/pages/c4p/_components/diversity.tsx Diversity step copy/options moved to i18n with interpolated link.
src/website/pages/c4p/_components/about.tsx About step labels/options moved to i18n; updates aria-labels accordingly.
src/website/pages/account/index.tsx New /account page consuming /api/vote/me.
src/website/hooks/c4p/useSubmit.tsx C4P submit toasts moved to i18n.
src/website/contexts/c4p/schema.ts Zod error messages changed to translation keys, resolved via text() at validation time.
src/website/contexts/c4p/index.tsx “required fields” toast moved to i18n.
src/website/contexts/c4p/definitions.ts C4P option/topic labels now reference translation IDs instead of hardcoded strings.
src/website/components/shared/i18n.tsx Exports TranslationId type for reuse.
src/website/components/_partial/Navbar.tsx Adds global login error toast handler + integrates new AuthButton.
src/website/components/_partial/AuthButton.tsx New navbar auth button: login link or account dropdown based on /api/vote/me.
src/server/types.ts Replaces Stripe env requirements with voting/OAuth env fields.
src/server/routes/vote.ts New vote routes (GET talks/votes; POST add/remove vote) with session + budget enforcement.
src/server/routes/stripe-webhook.ts Removes Stripe webhook handler.
src/server/routes/c4p.ts Uses shared parseRequest helper for JSON/content-type/size/schema validation.
src/server/routes/auth.ts New OAuth login/callback/session-cookie flow + /api/vote/me + logout.
src/server/routes.ts Registers new auth/vote routes; removes Stripe webhook route.
src/server/repositories/vote.ts D1 repository for votable talks, user votes, casting/removing votes, tier budget lookup.
src/server/index.ts Adds routing for auth/vote endpoints; enables GET in CORS and credentials when origin is explicit.
src/server/helpers/session.ts New JWT session signing/verification + dev header bypass.
src/server/helpers/request.ts Adds parseRequest helper shared across routes.
src/server/helpers/oauth.ts OAuth helper: build authorize URL, exchange code, fetch userinfo, manager token cache/refresh, attendee tier lookup.
src/server/helpers/cookies.ts Adds cookie reader helper.
src/server/configs/vote.ts Voting window (VOTE_CLOSES_AT) + votable talk status constant.
src/server/configs/stripe.ts Removes Stripe config.
src/server/configs/oauth.ts Adds guild.host OAuth endpoint + cookie + scope constants.
resources/schema.sql Adds tables for tier budgets, votes, and cached manager OAuth tokens.
README.md Mentions community voting as part of repo scope.
package.json Removes Stripe dependency; adds jose.
package-lock.json Lockfile updated for jose and removal of Stripe.
i18n/pt-BR/code.json Adds vote/account/auth + expanded C4P translations (pt-BR).
i18n/es-419/code.json Adds vote/account/auth + expanded C4P translations (es-419).
i18n/en-US/code.json Adds vote/account/auth + expanded C4P translations (en-US).
DEVELOPMENT.md Adds deep-dive documentation on the voting system architecture/ops.
CLAUDE.md Adds repo guidance/documentation (tooling, conventions, voting system overview).
.gitignore Ignores /.serena.
.env.example Clarifies build/deploy vars vs runtime secrets; removes Stripe vars.
.dev.vars.example Adds runtime secret template for guild.host OAuth + session config.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/website/components/_partial/AuthButton.tsx
Comment thread src/server/helpers/request.ts
Comment thread .dev.vars.example
@khaosdoctor khaosdoctor requested a review from Copilot July 12, 2026 00:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 46 out of 48 changed files in this pull request and generated 9 comments.

Comment thread src/server/routes/auth.ts Outdated
Comment thread src/server/routes/auth.ts
Comment thread src/server/helpers/session.ts Outdated
Comment thread test/server/routes/vote.test.ts Outdated
Comment thread TODO.md Outdated
Comment thread src/server/repositories/vote.ts
Comment thread i18n/pt-BR/code.json
Comment thread i18n/es-419/code.json
Comment thread package.json

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 46 out of 48 changed files in this pull request and generated 4 comments.

Comment thread src/website/contexts/c4p/schema.ts
Comment thread src/server/routes/auth.ts
Comment thread src/server/routes/auth.ts Outdated
Comment thread src/server/routes/auth.ts
@khaosdoctor khaosdoctor merged commit 090be0c into main Jul 13, 2026
1 check passed
@khaosdoctor khaosdoctor deleted the voting-system branch July 13, 2026 00:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants