1
0
Fork 0
polaris-task-force/src/collections/market/MarketNegotiations.ts
Z8MB1E 653caa8064 feat(rbac): migrate collection access controls to RBAC permissions
Replace legacy isDeveloper/isAdmin/hasRoles checks with
hasPermission/requirePermission across all collections. Add roleDocs
relationship to Users, enlistmentDate to Profiles, and field-level
intel_excerpt permission gate on Profiles. Auto-generated payload-types
updated to reflect the new Roles collection and roleDocs field.
2026-08-19 19:47:51 -04:00

157 lines
4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { CollectionConfig, Where } from "payload";
import type { User } from "@/payload-types";
import { requirePermission, hasPermission } from "@/utils/access-control/hasPermission";
export const MarketNegotiations: CollectionConfig = {
slug: "market-negotiations",
admin: {
group: "Market",
useAsTitle: "id",
defaultColumns: [
"id",
"listing",
"buyer",
"amount",
"patience",
"proposedBy",
"status",
"updatedAt",
],
pagination: { defaultLimit: 50 },
},
access: {
read: async ({ req }) => {
const user = req.user as User | null;
if (!user) return false;
if (await hasPermission(req.payload, user, "market-negotiations:read")) return true;
return {
or: [{ buyer: { equals: user.id } }, { "listing.seller": { equals: user.id } }],
} as Where;
},
create: ({ req }) => !!req.user,
update: async ({ req }) => {
const user = req.user as User | null;
if (!user) return false;
if (await hasPermission(req.payload, user, "market-negotiations:update")) return true;
return {
or: [{ buyer: { equals: user.id } }, { "listing.seller": { equals: user.id } }],
} as Where;
},
delete: requirePermission("market-negotiations:delete"),
},
fields: [
{
name: "listing",
type: "relationship",
relationTo: "market-listings",
required: true,
index: true,
admin: {
description: "The market listing this negotiation thread belongs to.",
},
},
{
name: "buyer",
type: "relationship",
relationTo: "users",
required: true,
index: true,
admin: {
description: "The player interested in buying the listing.",
},
},
{
name: "status",
type: "select",
required: true,
defaultValue: "open",
options: [
{ label: "Open", value: "open" },
{ label: "Accepted", value: "accepted" },
{ label: "Rejected", value: "rejected" },
{ label: "Closed (patience exhausted)", value: "closed" },
{ label: "Cancelled", value: "cancelled" },
{ label: "Expired", value: "expired" },
],
index: true,
},
{
name: "patience",
type: "number",
defaultValue: 0,
min: 0,
max: 100,
admin: {
description:
"NPC vendor patience (0–100). Rises each bargaining round and sharply for lowball offers; at 100 the negotiation closes and the buyer can only buy at the asking price.",
},
},
{
name: "quantity",
type: "number",
min: 1,
defaultValue: 1,
admin: {
description: "How many units the buyer wants from the listing.",
},
},
{
name: "amount",
type: "number",
required: true,
min: 0,
admin: {
description:
"The per-unit price currently on the table. Proposed by the buyer or the seller depending on the proposal.",
},
},
{
name: "proposedBy",
type: "select",
required: true,
defaultValue: "buyer",
options: [
{ label: "Buyer", value: "buyer" },
{ label: "Seller", value: "seller" },
],
},
{
name: "acceptedPrice",
type: "number",
admin: {
description: "The per-unit price agreed when the negotiation is accepted.",
},
},
{
name: "history",
type: "array",
fields: [
{
name: "amount",
type: "number",
required: true,
},
{
name: "from",
type: "select",
required: true,
options: [
{ label: "Buyer", value: "buyer" },
{ label: "Seller", value: "seller" },
],
},
{
name: "note",
type: "text",
},
{
name: "at",
type: "date",
required: true,
defaultValue: () => new Date().toISOString(),
},
],
},
],
timestamps: true,
};