Background
The module-layout refactor #200 reorganized src/ into client/, commands/. That work surfaced lateral dependencies between command modules databases/connections.
This cycle dates to the managed-database feature work (d898d99 feat(databases): attach/detach connection catalogs and the managed-database demo flow)
Problem
commands/connections.rs and commands/databases.rs depend on each other:
| From |
→ To |
Symbols |
connections |
databases |
get_database, try_resolve_database |
databases |
connections |
resolve_connection_id, try_resolve_connection_id |
It compiles but you can't read either module in isolation. The cycle exists because connection resolution itself consults managed-database catalog aliases.
Two more lateral deps ride along (lower stakes, same root cause):
indexes → connections (resolve_connection_id), indexes → databases (list_database_ids, get_database)
results → query (fetch_arrow_result, print_result)
Proposed approach
The shared functions are resolvers — "given a user-typed name/id, hit the API and return the resource." That's a client/-layer concern, not a command concern. Move them down so commands depend downward on client:: instead of sideways on each other.
- Introduce
client/resources/connections.rs and client/resources/databases.rs.
- Move the resolvers there — and the model structs they return (
Database at commands/databases.rs:254, plus the connection lookup's private Connection/ListResponse). This is the main effort: those models are woven into the owning commands' display code, which must then import them back from client/.
- With both resolvers as siblings in
client/resources/, they can cooperate freely and the command-level cycle disappears.
- Repoint the ~6 call sites in
connections, databases, indexes, results.
Design notes
- Keep the client layer side-effect-free. Mirror the
auth → client/credentials split: the pure try_resolve_* (return Result) functions belong in client/; the resolve_* / *_or_exit wrappers that print + std::process::exit are UI — leave thin shims in the command modules or drop them.
fetch_arrow_result (API fetch) → client/; print_result (rendering) → stays presentation (commands/query or output/).
Acceptance criteria
Background
The module-layout refactor #200 reorganized
src/intoclient/,commands/. That work surfaced lateral dependencies between command modulesdatabases/connections.This cycle dates to the managed-database feature work (
d898d99 feat(databases): attach/detach connection catalogsand the managed-database demo flow)Problem
commands/connections.rsandcommands/databases.rsdepend on each other:connectionsdatabasesget_database,try_resolve_databasedatabasesconnectionsresolve_connection_id,try_resolve_connection_idIt compiles but you can't read either module in isolation. The cycle exists because connection resolution itself consults managed-database catalog aliases.
Two more lateral deps ride along (lower stakes, same root cause):
indexes→connections(resolve_connection_id),indexes→databases(list_database_ids,get_database)results→query(fetch_arrow_result,print_result)Proposed approach
The shared functions are resolvers — "given a user-typed name/id, hit the API and return the resource." That's a
client/-layer concern, not a command concern. Move them down so commands depend downward onclient::instead of sideways on each other.client/resources/connections.rsandclient/resources/databases.rs.Databaseatcommands/databases.rs:254, plus the connection lookup's privateConnection/ListResponse). This is the main effort: those models are woven into the owning commands' display code, which must then import them back fromclient/.client/resources/, they can cooperate freely and the command-level cycle disappears.connections,databases,indexes,results.Design notes
auth→client/credentialssplit: the puretry_resolve_*(returnResult) functions belong inclient/; theresolve_*/*_or_exitwrappers thatprint+std::process::exitare UI — leave thin shims in the command modules or drop them.fetch_arrow_result(API fetch) →client/;print_result(rendering) → stays presentation (commands/queryoroutput/).Acceptance criteria
crate::commands::Xreference appears inside anothercommands/module for the resolver/model symbols above (except the allowedupdate→skill).grep -rn "crate::commands" src/client/returns nothing (client never depends on commands).connectionsanddatabasesno longer reference each other.cargo testgreen;cargo clippyno new warnings.