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.xlsx→ Livelihood 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:
- Application (Stage 1) — SHG membership + FPCL shareholder/willingness gating → goat-rearing screening → revolving-fund loan receipt.
- Follow-up 1 — goat purchase (male/female bought with the fund) + insurance + market channels.
- 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.
| # | Question | Type | Options / Range | Logic |
|---|---|---|---|---|
| 2.0 | Member of an SHG? | Single | Yes / No | No → close, status Member not in SHG |
| 2.1 | Name of the SHG | Text | skip if 2.0=No | |
| 2.2 | Member of SHG since (years) | Number | 0–30 | skip if 2.0=No |
| 2.3 | Shareholder of Meshavaram FPCL? | Single | Yes / No | |
| 2.4 | Willing to join Meshavaram FPCL? | Single | Yes / No | skip if 2.3=Yes. Yes → reopen after 30 days, status willing to join. No → close, status not willing to join |
| 2.5 | Shareholder since (year) | Single | 2019…2030 | skip if 2.3=No |
| 2.6 | Responsibility in the FPO | Single | Shareholder / Director | |
| 2.7 | Services availed from FPO | Single → conditional list | Yes/No; on Yes show services list (single-select): Training/Demo, Farm advisory, Agrl. inputs, Credit, Marketing, Animal Husbandry, Goat rearing, Govt. schemes, Others | Decision F: Yes/No gate, then single-select list |
| 2.8 | Specify others | Text | if services=Others | |
| — | Prior experience in goat rearing? | Single | Yes / No | No S.No in sheet — treated as real field (decision G) |
| 2.9 | If yes, goats currently reared | Number | 0–10 | >5 → close, status Member rejected (goat limit reached). Capture full 0–10 range for reporting (decision E) |
| 2.10 | Project goat training completed | Multi | Breed Selection, Feed & Water Mgmt, Disease Prevention, Shed Mgmt, Enterprise mgmt, Risk Mgmt, Exposure to other FPOs, Financial mgmt | |
| 2.11 | Attended village awareness campaign? | Single | Yes / No | Decision F: make Yes/No |
| 2.12 | Received revolving-fund loan? | Single | Yes / No | Yes → open follow-up, status received Loan. No → close, status not received Loan |
| 2.13 | Date of fund receipt | Date | skip if 2.12=No. Anchors FU1 timing | |
| 2.14 | Amount received | Number | default 10000 | |
| 2.15 | When to do the follow-up? | Single | 7 / 10 / 15 days | surveyor-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.
| # | Question | Type | Options / Range | Logic |
|---|---|---|---|---|
| 3.1 | Male/female goats bought with fund | Multi | Male / Female | |
| 3.2 | No. of male goats | Number | 0–5 | skip if 3.1=Female only |
| 3.3 | No. of female goats | Number | 0–5 | skip if 3.1=Male only |
| 3.4 | Goat insurance done? | Single | Yes / No | No → continue anyway (decision D) |
| 3.6 | Market channels to sell goats | Multi | Local Market, Broker, Project-established market, Others | 3.5 blank in sheet = sheet artifact, ignored (decision G) |
| 3.7 | Specify others | Text | if 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)
| Ticket | Decision |
|---|---|
| SWF-2026-00126 | Parent 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-00127 | When 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-00128 | Option rename: "Defaulted, No payment made" → "Defaulted, payment delayed". Existing rows migrated by patch v3_0._021. |
| SWF-2026-00139 | Sticky-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.