493 lines
21 KiB
Markdown
493 lines
21 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 current Tower operator sample is available at:
|
|
|
|
```bash
|
|
REAL_RASTER_PATH=/mnt/user/appdata/geointel/storage/operator-data/geel_orthophoto_wms_512.tif \
|
|
REAL_REFERENCE_VECTOR_PATH=/mnt/user/appdata/geointel/storage/operator-data/geel_grb_gbg_buildings.geojson \
|
|
bash scripts/verify_real_data_detection_qa_workflow.sh http://192.168.10.150:1202
|
|
```
|
|
|
|
Those files are runtime artifacts generated from Digitaal Vlaanderen's
|
|
OMWRGBMRVL WMS `Ortho` layer and GRB OGC API Features `GBG` building collection
|
|
for a small Geel AOI. They are intentionally not repository fixtures.
|
|
|
|
To prepare the documented operator samples reproducibly inside the all-in-one
|
|
runtime container, run:
|
|
|
|
```bash
|
|
docker exec -it geointel python3 /app/scripts/prepare_operator_real_data_samples.py
|
|
```
|
|
|
|
This writes GeoTIFF/GeoJSON pairs and `operator_samples_manifest.json` under
|
|
`/app/storage/operator-data` inside the container, which maps to
|
|
`storage/operator-data` in the Tower appdata checkout. The default corpus
|
|
contains reference AOIs for Geel, Mol, Turnhout, Herentals, Balen, Retie and
|
|
Westerlo plus background candidates for Postel-bos, Lommel-heide and
|
|
Kasterlee-bos. Normal reference AOIs still fail when GRB returns no buildings;
|
|
background candidates are explicitly marked with `sample_role` and may write an
|
|
empty reference FeatureCollection for negative-tile training. The helper fetches
|
|
only the explicit documented AOIs, records Digitaal Vlaanderen attribution and
|
|
reuses existing files by default. Use `--force` only when the local runtime
|
|
artifacts should be regenerated.
|
|
|
|
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. Configured-YOLO model class labels are normalized to
|
|
lowercase for filtering and persisted detections, while the original model label
|
|
is retained in detection provenance. Raster tile manifests generated by the
|
|
workflow include source CRS metadata so persisted detection GeoJSON coordinates
|
|
can be transformed to WGS84. A zero detection count is accepted
|
|
operationally only when the selected model genuinely returns no usable
|
|
detections after class filtering; it must be interpreted as model/data quality
|
|
evidence rather than as a successful building extraction result.
|
|
|
|
Run a confidence-threshold calibration sweep against the same real-data path:
|
|
|
|
```bash
|
|
REAL_RASTER_PATH=/mnt/user/appdata/geointel/storage/operator-data/geel_orthophoto_wms_512.tif \
|
|
REAL_REFERENCE_VECTOR_PATH=/mnt/user/appdata/geointel/storage/operator-data/geel_grb_gbg_buildings.geojson \
|
|
CALIBRATION_THRESHOLDS="0.50 0.35 0.25 0.15" \
|
|
bash scripts/run_detection_calibration_sweep.sh http://192.168.10.150:1202
|
|
```
|
|
|
|
The sweep reuses `verify_real_data_detection_qa_workflow.sh` once per
|
|
threshold, so every row is backed by persisted Project, Dataset, AnalysisRun,
|
|
Detection, QualityCheck, Metric and export records. It writes per-threshold
|
|
logs plus `calibration_summary.json` under
|
|
`artifacts/detection-calibration/<timestamp>` unless
|
|
`CALIBRATION_OUTPUT_DIR` is set. This is a calibration/benchmarking tool only:
|
|
it does not seed demo data, enable fixture detections, fetch external data or
|
|
download model weights.
|
|
|
|
Run a broader model/tile/threshold quality matrix when multiple local model
|
|
assets or tile settings need to be compared:
|
|
|
|
```bash
|
|
REAL_RASTER_PATH=/mnt/user/appdata/geointel/storage/operator-data/geel_orthophoto_wms_512.tif \
|
|
REAL_REFERENCE_VECTOR_PATH=/mnt/user/appdata/geointel/storage/operator-data/geel_grb_gbg_buildings.geojson \
|
|
QUALITY_MODEL_ASSET_IDS="yolov8n-building-segmentation-pt yolov8n-pt" \
|
|
QUALITY_TILE_SIZES="512 640" \
|
|
QUALITY_TILE_OVERLAPS="64" \
|
|
QUALITY_THRESHOLDS="0.50 0.15" \
|
|
bash scripts/run_detection_quality_matrix.sh http://192.168.10.150:1202
|
|
```
|
|
|
|
The quality matrix repeats the same real-data upload, tiling, configured-YOLO,
|
|
QA/QC and export workflow for every model/tile/threshold row. It writes per-run
|
|
logs plus `quality_matrix_summary.json` under
|
|
`artifacts/detection-quality-matrix/<timestamp>` unless `QUALITY_OUTPUT_DIR` is
|
|
set. The summary ranks `best_by_score`, `best_by_recall` and
|
|
`best_by_precision` so the next model decision is based on persisted
|
|
`QualityCheck`/`Metric` evidence rather than visual guesses. It does not create
|
|
provider data, use fixtures or download model weights.
|
|
|
|
Run the same matrix across every prepared operator sample:
|
|
|
|
```bash
|
|
OPERATOR_SAMPLE_MANIFEST_PATH=storage/operator-data/operator_samples_manifest.json \
|
|
QUALITY_MODEL_ASSET_IDS="yolov8n-building-segmentation-pt yolov8n-pt" \
|
|
QUALITY_TILE_SIZES="512 640" \
|
|
QUALITY_TILE_OVERLAPS="64" \
|
|
QUALITY_THRESHOLDS="0.50 0.15" \
|
|
bash scripts/run_multi_sample_detection_quality_matrix.sh http://192.168.10.150:1202
|
|
```
|
|
|
|
The multi-sample wrapper writes one per-sample `quality_matrix_summary.json`
|
|
plus a combined `multi_sample_quality_summary.json` with
|
|
`best_overall_by_score`, `best_overall_by_recall`,
|
|
`best_overall_by_precision` and `best_by_sample` rankings. It resolves
|
|
container-style `/app/storage/...` manifest paths to repo-relative
|
|
`storage/...` paths when run from the Tower host checkout.
|
|
|
|
Export the same operator samples to a local YOLO detection dataset when the
|
|
public model candidates are not strong enough for the target imagery:
|
|
|
|
```bash
|
|
docker exec -it geointel python3 /app/scripts/export_operator_yolo_dataset.py \
|
|
--manifest-path /app/storage/operator-data/operator_samples_manifest.json \
|
|
--output-dir /app/storage/operator-data/yolo-building-dataset \
|
|
--val-samples turnhout \
|
|
--force
|
|
```
|
|
|
|
The exporter writes `dataset.yaml`, `images/train`, `labels/train`,
|
|
`images/val`, `labels/val` and `yolo_dataset_summary.json`. It uses only the
|
|
explicit operator sample manifest and GRB building references where
|
|
`source_name=grb` and `reference_layer_name=buildings`. It does not call
|
|
GeoIntel APIs, create provider data, run inference or train a model.
|
|
|
|
Run a small local training smoke only in an AI-enabled runtime with an existing
|
|
local base model file:
|
|
|
|
```bash
|
|
docker exec \
|
|
-e OPERATOR_YOLO_DATASET_DIR=/app/storage/operator-data/yolo-building-dataset \
|
|
-e YOLO_BASE_MODEL_PATH=/app/models/yolov8n.pt \
|
|
-e TRAIN_MODEL_OUTPUT_PATH=/app/models/geointel-building-detector.pt \
|
|
-e TRAIN_EPOCHS=8 \
|
|
-e TRAIN_IMGSZ=512 \
|
|
-e TRAIN_BATCH=2 \
|
|
-e TRAIN_WORKERS=0 \
|
|
-e TRAIN_DEVICE=cpu \
|
|
-e PYTHON_BIN=python3 \
|
|
geointel bash /app/scripts/train_operator_yolo_detector.sh
|
|
```
|
|
|
|
The training wrapper is intentionally outside the product UI. It runs
|
|
Ultralytics from the existing runtime, copies the best trained artifact to
|
|
`TRAIN_MODEL_OUTPUT_PATH` and writes `training_summary.json`. Afterward, treat
|
|
the resulting `.pt` file like any other local model asset: verify preflight,
|
|
run the real-data matrix and compare persisted QA/QC metrics before activating
|
|
it as a useful default.
|
|
|
|
When whole-image training does not improve QA/QC, export a tile-level dataset
|
|
with overlapping raster windows:
|
|
|
|
```bash
|
|
docker exec -it geointel python3 /app/scripts/export_operator_yolo_tile_dataset.py \
|
|
--manifest-path /app/storage/operator-data/operator_samples_manifest.json \
|
|
--output-dir /app/storage/operator-data/yolo-building-tile-expanded160 \
|
|
--tile-size 160 \
|
|
--stride 80 \
|
|
--negative-keep-ratio 1.0 \
|
|
--val-samples turnhout,retie,kasterlee_bos \
|
|
--force
|
|
```
|
|
|
|
The tile exporter clips GRB building bounding boxes into each tile, writes
|
|
YOLO labels beside each tile image, keeps a deterministic ratio of empty
|
|
negative tiles, and records `yolo_tile_dataset_summary.json` with
|
|
`positive_tile_count`, `negative_tile_count` and skipped negative tile counts.
|
|
It remains operator tooling only: no provider fetch, no API mutation and no
|
|
automatic model training.
|
|
|
|
Train against the tile dataset by pointing the existing wrapper at the tile
|
|
output directory:
|
|
|
|
```bash
|
|
docker exec \
|
|
-e OPERATOR_YOLO_DATASET_DIR=/app/storage/operator-data/yolo-building-tile-expanded160 \
|
|
-e YOLO_BASE_MODEL_PATH=/app/models/yolov8n.pt \
|
|
-e TRAIN_OUTPUT_DIR=/app/storage/training/operator-yolo \
|
|
-e TRAIN_RUN_NAME=geointel-building-yolov8n-expanded160e50 \
|
|
-e TRAIN_MODEL_OUTPUT_PATH=/app/models/geointel-building-yolov8n-expanded160e50.pt \
|
|
-e TRAIN_EPOCHS=50 \
|
|
-e TRAIN_IMGSZ=256 \
|
|
-e TRAIN_BATCH=8 \
|
|
-e TRAIN_WORKERS=0 \
|
|
-e TRAIN_DEVICE=cpu \
|
|
-e PYTHON_BIN=python3 \
|
|
geointel bash /app/scripts/train_operator_yolo_detector.sh
|
|
```
|
|
|
|
Benchmark any trained candidate through the same persisted QA/QC matrix before
|
|
using it operationally:
|
|
|
|
```bash
|
|
OPERATOR_SAMPLE_MANIFEST_PATH=storage/operator-data/operator_samples_manifest.json \
|
|
OPERATOR_SAMPLE_SLUGS="geel mol turnhout retie kasterlee_bos" \
|
|
QUALITY_MODEL_ASSET_IDS="geointel-building-yolov8n-expanded160e50-pt geointel-building-yolov8n-tile30-pt yolov8s-building-segmentation-pt" \
|
|
QUALITY_TILE_SIZES="640" \
|
|
QUALITY_TILE_OVERLAPS="64" \
|
|
QUALITY_THRESHOLDS="0.25 0.15 0.05" \
|
|
MULTI_SAMPLE_OUTPUT_DIR=artifacts/detection-quality-matrix/multi-sample/expanded160e50-live \
|
|
bash scripts/run_multi_sample_detection_quality_matrix.sh http://192.168.10.150:1202
|
|
```
|
|
|
|
The expanded 50-epoch candidate improved dense Geel/Mol/Turnhout/Retie scores,
|
|
but the sparse Kasterlee-bos run still showed too many false positives. Treat it
|
|
as the best current experimental dense-AOI candidate, not as a V1 default.
|
|
|
|
Export calibration QA evidence for visual review:
|
|
|
|
```bash
|
|
CALIBRATION_SUMMARY_PATH=/mnt/user/appdata/geointel/artifacts/detection-calibration/20260707T002103Z/calibration_summary.json \
|
|
bash scripts/export_detection_calibration_evidence.sh http://192.168.10.150:1202
|
|
```
|
|
|
|
The evidence export reads each persisted `quality_check_id`, calls the existing
|
|
QA evidence GeoJSON endpoint, writes `calibration_evidence.geojson`,
|
|
`calibration_evidence_summary.json` and a standalone
|
|
`calibration_evidence_review.html` with an SVG overview of matched detections,
|
|
matched references, false positives and false negatives. Set
|
|
`CALIBRATION_EVIDENCE_MODE=best` to export only the `best_by_score` run.
|
|
|
|
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
|
|
```
|