Skip to content

refactor(services): ResolvedProjectCredentials dataclass over (stack_url, token) tuple (#516 NB-1)#519

Merged
padak merged 1 commit into
mainfrom
refactor/resolve-project-credentials-dataclass
Jul 22, 2026
Merged

refactor(services): ResolvedProjectCredentials dataclass over (stack_url, token) tuple (#516 NB-1)#519
padak merged 1 commit into
mainfrom
refactor/resolve-project-credentials-dataclass

Conversation

@padak

@padak padak commented Jul 22, 2026

Copy link
Copy Markdown
Member

Addresses NB-1 from the #516 review.

⚠️ Stacked on #516. Base branch is feat/512-table-snapshots, not main, because snapshot_service.py (one of the three files) only exists on that branch. Merge #516 first; GitHub will retarget this to main automatically. The diff below is only the refactor (4 files).

Why

The three single-project services — token, stream, snapshot — each carried a byte-identical helper:

def _resolve_project(self, alias: str) -> tuple[str, str]:
    ...
    return project.stack_url, project.token

That bare (stack_url, token) 2-tuple is exactly the heterogeneous positional return CONTRIBUTING.md forbids for new code ("Return values — name them with dataclasses, not tuples"). The #516 review flagged the newly-added snapshot_service instance (NB-1) and noted that fixing it in isolation would diverge from the two grandfathered siblings — so the trio is fixed together here.

What

  • New ResolvedProjectCredentials frozen dataclass + shared resolve_project_credentials(config_store, alias) helper in services/base.py (the existing home for cross-service free functions like default_client_factory / sanitize_unexpected_error). This also collapses the previously-triplicated lookup body into one place.
  • All three _resolve_project helpers now delegate to the shared function and return the dataclass; call sites read creds.stack_url / creds.token instead of positional unpacking.
  • The token_service ConfigError import is dropped (now unused there).

Behavior preserved

Scope

Only the three _resolve_project credential helpers. The other pre-existing tuple[str, str] returns in the codebase (http_forwarder_service.resolve_endpoint, project_service.resolve_pinned_alias) are unrelated and stay grandfathered per CONTRIBUTING.md.

Verification

make check clean — 4648 passed, 8 skipped (identical count to the #516 baseline, confirming no tests added/removed and no regressions). ruff + ty clean on all four files. No new tests were needed: the change is a pure return-type refactor with no behavior change, and the existing service/CLI suites (token, stream, snapshot — 98 tests across them) already exercise every converted call site and the unchanged error path.


Open in Devin Review

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

Base automatically changed from feat/512-table-snapshots to main July 22, 2026 09:40
…rl, token) tuple (#516 NB-1)

The single-project services (token / stream / snapshot) each carried a
byte-identical `_resolve_project(alias) -> tuple[str, str]` returning
(stack_url, token) -- a bare heterogeneous 2-tuple whose positional order a
caller has to remember. CONTRIBUTING.md ("Return values -- name them with
dataclasses, not tuples") forbids this for new code; PR #516 review flagged the
new snapshot_service instance (NB-1), and fixing the trio together keeps them
consistent rather than diverging from the two grandfathered siblings.

- New `ResolvedProjectCredentials` frozen dataclass + shared
  `resolve_project_credentials(config_store, alias)` helper in services/base.py
  (the existing home for cross-service free functions like default_client_factory),
  which also removes the previously-triplicated lookup body.
- All three `_resolve_project` helpers delegate to it; call sites now read
  `creds.stack_url` / `creds.token` instead of positional unpacking.
- The "not registered" ConfigError message is preserved verbatim (not switched
  to the richer ConfigStore.project_not_found_error) so behavior is identical.
- Drops the now-unused ConfigError import from token_service.

make check clean (4648 passed, 8 skipped); no behavior change.
@padak
padak force-pushed the refactor/resolve-project-credentials-dataclass branch from 5458d8a to f5de1f9 Compare July 22, 2026 09:41
@padak
padak merged commit 59f3ca8 into main Jul 22, 2026
4 checks passed
@padak
padak deleted the refactor/resolve-project-credentials-dataclass branch July 22, 2026 09:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant