Skip to content

Commit eff0b69

Browse files
committed
test(dogfood): seed the tz-boundary analytics fixture through preserveAudit
The analytics timezone fixture back-dates `created_at` to a deliberate DST boundary and was relying on the create-side `??` that #15964 removes — the first measured LEGITIMATE consumer of that hole. It now uses the explicit historical channel the same ruling preserved (`preserveAudit`, what REST's `treatAsHistorical` sets), and every assertion in the file is byte-unchanged. `isSystem` alone never preserved it: that flag exempts the engine's readonly strip, not the audit binder's stamp. Both halves are pinned at unit level in `plugin-audit-created-at-create-side.test.ts`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ARYe3yQTQCUFm5qPYNgKaJ
1 parent fe4d6ce commit eff0b69

2 files changed

Lines changed: 60 additions & 2 deletions

File tree

packages/objectql/src/plugin-audit-created-at-create-side.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,44 @@ describe('audit binder: create-side `created_at` (#15964)', () => {
170170
expect(Date.parse(row.created_at)).toBeGreaterThan(Date.parse('2020-01-01T00:00:00.000Z'));
171171
});
172172

173+
// [#15964] `isSystem` on its own is NOT a back-dating channel, and never was.
174+
// It exempts the engine's readonly STRIP; the audit binder's stamp is not
175+
// gated on it at all. Before this change a system-context seed kept its
176+
// supplied `created_at` because of the `??`, not because of its elevation —
177+
// which is how a legitimate back-dating fixture came to depend on the hole
178+
// (`packages/qa/dogfood/test/analytics-timezone.dogfood.test.ts` seeds a
179+
// timezone-boundary instant exactly this way). Both halves are pinned here so
180+
// the next such seed is told which flag it actually needs.
181+
it('`isSystem` alone does NOT preserve it, and `isSystem` + `preserveAudit` does', async () => {
182+
const { objectql, captured } = await boot('repro_system_seed');
183+
184+
await objectql.insert('repro_system_seed', forgedPayload(), {
185+
context: { isSystem: true },
186+
});
187+
await objectql.insert('repro_system_seed', forgedPayload(), {
188+
context: { isSystem: true, preserveAudit: true },
189+
});
190+
191+
const [elevatedOnly, historical] = captured;
192+
printTable('isSystem only', elevatedOnly);
193+
printTable('isSystem + preserveAudit', historical);
194+
195+
// The system context skips the strip, so `id` and `run_at` DO survive here —
196+
// that is the control proving the elevation really took effect, and it is
197+
// what makes the `created_at` row below a statement about the binder alone.
198+
expect(elevatedOnly.id).toBe(FORGED_ID);
199+
expect(elevatedOnly.run_at).toBe(FORGED_AT);
200+
// …and the binder still stamps, because it is not gated on `isSystem`.
201+
expect(elevatedOnly.created_at).not.toBe(FORGED_AT);
202+
expect(elevatedOnly.updated_at).not.toBe(FORGED_AT);
203+
204+
// The explicit channel — `ExecutionContext.preserveAudit`, what REST's
205+
// `treatAsHistorical` import sets — reaches the binder through
206+
// `buildSession` independently of `isSystem`, so a back-dated seed works.
207+
expect(historical.created_at).toBe(FORGED_AT);
208+
expect(historical.updated_at).toBe(FORGED_AT);
209+
});
210+
173211
// The ruled control: the historical-import channel is EXPLICIT and still
174212
// works. `runImport({ treatAsHistorical: true })` puts `preserveAudit: true`
175213
// on the write context (`packages/rest/src/import-runner.ts`), which is

packages/qa/dogfood/test/analytics-timezone.dogfood.test.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,34 @@ describe('dogfood: org timezone drives analytics date bucketing (#1982/#2018)',
4242
stack = await bootStack(crmStack);
4343

4444
// Deterministic fixture: N leads pinned to the tz-boundary instant, inserted
45-
// as system so the write path's defaults/validation don't fight the setup.
45+
// as system so the write path's defaults/validation don't fight the setup,
46+
// and with `preserveAudit` because a BACK-DATED `created_at` is exactly what
47+
// that flag exists to permit.
48+
//
49+
// [#15964] `preserveAudit` is REQUIRED here and is not decoration. The audit
50+
// binder's `beforeInsert` stamp used to be `record.created_at ?? now` — a
51+
// caller-supplied value won on EVERY insert, with no flag — which is the
52+
// hole a plain REST `POST` reached to forge the audit anchor. It is now the
53+
// same shape as `updated_at`, `preserveAudit ? (… ?? now) : now`, on the
54+
// maintainer ruling of 2026-09-06 (decision batch #54, option A). This
55+
// fixture is a LEGITIMATE back-dating consumer of the old behaviour — the
56+
// first one measured — so it moves to the explicit channel the same ruling
57+
// preserved rather than the accident it used to ride on.
58+
//
59+
// ⚠️ `isSystem` alone does NOT do this and never did: it exempts the engine's
60+
// readonly STRIP, not the audit binder's stamp, which is why this fixture
61+
// used to depend on the `??` rather than on its own elevation. Measured
62+
// both ways in `@objectstack/objectql`'s
63+
// `plugin-audit-created-at-create-side.test.ts`. `preserveAudit` is the flag
64+
// REST's `treatAsHistorical` import sets on the write context
65+
// (`packages/rest/src/import-runner.ts`), reaching this same hook.
4666
// eslint-disable-next-line @typescript-eslint/no-explicit-any
4767
const ql = await stack.kernel.getServiceAsync<any>('objectql');
4868
for (let i = 0; i < N_LEADS; i++) {
4969
await ql.insert(
5070
'crm_lead',
5171
{ name: `tz-lead-${i}`, status: 'new', created_at: BOUNDARY },
52-
{ context: { isSystem: true } },
72+
{ context: { isSystem: true, preserveAudit: true } },
5373
);
5474
}
5575
// Sanity: confirm created_at actually persisted as the boundary instant

0 commit comments

Comments
 (0)