# UI/UX Library — Parallel Agent Orchestration

**Project:** AGNET Uzbekistan Platform  
**Version:** 1.0.0  
**Created:** 2026-06-27  
**Status:** Ready to execute  
**Parent spec:** [`UI_UX_LIBRARY_PLAN.md`](./UI_UX_LIBRARY_PLAN.md)  
**Sync pattern:** [`P2P3_ARCHITECTURE_DB_SYNC.md`](./P2P3_ARCHITECTURE_DB_SYNC.md)

---

## 1. Goal

Execute the 6-phase UI/UX library rollout using **parallel Cursor agents** with **contract-first sync** across:

| Layer | Repo / path |
|-------|-------------|
| **DB + seed** | `mpgis-farmer-platform` — Prisma models, migrations, `db:seed` |
| **Core API** | `mpgis-farmer-platform/services/core-api` — `GET /farmer/dashboard` enrich |
| **BFF + types** | `Agnet` — `lib/api-types.ts`, `app/api/farmer/dashboard/route.ts` |
| **Dev mock** | `Agnet/lib/dev-api-mock.ts` — mockup-faithful fixtures |
| **View models** | `Agnet/lib/farmer-dashboard.ts` — `mapDashboardResponse()` |
| **UI library** | `Agnet/components/ui/`, `components/agnet/` |
| **i18n** | `Agnet/lib/i18n/dashboard-labels.ts` |
| **E2E** | `Agnet/e2e/tests/farmer-dashboard.spec.ts`, `tests/contract/` |

**Design authority:** Mockup-derived tokens in `UI_UX_LIBRARY_PLAN.md` §4 supersede auto-generated `ui-ux-pro-max` output. Use `@ui-ux-pro-max` for UX checklist and stack guidance only.

---

## 2. Skill routing (via `@skill-router`)

| Agent role | Primary skill | Secondary skills |
|------------|---------------|------------------|
| **G0 — Contract gatekeeper** | `@senior-architect` | `@api-patterns`, `@prisma-expert` |
| **A — Design tokens + primitives** | `@ui-ux-pro-max` | `@frontend-design` |
| **B — Layout shell** | `@frontend-design` | `@ui-ux-pro-max` |
| **C — Identity dashboard** | `@senior-fullstack` | `@ui-ux-pro-max` |
| **D — Finance dashboard** | `@senior-fullstack` | `@ui-ux-pro-max` |
| **E — Inputs dashboard** | `@senior-fullstack` | `@ui-ux-pro-max` |
| **F — Backend + DB + seed** | `@backend-dev-guidelines` | `@prisma-expert`, `@database-design` |
| **G — i18n + QA + integration** | `@playwright-skill` | `@test-fixing` |

**Fully autonomous wave (optional):** After G0 merges, launch C + D + E + F in parallel via `@dispatching-parallel-agents` or `@subagent-driven-development`.

---

## 3. Contract-first sync model

All parallel agents **must** converge on a single contract before module UI work begins.

```mermaid
flowchart LR
  subgraph Wave0["Wave 0 — G0 only"]
    OAS["OpenAPI / api-types.ts"]
    VM["ViewModel interfaces"]
    FIX["dashboard-fixtures.json"]
    SEED["Prisma + seed plan"]
  end

  subgraph Wave1["Wave 1 — parallel after G0 merge"]
    F["Agent F: core-api + DB"]
    A["Agent A: tokens + ui/"]
    B["Agent B: layout shell"]
  end

  subgraph Wave2["Wave 2 — parallel after A+B merge"]
    C["Agent C: Identity"]
    D["Agent D: Finance"]
    E["Agent E: Inputs"]
    MOCK["dev-api-mock extensions"]
  end

  subgraph Wave3["Wave 3 — G0 integration"]
    G["Agent G: i18n + E2E + axe"]
  end

  OAS --> F
  OAS --> MOCK
  VM --> C
  VM --> D
  VM --> E
  FIX --> MOCK
  SEED --> F
  A --> B
  B --> C
  B --> D
  B --> E
  F --> G
  C --> G
  D --> G
  E --> G
```

### 3.1 Single source of truth files (G0 deliverables)

| File | Purpose |
|------|---------|
| `specs/contracts/dashboard-v2.openapi.yaml` | Canonical API shape for all new fields |
| `lib/api-types.ts` | TypeScript mirror of OpenAPI |
| `lib/farmer-dashboard.ts` | ViewModel interfaces + `mapDashboardResponse()` |
| `lib/fixtures/dashboard-mockup-personas.ts` | Shared fixture data (Ramesh / Islomjon / Burkina personas) |
| `lib/e2e/api-flow-registry.ts` | Add F16–F18 dashboard module flows |
| `mpgis-farmer-platform/prisma/schema.prisma` | New columns / JSON fields (see §5) |

**Rule:** No agent edits view models or API types independently. G0 opens the PR; module agents only consume.

---

## 4. DB ↔ API ↔ UI sync matrix (dashboard v2)

Extend `DB_API_SYNC_MATRIX` in `lib/e2e/api-flow-registry.ts`:

| DB (core-api) | API `FarmerDashboardResponse` | ViewModel | UI component |
|---------------|------------------------------|-----------|--------------|
| `FarmerProfile.publicFarmerId` | `identity.farmerId` | `identity.farmerId` | `FarmProfileCard` |
| `FarmerProfile.displayName` | `identity.farmName` | `identity.farmName` | `FarmProfileCard` |
| `KycRecord.photoUrl` | `identity.ekyc.photoUrl` | `identity.ekyc.photoUrl` | `EkycCard` |
| `KycRecord.dob` | `identity.ekyc.dob` | `identity.ekyc.dob` | `EkycCard` |
| `KycRecord.pinflMasked` | `identity.ekyc.aadhaarMasked` | `identity.ekyc.aadhaarMasked` | `EkycCard` |
| `User.phone` (masked) | `identity.ekyc.mobileMasked` | `identity.ekyc.mobileMasked` | `EkycCard` |
| `LandParcel.geometry` (GeoJSON) | `identity.gis.polygonGeoJson` | `identity.gis` | `GisMapCard` |
| `LandParcel.areaHa` | `identity.gis.areaHa` | `identity.gis.areaHa` | `GisMapCard` |
| `LandParcel.centroid` | `identity.gis.lat/lng` | `identity.gis` | `GisMapCard` |
| `Document[]` (land evidence) | `identity.landEvidence[]` | `identity.landEvidence` | `LandEvidenceList` |
| `YieldHistory` (new table or JSON) | `identity.yieldHistory[]` | `identity.yieldHistory` | `YieldHistoryChart` |
| `EligibilityRuleResult[]` | `identity.compliance[]` | `identity.compliance` | `ComplianceChecklist` |
| `ScoringRun.totalScore` (normalized /100) | `finance.eligibilityScore` | `finance.eligibilityScore` | `EligibilityGauge` |
| `FinanceCase.routedInstitution` | `finance.routedInstitution` | `finance.routedInstitution` | `CaseHeaderMetrics` |
| `FinanceCase.slaDueAt` | `finance.sla` | `finance.sla` | `CaseHeaderMetrics` |
| `InstitutionMatch[]` | `finance.bankMatches[]` | `finance.bankMatches` | `BankRoutingList` |
| `Document[]` (finance) | `finance.documents[]` | `finance.documents` | `DocumentChecklist` |
| `FinanceCase.statusHistory` | `finance.stages[]` | `finance.stages` | `ApprovalPathStepper` |
| `CatalogAggregate` (view) | `inputs.kpis` | `inputs.kpis` | `InputsKpiRow` |
| `Supplier.rating` | `inputs.suppliers[]` | `inputs.suppliers` | `SupplierRatingList` |
| `ProductCatalog` | `inputs.catalog[]` | `inputs.catalog` | `FeaturedCatalogTabs` |
| `InputVoucher` | `inputs.voucher` | `inputs.voucher` | `VoucherCard` |
| `DeliveryShipment` | `inputs.delivery` | `inputs.delivery` | `DeliveryTrackingStepper` |

