1
0
Fork 0
polaris-task-force/src/lib/base/storage.ts
Z8MB1E c33d0ceb27 feat(base): add staffing service library
Adds the lib/base service layer: hire/fire staff, set labor headcount, storage consumption helpers, and structure upgrade handling, all with event logging and permission checks.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-06 01:24:08 -04:00

42 lines
1.5 KiB
TypeScript

import type { Payload } from "payload";
import type { GameStructure, Resource } from "@/payload-types";
type StorageEntry = NonNullable<GameStructure["storedResources"]>[number];
export function relationshipId(
value: number | { id: number } | null | undefined,
): number | null {
if (typeof value === "number") return value;
return value?.id ?? null;
}
export function storedAmount(entries: readonly StorageEntry[], resourceId: number): number {
return entries.reduce((total, entry) => {
return total + (relationshipId(entry.resource) === resourceId ? entry.amount : 0);
}, 0);
}
export function consumeStorage(
entries: readonly StorageEntry[],
resourceId: number,
requested: number,
): { readonly entries: StorageEntry[]; readonly remaining: number } {
let remaining = requested;
const updated = entries
.map((entry) => {
if (remaining <= 0 || relationshipId(entry.resource) !== resourceId) return entry;
const consumed = Math.min(entry.amount, remaining);
remaining -= consumed;
return { ...entry, amount: entry.amount - consumed };
})
.filter((entry) => entry.amount > 0);
return { entries: updated, remaining };
}
export async function resourceName(payload: Payload, resource: number | Resource): Promise<string> {
if (typeof resource === "object") return resource.name;
const document = await payload
.findByID({ collection: "resources", id: resource, depth: 0, overrideAccess: true })
.catch(() => null);
return document?.name ?? `Resource #${resource}`;
}