Composting Platform — Architecture
System Architecture

Composting API (Fastify, Node 20+, PostgreSQL) and Composting mobile app (Expo, React Native). The API exposes REST resources for authentication, farms, measurements, and sync (upload/download). The client uses Expo SQLite while offline and synchronises when the device is back online.
Backend Architecture

Layers: HTTP entry points (controllers, routes), use cases (auth, farms, measurements, sync), Prisma repositories, and an authenticate plugin. Fastify with CORS, JWT, and Zod-backed request typing. Prisma ORM on PostgreSQL. Optional Google Sheets integration for Master tenants.
Mobile Architecture

Expo Router with tab and stack routes: dashboard (index), farms (list and create), measurements (list, create, edit by id), plus role-specific areas (management, admin, master, dev) and user onboarding where applicable. Shared UI: Button, Card, Form, Header, Input, OfflineIndicator, SyncButton, SyncStatus. Redux Toolkit slices: auth, farm, measurement, sync, initialSync (with additional slices for users and leiras where needed). Supporting modules: secure auth (auto-refresh, token validation), SQLite repositories, auto-sync, and an HTTP API client. Sentry is used for error reporting.
Database Model

PostgreSQL schema (labels below are descriptive). User: unique name, password, role USER | ADMIN | MASTER | DEV, optional master link, spreadsheet metadata for Masters. Farm: name, master, optional worksheet id for Sheets. LeiraMeasurement: windrow readings linked to a farm — optional timestamp, leira number, three temperature probes and average, humidity and odor enums, composting phase enum, status DRAFT | PARTIAL | COMPLETE, optional notes and audit fields. GoogleOAuthToken: singleton row storing the Google refresh token used for Sheets/Drive APIs.
API Design

REST groups: authentication (POST /signup, POST /signin, POST /auth/refresh), users, farms CRUD, measurements CRUD, sync (POST /sync/upload, POST /sync/download), Google OAuth URLs/callback, and health (including a DB check endpoint). JSON request and response bodies. Protected routes require Authorization: Bearer <JWT>. Access-token lifetime is environment-specific.
Authentication Flow

Sign-up and sign-in return JWT access and refresh tokens. Tokens live in secure device storage; Redux keeps session state. Axios interceptors attach Bearer tokens and, on 401, call POST /auth/refresh then retry the original request. Fastify JWT verification and role guards (USER, ADMIN, MASTER, DEV hierarchy) protect routes. Optional Google OAuth supports Sheets provisioning for authorised roles.
Deployment Architecture

API: Node 20+, production build entrypoint, prisma migrate deploy, DATABASE_URL and JWT_SECRET, plus optional Google service-account or OAuth variables. Mobile: EAS Build for Android, Sentry releases with source maps. PostgreSQL on Docker Compose locally or a managed provider in production. Observability: Sentry, structured logging, and health endpoints.
Data Sync Flow

Offline-first: writes land in SQLite and are marked for sync. When NetInfo reports connectivity, a sync engine batches uploads with client-generated ids, applies server id mapping from responses, then pulls server deltas and merges them locally. Masters may optionally mirror rows to Google Sheets after the server commit; PostgreSQL remains the system of record.