Add docs/map-system.md with the mapping table and update AGENTS.md plus sub-AGENTS files for the map collections, routing, placement, and construction model. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
4.5 KiB
4.5 KiB
AGENTS.md — Payload Collections
Parent:
../../AGENTS.md— commands, RBAC basics, Payload CMS config.
Overview
54 files (~53 collections) across 15 domain groups. Access control defined in src/permissions/index.ts (~870 lines, permission registry across groups). RBAC check: hasPermission(payload, user, "collection:action").
Structure
collections/
Media.ts # Image uploads (public read; used by wiki image upload)
Shims.ts # Global: audience-targeted content (admin-only)
users/ 11 files # Users (auth), Ranks, Profiles (incl. minigame stats), Awards,
# Qualifications, Assignments, AssignmentTransfers, Experience,
# Evaluations, Roles (dynamic RBAC), UserNotifications
intelligence/ 5 files # Missions, MissionAttendances, Campaigns, Factions, Technologies
logistics/ 5 files # Structures (staffing defaults), Resources, Assets, Vehicles, Shipments
banking/ 3 files # BankAccounts, BankTransactions, LedgerEntries
market/ 2 files # MarketListings, MarketNegotiations
locker/ 2 files # LockerStorages, Loadouts
game/ 9 files # GameRules (global, currency + staffing flags), GameStructures,
# GameVehicles, GameNpcs, GameHardResources, GameEventLogs,
# NpcStaffing, LaborClassifications (+ shared staffingFields.ts factory)
server/ 5 files # MissionFiles, ModLists, GameServers, ArmaCommands, ArmaSyncEvents
world/ 5 files # Maps (basemap config), MapRoads/MapZones/ResourceNodes (map features), NarrativeEvents
projects/ 4 files # Projects, Labels, Releases, Sprints (Jira-like)
tickets/ 2 files # Tickets (Lexical rich text), TicketVotes
wiki/ 3 files # WikiPages, WikiRevisions, WikiTemplates
Key relationships
Users ──┬── Profiles ──┬── Qualifications
│ ├── Awards
│ ├── Assignments ── Ranks
│ ├── AssignmentTransfers
│ └── Experience
├── UserNotifications
├── Evaluations
└── BankAccounts ── BankTransactions ── LedgerEntries
GameStructures ── Structures (template) ── Resources/Assets/Vehicles
GameStructures ── NpcStaffing ── LaborClassifications
GameVehicles ── Vehicles (template)
GameNpcs ── MarketListings ── MarketNegotiations
MissionAttendances ── Missions ── Campaigns
Access control pattern
Collections define access at field + document level using helpers from src/utils/access-control/:
isRole(role)— single role checkhasRoles(roles[])— any-of role checkhasPermission(payload, user, "collection:action")— full RBAC (cached 30s)hasLogisticsQualification()/hasIntelligenceQualification()— queries Profiles
Admin group access: developer only for destructive operations, admin for read/write.
Hooks with side effects
StructuresbeforeChange: emitsstructure:resize; blueprint "Staffing Defaults" group viastaffingFields.tsGameStructuresafterChange: emits storage edit events;beforeChangecopies blueprint staffing defaults on createUsersafterChange: maintains profile syncBankTransactionsbeforeValidate: auto-generatestransactionNumberMarketNegotiations: patience meter enforcement
Where to look
| Task | Path |
|---|---|
| Add a new collection | Create <Name>.ts here, register in src/payload.config.ts |
| Add RBAC permission | src/permissions/index.ts (add to group + add check) |
| Modify collection access | <collection>/access.ts or inline in collection file |
| Add field hook | Inline in collection definition (beforeChange/afterChange) |
| Relationship graph | See key relationships above; Payload manages FK constraints |
Anti-patterns
- NEVER edit
src/payload-types.tsorsrc/payload-generated-schema.ts— runbun run generate:typesinstead - NEVER add
accessfunctions that callpayload.auth()without handling the null user case - NEVER use
payload.createinafterChangehooks without checking for infinite loops - NEVER mix
overrideAccess: truewithout a permission check — always gate behind RBAC first