1
0
Fork 0
polaris-task-force/src/collections/operations/OperationEffects.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

108 lines
No EOL
3 KiB
TypeScript

import type { CollectionConfig } from "payload";
/**
* Derived-effect ledger for validated operation events.
*
* One row per (event, effect type) pair, keyed by `effectKey` =
* `${eventId}:${effectType}` so an exact retry is a no-op. Effects are the
* only place derived operation state may be recorded; they always carry
* provenance back to both the operation event and the raw source event.
*
* Writes are internal only (create/update/delete denied; the bridge writes
* via `overrideAccess`). Read is open to any logged-in user.
*/
export const OperationEffects: CollectionConfig = {
slug: "operation-effects",
admin: {
group: "Operations",
useAsTitle: "effectKey",
defaultColumns: ["effectKey", "operationId", "effectType", "status", "appliedAt"],
},
access: {
read: ({ req }) => !!req.user,
create: () => false,
update: () => false,
delete: () => false,
},
fields: [
{
name: "operationEvent",
type: "relationship",
relationTo: "operation-events",
required: true,
index: true,
admin: {
description: "The validated operation event this effect derives from.",
},
},
{
name: "sourceEvent",
type: "relationship",
relationTo: "arma-sync-events",
required: true,
index: true,
admin: {
description: "The raw source event this effect derives from.",
},
},
{
name: "operationId",
type: "text",
required: true,
index: true,
},
{
name: "effectKey",
type: "text",
required: true,
unique: true,
index: true,
admin: {
description: "Idempotency key: `${eventId}:${effectType}`.",
},
},
{
name: "effectType",
type: "select",
required: true,
options: [
{ label: "Operation Started", value: "operation.started" },
{ label: "Operation Ended", value: "operation.ended" },
{ label: "Objective Updated", value: "operation.objective-updated" },
{ label: "Extraction Recorded", value: "operation.extraction-recorded" },
{ label: "Inventory Recorded", value: "operation.inventory-recorded" },
],
},
{
name: "status",
type: "select",
required: true,
defaultValue: "applied",
options: [
{ label: "Applied", value: "applied" },
{ label: "Pending", value: "pending" },
{ label: "Failed", value: "failed" },
{ label: "Reversed", value: "reversed" },
],
},
{ name: "payload", type: "json" },
{
name: "reversalOf",
type: "relationship",
relationTo: "operation-effects",
admin: {
description: "Set when this effect reverses another effect.",
},
},
{
name: "reversedBy",
type: "relationship",
relationTo: "operation-effects",
admin: {
description: "Set when this effect has been reversed.",
},
},
{ name: "reconciliationNotes", type: "textarea" },
{ name: "appliedAt", type: "date" },
],
};