Fix OpenAPI conversation action paths#760
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates several OpenAPI paths in the conversations routes to include the /v1 prefix, specifically for the pin, unpin, archive, unarchive, and clone endpoints. Additionally, a unit test has been added to verify that these paths are correctly prefixed and that the old paths without the prefix are absent. There are no review comments, and I have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Review — Fix OpenAPI conversation action pathsFocused, correct fix. Verified the claims:
No critical issues found. Minor (non-blocking): the test checks three path keys, which is sufficient since the POST/DELETE pairs for ✅ Approved |
Evrard-Nil
left a comment
There was a problem hiding this comment.
Reviewed thoroughly with a local build + spec dump. LGTM — approving.
Verified the core claim is correct:
- Action handlers are registered without
/v1inbuild_conversation_routes()(crates/api/src/lib.rs:1230-1239:.route("/conversations/{conversation_id}/pin", post(pin).delete(unpin)),.../archive,.../clone), and that router is merged under.nest("/v1", …)atlib.rs:930. So the true runtime path is/v1/conversations/{conversation_id}/{archive,clone,pin}— exactly the new annotation strings (param name{conversation_id}matches too). The pre-fix bare/conversations/...annotations did 404 generated clients. ✅
No double-prefix: ApiDoc (openapi.rs) has no servers/nest/path-prefix and its only modifier (SecurityAddon) never touches paths. Dumped the real ApiDoc::openapi() spec — renders single /v1/conversations/..., no /v1/v1. ✅
Consistency: all 12 utoipa annotations in conversations.rs now use /v1/; the other 7 already did, these 5 ops (3 unique path keys) were the last stragglers. Grepped every route file for path = "/ excluding /v1 → zero matches org-wide. Nothing missed. ✅
Build/test: cargo test -p api --lib openapi → 3 passed (incl. the new test_openapi_conversation_action_paths_use_v1_prefix, which builds the real spec and asserts prefixed-present + bare-absent). cargo fmt --all -- --check clean. cargo clippy -p api --all-targets -- -D warnings clean. ✅
Minor (non-blocking, out of scope): the regression test keys on path strings, not HTTP methods — archive+pin each carry POST+DELETE under one key, so all 5 ops are covered, but a hypothetical regression that kept the path key while dropping the DELETE op would slip through. Extremely low risk; fine to leave as-is.
PierreLeGuen
left a comment
There was a problem hiding this comment.
This PR correctly fixes the five utoipa::path annotations in crates/api/src/routes/conversations.rs (pin, unpin, archive, unarchive, clone) that were missing the /v1 prefix, and adds a regression test.
Correctness verified:
- The router registers these handlers at relative paths like
/conversations/{conversation_id}/pininbuild_conversation_routes(crates/api/src/lib.rs:1229-1240), nested under/v1(crates/api/src/lib.rs:931), so the runtime paths are indeed/v1/conversations/...and the previous spec paths were wrong. - The OpenAPI doc sets no
serversbase URL or path-modifying modifier (crates/api/src/openapi.rs:303;SecurityAddononly adds security schemes), so annotations must carry the full/v1prefix — no/v1/v1double-prefix risk. - All 12
utoipapath annotations inconversations.rsnow consistently use/v1/, and a repo-wide grep confirms no remaining unprefixedpath = "..."annotations in the api crate — the fix is complete, not partial. - The new test asserts both the presence of the
/v1-prefixed path keys and the absence of the unprefixed variants, guarding against regression. Pin/archive each share one path key for POST and DELETE, which the test comment correctly notes.
Scope exclusions (duplicate model list surfaces, 422 envelopes from #650) are documented in the PR body as follow-ups, which is reasonable. No privacy/logging concerns — the change touches only doc annotations and a test.
Local checks run:
cargo test -p api --lib openapi— 3 passed, including the newtest_openapi_conversation_action_paths_use_v1_prefixcargo test --lib --bins— 742 passed, 1 ignored (pre-existing), 0 failedcargo clippy -p api --all-targets -- -D warnings— cleancargo fmt --all -- --check— cleangit diff --check— clean- CI on the PR (Lint, Test Suite, security_audit) is green; integration/vLLM paths weren't run locally as they need services/secrets.
Problem
Part of #650.
The generated OpenAPI spec documented five conversation action operations without the
/v1prefix:POST /conversations/{conversation_id}/archiveDELETE /conversations/{conversation_id}/archivePOST /conversations/{conversation_id}/pinDELETE /conversations/{conversation_id}/pinPOST /conversations/{conversation_id}/cloneThose unprefixed paths return bare 404s at runtime. The actual router mounts the handlers under
/v1, so generated clients call the wrong URLs for archive, unarchive, pin, unpin, and clone.Change
utoipa::pathannotations for the conversation action handlers to document the runtime/v1/conversations/...paths.What Else Is Needed
Tests
cargo test -p api --lib openapicargo fmt --all -- --checkcargo clippy --all-targets --all-features -- -D warningscargo test --lib --bins