noCV
PMIGRATE-103 · Establish a stable boundary

Separate account policy from legacy SQL and replacement storage

Practice briefStoryIntermediate

The rule that a suspended account cannot enable a new booking channel lives inside a legacy SQL helper. The replacement adapter would bypass that rule if handlers called it directly.

Focused work estimate
3h + prerequisites
Priority in the scenario
High
Engineering practice
Dependency inversion · Domain policy · Transaction contracts

Estimated field mix

  • System design50%
  • Backend30%
  • Database engineering20%

Field percentages are editorial estimates of the ticket's engineering focus. They total 100%; they are not measured time, proficiency scores, or ownership evidence.

Pattern topics

  • Ports and AdaptersRefactor

    Move account policy above concrete storage and give both adapters the same explicit authorization, revision, and transaction obligations.

Your next step

Review it, then add it to your workspace.

The board opens an editable draft; nothing is saved until you confirm it. Sign-in and workspace permissions apply, and Demo boards remain ephemeral.

Project context

A fictional B2B scheduling service stores account settings in a legacy module whose database access leaks into HTTP handlers. A replacement must support existing clients and migration by tenant. Build a local modular application, a synthetic two-tenant dataset, and controllable old/new adapters; no baseline repository or fixtures are supplied. Keep the exercise in one application and local database, with no live customer traffic.

Setup prerequisites

  • REST contracts
  • Tenant authorization
  • Transactions
  • Dependency injection

Preceding work

Complete these dependencies, or supply their agreed outputs before taking this ticket.

Acceptance criteria

  • Place the account policy in an application operation depending on explicit read/write ports instead of concrete database helpers.
  • Run the same operation against old and new storage adapters with identical authorization and suspended-account behavior.
  • Keep transaction and expected-revision requirements explicit in the port contract; adapters cannot report success after a failed commit.

Implementation constraints

  • Introduce ports for the needed use case only; do not create a universal repository abstraction or change the application into microservices.

Verification to include

  • Run a shared contract suite for both adapters over active, suspended, and missing accounts.
  • Inject a stale revision and commit failure in each adapter and verify no enabled channel or success response is produced.

Deliverables

  • Account operation, two local adapters, and shared behavior contract

Rollout and recovery

Keep the legacy adapter selected while introducing the boundary; enable the replacement only after parity cases pass.

Value of the work

For the engineer: Practice incremental migration, dependency boundaries, compatibility testing, and removing abstractions that obscure behavior rather than enabling change.

For the team: Inspect a migration plan with measurable parity, explicit write ownership, tenant-safe routing, and rollback limits instead of accepting a rewrite diagram alone.

Evidence boundaries

Outcome Evidence: Tests, patches, and runbooks are requested deliverables. They become Outcome Evidence only through a qualified Mission and immutable Evidence IDs.

Ownership Evidence: Independent adaptation must be observed under a declared verification policy and cite immutable Evidence IDs. Completing a planning ticket establishes no Ownership Evidence.