Summary
We want one consistent convention for vendor fields on SOVD-standard endpoint payloads: nested "x-medkit": { ... }. Today that rule is broken in at least one place: GET /updates/{id}/status emits the vendor phase as a flat top-level key "x-medkit-phase" instead of "x-medkit": { "phase": "..." }. Surfaced during review of selfpatch/ros2_medkit_web_ui#72 (new typed client-side support for that field).
Other SOVD-endpoint payloads already follow the nested convention (examples from existing handlers and transforms):
- Faults collections:
"x-medkit": { "count": N }
- Data / operations detail:
"x-medkit": { "ros2": { "kind": "...", "topic": "...", "type": "..." }, "access": "read|write", "entity_id": "..." }
- Bulkdata:
"x-medkit": { "fault_code": "...", "duration_sec": 5.0, "format": "mcap" }
Proposed solution
- On SOVD-standard endpoint responses, move all
x-medkit-* flat top-level vendor keys into a nested x-medkit object. Concrete case today: GET /updates/{id}/status emits { "x-medkit": { "phase": "prepared" } }.
- Reflect the change in schema + docs (
docs/api/rest.rst, OpenAPI spec).
- Downstream clients update type + readers in lockstep (web UI, MCP server, foxglove extension, generated clients).
Out of scope
- Vendor-extension endpoints like
/apps/{id}/x-medkit-param-beacon. That route lives under the OpenAPI x-<vendor>-<name> namespace and its payload is fully vendor-owned, so the nesting rule does not apply there.
- Capability / route naming - not affected.
Additional context
Existing nested examples for reference:
src/ros2_medkit_gateway/src/http/handlers/fault_handlers.cpp (faults x-medkit.count)
src/ros2_medkit_gateway/src/http/handlers/data_handlers.cpp, operations_handlers.cpp (x-medkit.ros2.*, x-medkit.access, x-medkit.entity_id)
src/ros2_medkit_gateway/src/http/handlers/bulkdata_handlers.cpp
Flat cases to migrate (non-exhaustive):
src/ros2_medkit_gateway/include/ros2_medkit_gateway/updates/update_types.hpp - x-medkit-phase on GET /updates/{id}/status
Summary
We want one consistent convention for vendor fields on SOVD-standard endpoint payloads: nested
"x-medkit": { ... }. Today that rule is broken in at least one place:GET /updates/{id}/statusemits the vendor phase as a flat top-level key"x-medkit-phase"instead of"x-medkit": { "phase": "..." }. Surfaced during review of selfpatch/ros2_medkit_web_ui#72 (new typed client-side support for that field).Other SOVD-endpoint payloads already follow the nested convention (examples from existing handlers and transforms):
"x-medkit": { "count": N }"x-medkit": { "ros2": { "kind": "...", "topic": "...", "type": "..." }, "access": "read|write", "entity_id": "..." }"x-medkit": { "fault_code": "...", "duration_sec": 5.0, "format": "mcap" }Proposed solution
x-medkit-*flat top-level vendor keys into a nestedx-medkitobject. Concrete case today:GET /updates/{id}/statusemits{ "x-medkit": { "phase": "prepared" } }.docs/api/rest.rst, OpenAPI spec).Out of scope
/apps/{id}/x-medkit-param-beacon. That route lives under the OpenAPIx-<vendor>-<name>namespace and its payload is fully vendor-owned, so the nesting rule does not apply there.Additional context
Existing nested examples for reference:
src/ros2_medkit_gateway/src/http/handlers/fault_handlers.cpp(faultsx-medkit.count)src/ros2_medkit_gateway/src/http/handlers/data_handlers.cpp,operations_handlers.cpp(x-medkit.ros2.*,x-medkit.access,x-medkit.entity_id)src/ros2_medkit_gateway/src/http/handlers/bulkdata_handlers.cppFlat cases to migrate (non-exhaustive):
src/ros2_medkit_gateway/include/ros2_medkit_gateway/updates/update_types.hpp-x-medkit-phaseonGET /updates/{id}/status