You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* chore(billing): batch 4 — RUNBOOKS accuracy, params validation, cursor pagination, log levels
1. RUNBOOKS.md: #2 dead-letter retry count 3→5 (matches BILLING_WEBHOOK_MAX_ATTEMPTS=5);
#3 plans/bump body: drop 'reason' field (not in AdminBumpPlanRequest schema, was 422)
2. Zod params validation on admin endpoints: AdminOrgIdParam (ObjectId regex) +
AdminEventIdParam (evt_* regex) wired via safeParse in adminGetCustomerStatus,
adminSyncFromStripe, adminCancelSubscription, adminPurgeDeadLetter → 422 on invalid input
3. Cursor-based pagination in reconcile service: replace skip+limit with
_id > lastSeenId cursor in _fetchPage / findPageForReconciliation.
Stable across new subscription inserts mid-run. Tests for multi-page + cursor stability.
4. dispute.funds_reinstated log level: logger.warn → logger.error in
handleChargeDisputeFundsReinstated (action-required state, not warn-noise)
5. creditPack duplicate observability: log result.applied=false at debug level
in handleCheckoutPaymentCompleted to surface Stripe redelivery phantom calls
6. billing.init.js console.warn → logger.warn (6 occurrences)
* fix(billing): add AdminOrgIdParam validation to adminDisputeCredit path param
Completes the Batch 4 admin endpoint param coverage — adminDisputeCredit
/:orgId was missed in the initial pass. Now all 5 :orgId admin endpoints
validate with AdminOrgIdParam.safeParse → 422 on invalid ObjectId.
* test(billing): strengthen service-wiring assertions in admin param validation tests
CodeRabbit nit: tests asserting "reaches the service" now also verify the
controller passed the validated param to the service method (getCustomerStatus
called with orgId, purgeDeadLetter called with eventId).
Copy file name to clipboardExpand all lines: modules/billing/RUNBOOKS.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -54,7 +54,7 @@ Operational runbooks for the billing module. Each runbook references real endpoi
54
54
55
55
## 2 — Dead-Letter Investigation
56
56
57
-
**Context**: Stripe webhook events that fail processing 3+ times (or where the idempotency guard fires on a poisoned payload) are marked `deadLetter: true` in `processedStripeEvents`. They accumulate and must be reviewed manually — partial TTL index excludes them from auto-expiry.
57
+
**Context**: Stripe webhook events that fail processing 5+ times (or where the idempotency guard fires on a poisoned payload) are marked `deadLetter: true` in `processedStripeEvents`. They accumulate and must be reviewed manually — partial TTL index excludes them from auto-expiry.
58
58
59
59
**Steps**:
60
60
@@ -123,7 +123,7 @@ Operational runbooks for the billing module. Each runbook references real endpoi
// — log as error so this surfaces in error-level alerting dashboards, not buried in warn noise.
1131
+
logger.error('[billing.webhook] dispute.funds_reinstated received — ACTION REQUIRED: use POST /api/admin/billing/dispute/credit/:orgId to restore the extras balance',{
0 commit comments