# woodbutcherth1/hourstracker architecture

> Architecture diagram of the GitHub repository woodbutcherth1/hourstracker, 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/woodbutcherth1/hourstracker
- Repository: https://github.com/woodbutcherth1/hourstracker

## Overview

HoursTracker is an iOS work-hours and payroll companion for workers configuring Israeli work rules. The principal workflow is clocking or entering shifts, calculating overtime and estimated pay, reviewing history, and exporting reports. Separate capabilities include workplace geofence reminders, OCR-based timesheet and payslip import, an assistant over personal records, and synchronization across devices. The graph combines README-documented product behavior with relationships visible in the supplied source index and excerpts; some subsystem links are omitted where implementation wiring was not shown.

Main entry points: [`HoursTracker/ViewModels/AppViewModel.swift`](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/ViewModels/AppViewModel.swift) (Work Session Controller), [`HoursTracker/Managers/Assistant/AssistantEngine.swift`](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/Assistant/AssistantEngine.swift) (Assistant Engine), [`HoursTracker/Models/OvertimeCalculator.swift`](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Models/OvertimeCalculator.swift) (Overtime and Pay), [`HoursTracker/Managers/ExportManager.swift`](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/ExportManager.swift) (Report Export)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_work["Time and Pay"]
  node_viewmodel["Work Session Controller<br/>[AppViewModel.swift]"]
  node_session["Work Sessions<br/>[WorkSession.swift]"]
  node_settings["Workplace Rules"]
  node_overtime["Overtime and Pay"]
  node_location["Arrival Reminders"]
end

subgraph group_data["Storage and Sync"]
  node_persistence[("Local Persistence")]
  node_cloudkit["CloudKit Sync"]
  node_account["Account Sync"]
end

subgraph group_documents["Documents and Imports"]
  node_exportui["Export Screen<br/>[ExportView.swift]"]
  node_export["Report Export"]
  node_full_export["Full Data Export"]
  node_scanner["Timesheet Scanner"]
  node_scanner_route["Scanner Provider Router"]
  node_payslips[("Payslip Library<br/>[PayslipStore.swift]")]
  node_payslip_route["Payslip Provider Router"]
end

subgraph group_assist["Assistant"]
  node_assistant_ui["Assistant Chat"]
  node_assistant_vm["Assistant Controller"]
  node_assistant_engine["Assistant Engine"]
  node_assistant_route["Assistant Provider Router"]
end

subgraph group_surfaces["App Surfaces"]
  node_app["App Shell"]
  node_home["Home and History"]
  node_watch["Apple Watch App"]
  node_widget["Widget and Live Activity<br/>[HoursWidget.swift]"]
end

node_worker(("Worker"))
node_export_file["Exported Report"]

node_worker -->|"uses"| node_app
node_app -->|"hosts"| node_viewmodel
node_worker -->|"tracks shifts"| node_home
node_home -.->|"manages sessions"| node_viewmodel
node_viewmodel -.->|"updates"| node_session
node_session -->|"calculates pay"| node_overtime
node_settings -->|"sets work rules"| node_overtime
node_worker -->|"sets workplace"| node_location
node_viewmodel -.->|"persists"| node_persistence
node_persistence -->|"syncs"| node_cloudkit
node_worker -.->|"syncs account"| node_account
node_worker -->|"requests export"| node_exportui
node_exportui -.->|"requests report"| node_viewmodel
node_viewmodel -->|"builds report"| node_export
node_export -->|"uses pay rules"| node_overtime
node_export -->|"creates"| node_export_file
node_worker -.->|"imports or exports data"| node_full_export
node_viewmodel -->|"starts import"| node_scanner
node_scanner -->|"structures OCR"| node_scanner_route
node_worker -.->|"manages payslips"| node_payslips
node_payslips -.->|"extracts fields"| node_payslip_route
node_worker -->|"asks questions"| node_assistant_ui
node_assistant_ui -->|"sends chat"| node_assistant_vm
node_assistant_vm -.->|"requests answers"| node_assistant_engine
node_assistant_engine -->|"calculates totals"| node_overtime
node_assistant_engine -->|"reads records"| node_payslips
node_assistant_route -.->|"plans answers"| node_assistant_engine
node_worker -.->|"tracks on watch"| node_watch
node_worker -.->|"views activity"| node_widget

