GeoVault is a privacy-first, zero-backend personal location notebook built with React Native (Expo). All data lives on the user’s device. Google Drive backup is optional and uses the REST API directly from the client — no server involved.
any types)All features must work client-side only. Never suggest server-side components, hosted databases, or third-party APIs with usage fees. Google Drive backup uses the REST API directly from the client with OAuth tokens managed by the native SDK.
app/ # expo-router screens (file-based routing)
(tabs)/ # Bottom tab navigator (Places, Search, Settings)
place/ # Place CRUD screens ([id], new, edit/[id])
src/
db/ # SQLite database layer (database, migrations, repositories, seed)
services/ # Business logic
url-parser.service.ts # Google/Apple Maps URL parsing
export.service.ts # JSON export/import
google-auth.service.ts # Google Sign-In wrapper
google-drive.service.ts # Drive REST API (list, upload, download, delete)
backup.service.ts # Backup orchestration (performBackup, performRestore)
auto-backup.service.ts # Background fetch task registration
stores/ # Zustand state stores
places.store.ts # Places with pagination (PAGE_SIZE=30)
search.store.ts # Search with pagination
settings.store.ts # Theme, auto-backup preferences
backup.store.ts # Google Drive backup state
components/ # Reusable UI components
constants/ # Categories, tags, theme colors
types/ # TypeScript interfaces (place.types, backup.types)
utils/ # Helpers (uuid, date formatting)
PRAGMA user_version (currently v3)getPaginated(limit, offset, filters)Zustand stores are thin caches over SQLite. Places and search use pagination (30 items per page) with infinite scroll. Backup store is the exception — it handles async Google API calls with loading states.
appDataFolder (hidden, app-specific, non-sensitive scope)geovault-backup.json — updated on each backup, old versions pruned (keep 3)expo-background-fetch with user-configurable intervals (Daily/Weekly/Monthly)@expo/vector-icons (Ionicons, MaterialCommunityIcons, etc.) for all icons.Alert.alert() — use custom themed modals instead:
StatusDialog for success/error feedbackConfirmDialog for destructive confirmationsImportDialog for import mode selectionBackupRestoreDialog for restore mode selectionany types. Use unknown for catch blocks, proper interfaces for all data.as assertions. Use type guards (e.g., isValidCategory()) instead.unknown (e.g., catch (_error: unknown)).StatusDialog on failure.Pressable components must have accessibilityRole and accessibilityLabel.accessibilityState where applicable.accessibilityRole="tab".accessibilityLabel.src/constants/theme.ts — use COLORS constant for any style-object colors.tailwind.config.js.ThemeContext.removeClippedSubviews, maxToRenderPerBatch, windowSize, initialNumToRenderPlaceCard) must be wrapped with React.memouseCallback for keyExtractor, renderItem, and event handlers passed to listsnpx expo start # Start dev server (JS only, no native modules)
npx expo run:ios # Build and run on iOS (required for native modules)
npx expo run:android # Build and run on Android (required for native modules)
npx expo prebuild # Generate native projects
npx expo prebuild --clean # Regenerate native projects from scratch
node node_modules/typescript/bin/tsc --noEmit # Type check
npx expo export --platform ios # Test production bundle
Important: Google Sign-In and Background Fetch require development builds (run:android/run:ios). They do NOT work with Expo Go or npx expo start.
src/db/database.ts — SQLite singleton, migrations, all features depend on thissrc/db/places.repository.ts — All place CRUD + FTS5 search + paginationsrc/types/place.types.ts — Core data interfaces + validation helperssrc/types/backup.types.ts — Backup state and Drive file metadata typessrc/services/google-auth.service.ts — Google Sign-In (configure, signIn, getAccessToken)src/services/google-drive.service.ts — Drive REST API (upload, download, list, delete)src/services/backup.service.ts — Backup orchestration (performBackup, performRestore)src/services/auto-backup.service.ts — Background fetch task for auto-backupsrc/services/export.service.ts — JSON export/import + file pickersrc/services/url-parser.service.ts — Google/Apple Maps URL parsingsrc/constants/theme.ts — Centralized colors, spacing, roundness, app versionapp.config.ts — Expo configuration (bundle IDs, permissions, plugins)The app uses these OAuth client IDs (project: GeoVault):
src/services/google-auth.service.tsapp.config.ts as reversed URL schemeOAuth consent screen scope: https://www.googleapis.com/auth/drive.appdata
src/db/migrations.ts and bump version in database.tssrc/db/src/types/app/StatusDialog/ConfirmDialog for user feedback — never Alert.alert()tsc --noEmit to verify zero type errorsnpx expo run:*In development (__DEV__), Settings shows a “DEV TOOLS” section with:
Seed data is in src/db/seed.ts and only runs when manually triggered.