# johnyrex/gcr-election-portal architecture

> Architecture diagram of the GitHub repository johnyrex/gcr-election-portal, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/johnyrex/gcr-election-portal
- Repository: https://github.com/johnyrex/gcr-election-portal

## Overview

This is a Next.js election-information and voting application. Visitors browse election information, candidate profiles, announcements and published results; eligible voters enter the voting flow, verify, review a ballot and submit it. Administrators manage candidates and voters, import voter data, and view election dashboards. The service layer centralizes election API requests, while the API route implements the server endpoint. The available excerpts establish some page composition and client-to-service/API calls, but do not show the API route’s backend persistence or all admin routing, so those relationships are not inferred.

Main entry points: [`services/electionService.ts`](https://github.com/johnyrex/gcr-election-portal/blob/main/services/electionService.ts) (Election service), [`features/voting/VotingFlow.tsx`](https://github.com/johnyrex/gcr-election-portal/blob/main/features/voting/VotingFlow.tsx) (Voting flow), [`features/admin/candidates/CandidateManager.tsx`](https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/candidates/CandidateManager.tsx) (Candidate management), [`app/page.tsx`](https://github.com/johnyrex/gcr-election-portal/blob/main/app/page.tsx) (Home overview)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_public["Public election experience"]
  node_home["Home overview<br/>[page.tsx]"]
  node_home_features["Home features"]
  node_candidate_browse["Candidate browsing<br/>[CandidateGrid.tsx]"]
  node_candidate_profiles["Candidate profiles<br/>[page.tsx]"]
  node_announcements["Announcements<br/>[page.tsx]"]
  node_election_info["Election information<br/>[page.tsx]"]
  node_constitution["Constitution<br/>[page.tsx]"]
  node_results_page["Published results"]
end

subgraph group_vote["Voting workflow"]
  node_voting_page["Voting entry<br/>[page.tsx]"]
  node_voting_flow["Voting flow<br/>[VotingFlow.tsx]"]
  node_verification["Voter verification"]
  node_ballot["Ballot and submission<br/>[Ballot.tsx]"]
  node_confirmation["Vote confirmation<br/>[Confirmation.tsx]"]
end

subgraph group_admin["Election administration"]
  node_admin_login["Admin login<br/>[AdminLogin.tsx]"]
  node_admin_dashboard["Admin dashboard<br/>[AdminDashboard.tsx]"]
  node_candidate_admin["Candidate management"]
  node_candidate_editor["Candidate editor<br/>[CandidateModal.tsx]"]
  node_candidate_table["Candidate table<br/>[CandidateTable.tsx]"]
  node_voter_admin["Voter management<br/>[VotersManager.tsx]"]
  node_csv_import["CSV voter import"]
  node_analytics["Election analytics"]
end

subgraph group_runtime["Election API and UI foundations"]
  node_service["Election service<br/>[electionService.ts]"]
  node_api["Election API route<br/>[route.ts]"]
  node_election_config["Election configuration<br/>[config.ts]"]
  node_candidate_data["Candidate content<br/>[candidates.ts]"]
  node_ui_primitives["Shared UI primitives"]
end

node_visitor(("Visitor"))
node_voter(("Eligible voter"))
node_admin_user(("Administrator"))

node_visitor -->|"opens"| node_home
node_home -->|"renders"| node_home_features
node_visitor -->|"browses"| node_candidate_browse
node_candidate_browse -->|"reads"| node_candidate_data
node_home_features -->|"previews"| node_candidate_data
node_candidate_profiles -->|"reads"| node_candidate_data
node_visitor -->|"opens"| node_announcements
node_visitor -->|"opens"| node_election_info
node_visitor -->|"opens"| node_constitution
node_visitor -->|"views"| node_results_page
node_results_page -->|"requests results"| node_service
node_voter -->|"starts"| node_voting_page
node_voting_page -->|"renders"| node_voting_flow
node_voting_flow -->|"renders"| node_verification
node_voting_flow -->|"renders"| node_ballot
node_voting_flow -->|"renders"| node_confirmation
node_ballot -->|"loads candidates"| node_service
node_ballot -->|"submits ballot"| node_api
node_admin_user -->|"signs in"| node_admin_login
node_admin_user -->|"uses"| node_admin_dashboard
node_admin_user -->|"manages candidates"| node_candidate_admin
node_candidate_admin -->|"opens editor"| node_candidate_editor
node_candidate_admin -->|"renders table"| node_candidate_table
node_candidate_admin -->|"manages records"| node_service
node_admin_user -->|"manages voters"| node_voter_admin
node_voter_admin -->|"offers import"| node_csv_import
node_voter_admin -->|"updates voters"| node_service
node_csv_import -->|"imports voters"| node_service
node_admin_user -->|"views analytics"| node_analytics
node_admin_dashboard -->|"requests election data"| node_service
node_admin_login -->|"authenticates"| node_service
node_service -->|"sends requests"| node_api
node_service -->|"reads settings"| node_election_config
node_home -.->|"uses components"| node_ui_primitives

click node_home "https://github.com/johnyrex/gcr-election-portal/blob/main/app/page.tsx"
click node_home_features "https://github.com/johnyrex/gcr-election-portal/tree/main/features/home"
click node_candidate_browse "https://github.com/johnyrex/gcr-election-portal/blob/main/features/candidates/CandidateGrid.tsx"
click node_candidate_profiles "https://github.com/johnyrex/gcr-election-portal/blob/main/app/candidates/%5Bslug%5D/page.tsx"
click node_announcements "https://github.com/johnyrex/gcr-election-portal/blob/main/app/announcements/page.tsx"
click node_election_info "https://github.com/johnyrex/gcr-election-portal/blob/main/app/elections/page.tsx"
click node_constitution "https://github.com/johnyrex/gcr-election-portal/blob/main/app/constitution/page.tsx"
click node_results_page "https://github.com/johnyrex/gcr-election-portal/blob/main/features/results/ResultsDashboard.tsx"
click node_voting_page "https://github.com/johnyrex/gcr-election-portal/blob/main/app/vote/page.tsx"
click node_voting_flow "https://github.com/johnyrex/gcr-election-portal/blob/main/features/voting/VotingFlow.tsx"
click node_verification "https://github.com/johnyrex/gcr-election-portal/blob/main/features/voting/VerificationForm.tsx"
click node_ballot "https://github.com/johnyrex/gcr-election-portal/blob/main/features/voting/Ballot.tsx"
click node_confirmation "https://github.com/johnyrex/gcr-election-portal/blob/main/features/voting/Confirmation.tsx"
click node_admin_login "https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/AdminLogin.tsx"
click node_admin_dashboard "https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/AdminDashboard.tsx"
click node_candidate_admin "https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/candidates/CandidateManager.tsx"
click node_candidate_editor "https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/candidates/CandidateModal.tsx"
click node_candidate_table "https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/candidates/CandidateTable.tsx"
click node_voter_admin "https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/voters/VotersManager.tsx"
click node_csv_import "https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/voters/CsvImportButton.tsx"
click node_analytics "https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/analytics/AnalyticsDashboard.tsx"
click node_service "https://github.com/johnyrex/gcr-election-portal/blob/main/services/electionService.ts"
click node_api "https://github.com/johnyrex/gcr-election-portal/blob/main/app/api/election/route.ts"
click node_election_config "https://github.com/johnyrex/gcr-election-portal/blob/main/lib/config.ts"
click node_candidate_data "https://github.com/johnyrex/gcr-election-portal/blob/main/constants/candidates.ts"
click node_ui_primitives "https://github.com/johnyrex/gcr-election-portal/tree/main/components/ui"

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_home,node_home_features,node_candidate_browse,node_candidate_profiles,node_announcements,node_election_info,node_constitution,node_results_page toneBlue
class node_voting_page,node_voting_flow,node_verification,node_ballot,node_confirmation toneAmber
class node_admin_login,node_admin_dashboard,node_candidate_admin,node_candidate_editor,node_candidate_table,node_voter_admin,node_csv_import,node_analytics toneMint
class node_service,node_api,node_election_config,node_candidate_data,node_ui_primitives toneRose
class node_visitor,node_voter,node_admin_user toneIndigo
```

## Components

### Public election experience

- [Home overview](https://github.com/johnyrex/gcr-election-portal/blob/main/app/page.tsx): `app/page.tsx`
- [Home features](https://github.com/johnyrex/gcr-election-portal/tree/main/features/home): `features/home`
- [Candidate browsing](https://github.com/johnyrex/gcr-election-portal/blob/main/features/candidates/CandidateGrid.tsx): `features/candidates/CandidateGrid.tsx`
- [Candidate profiles](https://github.com/johnyrex/gcr-election-portal/blob/main/app/candidates/%5Bslug%5D/page.tsx): `app/candidates/[slug]/page.tsx`
- [Announcements](https://github.com/johnyrex/gcr-election-portal/blob/main/app/announcements/page.tsx): `app/announcements/page.tsx`
- [Election information](https://github.com/johnyrex/gcr-election-portal/blob/main/app/elections/page.tsx): `app/elections/page.tsx`
- [Constitution](https://github.com/johnyrex/gcr-election-portal/blob/main/app/constitution/page.tsx): `app/constitution/page.tsx`
- [Published results](https://github.com/johnyrex/gcr-election-portal/blob/main/features/results/ResultsDashboard.tsx): `features/results/ResultsDashboard.tsx`

### Voting workflow

- [Voting entry](https://github.com/johnyrex/gcr-election-portal/blob/main/app/vote/page.tsx): `app/vote/page.tsx`
- [Voting flow](https://github.com/johnyrex/gcr-election-portal/blob/main/features/voting/VotingFlow.tsx): `features/voting/VotingFlow.tsx`
- [Voter verification](https://github.com/johnyrex/gcr-election-portal/blob/main/features/voting/VerificationForm.tsx): `features/voting/VerificationForm.tsx`
- [Ballot and submission](https://github.com/johnyrex/gcr-election-portal/blob/main/features/voting/Ballot.tsx): `features/voting/Ballot.tsx`
- [Vote confirmation](https://github.com/johnyrex/gcr-election-portal/blob/main/features/voting/Confirmation.tsx): `features/voting/Confirmation.tsx`

### Election administration

- [Admin login](https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/AdminLogin.tsx): `features/admin/AdminLogin.tsx`
- [Admin dashboard](https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/AdminDashboard.tsx): `features/admin/AdminDashboard.tsx`
- [Candidate management](https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/candidates/CandidateManager.tsx): `features/admin/candidates/CandidateManager.tsx`
- [Candidate editor](https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/candidates/CandidateModal.tsx): `features/admin/candidates/CandidateModal.tsx`
- [Candidate table](https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/candidates/CandidateTable.tsx): `features/admin/candidates/CandidateTable.tsx`
- [Voter management](https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/voters/VotersManager.tsx): `features/admin/voters/VotersManager.tsx`
- [CSV voter import](https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/voters/CsvImportButton.tsx): `features/admin/voters/CsvImportButton.tsx`
- [Election analytics](https://github.com/johnyrex/gcr-election-portal/blob/main/features/admin/analytics/AnalyticsDashboard.tsx): `features/admin/analytics/AnalyticsDashboard.tsx`

### Election API and UI foundations

- [Election service](https://github.com/johnyrex/gcr-election-portal/blob/main/services/electionService.ts): `services/electionService.ts`
- [Election API route](https://github.com/johnyrex/gcr-election-portal/blob/main/app/api/election/route.ts): `app/api/election/route.ts`
- [Election configuration](https://github.com/johnyrex/gcr-election-portal/blob/main/lib/config.ts): `lib/config.ts`
- [Candidate content](https://github.com/johnyrex/gcr-election-portal/blob/main/constants/candidates.ts): `constants/candidates.ts`
- [Shared UI primitives](https://github.com/johnyrex/gcr-election-portal/tree/main/components/ui): `components/ui`

### Other components

- **Visitor**
- **Eligible voter**
- **Administrator**

## Connections

- Visitor → Home overview: opens (evidence: `app/page.tsx`)
- Home overview → Home features: renders (evidence: `app/page.tsx`)
- Visitor → Candidate browsing: browses
- Candidate browsing → Candidate content: reads (evidence: `features/candidates/CandidateGrid.tsx`)
- Home features → Candidate content: previews (evidence: `features/home/CandidatePreview.tsx`)
- Candidate profiles → Candidate content: reads (evidence: `app/candidates/[slug]/page.tsx`)
- Visitor → Announcements: opens (evidence: `app/announcements/page.tsx`)
- Visitor → Election information: opens (evidence: `app/elections/page.tsx`)
- Visitor → Constitution: opens (evidence: `app/constitution/page.tsx`)
- Visitor → Published results: views
- Published results → Election service: requests results (evidence: `features/results/ResultsDashboard.tsx`)
- Eligible voter → Voting entry: starts (evidence: `app/vote/page.tsx`)
- Voting entry → Voting flow: renders (evidence: `app/vote/page.tsx`)
- Voting flow → Voter verification: renders (evidence: `features/voting/VotingFlow.tsx`)
- Voting flow → Ballot and submission: renders (evidence: `features/voting/VotingFlow.tsx`)
- Voting flow → Vote confirmation: renders (evidence: `features/voting/VotingFlow.tsx`)
- Ballot and submission → Election service: loads candidates (evidence: `features/voting/Ballot.tsx`)
- Ballot and submission → Election API route: submits ballot (evidence: `features/voting/Ballot.tsx`)
- Administrator → Admin login: signs in
- Administrator → Admin dashboard: uses
- Administrator → Candidate management: manages candidates
- Candidate management → Candidate editor: opens editor (evidence: `features/admin/candidates/CandidateManager.tsx`)
- Candidate management → Candidate table: renders table (evidence: `features/admin/candidates/CandidateManager.tsx`)
- Candidate management → Election service: manages records (evidence: `features/admin/candidates/CandidateManager.tsx`)
- Administrator → Voter management: manages voters
- Voter management → CSV voter import: offers import (evidence: `features/admin/voters/VotersManager.tsx`)
- Voter management → Election service: updates voters (evidence: `features/admin/voters/VotersManager.tsx`)
- CSV voter import → Election service: imports voters (evidence: `features/admin/voters/CsvImportButton.tsx`)
- Administrator → Election analytics: views analytics
- Admin dashboard → Election service: requests election data (evidence: `features/admin/AdminDashboard.tsx`)
- Admin login → Election service: authenticates (evidence: `features/admin/AdminLogin.tsx`)
- Election service → Election API route: sends requests (evidence: `services/electionService.ts`)
- Election service → Election configuration: reads settings (evidence: `services/electionService.ts`)
- Home overview → Shared UI primitives: uses components
