fix(billing): stop the reminder claim from rewriting stale metadata

Stripe merges metadata on update, so spreading the snapshot read during
the list call re-asserted stale values over anything written since. Send
only the key being claimed.

The claim is not exclusive and the comment no longer says it is: two
replicas can still read the same unset marker. Marking before the send
only keeps a crash mid-send from resending on the next run.
This commit is contained in:
Mauricio Siu
2026-09-18 02:41:28 -06:00
parent f34151bc12
commit 14e059784c
@@ -94,9 +94,11 @@ const processSubscription = async (
);
const plan = planFromPriceIds(priceIds);
// Claim the reminder before sending so concurrent replicas don't double-send.
// Marked before sending so a crash mid-send cannot resend on the next run.
// Stripe merges metadata, so only the claimed key travels; spreading the
// snapshot read at list time would rewrite concurrent changes.
await stripe.subscriptions.update(subscription.id, {
metadata: { ...subscription.metadata, [threshold.metadataKey]: "sent" },
metadata: { [threshold.metadataKey]: "sent" },
});
try {
@@ -109,7 +111,7 @@ const processSubscription = async (
});
} catch (error) {
await stripe.subscriptions.update(subscription.id, {
metadata: { ...subscription.metadata, [threshold.metadataKey]: "" },
metadata: { [threshold.metadataKey]: "" },
});
throw error;
}