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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions