noCV
PPOLICY-108 · Migrate and simplify

Remove the process-wide current-partner setting

Practice briefBugAdvanced

The quote singleton stores currentPartner before resolving a contract. Two overlapping synthetic requests can change that value between validation and calculation, applying one tenant's negotiated rate to another.

Focused work estimate
3h + prerequisites
Priority in the scenario
High
Engineering practice
Tenant isolation · Dependency injection · Concurrency

Estimated field mix

  • Backend50%
  • Security50%

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

  • SingletonRemove

    Remove a globally mutable partner context that leaks negotiated rules across overlapping requests, while allowing immutable shared definitions.

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 equipment-rental service supports direct customers and two reseller contracts. Pricing now lives in a long conditional with subclasses left over from a discontinued campaign. Build a local TypeScript quoting module and synthetic fixtures; no starter repository, real charges, tax advice, or payment connection is supplied. Amounts use integer cents and the exercise supports USD only.

Setup prerequisites

  • Pure functions
  • Object composition
  • Integer arithmetic

Preceding work

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

Acceptance criteria

  • Tenant and contract identity travel explicitly through each quote operation.
  • Remove mutable request state from the Singleton; shared immutable rule definitions may remain cached.
  • Any remaining cache uses tenant, contract, and revision in its identity and cannot expose another tenant's rule configuration.

Implementation constraints

  • Do not serialize all requests behind a global lock to hide the leak; preserve independent concurrent execution.

Verification to include

  • Interleave requests for two tenants at a controlled barrier and assert both receive their own rate.
  • Repeat the test after a failed request and a cache hit to detect stale tenant state.

Deliverables

  • Explicit request context and tenant-isolation concurrency regression

Rollout and recovery

Switch the local composition root to stateless quotation; discard the old mutable cache on rollback or restart.

Value of the work

For the engineer: Practice choosing, testing, and removing object-design abstractions around versioned business rules and tenant isolation.

For the team: Review changes that let a team introduce a contract without silently changing existing quotes, together with the maintenance costs of the chosen design.

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.