# ctrlv-ince/seagrass-ai architecture

> Architecture diagram of the GitHub repository ctrlv-ince/seagrass-ai, 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/ctrlv-ince/seagrass-ai
- Repository: https://github.com/ctrlv-ince/seagrass-ai

## Overview

Seagrass supports field collection and meadow assessment: researchers record surveys, inspect detections and spatial maps, and review wave-attenuation predictions. The web app exposes dashboard, survey, detection, wave-model, and map views; the mobile client is documented as camera/GPS-enabled and offline-first. Both clients use the REST API, whose routes cover surveys, detections, predictions, and maps. The backend also documents PostgreSQL/PostGIS and S3/MinIO storage. Some service-to-route wiring is not shown in the excerpts, so those relationships are omitted or marked unverified.

Main entry points: [`web/src/App.tsx`](https://github.com/ctrlv-ince/seagrass-ai/blob/master/web/src/App.tsx) (Web app), [`backend/app/api/router.py`](https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/api/router.py) (API router), [`mobile/App.tsx`](https://github.com/ctrlv-ince/seagrass-ai/blob/master/mobile/App.tsx) (Mobile app), [`backend/app/api/surveys.py`](https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/api/surveys.py) (Survey routes)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web application"]
  node_webapp["Web app<br/>[App.tsx]"]
  node_dashboard["Dashboard<br/>[Dashboard.tsx]"]
  node_surveyview["Survey views<br/>[Surveys.tsx]"]
  node_detectionview["Detection view<br/>[Detection.tsx]"]
  node_wavemodelview["Wave model view<br/>[WaveModel.tsx]"]
  node_mapview["Map view<br/>[MapView.tsx]"]
  node_webclient["Web API client<br/>[client.ts]"]
end

subgraph group_mobile["Field application"]
  node_mobileapp["Mobile app<br/>[App.tsx]"]
  node_surveycapture["Survey capture<br/>[new.tsx]"]
  node_surveyrecord["Survey record<br/>[&#91;id&#93;.tsx]"]
  node_gps["GPS capture<br/>[useLocation.ts]"]
  node_camera["Camera capture<br/>[useCamera.ts]"]
  node_offline["Offline sync<br/>[useOfflineSync.ts]"]
  node_localdb[("Local survey store<br/>[schema.ts]")]
end

subgraph group_api["Backend API"]
  node_backend["API application<br/>[main.py]"]
  node_router["API router<br/>[router.py]"]
  node_surveyapi["Survey routes<br/>[surveys.py]"]
  node_detectionapi["Detection routes<br/>[detections.py]"]
  node_predictionapi["Prediction routes<br/>[predictions.py]"]
  node_mapsapi["Map routes<br/>[maps.py]"]
end

subgraph group_science["Assessment services"]
  node_yolo["YOLO detection<br/>[yolo_service.py]"]
  node_wave["Wave regression<br/>[wave_model.py]"]
end

subgraph group_data["Data and storage"]
  node_database[("PostgreSQL / PostGIS<br/>[database.py]")]
  node_surveydata["Survey model<br/>[survey.py]"]
  node_surveycontract["Survey schema<br/>[survey.py]"]
  node_predictioncontract["Prediction schema<br/>[prediction.py]"]
  node_storage["Object storage<br/>[storage.py]"]
end

node_researcher(("Researcher"))
node_s3[("S3 / MinIO")]

node_researcher -->|"uses"| node_webapp
node_researcher -->|"collects with"| node_mobileapp
node_webapp -->|"routes to"| node_dashboard
node_webapp -->|"routes to"| node_surveyview
node_webapp -->|"routes to"| node_detectionview
node_webapp -->|"routes to"| node_wavemodelview
node_webapp -->|"routes to"| node_mapview
node_webapp -.->|"uses API"| node_webclient
node_webclient -->|"REST requests"| node_backend
node_mobileapp -.->|"provides"| node_surveycapture
node_mobileapp -.->|"provides"| node_surveyrecord
node_surveycapture -.->|"captures location"| node_gps
node_surveycapture -.->|"captures images"| node_camera
node_offline -.->|"syncs surveys"| node_localdb
node_mobileapp -->|"REST requests"| node_backend
node_backend -->|"mounts routes"| node_router
node_router -->|"registers"| node_surveyapi
node_router -->|"registers"| node_detectionapi
node_router -->|"registers"| node_predictionapi
node_router -->|"registers"| node_mapsapi
node_surveyapi -->|"queries"| node_database
node_detectionapi -->|"uses session"| node_database
node_predictionapi -->|"uses session"| node_database
node_mapsapi -->|"uses session"| node_database
node_surveyapi -->|"uses model"| node_surveydata
node_surveyapi -->|"uses schema"| node_surveycontract
node_predictionapi -->|"uses schema"| node_predictioncontract
node_detectionapi -.->|"invokes inference"| node_yolo
node_predictionapi -.->|"runs model"| node_wave
node_storage -->|"uploads objects"| node_s3

click node_webapp "https://github.com/ctrlv-ince/seagrass-ai/blob/master/web/src/App.tsx"
click node_dashboard "https://github.com/ctrlv-ince/seagrass-ai/blob/master/web/src/pages/Dashboard.tsx"
click node_surveyview "https://github.com/ctrlv-ince/seagrass-ai/blob/master/web/src/pages/Surveys.tsx"
click node_detectionview "https://github.com/ctrlv-ince/seagrass-ai/blob/master/web/src/pages/Detection.tsx"
click node_wavemodelview "https://github.com/ctrlv-ince/seagrass-ai/blob/master/web/src/pages/WaveModel.tsx"
click node_mapview "https://github.com/ctrlv-ince/seagrass-ai/blob/master/web/src/pages/MapView.tsx"
click node_webclient "https://github.com/ctrlv-ince/seagrass-ai/blob/master/web/src/api/client.ts"
click node_mobileapp "https://github.com/ctrlv-ince/seagrass-ai/blob/master/mobile/App.tsx"
click node_surveycapture "https://github.com/ctrlv-ince/seagrass-ai/blob/master/mobile/app/survey/new.tsx"
click node_surveyrecord "https://github.com/ctrlv-ince/seagrass-ai/blob/master/mobile/app/survey/%5Bid%5D.tsx"
click node_gps "https://github.com/ctrlv-ince/seagrass-ai/blob/master/mobile/src/hooks/useLocation.ts"
click node_camera "https://github.com/ctrlv-ince/seagrass-ai/blob/master/mobile/src/hooks/useCamera.ts"
click node_offline "https://github.com/ctrlv-ince/seagrass-ai/blob/master/mobile/src/hooks/useOfflineSync.ts"
click node_localdb "https://github.com/ctrlv-ince/seagrass-ai/blob/master/mobile/src/db/schema.ts"
click node_backend "https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/main.py"
click node_router "https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/api/router.py"
click node_surveyapi "https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/api/surveys.py"
click node_detectionapi "https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/api/detections.py"
click node_predictionapi "https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/api/predictions.py"
click node_mapsapi "https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/api/maps.py"
click node_yolo "https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/services/yolo_service.py"
click node_wave "https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/services/wave_model.py"
click node_database "https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/database.py"
click node_surveydata "https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/models/survey.py"
click node_surveycontract "https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/schemas/survey.py"
click node_predictioncontract "https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/schemas/prediction.py"
click node_storage "https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/services/storage.py"

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_webapp,node_dashboard,node_surveyview,node_detectionview,node_wavemodelview,node_mapview,node_webclient toneBlue
class node_mobileapp,node_surveycapture,node_surveyrecord,node_gps,node_camera,node_offline,node_localdb,node_s3 toneAmber
class node_backend,node_router,node_surveyapi,node_detectionapi,node_predictionapi,node_mapsapi toneMint
class node_yolo,node_wave toneRose
class node_database,node_surveydata,node_surveycontract,node_predictioncontract,node_storage,node_researcher toneIndigo
```

## Components

### Web application

- [Web app](https://github.com/ctrlv-ince/seagrass-ai/blob/master/web/src/App.tsx): `web/src/App.tsx`
- [Dashboard](https://github.com/ctrlv-ince/seagrass-ai/blob/master/web/src/pages/Dashboard.tsx): `web/src/pages/Dashboard.tsx`
- [Survey views](https://github.com/ctrlv-ince/seagrass-ai/blob/master/web/src/pages/Surveys.tsx): `web/src/pages/Surveys.tsx`
- [Detection view](https://github.com/ctrlv-ince/seagrass-ai/blob/master/web/src/pages/Detection.tsx): `web/src/pages/Detection.tsx`
- [Wave model view](https://github.com/ctrlv-ince/seagrass-ai/blob/master/web/src/pages/WaveModel.tsx): `web/src/pages/WaveModel.tsx`
- [Map view](https://github.com/ctrlv-ince/seagrass-ai/blob/master/web/src/pages/MapView.tsx): `web/src/pages/MapView.tsx`
- [Web API client](https://github.com/ctrlv-ince/seagrass-ai/blob/master/web/src/api/client.ts): `web/src/api/client.ts`

### Field application

- [Mobile app](https://github.com/ctrlv-ince/seagrass-ai/blob/master/mobile/App.tsx): `mobile/App.tsx`
- [Survey capture](https://github.com/ctrlv-ince/seagrass-ai/blob/master/mobile/app/survey/new.tsx): `mobile/app/survey/new.tsx`
- [Survey record](https://github.com/ctrlv-ince/seagrass-ai/blob/master/mobile/app/survey/%5Bid%5D.tsx): `mobile/app/survey/[id].tsx`
- [GPS capture](https://github.com/ctrlv-ince/seagrass-ai/blob/master/mobile/src/hooks/useLocation.ts): `mobile/src/hooks/useLocation.ts`
- [Camera capture](https://github.com/ctrlv-ince/seagrass-ai/blob/master/mobile/src/hooks/useCamera.ts): `mobile/src/hooks/useCamera.ts`
- [Offline sync](https://github.com/ctrlv-ince/seagrass-ai/blob/master/mobile/src/hooks/useOfflineSync.ts): `mobile/src/hooks/useOfflineSync.ts`
- [Local survey store](https://github.com/ctrlv-ince/seagrass-ai/blob/master/mobile/src/db/schema.ts): `mobile/src/db/schema.ts`

### Backend API

- [API application](https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/main.py): `backend/app/main.py`
- [API router](https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/api/router.py): `backend/app/api/router.py`
- [Survey routes](https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/api/surveys.py): `backend/app/api/surveys.py`
- [Detection routes](https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/api/detections.py): `backend/app/api/detections.py`
- [Prediction routes](https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/api/predictions.py): `backend/app/api/predictions.py`
- [Map routes](https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/api/maps.py): `backend/app/api/maps.py`

### Assessment services

- [YOLO detection](https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/services/yolo_service.py): `backend/app/services/yolo_service.py`
- [Wave regression](https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/services/wave_model.py): `backend/app/services/wave_model.py`

### Data and storage

- [PostgreSQL / PostGIS](https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/database.py): `backend/app/database.py`
- [Survey model](https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/models/survey.py): `backend/app/models/survey.py`
- [Survey schema](https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/schemas/survey.py): `backend/app/schemas/survey.py`
- [Prediction schema](https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/schemas/prediction.py): `backend/app/schemas/prediction.py`
- [Object storage](https://github.com/ctrlv-ince/seagrass-ai/blob/master/backend/app/services/storage.py): `backend/app/services/storage.py`

### Other components

- **Researcher**
- **S3 / MinIO**

## Connections

- Researcher → Web app: uses
- Researcher → Mobile app: collects with
- Web app → Dashboard: routes to (evidence: `web/src/App.tsx`)
- Web app → Survey views: routes to (evidence: `web/src/App.tsx`)
- Web app → Detection view: routes to (evidence: `web/src/App.tsx`)
- Web app → Wave model view: routes to (evidence: `web/src/App.tsx`)
- Web app → Map view: routes to (evidence: `web/src/App.tsx`)
- Web app → Web API client: uses API
- Web API client → API application: REST requests
- Mobile app → Survey capture: provides
- Mobile app → Survey record: provides
- Survey capture → GPS capture: captures location
- Survey capture → Camera capture: captures images
- Offline sync → Local survey store: syncs surveys
- Mobile app → API application: REST requests
- API application → API router: mounts routes (evidence: `backend/app/main.py`)
- API router → Survey routes: registers (evidence: `backend/app/api/router.py`)
- API router → Detection routes: registers (evidence: `backend/app/api/router.py`)
- API router → Prediction routes: registers (evidence: `backend/app/api/router.py`)
- API router → Map routes: registers (evidence: `backend/app/api/router.py`)
- Survey routes → PostgreSQL / PostGIS: queries (evidence: `backend/app/api/surveys.py`)
- Detection routes → PostgreSQL / PostGIS: uses session (evidence: `backend/app/api/detections.py`)
- Prediction routes → PostgreSQL / PostGIS: uses session (evidence: `backend/app/api/predictions.py`)
- Map routes → PostgreSQL / PostGIS: uses session (evidence: `backend/app/api/maps.py`)
- Survey routes → Survey model: uses model (evidence: `backend/app/api/surveys.py`)
- Survey routes → Survey schema: uses schema (evidence: `backend/app/api/surveys.py`)
- Prediction routes → Prediction schema: uses schema (evidence: `backend/app/api/predictions.py`)
- Detection routes → YOLO detection: invokes inference
- Prediction routes → Wave regression: runs model
- Object storage → S3 / MinIO: uploads objects (evidence: `backend/app/services/storage.py`)
