Skip to content

feat(spp_api_v2_gis): promote to Beta with validation and exception fixes#147

Open
emjay0921 wants to merge 1 commit into19.0from
beta/spp-api-v2-gis
Open

feat(spp_api_v2_gis): promote to Beta with validation and exception fixes#147
emjay0921 wants to merge 1 commit into19.0from
beta/spp-api-v2-gis

Conversation

@emjay0921
Copy link
Copy Markdown
Contributor

Why is this change needed?

The spp_api_v2_gis module has been reviewed for Alpha to Beta promotion. Code review identified two issues: unvalidated GeoJSON geometry inputs in schemas, and suppressed exception chains in routers that make debugging difficult.

How was the change implemented?

Schema Validation

  • Added _validate_geojson_geometry() validator that checks geometry type is Polygon or MultiPolygon and coordinates is a non-empty array
  • Applied to SpatialQueryRequest, GeometryItem (batch), and GeofenceCreateRequest
  • Typed geofence_type as Literal["hazard_zone", "service_area", "targeting_area", "custom"] instead of open string

Exception Chaining

  • Changed from None to from e in 5 places across 3 routers (proximity, statistics, spatial_query)
  • Preserves exception chain for better debugging while still returning clean HTTP errors to clients

Beta Promotion

  • Bumped version 19.0.2.0.0 to 19.0.2.0.1
  • Changed development_status from Alpha to Beta
  • Added SPP module icon
  • Updated HISTORY.md

New unit tests

N/A — existing 191 tests all pass (0 failures)

Unit tests executed by the author

  • spp_api_v2_gis: 227 tests run, 0 failed, 0 errors

How to test manually

  1. Install module and generate MIS demo data (for area/report data)
  2. Get OAuth token via POST /api/v2/spp/oauth/token
  3. Test OGC collections, spatial queries, geofences using attached Postman collection
  4. Verify invalid geometries are rejected with 422 (e.g., {"type": "Point", "coordinates": [0,0]} should fail)

Related links

…ixes

Promote spp_api_v2_gis from Alpha to Beta after code review.

- Add GeoJSON geometry validation to spatial query and geofence schemas
  (type must be Polygon/MultiPolygon, coordinates must be non-empty)
- Type geofence_type as Literal enum instead of open string
- Fix exception chaining: use `from e` instead of `from None` in
  proximity, statistics, and spatial_query routers for better debugging
- Add SPP module icon
- Bump version 19.0.2.0.0 -> 19.0.2.0.1
- Update HISTORY.md
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 1, 2026

Codecov Report

❌ Patch coverage is 72.72727% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.06%. Comparing base (f738582) to head (2ae14e6).

Files with missing lines Patch % Lines
spp_api_v2_gis/schemas/query.py 77.27% 5 Missing ⚠️
spp_api_v2_gis/routers/proximity.py 0.00% 1 Missing ⚠️
spp_api_v2_gis/routers/spatial_query.py 0.00% 1 Missing ⚠️
spp_api_v2_gis/routers/statistics.py 0.00% 1 Missing ⚠️
spp_api_v2_gis/schemas/geofence.py 87.50% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             19.0     #147      +/-   ##
==========================================
- Coverage   71.06%   71.06%   -0.01%     
==========================================
  Files         925      925              
  Lines       54704    54731      +27     
==========================================
+ Hits        38876    38895      +19     
- Misses      15828    15836       +8     
Flag Coverage Δ
spp_api_v2_gis 71.64% <72.72%> (+0.11%) ⬆️
spp_base_common 90.26% <ø> (ø)
spp_dci_demo 69.23% <ø> (ø)
spp_mis_demo_v2 69.73% <ø> (ø)
spp_programs 62.20% <ø> (-0.03%) ⬇️
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_api_v2_gis/__manifest__.py 0.00% <ø> (ø)
spp_api_v2_gis/routers/proximity.py 46.15% <0.00%> (ø)
spp_api_v2_gis/routers/spatial_query.py 35.00% <0.00%> (ø)
spp_api_v2_gis/routers/statistics.py 36.66% <0.00%> (ø)
spp_api_v2_gis/schemas/geofence.py 96.87% <87.50%> (-3.13%) ⬇️
spp_api_v2_gis/schemas/query.py 93.82% <77.27%> (-6.18%) ⬇️

... and 1 file 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.

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 promotes the spp_api_v2_gis module to Beta status (v19.0.2.0.1), removing alpha-related warnings and updating documentation. Key improvements include the implementation of GeoJSON geometry validation for spatial queries and geofences, the addition of a module icon, and the use of proper exception chaining in routers for better debugging. Feedback suggests refining the error message formatting for invalid geometry types and enhancing coordinate validation to verify the structural nesting required for Polygon and MultiPolygon types.

Comment on lines +18 to +19
if geo_type not in _VALID_GEOMETRY_TYPES:
raise ValueError(f"geometry type must be one of {_VALID_GEOMETRY_TYPES}, got '{geo_type}'")
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 error message for invalid geometry types uses the default string representation of a Python set, which can look a bit unpolished (e.g., {'Polygon', 'MultiPolygon'}). It's better to format it as a sorted, comma-separated string for better readability.

Suggested change
if geo_type not in _VALID_GEOMETRY_TYPES:
raise ValueError(f"geometry type must be one of {_VALID_GEOMETRY_TYPES}, got '{geo_type}'")
if geo_type not in _VALID_GEOMETRY_TYPES:
valid_types = ", ".join(sorted(_VALID_GEOMETRY_TYPES))
raise ValueError(f"geometry type must be one of {valid_types}, got '{geo_type}'")

Comment on lines +21 to +22
if not coords or not isinstance(coords, list):
raise ValueError("geometry must have a non-empty 'coordinates' array")
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 validation for the coordinates field is quite basic. While it correctly checks for a non-empty list, it doesn't verify that the structure matches what's expected for a Polygon (list of lists of lists) or MultiPolygon (list of lists of lists of lists). While a full GeoJSON validator might be overkill, consider adding a check for minimum nesting depth to catch obviously malformed inputs like [0, 0] for a Polygon.

@gonzalesedwin1123
Copy link
Copy Markdown
Member

Increase the test coverage by at least 90%

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.

2 participants