Skip to content

feat: nested geofences (grant area_manager access to all child areas of a region) #111

Description

@dadofsambonzuki

Problem

Today, the area_manager role is scoped by a flat list of numeric area IDs in the user.geofence column (e.g., [364, 935, 53, ...]). This has two limitations:

  1. No nesting — granting "UK area admin" requires listing every UK community (country + 40+ community areas). If a new community is created inside the UK, it must be manually added to the geofence list.
  2. Static lists — an admin must maintain geofence lists manually, running DB queries to discover new areas within the permitted region.

Example: ollie has geofence = [364, 53, 79, 93, 98, 100, ...] (43 IDs for UK country + all communities). A cleaner model would be geofence = [364] and the API resolves "all areas nested within area 364."

Proposed solution

Allow a single parent area ID in the geofence to imply access to all child areas dynamically. The check changes from:

geofence.contains(&area_id)

to something like:

geofence.contains(&area_id) || is_nested_within_any(area_id, &geofence)

Where is_nested_within_any does a spatial containment check: the child area's centroid (or bounding box) falls within the geofenced parent area's polygon. This would also enable automatic access to newly created areas within the permitted region — no geofence list syncing required.

Implementation considerations:

  • Spatial containment: the API already stores area polygons as GeoJSON in area.tags.geo_json. A centroid or bbox containment check against the parent area's geometry is sufficient. The area.bbox_west/south/east/north columns make this efficient (a quick index scan before the full polygon check).
  • Fallback behavior: if the geofence contains a non-country area (e.g., a community), only that specific area is accessible — no implicit children because communities don't nest.
  • Backward compatibility: existing flat-list geofences should continue working. The containment check is additive.
  • Performance: for add_area, the user can't create new top-level areas when geofenced — but they could create communities inside their permitted region. The containment check for one area is cheap; for listing, a bbox pre-filter avoids full-polygon checks.

Alternative considered

A geofence_mode column (flat vs nested) to opt in, but that adds schema complexity. Simpler to make the behavioral change transparent: if a geofenced parent area contains the target area, access is granted.

Related

  • area_manager role introduced in recent schema migrations (geofence column on user)
  • check_geofence() in api/src/service/area.rs is the central enforcement point
  • Ref: set_user_geofence RPC, add_area handler (blocks area managers with non-empty geofence from creating new areas)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

enhancementNew feature or request

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions