React Native (Expo) app for offline-first asset mapping with Mapbox integration.
# Install dependencies
npm install
# Configure environment
# The backend API URL is configured in-app via the Download tab
# Start development server
npm start
# Run on iOS
npx expo run:ios
# Run on Android
npx expo run:android- Node.js 18+
- Backend server running (see Backend Setup)
- iOS Simulator or Android Emulator
- Expo CLI (
npm install -g expo-cli)
- 📍 Pin-based asset mapping with Mapbox
- 📝 Dynamic forms with field validation
- 🔄 Offline-first with background sync
- 📦 Offline map pack downloads
- 🗃️ Dual database: SQLite (local) + PostgreSQL (via Backend API)
- 🔐 Idempotent sync operations via backend
- 📊 Event streaming and audit logging
- React Native + Expo Router
- TypeScript (strict mode)
- Mapbox for maps
- Drizzle ORM for type-safe database
- Backend API for sync operations (Express.js)
- Supabase for database (via backend)
- React Query for API state
├── app/ # Expo Router screens
├── apis/ # Backend API clients
├── db/schema/ # Database schemas (SQLite + PostgreSQL)
├── features/ # Feature-specific logic
├── services/ # Business logic & repositories
├── shared/ # Shared utilities, types, components
├── hooks/ # Custom React hooks
├── providers/ # React context providers
└── docs/ # Documentation
npm test # Run all tests
npm test -- --watch # Watch mode
npm test -- --coverage # With coveragenpm run db:generate # Generate migrations
npm run db:push # Apply migrations
npm run db:studio # Open database browsernpm run db:pg:generate # Generate migrations
npm run db:pg:push # Apply migrations to Supabase
npm run db:pg:pull # Pull schema from Supabase
npm run db:pg:studio # Open Supabase browserCreate .env file:
# Required
EXPO_PUBLIC_MAPBOX_KEY=your_mapbox_token
# Optional - Backend API URL is configured in-app
# SUPABASE_DB_URL=postgresql://user:pass@host:6543/databaseGet Mapbox token: https://account.mapbox.com/access-tokens/
Get Supabase URL: Dashboard → Settings → Database → Connection string (Transaction mode)
- DRY - No code duplication, extract to
shared/utils/ - Type Safe - Strict TypeScript, no
any - Minimal - Less code is better code
- Tested - Utilities have 100% coverage
- Documented - JSDoc on all utilities
See Code Quality Guidelines for details.
- Local-first: All operations on SQLite first
- Background sync: Queue-based sync to Supabase
- Conflict resolution: Last-write-wins with timestamps
- Retry logic: Exponential backoff for failures
- SQLite (local): Full schema with sync metadata
- PostgreSQL (Supabase): Core tables only, no local-only fields
- Drizzle ORM: Single source of truth for schemas
- Type safety: Auto-generated types from schema
BaseLocalRepository- Shared local DB operationsBaseRemoteRepository- Shared remote API operations- Entity-specific repos extend bases
- Consistent CRUD interface
- Read Code Quality Guidelines
- Check Next Tasks for current work
- Follow the checklist before committing:
- No duplicated code
- All types explicit
- Functions < 50 lines
- Utilities documented & tested
- Tests passing
[Add license information]
[Add support information]