# demainman/sin-000-healthsafe architecture

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

- Interactive diagram: https://gitdiagram.com/demainman/sin-000-healthsafe
- Repository: https://github.com/demainman/sin-000-healthsafe

## Overview

HealthSafe is a set of independently runnable services for cleaning ward exports, serving ward and emergency-status data, calculating on-call schedules, and delivering persistent equipment alerts. Its main workflow runs from CSV ingestion through ward lookup and emergency-level retrieval to schedule calculation, storage, and event broadcast; separate event and queue branches carry staffing updates and equipment failures. The README documents the full service contracts, while source excerpts verify only selected calls and wiring, so undocumented links are omitted.

Main entry points: [`staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingService.java`](https://github.com/demainman/sin-000-healthsafe/blob/main/staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingService.java) (Schedule workflow), [`ward-service/src/main/java/co/wethinkcode/healthsafe/WardServiceApp.java`](https://github.com/demainman/sin-000-healthsafe/blob/main/ward-service/src/main/java/co/wethinkcode/healthsafe/WardServiceApp.java) (Ward API), [`ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionStore.java`](https://github.com/demainman/sin-000-healthsafe/blob/main/ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionStore.java) (CSV ingestion), [`ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionServiceApp.java`](https://github.com/demainman/sin-000-healthsafe/blob/main/ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionServiceApp.java) (Ingestion API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ingestion["Ward ingestion"]
  node_ingest_app["Ingestion API"]
  node_ingest_store["CSV ingestion"]
  node_csv_cleaner["CSV cleaner"]
  node_ingest_report["Ingestion report"]
end

subgraph group_ward["Ward service"]
  node_ward_api["Ward API"]
  node_ingestion_client["Ingestion client"]
  node_ward_store[("Ward store<br/>[WardStore.java]")]
  node_staffing_updates[("Update store")]
  node_staffing_subscriber["Event subscriber"]
  node_failure_publisher["Failure publisher"]
end

subgraph group_staffing["Staffing service"]
  node_staffing_api["Staffing API"]
  node_staffing_service["Schedule workflow"]
  node_ward_client["Ward client<br/>[WardClient.java]"]
  node_level_client["Status client"]
  node_calculator["Schedule calculator"]
  node_schedule_store[("Schedule store<br/>[ScheduleStore.java]")]
  node_event_publisher["Event publisher"]
end

subgraph group_emergency["Emergency status"]
  node_emergency_api["Emergency API"]
  node_emergency_store[("Status store")]
end

subgraph group_equipment["Equipment alerts"]
  node_alert_consumer["Alert consumer"]
  node_alert_store[("Alert store")]
  node_alert_api["Alert API"]
end

node_operator(("HTTP clients"))
node_topic["Staffing topic"]
node_failure_queue["Failure queue"]

node_operator -->|"requests data"| node_ingest_app
node_ingest_app -->|"serves report"| node_ingest_store
node_ingest_store -->|"cleans rows"| node_csv_cleaner
node_ingest_store -->|"builds report"| node_ingest_report
node_operator -->|"requests wards"| node_ward_api
node_ward_api -->|"refreshes from"| node_ingestion_client
node_ingestion_client -->|"fetches wards"| node_ingest_app
node_ward_api -->|"loads and serves"| node_ward_store
node_operator -->|"requests schedule"| node_staffing_api
node_staffing_api -->|"dispatches request"| node_staffing_service
node_staffing_service -->|"fetches ward"| node_ward_client
node_ward_client -->|"gets ward"| node_ward_api
node_staffing_service -->|"fetches status"| node_level_client
node_level_client -->|"gets status"| node_emergency_api
node_operator -->|"sets status"| node_emergency_api
node_staffing_service -->|"calculates schedule"| node_calculator
node_staffing_service -->|"saves schedule"| node_schedule_store
node_staffing_service -->|"publishes schedule"| node_event_publisher
node_event_publisher -->|"broadcasts event"| node_topic
node_topic -->|"delivers event"| node_staffing_subscriber
node_staffing_subscriber -->|"stores latest"| node_staffing_updates
node_operator -->|"reports failure"| node_ward_api
node_ward_api -->|"publishes failure"| node_failure_publisher
node_failure_publisher -->|"sends alert"| node_failure_queue
node_failure_queue -->|"delivers alert"| node_alert_consumer
node_alert_consumer -->|"stores and acknowledges"| node_alert_store
node_operator -->|"retrieves alerts"| node_alert_api
node_alert_api -->|"reads alerts"| node_alert_store

click node_ingest_app "https://github.com/demainman/sin-000-healthsafe/blob/main/ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionServiceApp.java"
click node_ingest_store "https://github.com/demainman/sin-000-healthsafe/blob/main/ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionStore.java"
click node_csv_cleaner "https://github.com/demainman/sin-000-healthsafe/blob/main/ingestion-service/src/main/java/co/wethinkcode/healthsafe/WardCsvCleaner.java"
click node_ingest_report "https://github.com/demainman/sin-000-healthsafe/blob/main/ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionReport.java"
click node_ward_api "https://github.com/demainman/sin-000-healthsafe/blob/main/ward-service/src/main/java/co/wethinkcode/healthsafe/WardServiceApp.java"
click node_ingestion_client "https://github.com/demainman/sin-000-healthsafe/blob/main/ward-service/src/main/java/co/wethinkcode/healthsafe/IngestionClient.java"
click node_ward_store "https://github.com/demainman/sin-000-healthsafe/blob/main/ward-service/src/main/java/co/wethinkcode/healthsafe/WardStore.java"
click node_staffing_updates "https://github.com/demainman/sin-000-healthsafe/blob/main/ward-service/src/main/java/co/wethinkcode/healthsafe/StaffingUpdateStore.java"
click node_staffing_subscriber "https://github.com/demainman/sin-000-healthsafe/blob/main/ward-service/src/main/java/co/wethinkcode/healthsafe/StaffingEventSubscriber.java"
click node_emergency_api "https://github.com/demainman/sin-000-healthsafe/blob/main/alert-level-service/src/main/java/co/wethinkcode/healthsafe/AlertLevelServiceApp.java"
click node_emergency_store "https://github.com/demainman/sin-000-healthsafe/blob/main/alert-level-service/src/main/java/co/wethinkcode/healthsafe/AlertLevelStore.java"
click node_staffing_api "https://github.com/demainman/sin-000-healthsafe/blob/main/staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingServiceApp.java"
click node_staffing_service "https://github.com/demainman/sin-000-healthsafe/blob/main/staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingService.java"
click node_ward_client "https://github.com/demainman/sin-000-healthsafe/blob/main/staffing-service/src/main/java/co/wethinkcode/healthsafe/WardClient.java"
click node_level_client "https://github.com/demainman/sin-000-healthsafe/blob/main/staffing-service/src/main/java/co/wethinkcode/healthsafe/AlertLevelClient.java"
click node_calculator "https://github.com/demainman/sin-000-healthsafe/blob/main/staffing-service/src/main/java/co/wethinkcode/healthsafe/ScheduleCalculator.java"
click node_schedule_store "https://github.com/demainman/sin-000-healthsafe/blob/main/staffing-service/src/main/java/co/wethinkcode/healthsafe/ScheduleStore.java"
click node_event_publisher "https://github.com/demainman/sin-000-healthsafe/blob/main/staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingEventPublisher.java"
click node_failure_publisher "https://github.com/demainman/sin-000-healthsafe/blob/main/ward-service/src/main/java/co/wethinkcode/healthsafe/EquipmentFailurePublisher.java"
click node_alert_consumer "https://github.com/demainman/sin-000-healthsafe/blob/main/equipment-alert-service/src/main/java/co/wethinkcode/healthsafe/EquipmentAlertConsumer.java"
click node_alert_store "https://github.com/demainman/sin-000-healthsafe/blob/main/equipment-alert-service/src/main/java/co/wethinkcode/healthsafe/EquipmentAlertStore.java"
click node_alert_api "https://github.com/demainman/sin-000-healthsafe/blob/main/equipment-alert-service/src/main/java/co/wethinkcode/healthsafe/EquipmentAlertServiceApp.java"

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_ingest_app,node_ingest_store,node_csv_cleaner,node_ingest_report,node_operator toneBlue
class node_ward_api,node_ingestion_client,node_ward_store,node_staffing_updates,node_staffing_subscriber,node_failure_publisher toneAmber
class node_staffing_api,node_staffing_service,node_ward_client,node_level_client,node_calculator,node_schedule_store,node_event_publisher toneMint
class node_emergency_api,node_emergency_store,node_failure_queue toneRose
class node_alert_consumer,node_alert_store,node_alert_api,node_topic toneIndigo
```

## Components

### Ward ingestion

- [Ingestion API](https://github.com/demainman/sin-000-healthsafe/blob/main/ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionServiceApp.java): `ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionServiceApp.java`
- [CSV ingestion](https://github.com/demainman/sin-000-healthsafe/blob/main/ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionStore.java): `ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionStore.java`
- [CSV cleaner](https://github.com/demainman/sin-000-healthsafe/blob/main/ingestion-service/src/main/java/co/wethinkcode/healthsafe/WardCsvCleaner.java): `ingestion-service/src/main/java/co/wethinkcode/healthsafe/WardCsvCleaner.java`
- [Ingestion report](https://github.com/demainman/sin-000-healthsafe/blob/main/ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionReport.java): `ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionReport.java`

### Ward service

- [Ward API](https://github.com/demainman/sin-000-healthsafe/blob/main/ward-service/src/main/java/co/wethinkcode/healthsafe/WardServiceApp.java): `ward-service/src/main/java/co/wethinkcode/healthsafe/WardServiceApp.java`
- [Ingestion client](https://github.com/demainman/sin-000-healthsafe/blob/main/ward-service/src/main/java/co/wethinkcode/healthsafe/IngestionClient.java): `ward-service/src/main/java/co/wethinkcode/healthsafe/IngestionClient.java`
- [Ward store](https://github.com/demainman/sin-000-healthsafe/blob/main/ward-service/src/main/java/co/wethinkcode/healthsafe/WardStore.java): `ward-service/src/main/java/co/wethinkcode/healthsafe/WardStore.java`
- [Update store](https://github.com/demainman/sin-000-healthsafe/blob/main/ward-service/src/main/java/co/wethinkcode/healthsafe/StaffingUpdateStore.java): `ward-service/src/main/java/co/wethinkcode/healthsafe/StaffingUpdateStore.java`
- [Event subscriber](https://github.com/demainman/sin-000-healthsafe/blob/main/ward-service/src/main/java/co/wethinkcode/healthsafe/StaffingEventSubscriber.java): `ward-service/src/main/java/co/wethinkcode/healthsafe/StaffingEventSubscriber.java`
- [Failure publisher](https://github.com/demainman/sin-000-healthsafe/blob/main/ward-service/src/main/java/co/wethinkcode/healthsafe/EquipmentFailurePublisher.java): `ward-service/src/main/java/co/wethinkcode/healthsafe/EquipmentFailurePublisher.java`

### Staffing service

- [Staffing API](https://github.com/demainman/sin-000-healthsafe/blob/main/staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingServiceApp.java): `staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingServiceApp.java`
- [Schedule workflow](https://github.com/demainman/sin-000-healthsafe/blob/main/staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingService.java): `staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingService.java`
- [Ward client](https://github.com/demainman/sin-000-healthsafe/blob/main/staffing-service/src/main/java/co/wethinkcode/healthsafe/WardClient.java): `staffing-service/src/main/java/co/wethinkcode/healthsafe/WardClient.java`
- [Status client](https://github.com/demainman/sin-000-healthsafe/blob/main/staffing-service/src/main/java/co/wethinkcode/healthsafe/AlertLevelClient.java): `staffing-service/src/main/java/co/wethinkcode/healthsafe/AlertLevelClient.java`
- [Schedule calculator](https://github.com/demainman/sin-000-healthsafe/blob/main/staffing-service/src/main/java/co/wethinkcode/healthsafe/ScheduleCalculator.java): `staffing-service/src/main/java/co/wethinkcode/healthsafe/ScheduleCalculator.java`
- [Schedule store](https://github.com/demainman/sin-000-healthsafe/blob/main/staffing-service/src/main/java/co/wethinkcode/healthsafe/ScheduleStore.java): `staffing-service/src/main/java/co/wethinkcode/healthsafe/ScheduleStore.java`
- [Event publisher](https://github.com/demainman/sin-000-healthsafe/blob/main/staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingEventPublisher.java): `staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingEventPublisher.java`

### Emergency status

- [Emergency API](https://github.com/demainman/sin-000-healthsafe/blob/main/alert-level-service/src/main/java/co/wethinkcode/healthsafe/AlertLevelServiceApp.java): `alert-level-service/src/main/java/co/wethinkcode/healthsafe/AlertLevelServiceApp.java`
- [Status store](https://github.com/demainman/sin-000-healthsafe/blob/main/alert-level-service/src/main/java/co/wethinkcode/healthsafe/AlertLevelStore.java): `alert-level-service/src/main/java/co/wethinkcode/healthsafe/AlertLevelStore.java`

### Equipment alerts

- [Alert consumer](https://github.com/demainman/sin-000-healthsafe/blob/main/equipment-alert-service/src/main/java/co/wethinkcode/healthsafe/EquipmentAlertConsumer.java): `equipment-alert-service/src/main/java/co/wethinkcode/healthsafe/EquipmentAlertConsumer.java`
- [Alert store](https://github.com/demainman/sin-000-healthsafe/blob/main/equipment-alert-service/src/main/java/co/wethinkcode/healthsafe/EquipmentAlertStore.java): `equipment-alert-service/src/main/java/co/wethinkcode/healthsafe/EquipmentAlertStore.java`
- [Alert API](https://github.com/demainman/sin-000-healthsafe/blob/main/equipment-alert-service/src/main/java/co/wethinkcode/healthsafe/EquipmentAlertServiceApp.java): `equipment-alert-service/src/main/java/co/wethinkcode/healthsafe/EquipmentAlertServiceApp.java`

### Other components

- **HTTP clients**
- **Staffing topic**
- **Failure queue**

## Connections

- HTTP clients → Ingestion API: requests data (evidence: `README.md`)
- Ingestion API → CSV ingestion: serves report (evidence: `ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionServiceApp.java`)
- CSV ingestion → CSV cleaner: cleans rows (evidence: `ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionStore.java`)
- CSV ingestion → Ingestion report: builds report (evidence: `ingestion-service/src/main/java/co/wethinkcode/healthsafe/IngestionStore.java`)
- HTTP clients → Ward API: requests wards (evidence: `README.md`)
- Ward API → Ingestion client: refreshes from (evidence: `ward-service/src/main/java/co/wethinkcode/healthsafe/WardServiceApp.java`)
- Ingestion client → Ingestion API: fetches wards (evidence: `ward-service/src/main/java/co/wethinkcode/healthsafe/IngestionClient.java`)
- Ward API → Ward store: loads and serves (evidence: `ward-service/src/main/java/co/wethinkcode/healthsafe/WardServiceApp.java`)
- HTTP clients → Staffing API: requests schedule (evidence: `README.md`)
- Staffing API → Schedule workflow: dispatches request (evidence: `staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingServiceApp.java`)
- Schedule workflow → Ward client: fetches ward (evidence: `staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingService.java`)
- Ward client → Ward API: gets ward (evidence: `README.md`)
- Schedule workflow → Status client: fetches status (evidence: `staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingService.java`)
- Status client → Emergency API: gets status (evidence: `README.md`)
- HTTP clients → Emergency API: sets status (evidence: `README.md`)
- Schedule workflow → Schedule calculator: calculates schedule (evidence: `staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingService.java`)
- Schedule workflow → Schedule store: saves schedule (evidence: `staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingService.java`)
- Schedule workflow → Event publisher: publishes schedule (evidence: `staffing-service/src/main/java/co/wethinkcode/healthsafe/StaffingService.java`)
- Event publisher → Staffing topic: broadcasts event (evidence: `README.md`)
- Staffing topic → Event subscriber: delivers event (evidence: `README.md`)
- Event subscriber → Update store: stores latest (evidence: `ward-service/src/main/java/co/wethinkcode/healthsafe/StaffingEventSubscriber.java`)
- HTTP clients → Ward API: reports failure (evidence: `README.md`)
- Ward API → Failure publisher: publishes failure (evidence: `ward-service/src/main/java/co/wethinkcode/healthsafe/WardServiceApp.java`)
- Failure publisher → Failure queue: sends alert (evidence: `README.md`)
- Failure queue → Alert consumer: delivers alert (evidence: `README.md`)
- Alert consumer → Alert store: stores and acknowledges (evidence: `equipment-alert-service/src/main/java/co/wethinkcode/healthsafe/EquipmentAlertConsumer.java`)
- HTTP clients → Alert API: retrieves alerts (evidence: `README.md`)
- Alert API → Alert store: reads alerts (evidence: `equipment-alert-service/src/main/java/co/wethinkcode/healthsafe/EquipmentAlertServiceApp.java`)
