Skip to content

fix(spp_demo,spp_mis_demo_v2): convert stories to households, locale-aware names, sync docs#131

Open
emjay0921 wants to merge 20 commits into19.0from
demo-readme-sync
Open

fix(spp_demo,spp_mis_demo_v2): convert stories to households, locale-aware names, sync docs#131
emjay0921 wants to merge 20 commits into19.0from
demo-readme-sync

Conversation

@emjay0921
Copy link
Copy Markdown
Contributor

@emjay0921 emjay0921 commented Mar 23, 2026

Why is this change needed?

Several demo stories were created as individuals but enrolled in group-targeting programs, causing CEL expression mismatches. Default story names were a mix of Filipino, Arabic, and other origins instead of being culturally consistent per locale. USE_CASES.md and program references were outdated. Demo programs had no compliance criteria configured, missing a key feature demonstration.

How was the change implemented?

Story & Program Fixes (spp_demo, spp_mis_demo_v2)

  • Convert 4 stories (maria_santos, juan_dela_cruz, ibrahim_hassan, ahmed_said) from individual to household type with proper head/spouse/children members
  • Replace all non-Filipino default names with Filipino names for locale consistency (si_LK and fr_TG overrides continue to work)
  • Remove all farm references (farm_size, farm_type, Input Subsidy, Livestock Improvement) from story definitions and MIS demo
  • Fix david_sofia_martinez enrollment key mismatch
  • Update event_types.xml: farm_condition_score → household_condition_score
  • Remove max_farm_size_subsidy constant
  • Hide obsolete demo generator settings from Settings UI

Compliance Criteria (spp_mis_demo_v2)

  • Add compliance manager CEL expressions to 2 programs:
    • Cash Transfer: per_capita_income < poverty_line
    • Conditional Child Grant: per_capita_income < income_threshold (overridden to 2000)
  • Santos story demonstrates compliance failure → graduation (cycle membership = non_compliant)
  • Dela Cruz story demonstrates compliance passing (cycle membership = enrolled)
  • Add _CCG eligibility flag to 4 household blueprints (bp_01, bp_04, bp_06, bp_28) for Conditional Child Grant volume enrollments (~110 households)
  • Add program constant override via spp.cel.program.parameter for income_threshold
  • Add Santos Universal Child Grant enrollment for partial exit story

Documentation Sync (spp_mis_demo_v2)

  • Rewrite USE_CASES.md to v3 spec with compliance scenarios
  • Fix wizard view: "6 programs" → "7 programs" with Conditional Child Grant
  • Update i18n translations (.pot, fr.po) for program count

README Regeneration

  • Regenerate READMEs for spp_mis_demo_v2, spp_farmer_registry_demo, spp_case_demo, spp_grm_demo using custom template (removes OCA banner)

New unit tests

  • 12 new tests for compliance configuration and behavior:
    • Compliance CEL expression validation for Cash Transfer and CCG
    • Program constant override verification
    • Non-compliant cycle membership creation for Santos
    • Programs without compliance have empty expressions
    • Santos enrollment structure (graduated + non_compliant_cycle + UCG)
    • Blueprint eligibility flags include conditional_child_grant

Unit tests executed by the author

  • spp_mis_demo_v2: 269 tests, 0 failed
  • Verified on live instances across all 3 locales:
    • Philippines (fil_PH): 2,868 registrants, CCG=110 enrolled, compliance PASS
    • Togo (fr_TG): 2,868 registrants, CCG=95 enrolled, compliance PASS
    • Sri Lanka (si_LK): 2,868 registrants, CCG=95 enrolled, compliance PASS

How to test manually

  • Run MIS Demo generator with any country
  • Open Cash Transfer Program → verify compliance manager has per_capita_income < poverty_line
  • Open Santos household → Cash Transfer = exited, cycle membership = non_compliant
  • Open Dela Cruz household → Cash Transfer = enrolled, cycle membership = enrolled (compliant)
  • Open Conditional Child Grant → verify compliance manager and income_threshold = 2000
  • Verify CCG has ~100 enrolled households from volume data

Related links

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on synchronizing and enhancing the documentation for two demo data generators, spp_farmer_registry_demo and spp_mis_demo_v2. The changes ensure that the DESCRIPTION.md files accurately reflect the current capabilities and configurations of these modules, providing clearer guidance on their use, particularly regarding seeded data generation, updated program counts, and supported features like multi-locale and geographic data.

