# AGNET Onboarding Wizard — Comprehensive Field Specification

**Source:** UX Research analysis (2026-06-26)  
**Audience:** Product, engineering, compliance  
**Principle:** Collect minimum viable truth at launch (P0), enrich progressively (P1/P2), never block completion on optional data.

## Current vs Target

| Metric | Pilot (today) | P0 launch target | P0 + P1 |
|--------|---------------|------------------|---------|
| Total wizard time | 28–42 min | 35–50 min | 50–70 min |
| Fields per step (avg) | 3–5 | 8–12 | 12–18 |

---

## Global UX Patterns

| Pattern | Application |
|---------|-------------|
| Progressive disclosure | P0 visible first; "Add more details" for P1; P2 behind agent toggle |
| Icon + label selects | District, crop, purpose, asset type — no free-text at P0 |
| Agent-assist path | "Field agent will help" on GIS, KYC, documents — never blocks |
| Smart defaults | Prefill from prior steps with source badge ("From your ID") |
| UZS primary | All amounts in soums; USD computed with FX snapshot |
| Audio prompts (P1) | Tap-to-hear consent and labels in uz/ru |

---

## Step 1: ACCOUNT

**Goal:** Verified contact anchor for OTP auth and case notifications.  
**Time:** 1–2 min → 2–3 min (+P1)

### P0 — Required today + launch

| Field | Type | Validation | Platform use |
|-------|------|------------|--------------|
| `phone` | string | E.164 `+998[0-9]{9}` | Auth, SMS, institution contact |
| `verified` | boolean | `true` after OTP | Audit trail |
| `verificationMethod` | enum | `sms` \| `voice_otp` | Ops analytics |

### P1 — Optional enrichment

| Field | Type | Platform use |
|-------|------|--------------|
| `preferredLanguage` | enum `uz`\|`ru`\|`en` | i18n, call-center routing |
| `whatsappOptIn` | boolean | Higher engagement in UZ |
| `referralSource` | enum (ref: `referral_sources`) | Growth analytics |

### P2 — Defer

`assistedByAgentId`, device fingerprint, push token

### Remove

Email (low adoption among target farmers)

---

## Step 2: CONSENT

**Goal:** Auditable consent for credit checks, GIS analysis, institution data sharing.  
**Time:** 2–4 min → 3–5 min

### P0

| Field | Type | Validation | Platform use |
|-------|------|------------|--------------|
| `accepted` | map\<string, boolean\> | All required keys `true` | ConsentRecord |
| `accepted.credit_bureau` | boolean | Required | Agrobank requirement |
| `accepted.gis_satellite` | boolean | Required | NDVI/SATAI scoring |
| `accepted.data_sharing_institutions` | boolean | Required | FinanceCase routing |
| `consentVersion` | string | Semver | Legal defensibility |
| `consentType` | string | e.g. `credit_check` | Indexing |
| `acceptedAt` | datetime | ISO 8601 | Audit |
| `locale` | enum `uz`\|`ru` | From preferred language | Legal validity |

### P1

| Field | Platform use |
|-------|--------------|
| `accepted.marketing` | Optional engagement consent |
| `ipAddress`, `userAgent` | Fraud audit (server-captured) |

---

## Step 3: KYC

**Goal:** Identity verification against national registry; anchor name/DOB for scoring.  
**Time:** 2–3 min (pilot) → 5–8 min (OneID + photo)

### P0 — Production

| Field | Type | Validation | Platform use |
|-------|------|------------|--------------|
| `idType` | enum | `national_id`\|`passport`\|`biometric_passport` | Verification routing |
| `nationalId` / `pinfl` | string | PINFL 14 digits | OneID lookup |
| `oneIdSessionId` | string | UUID | Dispute resolution |
| `fullNameOfficial` | string | Read-only from registry | Prefills Step 4 |
| `dateOfBirthOfficial` | date | Read-only | Age eligibility |
| `genderOfficial` | enum | Read-only | Demographics |
| `kycStatus` | enum | System-set | Workflow |
| `verifiedAt` | datetime | System-set | Audit |

### P1

| Field | Platform use |
|-------|--------------|
| `idPhotoFrontId`, `idPhotoBackId` | Manual review fallback |
| `selfieMatchScore` | Liveness anti-fraud |
| `kycAssistMode` | `self_serve` \| `agent_assisted` |

### Remove in production

Pilot auto-set `kycStatus: verified` without API call (see **W-003** / T-001)

---

## Step 4: FARM_PROFILE

**Goal:** Demographics and experience for scoring segmentation and institution questionnaires.  
**Time:** 3–5 min → 4–6 min

### P0

| Field | Type | Validation | Platform use |
|-------|------|------------|--------------|
| `fullName` | string | 2–100 chars; prefill from KYC | Display, legal docs |
| `dateOfBirth` | date | Age 18–85 | Eligibility rules |
| `gender` | enum | `male`\|`female`\|`prefer_not_to_say` | Reporting |
| `primaryLanguage` | enum | `uz`\|`ru` | Comms |
| `region` | enum | ref: `regions` | Cascades to district |
| `district` | enum | ref: `districts` | Regional scoring models |
| `householdSize` | integer | 1–20 | Income-per-capita proxy |
| `yearsFarming` | integer | 0–60 | Experience score |
| `farmerType` | enum | `owner`\|`tenant`\|`family_farm`\|`cooperative_member` | Product matching |
| `education` | enum | `none`…`university` | Financial literacy proxy |

### P1

| Field | Platform use |
|-------|--------------|
| `dependentsCount` | Repayment capacity |
| `alternatePhone` | Reachability |
| `village` | Prefills Step 5, agent routing |
| `coApplicantName`, `coApplicantPinfl` | Joint liability products |

### P2

`hasBankAccount`, `primaryBank`

---

## Step 5: LAND_SKETCH

**Goal:** Land tenure and registry metadata for collateral, GIS linking, SATAI calibration.  
**Time:** 3–5 min → 5–8 min (multi-parcel)

### P0 — Primary parcel (`parcels[]`, min 1)

| Field | Type | Validation | Platform use |
|-------|------|------------|--------------|
| `parcels[].district` | enum | ref: `districts` | Geo segmentation |
| `parcels[].village` | string | 2–80 chars | Agent routing |
| `parcels[].areaHa` | decimal | 0.01–500 | Yield/ha, collateral |
| `parcels[].tenureType` | enum | `owned`\|`leased`\|`sharecrop`\|`communal`\|`inheritance` | Collateral rules |
| `parcels[].landUseType` | enum | `irrigated_cropland`\|`rainfed`\|`orchard`\|`pasture`\|`greenhouse` | SATAI model |
| `parcels[].irrigationSource` | enum | `canal`\|`well`\|`drip`\|`rainfed`\|`mixed` | Drought risk |
| `parcels[].isPrimary` | boolean | Exactly one `true` | GIS default target |
| `parcels[].registryRef` | string | Kadastr format or empty | Registry verification |

### P1 — Conditional / multi-parcel

| Field | Condition | Platform use |
|-------|-----------|--------------|
| `parcels[].irrigationReliability` | Optional | Risk scoring |
| `parcels[].soilType` | Optional | Input recommendations |
| `parcels[].leaseEndDate` | If leased | Collateral validity |
| `parcels[].landlordConsent` | If leased | Legal |
| `parcels[].parcelLabel` | Optional | Farmer mental model |

---

## Step 6: GIS_MAPPING

**Goal:** Geospatial anchor for NDVI, drought index, SATAI yield forecasting.  
**Time:** 1–2 min (skip) → 4–8 min (polygon)

### P0

| Field | Type | Validation | Platform use |
|-------|------|------------|--------------|
| `gisStatus` | enum | `coordinates_provided`\|`agent_pending`\|`polygon_provided` | Workflow |
| `parcelId` | string | FK to primary parcel | Multi-parcel |
| `coordinates.lat`, `coordinates.lng` | decimal | UZ bounds | NDVI fallback |
| `coordinates.accuracyM` | number | From Geolocation API | Quality flag |
| `note` | string | ≤200 chars | Agent instructions |
| `captureMethod` | enum | System-set | Quality scoring |

### P1

| Field | Platform use |
|-------|--------------|
| `geoJson` | Precise NDVI/SATAI (map draw) |
| `derivedAreaHa` | Cross-check vs declared area (flag >20% mismatch) |
| `agentVisitPreferredDate`, `agentVisitPhone` | Ops scheduling |
| `ndviEnrichmentStatus` | Scoring pipeline (system) |

### UX rule

Never block on polygon — GPS pin or `agent_pending` sufficient for P0.

---

## Step 7: CROP_PLAN

**Goal:** Production plan for revenue forecast, SATAI cross-check, trade matching, inputs.  
**Time:** 3–5 min → 5–8 min

### P0 — Per crop entry (min 1)

| Field | Type | Validation | Platform use |
|-------|------|------------|--------------|
| `crops[].crop` | enum | ref: `crops` | SATAI, trade |
| `crops[].season` | enum | `spring`\|`summer`\|`autumn`\|`winter` | Calendar |
| `crops[].areaHa` | decimal | ≤ total land | Yield/ha |
| `crops[].expectedYield` | decimal | >0; plausible per crop | SATAI cross-check |

### P1

| Field | Platform use |
|-------|--------------|
| `crops[].variety` | Input recommendations |
| `crops[].parcelId` | Multi-parcel link |
| `crops[].plantingMonth`, `harvestMonth` | Cashflow timing |
| `crops[].priorYearYield` | Historical validation |
| `crops[].intendedMarket` | Buyer matching |
| `crops[].hasBuyerContract` | Revenue certainty |

### Validation

Sum of `crops[].areaHa` must not exceed total land from Step 5 (**W-010**).

---

## Step 8: FARM_ASSETS

**Goal:** Collateral inventory for asset-based lending and exposure calculation.  
**Time:** 3–5 min → 4–7 min

### P0

| Field | Type | Validation | Platform use |
|-------|------|------------|--------------|
| `assets[].assetType` | enum | ref: `asset_types` | Valuation models |
| `assets[].condition` | enum | `new`\|`good`\|`fair`\|`poor` | Depreciation |
| `assets[].estimatedValue` | decimal | ≥0 USD or UZS | Collateral sum |
| `assets[].quantity` | integer | ≥1, default 1 | Livestock, tools |
| `totalAssetValueUsd` | decimal | Computed | Scoring feature |
| `noneDeclared` | boolean | Shortcut if no assets | Completion rate |

### P1

| Field | Platform use |
|-------|--------------|
| `assets[].description`, `yearAcquired` | Manual review |
| `assets[].ownershipStatus`, `hasTitle` | Collateral validity |
| `assets[].serialNumber` | Equipment verification |
| `storageCapacityTons`, `coldStorage` | Trade module |

---

## Step 9: FINANCE_REQUEST

**Goal:** Credit need and repayment capacity for DTI, institution routing, FinanceCase.  
**Time:** 2–4 min → 4–7 min

> **Recommended reorder:** Run **DOCUMENTS (Step 10) before FINANCE_REQUEST** so OCR prefills income/loans (**W-005**).

### P0

| Field | Type | Validation | Platform use |
|-------|------|------------|--------------|
| `purpose` | enum | ref: `finance_purposes` | Product routing |
| `amountUzs` | decimal | ≥500,000 UZS | Core request |
| `amountUsd` | decimal | Computed from FX | Institution reporting |
| `termMonths` | integer | 3–60 | DTI, product match |
| `monthlyIncomeUzs` | decimal | ≥0; OCR prefill | DTI numerator |
| `existingLoansUzs` | decimal | ≥0; OCR prefill | DTI denominator |
| `repaymentHistory` | enum | `none`\|`good`\|`fair`\|`poor` | Rules engine |

### P1

| Field | Platform use |
|-------|--------------|
| `monthlyExpensesUzs`, `existingLoanPaymentsUzs` | Accurate DTI |
| `useOfFundsBreakdown[]` | Institution diligence |
| `expectedRevenueUzs` | Auto-suggest from crop plan |
| `collateralOffered` | Prefill from land/assets |
| `preferredInstitution` | Routing hint |
| `disbursementAccount` | IBAN for settlement (post-approval) |

---

## Step 10: DOCUMENTS

**Goal:** KYC and financial evidence for OCR, document quality scoring, institution checklist.  
**Time:** 5–12 min → 6–15 min

### P0 — Required document set (UZ pilot)

| docType | Label | Required |
|---------|-------|----------|
| `national_id` | National ID photo | If not OneID-verified |
| `land_deed` | Land deed / e-Ijara | **Yes** |
| `bank_statement` | Bank statement (3 months) | **Yes** |
| `tax_receipt` | Tax receipt / daromad | Optional |

### P0 — Metadata per upload

| Field | Platform use |
|-------|--------------|
| `uploaded` map | Compliance gate |
| `documents[].fileId`, `uploadedAt` | Audit |
| `extractionStatus` | OCR pipeline |
| `extractedFinancials.monthlyIncomeUzs` | Prefill finance |
| `extractedFinancials.existingLoansUzs` | Prefill finance |
| `extractedFinancials.accountBalanceUzs` | Liquidity signal |
| `documentQualityScore` | Scoring feature |

### P1

`income_certificate`, `crop_contract`, `equipment_invoice`, `photos_assets`, `documentAssistMode`

---

## Step 11: REVIEW

**Goal:** Verify accuracy, resolve conflicts, submit for scoring.  
**Time:** 2–3 min → 5–8 min

### P0

| Field | Platform use |
|-------|--------------|
| `reviewed`, `reviewedAt` | Legal attestation |
| `attestationText` | CMS version reference |
| Summary cards (display) | Identity, Land, Crops, Assets, Finance, Documents |

### P1

| Field | Platform use |
|-------|--------------|
| `conflicts[]` | System-detected mismatches (income vs OCR, area vs crops) |
| `conflicts[].resolution` | `keep_mine`\|`use_document`\|`edit` |
| `ocrOverrides` | Model feedback |
| `editSteps[]` | Friction analytics |

---

## Step 12: SCORING

**Goal:** Transparent wait state; no farmer data entry.  
**Time:** 1–3 min (polling)

### System fields (P0)

| Field | Platform use |
|-------|--------------|
| `scoringComplete`, `decision`, `score` | Gate to Result |
| `reasonCodes[]` | Transparency (top 3 in plain language) |

### P1 display

`ndviStatus`, `sataiYieldEstimate`, `droughtIndex`, `dtiRatio` — show bands, not raw numbers

---

## Step 13: RESULT

**Goal:** Communicate outcome; route to dashboard modules.  
**Time:** 1–2 min

### P0

| Field | Platform use |
|-------|--------------|
| `acknowledged`, `acknowledgedAt` | Completion gate |
| `outcome` | Dashboard routing tone |
| `financeCaseId`, `financeCaseStatus` | Expectation setting |
| `conditionalRequirements[]` | Actionable improvements if conditional |

### P1

| Field | Platform use |
|-------|--------------|
| `inputRecommendations[]` | Seeds Inputs module |
| `buyerOffers[]` | Seeds Trade module |
| `recommendedModules[]` | Engagement CTAs |

---

## Cross-Step Dependencies

```mermaid
flowchart LR
    KYC -->|fullName, DOB| FP[FARM_PROFILE]
    FP -->|district, village| LS[LAND_SKETCH]
    LS -->|parcelId, areaHa| GIS[GIS_MAPPING]
    LS -->|areaHa| CP[CROP_PLAN]
    CP -->|expectedRevenue| FIN[FINANCE_REQUEST]
    DOC[DOCUMENTS OCR] -->|income, loans| FIN
    FA[FARM_ASSETS] -->|collateral| FIN
    GIS --> SCOR[SCORING]
    FIN --> SCOR
    DOC --> SCOR
    SCOR --> RES[RESULT]
    RES --> FC[FinanceCase]
```

| Source | Target | Fields |
|--------|--------|--------|
| KYC | FARM_PROFILE | `fullName`, `dateOfBirth`, `gender` |
| ACCOUNT | FARM_PROFILE | `preferredLanguage` → `primaryLanguage` |
| FARM_PROFILE | LAND_SKETCH | `district`, `village` |
| LAND_SKETCH | GIS_MAPPING | Primary `parcelId` |
| LAND_SKETCH | CROP_PLAN | Total `areaHa` validation |
| CROP_PLAN | FINANCE_REQUEST | `expectedRevenueUzs` |
| DOCUMENTS | FINANCE_REQUEST | `monthlyIncomeUzs`, `existingLoansUzs` |
| FARM_ASSETS | FINANCE_REQUEST | `collateralOffered` |
| SCORING | RESULT | `decision`, `score`, `reasonCodes` |

---

## Priority Summary

| Tier | Scope |
|------|-------|
| **P0** | All fields marked required above — launch scoring, KYC, FinanceCase |
| **P1** | Multi-parcel, polygon GIS, OCR confidence UX, conflict resolution, institution docs |
| **P2** | Livestock, NPS feedback, guarantor, asset photos, soil lab |

## Top 5 Research Recommendations

1. **Reorder DOCUMENTS before FINANCE** — highest ROI for data quality.
2. **UZS-first with OCR prefill** — farmers think in soums; improves DTI accuracy.
3. **Never block on GIS polygon** — GPS pin or agent path is P0 sufficient.
4. **KYC → Profile prefill chain** — reduces duplicate entry dropout.
5. **Cap P0 at ≤50 minutes** — usability test with 8–10 farmers before P1 expansion.

---

*Implementation tasks tracked in `specs/PROJECT_PLAN.md` section **Wizard Field Expansion (W-001–W-019)**.*
