From d7fafbd88343b4d6fb49b04c0e6d8e62029cd002 Mon Sep 17 00:00:00 2001 From: Z8MB1E Date: Sun, 2 Aug 2026 04:10:43 -0400 Subject: [PATCH] chore: update AGENTS.md with banking system documentation --- AGENTS.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 6d91379..b300724 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -32,7 +32,7 @@ bun run generate:importmap # regenerates payload admin importMap npx tsc --noEmit 2>&1 | grep -E "error TS" | grep -v "\.next/" ``` -Known pre-existing errors, don't chase them: `src/utils/access-control/hasLogisticsQualification.ts` (lines 12, 19 — `'user' is possibly 'null'`) and `src/payload-generated-schema.ts:1848` (generated file). Anything else is yours. +Known pre-existing errors, don't chase them: `src/utils/access-control/hasLogisticsQualification.ts` (lines 12, 19 — `'user' is possibly 'null'`) and `src/payload-generated-schema.ts` (line 1883, generated file — moves when the schema is regenerated). Anything else is yours. ## Test details @@ -67,6 +67,7 @@ Organized by domain under `src/collections/`: - **users/** — Users (auth, username login), Ranks, Profiles, Awards, Qualifications, Assignments, Experience - **intelligence/** — Missions, Campaigns, Factions, Technologies - **logistics/** — Assets, Resources, Vehicles, Structures, Shipments +- **banking/** — BankAccounts, BankTransactions, LedgerEntries - **world/** — Maps, NarrativeEvents - **server/** — MissionFiles, ModLists - **game/** — GameRules (global), GameStructures, GameHardResources, GameEventLogs, GameVehicles @@ -130,6 +131,25 @@ gameTick → POST `/api/game-tick/notify` (guarded by `x-game-tick-secret` heade - Enforced in: `structures/actions.ts` (`addResource`, `transferResource`, `placeResourceOnGrid`), `shipments/actions.ts` (`createShipment` destination check), and `processShipmentTick.ts` on arrival. - UI: `ManageStorageDialog` caps deposits to `min(mass, allowance)` and filters non-whitelisted items; structure page shows an amber "whitelist mode" banner when `restrictToAllowed` is set. +## Banking System + +`src/collections/banking/` — `bank-accounts`, `bank-transactions`, `ledger-entries`. Per-person money for a future market feature plus unit/faction treasuries. Admin group: **Banking**. + +- **BankAccounts**: `name`, `accountType` (`treasury`/`faction`/`personal`), `ownerFaction`/`ownerUser` (relationship, conditionally shown by type), `currency` (→ resources, defaults to the Game Rules main currency), `balance` (number, admin read-only — maintained by transactions), `status` (`open`/`frozen`/`closed`). Read: any logged-in user. Create/update: admin/developer. Delete: developer only. +- **BankTransactions**: `transactionNumber` (unique, auto-generated), `type` (`deposit`/`withdrawal`/`transfer`/`payment`/`fee`/`salary`/`adjustment`), `fromAccount`/`toAccount` (→ bank-accounts, optional per type), `amount`, `fee`, `memo`, `actor` (→ users), `status` (`completed`/`reversed`), `reference` (reversal), `timestamp`. Access: developer create/update/delete, any logged-in read. + - `transactionNumber` is auto-generated in a **beforeValidate hook** (`TXN--`) when empty. **Do not require callers to pass it.** Callers may pass `""` to satisfy TS on the required field — the hook treats falsy as missing. +- **LedgerEntries**: one per affected account per transaction. `account`, `transaction`, `type`, signed `amount` (positive = credit, negative = debit), `balanceAfter`, `memo`, `timestamp`. Read: any logged-in user. Create/update/delete: developer only. +- **Service lib**: `src/lib/banking/index.ts`. + - `applyTransaction(payload, { type, fromAccountId?, toAccountId?, amount, fee?, memo?, actorId? })` — single source of truth for balance math. Validates accounts exist/open/frozen + sufficient funds, creates the `bank-transactions` doc, appends ledger entries (signed), updates both balances, returns the transaction. Throws descriptive `Error`s. + - `createAccount(payload, { name, accountType, ownerFactionId?, ownerUserId? })` — creates a zeroed account in the main currency; throws if no main currency is set in Game Rules. + - `ensurePersonalAccount(payload, userId)` — finds-or-creates a personal account for a user (dedup). + - `getMainCurrencyId` / `getMainCurrencyName` — resolve the Game Rules `mainCurrency` → resource. + - `src/lib/banking/format.ts` — `formatAmount`, `currencyLabel`, `formatDate`. +- **Server actions**: `src/app/(frontend)/logistics/banking/actions.ts`. `createBankAccount` (regular users may only create their own personal account; treasury/faction require a manager), `ensureMyAccount`, `depositFunds`/`withdrawFunds`/`transferFunds`. Permission model: personal accounts are owner- or manager-only; **treasury/faction accounts are manager-only**. Manager = admin/developer or logistics-qualified (`hasLogisticsQualification`). Emits `finance:deposit` / `finance:withdraw` / `finance:transfer` / `bank:account-create` events. +- **UI**: `src/app/(frontend)/logistics/banking/` (overview + `[id]` detail), components in `src/components/frontend/banking/` (`BankingOverview`, `AccountCard`, `AccountDetail`, `CreateAccountDialog`, `BankTransactionDialog`, `LedgerTable`, `MyWalletCard`). Sidebar entry "Banking" under Logistics. +- **Event targets**: `bank-accounts`, `bank-transactions`, `ledger-entries` added to `GameEventLogs` `TARGET_COLLECTIONS` and `emit.ts` `targetCollection` union. Finance event types in `eventTypes.ts`. +- **Gotchas**: Payload's create TS overloads reject `undefined` on relationship/required fields — pass `null` for empty relationships and a concrete value (`""` for `transactionNumber`) or TS falls through to the draft-variant and errors `Property 'draft' is missing`. No migration has been added for these collections yet (project relies on dev `push: true`). + ## Narrative Events System `src/collections/world/NarrativeEvents.ts` — `narrative-events` collection. A flowchart-based narrative event editor using `@xyflow/react` (React Flow) in the Payload admin panel.