feat: add governed nationwide AOI orchestration and CUDA enforcement
GeoIntel release gates / Compile, test, contracts and builds (push) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (push) Canceled after 0s
GeoIntel release gates / GIS image, SBOM and container scan (push) Canceled after 0s

This commit is contained in:
Jens
2026-07-26 05:23:33 +02:00
parent 25b6f1ab39
commit 2be72fac58
50 changed files with 1596 additions and 51 deletions
+85 -4
View File
@@ -275,6 +275,74 @@ Idempotently creates or returns a project Area from the exact persisted NGI
municipality geometry. The resulting Area can be used by all existing bounded
selection, acquisition, analysis and export contracts.
## Resumable AOI operations
### POST `/api/v1/projects/{project_id}/aoi-operations`
Creates one persisted parent operation and deterministic bounded partitions.
Exactly one of `area_id` or an EPSG:4326 `bbox` is required. Partitioning is
calculated in EPSG:31370 and clipped to the exact AOI; source side limits remain
server concerns. Optional `coverage_zone` clips the immutable AOI snapshot to
the persisted legal/regional scope before planning. The production worker
automatically claims queued children; clients poll the parent instead of
driving provider requests.
```json
{
"area_id": "optional-uuid",
"operation_type": "acquire",
"provider_key": "grb",
"product_key": "buildings",
"max_partition_side_m": null,
"max_attempts": 3,
"parameters_json": {"force_refresh": false}
}
```
When `max_partition_side_m` is omitted, the backend derives the limit from the
governed provider registry. An explicit value can only make partitions smaller,
never relax the provider budget. The response reports parent status, progress from `0.0` to `1.0`, per-status
partition counts and child partition evidence. Stable partition keys make
planning and completion idempotent.
### GET `/api/v1/projects/{project_id}/aoi-operations/{operation_id}`
Returns the persisted operation, aggregate progress and every child state.
### GET `/api/v1/projects/{project_id}/aoi-operations`
Lists the most recent parent operations for the project with their derived
progress, status counts and child evidence.
### POST `/api/v1/projects/{project_id}/aoi-operations/{operation_id}/execute-next`
Claims and executes one queued partition through the registered governed
provider. Registered executors cover `grb`, `orthophoto`, `dhmv`,
`spw_terrain`, `official_vector`, `flood_hazard`, `thematic_raster`, `walous`,
`bathymetry_profiles` and `mdk_bathymetry`; their existing configuration and
zone contracts remain authoritative. Every
execution creates a linked child Job. Transient provider failures are retried
within the stored attempt budget; validation failures fail immediately.
### POST `/api/v1/projects/{project_id}/aoi-operations/{operation_id}/partitions/claim`
Atomically claims the next queued child using a locked, skip-locked database
selection. Returns `data: null` when no queued child remains.
### PUT `/api/v1/projects/{project_id}/aoi-operations/{operation_id}/partitions/{partition_id}/checkpoint`
Persists provider-specific restart evidence for a running child.
### POST `/api/v1/projects/{project_id}/aoi-operations/{operation_id}/partitions/{partition_id}/complete`
Marks a running child successful or explicitly skipped. Repeating completion
for a terminal successful/skipped child is idempotent.
### POST `/api/v1/projects/{project_id}/aoi-operations/{operation_id}/partitions/{partition_id}/fail`
Records an error and either returns the child to `queued` within its attempt
budget or terminalizes it as `failed`.
## Datasets
### POST `/api/v1/projects/{project_id}/datasets/upload`
@@ -1098,7 +1166,8 @@ mode, source URL, attribution, licence and limitation text.
Allowed result states are exactly:
- `operational`: a matching `ready` Dataset is materialized in the project;
- `operational`: one matching `ready` Dataset or the spatial union of governed
partition Datasets covers the complete selection;
- `partial`: the governed integration exists but matching project data is
absent or incomplete;
- `not_configured`: an audited source has no operational adapter;
@@ -1124,7 +1193,9 @@ Areas. Cross-region and land/sea selections remain split by zone.
The response returns `intersected_zones`, `outside_supported_scope`, one item
per zone/theme combination, matching source names and IDs of actually
materialized Datasets. An empty `themes` list requests the complete normalized
materialized Datasets. Every materialized item also carries evidence for
authority, source version, observation/publication time, CRS, resolution,
coverage bbox, attribution, licence and checksum where persisted. An empty `themes` list requests the complete normalized
vocabulary. Unknown themes fail with `COVERAGE_THEME_UNSUPPORTED`.
The Map workbench uses this response before a rectangle analysis. It queries
@@ -1396,6 +1467,7 @@ Response data:
"checks": {
"enabled": true,
"dependencies_available": true,
"accelerator_ready": true,
"model_path_set": false,
"model_file_exists": null,
"model_load_requested": false,
@@ -1411,7 +1483,9 @@ Response data:
"yolo_config_dir": "/app/storage/ultralytics",
"torch_version": "2.12.1",
"ultralytics_version": "8.4.88",
"cuda_available": false
"cuda_available": true,
"configured_device": "cuda:0",
"cuda_required": true
},
"tile_count": 0,
"max_tiles": 100,
@@ -1422,7 +1496,14 @@ Response data:
### POST `/api/v1/detection/run`
Creates a detection job and detection analysis run. If the requested model is unavailable, the job and analysis run are marked `failed` with `DETECTION_MODEL_UNAVAILABLE` or `DETECTION_DEPENDENCY_UNAVAILABLE`.
Creates a detection job and detection analysis run. If the requested model is unavailable, the job and analysis run are marked `failed` with `DETECTION_MODEL_UNAVAILABLE` or `DETECTION_DEPENDENCY_UNAVAILABLE`. When `YOLO_REQUIRE_CUDA=true`, missing CUDA or a CPU device selection fails closed with `DETECTION_ACCELERATOR_UNAVAILABLE` or `DETECTION_ACCELERATOR_MISCONFIGURED`; production inference never silently falls back to CPU.
The configured model exposes only classes declared by `YOLO_MODEL_CLASSES`;
the current promoted server detector is building-only. Unsupported class
filters fail with `DETECTION_CLASS_NOT_VALIDATED`. With production scope
enforcement enabled, the raster must belong to a persisted Area matching the
configured validated Mol/Kempen evidence or inference fails with
`DETECTION_VALIDATION_SCOPE_UNAVAILABLE`.
Request: