Files
geointel/scripts/README.md
T
Codex f0a58011fe
GeoIntel CI / docs-smoke (push) Has been cancelled
GeoIntel CI / contract-smoke (push) Has been cancelled
Add real data detection QA workflow smoke
2026-07-07 00:19:23 +02:00

286 lines
12 KiB
Markdown

# Scripts
Setup-, import-, demo- en maintenance-scripts voor GeoIntel.
## Runtime verification
Audit the active backend route surface against `docs/API_CONTRACTS.md`:
```bash
python scripts/audit_api_contracts.py
```
The audit imports the FastAPI app, compares implemented `GET`/`POST`/`PATCH`/
`DELETE` routes with active API contract headings and tracks the explicit
non-envelope exceptions (`/health` and export downloads). It fails when a route
exists without docs or when docs claim an endpoint that is not implemented.
Verify the browser-facing Docker/LAN runtime:
```bash
bash scripts/verify_browser_runtime.sh http://192.168.10.150:1202
bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202
```
Verify the explicit demo workflow plus export artifact path:
```bash
bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202
```
The demo/export smoke is intentionally mutating and idempotent: it seeds the
offline fixture demo if needed, verifies the project area GeoJSON, fixture
datasets, vector FeatureCollection content, vector feature summary, persisted
QA/QC metrics, creates metadata/report/vector GeoJSON exports, lists exports
and downloads the JSON/GeoJSON/HTML artifacts through the frontend proxy. The
persisted QA/QC result is compared against `fixtures/golden/expected_qa_metrics.json`
so runtime demo precision, recall, F1, mean IoU and false-positive/negative
counts cannot drift silently.
Verify the explicit demo raster workflow:
```bash
bash scripts/verify_demo_raster_workflow.sh http://192.168.10.150:1202
```
The raster smoke is intentionally mutating and idempotent enough for local
runtime checks: it seeds the offline demo workflow, validates the
`demo_context_raster.tif` fixture dataset, then exercises raster inspect,
preview, stats and one small tile/manifest generation through canonical
`data` envelopes. It does not run AI inference or fetch external imagery.
Verify that the browser-facing workbench can populate the default demo start
state through the frontend proxy:
```bash
bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202
```
This smoke is dependency-light and intentionally idempotent: it seeds the
offline demo workflow, then verifies that `GeoIntel Demo - Building QA` exposes
the `Demo AOI - Geel buildings` map geometry, `3/3 ready` demo datasets
(candidate vector, reference vector and raster fixture) and a persisted QA/QC
result through canonical `data.items` envelopes. Pair it with a Codex/browser
screenshot pass when checking visual layout or overflow.
Verify the backing state for the core workbench interactions:
```bash
bash scripts/verify_workbench_interactions.sh http://192.168.10.150:1202
```
This smoke validates the state behind project switching, AOI/map selection,
dataset selection, QA refresh and export refresh through the same frontend
proxy used by the browser. The frontend also exposes stable `data-testid`
anchors for Codex/browser click checks on those controls.
Verify the browser click handoff from raster tiling into Detection and
Segmentation Lab:
```bash
bash scripts/verify_ai_handoff_interactions.sh http://192.168.10.150:1202
```
The AI handoff smoke seeds the explicit offline demo workflow, generates a
small raster tile manifest, opens the workbench in Chromium, clicks the raster
inspector `Use in Detection Lab` and `Use in Segmentation Lab` actions, and
verifies that the selected raster dataset plus manifest path are populated in
the AI workspace. Playwright/Chromium must be available in the runner
environment; GeoIntel does not add Playwright as a frontend dependency by
default. The main readiness gate checks this script's syntax only.
Capture visual regression handoff screenshots for the workbench:
```bash
bash scripts/capture_workbench_screenshots.sh http://192.168.10.150:1202
CAPTURE_MOBILE=0 bash scripts/capture_workbench_screenshots.sh http://192.168.10.150:1202 /tmp/geointel-screens
```
The capture script seeds the explicit offline demo workflow, opens each main
workspace, captures viewport desktop screenshots and, by default, viewport
mobile screenshots.
It writes PNG files plus `manifest.json` under `artifacts/screenshots/...` or a
caller-provided output directory. Playwright/Chromium must be available in the
runner environment; GeoIntel does not add Playwright as a frontend dependency
by default. The main readiness gate checks script syntax only.
Verify the deterministic QA/QC golden benchmark:
```bash
bash scripts/verify_golden_qa_benchmark.sh
python scripts/run_golden_qa_benchmark.py --json
```
The benchmark uses only explicit local fixtures under `fixtures/golden`,
executes the existing QA/QC matching logic, verifies the expected precision,
recall, F1, mean IoU and false-positive/false-negative counts, and checks that
`QualityCheck` plus `Metric` rows would be persisted. Scenarios are listed in
`fixtures/golden/golden_qa_benchmarks.json` and currently cover partial match,
perfect match, no-overlap and MultiPolygon building comparisons. The main
readiness gate runs this benchmark so QA metric drift fails before a release.
Verify a configured local YOLO model without running inference:
```bash
python scripts/yolo_preflight.py --model-path /absolute/path/to/model.pt --tile-manifest-path /absolute/path/to/manifest.json --check-model-load --json
```
Against the Docker runtime:
```bash
docker compose exec -T backend python scripts/yolo_preflight.py --model-path /absolute/path/to/model.pt --tile-manifest-path /absolute/path/to/manifest.json --check-model-load --json
```
The model-load smoke is opt-in, requires real optional AI dependencies, refuses
`--assume-dependencies`, loads only the supplied local file and does not download
weights or run prediction.
Verify the full configured-YOLO model asset workflow against a running runtime:
```bash
bash scripts/verify_model_asset_detection_workflow.sh http://192.168.10.150:1202
```
This smoke is intentionally mutating and requires a real AI-enabled runtime with
at least one mounted local model asset. It seeds the explicit offline demo
workflow, generates a small raster tile manifest, selects the active local model
asset from `GET /api/v1/detection/model-assets`, validates read-only YOLO
preflight, runs `POST /api/v1/detection/run`, and verifies the persisted
AnalysisRun, Detection list and Detection GeoJSON endpoints. A zero detection
count is allowed because the demo raster is a synthetic runtime fixture; the
script validates the operational path and provenance, not production model
quality. The main readiness gate checks this script's syntax only.
Verify the full operator-provided raster/reference detection and QA path:
```bash
REAL_RASTER_PATH=/mnt/user/appdata/geointel/data/orthophoto.tif \
REAL_REFERENCE_VECTOR_PATH=/mnt/user/appdata/geointel/data/reference-buildings.geojson \
bash scripts/verify_real_data_detection_qa_workflow.sh http://192.168.10.150:1202
```
The real-data smoke is intentionally mutating and refuses to run without
operator-supplied files. Current V1 upload support expects a georeferenced
`.tif`, `.tiff` or `.geotiff` raster and a `.geojson` or `.json` reference
building vector. The script creates a project, uploads the raster as a source
dataset, uploads the vector as a `reference` dataset, validates raster/vector
metadata, tiles the raster, selects a mounted local model asset, verifies
read-only YOLO preflight, runs configured YOLO detection, runs detection QA
against persisted `vector_features`, and exports the detection run as GeoJSON.
It does not seed demo data, enable fixture detections, fetch external data or
download model weights. A zero detection count is accepted operationally, but
must be interpreted as model/data quality evidence rather than as a successful
building extraction result.
Docker images install only the GIS runtime by default. To build a local/Tower
image with PyTorch/Ultralytics available for the configured-YOLO preflight and
runtime path, set:
```bash
GEOINTEL_INSTALL_AI=true
```
For Unraid/all-in-one deployments, place model files under
`GEOINTEL_MODELS_PATH` so they appear in the container under `/app/models`, then
set `YOLO_ENABLED=true`, `YOLO_MODELS_DIR=/app/models` and
`YOLO_MODEL_PATH=/app/models/<model>.pt`.
Configure the Unraid/Tower env file from an existing local model without
downloading weights or running inference:
```bash
python scripts/configure_yolo_model.py \
--models-dir /mnt/user/appdata/geointel/models \
--env-file /mnt/user/appdata/geointel/.env
```
If exactly one supported model file (`.pt`, `.onnx` or `.engine`) is present,
apply the env update explicitly:
```bash
python scripts/configure_yolo_model.py \
--models-dir /mnt/user/appdata/geointel/models \
--env-file /mnt/user/appdata/geointel/.env \
--apply
```
The configurator refuses to proceed when no model exists or when multiple model
files are present without `--model-file`. It writes only
`GEOINTEL_INSTALL_AI=true`, `YOLO_ENABLED=true`, `YOLO_MODELS_DIR=/app/models`
and the mounted `YOLO_MODEL_PATH`.
Clean old offline demo export artifacts without touching uploaded source data:
```bash
python scripts/cleanup_demo_artifacts.py
python scripts/cleanup_demo_artifacts.py --keep-latest 10 --export-type project_report_html
python scripts/cleanup_demo_artifacts.py --keep-latest 10 --max-delete 100 --apply
```
Against the Docker runtime, run the backend-container entrypoint:
```bash
docker compose exec -T backend python scripts/cleanup_demo_artifacts.py
docker compose exec -T backend python scripts/cleanup_demo_artifacts.py --keep-latest 10 --export-type project_report_html
docker compose exec -T backend python scripts/cleanup_demo_artifacts.py --keep-latest 10 --max-delete 100 --apply
```
The cleanup script is dry-run by default. It only targets the explicit
`GeoIntel Demo - Building QA` project unless `--project-name` is provided, keeps
the newest exports per matching project, deletes only `exports` rows/files when
`--apply` is set, and refuses to remove files outside the configured
`STORAGE_ROOT`. `--max-delete` defaults to 25 and blocks large cleanup runs until
the operator raises it after reviewing dry-run output. Repeat `--export-type` to
limit cleanup to specific artifact kinds such as `project_report_html` or
`project_metadata_json`.
Verify the cleanup path against a running backend without deleting anything:
```bash
bash scripts/verify_demo_cleanup_dry_run.sh
CLEANUP_MODE=compose bash scripts/verify_demo_cleanup_dry_run.sh
CLEANUP_MODE=container CLEANUP_CONTAINER=geointel bash scripts/verify_demo_cleanup_dry_run.sh
```
The smoke runs the cleanup command without `--apply`, expects `dry_run=true`,
expects `deleted_export_count=0`, verifies candidate fields are present and
prints the matched/type-filtered/selected counts. Use `KEEP_LATEST`,
`MAX_DELETE` and `EXPORT_TYPE` environment variables to adjust the dry-run
thresholds without changing the script. The main readiness gate checks this
script's syntax; run it explicitly against Docker/PostGIS when validating a
live deployment.
## Tower deployment
Push the local branch to Gitea, then rebuild the Unraid/Tower Docker runtime:
```bash
bash scripts/deploy_tower.sh
```
From the Codex Windows workspace, use the PowerShell wrapper:
```powershell
.\scripts\deploy_tower.ps1
```
For the first deployment into an existing non-Git appdata folder, bootstrap the
checkout explicitly:
```bash
DEPLOY_BOOTSTRAP=1 bash scripts/deploy_tower.sh
```
```powershell
.\scripts\deploy_tower.ps1 -Bootstrap
```
Useful overrides:
```bash
REMOTE_HOST=root@192.168.10.150
REMOTE_PATH=/mnt/user/appdata/geointel
REMOTE_REPO=gitea-widefrog:NuklearRabbit/geointel.git
FRONTEND_URL=http://192.168.10.150:1202
```