# Sahakari Management System — Architecture Blueprint

  > "ghar paila 1 tale banauni soche, pachi 10 tale banaye." This document fixes that — it designs a 10-story foundation **upfront**, mapped from the existing **Akash DMS Plus** (Laravel) production system into a modern **NestJS + React** stack.

  ## 1. The legacy system in numbers

  | What | Count |
  |------|------:|
  | Eloquent models (tenant + central) | **183** |
  | Controllers | **153** |
  | Migrations | **378** |
  | Tenant route files | **37** |
  | Production cooperatives | **75 districts** |
  | Customers | **100,000+** |
  | Accounts | **250,000+** |

  The legacy stack: **Laravel 10 + Inertia + React + TypeScript + MySQL + stancl/tenancy + spatie/permission + OnlyOffice + Bacon QR + Nepali Calendar + dompdf + maatwebsite/excel + sanctum + google2fa**. Same business logic, same content, same Nepali workflows are now ported into a modern stack with proper foundations.

  ## 2. Why a new foundation matters

  The legacy app grew organically: every new feature added one more controller, one more route file, one more page directory. Result: 153 controllers with overlapping concerns, repeated DataTable code in every page, no consistent permission UI, no reusable form primitives, mobile UI was an afterthought.

  The new system fixes this at the **foundation** layer. Every feature added later **costs the same effort**, because the primitives are already there.

  ## 3. Stack decisions

  | Layer | Choice | Why |
  |-------|--------|-----|
  | API | **NestJS 11** | Modular, decorator-driven, built-in DI, perfect fit for 50+ domain modules |
  | ORM | **TypeORM 0.3** | Multi-datasource native, runtime tenant DB switching, same entities work on MySQL/Postgres/SQLite |
  | Tenant isolation | **Schema-per-tenant** (path: `/{tenant}/coop/...`) | Same model as legacy; full data isolation |
  | Auth | **JWT + httpOnly cookie + argon2** | Stateless, mobile-friendly, secure |
  | Permissions | **Permission-key based** (`users.create`, `loans.approve`) | Same model as spatie/permission, sidebar/route/button level enforcement |
  | Frontend | **React 19 + Vite 7 + Tailwind v4 + shadcn/ui** | Next.js artifact unavailable on Replit; React+Vite gives equivalent SPA capabilities for an admin product |
  | Routing | **wouter** | Lightweight, no build constraints |
  | Data | **TanStack Query + TanStack Table** | Server-state caching + powerful tables out of the box |
  | Forms | **react-hook-form + zod** | Type-safe, performant |
  | Locale | **Nepali script (देवनागरी) + English** with BS dates | First-class, not retrofitted |
  | Files | **Replit Object Storage** (S3-compatible) | Replaces Laravel local disk; CDN-ready |
  | PDF/Excel | **server-side render (puppeteer + exceljs)** | Same outputs as legacy dompdf/maatwebsite |

  ## 4. Foundation layers (the 10 stories)

  ```
  ┌─────────────────────────────────────────────────────────────────┐
  │  10. Domain modules  (members, loans, auctions, file-manager…) │
  │      ↑ each is a self-contained slice; foundation gives all    │
  │        primitives so a new module is "register + describe"     │
  ├─────────────────────────────────────────────────────────────────┤
  │   9. UX primitives  (PageHeader, DataTable, Form, Drawer,      │
  │      EmptyState, ErrorBoundary, ActionBar, FilterChips)        │
  ├─────────────────────────────────────────────────────────────────┤
  │   8. Domain primitives  (NepaliDatePicker, AddressPicker,      │
  │      MoneyInput, MemberPicker, OfficePicker, FileUpload,       │
  │      RichText, AmountInWords-Nepali)                           │
  ├─────────────────────────────────────────────────────────────────┤
  │   7. Module registry & sidebar grouping  (one source of truth  │
  │      for nav, permissions, breadcrumbs, route guards)          │
  ├─────────────────────────────────────────────────────────────────┤
  │   6. Cross-cutting services  (audit log, lookups,              │
  │      object storage, Nepali date, notifications, exports)      │
  ├─────────────────────────────────────────────────────────────────┤
  │   5. Address master  (Province / District / Local Govt / Ward │
  │      — codes mirror Nepal's 3-char system from the legacy DB) │
  ├─────────────────────────────────────────────────────────────────┤
  │   4. Permission & role engine  (sidebar / route / button-level│
  │      enforcement everywhere)                                  │
  ├─────────────────────────────────────────────────────────────────┤
  │   3. Authentication  (JWT + httpOnly cookie + 2FA-ready)      │
  ├─────────────────────────────────────────────────────────────────┤
  │   2. Multi-tenancy  (schema-per-tenant via TypeORM dynamic     │
  │      data sources + AsyncLocalStorage tenant context)          │
  ├─────────────────────────────────────────────────────────────────┤
  │   1. Database connection management  (driver-agnostic:         │
  │      sql.js → mysql2 → pg, same entities, zero rewrites)       │
  └─────────────────────────────────────────────────────────────────┘
  ```

  Layers 1–9 are **foundation work** (built once). Layer 10 is **domain work** (added incrementally as users need each module).

  ## 5. Conventions every module follows

  Each domain module lives in **two places**:

  ```
  artifacts/api-server/src/modules/<domain>/
    ├─ <domain>.module.ts        ← NestJS module
    ├─ <domain>.controller.ts    ← REST endpoints, @Permissions guard
    ├─ <domain>.service.ts       ← business logic, audit log
    ├─ <domain>.repository.ts    ← TypeORM queries
    ├─ entities/<entity>.ts      ← TypeORM entity
    ├─ dto/                      ← class-validator DTOs
    └─ permissions.ts            ← module's permission keys

  artifacts/web/src/modules/<domain>/
    ├─ index.ts                  ← module manifest (label, icon, group, routes, permissions)
    ├─ pages/                    ← page components
    ├─ components/               ← module-specific UI
    ├─ hooks/                    ← module-specific TanStack Query hooks
    └─ types.ts                  ← shared types
  ```

  The module manifest is the **single source of truth** for the sidebar, breadcrumbs, route guards, and permission menu. Add a module → it appears in the sidebar with its icon, group, and access control automatically.

  ## 6. The new sidebar groups (mapped from legacy)

  | Group | Modules (Phase) |
  |-------|------------------|
  | **Workspace** | Dashboard (1), Notices, Tasks (2), CRM Leads (3) |
  | **Members** | Members (1), Pre-members (2), Member Documents (2), Member Import (3) |
  | **Loans** | Applications (2), Collaterals (2), Credit Analysis (3), Recommendation (3), Disbursement (3), Renewals (3), Auctions (4), Blacklist (4) |
  | **Office Records** | Darta Chalani (2), Letters & Templates (3), Minute Book (3), Taketa Patra (4) |
  | **File Manager** | Files & Folders (3), Shared (3), Trash (3) |
  | **Reports** | Member Reports (3), Loan Reports (3), Office Reports (3), Export Logs (3) |
  | **Master Data** | Offices (1), Branches (2), Departments (2), Loan Purposes/Titles (2), Insurance (2), Surveyors/Valuators (3), Newspapers (3) |
  | **Settings** | Roles & Permissions (1), Users (1), Site Config (2), SMS/Email (2), Document Types (2), Address Tree (2) |

  Phase numbers indicate when each module ships. **Phase 0 (done)** = Auth + Tenant + User/Role/Office.

  ## 7. Phased delivery

  | Phase | Goal | Key deliverable |
  |-------|------|------------------|
  | **0** ✅ | Auth, multi-tenancy, user/role/office CRUD | Demo tenant, 16 working endpoints |
  | **1** ⬅ now | Foundation primitives + Members module | DataTable, PageHeader, NepaliDatePicker, Members CRUD with full KYC |
  | **2** | Loan Applications + Office Records | Application wizard, Darta Chalani, Master data CRUD |
  | **3** | Credit workflow + File Manager + Reports | Forwarding, recommendations, reports, drive-like file UI |
  | **4** | Auctions, Blacklist, Letter Automation, Document Editor | OnlyOffice/Syncfusion integration, letter templates |
  | **5** | Online Member Portal + Mobile (Expo) | Member-facing app with loan apply, statements |

  ## 8. Migration path from legacy

  When a tenant is ready to switch, one-time migration scripts will:
  1. Read the legacy MySQL tenant DB
  2. Map legacy tables → new entities (1:1 for shared concepts; flatten/normalize where over-engineered in legacy)
  3. Stream-write into the new schema preserving `legacy_id` for cross-reference
  4. Run integrity checks
  5. Cut over with downtime ≤ 30 min per tenant

  Legacy tables we **deliberately drop or merge** (and why) will be listed in `docs/MIGRATION_NOTES.md` as we port each module.

  ## 9. Mobile & accessibility from day one

  - **Sidebar** collapses to a sheet (top hamburger) below `md` breakpoint.
  - **DataTable** swaps to card-stack layout below `sm`.
  - **Forms** use native input types where possible for mobile keyboard.
  - All dialogs are **focus-trapped** and keyboard-navigable.
  - Color contrast ≥ WCAG AA.
  - Future: Expo (React Native) artifact reuses the same API and design tokens.
  