1
0
Fork 0

docs: comprehensively document event log system in AGENTS.md

- Update schema to reflect system field, targetCollection select options,
  and access controls (read/create for all, update for admins/devs,
  delete for devs only)
- Document narrative event creation workflow for GM/admin use
- Document EventLedger UI behavior: refreshKey prop, 30s polling, actor
  prefix with 'You' substitution, multi-select type filter, narrative
  styling, flicker-free re-fetch
- Add step-by-step guide for adding event logging to new actions
- Document non-structure events limitation and future pattern
This commit is contained in:
Jason Fraley 2026-07-28 16:09:48 -04:00
parent dfbe0cb6c5
commit 9fd4b22d90

View file

@ -68,13 +68,35 @@ Access control helpers live in `src/utils/access-control/` (isRole, hasRoles). R
## Event Log System
`src/collections/game/GameEventLogs.ts` — append-only `game-event-logs` collection.
`src/collections/game/GameEventLogs.ts` — `game-event-logs` collection.
- **Schema**: `timestamp`, `type` (text/indexed), `message` (human-readable), `actor` (→ users), `structure` (→ game-structures), `targetCollection`/`targetId` (polymorphic ref), `data` (JSON blob).
- **Emit**: `emitGameEvent(payload, { type, message, actor?, structure?, targetCollection?, targetId?, data? })` in `src/utils/event-log/emit.ts`.
- **Types**: `EventTypes` constants in `src/utils/event-log/eventTypes.ts` — add new event categories there without touching the collection.
- **Schema**: `system` (boolean, default `true` — system-generated vs GM/narrative), `timestamp`, `type` (text/indexed), `message` (human-readable), `actor` (→ users), `structure` (→ game-structures), `targetCollection` (select — pick from known collections), `targetId` (number, polymorphic ref), `data` (JSON blob).
- **Access**: any logged-in user can read/create. Update restricted to admins/developers. Delete restricted to developers.
- **Emit**: `emitGameEvent(payload, { type, message, actor?, structure?, targetCollection?, targetId?, data? })` in `src/utils/event-log/emit.ts`. Silently catches errors (fire-and-forget). Always sets `system: true`.
- **Types**: `EventTypes` constants in `src/utils/event-log/eventTypes.ts` — add new event categories there without touching the collection. Using these constants gives TypeScript narrowing on the `type` field.
- **Wiring**: Server actions in `actions.ts` emit events after successful mutations. `GameStructures` afterChange hook catches admin-panel storage edits. `Structures` beforeChange hook emits `structure:resize`.
- **UI**: `EventLedger` component (`src/components/frontend/storage/EventLedger.tsx`) queries the REST API for a given `structureId` and renders a scrollable feed. Integrated in `StructureStorageView`.
- **targetCollection options**: `game-structures`, `structures`, `resources`, `assets`, `vehicles`, `factions`, `missions`, `campaigns`, `users`, `technologies`, `maps`. If a new collection is added that should be a valid target, add an option here.
- **Narrative events**: admins/developers can create entries manually in the Payload admin panel with `system: false` for GM-written narrative events. These are visually distinct in the UI (amber accent, book icon).
### UI
`EventLedger` component (`src/components/frontend/storage/EventLedger.tsx`):
- Queries the REST API (`/api/game-event-logs`) for a given `structureId` and renders a scrollable feed.
- Accepts optional `refreshKey` prop — parent passes an incrementing counter to trigger re-fetch after mutations.
- Auto-polls every 30s for background updates.
- Shows actor name prefix ("You" for current user, username for others).
- Filter by event type via multi-select shadcn `DropdownMenuCheckboxItem`.
- Narrative events (system: false) styled with amber border + book icon.
- On re-fetch, preserves existing entries while loading to avoid flicker.
### Adding event logging for new actions
1. Add event type constant to `src/utils/event-log/eventTypes.ts` if it doesn't exist yet.
2. If the target collection slug isn't in the `TARGET_COLLECTIONS` array in `GameEventLogs.ts`, add it.
3. Call `emitGameEvent(payload, { type: EventTypes.xxx, message: "...", ... })` after the successful mutation in the server action.
4. `EventLedger` will pick it up automatically if it's scoped to the same `structureId`.
### Non-structure events
The `EventLedger` currently filters by `structure.id`. For event logs scoped to other entities (e.g., faction finance ledger), a new ledger variant would need to be created that queries by `targetCollection` + `targetId` instead.
## Auth