1
0
Fork 0

feat(server): allow GM respawn ticket adjustments with permission-gated access

This commit is contained in:
Jason Fraley 2026-09-22 14:52:44 -04:00
parent a6b5b19807
commit 239e95c462
3 changed files with 44 additions and 8 deletions

View file

@ -1,4 +1,5 @@
import { CollectionConfig } from "payload"; import { CollectionConfig } from "payload";
import { requirePermission } from "@/utils/access-control/hasPermission";
/** /**
* Per-player respawn ticket balances. Tickets are awarded automatically when a * Per-player respawn ticket balances. Tickets are awarded automatically when a
@ -8,17 +9,17 @@ import { CollectionConfig } from "payload";
* missions and are served to the Arma 3 mod via the arma-bridge tickets * missions and are served to the Arma 3 mod via the arma-bridge tickets
* route, which loads them into the game at mission start. * route, which loads them into the game at mission start.
* *
* Written internally by the settlement lib (overrideAccess); the admin panel * Written internally by the settlement lib (overrideAccess); GMs can also
* is read-only so balance changes always have a settlement behind them. * adjust balances manually in the admin panel.
*/ */
export const RespawnTickets: CollectionConfig = { export const RespawnTickets: CollectionConfig = {
slug: "respawn-tickets", slug: "respawn-tickets",
admin: { group: "Server", useAsTitle: "user", defaultColumns: ["user", "balance"] }, admin: { group: "Server", useAsTitle: "user", defaultColumns: ["user", "balance"] },
access: { access: {
read: ({ req }) => !!req.user, read: requirePermission("respawn-tickets:read"),
create: () => false, create: requirePermission("respawn-tickets:create"),
update: () => false, update: requirePermission("respawn-tickets:update"),
delete: () => false, delete: requirePermission("respawn-tickets:delete"),
}, },
fields: [ fields: [
{ name: "user", type: "relationship", relationTo: "users", required: true, unique: true, index: true }, { name: "user", type: "relationship", relationTo: "users", required: true, unique: true, index: true },
@ -28,7 +29,7 @@ export const RespawnTickets: CollectionConfig = {
defaultValue: 0, defaultValue: 0,
admin: { admin: {
description: description:
"Accumulated respawn tickets (1 per yes-attended op, 0.5 tentative, 0.25 no). Maintained by settlement; read-only.", "Accumulated respawn tickets (1 per yes-attended op, 0.5 tentative, 0.25 no). Settlement adjusts automatically; GMs can adjust manually.",
}, },
}, },
], ],

View file

@ -1870,6 +1870,11 @@ export interface Role {
| 'mod-lists:update' | 'mod-lists:update'
| 'mod-lists:delete' | 'mod-lists:delete'
| 'admin:mod-lists:manage' | 'admin:mod-lists:manage'
| 'respawn-tickets:create'
| 'respawn-tickets:read'
| 'respawn-tickets:update'
| 'respawn-tickets:delete'
| 'admin:respawn-tickets:manage'
| 'game-servers:create' | 'game-servers:create'
| 'game-servers:read' | 'game-servers:read'
| 'game-servers:update' | 'game-servers:update'
@ -4295,7 +4300,7 @@ export interface RespawnTicket {
id: number; id: number;
user: number | User; user: number | User;
/** /**
* Accumulated respawn tickets (1 per yes-attended op, 0.5 tentative, 0.25 no). Maintained by settlement; read-only. * Accumulated respawn tickets (1 per yes-attended op, 0.5 tentative, 0.25 no). Settlement adjusts automatically; GMs can adjust manually.
*/ */
balance?: number | null; balance?: number | null;
updatedAt: string; updatedAt: string;
@ -9248,6 +9253,18 @@ export interface GameRule {
*/ */
tickIntervalHintMinutes?: number | null; tickIntervalHintMinutes?: number | null;
}; };
/**
* When off, the Zone Pressure feature is hidden from the Operations feed (the overview card and the AAR section).
*/
zonePressureEnabled?: boolean | null;
/**
* When off, the Personnel > Statistics page and its navigation entry are hidden.
*/
statisticsEnabled?: boolean | null;
/**
* When off, the Helpdesk page and its navigation entry are hidden.
*/
helpdeskEnabled?: boolean | null;
updatedAt?: string | null; updatedAt?: string | null;
createdAt?: string | null; createdAt?: string | null;
} }
@ -9340,6 +9357,9 @@ export interface GameRulesSelect<T extends boolean = true> {
coldStartObservations?: T; coldStartObservations?: T;
tickIntervalHintMinutes?: T; tickIntervalHintMinutes?: T;
}; };
zonePressureEnabled?: T;
statisticsEnabled?: T;
helpdeskEnabled?: T;
updatedAt?: T; updatedAt?: T;
createdAt?: T; createdAt?: T;
globalType?: T; globalType?: T;

View file

@ -526,6 +526,16 @@ export const PERMISSION_GROUPS: PermissionGroup[] = [
{ value: "admin:mod-lists:manage", label: "Manage Admin Page" }, { value: "admin:mod-lists:manage", label: "Manage Admin Page" },
], ],
}, },
{
group: "Respawn Tickets",
permissions: [
{ value: "respawn-tickets:create", label: "Create" },
{ value: "respawn-tickets:read", label: "Read" },
{ value: "respawn-tickets:update", label: "Update" },
{ value: "respawn-tickets:delete", label: "Delete" },
{ value: "admin:respawn-tickets:manage", label: "Manage Admin Page" },
],
},
{ {
group: "Game Servers", group: "Game Servers",
permissions: [ permissions: [
@ -907,6 +917,11 @@ export const ALL_PERMISSION_VALUES = PERMISSION_GROUPS.flatMap((g) =>
"mod-lists:update", "mod-lists:update",
"mod-lists:delete", "mod-lists:delete",
"admin:mod-lists:manage", "admin:mod-lists:manage",
"respawn-tickets:create",
"respawn-tickets:read",
"respawn-tickets:update",
"respawn-tickets:delete",
"admin:respawn-tickets:manage",
"game-servers:create", "game-servers:create",
"game-servers:read", "game-servers:read",
"game-servers:update", "game-servers:update",