Highlights

  • New Documentation for spp_farmer_registry_demo: A new DESCRIPTION.md file was added for spp_farmer_registry_demo, comprehensively detailing its demo data generator capabilities, including 8 fixed story farms, approximately 730 volume farms generated via a seeded random generator, and 5 agricultural subsidy programs with CEL eligibility expressions.
  • Updated Documentation for spp_mis_demo_v2: The existing DESCRIPTION.md for spp_mis_demo_v2 was updated to reflect an increase from 6 to 7 social protection programs (now including a 'Conditional Child Grant'), document seeded volume generation for approximately 730 deterministic households, and highlight new features such as multi-locale support and geographic data loading.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the documentation for spp_farmer_registry_demo and spp_mis_demo_v2. A new DESCRIPTION.md is added for the farmer registry demo, and the existing one for the MIS demo is updated to reflect new features like additional programs and seeded data generation. The changes are accurate and improve the documentation. I have a couple of suggestions to further improve the documentation's consistency and formatting.

Comment on lines +17 to +19
| Model | Description |
| ------------------------------ | --------------------------------------------------- |
| `spp.farmer.demo.generator` | Core demo generator wizard with all generation logic |
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The markdown table formatting is a bit messy. For better readability and maintainability of the source, please align the columns.

Suggested change
| Model | Description |
| ------------------------------ | --------------------------------------------------- |
| `spp.farmer.demo.generator` | Core demo generator wizard with all generation logic |
| Model | Description |
|-------------------------------|------------------------------------------------------|
| `spp.farmer.demo.generator` | Core demo generator wizard with all generation logic |

All programs use CEL expressions with activated registry variables:

- **Universal Child Grant**: `r.is_group == true and child_count > 0` (member aggregation)
- **Conditional Child Grant**: First 1,000 days targeting for young children
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The newly added 'Conditional Child Grant' program is missing its CEL eligibility expression, unlike the other programs in this list. For consistency and completeness, please add the CEL expression.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 23, 2026

Codecov Report

❌ Patch coverage is 75.00000% with 24 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.44%. Comparing base (5b26ad7) to head (91146e9).
⚠️ Report is 32 commits behind head on 19.0.

Files with missing lines Patch % Lines
spp_mis_demo_v2/models/mis_demo_generator.py 78.78% 14 Missing ⚠️
spp_programs/models/program_manager_ui.py 0.00% 8 Missing ⚠️
spp_mis_demo_v2/models/seeded_volume_generator.py 90.47% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             19.0     #131      +/-   ##
==========================================
+ Coverage   70.98%   72.44%   +1.45%     
==========================================
  Files         899      903       +4     
  Lines       52791    53081     +290     
==========================================
+ Hits        37476    38456     +980     
+ Misses      15315    14625     -690     
Flag Coverage Δ
spp_api_v2 80.10% <ø> (+0.13%) ⬆️
spp_api_v2_change_request 66.85% <ø> (ø)
spp_api_v2_cycles 71.12% <ø> (ø)
spp_api_v2_data 64.41% <ø> (ø)
spp_api_v2_entitlements 70.19% <ø> (ø)
spp_api_v2_gis 71.52% <ø> (ø)
spp_api_v2_products 66.27% <ø> (ø)
spp_api_v2_service_points 70.94% <ø> (ø)
spp_api_v2_simulation 71.12% <ø> (ø)
spp_api_v2_vocabulary 57.26% <ø> (ø)
spp_audit 72.60% <ø> (+8.41%) ⬆️
spp_base_common 90.26% <ø> (ø)
spp_case_demo 94.34% <ø> (ø)
spp_case_entitlements 97.61% <ø> (ø)
spp_case_programs 97.14% <ø> (ø)
spp_cel_event 85.11% <ø> (ø)
spp_claim_169 58.11% <ø> (ø)
spp_dci_client_dr 55.87% <ø> (ø)
spp_programs 62.17% <0.00%> (+9.32%) ⬆️
spp_security 66.66% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
spp_demo/locale_providers/fil_PH/__init__.py 100.00% <ø> (ø)
spp_demo/locale_providers/fr_TG/__init__.py 100.00% <ø> (ø)
spp_demo/locale_providers/si_LK/__init__.py 100.00% <ø> (ø)
spp_demo/models/demo_data_generator.py 70.81% <ø> (-0.50%) ⬇️
spp_demo/models/demo_stories.py 98.93% <ø> (-1.07%) ⬇️
spp_mis_demo_v2/__manifest__.py 0.00% <ø> (ø)
spp_mis_demo_v2/models/demo_programs.py 96.77% <ø> (ø)
spp_mis_demo_v2/models/demo_variables.py 21.56% <ø> (ø)
spp_mis_demo_v2/models/household_blueprints.py 87.50% <100.00%> (ø)
spp_mis_demo_v2/models/seeded_volume_generator.py 94.94% <90.47%> (ø)
... and 2 more

... and 31 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…h code

- Create DESCRIPTION.md for spp_farmer_registry_demo (was missing)
- Fix spp_mis_demo_v2: 6 programs -> 7, document seeded generation,
  add Conditional Child Grant, multi-locale, geographic data loading
Include auto-generated README.rst and index.html from
oca-gen-addon-readme (Python 3.11) to match CI expectations.
- spp_case_demo: mention 3 background cases, clarify non-deterministic generation
- spp_grm_demo: list all 8 personas, add missing dependencies (spp_grm_registry, spp_grm_programs), clarify non-deterministic generation
Include auto-generated README.rst and index.html from
oca-gen-addon-readme (Python 3.11) to match CI expectations.
Delete README.md — its content is covered by readme/DESCRIPTION.md
(module description) and docs/USE_CASES.md (developer guide).
Fix "6 programs" -> "7 programs" in USE_CASES.md overview.
…locale-aware names

- Convert maria_santos, juan_dela_cruz, ibrahim_hassan, ahmed_said from
  individual/farmer to household type with proper head/spouse/children
  members, fixing enrollment in group-targeting programs
- Replace all non-Filipino default names with Filipino names so the
  default locale (fil_PH) is culturally consistent; si_LK and fr_TG
  locale overrides continue to work via LOCALE_NAMES
- Remove all farm references (farm_size, farm_type, Input Subsidy,
  Livestock Improvement) from story definitions and MIS demo
- Update USE_CASES.md to match actual programs and stories
- Fix david_sofia_martinez enrollment key mismatch
- Update event_types.xml: farm_condition_score -> household_condition_score
@emjay0921 emjay0921 changed the title docs(spp_farmer_registry_demo,spp_mis_demo_v2): sync descriptions with code fix(spp_demo,spp_mis_demo_v2): convert stories to households, locale-aware names, sync docs Mar 26, 2026
…ment fixes

- Story households use family-name-only (Santos, Dela Cruz, etc.)
- Manuel Santos elderly renamed to Pangilinan to avoid Santos conflict
- Tutorial families renamed: Santos→Tolentino, Cruz→Salazar, Reyes→Mercado
- Locale names updated for si_LK and fr_TG (family name only for groups)
- Expanded name pools: fil_PH 714, si_LK 535, fr_TG 561 surnames
- Seeded generator: suffix filter for compound names, unique names from
  shuffled pool, shared family name within households
- Fix cycle creation: use today then backdate via SQL to bypass
  _check_dates constraint (fixes Santos 0 payments, Gutierrez  bug)
- Batch create optimization: mail_create_nolog + tracking_disable
Add compliance managers to Cash Transfer (per_capita_income < poverty_line)
and Conditional Child Grant (per_capita_income < income_threshold with
program-level override to 2000). Santos story demonstrates compliance
failure triggering graduation (non_compliant cycle membership), while
Dela Cruz demonstrates compliance passing on the same program.

- Configure compliance CEL expressions on 2 of 7 programs
- Add program constant override for income_threshold via spp.cel.program.parameter
- Mark Santos cycle membership as non_compliant after payment creation
- Add CCG eligibility flag to 4 household blueprints (bp_01, bp_04, bp_06, bp_28)
- Add Santos Universal Child Grant enrollment for partial exit story
- Update wizard view, translations, and USE_CASES.md to v3 spec
- Add 12 new tests for compliance configuration and behavior
Comment on lines +1412 to +1417
_logger.info(
"Individual enrollment: using head member %s (id=%s) from group %s",
enrollee.name,
enrollee.id,
registrant.name,
)

Check warning

Code scanning / Semgrep OSS

