81 lines
6.6 KiB
Markdown
81 lines
6.6 KiB
Markdown
|
|
# SIM Order & Lifecycle States
|
||
|
|
|
||
|
|
This document stays in sync with the strongly typed lifecycle definitions that live in the SIM
|
||
|
|
domain package. When workflow steps change, update the types first and then revise this doc so
|
||
|
|
deployments, QA, and onboarding all use the same vocabulary.
|
||
|
|
|
||
|
|
## Core Types
|
||
|
|
|
||
|
|
The lifecycle exports below are the single source of truth for state names and transitions.
|
||
|
|
|
||
|
|
```1:120:packages/domain/sim/lifecycle.ts
|
||
|
|
export const SIM_LIFECYCLE_STAGE = {
|
||
|
|
CHECKOUT: "checkout",
|
||
|
|
ORDER_PENDING_REVIEW: "order.pendingReview",
|
||
|
|
ACTIVATION_PROCESSING: "activation.processing",
|
||
|
|
ACTIVATION_FAILED_PAYMENT: "activation.failedPayment",
|
||
|
|
ACTIVATION_PROVISIONING: "activation.provisioning",
|
||
|
|
SERVICE_ACTIVE: "service.active",
|
||
|
|
PLAN_CHANGE_SCHEDULED: "planChange.scheduled",
|
||
|
|
PLAN_CHANGE_APPLIED: "planChange.applied",
|
||
|
|
CANCELLATION_SCHEDULED: "cancellation.scheduled",
|
||
|
|
SERVICE_CANCELLED: "service.cancelled",
|
||
|
|
} as const;
|
||
|
|
|
||
|
|
export const SIM_MANAGEMENT_ACTION = {
|
||
|
|
TOP_UP_DATA: "topUpData",
|
||
|
|
CHANGE_PLAN: "changePlan",
|
||
|
|
UPDATE_FEATURES: "updateFeatures",
|
||
|
|
CANCEL_SIM: "cancelSim",
|
||
|
|
REISSUE_ESIM: "reissueEsim",
|
||
|
|
} as const;
|
||
|
|
```
|
||
|
|
|
||
|
|
- `SimLifecycleStage` — union of the keys above.
|
||
|
|
- `SimManagementAction` — canonical action names referenced by BFF services, workers, and docs.
|
||
|
|
- `SIM_ORDER_FLOW` — ordered list of activation transitions.
|
||
|
|
- `SIM_MANAGEMENT_FLOW` — per-action transitions that describe how a request moves between states.
|
||
|
|
|
||
|
|
## Order + Activation Flow (`SIM_ORDER_FLOW`)
|
||
|
|
|
||
|
|
| Step | Transition | Details |
|
||
|
|
| ---- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||
|
|
| 1 | `checkout.createOrder`: `checkout → order.pendingReview` | `orderWithSkuValidationSchema` ensures the cart is valid before the BFF writes a Salesforce order. |
|
||
|
|
| 2 | `orders.activateSim`: `order.pendingReview → activation.processing` | `SimOrderActivationService` locks the request (cache key) and kicks off billing. |
|
||
|
|
| 3a | `payments.failure`: `activation.processing → activation.failedPayment` | WHMCS capture failed. Invoice is cancelled via `SimBillingService`, user must retry. |
|
||
|
|
| 3b | `payments.success`: `activation.processing → activation.provisioning` | Payment succeeded; Freebit provisioning and add-on updates run. |
|
||
|
|
| 4 | `provisioning.complete`: `activation.provisioning → service.active` | Freebit returns success, cache records the idempotent result, and the monthly WHMCS subscription is scheduled for the first of next month via `SimScheduleService`. |
|
||
|
|
|
||
|
|
## SIM Management Actions (`SIM_MANAGEMENT_FLOW`)
|
||
|
|
|
||
|
|
All customer-facing actions execute through `SimActionRunnerService`, guaranteeing consistent
|
||
|
|
notifications and structured logs. The table below maps directly to the typed transitions.
|
||
|
|
|
||
|
|
| Action (`SimManagementAction`) | Transition(s) | Notes |
|
||
|
|
| ------------------------------ | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
||
|
|
| `topUpData` | `service.active → service.active` | One-time invoice captured through `SimBillingService`; Freebit quota increases immediately. |
|
||
|
|
| `changePlan` | `service.active → planChange.scheduled → planChange.applied → service.active` | `SimScheduleService.resolveScheduledDate` auto-picks the first day of next month unless the user provides `scheduledAt`. |
|
||
|
|
| `updateFeatures` | `service.active → service.active` | Voice toggles run instantly. If `networkType` changes, the second phase is queued (see below). |
|
||
|
|
| `cancelSim` | `service.active → cancellation.scheduled → service.cancelled` | Default schedule = first day of next month; users can override by passing a valid `YYYYMMDD` date. |
|
||
|
|
| `reissueEsim` | `service.active → service.active` | Freebit eSIM profile reissued; lifecycle stage does not change. |
|
||
|
|
|
||
|
|
## Deferred Jobs
|
||
|
|
|
||
|
|
Network-type changes are persisted as BullMQ jobs so they survive restarts and include retry
|
||
|
|
telemetry.
|
||
|
|
|
||
|
|
- Enqueue: `SimPlanService` → `SimManagementQueueService.scheduleNetworkTypeChange`
|
||
|
|
- Worker: `SimManagementProcessor` consumes the `sim-management` queue and calls
|
||
|
|
`FreebitOrchestratorService.updateSimFeatures` when the delay expires.
|
||
|
|
|
||
|
|
## Validation & Feedback Layers
|
||
|
|
|
||
|
|
| Layer | Enforcement | Customer feedback |
|
||
|
|
| --------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
|
||
|
|
| Frontend | Domain schemas (`orderWithSkuValidationSchema`, SIM configure schemas) | Immediate form errors (e.g., missing activation fee, invalid EID). |
|
||
|
|
| BFF | `SimOrderActivationService`, `SimPlanService`, `SimTopUpService` | Sanitized business errors (`VAL_001`, payment failures) routed through Secure Error Mapper. |
|
||
|
|
| Background jobs | `SimManagementProcessor` | Logged with request metadata; failures fan out via `SimNotificationService`. |
|
||
|
|
|
||
|
|
Keep this file and `packages/domain/sim/lifecycle.ts` in lockstep. When adding a new stage or action,
|
||
|
|
update the domain types first, then describe the change here so every team shares the same model.
|