Skip to content

Decouple connections ⇄ databases: move resource resolvers into the client/ layer #201

Description

@pthurlow

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):

  • indexesconnections (resolve_connection_id), indexesdatabases (list_database_ids, get_database)
  • resultsquery (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.

  1. Introduce client/resources/connections.rs and client/resources/databases.rs.
  2. 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/.
  3. With both resolvers as siblings in client/resources/, they can cooperate freely and the command-level cycle disappears.
  4. Repoint the ~6 call sites in connections, databases, indexes, results.

Design notes

  • Keep the client layer side-effect-free. Mirror the authclient/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

  • No crate::commands::X reference appears inside another commands/ module for the resolver/model symbols above (except the allowed updateskill).
  • grep -rn "crate::commands" src/client/ returns nothing (client never depends on commands).
  • connections and databases no longer reference each other.
  • cargo test green; cargo clippy no new warnings.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions