teqo-backup/src/utilities/campaignEntityActions.ts
Francisco Ignácio Fontoura Solla f23c2582ee Break up the god modules into deep domain modules
- campaignAccess.ts (990 lines, ~80 exports) is now a 130-line explicit
  re-export surface over 14 domain modules in src/utilities/access/
  (shared actor predicates + per-collection access); public surface
  AST-verified identical, import sites untouched
- actions/supporter.ts split: single-supporter lifecycle (407) vs the CSV
  import pipeline in supporterImport.ts (357); 'use server' re-export
  constraint honored with thin async delegates
- organization/stateDeputy clone twins deduped by POLICY:
  runStaffEntityMutation (fresh staff assert + unique-conflict translation)
  keeps each caller's concretely-typed Payload mutation
- runCampaignRedirectFormAction removes the copy-pasted try/map/redirect
  ladder from 4 create formActions (planos kept its genuinely custom flow)
- Plaza→Municipality identifier rename finished (context keys, list-label
  and leadership constants, fixture sequence, test constants)
- RefreshRouteOnSave (React component) moved out of utilities/ to components/
2026-07-23 23:44:45 -03:00

39 lines
1.2 KiB
TypeScript

import 'server-only'
import type { Payload } from 'payload'
import type { CampaignUser } from '@/payload-types'
import { reloadStaffActor } from '@/utilities/campaignActionContext'
/**
* Shared policy for simple staff-managed reference entities (organizações,
* dobradinhas): fresh staff assert → run the caller's concretely-typed
* mutation → translate unique-index conflicts into a safe user-facing message.
*/
export type StaffEntityPolicy = {
/** Thrown when the fresh actor is not campaign staff. */
staffMessage: string
/** Matches the collection's unique-index violation. */
conflictPattern: RegExp
/** Safe user-facing message for a unique conflict. */
conflictMessage: string
}
export const runStaffEntityMutation = async <Result>(
payload: Payload,
actor: CampaignUser,
policy: StaffEntityPolicy,
mutate: (currentActor: CampaignUser) => Promise<Result>,
): Promise<Result> => {
const currentActor = await reloadStaffActor(payload, actor, policy.staffMessage)
try {
return await mutate(currentActor)
} catch (error) {
const message = error instanceof Error ? error.message : String(error)
if (policy.conflictPattern.test(message)) {
throw new Error(policy.conflictMessage)
}
throw error
}
}