1
0
Fork 0
polaris-task-force/tests/int/operation-ledger.int.spec.ts
Z8MB1E cc23742dd8 feat(operations): versioned operation event and effect ledger
Consume raw arma-sync-events into a validated, idempotent operation ledger: contract v1, reject/dead-letter with zero effects, effect keys with unique-constraint race handling, and a staged-activation flag hook. Registers the operations permission domains.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-20 02:43:40 -04:00

400 lines
No EOL
13 KiB
TypeScript

import { getPayload, Payload } from "payload";
import config from "@/payload.config";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { hashPayload, processOperationEvent, stableStringify } from "@/lib/operations/process";
import type { RawSyncEvent } from "@/lib/operations/types";
type JsonValue = string | number | boolean | unknown[] | { [k: string]: unknown } | null;
let payload: Payload;
const RUN = `op-${Date.now().toString(36)}`;
describe("Operation ledger", () => {
let userId: number;
let profileId: number;
let serverId: number;
const createdSyncEventIds: number[] = [];
const createdEventIds: number[] = [];
const createdEffectIds: number[] = [];
beforeAll(async () => {
const payloadConfig = await config;
payload = await getPayload({ config: payloadConfig });
const user = await payload.create({
collection: "users",
data: {
username: `${RUN}-op`,
discordUsername: `${RUN}-op-discord`,
displayName: `${RUN} Operator`,
steamId: `${RUN}-steam-001`,
password: "Test1234",
},
overrideAccess: true,
depth: 0,
});
userId = user.id;
const profiles = await payload.find({
collection: "profiles",
where: { user: { equals: userId } },
limit: 1,
depth: 0,
overrideAccess: true,
});
profileId = profiles.docs[0].id;
const server = await payload.create({
collection: "game-servers",
data: {
serverId: `${RUN}-srv`,
name: `${RUN} Server`,
status: "online",
},
overrideAccess: true,
depth: 0,
});
serverId = server.id;
});
afterAll(async () => {
for (const id of createdEffectIds) {
await payload.delete({ collection: "operation-effects", id, overrideAccess: true }).catch(() => {});
}
for (const id of createdEventIds) {
await payload.delete({ collection: "operation-events", id, overrideAccess: true }).catch(() => {});
}
for (const id of createdSyncEventIds) {
await payload.delete({ collection: "arma-sync-events", id, overrideAccess: true }).catch(() => {});
}
if (profileId) {
await payload.delete({ collection: "profiles", id: profileId, overrideAccess: true }).catch(() => {});
}
if (userId) {
await payload.delete({ collection: "users", id: userId, overrideAccess: true }).catch(() => {});
}
if (serverId) {
await payload.delete({ collection: "game-servers", id: serverId, overrideAccess: true }).catch(() => {});
}
});
async function createRawEvent(opts: {
eventId: string;
type: string;
payload: JsonValue;
}): Promise<RawSyncEvent> {
const occurredAt = new Date().toISOString();
const syncDoc = await payload.create({
collection: "arma-sync-events",
data: {
eventId: opts.eventId,
server: serverId,
type: opts.type,
occurredAt,
payload: opts.payload,
},
overrideAccess: true,
depth: 0,
});
createdSyncEventIds.push(syncDoc.id);
return {
id: syncDoc.id,
eventId: syncDoc.eventId,
server: serverId,
type: syncDoc.type,
occurredAt,
payload: syncDoc.payload,
};
}
describe("stableStringify", () => {
it("produces stable output regardless of key order", () => {
expect(stableStringify({ b: 1, a: 2 })).toBe(stableStringify({ a: 2, b: 1 }));
expect(stableStringify([{ b: 1, a: 2 }])).toBe(stableStringify([{ a: 2, b: 1 }]));
expect(stableStringify([{ b: 1 }, { a: 2 }])).not.toBe(stableStringify([{ a: 2 }, { b: 1 }]));
});
});
describe("processOperationEvent", () => {
it("records a validated operation.start and derives an operation.started effect", async () => {
const raw = await createRawEvent({
eventId: `${RUN}-evt-start`,
type: "operation.start",
payload: { operationId: RUN, version: 1 },
});
await processOperationEvent(payload, raw);
const events = await payload.find({
collection: "operation-events",
where: { eventId: { equals: raw.eventId } },
limit: 1,
depth: 0,
overrideAccess: true,
});
expect(events.docs).toHaveLength(1);
const event = events.docs[0];
expect(event.status).toBe("validated");
expect(event.operationId).toBe(RUN);
expect(event.type).toBe("operation.start");
expect(event.version).toBe(1);
expect(event.sourceEvent).toBe(raw.id);
expect(event.payloadHash).toBe(hashPayload(raw.payload));
createdEventIds.push(event.id);
const effects = await payload.find({
collection: "operation-effects",
where: { operationEvent: { equals: event.id } },
limit: 10,
depth: 0,
overrideAccess: true,
});
expect(effects.docs).toHaveLength(1);
const effect = effects.docs[0];
expect(effect.effectType).toBe("operation.started");
expect(effect.status).toBe("applied");
expect(effect.sourceEvent).toBe(raw.id);
expect(effect.operationId).toBe(RUN);
createdEffectIds.push(effect.id);
});
it("is idempotent for a duplicate raw event", async () => {
const raw = await createRawEvent({
eventId: `${RUN}-evt-dup`,
type: "operation.end",
payload: { operationId: RUN, version: 1 },
});
await processOperationEvent(payload, raw);
await processOperationEvent(payload, raw);
const events = await payload.find({
collection: "operation-events",
where: { eventId: { equals: raw.eventId } },
limit: 10,
depth: 0,
overrideAccess: true,
});
expect(events.docs).toHaveLength(1);
createdEventIds.push(events.docs[0].id);
const effects = await payload.find({
collection: "operation-effects",
where: { operationEvent: { equals: events.docs[0].id } },
limit: 10,
depth: 0,
overrideAccess: true,
});
expect(effects.docs).toHaveLength(1);
createdEffectIds.push(effects.docs[0].id);
});
it("retains an unsupported-version event with zero effects", async () => {
const raw = await createRawEvent({
eventId: `${RUN}-evt-v2`,
type: "operation.start",
payload: { operationId: RUN, version: 2 },
});
await processOperationEvent(payload, raw);
const events = await payload.find({
collection: "operation-events",
where: { eventId: { equals: raw.eventId } },
limit: 1,
depth: 0,
overrideAccess: true,
});
expect(events.docs).toHaveLength(1);
const event = events.docs[0];
expect(event.status).toBe("rejected");
expect(event.version).toBe(2);
expect(event.error).toMatchObject({ code: "unsupported-version" });
createdEventIds.push(event.id);
const effects = await payload.find({
collection: "operation-effects",
where: { operationEvent: { equals: event.id } },
limit: 10,
depth: 0,
overrideAccess: true,
});
expect(effects.docs).toHaveLength(0);
});
it("records player.kill as validated with zero effects", async () => {
const raw = await createRawEvent({
eventId: `${RUN}-evt-kill`,
type: "player.kill",
payload: [
"Victim", "", `${RUN} Killer`, `${RUN}-steam-001`,
`${RUN} Killer`, `${RUN}-steam-001`, "O_T_Soldier_AT_F", "B_Officer_Parade_Veteran_F",
],
});
await processOperationEvent(payload, raw);
const events = await payload.find({
collection: "operation-events",
where: { eventId: { equals: raw.eventId } },
limit: 1,
depth: 0,
overrideAccess: true,
});
expect(events.docs).toHaveLength(1);
expect(events.docs[0].status).toBe("validated");
expect(events.docs[0].operationId).toBe("unknown");
createdEventIds.push(events.docs[0].id);
const effects = await payload.find({
collection: "operation-effects",
where: { operationEvent: { equals: events.docs[0].id } },
limit: 10,
depth: 0,
overrideAccess: true,
});
expect(effects.docs).toHaveLength(0);
});
it("rejects a malformed payload with zero effects", async () => {
const raw = await createRawEvent({
eventId: `${RUN}-evt-bad`,
type: "operation.start",
payload: [],
});
await processOperationEvent(payload, raw);
const events = await payload.find({
collection: "operation-events",
where: { eventId: { equals: raw.eventId } },
limit: 1,
depth: 0,
overrideAccess: true,
});
expect(events.docs).toHaveLength(1);
expect(events.docs[0].status).toBe("rejected");
expect(events.docs[0].error).toMatchObject({ code: "invalid-payload" });
createdEventIds.push(events.docs[0].id);
const effects = await payload.find({
collection: "operation-effects",
where: { operationEvent: { equals: events.docs[0].id } },
limit: 10,
depth: 0,
overrideAccess: true,
});
expect(effects.docs).toHaveLength(0);
});
it("dead-letters an unknown type with zero effects", async () => {
const raw = await createRawEvent({
eventId: `${RUN}-evt-unknown`,
type: "some.unknown.type",
payload: { anything: true },
});
await processOperationEvent(payload, raw);
const events = await payload.find({
collection: "operation-events",
where: { eventId: { equals: raw.eventId } },
limit: 1,
depth: 0,
overrideAccess: true,
});
expect(events.docs).toHaveLength(1);
expect(events.docs[0].status).toBe("dead-letter");
expect(events.docs[0].type).toBe("some.unknown.type");
expect(events.docs[0].error).toMatchObject({ code: "unsupported-type" });
createdEventIds.push(events.docs[0].id);
const effects = await payload.find({
collection: "operation-effects",
where: { operationEvent: { equals: events.docs[0].id } },
limit: 10,
depth: 0,
overrideAccess: true,
});
expect(effects.docs).toHaveLength(0);
});
it("links actor from the payload", async () => {
const raw = await createRawEvent({
eventId: `${RUN}-evt-extract`,
type: "operation.extraction",
payload: { operationId: RUN, version: 1, actorId: userId, player: `${RUN} Operator` },
});
await processOperationEvent(payload, raw);
const events = await payload.find({
collection: "operation-events",
where: { eventId: { equals: raw.eventId } },
limit: 1,
depth: 0,
overrideAccess: true,
});
expect(events.docs).toHaveLength(1);
expect(events.docs[0].actor).toBe(userId);
createdEventIds.push(events.docs[0].id);
const effects = await payload.find({
collection: "operation-effects",
where: { operationEvent: { equals: events.docs[0].id } },
limit: 10,
depth: 0,
overrideAccess: true,
});
expect(effects.docs).toHaveLength(1);
expect(effects.docs[0].effectType).toBe("operation.extraction-recorded");
createdEffectIds.push(effects.docs[0].id);
});
});
describe("end-to-end via arma-sync-events create", () => {
it("consumes a real sync event through the afterChange hook", async () => {
const syncEvent = await payload.create({
collection: "arma-sync-events",
data: {
eventId: `${RUN}-real-1`,
server: serverId,
type: "operation.start",
occurredAt: new Date().toISOString(),
payload: { operationId: RUN, version: 1 },
},
overrideAccess: true,
depth: 0,
});
createdSyncEventIds.push(syncEvent.id);
const events = await payload.find({
collection: "operation-events",
where: { sourceEvent: { equals: syncEvent.id } },
limit: 1,
depth: 0,
overrideAccess: true,
});
expect(events.docs).toHaveLength(1);
const event = events.docs[0];
expect(event.status).toBe("validated");
expect(event.operationId).toBe(RUN);
expect(event.eventId).toBe(`${RUN}-real-1`);
createdEventIds.push(event.id);
const effects = await payload.find({
collection: "operation-effects",
where: { operationEvent: { equals: event.id } },
limit: 10,
depth: 0,
overrideAccess: true,
});
expect(effects.docs).toHaveLength(1);
const effect = effects.docs[0];
expect(effect.effectType).toBe("operation.started");
expect(effect.sourceEvent).toBe(syncEvent.id);
expect(effect.operationEvent).toBe(event.id);
createdEffectIds.push(effect.id);
});
});
});