# vigneshpy/moi-app architecture

> Architecture diagram of the GitHub repository vigneshpy/moi-app, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/vigneshpy/moi-app
- Repository: https://github.com/vigneshpy/moi-app

## Overview

#### Purpose and Active Product Boundary
Moi is an offline-first Expo/React Native mobile app for recording gifts (“moi”) for weddings and other functions. The active product stores all user data locally; it has no account, cloud, or required network path. The repository also retains an archived Express/MongoDB API, but the README identifies it as unused in offline mode.

#### Workspace and Entrypoints
The pnpm workspace contains mobile and API applications: `pnpm-workspace.yaml`, `apps/mobile/package.json`, and `apps/api/package.json`. Mobile startup and route composition begin in `apps/mobile/app/_layout.tsx`, with the initial route in `apps/mobile/app/index.tsx`. Expo Router maps the `app/` filesystem into native navigation.

#### Mobile Navigation and User Flows
The tab shell is defined at `apps/mobile/app/(tabs)/_layout.tsx`; primary dashboard, event, gift, and profile surfaces live under `apps/mobile/app/(tabs)/`. Event workflows branch into modal routes for creation, details, and ledger review: `apps/mobile/app/modal/events/AddEvents.tsx`, `apps/mobile/app/modal/events/EventDetails.tsx`, and `apps/mobile/app/modal/events/Ledger.tsx`.

#### Offline Persistence Layer
SQLite is the system of record on-device. Database initialization/schema ownership is concentrated in `apps/mobile/db/index.ts` and `apps/mobile/db/schema.ts`. Domain CRUD and export-oriented data access are separated by entity in `apps/mobile/db/events.ts`, `apps/mobile/db/gifts.ts`, and `apps/mobile/db/export.ts`. This boundary allows UI/state code to operate against local persistence without an API dependency.

#### State, Presentation, and Localization
Zustand stores coordinate event and gift state between screens and the SQLite layer: `apps/mobile/store/eventsStore.ts` and `apps/mobile/store/giftsStore.ts`. Shared visual primitives encode the Tamil wedding design system in `apps/mobile/components/ui/AppText.tsx`, `apps/mobile/components/ui/MangoFrame.tsx`, and `apps/mobile/theme/tokens.ts`. Bilingual English/Tamil resources and i18n setup are in `apps/mobile/i18n/index.ts`, `apps/mobile/i18n/en.json`, and `apps/mobile/i18n/ta.json`.

#### Device Integrations and Runtime
The mobile runtime is Expo SDK 52 / React Native 0.76, configured by `apps/mobile/app.json` and `apps/mobile/package.json`. Local SQLite enables offline use; export uses device-side PDF generation and the native share sheet. Custom font loading is centralized in `apps/mobile/theme/useFonts.ts`; event/gift domain typing and formatting support reside in `apps/mobile/lib/event-types.d.ts` and `apps/mobile/lib/event-utils.ts`.

#### Archived Server Capability
The legacy backend is an Express service with MongoDB-facing connection/model layers: `apps/api/src/index.ts`, `apps/api/src/connection/db.ts`, and `apps/api/src/models/eventModel.ts`. It exposes route/controller paths for authentication, events, gifts, RSVPs, transactions, SMS, and S3 upload, including `apps/api/src/routes/eventRoutes.ts`, `apps/api/src/controllers/sendSMS.ts`, and `apps/api/src/controllers/s3Uploader.ts`. It can run in Docker or be packaged for AWS Lambda via `apps/api/Dockerfile`, `apps/api/src/lambda.ts`, and `apps/api/serverless.yml`, but is outside the current offline mobile data flow.