Semgrep Finding: semgrep.odoo-pii-in-log-name Warning

PII (person name) in log message. Use record ID instead.
Bad: _logger.info("Processing %s", partner.name)
Good: _logger.info("Processing partner ID=%s", partner.id)
The spp CLI imports tomllib which is only available in Python 3.11+.
Add a fallback to the tomli backport package, and gracefully skip
TOML config loading with a warning if neither is available.
Remove `str | None` and `str | list` type annotations that require
Python 3.10+. The spp CLI now works on Python 3.9+.
…low, use case accuracy

Fix eligibility managers not getting CEL expressions set (get_manager
doesn't handle MANAGER_ELIGIBILITY — use program.eligibility_manager_ids
directly instead). Fix CR approval workflow using with_user() for the
correct validator users (local + HQ) to pass multi-tier approval checks.
Fix eligibility UI summary showing "Configured" instead of actual CEL.

spp_mis_demo_v2:
- Fix _configure_eligibility_manager to access wrapper directly
- Fix _configure_logic_studio to always set CEL on eligibility manager
- Fix _set_cr_state to use demo_cr_local_validator and demo_cr_hq_validator
  for multi-tier approval (approve, reject, revision)
- Change Rosa Garcia exit CR from applied to pending (prevents enrollment deletion)
- Update use case: Santos 5 members (add Lola), Reyes multi-generational 8 members,
  13 CRs with accurate types/states, fix Rosa Garcia and Lorna Pascual references

spp_programs:
- Show "CEL Expression" as eligibility type when mode is cel
- Show actual CEL expression in eligibility summary (was just "Configured")

spp_demo:
- Fix Rosa Garcia age 67 → 72
- Fix Lorna Pascual age 32 → 55
cr.sudo().action_submit_for_approval()
cr.sudo().action_approve()
# Approve all tiers — multi-tier requires each tier's validator
cr.with_user(local_validator).sudo().action_approve()

Check warning

Code scanning / Semgrep OSS

Semgrep Finding: semgrep.odoo-sudo-without-context Warning

sudo() bypasses all access controls. Ensure this is: Intentional and documented Using minimal scope (e.g., .sudo().read(['field']) not .sudo()) Not exposing sensitive data to unauthorized users
cr.with_user(local_validator).sudo().action_approve()
if cr.approval_state == "pending":
# Still pending = more tiers, approve with HQ validator
cr.with_user(hq_validator).sudo().action_approve()

Check warning

Code scanning / Semgrep OSS

Semgrep Finding: semgrep.odoo-sudo-without-context Warning

sudo() bypasses all access controls. Ensure this is: Intentional and documented Using minimal scope (e.g., .sudo().read(['field']) not .sudo()) Not exposing sensitive data to unauthorized users
if rejection_reason and "rejection_reason" in cr._fields:
cr.sudo().write({"rejection_reason": rejection_reason})
# Use _do_reject directly to bypass the wizard
cr.with_user(local_validator).sudo()._do_reject(rejection_reason or "Request rejected")

Check warning

Code scanning / Semgrep OSS

Semgrep Finding: semgrep.odoo-sudo-without-context Warning

