# thanhdang13/signa architecture

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

- Interactive diagram: https://gitdiagram.com/thanhdang13/signa
- Repository: https://github.com/thanhdang13/signa

## Overview

Signa is a voting and election-management system with an Android client, a NestJS API, and background workers. Its central workflow lets an organizer manage an election, generate ballots, and then upload scanned ballots for asynchronous OMR processing and status review. The API also supports identity and election operations; workers generate ballot PDFs and process scans. The source excerpts show controller dispatch and PDF rendering dependencies, but do not expose most handler-to-storage or queue-to-worker wiring, so those links are omitted or marked unverified.

Main entry points: [`apps/android/src/app/index.tsx`](https://github.com/thanhdang13/signa/blob/main/apps/android/src/app/index.tsx) (Android app), [`apps/api/src/modules/ballot/presentation/controllers/ballot.controller.ts`](https://github.com/thanhdang13/signa/blob/main/apps/api/src/modules/ballot/presentation/controllers/ballot.controller.ts) (Ballot API), [`apps/api/src/modules/ballot/application`](https://github.com/thanhdang13/signa/tree/main/apps/api/src/modules/ballot/application) (Ballot handlers), [`apps/worker/src/modules/ballot/services/ballot-pdf-generation.service.ts`](https://github.com/thanhdang13/signa/blob/main/apps/worker/src/modules/ballot/services/ballot-pdf-generation.service.ts) (PDF rendering)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Mobile client"]
  node_mobile["Android app<br/>[index.tsx]"]
end

subgraph group_api["API and domain"]
  node_identity["Identity API"]
  node_election["Election API"]
  node_ballotapi["Ballot API"]
  node_domain["Election handlers"]
  node_ballotdomain["Ballot handlers"]
end

subgraph group_jobs["Async processing"]
  node_genworker["Ballot worker"]
  node_pdf["PDF rendering"]
  node_markers["Marker drawing"]
  node_fields["Form rendering"]
  node_scanworker["OMR processor"]
  node_qr["QR verification"]
  node_opencv["OpenCV service<br/>[opencv.service.ts]"]
end

subgraph group_infra["Runtime services"]
  node_queue["Job publisher"]
  node_s3[("Object storage<br/>[aws-s3.service.ts]")]
  node_db[("Application database<br/>[database.module.ts]")]
end

node_organizer(("Organizer"))

node_organizer -.->|"uses"| node_mobile
node_mobile -.->|"requests"| node_identity
node_mobile -.->|"manages"| node_election
node_mobile -.->|"scans ballots"| node_ballotapi
node_identity -.->|"authenticates"| node_domain
node_election -->|"dispatches"| node_domain
node_ballotapi -->|"dispatches"| node_ballotdomain
node_ballotdomain -.->|"publishes jobs"| node_queue
node_queue -.->|"dispatches jobs"| node_genworker
node_genworker -.->|"generates PDFs"| node_pdf
node_pdf -->|"draws markers"| node_markers
node_pdf -->|"renders fields"| node_fields
node_queue -.->|"dispatches jobs"| node_scanworker
node_scanworker -.->|"verifies QR"| node_qr
node_qr -->|"uses image ops"| node_opencv
node_ballotapi -.->|"requests URLs"| node_s3
node_ballotdomain -.->|"persists results"| node_db

click node_mobile "https://github.com/thanhdang13/signa/blob/main/apps/android/src/app/index.tsx"
click node_identity "https://github.com/thanhdang13/signa/blob/main/apps/api/src/modules/identity/presentation/controllers/identity.controller.ts"
click node_election "https://github.com/thanhdang13/signa/blob/main/apps/api/src/modules/election/presentation/controllers/election.controller.ts"
click node_ballotapi "https://github.com/thanhdang13/signa/blob/main/apps/api/src/modules/ballot/presentation/controllers/ballot.controller.ts"
click node_domain "https://github.com/thanhdang13/signa/tree/main/apps/api/src/modules/election/application"
click node_ballotdomain "https://github.com/thanhdang13/signa/tree/main/apps/api/src/modules/ballot/application"
click node_queue "https://github.com/thanhdang13/signa/blob/main/packages/nest/queue/src/services/queue-publisher.service.ts"
click node_genworker "https://github.com/thanhdang13/signa/blob/main/apps/worker/src/modules/ballot/processors/ballot-generation.processor.ts"
click node_pdf "https://github.com/thanhdang13/signa/blob/main/apps/worker/src/modules/ballot/services/ballot-pdf-generation.service.ts"
click node_markers "https://github.com/thanhdang13/signa/blob/main/apps/worker/src/modules/ballot/services/aruco-marker-drawing.service.ts"
click node_fields "https://github.com/thanhdang13/signa/blob/main/apps/worker/src/modules/ballot/services/form-field-rendering.service.ts"
click node_scanworker "https://github.com/thanhdang13/signa/blob/main/apps/worker/src/modules/scanning/processors/omr-processing.processor.ts"
click node_qr "https://github.com/thanhdang13/signa/blob/main/apps/worker/src/modules/scanning/services/qr-verification.service.ts"
click node_opencv "https://github.com/thanhdang13/signa/blob/main/apps/worker/src/modules/scanning/services/opencv.service.ts"
click node_s3 "https://github.com/thanhdang13/signa/blob/main/packages/nest/s3/src/adapters/aws-s3.service.ts"
click node_db "https://github.com/thanhdang13/signa/blob/main/apps/api/src/core/database/database.module.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_mobile toneBlue
class node_identity,node_election,node_ballotapi,node_domain,node_ballotdomain toneAmber
class node_genworker,node_pdf,node_markers,node_fields,node_scanworker,node_qr,node_opencv toneMint
class node_queue,node_s3,node_db toneRose
class node_organizer toneIndigo
```

## Components

### Mobile client

- [Android app](https://github.com/thanhdang13/signa/blob/main/apps/android/src/app/index.tsx): `apps/android/src/app/index.tsx`

### API and domain

- [Identity API](https://github.com/thanhdang13/signa/blob/main/apps/api/src/modules/identity/presentation/controllers/identity.controller.ts): `apps/api/src/modules/identity/presentation/controllers/identity.controller.ts`
- [Election API](https://github.com/thanhdang13/signa/blob/main/apps/api/src/modules/election/presentation/controllers/election.controller.ts): `apps/api/src/modules/election/presentation/controllers/election.controller.ts`
- [Ballot API](https://github.com/thanhdang13/signa/blob/main/apps/api/src/modules/ballot/presentation/controllers/ballot.controller.ts): `apps/api/src/modules/ballot/presentation/controllers/ballot.controller.ts`
- [Election handlers](https://github.com/thanhdang13/signa/tree/main/apps/api/src/modules/election/application): `apps/api/src/modules/election/application`
- [Ballot handlers](https://github.com/thanhdang13/signa/tree/main/apps/api/src/modules/ballot/application): `apps/api/src/modules/ballot/application`

### Async processing

- [Ballot worker](https://github.com/thanhdang13/signa/blob/main/apps/worker/src/modules/ballot/processors/ballot-generation.processor.ts): `apps/worker/src/modules/ballot/processors/ballot-generation.processor.ts`
- [PDF rendering](https://github.com/thanhdang13/signa/blob/main/apps/worker/src/modules/ballot/services/ballot-pdf-generation.service.ts): `apps/worker/src/modules/ballot/services/ballot-pdf-generation.service.ts`
- [Marker drawing](https://github.com/thanhdang13/signa/blob/main/apps/worker/src/modules/ballot/services/aruco-marker-drawing.service.ts): `apps/worker/src/modules/ballot/services/aruco-marker-drawing.service.ts`
- [Form rendering](https://github.com/thanhdang13/signa/blob/main/apps/worker/src/modules/ballot/services/form-field-rendering.service.ts): `apps/worker/src/modules/ballot/services/form-field-rendering.service.ts`
- [OMR processor](https://github.com/thanhdang13/signa/blob/main/apps/worker/src/modules/scanning/processors/omr-processing.processor.ts): `apps/worker/src/modules/scanning/processors/omr-processing.processor.ts`
- [QR verification](https://github.com/thanhdang13/signa/blob/main/apps/worker/src/modules/scanning/services/qr-verification.service.ts): `apps/worker/src/modules/scanning/services/qr-verification.service.ts`
- [OpenCV service](https://github.com/thanhdang13/signa/blob/main/apps/worker/src/modules/scanning/services/opencv.service.ts): `apps/worker/src/modules/scanning/services/opencv.service.ts`

### Runtime services

- [Job publisher](https://github.com/thanhdang13/signa/blob/main/packages/nest/queue/src/services/queue-publisher.service.ts): `packages/nest/queue/src/services/queue-publisher.service.ts`
- [Object storage](https://github.com/thanhdang13/signa/blob/main/packages/nest/s3/src/adapters/aws-s3.service.ts): `packages/nest/s3/src/adapters/aws-s3.service.ts`
- [Application database](https://github.com/thanhdang13/signa/blob/main/apps/api/src/core/database/database.module.ts): `apps/api/src/core/database/database.module.ts`

### Other components

- **Organizer**

## Connections

- Organizer → Android app: uses
- Android app → Identity API: requests
- Android app → Election API: manages
- Android app → Ballot API: scans ballots
- Identity API → Election handlers: authenticates
- Election API → Election handlers: dispatches (evidence: `apps/api/src/modules/election/presentation/controllers/election.controller.ts`)
- Ballot API → Ballot handlers: dispatches (evidence: `apps/api/src/modules/ballot/presentation/controllers/ballot.controller.ts`)
- Ballot handlers → Job publisher: publishes jobs
- Job publisher → Ballot worker: dispatches jobs
- Ballot worker → PDF rendering: generates PDFs
- PDF rendering → Marker drawing: draws markers (evidence: `apps/worker/src/modules/ballot/services/ballot-pdf-generation.service.ts`)
- PDF rendering → Form rendering: renders fields (evidence: `apps/worker/src/modules/ballot/services/ballot-pdf-generation.service.ts`)
- Job publisher → OMR processor: dispatches jobs
- OMR processor → QR verification: verifies QR
- QR verification → OpenCV service: uses image ops (evidence: `apps/worker/src/modules/scanning/services/qr-verification.service.ts`)
- Ballot API → Object storage: requests URLs
- Ballot handlers → Application database: persists results