Main entry points: [`apps/mobile/app/(tabs)/_layout.tsx`](https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/app/(tabs)/_layout.tsx) (Tab navigation), [`apps/api/src/index.ts`](https://github.com/vigneshpy/moi-app/blob/master/apps/api/src/index.ts) (Legacy Express API), [`apps/mobile/app/_layout.tsx`](https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/app/_layout.tsx) (Root router), [`apps/mobile/package.json`](https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/package.json) (Expo mobile runtime)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_mobile["Mobile app"]
  node_mobile_runtime{{"Expo mobile runtime<br/>[package.json]"}}
  node_root_router["Root router<br/>Expo Router layout<br/>[_layout.tsx]"]
  node_initial_route["Initial route<br/>[index.tsx]"]
  node_tab_shell["Tab navigation<br/>route layout<br/>[_layout.tsx]"]
  node_event_modals["Event modal flows<br/>modal routes<br/>[AddEvents.tsx]"]
  node_zustand_state["Event and gift state<br/>Zustand stores<br/>[eventsStore.ts]"]
  node_design_system["Tamil wedding UI<br/>visual primitives<br/>[AppText.tsx]"]
  node_localization["English and Tamil i18n<br/>localization<br/>[index.ts]"]
  node_font_loader["Custom fonts<br/>font runtime<br/>[useFonts.ts]"]
end

subgraph group_data["Offline data"]
  node_sqlite_core[("SQLite schema and initialization<br/>local database<br/>[index.ts]")]
  node_domain_crud["Event and gift CRUD<br/>data access<br/>[events.ts]"]
  node_export_access["Export data access<br/>export query layer<br/>[export.ts]"]
  node_device_export["PDF and native sharing<br/>device integration"]
end

subgraph group_legacy["Archived API"]
  node_api_service{{"Legacy Express API<br/>Express service<br/>[index.ts]"}}
  node_mongo_layer[("MongoDB models<br/>database layer<br/>[db.ts]")]
  node_api_routes["API routes<br/>HTTP routes<br/>[eventRoutes.ts]"]
  node_external_integrations["SMS and S3 upload<br/>external integrations<br/>[sendSMS.ts]"]
  node_api_deployment["Docker and Lambda packaging<br/>deployment targets"]
end

node_workspace["pnpm workspace<br/>monorepo"]

node_workspace -->|"contains"| node_mobile_runtime
node_workspace -->|"contains"| node_api_service
node_mobile_runtime -->|"runs"| node_root_router
node_root_router -->|"starts at"| node_initial_route
node_root_router -->|"composes"| node_tab_shell
node_tab_shell -->|"opens"| node_event_modals
node_root_router -->|"loads"| node_font_loader
node_tab_shell -->|"reads and updates"| node_zustand_state
node_event_modals -->|"reads and updates"| node_zustand_state
node_tab_shell -->|"renders with"| node_design_system
node_tab_shell -->|"localizes with"| node_localization
node_zustand_state -->|"persists through"| node_domain_crud
node_domain_crud -->|"reads and writes"| node_sqlite_core
node_export_access -->|"queries"| node_sqlite_core
node_event_modals -->|"requests ledger export"| node_export_access
node_export_access -->|"supplies export data"| node_device_export
node_api_service -->|"serves"| node_api_routes
node_api_service -->|"uses"| node_mongo_layer
node_api_routes -->|"invokes"| node_external_integrations
node_api_service -->|"packaged for"| node_api_deployment
node_mobile_runtime -.->|"no active dependency"| node_api_service

click node_workspace "https://github.com/vigneshpy/moi-app/blob/master/pnpm-workspace.yaml"
click node_mobile_runtime "https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/package.json"
click node_root_router "https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/app/_layout.tsx"
click node_initial_route "https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/app/index.tsx"
click node_tab_shell "https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/app/(tabs)/_layout.tsx"
click node_event_modals "https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/app/modal/events/AddEvents.tsx"
click node_zustand_state "https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/store/eventsStore.ts"
click node_design_system "https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/components/ui/AppText.tsx"
click node_localization "https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/i18n/index.ts"
click node_font_loader "https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/theme/useFonts.ts"
click node_sqlite_core "https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/db/index.ts"
click node_domain_crud "https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/db/events.ts"
click node_export_access "https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/db/export.ts"
click node_api_service "https://github.com/vigneshpy/moi-app/blob/master/apps/api/src/index.ts"
click node_mongo_layer "https://github.com/vigneshpy/moi-app/blob/master/apps/api/src/connection/db.ts"
click node_api_routes "https://github.com/vigneshpy/moi-app/blob/master/apps/api/src/routes/eventRoutes.ts"
click node_external_integrations "https://github.com/vigneshpy/moi-app/blob/master/apps/api/src/controllers/sendSMS.ts"
click node_api_deployment "https://github.com/vigneshpy/moi-app/blob/master/apps/api/Dockerfile"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_mobile_runtime,node_root_router,node_initial_route,node_tab_shell,node_event_modals,node_zustand_state,node_design_system,node_localization,node_font_loader toneBlue
class node_sqlite_core,node_domain_crud,node_export_access,node_device_export toneAmber
class node_api_service,node_mongo_layer,node_api_routes,node_external_integrations,node_api_deployment toneMint
class node_workspace toneNeutral
```

## Components

### Mobile app

Expo Router offline-first client.

- [Expo mobile runtime](https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/package.json): Expo SDK 52 / React Native · `apps/mobile/package.json`
- [Root router](https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/app/_layout.tsx): Expo Router layout · Bootstraps navigation and route composition. · `apps/mobile/app/_layout.tsx`
- [Initial route](https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/app/index.tsx): route · `apps/mobile/app/index.tsx`
- [Tab navigation](https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/app/(tabs)/_layout.tsx): route layout · Hosts dashboard, event, gift, and profile surfaces. · `apps/mobile/app/(tabs)/_layout.tsx`
- [Event modal flows](https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/app/modal/events/AddEvents.tsx): modal routes · Creation, details, and ledger review workflows. · `apps/mobile/app/modal/events/AddEvents.tsx`
- [Event and gift state](https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/store/eventsStore.ts): Zustand stores · Coordinates state between screens and persistence. · `apps/mobile/store/eventsStore.ts`
- [Tamil wedding UI](https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/components/ui/AppText.tsx): visual primitives · `apps/mobile/components/ui/AppText.tsx`
- [English and Tamil i18n](https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/i18n/index.ts): localization · `apps/mobile/i18n/index.ts`
- [Custom fonts](https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/theme/useFonts.ts): font runtime · `apps/mobile/theme/useFonts.ts`

### Offline data

On-device persistence and export.

- [SQLite schema and initialization](https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/db/index.ts): local database · System of record for all active user data. · `apps/mobile/db/index.ts`
- [Event and gift CRUD](https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/db/events.ts): data access · `apps/mobile/db/events.ts`
- [Export data access](https://github.com/vigneshpy/moi-app/blob/master/apps/mobile/db/export.ts): export query layer · `apps/mobile/db/export.ts`
- **PDF and native sharing**: device integration · Generates exports locally and opens the share sheet.

### Archived API

Retained but outside the active product flow.

- [Legacy Express API](https://github.com/vigneshpy/moi-app/blob/master/apps/api/src/index.ts): Express service · Archived capability; unused by offline mobile mode. · `apps/api/src/index.ts`
- [MongoDB models](https://github.com/vigneshpy/moi-app/blob/master/apps/api/src/connection/db.ts): database layer · `apps/api/src/connection/db.ts`
- [API routes](https://github.com/vigneshpy/moi-app/blob/master/apps/api/src/routes/eventRoutes.ts): HTTP routes · Includes event, gift, RSVP, transaction, and auth paths. · `apps/api/src/routes/eventRoutes.ts`
- [SMS and S3 upload](https://github.com/vigneshpy/moi-app/blob/master/apps/api/src/controllers/sendSMS.ts): external integrations · `apps/api/src/controllers/sendSMS.ts`
- [Docker and Lambda packaging](https://github.com/vigneshpy/moi-app/blob/master/apps/api/Dockerfile): deployment targets · `apps/api/Dockerfile`

### Other components

- [pnpm workspace](https://github.com/vigneshpy/moi-app/blob/master/pnpm-workspace.yaml): monorepo · Contains mobile and archived API applications. · `pnpm-workspace.yaml`

## Connections

- pnpm workspace → Expo mobile runtime: contains
- pnpm workspace → Legacy Express API: contains
- Expo mobile runtime → Root router: runs
- Root router → Initial route: starts at
- Root router → Tab navigation: composes
- Tab navigation → Event modal flows: opens
- Root router → Custom fonts: loads
- Tab navigation → Event and gift state: reads and updates
- Event modal flows → Event and gift state: reads and updates
- Tab navigation → Tamil wedding UI: renders with
- Tab navigation → English and Tamil i18n: localizes with
- Event and gift state → Event and gift CRUD: persists through
- Event and gift CRUD → SQLite schema and initialization: reads and writes
- Export data access → SQLite schema and initialization: queries
- Event modal flows → Export data access: requests ledger export
- Export data access → PDF and native sharing: supplies export data
- Legacy Express API → API routes: serves
- Legacy Express API → MongoDB models: uses
- API routes → SMS and S3 upload: invokes
- Legacy Express API → Docker and Lambda packaging: packaged for
- Expo mobile runtime → Legacy Express API: no active dependency · Offline mode does not call the archived API.
