feat(card): add CardController shell to Engine#27020
Conversation
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection:
The SmokeCard tag is appropriate because:
Risk is medium (not low) because:
However, the changes are additive (not modifying existing behavior) and follow established patterns, so comprehensive testing beyond SmokeCard is not necessary. Performance Test Selection: |
The committed fixture schema is out of date. To update, comment: |
|



Description
Introduces the
CardControllershell into the Engine as the first step toward the multi-provider Card architecture.Why: The Card feature is tightly coupled to Baanx with business logic scattered across hooks, views, and a 2,600-line SDK monolith. To support multiple card providers and clean up the architecture, we need a proper Engine controller that owns the Card feature's persistent state. This PR lays the foundation — an inert controller that holds state and syncs it to Redux via the standard Engine batcher. No user-facing changes.
What changed:
New files:
app/core/Engine/controllers/card-controller/types.ts: DefinesCardControllerState(5 fields:selectedCountry,activeProviderId,isAuthenticated,cardholderAccounts,providerData), default state factory, and action/event/messenger types.app/core/Engine/controllers/card-controller/CardController.ts: Bare-bones controller extendingBaseController. All state is persisted and markedusedInUi: true. No business logic yet — provider delegation comes in subsequent PRs.app/core/Engine/controllers/card-controller/index.ts: Init function following the standard Engine pattern — reads persisted state, creates controller instance.app/core/Engine/messengers/card-controller-messenger/index.ts: Simple messenger with no delegated actions/events (those will be added when the controller needs to talk toKeyringController,TransactionController, etc.).app/selectors/cardController.ts: Four selectors:selectCardSelectedCountry,selectCardActiveProviderId,selectIsCardAuthenticated,selectCardholderAccounts.Modified files:
app/core/Engine/types.ts: AddedCardControllertoControllers,EngineState,GlobalActions,GlobalEvents, andControllersToInitialize.app/core/Engine/Engine.ts: Registered init function, destructured fromcontrollersByName, added tothis.contextandstategetter.app/core/Engine/messengers/index.ts: AddedCardControllerentry toCONTROLLER_MESSENGERS.app/core/Engine/constants.ts: Added'CardController:stateChange'toBACKGROUND_STATE_CHANGE_EVENT_NAMES.app/util/test/initial-background-state.json: AddedCardControllerdefault state to the test fixture..github/CODEOWNERS: Assignedapp/core/Engine/controllers/card-controller,app/core/Engine/messengers/card-controller-messenger, andapp/selectors/cardController.tsto@MetaMask/card.Test files:
CardController.test.ts: Tests controller construction with default state, partial state, and full persisted state.index.test.ts: Tests the init function returns a controller instance, uses default state when none is persisted, and uses persisted state when provided.cardController.test.ts: Tests all four selectors with populated state, empty state, and undefinedCardControllerstate (fallback values).Changelog
CHANGELOG entry: null
Related issues
Fixes:
Manual testing steps
Screenshots/Recordings
No UI changes — this is an infrastructure-only PR.
Before
No
CardControllerin Engine. Card state managed entirely by Redux slice.After
CardControllerexists in Engine with default state. Syncs tostate.engine.backgroundState.CardController. Existing Card feature behavior is unchanged.Pre-merge author checklist
Pre-merge reviewer checklist
Note
Medium Risk
Medium risk because it updates core Engine initialization/types and introduces new persisted background state, which could affect startup or state serialization despite having no business logic yet.
Overview
Introduces a new
CardController(BaseController) that persists Card feature state (selectedCountry,activeProviderId,isAuthenticated,cardholderAccounts,providerData) and exposes it via the standard Engine background state batching.Wires the controller into Engine initialization and messaging (
Engine.ts,messengers/index.ts,types.ts,constants.ts) soCardControllerstate is included inEngine.state, state-change subscriptions, and debug/state log fixtures.Adds initial selectors in
selectors/cardController.ts, plus unit tests for controller construction/init and selector fallbacks, and updatesCODEOWNERSfor new Card Engine paths.Written by Cursor Bugbot for commit 8363bb1. This will update automatically on new commits. Configure here.