# absentdsaga/tally-buildersgiving architecture

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

- Interactive diagram: https://gitdiagram.com/absentdsaga/tally-buildersgiving
- Repository: https://github.com/absentdsaga/tally-buildersgiving

## Overview

Tally is a volunteer-hours and safety-reporting app for small nonprofits. Volunteers submit a spoken or typed shift update; the server transcribes and parses it, checks for duplicates, and records hours and concerns for staff review. Separate shift-host features support event check-in, task assignment, messaging, and questions. Staff review and approve hours, handle concerns, and access reports and proof/letter views. The graph follows documented routes and source-index references; some unsampled subsystems are connected only where the README documents their behavior.

Main entry points: [`src/update.ts`](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/update.ts) (Update processing), [`src/database.ts`](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/database.ts) (Hours and concerns), [`public/app.js`](https://github.com/absentdsaga/tally-buildersgiving/blob/main/public/app.js) (Volunteer app), [`src/staffdata.ts`](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/staffdata.ts) (Staff data)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_volunteer["Volunteer experience"]
  node_volunteer_ui["Volunteer app<br/>[app.js]"]
end

subgraph group_shift["Shift host"]
  node_event[("Event and check-in<br/>[event.ts]")]
  node_today["Today and check-in API<br/>[today.ts]"]
  node_tasks_ui["Task board<br/>[tasks.js]"]
  node_task_api["Task API<br/>[taskapi.ts]"]
  node_tasks[("Task assignments<br/>[tasks.ts]")]
  node_chat_ui["Shift chat<br/>[chat.js]"]
  node_message_api["Message API<br/>[messageapi.ts]"]
  node_messages[("Message threads<br/>[messages.ts]")]
  node_ask_ui["Shift questions<br/>[ask.js]"]
  node_ask["Answer questions<br/>[ask.ts]"]
  node_report_ui["Volunteer reports<br/>[report.js]"]
end

subgraph group_server["Server workflows"]
  node_update_route["Update route<br/>[index.ts]"]
  node_update_handler["Update processing<br/>[update.ts]"]
  node_audio["Audio transcription<br/>[speech.ts]"]
  node_extractor["AI extraction<br/>[ai.ts]"]
  node_fallback["Fallback parser<br/>[fallback.ts]"]
  node_speak["Spoken responses<br/>[speak.ts]"]
end

subgraph group_data["Records and reporting"]
  node_records[("Hours and concerns<br/>[database.ts]")]
  node_reports[("Report handling<br/>[reports.ts]")]
  node_letter["Hours letter<br/>[letter.ts]"]
  node_proof["Proof lookup<br/>[proof.ts]"]
end

subgraph group_staff["Staff operations"]
  node_staff_ui["Staff dashboard<br/>[staff.js]"]
  node_staff_data["Staff data<br/>[staffdata.ts]"]
  node_staff_gate["Staff access<br/>[staffgate.ts]"]
end

node_volunteer(("Volunteer"))
node_speech_service{{"Speech service"}}
node_gemini{{"Gemini AI"}}

node_volunteer -->|"uses"| node_volunteer_ui
node_volunteer_ui -->|"submits update"| node_update_route
node_update_route -->|"routes update"| node_update_handler
node_update_handler -->|"transcribes audio"| node_audio
node_audio -->|"requests transcription"| node_speech_service
node_update_handler -->|"extracts shift data"| node_extractor
node_extractor -->|"requests extraction"| node_gemini
node_extractor -->|"falls back to"| node_fallback
node_update_handler -->|"checks danger words"| node_fallback
node_update_handler -->|"checks and saves"| node_records
node_volunteer -->|"staff reviews"| node_staff_ui
node_staff_ui -->|"requires passcode"| node_staff_gate
node_staff_ui -->|"requests dashboard data"| node_staff_data
node_staff_data -->|"reads and updates"| node_records
node_staff_data -->|"reads check-ins"| node_event
node_staff_data -->|"reads tasks"| node_tasks
node_volunteer_ui -->|"loads shift details"| node_today
node_today -->|"reads and records check-in"| node_event
node_today -->|"checks volunteer history"| node_records
node_today -->|"reads completed tasks"| node_tasks
node_tasks_ui -->|"requests task actions"| node_task_api
node_task_api -->|"manages assignments"| node_tasks
node_chat_ui -->|"sends and polls"| node_message_api
node_message_api -->|"reads and writes threads"| node_messages
node_message_api -->|"transcribes voice notes"| node_audio
node_ask_ui -->|"asks question"| node_ask
node_ask -->|"uses event notes"| node_event
node_ask -->|"uses task details"| node_tasks
node_ask -->|"uses staff notes"| node_records
node_report_ui -->|"submits and checks reports"| node_reports
node_reports -->|"reads and records reports"| node_records
node_volunteer_ui -->|"opens hours letter"| node_letter
node_letter -->|"reads approved shifts"| node_records
node_letter -->|"uses organization details"| node_staff_data
node_volunteer_ui -->|"opens proof page"| node_proof
node_proof -->|"looks up approved update"| node_records
node_update_handler -->|"builds spoken response"| node_speak

click node_volunteer_ui "https://github.com/absentdsaga/tally-buildersgiving/blob/main/public/app.js"
click node_update_route "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/index.ts"
click node_update_handler "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/update.ts"
click node_audio "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/speech.ts"
click node_extractor "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/ai.ts"
click node_fallback "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/fallback.ts"
click node_records "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/database.ts"
click node_staff_ui "https://github.com/absentdsaga/tally-buildersgiving/blob/main/public/staff.js"
click node_staff_data "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/staffdata.ts"
click node_staff_gate "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/staffgate.ts"
click node_event "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/event.ts"
click node_today "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/today.ts"
click node_tasks_ui "https://github.com/absentdsaga/tally-buildersgiving/blob/main/public/tasks.js"
click node_task_api "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/taskapi.ts"
click node_tasks "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/tasks.ts"
click node_chat_ui "https://github.com/absentdsaga/tally-buildersgiving/blob/main/public/chat.js"
click node_message_api "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/messageapi.ts"
click node_messages "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/messages.ts"
click node_ask_ui "https://github.com/absentdsaga/tally-buildersgiving/blob/main/public/ask.js"
click node_ask "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/ask.ts"
click node_report_ui "https://github.com/absentdsaga/tally-buildersgiving/blob/main/public/report.js"
click node_reports "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/reports.ts"
click node_letter "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/letter.ts"
click node_proof "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/proof.ts"
click node_speak "https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/speak.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_volunteer_ui toneBlue
class node_event,node_today,node_tasks_ui,node_task_api,node_tasks,node_chat_ui,node_message_api,node_messages,node_ask_ui,node_ask,node_report_ui toneAmber
class node_update_route,node_update_handler,node_audio,node_extractor,node_fallback,node_speak toneMint
class node_records,node_reports,node_letter,node_proof toneRose
class node_staff_ui,node_staff_data,node_staff_gate,node_volunteer,node_speech_service,node_gemini toneIndigo
```

## Components

### Volunteer experience

- [Volunteer app](https://github.com/absentdsaga/tally-buildersgiving/blob/main/public/app.js): `public/app.js`

### Shift host

- [Event and check-in](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/event.ts): `src/event.ts`
- [Today and check-in API](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/today.ts): `src/today.ts`
- [Task board](https://github.com/absentdsaga/tally-buildersgiving/blob/main/public/tasks.js): `public/tasks.js`
- [Task API](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/taskapi.ts): `src/taskapi.ts`
- [Task assignments](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/tasks.ts): `src/tasks.ts`
- [Shift chat](https://github.com/absentdsaga/tally-buildersgiving/blob/main/public/chat.js): `public/chat.js`
- [Message API](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/messageapi.ts): `src/messageapi.ts`
- [Message threads](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/messages.ts): `src/messages.ts`
- [Shift questions](https://github.com/absentdsaga/tally-buildersgiving/blob/main/public/ask.js): `public/ask.js`
- [Answer questions](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/ask.ts): `src/ask.ts`
- [Volunteer reports](https://github.com/absentdsaga/tally-buildersgiving/blob/main/public/report.js): `public/report.js`

### Server workflows

- [Update route](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/index.ts): `src/index.ts`
- [Update processing](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/update.ts): `src/update.ts`
- [Audio transcription](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/speech.ts): `src/speech.ts`
- [AI extraction](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/ai.ts): `src/ai.ts`
- [Fallback parser](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/fallback.ts): `src/fallback.ts`
- [Spoken responses](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/speak.ts): `src/speak.ts`

### Records and reporting

- [Hours and concerns](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/database.ts): `src/database.ts`
- [Report handling](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/reports.ts): `src/reports.ts`
- [Hours letter](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/letter.ts): `src/letter.ts`
- [Proof lookup](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/proof.ts): `src/proof.ts`

### Staff operations

- [Staff dashboard](https://github.com/absentdsaga/tally-buildersgiving/blob/main/public/staff.js): `public/staff.js`
- [Staff data](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/staffdata.ts): `src/staffdata.ts`
- [Staff access](https://github.com/absentdsaga/tally-buildersgiving/blob/main/src/staffgate.ts): `src/staffgate.ts`

### Other components

- **Volunteer**
- **Speech service**
- **Gemini AI**

## Connections

- Volunteer → Volunteer app: uses (evidence: `README.md`)
- Volunteer app → Update route: submits update (evidence: `README.md`)
- Update route → Update processing: routes update (evidence: `src/index.ts`)
- Update processing → Audio transcription: transcribes audio (evidence: `src/update.ts`)
- Audio transcription → Speech service: requests transcription (evidence: `README.md`)
- Update processing → AI extraction: extracts shift data (evidence: `src/update.ts`)
- AI extraction → Gemini AI: requests extraction (evidence: `src/ai.ts`)
- AI extraction → Fallback parser: falls back to (evidence: `src/ai.ts`)
- Update processing → Fallback parser: checks danger words (evidence: `src/update.ts`)
- Update processing → Hours and concerns: checks and saves (evidence: `src/update.ts`)
- Volunteer → Staff dashboard: staff reviews (evidence: `README.md`)
- Staff dashboard → Staff access: requires passcode (evidence: `README.md`)
- Staff dashboard → Staff data: requests dashboard data (evidence: `README.md`)
- Staff data → Hours and concerns: reads and updates (evidence: `src/staffdata.ts`)
- Staff data → Event and check-in: reads check-ins (evidence: `src/staffdata.ts`)
- Staff data → Task assignments: reads tasks (evidence: `src/staffdata.ts`)
- Volunteer app → Today and check-in API: loads shift details (evidence: `README.md`)
- Today and check-in API → Event and check-in: reads and records check-in (evidence: `src/today.ts`)
- Today and check-in API → Hours and concerns: checks volunteer history (evidence: `src/today.ts`)
- Today and check-in API → Task assignments: reads completed tasks (evidence: `src/today.ts`)
- Task board → Task API: requests task actions (evidence: `README.md`)
- Task API → Task assignments: manages assignments (evidence: `src/taskapi.ts`)
- Shift chat → Message API: sends and polls (evidence: `README.md`)
- Message API → Message threads: reads and writes threads (evidence: `src/messageapi.ts`)
- Message API → Audio transcription: transcribes voice notes (evidence: `src/messageapi.ts`)
- Shift questions → Answer questions: asks question (evidence: `README.md`)
- Answer questions → Event and check-in: uses event notes (evidence: `src/ask.ts`)
- Answer questions → Task assignments: uses task details (evidence: `src/ask.ts`)
- Answer questions → Hours and concerns: uses staff notes (evidence: `src/ask.ts`)
- Volunteer reports → Report handling: submits and checks reports (evidence: `README.md`)
- Report handling → Hours and concerns: reads and records reports (evidence: `src/reports.ts`)
- Volunteer app → Hours letter: opens hours letter (evidence: `README.md`)
- Hours letter → Hours and concerns: reads approved shifts (evidence: `src/letter.ts`)
- Hours letter → Staff data: uses organization details (evidence: `src/letter.ts`)
- Volunteer app → Proof lookup: opens proof page (evidence: `README.md`)
- Proof lookup → Hours and concerns: looks up approved update (evidence: `src/proof.ts`)
- Update processing → Spoken responses: builds spoken response (evidence: `src/update.ts`)
