Business / Field Data Application
Field Capture
An offline-first field data capture application for logging material deliveries, ticket photos, supplier records, and idempotent PostgreSQL synchronization.
- Project type
- Offline-First Field Data Capture & Sync Application
- Status
- Public Repository & Functional Prototype
- Built with
- React Native / Mobile, TypeScript, SQLite (Local Persistence), Node.js & Express
1600 × 1000
Field Capture
Overview
About Field Capture
Context
Based directly on the Field-Capture repository architecture, FieldCapture was engineered to solve a critical reliability problem in field operations: capturing material deliveries (rebar, structural steel, ready-mix concrete, lumber) in deep excavations, basements, or remote job sites where cellular connectivity drops to zero.
The problem
Standard cloud-only forms fail when field workers lose signal mid-submission, leading to lost delivery ticket photos, missing purchase order logs, or duplicate database records when workers repeatedly tap "Submit" on flaky networks.
The solution
We built an offline-first architecture where the local SQLite database is the single source of truth on the device. Every delivery record and physical ticket photo is written to local storage first, queued with a cryptographic UUIDv4 `idempotencyKey`, and transmitted by an automatic Sync Manager to a Node.js + Express + TypeScript API and PostgreSQL database (`UNIQUE(idempotency_key)`) once connectivity returns.
Field Capture (FieldCapture) is an offline-first field data capture application engineered for construction job sites and field environments with intermittent or zero cellular connectivity. It enables field personnel and foremen to photograph physical delivery tickets, enter supplier and purchase order data, log delivery notes, and persist everything locally in SQLite and sandboxed storage before automatically syncing to a Node.js + Express + TypeScript backend and PostgreSQL database with UUIDv4 idempotency protection.
Features
What it does
- 01
Local SQLite Source of Truth & Sandboxed Photo Storage
Writes supplier, PO, and delivery notes to local SQLite and copies ticket photos into persistent application storage so records render reliably even in airplane mode.
- 02
Automatic Connectivity Sync Manager
Listens for network restoration and transitions records through explicit states (`QUEUED`, `UPLOADING`, `SYNCED`, `FAILED`) with multipart upload of photos and metadata.
- 03
Interrupted Upload & App-Restart Recovery
If the app is terminated while a record is in the `UPLOADING` state, initialization automatically recovers the record back to `QUEUED` with an audit note so no delivery is stranded.
- 04
End-to-End Idempotency & Deduplication
Combines UI submission throttling, client-generated UUIDv4 `idempotencyKey` values, and a PostgreSQL `UNIQUE(idempotency_key)` constraint so network retries return the existing record instead of creating duplicates.
- 05
Interactive Resilience Testing Suite
Includes built-in developer controls to toggle Forced Offline Mode, Forced Online Mode, Simulated HTTP 500 Outages, and App-Restart Crash Recovery during live evaluations.
How it works
Architecture and workflow
Mobile client with local SQLite persistence and connectivity-driven Sync Manager communicating via multipart POST requests to a Node.js + Express + TypeScript backend, Vercel Blob photo storage, and a PostgreSQL database.
- 01
On-Site Ticket Capture (Offline or Online)
The foreman photographs the physical delivery ticket, logs supplier and PO details, and saves the record immediately to local SQLite with status QUEUED.
- 02
Network Detection & Queue Dispatch
When connectivity is available, the Sync Manager transitions queued items to UPLOADING and sends a multipart payload containing the UUIDv4 idempotencyKey.
- 03
Idempotent Backend Persistence
The Node.js/Express API stores the ticket photo in Vercel Blob and inserts the delivery into PostgreSQL, enforcing UNIQUE(idempotency_key) to prevent duplicates.
- 04
Sync Confirmation or Retry Diagnostics
Confirmed records transition to SYNCED; if a network drop or 500 outage occurs, the record is marked FAILED with diagnostic details and one-tap retry.
Technology
Tools used
Client & Offline Persistence
- Mobile Client UI
- Local SQLite Database
- Sandboxed Local File URIs
- Offline Sync Manager
Backend API Service
- Node.js
- Express.js
- TypeScript
- Multipart Upload Pipeline
Cloud Storage & Database
- PostgreSQL (UNIQUE idempotency_key)
- Vercel Blob (Delivery Ticket Images)
Challenges
Problems we solved along the way
- Challenge 01
Preventing duplicate delivery logs when field connections drop after the server receives a request but before the client receives the HTTP 200 response
Resolution: Generated a UUIDv4 idempotencyKey on the client at creation time and enforced a UNIQUE constraint in PostgreSQL so repeat transmissions safely resolve to the original record.
- Challenge 02
Handling app crashes or OS kills mid-upload
Resolution: Implemented a startup recovery routine that inspects any record stuck in UPLOADING state and resets it to QUEUED with an audit log.
Start a project
Want something like Field Capture? Let’s talk.
Share a few details and get a clear scope and a written quote. No obligation.
- Free consultation
- Written quote
- Reply within 1 business day