Skip to content

Comments

feat: Add regions support for geographic analysis#82

Merged
anth-volk merged 10 commits intoapp-v2-migrationfrom
feat/add-regions-support
Feb 17, 2026
Merged

feat: Add regions support for geographic analysis#82
anth-volk merged 10 commits intoapp-v2-migrationfrom
feat/add-regions-support

Conversation

@anth-volk
Copy link
Contributor

Fixes #81

Summary

Adds support for regions (geographic areas) to enable location-specific policy analysis.

Changes

  • Region Model (src/policyengine_api/models/region.py):

    • code - Region identifier (e.g., "state/ca", "us")
    • label - Display name (e.g., "California")
    • region_type - Type of region (e.g., "state", "congressional_district")
    • requires_filter - Whether dataset filtering is needed
    • filter_field / filter_value - Parameters for dataset filtering
    • dataset_id - Associated dataset (FK)
    • tax_benefit_model_id - Associated model (FK)
  • Endpoints (src/policyengine_api/api/regions.py):

    • GET /regions/ - List regions with optional filters by model and region type
    • GET /regions/{region_id} - Get region by UUID
    • GET /regions/by-code/{region_code} - Get region by code
  • Analysis Integration (src/policyengine_api/api/analysis.py):

    • Added region parameter to economic impact request
    • Added _resolve_dataset_and_region() helper for dataset/region resolution
  • Migration (alembic/versions/20260210_add_regions_table.py):

    • Creates regions table with all required columns and foreign keys

TODO

  • Add seed data for US and UK regions
  • Wire filter_field/filter_value through to policyengine.py simulation execution
  • Add tests

Related

  • policyengine.py PR #231 adds dataset filtering support
  • App v2 branch feat/migrate-geographies-to-v2 adds frontend regions hook

🤖 Generated with Claude Code

@anth-volk anth-volk marked this pull request as ready for review February 10, 2026 22:44
@anth-volk anth-volk marked this pull request as draft February 10, 2026 22:44
@anth-volk anth-volk force-pushed the feat/add-regions-support branch from 321e7b9 to 6a19d4a Compare February 12, 2026 16:00
@anth-volk anth-volk changed the base branch from main to app-v2-migration February 16, 2026 22:07
anth-volk and others added 8 commits February 17, 2026 00:40
- Add Region SQLModel with filtering fields (code, label, region_type,
  requires_filter, filter_field, filter_value, dataset_id, etc.)
- Add Alembic migration for regions table
- Add GET /regions/ endpoint with filters by model and region type
- Add GET /regions/{region_id} and GET /regions/by-code/{code} endpoints
- Add region parameter to analysis endpoint with dataset/region resolution

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add filter_field and filter_value to Simulation model
- Include filter params in deterministic simulation ID generation
- Pass filter params from region to simulation creation
- Pass filter params to policyengine.py PESimulation when running

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Wire filter_field/filter_value through Modal functions to policyengine.py:
  - simulate_economy_uk, simulate_economy_us
  - economy_comparison_uk, economy_comparison_us
- Add fixtures_regions.py with factory functions for test data
- Add 25 unit tests for region resolution and filtering:
  - test__given_region_with_filter__then_filter_params_included.py
  - test__given_region_without_filter__then_filter_params_none.py
  - test__given_dataset_id__then_region_is_none.py
  - test__given_same_params__then_deterministic_id.py
  - test__given_invalid_region__then_404_error.py
  - test__given_existing_simulation__then_reuses_existing.py

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add seed_regions.py to populate the regions table with geographic data
from policyengine.py's region registries:

- US: National + 51 states (DC included)
- UK: National + 4 countries (England, Scotland, Wales, NI)

Optional flags:
- --include-places: Add US cities (333 places over 100K population)
- --include-districts: Add US congressional districts (436)
- --us-only / --uk-only: Seed only one country

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add --skip-regions, --include-places, and --include-districts CLI options
to seed.py. Regions are now seeded as part of the standard database setup
process, sourcing region definitions from policyengine.py's registries.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Default behavior now seeds all US regions (national, states, districts, places).
Use --skip-places and --skip-districts to exclude specific region types.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Break up monolithic seed.py into focused subscripts:
- seed_utils.py: Shared utilities (get_session, bulk_insert, console)
- seed_models.py: TaxBenefitModel, Version, Variables, Parameters, ParameterValues
- seed_datasets.py: Dataset seeding and S3 upload
- seed_policies.py: Example policy reforms
- seed_regions.py: Geographic regions (updated to use seed_utils)

Main seed.py is now an orchestrator with preset configurations:
- full: Everything (default)
- lite: Both countries, 2026 only, skip state params, core regions
- minimal: Both countries, 2026 only, no policies/regions
- uk-lite, uk-minimal: UK-only variants
- us-lite, us-minimal: US-only variants

Each subscript can also run standalone with its own CLI.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tests were written before _get_or_create_simulation and
_get_deterministic_simulation_id gained the simulation_type parameter.
Add SimulationType.ECONOMY and use keyword args for dataset_id/filter
params to match the current function signatures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@anth-volk anth-volk force-pushed the feat/add-regions-support branch from 4d515ce to 048b7e2 Compare February 16, 2026 23:40
anth-volk and others added 2 commits February 17, 2026 01:00
Merge 6 separate test__given_* files into test_analysis.py organized
by function tested: TestResolveDatasetAndRegion, TestGetDeterministicSimulationId,
TestGetOrCreateSimulation. Fix pre-existing test_missing_dataset_id assertion
(400 not 422). Move @pytest.mark.integration from file-level to class-level.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This test hits the real database (valid request passes validation),
so it needs a running Supabase instance like the other integration tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@anth-volk anth-volk marked this pull request as ready for review February 17, 2026 00:10
@anth-volk anth-volk merged commit 74b236c into app-v2-migration Feb 17, 2026
1 check passed
@anth-volk anth-volk deleted the feat/add-regions-support branch February 17, 2026 00:10
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.

Add regions support for geographic analysis

1 participant