Swasti · mForm V2→V3

10 — Livelihood (goat-rearing / Meshavaram FPCL) authoritative flow

✅ RESOLVED — Shweta confirmed all open questions 2026-05-27. Resolved decisions are listed below and inline. See Resolved decisions section at the bottom.

Regenerated 2026-05-27 from SP Flow All.xlsxLivelihood sheet. Build directive: mirror the existing form pattern (Stage-1 application + multi-visit follow-ups, offline-first save, derived status, detail screen with visit-history cards) so field users don’t need retraining.

Program shape

A goat-rearing livelihood program tied to the Meshavaram FPCL. Three phases:

  1. Application (Stage 1) — SHG membership + FPCL shareholder/willingness gating → goat-rearing screening → revolving-fund loan receipt.
  2. Follow-up 1 — goat purchase (male/female bought with the fund) + insurance + market channels.
  3. Monthly repayment follow-ups (FU2 … FU11) — up to 10 monthly repayment-tracking visits, each available anytime with a “due on <date>” hint anchored on the previous follow-up’s date, ending early once the loan is repaid (see decision C).

Stage 1 — Application

Member Details — auto-populate from the Member form (read-only): Name, DOB, Age, Phone, Gender, Marital Status, Disabled.

#QuestionTypeOptions / RangeLogic
2.0Member of an SHG?SingleYes / NoNo → close, status Member not in SHG
2.1Name of the SHGTextskip if 2.0=No
2.2Member of SHG since (years)Number0–30skip if 2.0=No
2.3Shareholder of Meshavaram FPCL?SingleYes / No
2.4Willing to join Meshavaram FPCL?SingleYes / Noskip if 2.3=Yes. Yes → reopen after 30 days, status willing to join. No → close, status not willing to join
2.5Shareholder since (year)Single2019…2030skip if 2.3=No
2.6Responsibility in the FPOSingleShareholder / Director
2.7Services availed from FPOSingle → conditional listYes/No; on Yes show services list (single-select): Training/Demo, Farm advisory, Agrl. inputs, Credit, Marketing, Animal Husbandry, Goat rearing, Govt. schemes, OthersDecision F: Yes/No gate, then single-select list
2.8Specify othersTextif services=Others
Prior experience in goat rearing?SingleYes / NoNo S.No in sheet — treated as real field (decision G)
2.9If yes, goats currently rearedNumber0–10>5 → close, status Member rejected (goat limit reached). Capture full 0–10 range for reporting (decision E)
2.10Project goat training completedMultiBreed Selection, Feed & Water Mgmt, Disease Prevention, Shed Mgmt, Enterprise mgmt, Risk Mgmt, Exposure to other FPOs, Financial mgmt
2.11Attended village awareness campaign?SingleYes / NoDecision F: make Yes/No
2.12Received revolving-fund loan?SingleYes / NoYes → open follow-up, status received Loan. No → close, status not received Loan
2.13Date of fund receiptDateskip if 2.12=No. Anchors FU1 timing
2.14Amount receivedNumberdefault 10000
2.15When to do the follow-up?Single7 / 10 / 15 dayssurveyor-chosen; governs FU1 due hint

Reopen rule: a rejected/closed form can be reopened at any time — applies to all terminal/rejection scenarios (decision I).


Follow-up 1 — Goat purchase

Available anytime; due-on hint derived from fund_receipt_date + (2.15 days). Done once only.

#QuestionTypeOptions / RangeLogic
3.1Male/female goats bought with fundMultiMale / Female
3.2No. of male goatsNumber0–5skip if 3.1=Female only
3.3No. of female goatsNumber0–5skip if 3.1=Male only
3.4Goat insurance done?SingleYes / NoNo → continue anyway (decision D)
3.6Market channels to sell goatsMultiLocal Market, Broker, Project-established market, Others3.5 blank in sheet = sheet artifact, ignored (decision G)
3.7Specify othersTextif 3.6=Others

Transition: regardless of 3.4, open FU2 ~30 days after 2.13; status Moving to Follow-up 2.


Monthly repayment follow-ups (FU2 → FU11)

Up to 11 follow-ups total = FU1 + FU2…FU11 (10 monthly). FU11 is the terminal repayment follow-up; ~5 is the common real-world case. Each opens anytime with a “due on <date>” hint anchored on the previous follow-up’s date (decision A). Early termination applies — stop once loan is fully repaid (decision B + C).

Each monthly visit:

  • Name / Age / Phone — pulled from the Member form (read-only).
  • Amount received (echo of 2.14) and Goat insurance done? (echo of 3.4) — editable each month for now; Shweta to confirm with client whether these become read-only echoes (decision H).
  • Repayment date for the month (Date).
  • Status of repayment (Single): Regular and on-time (paid days 1–5), Irregular, with delays (days 5–10), Defaulted, no payment (day 11+).
  • Is loan fully repaid? (Yes/No) — added per decision C. Yes → close, terminal status Loan fully repaid, flow closed.

Final follow-up (FU11) also captures: average net income from the goat enterprise (0–3000 … 20000–25000 / Others + specify). Terminal: Regular/Irregular → Loan Repayment Completed; Defaulted → Loan Repayment Not Completed.


Status taxonomy

Member not in SHG · willing to join FPCL · not willing to join FPCL · Member rejected (goat limit reached) · received Loan – moving to follow-up · not received Loan · Moving to Follow-up 2 · Nth Month Payment Completed · Loan Repayment Completed · Loan Repayment Not Completed · Loan fully repaid, flow closed.


✅ Resolved decisions

All open questions answered by Shweta Singh (group chat, 2026-05-27 10:48). These override any spec-body ambiguities.

  • A (timing): Follow-ups available anytime — show a “due on <date>” hint computed from the previous follow-up’s date. Do NOT hard-gate. (Recommendation b confirmed.)
  • B (count): Up to 11 follow-ups total = FU1 (goat purchase) + FU2…FU11 (10 monthly). FU11 is terminal. Early termination applies (see C). ~5 is the common real-world case.
  • C (fully-repaid signal): Add “Is loan fully repaid? (Yes/No)” to each monthly follow-up. Yes → close, terminal status Loan fully repaid, flow closed.
  • D (insurance = No): No dependency — continue anyway. 3.4=No does not block.
  • E (goat limit): Capture full 0–10 range. >5 → reject, status Member rejected (goat limit reached); ≤5 → continue.
  • F (2.7 services): 2.7 is Yes/No; on Yes show a single-select services list; on No hide it. 2.11 campaign is Yes/No.
  • G (numbering gaps): “Prior experience in goat rearing?” is a real field despite missing S.No. 3.5 blank = sheet artifact, ignore. Non-blocking.
  • H (monthly repeated fields): Amount Received and insurance are editable each month for now — Shweta to confirm with client; may later become read-only echoes.
  • I (reopen scope): Reopen applies to all terminal/rejection scenarios (not just SHG/FPCL).

Shweta also shared a Google Sheet (docs.google.com/spreadsheets/d/1tcvrHUSdeTrthcQGP_WASQoizEhT0Vf7) in the same group chat session — this pm-spec is the build authority; cross-check the sheet only if a specific field looks off.


Build status

Frappe backend

Originally committed mform_swasti 46f84f2. Livelihood module with 5 DocTypes (Livelihood Application, Goat Purchase Follow-up, Repayment Follow-up, plus supporting option masters) + status module + permissions/manifest patch _017. Verified on local bench: status branches, >5 goat-limit rejection.

Subsequent Frappe work merged via development branch (now the live deploy source — auto-deploys to staging on push, no PR gate). Heads as of 2026-06-05: fbad7ce (SWF-140 hotfix making loan_fully_repaid conditionally required), preceded by a915653 (status module — Defaulted is non-terminal) and 539c3ac (SWF-126/127/128 workflow + skip-logic + option rename).

Flutter UI

Originally committed swasti_flutter ce05c12 on feature/initial-app. Mirrors the Scheme Application pattern: application + 2 follow-up form types + detail screen with 6 collapsible sections. Member-detail Livelihood tab shows a listing with stage chips and an actionable “Overdue by N days” hint anchored on fund_receipt_date + 30d. FormEventConfigs wired.

Current Flutter HEAD on staging: 783cf85 (SWF-139 + SWF-140) — see the milestone log in progress.yml for the trail.

On-device verified

Originally on emulator-5554 (dev build): home count, listing card, detail header/pill, collapsible sections, Beneficiary resolution, auto-populate Member fields, stage-status flow. Phase-6 tester verification runs against a physical Vivo on the staging APK distributed via Firebase.

Child-table sync (#186) — resolved app-side

The SDK’s buildChildSchemaDDL emits reserved-word column names unquoted, so the CREATE for docs__user_document_type aborts the DDL loop and downstream docs__<child> tables (including Livelihood’s) never get the parent_uuid schema. Rather than wait for an SDK fix, we shipped two app-side commits: a child-table v2 schema migration that hand-builds the docs__<child> tables with parent_uuid + parent_doctype + parentfield + idx, and a rewrite of the offline eligibility matcher (applicable_schemes_local.dart) to join on parent_uuid. Save + full offline sync work end-to-end for all four flows including Livelihood. Background diagnosis in findings-186-member-sync-root-cause.md.

Decisions resolved in Phase 6 (post-original-design)

TicketDecision
SWF-2026-00126Parent application workflow closes on loan_fully_repaid = Yes. Implementation uses a direct SQL UPDATE on the local docs__livelihood_application row from the FU save handler (the SDK’s saveDocument uses INSERT-OR-REPLACE semantics, which nullifies un-payloaded columns); server on_update hook handles the canonical write on push. CTA close-gate uses the parent’s workflow_status.
SWF-2026-00127When repayment_status == "Defaulted, payment delayed", hide avg_net_income + loan_fully_repaid. Reorder so loan_fully_repaid sits at the end of the Repayment section.
SWF-2026-00128Option rename: "Defaulted, No payment made""Defaulted, payment delayed". Existing rows migrated by patch v3_0._021.
SWF-2026-00139Sticky-CTA sequence gate. Repayment Follow-up CTA is disabled (label "Complete Goat Purchase first") until at least one Goat Purchase Follow-up exists on the parent application.
SWF-2026-00140"Defaulted, payment delayed" is non-terminal. Derives current_status = "Nth Month Payment Delayed". Workflow closes ONLY when (a) loan_fully_repaid = Yes"Loan fully repaid, flow closed", or (b) visit 10 is filed without full repayment → "Loan Repayment Not Completed". Frappe hotfix fbad7ce made loan_fully_repaid conditionally required (mandatory_depends_on on JSON + server-side guard in _validate_conditional_mandatory) to match the SWF-127 skip-logic — the prior reqd: 1 was rejecting every Defaulted save with MandatoryError.

Open implementation decision

followup_number / is_final field on Repayment Follow-up so the Nth Month Payment Completed status carries the real month number. Currently computed at save time from existing-FU count + 1 on both ends — works, but adds round-trip risk if a sync drops mid-batch. Needs PM input before changing the schema.


Last updated 2026-05-04