Skip to content

refactor(backend): provider-scoped rollout Wave 1 (balance, line directory, diagnostics)#28

Merged
creativeux merged 3 commits into
mainfrom
feat/provider-scoped-wave1
Jul 1, 2026
Merged

refactor(backend): provider-scoped rollout Wave 1 (balance, line directory, diagnostics)#28
creativeux merged 3 commits into
mainfrom
feat/provider-scoped-wave1

Conversation

@creativeux

Copy link
Copy Markdown
Owner

What

Wave 1 of completing the provider-scoped repository conversion that the CDR vertical (PR #27) started. Converts the three read-only service/repository pairs to the provider-scoped layering: repositories own their client and translate provider shapes → HowdyBox domain models behind a HowdyBox-owned ABC; services depend only on the ABC and contain no provider knowledge.

Behavior-preserving — no /api/* contract, response-schema, or DB changes.

Plan/spec: specs/2026-06-29_feature_providerScopedRollout/ (plan.md, spec.md; passed Architect+QA persona review and the pre-implementation standards gate).

Pairs converted

Pair Change
balance VoipMsBalanceRepository owns the client + translates provider failures to ProviderLookupError; BalanceService depends on the ABC; router maps the domain error.
line directory Renamed the provider-named AccountService (services/voipms_account.py) → LineDirectoryService + VoipMsLineDirectoryRepository. Resolves the AccountService name collision with the DB account service. Rewires the parental-controls router.
diagnostics VoipMsDiagnosticsRepository owns did→sub resolution, the 4-call gather with graceful degradation, and the time-condition re-evaluation, returning a new LineDiagnostics domain model. DB-sourced parental-controls summary + timezone logic stays service-side.

Also

  • protocols.py: shared ProviderLookupError(kind) + classify_provider_error(); CallLookupError now subclasses it (CDR untouched). New BalanceRepository, LineDirectoryRepository, DiagnosticsRepository ABCs.
  • Standard: backend-layered-architecture.md gains a Repository writes / commands subsection (designed here, first implemented in Wave 2); migration note trimmed.

Judgment calls

  • Diagnostics translation as pure module functions (matching the existing build_pop_map) rather than private methods — keeps the granular translation unit tests as plain function calls.
  • Removed 3 diagnostics router tests that simulated the service raising provider errors: the service degrades gracefully and never raises them, so the route no longer maps them and those tests exercised an unreachable path. This is the spec's error-handling decision.

Verification

  • Services are provider-free — leak gate (VoipMs|timezone=|client. in the three services) is clean.
  • Full suite: 689 backend + 253 frontend tests pass (+28 net new); ruff check + ruff format --check clean.

Next

Wave 2 = remediation (first real write command, exercising the new command pattern), then Wave 3 = parental_controls + wizard. Snapshot stays exempt.

🤖 Generated with Claude Code

creativeux and others added 3 commits June 29, 2026 16:33
Plan completing the provider-scoped layering conversion the CDR vertical
started (the standard is already reconciled; only CDR's code was migrated).
Phased easy→hard across the six remaining pairs; snapshot stays exempt.

- requirements.md: interim-state inventory + success criteria
- plan.md: conversion recipe, wave sequencing, write/command pattern, risks
- spec.md: Wave 1 (balance, voipms_account→rename, diagnostics) — read-only
  verticals; designs the write/command pattern (first implemented in Wave 2).
  Passed Architect+QA persona review and the pre-implementation standards gate.

Personas: Architect, QA. GLaDOS plan-feature + spec-feature trace in README.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ctory, diagnostics)

Complete the provider-scoped layering for the three read-only pairs, per
specs/2026-06-29_feature_providerScopedRollout/spec.md. Behavior-preserving.

- protocols.py: add ProviderLookupError(kind) + classify_provider_error();
  CallLookupError now subclasses it. Add BalanceRepository,
  LineDirectoryRepository, DiagnosticsRepository ABCs.
- balance: VoipMsBalanceRepository owns the client and translates errors;
  BalanceService depends on the ABC; router maps ProviderLookupError.
- line directory: rename the provider-named AccountService (services/
  voipms_account.py) to LineDirectoryService + VoipMsLineDirectoryRepository,
  resolving the AccountService name collision with the DB account service.
  Rewire the parental-controls router.
- diagnostics: repository owns did→sub resolution, the 4-call gather with
  graceful degradation, and tc re-evaluation, returning a new LineDiagnostics
  domain model; translation is pure module functions. DB parental-controls
  summary translation stays service-side (DB models + line timezone). Router
  drops the unreachable provider except clauses (service degrades, never raises).
- standard: add "Repository writes / commands" subsection; trim migration note.

Services are provider-free (leak gate clean). Full suite 689 passed;
ruff check + format clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Address PR #28 review nit #1: TestFetchLineDiagnostics only asserted
degradation for the registration sub-call. Add the cases that moved out of
the old service tests when orchestration relocated to the repository:
sub-account-fail → None, did-routing-fail → None, servers-info-fail → empty
POP map (IDs unresolved), and all-four-fail → fully degraded. None raise.

Also record the two non-blocking review follow-ups (dedupe CDR error
classification onto classify_provider_error; diagnostics-route defense-in-depth)
in the rollout trace for a later wave.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@creativeux creativeux self-assigned this Jul 1, 2026
@creativeux creativeux merged commit c7f3722 into main Jul 1, 2026
2 checks passed
@creativeux creativeux deleted the feat/provider-scoped-wave1 branch July 1, 2026 18:44
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