Die API v1 ist als Produktgrenze geschärft in [dto.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host_api/src/dto.rs>) und [server.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host_api/src/server.rs>): getrennte Modelle für `state`, `preview`, `snapshot`, `command response`, `event stream` und stabile Fehlerobjekte mit echten Codes statt generischem Fallback. Dazu kamen `GET /api/v1/state` und `GET /api/v1/preview`, neue persistenzbezogene Commands wie `save_preset`, `save_creative_snapshot`, `recall_creative_snapshot`, `set_transition_style` und `upsert_group`, plus serverseitige Durchreichung der echten Fehlercodes. Die kreative Web-UI in [index.html](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/web/v1/index.html>), [app.js](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/web/v1/app.js>) und [styles.css](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/web/v1/styles.css>) nutzt jetzt genau diese API für Preset-Speichern/Überschreiben, Varianten, Transition-Style, filterbaren Eventfeed und klarere Preview-Darstellung, ohne Parallelarchitektur. Die Doku ist auf den neuen Stand gezogen in [docs/host_api.md](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/docs/host_api.md>), [README.md](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/README.md>), [docs/build_and_deploy.md](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/docs/build_and_deploy.md>) und [docs/architecture.md](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/docs/architecture.md>). Verifiziert habe ich `cargo check -q` und `cargo test -q`; dabei laufen die erweiterten Contract- und Persistenztests in [contract.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host_api/tests/contract.rs>) sowie neue Core-Tests in [show_store.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host/src/show_store.rs>) und [simulation.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host/src/simulation.rs>). Nicht separat verifiziert habe ich einen echten Browserlauf der Web-UI; die JS-Datei wurde hier nicht mit `node` geprüft, weil `node` in dieser Umgebung nicht installiert ist.
8.5 KiB
Host API
Purpose
The host API is the stable external product boundary for:
- the creative web UI
- the native engineering GUI
- future remote operator clients
- later external show-control adapters such as a grandMA bridge
The realtime rule remains strict:
- the API is a control and observation layer
- the host core remains the timing authority
- no frontend or external adapter is allowed to become the LED clock
Runtime Components
Core and API implementation:
crates/infinity_host/src/control.rscrates/infinity_host/src/scene.rscrates/infinity_host/src/show_store.rscrates/infinity_host/src/simulation.rscrates/infinity_host/src/external_control.rscrates/infinity_host_api/src/dto.rscrates/infinity_host_api/src/server.rs
Server startup:
cargo run -p infinity_host_api -- --config config/project.example.toml --bind 127.0.0.1:9001 --runtime-state data/runtime_state.json
Creative web UI V1 is served by the same process:
http://127.0.0.1:9001/
Versioning Policy
The current public contract is v1.
Rules:
- all public HTTP and WebSocket routes are namespaced under
/api/v1 - every response body carries
api_version: "v1" - additive fields are allowed inside
v1 - semantic breaking changes require a new version namespace
- external consumers must treat undocumented internal-only fields as unstable and ignore them
Stable External Models
Stable external response families:
- command response
- state snapshot
- preview snapshot
- combined snapshot
- catalog
- event stream
- typed error object
Stable external command families:
- global control
- pattern and preset selection
- group targeting
- scene parameter updates
- transition configuration
- preset persistence
- creative snapshot persistence and recall
- panel test trigger
Internal Versus External Fields
External and stable in v1:
- every field defined in
crates/infinity_host_api/src/dto.rs - route names and payload shapes documented below
- error object shape
{ api_version, error: { code, message } } - event stream envelope shape
{ api_version, sequence, generated_at_millis, message }
Internal and not part of the API contract:
- the exact shape of
HostSnapshotincrates/infinity_host/src/control.rs - simulation-only storage layout in
data/runtime_state.json - internal event history buffering size
- internal scene library structures in
show_store.rs - engineering-GUI-specific rendering or polling behavior
HTTP Endpoints
GET /api/v1/state
Returns only the stable state snapshot.
Example:
{
"api_version": "v1",
"generated_at_millis": 512,
"state": {
"system": {
"project_name": "Infinity Vis",
"schema_version": 1,
"topology_label": "6 nodes / 18 outputs / 106 LEDs"
},
"global": {
"blackout": false,
"master_brightness": 0.2,
"selected_pattern": "gradient",
"selected_group": "top_panels",
"transition_duration_ms": 320,
"transition_style": "chase"
},
"engine": {
"logic_hz": 120,
"frame_hz": 60,
"preview_hz": 15,
"uptime_ms": 512,
"frame_index": 30,
"dropped_frames": 0,
"active_transition": {
"style": "chase",
"from_pattern_id": "solid_color",
"to_pattern_id": "gradient",
"duration_ms": 320,
"progress": 0.28
}
}
}
}
GET /api/v1/preview
Returns only the stable preview snapshot.
Example:
{
"api_version": "v1",
"generated_at_millis": 512,
"preview": {
"generated_at_millis": 512,
"panels": [
{
"node_id": "node-01",
"panel_position": "top",
"representative_color_hex": "#FF8A5B",
"sample_led_hex": [
"#FF8A5B",
"#F36E43",
"#D85A2F"
],
"energy_percent": 47,
"source": "transition"
}
]
}
}
GET /api/v1/snapshot
Returns the convenience composition of state plus preview.
This route exists for lightweight clients and debugging. Consumers that want strict separation should prefer GET /api/v1/state and GET /api/v1/preview.
GET /api/v1/catalog
Returns the stable creative library:
- patterns
- presets
- groups
- creative snapshots
Example preset summary:
{
"preset_id": "ocean_gradient",
"pattern_id": "gradient",
"target_group": null,
"transition_duration_ms": 320,
"transition_style": "crossfade",
"source": "built_in"
}
Example creative snapshot summary:
{
"snapshot_id": "variant_floor",
"label": "Variant Floor",
"pattern_id": "noise",
"target_group": "bottom_panels",
"transition_duration_ms": 220,
"transition_style": "chase",
"saved_at_unix_ms": 1760000000000
}
GET /api/v1/presets
Returns only preset summaries.
GET /api/v1/groups
Returns only group summaries.
POST /api/v1/command
Accepts one versioned command envelope.
Example request:
{
"request_id": "web-1713352662000",
"command": {
"type": "save_creative_snapshot",
"payload": {
"snapshot_id": "variant_floor",
"label": "Variant Floor",
"overwrite": false
}
}
}
Example response:
{
"api_version": "v1",
"accepted": true,
"request_id": "web-1713352662000",
"generated_at_millis": 522,
"command_type": "save_creative_snapshot",
"summary": "creative snapshot saved: variant_floor"
}
Stable Error Object
All API failures return:
{
"api_version": "v1",
"error": {
"code": "unknown_creative_snapshot",
"message": "creative snapshot 'does_not_exist' does not exist"
}
}
Stable v1 error families currently include:
invalid_request_jsoninvalid_commandunknown_groupunknown_presetunknown_creative_snapshotpreset_existssnapshot_existsgroup_existspersist_failedmissing_websocket_keynot_found
WebSocket Event Stream
WS /api/v1/stream
The stream emits a typed envelope with a monotonic sequence counter:
{
"api_version": "v1",
"sequence": 19,
"generated_at_millis": 880,
"message": {
"type": "event",
"payload": {
"kind": "warning",
"code": "unknown_creative_snapshot",
"message": "creative snapshot 'does_not_exist' does not exist"
}
}
}
Stable message types:
snapshotpreviewevent
Stable event kinds:
infowarningerror
Guaranteed Commands In v1
Guaranteed control commands:
set_blackoutset_master_brightnessselect_patternrecall_presetselect_groupset_scene_parameterset_transition_duration_msset_transition_styletrigger_panel_test
Guaranteed persistence and creative-library commands:
save_presetsave_creative_snapshotrecall_creative_snapshotupsert_group
Persistence Behavior
The simulation-backed host service now persists runtime-facing creative data to data/runtime_state.json by default.
Persisted data includes:
- active scene
- global blackout and brightness state
- transition duration and style
- runtime user presets
- runtime user groups
- creative snapshots and variants
This persistence file is an internal runtime artifact, not the public API contract.
External Show Control Adapter Boundary
The generic internal adapter surface lives in:
crates/infinity_host/src/external_control.rs
Key rule:
- future adapters may only translate external intent into the defined host command surface
- they must not reach into simulation internals, UI state, or hardware driver details directly
Contract And Integration Coverage
Current software-side hardening lives in:
crates/infinity_host_api/tests/contract.rscrates/infinity_host/src/show_store.rstestscrates/infinity_host/src/simulation.rstests
Covered flows include:
- state, preview, snapshot, catalog, presets, and groups endpoints
- command success and typed command failure
- WebSocket snapshot, preview, and event messages
- group targeting
- parameter updates
- transition configuration
- blackout
- preset save
- creative snapshot save and recall
- persistence across restart
- a longer ignored load-oriented sequence for platform hardening
Web UI Scope
The current web UI intentionally focuses on creative use:
- pattern and preset selection
- group targeting
- transition configuration
- scene parameters
- preset save and overwrite
- creative snapshot save and recall
- preview
- raw snapshot display
- filterable event feed
Mapping, topology diagnostics, panel-test administration, and low-level node status remain primarily in the native engineering GUI.