Configuration
Everything the Settings screens write, they write through these routes. Zones and regions shape the ground; rules and doctrine decide what the system may do on it.
Zones
A zone is a named, categorised, shaped area. Its category is what the system acts
on: boundary is the geofence, keep_out is a solver hard constraint, jam and
gps_denied degrade comms in simulation, free_fire changes weapons posture,
isr_priority is a coverage objective, no_go and corridor steer navigation.
curl -X POST https://<your-backend-host>/api/zones \
-H "Content-Type: application/json" \
-d '{
"name": "tank farm keep-out",
"category": "keep_out",
"shape": { "shape": "circle", "center": [1.3521, 103.8198], "radius_m": 350 },
"band": { "ceiling_m": 120 }
}'
| Field | Required | Type | Meaning |
|---|---|---|---|
name | yes | string | Shown on the map and in every rule firing that cites the zone. |
category | yes | string | One of the categories above. |
shape | yes | object | Tagged by shape: circle (center as [lat, lon], radius_m) or polygon (points, at least 3). |
band | no | object | Vertical extent in metres above ground: floor_m, ceiling_m. Absent ends are open, so {} is every altitude. |
region_id | no | string | Scope to one region, or global when absent. |
params | no | object | Per-category knobs: priority for ISR weight, strength for jam intensity. |
GET /api/zones lists, PUT /api/zones/{id} replaces, DELETE /api/zones/{id}
removes. Writes take effect in the running rules on the next tick; a keep-out drawn
here is a keep-out the solver honours immediately. A 400 names the exact
validation rule: empty name, non-positive radius, a polygon under three points, or
an inverted altitude band.
Regions
A region is a defended place: where the map centres and what a scenario runs over.
GET/POST /api/regions, PUT/DELETE /api/regions/{id}, and
PUT /api/workspace/default-region selects the one the console opens on.
GET /api/meta returns the deployment's own description of itself: its regions and
defaults in one response.
Sensors
Emplaced sensors (a radar mast, an RF array) are placed with a position and a profile, then cued at tracks:
curl -X POST https://<your-backend-host>/api/sensors/rf-north/cue \
-H "Content-Type: application/json" \
-d '{ "track_id": "T-00492" }'
curl -X POST https://<your-backend-host>/api/sensors/rf-north/cue/release
GET /api/sensors/profiles lists the placeable profiles; GET /api/sensors
returns each placed sensor with its live pointing. A cue is a request: the sensor
reports where it is actually looking, and the picture renders that report, not the
request.
Doctrine, rules and settings
The decision loop runs the stored rule set, gated by posture and tuned by thresholds. Each has a small CRUD surface, and the whole of it exports as one document:
| Routes | What they hold |
|---|---|
GET/PUT/POST/PATCH/DELETE /api/rules, POST /api/rules/validate, GET /api/rules/library | The rule rows the loop runs, a validator for one row, and the shipped rule packs. |
GET/PUT /api/thresholds | The settings registry: every tunable key, its value, and where the value came from. |
GET/PUT /api/posture | The alert-state and control-status matrix, and the release table under it. |
GET/PUT /api/decision-config | The engagement, identification, geography and alerting policies. |
GET/PUT /api/influence | Operator influence over the planner: pinned pairs and weights. |
GET/PUT /api/planning-profiles | The profiles the planner authors one plan per pass for. |
GET /api/strategies | The compiled-in behaviour and solver strategy catalogues. |
GET /api/doctrine | Everything above, aggregated in one read. |
The export is a versioned YAML document, and the import round-trips it:
curl https://<your-backend-host>/api/doctrine/export > doctrine.yaml
curl -X POST https://<your-backend-host>/api/doctrine/import \
-H "Content-Type: application/yaml" --data-binary @doctrine.yaml
That makes doctrine reviewable the way code is: exported, diffed, committed, and
applied to another deployment. The same pattern covers the physical deployment:
GET /api/manifest.yaml downloads every asset, link and sensor as one document,
and POST /api/manifest applies one (with "dry_run": true to see the report
without writing).
Secrets
Credentials for integrations go into a write-only store: PUT /api/secrets/{name}
stores a value, GET /api/secrets lists names and hints, DELETE removes one.
There is deliberately no route that returns a value; a stored secret is referenced
by name (secret://…) in integration config and resolved server-side. 503 means
the store's encryption key is not configured on this deployment.