From d4c671d73ab2f14a47fae8ba17a74a2928e4b296 Mon Sep 17 00:00:00 2001 From: YueBit Date: Sat, 4 Jul 2026 19:09:25 +0800 Subject: [PATCH 1/2] Fix pluralized lifecycle status operationIds (closes #475) et_lc.first ('apps'/'components') was used for operationId construction, producing pluralized names like getAppsStatus and getComponentsStatus. Every other route uses the singular form (getAppDataItem, listComponentFaults). Changed to et_lc.second ('app'/'component') for consistency. --- src/ros2_medkit_gateway/src/http/rest_server.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ros2_medkit_gateway/src/http/rest_server.cpp b/src/ros2_medkit_gateway/src/http/rest_server.cpp index 516af5da2..392068e6b 100644 --- a/src/ros2_medkit_gateway/src/http/rest_server.cpp +++ b/src/ros2_medkit_gateway/src/http/rest_server.cpp @@ -1620,8 +1620,8 @@ void RESTServer::setup_routes() { for (const auto & et_lc : std::vector>{{"apps", "app"}, {"components", "component"}}) { const std::string base_lc = std::string("/") + et_lc.first + "/{" + et_lc.second + "_id}"; - // e.g. "Apps" / "Components" for operation ID construction - const std::string entity_cap = capitalize(std::string(et_lc.first)); + // e.g. "App" / "Component" for operation ID construction + const std::string entity_cap = capitalize(std::string(et_lc.second)); for (const auto & action : {"start", "restart", "force-restart", "shutdown", "force-shutdown"}) { std::string action_str = action; From 4d795bac7de640cef3994f852a6aed9c8ea2cb58 Mon Sep 17 00:00:00 2001 From: YueBit Date: Sun, 5 Jul 2026 13:51:10 +0800 Subject: [PATCH 2/2] test: add regression guard for lifecycle status operationId naming Assert that root OpenAPI spec uses singular entity names in lifecycle status operationIds (getAppStatus, getComponentStatus), not the plural collection names (getAppsStatus, getComponentsStatus). This prevents regression of the fix in #475. --- .../test/features/test_docs_endpoint.test.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/ros2_medkit_integration_tests/test/features/test_docs_endpoint.test.py b/src/ros2_medkit_integration_tests/test/features/test_docs_endpoint.test.py index e5cf93c8a..9db995d0c 100644 --- a/src/ros2_medkit_integration_tests/test/features/test_docs_endpoint.test.py +++ b/src/ros2_medkit_integration_tests/test/features/test_docs_endpoint.test.py @@ -77,6 +77,18 @@ def test_root_docs_returns_openapi_spec(self): f'Root spec should include /apps path. Paths: {list(paths.keys())}' ) + # Lifecycle status operationIds use the singular entity name + # (getAppStatus), not the plural collection name (getAppsStatus). + self.assertEqual( + paths['/apps/{app_id}/status']['get']['operationId'], + 'getAppStatus') + self.assertEqual( + paths['/components/{component_id}/status']['get']['operationId'], + 'getComponentStatus') + self.assertEqual( + paths['/apps/{app_id}/status/restart']['put']['operationId'], + 'putAppStatusRestart') + def test_apps_docs_returns_entity_collection_spec(self): """GET /apps/docs returns spec for apps collection.