# aeyvmor/cuddlebuddies architecture

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

- Interactive diagram: https://gitdiagram.com/aeyvmor/cuddlebuddies
- Repository: https://github.com/aeyvmor/cuddlebuddies

## Overview

ASTIG turns vehicle trips into geolocated infrastructure evidence, then supports officer review and work-order resolution. The principal path is mobile capture and offline queuing, API upload, asynchronous AI processing and persistence, then web review, prioritization, and work-order tracking. The README also documents analytics and a mock/demo web mode. Edges follow README-described workflow or shown calls; unsampled subsystems are represented at their exact directory paths, without asserting unverified internal wiring.

Main entry points: [`services/api/src/app.ts`](https://github.com/aeyvmor/cuddlebuddies/blob/main/services/api/src/app.ts) (Authenticated API), [`apps/web/src/App.tsx`](https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/web/src/App.tsx) (Operations dashboard), [`database/src`](https://github.com/aeyvmor/cuddlebuddies/tree/main/database/src) (Postgres and PostGIS), [`services/worker/src/ingest.ts`](https://github.com/aeyvmor/cuddlebuddies/blob/main/services/worker/src/ingest.ts) (Image processing)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_field["Field capture"]
  node_mobile["Capture app<br/>[App.tsx]"]
  node_capture["Image and GPS capture<br/>[capture.ts]"]
  node_session["Trip sessions<br/>[session.ts]"]
  node_offline["Offline queue<br/>[queue.ts]"]
  node_device[("Private device storage<br/>[storage.ts]")]
  node_uploader["Background uploader<br/>[upload.ts]"]
end

subgraph group_backend["Processing and data"]
  node_api["Authenticated API<br/>[app.ts]"]
  node_worker["Image processing<br/>[ingest.ts]"]
  node_vision["Vision provider<br/>[provider.ts]"]
  node_repositories["Operational repositories"]
  node_database[("Postgres and PostGIS")]
end

subgraph group_operations["Officer operations"]
  node_web["Operations dashboard<br/>[App.tsx]"]
  node_webapi["Web API adapter<br/>[httpClient.ts]"]
  node_mock["Offline demo API<br/>[mockClient.ts]"]
  node_map["Issue map and review<br/>[IssueMap.tsx]"]
  node_workorders["Work-order panel<br/>[WorkOrderPanel.tsx]"]
  node_analytics["Summary analytics<br/>[AnalyticsPanel.tsx]"]
end

subgraph group_shared["Domain and contracts"]
  node_domain["Risk and issue rules"]
  node_contracts["Shared API schemas"]
end

node_vehicle(("Vehicle operator"))
node_officer(("Authorized officer"))

node_vehicle -->|"starts trip"| node_mobile
node_mobile -->|"manages session"| node_session
node_session -->|"samples trip"| node_capture
node_capture -->|"records attempt"| node_offline
node_offline -->|"persists queue"| node_device
node_mobile -->|"uploads captures"| node_uploader
node_uploader -->|"registers and uploads"| node_api
node_api -->|"triggers processing"| node_worker
node_worker -->|"analyzes image"| node_vision
node_worker -->|"persists findings"| node_database
node_officer -->|"reviews issues"| node_web
node_web -->|"requests issue data"| node_webapi
node_web -->|"selects demo data"| node_mock
node_webapi -->|"calls API"| node_api
node_api -->|"dispatches operations"| node_repositories
node_api -->|"queries transaction"| node_database
node_repositories -.->|"reads and writes"| node_database
node_database -->|"scores observations"| node_domain
node_api -->|"validates responses"| node_contracts
node_worker -->|"validates detection"| node_contracts
node_web -->|"presents issues"| node_map
node_officer -->|"reviews and resolves"| node_workorders
node_web -->|"manages work orders"| node_workorders
node_web -->|"shows summaries"| node_analytics
node_officer -->|"creates and updates"| node_api
node_api -->|"stores work-order state"| node_database

click node_mobile "https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/mobile/App.tsx"
click node_capture "https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/mobile/src/capture.ts"
click node_session "https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/mobile/src/session.ts"
click node_offline "https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/mobile/src/queue.ts"
click node_device "https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/mobile/src/storage.ts"
click node_uploader "https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/mobile/src/upload.ts"
click node_api "https://github.com/aeyvmor/cuddlebuddies/blob/main/services/api/src/app.ts"
click node_worker "https://github.com/aeyvmor/cuddlebuddies/blob/main/services/worker/src/ingest.ts"
click node_vision "https://github.com/aeyvmor/cuddlebuddies/blob/main/services/worker/src/provider.ts"
click node_repositories "https://github.com/aeyvmor/cuddlebuddies/tree/main/services/api/src/repositories"
click node_database "https://github.com/aeyvmor/cuddlebuddies/tree/main/database/src"
click node_domain "https://github.com/aeyvmor/cuddlebuddies/tree/main/packages/domain/src"
click node_contracts "https://github.com/aeyvmor/cuddlebuddies/tree/main/packages/contracts/src"
click node_web "https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/web/src/App.tsx"
click node_webapi "https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/web/src/api/httpClient.ts"
click node_mock "https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/web/src/api/mockClient.ts"
click node_map "https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/web/src/components/IssueMap.tsx"
click node_workorders "https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/web/src/components/WorkOrderPanel.tsx"
click node_analytics "https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/web/src/components/AnalyticsPanel.tsx"

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,node_capture,node_session,node_offline,node_device,node_uploader toneBlue
class node_api,node_worker,node_vision,node_repositories,node_database toneAmber
class node_web,node_webapi,node_mock,node_map,node_workorders,node_analytics toneMint
class node_domain,node_contracts toneRose
class node_vehicle,node_officer toneIndigo
```

## Components

### Field capture

- [Capture app](https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/mobile/App.tsx): `apps/mobile/App.tsx`
- [Image and GPS capture](https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/mobile/src/capture.ts): `apps/mobile/src/capture.ts`
- [Trip sessions](https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/mobile/src/session.ts): `apps/mobile/src/session.ts`
- [Offline queue](https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/mobile/src/queue.ts): `apps/mobile/src/queue.ts`
- [Private device storage](https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/mobile/src/storage.ts): `apps/mobile/src/storage.ts`
- [Background uploader](https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/mobile/src/upload.ts): `apps/mobile/src/upload.ts`

### Processing and data

- [Authenticated API](https://github.com/aeyvmor/cuddlebuddies/blob/main/services/api/src/app.ts): `services/api/src/app.ts`
- [Image processing](https://github.com/aeyvmor/cuddlebuddies/blob/main/services/worker/src/ingest.ts): `services/worker/src/ingest.ts`
- [Vision provider](https://github.com/aeyvmor/cuddlebuddies/blob/main/services/worker/src/provider.ts): `services/worker/src/provider.ts`
- [Operational repositories](https://github.com/aeyvmor/cuddlebuddies/tree/main/services/api/src/repositories): `services/api/src/repositories`
- [Postgres and PostGIS](https://github.com/aeyvmor/cuddlebuddies/tree/main/database/src): `database/src`

### Officer operations

- [Operations dashboard](https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/web/src/App.tsx): `apps/web/src/App.tsx`
- [Web API adapter](https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/web/src/api/httpClient.ts): `apps/web/src/api/httpClient.ts`
- [Offline demo API](https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/web/src/api/mockClient.ts): `apps/web/src/api/mockClient.ts`
- [Issue map and review](https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/web/src/components/IssueMap.tsx): `apps/web/src/components/IssueMap.tsx`
- [Work-order panel](https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/web/src/components/WorkOrderPanel.tsx): `apps/web/src/components/WorkOrderPanel.tsx`
- [Summary analytics](https://github.com/aeyvmor/cuddlebuddies/blob/main/apps/web/src/components/AnalyticsPanel.tsx): `apps/web/src/components/AnalyticsPanel.tsx`

### Domain and contracts

- [Risk and issue rules](https://github.com/aeyvmor/cuddlebuddies/tree/main/packages/domain/src): `packages/domain/src`
- [Shared API schemas](https://github.com/aeyvmor/cuddlebuddies/tree/main/packages/contracts/src): `packages/contracts/src`

### Other components

- **Vehicle operator**
- **Authorized officer**

## Connections

- Vehicle operator → Capture app: starts trip (evidence: `README.md`)
- Capture app → Trip sessions: manages session (evidence: `apps/mobile/App.tsx`)
- Trip sessions → Image and GPS capture: samples trip (evidence: `apps/mobile/src/session.ts`)
- Image and GPS capture → Offline queue: records attempt (evidence: `apps/mobile/src/queue.ts`)
- Offline queue → Private device storage: persists queue (evidence: `apps/mobile/src/storage.ts`)
- Capture app → Background uploader: uploads captures (evidence: `apps/mobile/App.tsx`)
- Background uploader → Authenticated API: registers and uploads (evidence: `README.md`)
- Authenticated API → Image processing: triggers processing (evidence: `README.md`)
- Image processing → Vision provider: analyzes image (evidence: `services/worker/src/ingest.ts`)
- Image processing → Postgres and PostGIS: persists findings (evidence: `README.md`)
- Authorized officer → Operations dashboard: reviews issues (evidence: `README.md`)
- Operations dashboard → Web API adapter: requests issue data (evidence: `apps/web/src/main.tsx`)
- Operations dashboard → Offline demo API: selects demo data (evidence: `apps/web/src/main.tsx`)
- Web API adapter → Authenticated API: calls API (evidence: `README.md`)
- Authenticated API → Operational repositories: dispatches operations (evidence: `services/api/src/app.ts`)
- Authenticated API → Postgres and PostGIS: queries transaction (evidence: `services/api/src/app.ts`)
- Operational repositories → Postgres and PostGIS: reads and writes
- Postgres and PostGIS → Risk and issue rules: scores observations (evidence: `database/src/observations.ts`)
- Authenticated API → Shared API schemas: validates responses (evidence: `services/api/src/app.ts`)
- Image processing → Shared API schemas: validates detection (evidence: `services/worker/src/ingest.ts`)
- Operations dashboard → Issue map and review: presents issues (evidence: `apps/web/src/App.tsx`)
- Authorized officer → Work-order panel: reviews and resolves (evidence: `README.md`)
- Operations dashboard → Work-order panel: manages work orders (evidence: `apps/web/src/App.tsx`)
- Operations dashboard → Summary analytics: shows summaries (evidence: `apps/web/src/App.tsx`)
- Authorized officer → Authenticated API: creates and updates (evidence: `README.md`)
- Authenticated API → Postgres and PostGIS: stores work-order state (evidence: `README.md`)
