# wajahat-programmer/field-reports-app architecture

> Architecture diagram of the GitHub repository wajahat-programmer/field-reports-app, 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/wajahat-programmer/field-reports-app
- Repository: https://github.com/wajahat-programmer/field-reports-app

## Overview

Field Reports is an Android React Native app for composing photo reports and delivering them reliably over unreliable connections. The workflow is compose and prepare photos, save a report locally, then have the runner resume and upload it to the server; the home screen presents local delivery state alongside server-confirmed reports. The README documents chunked resumable uploads, retry/backoff, offline recovery, and background keep-alive. Edges are limited to relationships shown in excerpts, the source index, or README; native service wiring beyond the shown references is left out where uncertain.

Main entry points: [`src/core/runner.ts`](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/runner.ts) (Upload runner), [`src/screens/ComposeScreen.tsx`](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/screens/ComposeScreen.tsx) (Compose screen), [`src/app/services.ts`](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/app/services.ts) (Service assembly), [`src/app/hooks.ts`](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/app/hooks.ts) (Screen state hooks)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_compose["Report composition"]
  node_compose_screen["Compose screen<br/>[ComposeScreen.tsx]"]
  node_drafts[("Draft persistence<br/>[draftStore.ts]")]
  node_image_prep["Image preparation<br/>[imagePipeline.ts]"]
end

subgraph group_delivery["Reliable delivery"]
  node_services["Service assembly<br/>[services.ts]"]
  node_runner["Upload runner<br/>[runner.ts]"]
  node_validation["Report validation<br/>[validation.ts]"]
  node_transport["HTTP transport<br/>[httpTransport.ts]"]
  node_upload_protocol["Upload protocol<br/>[uploader.ts]"]
  node_backoff["Retry backoff<br/>[backoff.ts]"]
  node_error_policy["Error policy<br/>[errors.ts]"]
  node_reports_api["Server reports API<br/>[reportsApi.ts]"]
end

subgraph group_device["Device services"]
  node_photo_capture["Photo capture<br/>[photos.ts]"]
  node_camera_access["Camera permission"]
  node_report_store[("Report storage")]
  node_network["Network monitor<br/>[netInfoNetwork.ts]"]
  node_blob_uploader["Chunk transfer<br/>[blobUploader.ts]"]
  node_keepalive["Background keep-alive<br/>[keepAlive.ts]"]
  node_android_service["Android upload service"]
end

subgraph group_presentation["Status and history"]
  node_app["App lifecycle<br/>[App.tsx]"]
  node_home["Home screen<br/>[HomeScreen.tsx]"]
  node_hooks["Screen state hooks<br/>[hooks.ts]"]
  node_status["Delivery summary<br/>[status.ts]"]
  node_list_cache[("Server list cache<br/>[listCache.ts]")]
end

node_person(("Report filer"))
node_backend["Reports server"]
node_server_reports[("Delivered reports")]

node_person -->|"enters report"| node_compose_screen
node_compose_screen -->|"saves draft"| node_drafts
node_compose_screen -->|"checks access"| node_camera_access
node_compose_screen -->|"prepares photo"| node_photo_capture
node_photo_capture -->|"resizes image"| node_image_prep
node_compose_screen -->|"enqueues report"| node_runner
node_app -->|"creates services"| node_services
node_services -->|"constructs"| node_runner
node_services -->|"configures"| node_report_store
node_services -->|"configures"| node_network
node_services -->|"configures"| node_transport
node_runner -->|"validates input"| node_validation
node_runner -->|"persists states"| node_report_store
node_runner -->|"monitors changes"| node_network
node_runner -->|"uploads report"| node_upload_protocol
node_upload_protocol -->|"calls server"| node_transport
node_transport -->|"sends chunks"| node_blob_uploader
node_blob_uploader -->|"transfers bytes"| node_backend
node_transport -->|"sends requests"| node_backend
node_runner -->|"schedules retries"| node_backoff
node_runner -->|"classifies failures"| node_error_policy
node_app -->|"starts and resumes"| node_runner
node_app -->|"shows notification"| node_keepalive
node_keepalive -.->|"starts service"| node_android_service
node_person -->|"views status"| node_home
node_home -->|"reads screen state"| node_hooks
node_hooks -->|"subscribes to events"| node_runner
node_hooks -->|"loads draft"| node_drafts
node_home -->|"summarizes reports"| node_status
node_home -->|"loads server cache"| node_list_cache
node_hooks -->|"fetches report list"| node_reports_api
node_hooks -->|"caches report list"| node_list_cache
node_reports_api -->|"lists reports"| node_backend
node_backend -->|"stores delivered reports"| node_server_reports