click node_app "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/HoursTrackerApp.swift"
click node_home "https://github.com/woodbutcherth1/hourstracker/tree/main/HoursTracker/Views"
click node_viewmodel "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/ViewModels/AppViewModel.swift"
click node_session "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Models/WorkSession.swift"
click node_settings "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Models/WorkplaceSettings.swift"
click node_overtime "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Models/OvertimeCalculator.swift"
click node_location "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/LocationReminderManager.swift"
click node_persistence "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/PersistenceManager.swift"
click node_cloudkit "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/CloudKitSyncManager.swift"
click node_account "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/SupabaseAccountSyncManager.swift"
click node_exportui "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Views/ExportView.swift"
click node_export "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/ExportManager.swift"
click node_full_export "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/FullDataExportManager.swift"
click node_scanner "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/TimesheetScannerManager.swift"
click node_scanner_route "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/Scanner/ScannerLLMRouter.swift"
click node_payslips "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/PayslipStore.swift"
click node_payslip_route "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/Scanner/PayslipLLMRouter.swift"
click node_assistant_ui "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Views/Assistant/AssistantChatSheet.swift"
click node_assistant_vm "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/ViewModels/AssistantChatViewModel.swift"
click node_assistant_engine "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/Assistant/AssistantEngine.swift"
click node_assistant_route "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/Assistant/AssistantLLMRouter.swift"
click node_watch "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTrackerWatch/WatchSessionStore.swift"
click node_widget "https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTrackerWidget/HoursWidget.swift"

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_viewmodel,node_session,node_settings,node_overtime,node_location toneBlue
class node_persistence,node_cloudkit,node_account toneAmber
class node_exportui,node_export,node_full_export,node_scanner,node_scanner_route,node_payslips,node_payslip_route toneMint
class node_assistant_ui,node_assistant_vm,node_assistant_engine,node_assistant_route,node_worker toneRose
class node_app,node_home,node_watch,node_widget,node_export_file toneIndigo
```

## Components

### Time and Pay

- [Work Session Controller](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/ViewModels/AppViewModel.swift): `HoursTracker/ViewModels/AppViewModel.swift`
- [Work Sessions](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Models/WorkSession.swift): `HoursTracker/Models/WorkSession.swift`
- [Workplace Rules](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Models/WorkplaceSettings.swift): `HoursTracker/Models/WorkplaceSettings.swift`
- [Overtime and Pay](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Models/OvertimeCalculator.swift): `HoursTracker/Models/OvertimeCalculator.swift`
- [Arrival Reminders](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/LocationReminderManager.swift): `HoursTracker/Managers/LocationReminderManager.swift`

### Storage and Sync

- [Local Persistence](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/PersistenceManager.swift): `HoursTracker/Managers/PersistenceManager.swift`
- [CloudKit Sync](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/CloudKitSyncManager.swift): `HoursTracker/Managers/CloudKitSyncManager.swift`
- [Account Sync](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/SupabaseAccountSyncManager.swift): `HoursTracker/Managers/SupabaseAccountSyncManager.swift`

### Documents and Imports

- [Export Screen](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Views/ExportView.swift): `HoursTracker/Views/ExportView.swift`
- [Report Export](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/ExportManager.swift): `HoursTracker/Managers/ExportManager.swift`
- [Full Data Export](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/FullDataExportManager.swift): `HoursTracker/Managers/FullDataExportManager.swift`
- [Timesheet Scanner](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/TimesheetScannerManager.swift): `HoursTracker/Managers/TimesheetScannerManager.swift`
- [Scanner Provider Router](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/Scanner/ScannerLLMRouter.swift): `HoursTracker/Managers/Scanner/ScannerLLMRouter.swift`
- [Payslip Library](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/PayslipStore.swift): `HoursTracker/Managers/PayslipStore.swift`
- [Payslip Provider Router](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/Scanner/PayslipLLMRouter.swift): `HoursTracker/Managers/Scanner/PayslipLLMRouter.swift`

### Assistant

- [Assistant Chat](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Views/Assistant/AssistantChatSheet.swift): `HoursTracker/Views/Assistant/AssistantChatSheet.swift`
- [Assistant Controller](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/ViewModels/AssistantChatViewModel.swift): `HoursTracker/ViewModels/AssistantChatViewModel.swift`
- [Assistant Engine](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/Assistant/AssistantEngine.swift): `HoursTracker/Managers/Assistant/AssistantEngine.swift`
- [Assistant Provider Router](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/Managers/Assistant/AssistantLLMRouter.swift): `HoursTracker/Managers/Assistant/AssistantLLMRouter.swift`

### App Surfaces

- [App Shell](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTracker/HoursTrackerApp.swift): `HoursTracker/HoursTrackerApp.swift`
- [Home and History](https://github.com/woodbutcherth1/hourstracker/tree/main/HoursTracker/Views): `HoursTracker/Views`
- [Apple Watch App](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTrackerWatch/WatchSessionStore.swift): `HoursTrackerWatch/WatchSessionStore.swift`
- [Widget and Live Activity](https://github.com/woodbutcherth1/hourstracker/blob/main/HoursTrackerWidget/HoursWidget.swift): `HoursTrackerWidget/HoursWidget.swift`

### Other components

- **Worker**
- **Exported Report**

## Connections

- Worker → App Shell: uses
- App Shell → Work Session Controller: hosts (evidence: `HoursTracker/HoursTrackerApp.swift`)
- Worker → Home and History: tracks shifts
- Home and History → Work Session Controller: manages sessions (evidence: `HoursTracker/Views/Assistant/AssistantChatSheet.swift`)
- Work Session Controller → Work Sessions: updates (evidence: `HoursTracker/ViewModels/AppViewModel.swift`)
- Work Sessions → Overtime and Pay: calculates pay (evidence: `HoursTracker/Models/OvertimeCalculator.swift`)
- Workplace Rules → Overtime and Pay: sets work rules (evidence: `HoursTracker/Models/OvertimeCalculator.swift`)
- Worker → Arrival Reminders: sets workplace
- Work Session Controller → Local Persistence: persists (evidence: `HoursTracker/ViewModels/AppViewModel.swift`)
- Local Persistence → CloudKit Sync: syncs
- Worker → Account Sync: syncs account
- Worker → Export Screen: requests export
- Export Screen → Work Session Controller: requests report
- Work Session Controller → Report Export: builds report (evidence: `HoursTracker/ViewModels/AppViewModel.swift`)
- Report Export → Overtime and Pay: uses pay rules (evidence: `HoursTracker/Managers/ExportManager.swift`)
- Report Export → Exported Report: creates (evidence: `HoursTracker/Managers/ExportManager.swift`)
- Worker → Full Data Export: imports or exports data
- Work Session Controller → Timesheet Scanner: starts import (evidence: `HoursTracker/ViewModels/AppViewModel.swift`)
- Timesheet Scanner → Scanner Provider Router: structures OCR (evidence: `HoursTracker/Managers/TimesheetScannerManager.swift`)
- Worker → Payslip Library: manages payslips
- Payslip Library → Payslip Provider Router: extracts fields
- Worker → Assistant Chat: asks questions (evidence: `HoursTracker/Views/Assistant/AssistantChatSheet.swift`)
- Assistant Chat → Assistant Controller: sends chat (evidence: `HoursTracker/Views/Assistant/AssistantChatSheet.swift`)
- Assistant Controller → Assistant Engine: requests answers
- Assistant Engine → Overtime and Pay: calculates totals (evidence: `HoursTracker/Managers/Assistant/AssistantEngine.swift`)
- Assistant Engine → Payslip Library: reads records (evidence: `HoursTracker/Managers/Assistant/AssistantEngine.swift`)
- Assistant Provider Router → Assistant Engine: plans answers
- Worker → Apple Watch App: tracks on watch
- Worker → Widget and Live Activity: views activity
