4.0 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Desa+ is a React Native (Expo) mobile app for village administration — managing announcements, projects, discussions, members, divisions, and documents. Primary platforms are Android and iOS.
Commands
npm run start # Start Expo dev server
npm run android # Run on Android
npm run ios # Run on iOS
npm run lint # Expo lint
npm run test # Jest tests
npm run build:android # Production Android build via EAS (bumps version first)
Run a single test file:
bunx jest path/to/test.tsx --no-coverage
Project uses Bun as the package manager (
bun.lockpresent). Usebun add/bunxinstead ofnpm install/npx.
Architecture
Routing (Expo Router — file-based)
app/index.tsx— Login/splash (public); OTP verification is handled inline viacomponents/auth/viewVerification.tsx(not a separate route)app/(application)/— All authenticated screens; Expo Router enforces auth guard here- Deep-link navigation is handled by
lib/pushToPage.ts, which maps notification payloads to routes
State Management (three layers)
- Context (
providers/) — Auth (token encryption/decryption via CryptoES.AES), Theme (light/dark, persisted to AsyncStorage), and React Query client - Redux Toolkit (
lib/store.ts+ slices) — Feature-level state for CRUD operations. Slices follow a naming pattern:*Slice.tsfor read state,*Update.ts/*Create.tsfor mutation state - TanStack React Query — All server data fetching; configured with 5-min stale time, 24-hour cache retention, 2 retries, and AsyncStorage persistence for offline support
API Layer (lib/api.ts)
Single 773-line file defining 50+ Axios-based endpoints. The Axios instance reads baseURL from Constants.expoConfig.extra.URL_API (set in .env via app.config.js). Authentication uses Bearer tokens in headers. File uploads use FormData with multipart/form-data.
Three separate backend services are integrated:
- REST API (axios) — main business logic
- WhatsApp server — OTP delivery (separate token in
.env) - Firebase — real-time database (
lib/firebaseDatabase.ts) and push notifications (lib/useNotification.ts,lib/registerForPushNotificationsAsync.ts)
Providers Initialization Order
app/_layout.tsx wraps the app in: ErrorBoundary → NotifierWrapper → ThemeProvider → QueryProvider → AuthProvider → navigation stack. Redux store is provided inside app/(application)/_layout.tsx, not at the root.
Error Boundary
components/ErrorBoundary.tsx is a class component (required by React) wrapping the entire app. It uses React Native's built-in Text — do not replace it with the custom components/Text.tsx as that pulls in ThemeProvider → AsyncStorage, which breaks Jest tests.
Tests for ErrorBoundary live in __tests__/ErrorBoundary-test.tsx and use @testing-library/react-native.
Key Conventions
Imports: Use @/ alias (maps to project root, configured in tsconfig.json). Never use relative paths like ../../.
Utility functions: Prefixed with fun_ (e.g., lib/fun_stringToDate.ts, lib/fun_validateName.ts).
Styling: Use theme-aware colors from useTheme() hook. Global StyleSheet definitions live in constants/Styles.ts. Color tokens are in constants/Colors.ts with explicit light/dark variants.
Component structure: Feature-specific subdirectories under components/ (e.g., components/announcement/) typically contain a header component alongside list/card components for that feature.
Environment config: All env vars are declared in .env, exposed through app.config.js extra field, and accessed via Constants.expoConfig.extra.* or the constants/ConstEnv.ts wrapper.
EAS builds: Profiles are development, preview, and production in eas.json. Production builds auto-increment the app version via the bump script.