click node_compose_screen "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/screens/ComposeScreen.tsx"
click node_drafts "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/app/draftStore.ts"
click node_photo_capture "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/native/photos.ts"
click node_image_prep "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/imagePipeline.ts"
click node_camera_access "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/native/cameraPermission.ts"
click node_app "https://github.com/wajahat-programmer/field-reports-app/blob/main/App.tsx"
click node_services "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/app/services.ts"
click node_runner "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/runner.ts"
click node_validation "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/validation.ts"
click node_report_store "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/native/asyncStorageStore.ts"
click node_network "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/native/netInfoNetwork.ts"
click node_transport "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/httpTransport.ts"
click node_upload_protocol "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/uploader.ts"
click node_blob_uploader "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/native/blobUploader.ts"
click node_backoff "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/backoff.ts"
click node_error_policy "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/errors.ts"
click node_keepalive "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/native/keepAlive.ts"
click node_android_service "https://github.com/wajahat-programmer/field-reports-app/blob/main/android/app/src/main/java/com/fieldreports/UploadKeepAliveService.kt"
click node_home "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/screens/HomeScreen.tsx"
click node_hooks "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/app/hooks.ts"
click node_status "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/app/status.ts"
click node_list_cache "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/app/listCache.ts"
click node_reports_api "https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/reportsApi.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_compose_screen,node_drafts,node_image_prep toneBlue
class node_services,node_runner,node_validation,node_transport,node_upload_protocol,node_backoff,node_error_policy,node_reports_api,node_server_reports toneAmber
class node_photo_capture,node_camera_access,node_report_store,node_network,node_blob_uploader,node_keepalive,node_android_service,node_backend toneMint
class node_app,node_home,node_hooks,node_status,node_list_cache toneRose
class node_person toneIndigo
```

## Components

### Report composition

- [Compose screen](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/screens/ComposeScreen.tsx): `src/screens/ComposeScreen.tsx`
- [Draft persistence](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/app/draftStore.ts): `src/app/draftStore.ts`
- [Image preparation](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/imagePipeline.ts): `src/core/imagePipeline.ts`

### Reliable delivery

- [Service assembly](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/app/services.ts): `src/app/services.ts`
- [Upload runner](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/runner.ts): `src/core/runner.ts`
- [Report validation](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/validation.ts): `src/core/validation.ts`
- [HTTP transport](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/httpTransport.ts): `src/core/httpTransport.ts`
- [Upload protocol](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/uploader.ts): `src/core/uploader.ts`
- [Retry backoff](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/backoff.ts): `src/core/backoff.ts`
- [Error policy](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/errors.ts): `src/core/errors.ts`
- [Server reports API](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/core/reportsApi.ts): `src/core/reportsApi.ts`

### Device services

- [Photo capture](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/native/photos.ts): `src/native/photos.ts`
- [Camera permission](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/native/cameraPermission.ts): `src/native/cameraPermission.ts`
- [Report storage](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/native/asyncStorageStore.ts): `src/native/asyncStorageStore.ts`
- [Network monitor](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/native/netInfoNetwork.ts): `src/native/netInfoNetwork.ts`
- [Chunk transfer](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/native/blobUploader.ts): `src/native/blobUploader.ts`
- [Background keep-alive](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/native/keepAlive.ts): `src/native/keepAlive.ts`
- [Android upload service](https://github.com/wajahat-programmer/field-reports-app/blob/main/android/app/src/main/java/com/fieldreports/UploadKeepAliveService.kt): `android/app/src/main/java/com/fieldreports/UploadKeepAliveService.kt`

### Status and history

- [App lifecycle](https://github.com/wajahat-programmer/field-reports-app/blob/main/App.tsx): `App.tsx`
- [Home screen](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/screens/HomeScreen.tsx): `src/screens/HomeScreen.tsx`
- [Screen state hooks](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/app/hooks.ts): `src/app/hooks.ts`
- [Delivery summary](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/app/status.ts): `src/app/status.ts`
- [Server list cache](https://github.com/wajahat-programmer/field-reports-app/blob/main/src/app/listCache.ts): `src/app/listCache.ts`

### Other components

- **Report filer**
- **Reports server**
- **Delivered reports**

## Connections

- Report filer → Compose screen: enters report
- Compose screen → Draft persistence: saves draft (evidence: `src/screens/ComposeScreen.tsx`)
- Compose screen → Camera permission: checks access (evidence: `src/screens/ComposeScreen.tsx`)
- Compose screen → Photo capture: prepares photo (evidence: `src/screens/ComposeScreen.tsx`)
- Photo capture → Image preparation: resizes image (evidence: `src/native/photos.ts`)
- Compose screen → Upload runner: enqueues report (evidence: `src/screens/ComposeScreen.tsx`)
- App lifecycle → Service assembly: creates services (evidence: `App.tsx`)
- Service assembly → Upload runner: constructs (evidence: `src/app/services.ts`)
- Service assembly → Report storage: configures (evidence: `src/app/services.ts`)
- Service assembly → Network monitor: configures (evidence: `src/app/services.ts`)
- Service assembly → HTTP transport: configures (evidence: `src/app/services.ts`)
- Upload runner → Report validation: validates input (evidence: `src/core/runner.ts`)
- Upload runner → Report storage: persists states (evidence: `src/app/services.ts`)
- Upload runner → Network monitor: monitors changes (evidence: `src/app/services.ts`)
- Upload runner → Upload protocol: uploads report (evidence: `src/core/runner.ts`)
- Upload protocol → HTTP transport: calls server (evidence: `src/core/uploader.ts`)
- HTTP transport → Chunk transfer: sends chunks (evidence: `src/app/services.ts`)
- Chunk transfer → Reports server: transfers bytes (evidence: `README.md`)
- HTTP transport → Reports server: sends requests (evidence: `src/core/httpTransport.ts`)
- Upload runner → Retry backoff: schedules retries (evidence: `src/core/runner.ts`)
- Upload runner → Error policy: classifies failures (evidence: `src/core/runner.ts`)
- App lifecycle → Upload runner: starts and resumes (evidence: `App.tsx`)
- App lifecycle → Background keep-alive: shows notification (evidence: `App.tsx`)
- Background keep-alive → Android upload service: starts service
- Report filer → Home screen: views status (evidence: `src/screens/HomeScreen.tsx`)
- Home screen → Screen state hooks: reads screen state (evidence: `src/screens/HomeScreen.tsx`)
- Screen state hooks → Upload runner: subscribes to events (evidence: `src/app/hooks.ts`)
- Screen state hooks → Draft persistence: loads draft (evidence: `src/app/hooks.ts`)
- Home screen → Delivery summary: summarizes reports (evidence: `src/screens/HomeScreen.tsx`)
- Home screen → Server list cache: loads server cache (evidence: `src/screens/HomeScreen.tsx`)
- Screen state hooks → Server reports API: fetches report list (evidence: `src/app/hooks.ts`)
- Screen state hooks → Server list cache: caches report list (evidence: `src/app/hooks.ts`)
- Server reports API → Reports server: lists reports (evidence: `src/core/reportsApi.ts`)
- Reports server → Delivered reports: stores delivered reports (evidence: `README.md`)
