Files
mobile-darmasaba/CLAUDE.md
2026-04-20 17:05:40 +08:00

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.lock present). Use bun add / bunx instead of npm install / npx.

Architecture

Routing (Expo Router — file-based)

  • app/index.tsx — Login/splash (public); OTP verification is handled inline via components/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)

  1. Context (providers/) — Auth (token encryption/decryption via CryptoES.AES), Theme (light/dark, persisted to AsyncStorage), and React Query client
  2. Redux Toolkit (lib/store.ts + slices) — Feature-level state for CRUD operations. Slices follow a naming pattern: *Slice.ts for read state, *Update.ts/*Create.ts for mutation state
  3. 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: ErrorBoundaryNotifierWrapperThemeProviderQueryProviderAuthProvider → 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 Textdo not replace it with the custom components/Text.tsx as that pulls in ThemeProviderAsyncStorage, 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.