---

## 5. Seed data strategy

### 5.1 Dev personas (`lib/fixtures/dashboard-mockup-personas.ts`)

| Persona | `userId` suffix | Module emphasis | Mockup reference |
|---------|-----------------|-----------------|------------------|
| `islomjon` | `…001` | Identity — GIS + eKYC | `agnet-identity-dashboard.png` |
| `agrobank-case` | `…002` | Finance — 78/100, Agrobank | `agnet-finance-dashboard.png` |
| `burkina-inputs` | `…003` | Inputs — catalog + voucher | `agnet-inputs-dashboard.png` |

G0 creates this file. Agents F and MOCK import it — **never duplicate fixture literals**.

### 5.2 Core-api seed (`mpgis-farmer-platform`)

Add to `prisma/seed.ts` (or `seed/dashboard-demo.ts`):

```typescript
// Pseudocode — G0/F implement
await seedDashboardPersona("islomjon", {
  farmerProfile: { publicFarmerId: "AGID-FMR-00142", displayName: "Islomjon Abdullaev" },
  landParcel: { areaHa: 4.52, geometry: MOCK_POLYGON_TASHKENT },
  kyc: { photoUrl: "/agnet-assets/demo-ekyc.jpg", status: "verified" },
  yieldHistory: [{ year: 2020, yieldTHa: 3.2, crop: "cotton" }, /* … */ ],
  compliance: [{ key: "gis", passed: true }, /* 6 items */ ],
});
```

**Sync rule:** Seed values must match `dashboard-mockup-personas.ts` field-for-field. CI contract test compares mock response ↔ seed query.

### 5.3 Agnet dev mock

`handleDevFarmerDashboard()` maps `userId` → persona fixture when `CORE_API_USE_MOCK=true`. Extends existing session-derived logic; persona override applies when `userId` matches demo accounts.

---

## 6. Parallel agent definitions

### Wave 0 — G0: Contract gatekeeper (blocks all others)

**Duration:** 2–3 days  
**Branch:** `feat/ui-g0-dashboard-contract`  
**Must merge before:** A, B, C, D, E, F

```
@senior-architect @api-patterns

## Mission
Open the dashboard v2 contract PR. No UI components. Define types, fixtures, seed plan, and sync matrix so parallel agents cannot drift.

## Repos
- BFF: /Users/sohansoni/MPGIS/Agnet
- Backend: /Users/sohansoni/MPGIS/mpgis-farmer-platform

## Deliverables
1. `specs/contracts/dashboard-v2.openapi.yaml` — IdentityModule, FinanceModule, InputsModule extensions per UI_UX_LIBRARY_PLAN.md §8
2. Update `lib/api-types.ts` + `lib/farmer-dashboard.ts` interfaces (fields only; mapper stubs OK)
3. Create `lib/fixtures/dashboard-mockup-personas.ts` with 3 personas matching PNG mockups
4. Extend `lib/e2e/api-flow-registry.ts`: F16 identity enrich, F17 finance enrich, F18 inputs enrich
5. Document Prisma delta in `specs/contracts/dashboard-v2-db-delta.md` (tables/columns for F)
6. Add failing contract tests in `tests/contract/dashboard-v2.test.ts` (assert fixture shape)

## Constraints
- Mockup tokens from UI_UX_LIBRARY_PLAN.md §4 — NOT ui-ux-pro-max auto palette
- Surgical diff — no component work
- Seed field names must match api-types exactly

## Exit criteria
- [ ] Contract PR merged
- [ ] `npm run test:contract` includes dashboard-v2 tests (may fail until F/MOCK land)
- [ ] F, A, B, C, D, E agents can branch from main without type conflicts
```

---

### Wave 1 — Agent A: Design tokens + UI primitives

**Duration:** 5–7 days | **Deps:** G0 merged | **Branch:** `feat/ui-001-primitives`

```
@ui-ux-pro-max @frontend-design

## Mission
Phase 1 (UI-001a–f): Canonical design tokens + `components/ui/*` primitives.

## Reference
- Tokens: specs/UI_UX_LIBRARY_PLAN.md §4 (NOT auto-generated fintech palette)
- Mockups: public/agnet-assets/agnet-*-dashboard.png

## Deliverables
1. Rewrite design-system/agnet-dashboard/MASTER.md + pages/identity|finance|inputs.md
2. Extend tailwind.config.ts (sidebar-bg, success-green, radius-card 12px)
3. components/ui/: Card, Badge, KpiCard, ProgressRing, Stepper, StatusBanner, DataRow, Tabs, Avatar
4. components/ui/chart/: bar-chart.tsx, chart-container.tsx (recharts)
5. Unit tests: Stepper states, Badge variants, ProgressRing aria

## ui-ux-pro-max checklist (§11)
- Lucide icons only, 44px touch targets, focus:ring-2 ring-green-deep
- prefers-reduced-motion on animations
- cursor-pointer on interactive elements

## Exit criteria
- [ ] All primitives render in isolation (Storybook optional)
- [ ] axe scan on primitives page: 0 critical
- [ ] No imports from components/farmer/ (primitives are leaf nodes)
```

---

### Wave 1 — Agent B: Layout shell

**Duration:** 5 days | **Deps:** G0 + A (ui primitives) | **Branch:** `feat/ui-002-layout`

```
@frontend-design @ui-ux-pro-max

## Mission
Phase 2 (UI-002a–e): Dashboard chrome — sidebar, header, page layout.

## Deliverables
1. components/agnet/layout/DashboardSidebar.tsx — #004D40 rail, Lucide nav
2. components/agnet/layout/DashboardHeader.tsx — title, GIS Verified slot
3. components/agnet/layout/DashboardPageLayout.tsx — sidebar + header + main
4. Refactor FarmerDashboardShell.tsx to compose new layout (keep mobile bottom nav)
5. Update e2e/tests/farmer-dashboard.spec.ts selectors

## Responsive (§7)
- ≥1280px: fixed rail
- 768–1279px: collapsed icons
- <768px: bottom tab bar (existing pattern)

## Exit criteria
- [ ] All 4 module routes render in new shell
- [ ] E2E farmer-dashboard.spec.ts passes
- [ ] No module content changes yet (shell only)
```

---

### Wave 1 — Agent F: Backend + DB + seed

**Duration:** 7–10 days | **Deps:** G0 merged | **Branch:** `feat/core-dashboard-v2` (mpgis-farmer-platform)

```
@backend-dev-guidelines @prisma-expert

## Mission
Implement dashboard v2 data layer in core-api. Stay byte-synced with specs/contracts/dashboard-v2.openapi.yaml.

## Deliverables
1. Prisma migration: FarmerProfile.publicFarmerId, KycRecord.photoUrl, LandParcel.geometry JSON, YieldHistory table, FinanceCase.slaDueAt, InstitutionMatch, InputVoucher, DeliveryShipment (per dashboard-v2-db-delta.md)
2. GET /farmer/dashboard enrich — map DB → OpenAPI shape
3. seed/dashboard-demo.ts — 3 personas from Agnet lib/fixtures/dashboard-mockup-personas.ts
4. core-api unit tests for dashboard mapper

## Sync rules
- Import persona field values from shared doc (copy verbatim from Agnet fixture file)
- Prisma: both relation sides, createdAt/updatedAt, @@index on queried fields
- Never return unmasked PII — use masked fields only

## Exit criteria
- [ ] prisma migrate deploy + db:seed succeeds
- [ ] GET /farmer/dashboard returns persona payloads for seed users
- [ ] Agnet contract tests pass against live core-api (CORE_API_USE_MOCK=false)
```

---

### Wave 2 — Agents C, D, E (parallel module rebuilds)

**Deps:** A + B merged; G0 fixtures available; F or dev-mock ready  
**Can run in parallel:** C ‖ D ‖ E

#### Agent C — Identity dashboard

**Branch:** `feat/ui-003-identity`

```
@senior-fullstack @ui-ux-pro-max

## Mission
Phase 3: Match agnet-identity-dashboard.png

## Deliverables
1. components/agnet/identity/* (GisMapCard, EkycCard, FarmProfileCard, LandEvidenceList, YieldHistoryChart, ComplianceChecklist)
2. Rewrite IdentityModule.tsx as composition
3. Wire mapDashboardResponse() for identity fields
4. i18n keys in dashboard-labels.ts (identity.*)
5. dev-api-mock: persona islomjon identity block (import from fixtures)

## Data
- Consume IdentityViewModel only — no direct API calls in components
- GIS v1: static map + SVG polygon; MapLibre deferred

## Exit criteria
- [ ] ≥90% layout match vs PNG
- [ ] E2E /farmers/dashboard/identity passes
```

#### Agent D — Finance dashboard

**Branch:** `feat/ui-004-finance`

```
@senior-fullstack @ui-ux-pro-max

## Mission
Phase 4: Match agnet-finance-dashboard.png

## Deliverables
1. components/agnet/finance/* (CaseHeaderMetrics, EligibilityGauge, BankRoutingList, DocumentChecklist, ApprovalPathStepper)
2. Refactor CreditScoreArc → ProgressRing usage in EligibilityGauge
3. Rewrite FinanceModule.tsx
4. i18n finance.* keys
5. dev-api-mock: agrobank-case persona

## Exit criteria
- [ ] Stepper reflects finance.stages[]
- [ ] Gauge shows eligibilityScore/100
- [ ] E2E finance route passes
```

#### Agent E — Inputs dashboard

**Branch:** `feat/ui-005-inputs`

```
@senior-fullstack @ui-ux-pro-max

## Mission
Phase 5: Match agnet-inputs-dashboard.png

## Deliverables
1. components/agnet/inputs/* (InputsKpiRow, SupplierRatingList, FeaturedCatalogTabs, VoucherCard, PaymentRouteStepper, DeliveryTrackingStepper)
2. Rewrite InputsModule.tsx
3. dev-api-mock: burkina-inputs persona (full catalog/voucher/delivery)
4. i18n inputs.* keys

## Note
If F not ready, ship UI with mock-only data. Contract fields must still match G0 types.

## Exit criteria
- [ ] 5 KPI cards + tabs + steppers render with mock data
- [ ] E2E inputs route passes
```

---

### Wave 3 — Agent G: Integration + i18n + QA

**Duration:** 7–10 days | **Deps:** C + D + E + F merged | **Branch:** `feat/ui-006-integration`

```
@playwright-skill @test-fixing

## Mission
Phase 6: Production-ready library — real API wiring, full i18n, accessibility, docs.

## Deliverables
1. Replace mock fixtures with live core-api where F is deployed
2. Complete uz/ru/en for identity, finance, inputs modules
3. axe-core E2E on all dashboard routes
4. npm run test:contract + test:e2e:api — refresh reports/e2e-api-flow-latest.md
5. docs/ui-library.md — component usage examples
6. Performance spot-check: LCP < 2.5s on 3G throttling

## Exit criteria
- [ ] All E2E green (UI + API)
- [ ] 0 critical axe violations
- [ ] i18n coverage 100% for module strings
- [ ] UI_UX_LIBRARY_PLAN.md §11 checklist complete
```

---

## 7. Sync gates (merge order)

| Gate | Condition | Owner |
|------|-----------|-------|
| **G0** | Contract PR merged to `main` | Human review + contract tests |
| **G1** | A + B merged (primitives + shell) | Visual review vs mockup sidebar |
| **G2** | F merged OR dev-mock personas complete | `test:contract` dashboard-v2 green |
| **G3** | C merged | Side-by-side identity PNG review ≥90% |
| **G4** | D + E merged | Finance + Inputs PNG review |
| **G5** | G complete | Full regression + i18n audit |

**Critical:** Do **not** merge C/D/E before G1. Do **not** merge G before at least mock data satisfies contract tests.

---

## 8. Daily sync protocol (parallel agents)

1. **Contract freeze:** After G0 merge, no agent adds fields without a G0 follow-up PR.
2. **Fixture single source:** All agents import `lib/fixtures/dashboard-mockup-personas.ts`.
3. **Type check:** `npm run typecheck` on Agnet before each PR.
4. **Cross-repo smoke:** `CORE_API_USE_MOCK=false npm run test:contract` when F has a branch ready.
5. **Selector coordination:** Only Agent B touches `data-testid` nav attributes; C/D/E consume them.
6. **i18n namespace:** C → `identity.*`, D → `finance.*`, E → `inputs.*`; G translates uz/ru.

---

## 9. Launch commands

### Sequential (safe default)

```bash
# 1. G0 contract (human kicks off)
# Paste G0 prompt → merge feat/ui-g0-dashboard-contract

# 2. Wave 1 parallel (3 agents)
# Agent A: feat/ui-001-primitives
# Agent B: feat/ui-002-layout (after A or rebase on A)
# Agent F: feat/core-dashboard-v2 (mpgis-farmer-platform)

# 3. Wave 2 parallel (3 agents, after G1 + G2)
# Agent C, D, E — separate branches

# 4. Wave 3
# Agent G — integration
```

### Fully parallel (after G0)

```bash
@dispatching-parallel-agents

Launch 4 agents in parallel:
1. Agent A — UI primitives (Agnet)
2. Agent B — Layout shell (Agnet, rebase on A daily)
3. Agent F — Backend/DB/seed (mpgis-farmer-platform)
4. Agent MOCK — dev-api-mock + mapDashboardResponse mapper (Agnet)

Sync point: daily rebase on main; contract tests must pass before module agents C/D/E start.
```

---

## 10. Ready-made master prompt (copy to new session)

```
@senior-architect @dispatching-parallel-agents @ui-ux-pro-max

Execute specs/UI_UX_PARALLEL_AGENTS.md for AGNET dashboard UI library.

Order:
1. Run G0 contract gatekeeper — merge before anything else
2. Parallel Wave 1: Agent A (primitives) + Agent F (core-api/DB/seed)
3. Agent B (layout) after A merges
4. Parallel Wave 2: Agents C, D, E (identity, finance, inputs)
5. Agent G (integration + i18n + E2E)

Repos:
- BFF/UI: /Users/sohansoni/MPGIS/Agnet
- Backend: /Users/sohansoni/MPGIS/mpgis-farmer-platform

Design: Mockup tokens in specs/UI_UX_LIBRARY_PLAN.md §4 — sidebar #004D40, page #F5F7F2.
Sync: specs/contracts/dashboard-v2.openapi.yaml is law. Fixtures in lib/fixtures/dashboard-mockup-personas.ts.

Success: UI_UX_LIBRARY_PLAN.md §13 metrics — ≥90% layout match, 0 critical axe, 100% i18n, E2E green.
```

---

## 11. Risks specific to parallel execution

| Risk | Mitigation |
|------|------------|
| Type drift between F and C/D/E | G0 contract + contract tests block merge |
| Duplicate fixture data | Single `dashboard-mockup-personas.ts` |
| E2E selector conflicts | Agent B owns shell testids |
| B rebase conflicts with A | A merges first; B rebases daily |
| F delayed | C/D/E ship with dev-mock; G wires real API |
| ui-ux-pro-max palette drift | §4 mockup tokens override in every agent prompt |

---

*Orchestration derived from UI_UX_LIBRARY_PLAN.md, P2P3_ARCHITECTURE_DB_SYNC.md, and ui-ux-pro-max workflow. Skill assignments via skill-router.*
