refactor(persistence): migrate bridge events file to canonical atomic-write util (DC-104) [glm-grade=A]
writeEvents() in scripts/stripe-license-bridge.js drops its private tmp+writeFileSync+rename copy (no fsync, Date.now() tmp names) and delegates to src/utils/atomic-write.js atomicWriteJSON (exclusive-create tmp, fsync, rename, parent-dir fsync, 0600). stripe-events.json is the Stripe webhook idempotency log - a torn write silently drops event-ids, so a Stripe retry re-runs delivery (duplicate license email; combined with a torn fulfillment record, a duplicate key mint). readEvents is JSON.parse-only, so the canonical serializer's trailing-newline drop is unobservable. Sole writer confirmed by grep. +2 DC-104 pins: full recordEvent->eventSeen dedupe cycle (0600/complete JSON/zero-leftovers) and 8-step back-to-back mutation parse-complete check. 121 suites / 2778 tests green. Judge: GLM-5.3 round-1 A (deleg_e8e1f9d0), URN urn:ump:frwh34wtlsunsymok6pzyujyehq6ikpvadypmsg7ndk7jjvzrp5a
This commit is contained in:
@@ -105,6 +105,7 @@ const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { generateCodes, loadSecret } = require('../license-keygen');
|
||||
const platformPaths = require('../platform-paths');
|
||||
const { atomicWriteJSON } = require('../src/utils/atomic-write');
|
||||
const catalog = require('../src/billing/catalog');
|
||||
const invoice = require('../src/billing/invoice');
|
||||
const { createFulfillmentStore, DELIVERY_LEASE_MS } = require('../src/billing/fulfillment-store');
|
||||
@@ -220,10 +221,11 @@ function readEvents() {
|
||||
}
|
||||
|
||||
function writeEvents(state) {
|
||||
// Atomic write: tmp + rename.
|
||||
const tmp = `${EVENTS_FILE}.tmp.${process.pid}.${Date.now()}`;
|
||||
fs.writeFileSync(tmp, JSON.stringify(state, null, 2) + '\n', { mode: 0o600 });
|
||||
fs.renameSync(tmp, EVENTS_FILE);
|
||||
// Canonical atomic writer (DC-099/DC-104): exclusive-create tmp + fsync +
|
||||
// rename + parent-dir fsync, 0600. Replaces the private tmp+rename copy —
|
||||
// a torn stripe-events.json silently drops event-ids, which makes a
|
||||
// Stripe retry re-run delivery (duplicate license email / duplicate key).
|
||||
atomicWriteJSON(EVENTS_FILE, state, { mode: 0o600 });
|
||||
}
|
||||
|
||||
function recordEvent(eventId, meta) {
|
||||
|
||||
Reference in New Issue
Block a user