Adds the npc-staffing and labor-classifications collections, a shared staffing field factory applied to both structure blueprints (Staffing Defaults group) and game structure instances, blueprint-derived staffing defaults on game structure create, staff-hiring toggles on Game Rules, and their database migrations.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Adds staff:hired/terminated/headcount-set, staff:salary-paid/unpaid, structure:upgraded/maintenance-paid/maintenance-unpaid/upkeep-short event types and registers npc-staffing as an event target collection.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Drops market's local treasury account lookup in favor of getTreasuryAccountId from the banking lib, re-exported for compatibility.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Market listings, offer dialogs, negotiation panels, and history now render prices from the full CurrencyConfig (symbol + singular/plural) instead of a nullable currency label string.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Banking overview, cards, detail, and activity feed now render amounts from the full CurrencyConfig (symbol + singular/plural) fetched from Game Rules instead of a plain currency label.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Adds a Universal Currency group to Game Rules (name, symbol, singular, plural, denomination) with a CurrencyConfig reader in the banking lib that pluralizes labels and prefixes symbols; registers the game_rules migration.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Extract the static sidebar nav data into sidebarData.ts and add a Wiki
entry (BookOpen) to the main nav. Adds scoped markdown styles
(columns, footnotes, note/warning callouts) under .wiki-markdown.
Index with search/tag/category tabs, new-page form, slug detail page with
create-CTA for missing pages, edit page redirecting to /wiki/new for
missing pages, and revision history page.
Frontend components for the wiki: content renderer (WikiContent),
editor with live preview and formatting toolbar (WikiEditor,
WikiEditorBody, WikiEditorToolbar, WikiLinkDialog, MarkdownGuide),
index/browse (WikiIndex, WikiStandardsDialog), page toolbar with
lock/delete/history (WikiToolbar, LockdownBanner), and revision history
(RevisionList).
Server actions for page create/update, revision restore, lockdown, and
delete (moderator-gated via intelligence qualification) plus wiki image
uploads. Adds wiki event types (wiki:page-create/edit/restore/lock/
unlock/delete) and registers wiki-pages/revisions/templates as valid event
log targets.
Service layer (createPage/updatePage/restoreRevision/setPageLockdown/
deletePage, slugification, template expansion, wikilink preprocessing,
category constants) plus the client-safe markdown rendering pipeline
(react-markdown + remark-gfm + remark-directive) shared by the server
component and the editor's live preview. Adds the three markdown
dependencies to package.json and bun.lock.
Add WikiPages, WikiRevisions, and WikiTemplates collections (admin group
Wiki), register them in the Payload config, and add migration batch 28
creating the wiki_pages/_texts, wiki_revisions, and wiki_templates tables
plus the three wiki values on the game_event_logs target_collection enum.
Includes the regenerated payload-types for the new collections.
Refactors grantAward to accept an array of recipientUserIds, adds
duplicate-award and eligibility checks per recipient, and returns a
per-recipient result summary. GrantAwardDialog gains a third step
showing grant results when some recipients fail. RecipientPicker is
rewritten to support multi-select with chip-based selected state and
a maxSelections cap.
Add transfer workflow components and utilities:
1. Transfer types and core functions (src/lib/transfers/index.ts):
- Type-safe transfer request and decision creation
- Appeal, cancel, and resolve core functions
- Server action conventions with error handling
2. Transfer UI components (src/components/frontend/transfers/):
- TransferActionDialog.tsx: Handle approval/rejection appeals
- TransferApprovalCard.tsx: Display approval decisions
- TransferNoteDialog.tsx: Add notes for transfers/appeals
- TransferRequestCard.tsx: Show transfer request details
- TransferResolutionCard.tsx: Display superuser resolutions
- TransfersView.tsx: Main transfers list page
- transferTypes.ts: Shared TypeScript types
3. Notification types (src/lib/transfers/notificationTypes.ts):
- Define notification type constants for transfer events
- Include TRANSFER_NOTIFICATION_TYPES for bridge filtering
4. Integration tests (tests/int/):
- transfer-requests.int.spec.ts: Test bot request polling
- transfer-bot-delivery.int.spec.ts: Test Discord notification delivery
These components and utilities complete the transfer workflow
implementation including approvals, appeals, and delivery.
Add AssignmentCard component integration showing user's assignments with transfer button.
Add RequestTransferDialog integration for requesting transfers.
Display current assignments as badges with leader indication.
Include proper loading states and error handling.
Update Payload configuration:
- Import AssignmentTransfers collection in src/payload.config.ts
Update notification system:
- src/lib/notifications/index.ts: Add transfer notification types
- Update notification helper to support new notification types
Update migrations index:
- src/migrations/index.ts: Register new assignment transfer migrations
These changes integrate the AssignmentTransfers collection into the
existing Payload configuration and notification infrastructure.
Add React components for assignment transfer user interface:
1. AssignmentCard.tsx: Display user's current assignment with transfer button.
Shows assignment details, current status, and allows initiating transfer requests.
2. RequestTransferDialog.tsx: Modal dialog for creating transfer requests.
- Selects target assignment from assignment list
- Optionally notes required for transfer
- Submits request to AssignmentTransfers collection
- Emits AssignmentTransferRequest event
3. Transfers page (src/app/(frontend)/transfers/): Transfer request list view.
- Requests card showing pending requests with requestor, target, current
- Approval cards for assignment leaders
- Appeal cards for rejected requests
- Completed/Cancelled status display
All components use shadcn/ui primitives, proper loading states, error handling,
and provide accessible keyboard navigation.
Add Discord bot services for assignment transfer interactions:
1. transferInteractions.ts: Handle button interactions for transfer requests,
approvals, rejections, appeals, completions, and cancellations.
2. transferRequests.ts: Poll for pending assignment transfers and trigger
notification delivery to Discord when status changes to pending/approved/rejected.
3. transferDelivery.ts: Deliver transfer notifications to users via DMs with
embeds showing status, details, and actions (approve/reject/appeal).
4. transferMessaging.ts: Provide Discord embed building for transfer messages
with status badges and action buttons.
5. Update bot index.ts: Add transfer button interaction handler with customId prefix "ptf-xfer:"
6. Update notificationBridge.ts: Exclude transfer notification types from general
notification polling to avoid duplication (Phase 2 feature).
Integration: Services are started via src/bot/services/index.ts and run alongside
existing mission and notification services.
Add event logging constants for assignment transfer events:
- AssignmentTransferRequest: Request initiated by user
- AssignmentTransferApprove: Leader approved transfer
- AssignmentTransferReject: Leader rejected transfer with reason
- AssignmentTransferAppeal: User appealed a rejection
- AssignmentTransferResolve: Final resolution by superuser
- AssignmentTransferComplete: Transfer completed successfully
- AssignmentTransferCancel: Transfer cancelled
Add assignment-transfers to GameEventLogs TARGET_COLLECTIONS
Add emitGameEvent support for all transfer event types in src/utils/event-log/emit.ts
This provides audit trail and notification support for the transfer workflow.
Add new AssignmentTransfers collection with fields for managing assignment transfer requests:
- requestor, requestedAssignment, currentAssignment (relationships to users/assignments)
- status (pending/approved/rejected/appealed/escalated/completed/cancelled)
- rejectionReason, appealReason (for rejections and appeals)
- transferAt, approvedAt, appealedAt, completedAt (audit timestamps)
- transferLead (relationship to users, current and requested assignment leaders)
- requestMessage, appealMessage (optional context messages)
Add database migrations:
- 20260831_180233_assignment_transfers: Create the main collection table
- 20260901_014006_add_assignment_transfer_event_target: Add assignment-transfers to GameEventLogs target collections
The collection enables the assignment transfer workflow where users can request transfers,
leaders can approve/reject with reasons, and users can appeal rejections.
Add a Profiles afterChange hook that diffs progression.awards against previousDoc (row id, falling back to award+date composite key) and sends an award:granted notification including the grant reason and issuer. Register award:granted as a muteable notification type.
- importArmaLibrary: upsert Arma export catalog into assets/vehicles via
Payload, materialize .paa thumbnails (convertPaaToPng) and link uploads,
resolve Fuel resource for vehicle fuel defaults
- extractArmaIcons: ref-driven PBO .paa extraction into a --paa-root tree
shaped like inventory icon ref paths
- package.json: add import:arma script
When the structure type has an image, render it as a full-bleed
cover behind the page header with vertical and horizontal gradient
overlays; text shifts to white for contrast. Headers without an
image keep the previous plain layout.
Add src/tools/cli with a CliFlow helper (boxed headers, labeled log
lines) and a reset-password command stub wired to the prompt package.
Runnable via 'bun run u:reset-password'; interactive flow to follow.
Add gap-1.5 to the roster tab triggers so icons and labels are not
glued together, and let the org chart tab scroll horizontally instead
of overflowing the page.
requireArmaServer (src/lib/arma-bridge/server.ts) wraps the shared
bridge auth + game-servers lookup that every v1 route repeated;
asJson (json.ts) narrows untrusted request values to what Payload's
json field validation accepts (strings normalize to the fallback
instead of failing the write). All four v1 routes now use both.
Also document the ARMA_BRIDGE_API_KEY env var missed when the bridge
routes landed.
Add the mission-tick Payload bin (external cron): sweeps missions
whose status is Scheduled/Active and whose scheduled calendar day
(classification.startDateTime, server-local) has fully passed and
sets them to Completed, emitting a mission:auto-complete event per
mission. Draft and terminal statuses are never touched; idempotent.
Notifies clients via the game-tick SSE path.
Logic lives in src/lib/intelligence/missionLifecycle.ts with an
integration test in tests/int/mission-lifecycle.int.spec.ts.
Cloning a mission whose array rows still carry the source doc's row
ids trips a unique-constraint violation in the drizzle adapter,
surfacing as 'ValidationError: The following field is invalid: id'.
Walk the collection's field schema (groups, tabs, rows, nested
arrays) and strip row ids before create — schema-driven so Lexical
richText blobs are cloned verbatim.
Also adopt the bin file logger and the standard fatal-error exit
path.
Add createBinLogger (src/scripts/lib/binFileLogger.ts): every log call
is appended synchronously to logs/<bin-key>/<YYYY-MM-DD>.log (UTC) in
addition to the console logger — sync writes because bin scripts
process.exit() immediately. Bin bodies are wrapped in try/catch so a
fatal error is logged to file and exits code 1. Override the directory
with BIN_LOG_DIR. logs/ is gitignored.
game-tick, market-tick, and processShipmentTick adopt the logger;
generate-mission follows with its clone fix; mission-tick lands with
its feature. Document BIN_LOG_DIR in .env.example and the logging in
AGENTS.md / README.
Mission objectives gain a redacted checkbox. Redacted objectives are
shown block-redacted to players; mission managers, authors, and Zeus
see the real text (via tooltip) and can toggle the flag from the
mission detail page. Toggles emit mission:objective-redacted-toggle
events. Also registers the mission:auto-complete event type used by
the upcoming mission-tick bin.
With the MCP plugin enabled, payload.auth() can return a
payload-mcp-api-keys doc instead of a User. Add an isPayloadUser
type guard and use it in every server action, page, and route that
treats the auth result as a real user, so API-key sessions can no
longer pass user auth checks. hasRoles now explicitly requires a
users-collection doc.
Register mcpPlugin on the Payload config. Auth now also accepts
payload-mcp-api-keys, so the generated types carry the new
collection and the user union widens accordingly. Follow-up commits
guard user auth paths against these API-key sessions.
Also apply incidental prettier formatting to generatePlainText().
Move Banking and Market out of Logistics into a commerce group beside Personal, and add a quick XP mini-mode toggle synced to the saved display preference via the layout-provided preferences prop.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add the mini XP display switch to PreferencesForm, wire it through the account page, and cover it in the integration test.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add the xpDisplayMini checkbox to user display preferences, regenerate types, and accept it in updatePreferences.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Thread the Payload request through createAccount/ensurePersonalAccount and the Users beforeChange hook writes so nested creates share the parent transaction instead of failing FK checks on a fresh connection.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add key-and-server-id authenticated endpoints for server heartbeat, event ingestion, and command pull/ack.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add GameServers, ArmaSyncEvents and ArmaCommands collections plus registration in payload config and regenerated types.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>