Satisfies the Next 16 rule that page files only export page fields:
getSupplyBoxDetail/getSupplyBoxList and getReservationList/getReservationDetail
move to reservations/surface.ts and pages import from it.
- Maps gain worldMap flag, description, freeform weather, latitude/longitude,
easeOfAccess and factionControl; picker cards render them as stat tags
- resource-nodes gain a shared icon set and may exist with no resources as
plain marker nodes (placement ignores marker-only nodes)
- sidebar gains the World Map entry; Infrastructure section gets defaultOpen
- migrations 20260921_120000/123000/130500/134000; includes the generated
types/schema sweep (currency emblem fields land in the next commit)
Add the Leaflet map page and client (markers, labels, layer toggles, shipment interpolation), the placement and authoring server actions, the map-features and map-import API routes, and the map styles including leaflet pane isolation so portals stack correctly.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Blueprints declare constructionDurationMinutes instead of tick counts. Delivering the last material starts construction at delivery time via maybeStartConstruction, setting constructionStartedAt/CompletesAt on the site; the game tick only sweeps completed sites. Structure detail page extracts server data helpers and shows a ConstructionPanel with a literal ETA countdown.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add pure routing, placement, point, and style libs plus map-system tests. Shipments gain a map relationship and routePath snapshot; ground vehicles route over the road network via Dijkstra while air and sea travel straight-line. Vehicle types declare a ground/air/sea transportMode and transit math works in meters.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Deposits/withdrawals of stock (economy-mutating) are now superuser-only, while moving items around (transfer/place/collect) stays open to logistics-qualified users; seed roles updated to match. ManageStorageDialog reworked alongside its toolbar/button/view wrappers, and the structure page wires up the new permission split.
Add getReferencePrices (modifier-applied NPC vendor price tip in CreateListingDialog) and resetEconomyState server action with a permission-gated 'Reset economy' button on listing cards for managers.
Ultraworked with [Sisyphus](https://github.com/code-yeongju/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Adds hire/terminate staff actions and an upgradeStructure server action plus baseManagement components (employment card, hire dialog, staff roster, upgrade card) wired into the structure detail page.
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>
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.
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.
Replace hasRoles calls with hasPermission in all server actions and page
components. Update qualification checks (logistics, intelligence) to use
permission-based checks instead of role name matching. Update staff lookup
in tickets/staff.ts to query roles collection. Use enlistmentDate field
on profile page instead of createdAt.
Tarkov-style flea market where users list locker items at a fixed price
and buyers pay through the banking system; items transfer directly
into the buyer's locker.
- market-listings + market-negotiations collections and the market page
with search/rarity filters and a Countdown timer on each card
- service lib (buyListing with partial-quantity + negotiated-price
support, clean-stock rule, creditLockerQuantity, auto pricing)
- negotiation flow: make/accept/reject/counter/withdraw, strictly-
increasing buyer offers, NPC vendor auto-resolution
- NPC vendors: game-npcs attribution, patience meter, dialogue, chat
bubbles, historical threads dialog
- 30d user / 7d auto listing durations, market-tick bin for expiry +
vendor restock, SSE notify on tick
- market event types + game-npcs/market target collections in the
event log; sidebar Market entry under Logistics
- partial-quantity purchases (buyListing/buyMarketListing/makeMarketOffer)
with full int test coverage (25 tests)
- Add resources list page with resource cards and detail pages
- Add vehicles list page with vehicle cards, filters, and detail pages
- Add ResourceCard, VehicleCard, and VehicleFilters components
- Widen structure detail page max-width from 4xl to 7xl
- New game-event-logs collection with timestamp, type, message, actor,
structure, targetCollection/targetId, and data (JSON) fields
- EventTypes constants registry for modular event category management
- emitGameEvent() utility for emitting events from server actions and hooks
- Register collection in Payload config
- Document event log system architecture in AGENTS.md
Server action: remove 'other.id === entryId' exclusion from the
split overlap scan so the source item's own footprint is treated
as occupied, forcing the split to find a different position.
UI: disable the split button via findEmptySpot check when no room
exists for the split stack, preventing a failed action.
- Move storage overview from /logistics/storage to /logistics root
- Rename page heading and sidebar label from Storage to Structures
- Update back link on structure detail page
- Remove old /logistics/storage route
- addResource, removeResource, placeResourceOnGrid, removeGridItem
now require admin or developer role (game master operations)
- transferResource, moveGridItem, mergeGridStacks, rotateGridItem,
splitGridStack, autoArrangeGrid require user, admin, or developer
(logistics operations that don't change total inventory)
- Guests are excluded from all mutating operations
Replace flat ResourceList with StructureStorageView (grid/list
toggle for structures with dimensions, flat list fallback for
non-grid structures). Apply pluralize to upkeep labels.
addResource now auto-places deposited resources onto the structure
grid (first-fit scan, fills existing stacks first, falls back to
flat-list behavior for non-grid structures).
New server actions:
- placeResourceOnGrid — explicit placement at x,y,rotated
- moveGridItem — move item to new position with optional rotation
- mergeGridStacks — merge two stacks of the same resource
- rotateGridItem — toggle rotation in-place
- removeGridItem — delete a grid entry
- splitGridStack — split a stack into two at an empty spot
- autoArrangeGrid — re-pack all items into grid