[codex] fix cron_sync_sub queue payload handling#1870
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughRelaxed queue consumer message validation to accept missing Changes
Sequence DiagramsequenceDiagram
participant Cron as Cron Trigger
participant ProcFunc as process_cron_sync_sub_jobs()
participant Queue as pgmq Queue
participant Consumer as Queue Consumer
participant Helper as extractMessageBody()
participant Handler as Message Handler
Cron->>ProcFunc: invoke
ProcFunc->>ProcFunc: query org/customer pairs
loop per org/customer
ProcFunc->>Queue: send message {function_name, function_type: NULL, payload:{orgId,customerId}}
end
Queue->>Consumer: dequeue message
Consumer->>Helper: extractMessageBody(message)
alt message has nested payload
Helper-->>Consumer: return nested payload object
else legacy top-level fields present
Helper-->>Consumer: return object built from top-level legacy fields
else no routing fields
Helper-->>Consumer: return {}
end
Consumer->>Handler: invoke function with normalized body
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 SQLFluff (4.0.4)supabase/migrations/20260327044102_fix_cron_sync_sub_queue_payload.sqlUser Error: No dialect was specified. You must configure a dialect or specify one on the command line using --dialect after the command. Available dialects: Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@supabase/migrations/20260327044102_fix_cron_sync_sub_queue_payload.sql`:
- Around line 20-23: The SQL constructing the queued message hard-codes
function_type = 'cloudflare' for cron_sync_sub, causing all cron_sync_sub jobs
to be routed to Cloudflare; change the payload construction so function_type is
NULL or omitted for the cron_sync_sub case (i.e. remove or set to NULL the
'function_type' field in the jsonb_build_object for 'cron_sync_sub'), and update
the corresponding test assertion in tests/process-cron-sync-sub-jobs.test.ts to
expect no 'function_type' or a null value for cron_sync_sub payloads.
In `@tests/process-cron-sync-sub-jobs.test.ts`:
- Around line 4-19: The teardown only deletes rows for a single orgId; change
clearCronSyncSubMessages (and similarly getCronSyncSubMessages) to remove/select
all messages that this RPC enqueues instead of filtering by orgId — i.e., target
rows in pgmq.q_cron_sync_sub by the message type/payload that identifies the
cron_sync_sub job (for example WHERE message->>'type' = 'cron_sync_sub' or the
appropriate message->'payload' flag used by process_cron_sync_sub_jobs()) rather
than COALESCE(... orgId), so all rows inserted by the invocation are cleaned up.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 655152c0-f9df-4cca-ba7f-bd9e9925bd77
📒 Files selected for processing (4)
supabase/functions/_backend/triggers/queue_consumer.tssupabase/migrations/20260327044102_fix_cron_sync_sub_queue_payload.sqltests/process-cron-sync-sub-jobs.test.tstests/queue-consumer-message-shape.unit.test.ts
There was a problem hiding this comment.
🧹 Nitpick comments (1)
supabase/functions/_backend/triggers/queue_consumer.ts (1)
477-479: Consider marking test helper export as internal-only.
queueConsumerTestUtilsworks, but an explicit internal/test-only naming convention (for example__test__) would reduce accidental production coupling.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@supabase/functions/_backend/triggers/queue_consumer.ts` around lines 477 - 479, Rename the exported test helper to an internal/test-only identifier to avoid accidental production use: change the export name queueConsumerTestUtils (which currently exposes extractMessageBody) to an unmistakably internal name such as __queueConsumerTestUtils__ or __test__queueConsumerUtils__, and update any references/imports accordingly so only tests import the new symbol; ensure extractMessageBody remains accessible via the renamed export but do not change its implementation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@supabase/functions/_backend/triggers/queue_consumer.ts`:
- Around line 477-479: Rename the exported test helper to an internal/test-only
identifier to avoid accidental production use: change the export name
queueConsumerTestUtils (which currently exposes extractMessageBody) to an
unmistakably internal name such as __queueConsumerTestUtils__ or
__test__queueConsumerUtils__, and update any references/imports accordingly so
only tests import the new symbol; ensure extractMessageBody remains accessible
via the renamed export but do not change its implementation.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: b4bbed16-39c9-4a73-a4e9-92d7b85396ee
📒 Files selected for processing (1)
supabase/functions/_backend/triggers/queue_consumer.ts
There was a problem hiding this comment.
🧹 Nitpick comments (1)
supabase/functions/_backend/triggers/queue_consumer.ts (1)
40-46: Tighten payload normalization to object-only before forwarding.Current casting allows any payload type to be treated as an object. Consider guarding for plain-object payloads and defaulting to
{}otherwise, so malformed payloads don’t propagate to trigger handlers.Suggested hardening
function extractMessageBody(message: Message): Record<string, unknown> { - if (message.message?.payload !== undefined) - return (message.message.payload ?? {}) as Record<string, unknown> + if (message.message?.payload !== undefined) { + const payload = message.message.payload + if (payload && typeof payload === 'object' && !Array.isArray(payload)) { + return payload as Record<string, unknown> + } + return {} + } const { function_name: _functionName, function_type: _functionType, ...legacyBody } = message.message ?? {} return legacyBody }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@supabase/functions/_backend/triggers/queue_consumer.ts` around lines 40 - 46, The extractMessageBody function currently casts any payload to an object; instead validate that message.message.payload is a plain object before returning it. In extractMessageBody, check that message.message?.payload is non-null, typeof 'object', not an Array, and not a function; if it passes, return it cast as Record<string, unknown>, otherwise return {} as the safe default; keep the existing legacy path that destructures function_name/function_type into legacyBody unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@supabase/functions/_backend/triggers/queue_consumer.ts`:
- Around line 40-46: The extractMessageBody function currently casts any payload
to an object; instead validate that message.message.payload is a plain object
before returning it. In extractMessageBody, check that message.message?.payload
is non-null, typeof 'object', not an Array, and not a function; if it passes,
return it cast as Record<string, unknown>, otherwise return {} as the safe
default; keep the existing legacy path that destructures
function_name/function_type into legacyBody unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5b928d7e-b89c-44fd-833d-61c9d309c95e
📒 Files selected for processing (3)
supabase/functions/_backend/triggers/queue_consumer.tstests/process-cron-sync-sub-jobs.test.tstests/queue-consumer-message-shape.unit.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- tests/queue-consumer-message-shape.unit.test.ts
- tests/process-cron-sync-sub-jobs.test.ts
|



Summary (AI generated)
process_cron_sync_sub_jobs()queue messages to use the shared{ function_name, function_type, payload }envelopequeue_consumerso already-queuedcron_sync_subjobs still dispatch withorgIdMotivation (AI generated)
cron_sync_subwas still being enqueued withorgIdandcustomerIdat the top level whilequeue_consumeronly forwardedmessage.payload. That made the recurring scheduler POST{}to/triggers/cron_sync_sub, producingno_orgIderrors in production logs.Business Impact (AI generated)
This restores recurring subscription sync jobs for paying organizations, removes noisy cron failures, and reduces the chance of stale billing state affecting product behavior tied to subscription status.
Test Plan (AI generated)
bunx eslint supabase/functions/_backend/triggers/queue_consumer.ts tests/queue-consumer-message-shape.unit.test.ts tests/process-cron-sync-sub-jobs.test.tsbun run supabase:with-env -- bunx vitest run tests/queue-consumer-message-shape.unit.test.ts tests/process-cron-sync-sub-jobs.test.tsGenerated with AI
Summary by CodeRabbit
New Features
Improvements
Tests