sudo() bypasses all access controls. Ensure this is: Intentional and documented Using minimal scope (e.g., .sudo().read(['field']) not .sudo()) Not exposing sensitive data to unauthorized users
if revision_notes and "revision_notes" in cr._fields:
cr.sudo().write({"revision_notes": revision_notes})
# Use _do_request_revision directly to bypass the wizard
cr.with_user(local_validator).sudo()._do_request_revision(

Check warning

Code scanning / Semgrep OSS

Semgrep Finding: semgrep.odoo-sudo-without-context Warning

sudo() bypasses all access controls. Ensure this is: Intentional and documented Using minimal scope (e.g., .sudo().read(['field']) not .sudo()) Not exposing sensitive data to unauthorized users
if apply:
try:
cr.sudo().action_apply()
cr.with_user(hq_validator).sudo().action_apply()

Check warning

Code scanning / Semgrep OSS

Semgrep Finding: semgrep.odoo-sudo-without-context Warning

sudo() bypasses all access controls. Ensure this is: Intentional and documented Using minimal scope (e.g., .sudo().read(['field']) not .sudo()) Not exposing sensitive data to unauthorized users
cr.sudo().action_submit_for_approval()
cr.sudo().action_approve()
# Approve all tiers — multi-tier requires each tier's validator
cr.with_user(local_validator).sudo().action_approve()

Check notice

Code scanning / Semgrep OSS

Semgrep Finding: semgrep.odoo-with-user-unvalidated Note

with_user() changes execution context. Verify: The user parameter is validated This doesn't create privilege escalation paths
cr.with_user(local_validator).sudo().action_approve()
if cr.approval_state == "pending":
# Still pending = more tiers, approve with HQ validator
cr.with_user(hq_validator).sudo().action_approve()

Check notice

Code scanning / Semgrep OSS

Semgrep Finding: semgrep.odoo-with-user-unvalidated Note

with_user() changes execution context. Verify: The user parameter is validated This doesn't create privilege escalation paths
if rejection_reason and "rejection_reason" in cr._fields:
cr.sudo().write({"rejection_reason": rejection_reason})
# Use _do_reject directly to bypass the wizard
cr.with_user(local_validator).sudo()._do_reject(rejection_reason or "Request rejected")

Check notice

Code scanning / Semgrep OSS

Semgrep Finding: semgrep.odoo-with-user-unvalidated Note

with_user() changes execution context. Verify: The user parameter is validated This doesn't create privilege escalation paths
if revision_notes and "revision_notes" in cr._fields:
cr.sudo().write({"revision_notes": revision_notes})
# Use _do_request_revision directly to bypass the wizard
cr.with_user(local_validator).sudo()._do_request_revision(

Check notice

Code scanning / Semgrep OSS

Semgrep Finding: semgrep.odoo-with-user-unvalidated Note

with_user() changes execution context. Verify: The user parameter is validated This doesn't create privilege escalation paths
if apply:
try:
cr.sudo().action_apply()
cr.with_user(hq_validator).sudo().action_apply()

Check notice

Code scanning / Semgrep OSS

Semgrep Finding: semgrep.odoo-with-user-unvalidated Note

with_user() changes execution context. Verify: The user parameter is validated This doesn't create privilege escalation paths
…rator

Add address, email, phone, birth_place, civil_status, ID documents,
and bank accounts to all demo registrants. Data is locale-aware across
Philippines, Togo, and Sri Lanka, and fully deterministic (seeded RNG).

Groups get: street address, city, zip, country, email, phone (char +
spp.phone.number with country), bank account (res.partner.bank),
household registration ID (spp.registry.id).

Individuals get: birth_place, civil_status (age-appropriate), email,
phone (char + spp.phone.number with country), national ID for adults
(age >= 15), birth certificate for children (age < 15).

- New DemographicEnricher utility class with batch and single-record modes
- Extend locale providers (fil_PH, fr_TG, si_LK) with cities, streets,
  phone formats, email domains, birth places, banks, ID format templates
- Integrate into SeededVolumeGenerator (Phase 5+6 after existing phases)
- Integrate into story registrant creation (enriches all story registrants)
- Add spp_banking dependency to manifest
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Target | Household (Group) |
| CEL (Eligibility) | `r.is_group == true and hh_total_income < poverty_line and hh_size >= 2` |
| CEL (Compliance) | `per_capita_income < poverty_line` |
Copy link
Copy Markdown
Contributor

@kneckinator kneckinator Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@emjay0921 does it make sense to have per_capita_income < poverty_line here?
Since it is conditionality, I would think something like if the per capita income is > 50% of the poverty line or something would make more sense?

Becuase since the total_hh_income must be less than poverty_line, I don't see how the average income across household members can be higher.

And since there is a need for at least two household members to be eligible, we would allow quite high aggregated household incomes before marking members as non_compliant.

…s, fix head enrollment

- Fix use case Country Name Equivalents: correct all Togolese and Sri Lankan
  names to match actual demo_stories.py mappings (e.g., Silva->Bandara,
  Agbeko->Lawson, Amouzou->Deku, etc.)
- Rewrite USE_CASES.md using QA's HH code format with all locale member
  names filled in, unified geographic table, corrected story IDs
- Add locale-aware area assignments to story registrants via STORY_AREA_MAP
  (specific areas per country for each story household/individual)
- Fix enroll_individual to find actual head member by membership type
  instead of first member by ID
- Verified 90/90 checks + 9/9 area assignments across all 3 locales
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants