Skip to content

Repository files navigation

FieldOps Manager

FieldOps Manager is an offline-first mobile application for field collection management. It was built with Expo, TypeScript and a feature-based architecture to demonstrate local persistence, synchronization queues, typed forms and scalable mobile state management.

The app focuses on a common field operations scenario: drivers or operators need to view assigned collections, complete them in unstable network conditions and let the app synchronize changes later when connectivity is restored.

Highlights

  • Offline-first data flow using expo-sqlite.
  • Hybrid fetching with TanStack Query v5: remote-first when online, SQLite fallback when offline.
  • Persistent synchronization queue for offline updates.
  • Feature-based architecture under src/features/coletas.
  • File-based navigation with Expo Router.
  • UI state isolated with Zustand.
  • Form validation with React Hook Form and Zod.
  • NativeWind styling for a corporate dashboard experience.
  • Strict TypeScript configuration.

Tech Stack

Layer Technology
Framework Expo SDK 55
Language TypeScript strict mode
Navigation Expo Router
Server/cache state TanStack Query v5
UI/session state Zustand
Local database expo-sqlite
Styling NativeWind
Forms React Hook Form
Validation Zod
Native runtime Expo Dev Client

Architecture

src
|-- app
|   |-- _layout.tsx
|   |-- index.tsx
|   `-- coletas
|       `-- [id].tsx
|-- features
|   `-- coletas
|       |-- components
|       |   |-- ColetaCard.tsx
|       |   |-- ColetaListSkeleton.tsx
|       |   |-- FinalizacaoColetaForm.tsx
|       |   `-- StatusBadge.tsx
|       |-- hooks
|       |   |-- useColetas.ts
|       |   `-- useSyncColetas.ts
|       |-- services
|       |   |-- coletasApi.ts
|       |   |-- coletasLocalService.ts
|       |   `-- database.ts
|       |-- store
|       |   `-- coletasStore.ts
|       `-- types
|           `-- coleta.ts
`-- shared
    |-- lib
    |   `-- queryClient.ts
    `-- providers
        `-- AppProviders.tsx

The project keeps business logic inside feature modules. Shared code is limited to app-level providers and infrastructure that can be reused by other features.

Offline-First Flow

  1. useColetas reads the current network state.
  2. When online, it fetches from the mock API and upserts the response into SQLite.
  3. When offline, it reads exclusively from SQLite.
  4. Collection finalization is saved locally first.
  5. If the device is offline or the remote mutation fails, the payload is stored in sync_queue.
  6. useSyncColetas flushes pending queue items when connectivity returns.

Local Database

The SQLite schema is created in src/features/coletas/services/database.ts.

Tables:

  • coletas: local collection records and sync metadata.
  • sync_queue: pending offline mutations waiting to be sent.

The local service in coletasLocalService.ts owns direct SQL operations. Hooks depend on this service instead of talking to SQLite directly, keeping UI and persistence concerns separated.

Screens

  • Dashboard list with metrics, status filters, search, pull-to-refresh and synchronization state.
  • Collection detail screen with a finalization form.
  • Skeleton loading state for perceived performance.
  • Offline queue indicator with manual sync action.

Getting Started

Install dependencies:

npm install

Run TypeScript validation:

npm run typecheck

Start the Expo server:

npm run start

Run the Android development build:

npm run android

Run the web target:

npm run web

Expo Go Note

This project targets Expo SDK 55. During the SDK 55 transition, the Play Store version of Expo Go may still be tied to the previous SDK channel. For the most reliable local workflow, use Expo Dev Client:

npm run android
npm run start

Then open the app through the generated development client instead of the Play Store Expo Go app.

Scripts

Command Description
npm run start Starts the Expo development server.
npm run android Builds/runs the Android development client.
npm run ios Builds/runs the iOS development client.
npm run web Starts the web target.
npm run typecheck Runs tsc --noEmit.

Implementation Notes

  • API calls are mocked in coletasApi.ts to keep the project self-contained.
  • Query invalidation is centralized through coletasQueryKeys.
  • The finalization form uses Zod coercion to convert text input into numeric payloads.
  • The app uses conservative render settings on FlatList for mobile performance.
  • SQL writes are grouped with exclusive transactions where consistency matters.

Next Steps

  • Add authentication and role-based route protection.
  • Persist TanStack Query metadata for richer cold-start behavior.
  • Add conflict resolution using server revision numbers.
  • Add integration tests for the sync queue.
  • Replace the mock API with a real backend adapter.

About

Offline-first mobile app for field collection management, built with Expo, TypeScript, SQLite, TanStack Query and feature-based architecture.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages