← all branches

fix/svc-name

needs attention
3577318 · fullpre-PRreviewed 2026-07-31 00:39 UTC2H · 3M · 3L · 1I
The branch
Purpose
Unblock CFE pipeline for orgs whose stored utility_contracts.serviceName has gone stale and cannot be corrected by re-submitting the job with the correct name.
Goal
Let a caller-supplied serviceName win over the cached contract name, while keeping the stored name reachable as a fallback so a wrong caller-supplied name doesn't permanently break an RPU.
Sub-goals
  • Emit both candidates from resolveServiceNameCandidates (caller first)
  • Thread serviceNameFallback through ASL to both collector and PS Lambdas
  • Retry once with fallback in attemptRegistrationWithRescue on SERVICE_NAME_MISMATCH
  • Maintain backward compat for in-flight SFN executions that omit the new field
The changes (whole branch)
What
Introduces resolveServiceNameCandidates() pure function in decisions.ts, adds serviceNameFallback to CacheCheckState/CacheCheckDecision, threads the field through the SFN ASL for both CfeStepFunctions and CfePaymentStatus stacks, and consumes it in both Lambda handlers.
Why
Prod incident 2026-07-30: 28 RPUs at org Tiendas Neto deadlocked. Pre-fix the stored name always won, so jobs submitted with the corrected name still re-registered with the old one and CFE kept answering SERVICE_NAME_MISMATCH.
Areas
domains/utility/src/cfe-job+1685infra/cdk/src/stacks/services/utility/bills/cfe+91services/utility/bills/cfe/src/handlers+222.claude/rules+82
Blast
7 files, +207/−10 across domain logic, infra ASL, and two Lambda handlers
prod-pipeline-fix sfn-compat-concern
ci· no PR — no CI checks availablecoderabbit· no .coderabbit.yaml

Findings · 9

correctness1

low

Empty-string configServiceName treated as absent — callers cannot explicitly clear a stored name

domains/utility/src/cfe-job/cfe-job.decisions.ts:928

`|| null` coercion means supplying service_name: '' via the API falls back to the stored name rather than clearing it.

security3

medium

Caller-controlled string becomes primary CFE identity with no visible server-side validation

services/utility/bills/cfe/src/handlers/collector.lambda.ts

The service_name from POST /v1/jobs now wins as the primary name sent to CFE portal. Verify upstream API handler enforces length cap and character-set constraint.

low

Only .trim() applied before external CFE submission

domains/utility/src/cfe-job/cfe-job.decisions.ts:928

No character-set restriction or length cap visible in this diff.

info

serviceNameFallback visible in SFN execution history

infra/cdk/src/stacks/services/utility/bills/cfe/stepfunctions.stack.ts

Titleholder legal names now appear in SFN ResultSelectors. Confirm history retention and IAM grants are scoped appropriately.

tests3

high

Lambda handler fallbackName expression is untested

services/utility/bills/cfe/src/handlers/collector.lambda.ts

The inline fallbackName ternary in both Lambda handlers has no unit tests. A bug here directly reproduces the prod incident. Add 3-case table tests: fallback absent, fallback equals primary (no-op), fallback differs from primary (used).

medium

ASL serviceNameFallback threading is an untested seam

infra/cdk/src/stacks/services/utility/bills/cfe/stepfunctions.stack.ts

Nothing verifies the ASL threads serviceNameFallback from cacheCheck output into Lambda Parameters. If missing, handler receives undefined and silently degrades — same incident.

low

'both absent → both null, collector fails fast with RPU_INVALID' does not assert the RPU_INVALID path

domains/utility/src/cfe-job/__tests__/cfe-job.decisions.test.ts

Test name promises RPU_INVALID but only asserts the null tuple. Rename or add a follow-up test.

improvement2

high

Identical 3-line fallbackName expression duplicated in two sibling Lambda handlers

services/utility/bills/cfe/src/handlers/payment-status.lambda.ts

collector.lambda.ts and payment-status.lambda.ts live in the same package and contain verbatim duplicate fallbackName derivation. Extract a shared helper (resolveFallbackName) so a future fix propagates to both.

medium

Redundant !== primaryName guard in Lambda handlers

services/utility/bills/cfe/src/handlers/collector.lambda.ts

resolveServiceNameCandidates already guarantees serviceNameFallback !== serviceName. The re-check is redundant and obscures the upstream invariant.