# bis0908/gender-reveal architecture

> Architecture diagram of the GitHub repository bis0908/gender-reveal, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-03). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/bis0908/gender-reveal
- Repository: https://github.com/bis0908/gender-reveal

## Overview

#### Purpose and Runtime
A Next.js 15 App Router application for creating and sharing personalized online gender-reveal events. TypeScript, Tailwind/shadcn UI, and Framer Motion power the browser experience; Vercel is the intended deployment target. The root shell and public landing entry are `app/layout.tsx` and `app/page.tsx`.

#### Reveal Creation and Token Boundary
The creation flow gathers parent, baby, schedule, D-day, and animation choices, then produces a shareable signed token rather than exposing event data directly. Primary UI orchestration is in `components/reveal-form/reveal-form.tsx`, with token issuance at `app/api/generate-token/route.ts` and verification at `app/api/verify-token/route.ts`. JWT configuration and server-only environment access are centralized in `lib/config.ts` and `lib/env.server.ts`; `JWT_SECRET` is the core trust boundary.

#### Shared Countdown and Reveal Experience
Recipients open `/countdown/[token]`, where token-derived event state drives a live countdown, voting/waiting states, and redirect to the reveal. The route is composed in `app/countdown/[token]/page.tsx`, with timed client behavior in `app/countdown/[token]/components/CountdownTimer.tsx`. The final reveal route is `app/reveal/page.tsx`, which renders staged loading, intro, animation, and result views through `app/reveal/components/RevealAnimation.tsx` and `app/reveal/components/RevealResults.tsx`.

#### Animation Rendering
Animation choice is a data-to-component dispatch boundary: event configuration selects an implementation, while the renderer isolates the presentation contract. `components/animation-renderer.tsx` and `components/animation-selection.tsx` connect form selection to animations such as `components/animations/reveal-animation.tsx`, `components/animations/balloonpop-animation.tsx`, and `components/animations/fireworks-animation.tsx`. This keeps visual variants separate from token, D-day, and voting logic.

#### D-Day Coordination and Voting
D-day events use server API routes to create event records, expose reveal-safe data, and accept votes: `app/api/dday/create/route.ts`, `app/api/dday/reveal-data/route.ts`, and `app/api/dday/vote/route.ts`. Input contracts live in `lib/schemas/dday-schema.ts`; timing and event transformations are in `lib/dday-utils.ts`. Client vote state is handled by `hooks/useVoteStatus.ts`, with cookie/device-style protections implied by the API boundary.

#### Persistence, Limits, and Integrations
Supabase is the durable analytics/database layer, represented by server/client adapters in `lib/supabase/server.ts` and `lib/supabase/client.ts`, plus migration `supabase/migrations/20260721233853_reveal_generation_metrics.sql`. Redis/Upstash is used for rate limiting via `lib/redis.ts` and `lib/services/generation-rate-limit.ts`. Generation metrics flow through `lib/services/generation-metrics.ts`; feedback enters through `app/api/feedback/route.ts` and may integrate with Google Sheets and email through `lib/services/google-sheets.ts` and `lib/services/email.ts`.

#### Administrative Observability and Access Control
Admin login, protected metrics pages, and an API reporting surface form the operational subsystem. Entrypoints are `app/admin/login/page.tsx`, `app/admin/metrics/page.tsx`, and `app/api/admin/metrics/route.ts`. Authorization is enforced through `lib/auth/require-admin.ts`, while metrics aggregation is owned by `lib/services/admin-metrics.ts`. Middleware-level Supabase session handling is implemented in `middleware.ts` and `lib/supabase/middleware.ts`.

#### Cross-Cutting UI and Localization
Shared navigation, theme, feedback, and locale support are anchored in `components/header.tsx`, `components/theme-provider.tsx`, and `lib/i18n/context.tsx`. Localized copy is bundled under `lib/i18n/locales/en.json`, `lib/i18n/locales/jp.json`, and `lib/i18n/locales/ko.json`. Changelog content is filesystem-backed Markdown, surfaced through `app/changelog/page.tsx` and parsed by `lib/markdown.ts`.

Main entry points: [`app/api/generate-token/route.ts`](https://github.com/bis0908/gender-reveal/blob/master/app/api/generate-token/route.ts) (Token APIs), [`components/reveal-form/reveal-form.tsx`](https://github.com/bis0908/gender-reveal/blob/master/components/reveal-form/reveal-form.tsx) (Reveal form), [`app/api/dday/create/route.ts`](https://github.com/bis0908/gender-reveal/blob/master/app/api/dday/create/route.ts) (D-Day APIs), [`lib/supabase/server.ts`](https://github.com/bis0908/gender-reveal/blob/master/lib/supabase/server.ts) (Supabase)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_public["Public Experience"]
  node_shell["App shell &amp; landing<br/>Next.js entry<br/>[layout.tsx]"]
  node_reveal_form["Reveal form<br/>client orchestration<br/>[reveal-form.tsx]"]
  node_animation_selection["Animation selection<br/>UI selector"]
end

subgraph group_token["Token &amp; Reveal"]
  node_token_api{{"Token APIs<br/>Next.js API routes<br/>[route.ts]"}}
  node_jwt_config{{"JWT trust boundary<br/>server config<br/>[config.ts]"}}
  node_countdown_route["Shared countdown<br/>dynamic route<br/>[page.tsx]"]
  node_countdown_timer["Countdown timer<br/>client behavior<br/>[CountdownTimer.tsx]"]
  node_reveal_route["Final reveal<br/>page route<br/>[page.tsx]"]
  node_reveal_renderer["Animation renderer<br/>presentation dispatch"]
  node_animation_variants["Reveal animation variants<br/>visual components"]
end

subgraph group_dday["D-Day Events"]
  node_dday_api{{"D-Day APIs<br/>Next.js API routes<br/>[route.ts]"}}
  node_dday_domain["D-Day contracts &amp; timing<br/>domain logic<br/>[dday-schema.ts]"]
  node_vote_state["Vote client state<br/>client hook<br/>[useVoteStatus.ts]"]
end

subgraph group_platform["Data &amp; Integrations"]
  node_supabase[("Supabase<br/>database &amp; analytics<br/>[server.ts]")]
  node_rate_limit["Generation rate limit<br/>Redis service"]
  node_generation_metrics["Generation metrics<br/>metrics service"]
  node_feedback_api{{"Feedback API<br/>Next.js API route<br/>[route.ts]"}}
end

subgraph group_admin["Administration"]
  node_admin_pages["Admin login &amp; metrics<br/>protected pages<br/>[page.tsx]"]
  node_admin_metrics_api{{"Admin metrics API<br/>reporting route<br/>[route.ts]"}}
  node_admin_auth{{"Admin authorization<br/>access control<br/>[require-admin.ts]"}}
  node_admin_metrics["Metrics aggregation<br/>admin service<br/>[admin-metrics.ts]"]
  node_session_middleware["Supabase session middleware<br/>request middleware<br/>[middleware.ts]"]
end

node_shell -->|"hosts"| node_reveal_form
node_reveal_form -->|"chooses"| node_animation_selection
node_reveal_form -->|"generates share token"| node_token_api
node_token_api -->|"signs/verifies with"| node_jwt_config
node_token_api -->|"checks generation limit"| node_rate_limit
node_token_api -->|"records generation"| node_generation_metrics
node_generation_metrics -->|"persists"| node_supabase
node_countdown_route -->|"verifies token"| node_token_api
node_countdown_route -->|"drives"| node_countdown_timer
node_countdown_route -->|"redirects when ready"| node_reveal_route
node_reveal_route -->|"renders"| node_reveal_renderer
node_reveal_renderer -->|"dispatches"| node_animation_variants
node_animation_selection -.->|"selects variant"| node_reveal_renderer
node_reveal_form -->|"creates D-Day event"| node_dday_api
node_dday_api -->|"validates &amp; transforms"| node_dday_domain
node_dday_api -->|"stores event and votes"| node_supabase
node_vote_state -->|"submits and refreshes votes"| node_dday_api
node_feedback_api -->|"records feedback"| node_supabase
node_admin_pages -->|"requests reports"| node_admin_metrics_api
node_admin_metrics_api -->|"requires"| node_admin_auth
node_admin_metrics_api -->|"aggregates"| node_admin_metrics
node_admin_metrics -->|"reads analytics"| node_supabase
node_session_middleware -->|"maintains session"| node_admin_pages

click node_shell "https://github.com/bis0908/gender-reveal/blob/master/app/layout.tsx"
click node_reveal_form "https://github.com/bis0908/gender-reveal/blob/master/components/reveal-form/reveal-form.tsx"
click node_animation_selection "https://github.com/bis0908/gender-reveal/blob/master/components/animation-selection.tsx"
click node_token_api "https://github.com/bis0908/gender-reveal/blob/master/app/api/generate-token/route.ts"
click node_jwt_config "https://github.com/bis0908/gender-reveal/blob/master/lib/config.ts"
click node_countdown_route "https://github.com/bis0908/gender-reveal/blob/master/app/countdown/%5Btoken%5D/page.tsx"
click node_countdown_timer "https://github.com/bis0908/gender-reveal/blob/master/app/countdown/%5Btoken%5D/components/CountdownTimer.tsx"
click node_reveal_route "https://github.com/bis0908/gender-reveal/blob/master/app/reveal/page.tsx"
click node_reveal_renderer "https://github.com/bis0908/gender-reveal/blob/master/components/animation-renderer.tsx"
click node_animation_variants "https://github.com/bis0908/gender-reveal/blob/master/components/animations/reveal-animation.tsx"
click node_dday_api "https://github.com/bis0908/gender-reveal/blob/master/app/api/dday/create/route.ts"
click node_dday_domain "https://github.com/bis0908/gender-reveal/blob/master/lib/schemas/dday-schema.ts"
click node_vote_state "https://github.com/bis0908/gender-reveal/blob/master/hooks/useVoteStatus.ts"
click node_supabase "https://github.com/bis0908/gender-reveal/blob/master/lib/supabase/server.ts"
click node_rate_limit "https://github.com/bis0908/gender-reveal/blob/master/lib/services/generation-rate-limit.ts"
click node_generation_metrics "https://github.com/bis0908/gender-reveal/blob/master/lib/services/generation-metrics.ts"
click node_feedback_api "https://github.com/bis0908/gender-reveal/blob/master/app/api/feedback/route.ts"
click node_admin_pages "https://github.com/bis0908/gender-reveal/blob/master/app/admin/metrics/page.tsx"
click node_admin_metrics_api "https://github.com/bis0908/gender-reveal/blob/master/app/api/admin/metrics/route.ts"
click node_admin_auth "https://github.com/bis0908/gender-reveal/blob/master/lib/auth/require-admin.ts"
click node_admin_metrics "https://github.com/bis0908/gender-reveal/blob/master/lib/services/admin-metrics.ts"
click node_session_middleware "https://github.com/bis0908/gender-reveal/blob/master/middleware.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_shell,node_reveal_form,node_animation_selection toneBlue
class node_token_api,node_jwt_config,node_countdown_route,node_countdown_timer,node_reveal_route,node_reveal_renderer,node_animation_variants toneAmber
class node_dday_api,node_dday_domain,node_vote_state toneMint
class node_supabase,node_rate_limit,node_generation_metrics,node_feedback_api toneRose
class node_admin_pages,node_admin_metrics_api,node_admin_auth,node_admin_metrics,node_session_middleware toneIndigo
```

## Components

### Public Experience

- [App shell & landing](https://github.com/bis0908/gender-reveal/blob/master/app/layout.tsx): Next.js entry · `app/layout.tsx`
- [Reveal form](https://github.com/bis0908/gender-reveal/blob/master/components/reveal-form/reveal-form.tsx): client orchestration · `components/reveal-form/reveal-form.tsx`
- [Animation selection](https://github.com/bis0908/gender-reveal/blob/master/components/animation-selection.tsx): UI selector · `components/animation-selection.tsx`

### Token & Reveal

- [Token APIs](https://github.com/bis0908/gender-reveal/blob/master/app/api/generate-token/route.ts): Next.js API routes · Issues and verifies signed share tokens. · `app/api/generate-token/route.ts`
- [JWT trust boundary](https://github.com/bis0908/gender-reveal/blob/master/lib/config.ts): server config · Server-only secret configuration for token signing. · `lib/config.ts`
- [Shared countdown](https://github.com/bis0908/gender-reveal/blob/master/app/countdown/%5Btoken%5D/page.tsx): dynamic route · `app/countdown/[token]/page.tsx`
- [Countdown timer](https://github.com/bis0908/gender-reveal/blob/master/app/countdown/%5Btoken%5D/components/CountdownTimer.tsx): client behavior · `app/countdown/[token]/components/CountdownTimer.tsx`
- [Final reveal](https://github.com/bis0908/gender-reveal/blob/master/app/reveal/page.tsx): page route · `app/reveal/page.tsx`
- [Animation renderer](https://github.com/bis0908/gender-reveal/blob/master/components/animation-renderer.tsx): presentation dispatch · Maps event animation choices to isolated visual variants. · `components/animation-renderer.tsx`
- [Reveal animation variants](https://github.com/bis0908/gender-reveal/blob/master/components/animations/reveal-animation.tsx): visual components · `components/animations/reveal-animation.tsx`

### D-Day Events

- [D-Day APIs](https://github.com/bis0908/gender-reveal/blob/master/app/api/dday/create/route.ts): Next.js API routes · Creates events, serves reveal-safe data, and accepts votes. · `app/api/dday/create/route.ts`
- [D-Day contracts & timing](https://github.com/bis0908/gender-reveal/blob/master/lib/schemas/dday-schema.ts): domain logic · `lib/schemas/dday-schema.ts`
- [Vote client state](https://github.com/bis0908/gender-reveal/blob/master/hooks/useVoteStatus.ts): client hook · `hooks/useVoteStatus.ts`

### Data & Integrations

- [Supabase](https://github.com/bis0908/gender-reveal/blob/master/lib/supabase/server.ts): database & analytics · Durable event and generation analytics storage. · `lib/supabase/server.ts`
- [Generation rate limit](https://github.com/bis0908/gender-reveal/blob/master/lib/services/generation-rate-limit.ts): Redis service · `lib/services/generation-rate-limit.ts`
- [Generation metrics](https://github.com/bis0908/gender-reveal/blob/master/lib/services/generation-metrics.ts): metrics service · `lib/services/generation-metrics.ts`
- [Feedback API](https://github.com/bis0908/gender-reveal/blob/master/app/api/feedback/route.ts): Next.js API route · May forward feedback to Sheets and email integrations. · `app/api/feedback/route.ts`

### Administration

- [Admin login & metrics](https://github.com/bis0908/gender-reveal/blob/master/app/admin/metrics/page.tsx): protected pages · `app/admin/metrics/page.tsx`
- [Admin metrics API](https://github.com/bis0908/gender-reveal/blob/master/app/api/admin/metrics/route.ts): reporting route · `app/api/admin/metrics/route.ts`
- [Admin authorization](https://github.com/bis0908/gender-reveal/blob/master/lib/auth/require-admin.ts): access control · `lib/auth/require-admin.ts`
- [Metrics aggregation](https://github.com/bis0908/gender-reveal/blob/master/lib/services/admin-metrics.ts): admin service · `lib/services/admin-metrics.ts`
- [Supabase session middleware](https://github.com/bis0908/gender-reveal/blob/master/middleware.ts): request middleware · `middleware.ts`

## Connections

- App shell & landing → Reveal form: hosts
- Reveal form → Animation selection: chooses
- Reveal form → Token APIs: generates share token
- Token APIs → JWT trust boundary: signs/verifies with
- Token APIs → Generation rate limit: checks generation limit
- Token APIs → Generation metrics: records generation
- Generation metrics → Supabase: persists
- Shared countdown → Token APIs: verifies token
- Shared countdown → Countdown timer: drives
- Shared countdown → Final reveal: redirects when ready
- Final reveal → Animation renderer: renders
- Animation renderer → Reveal animation variants: dispatches
- Animation selection → Animation renderer: selects variant
- Reveal form → D-Day APIs: creates D-Day event
- D-Day APIs → D-Day contracts & timing: validates & transforms
- D-Day APIs → Supabase: stores event and votes
- Vote client state → D-Day APIs: submits and refreshes votes
- Feedback API → Supabase: records feedback
- Admin login & metrics → Admin metrics API: requests reports
- Admin metrics API → Admin authorization: requires
- Admin metrics API → Metrics aggregation: aggregates
- Metrics aggregation → Supabase: reads analytics
- Supabase session middleware → Admin login & metrics: maintains session
