import type { AuthUser } from "@/auth/types"; import type { RuleEngineResourceSlug } from "@/types/rule-engine"; export const FREIGHT_PERMS = { bookings: { view: "edr_freight_app:bookings:view", clearanceView: "edr_freight_app:bookings:clearance_view", staffAccept: "edr_freight_app:bookings:staff_accept", requestChanges: "edr_freight_app:bookings:request_changes", reject: "edr_freight_app:bookings:reject", approveLineStaff: "edr_freight_app:bookings:approve_line_staff", approveDirector: "edr_freight_app:bookings:approve_director", approveCeo: "edr_freight_app:bookings:approve_ceo", rejectApproval: "edr_freight_app:bookings:reject_approval", generateContract: "edr_freight_app:bookings:generate_contract", signStaff: "edr_freight_app:bookings:sign_staff", operations: "edr_freight_app:bookings:operations", cancel: "edr_freight_app:bookings:cancel", reviewDocuments: "edr_freight_app:bookings:review_documents", uploadClearanceOutput: "edr_freight_app:bookings:upload_clearance_output", finalizeClearance: "edr_freight_app:bookings:finalize_clearance", }, contracts: { view: "edr_freight_app:contracts:view", staffAccept: "edr_freight_app:contracts:staff_accept", requestChanges: "edr_freight_app:contracts:request_changes", reject: "edr_freight_app:contracts:reject", approveLineStaff: "edr_freight_app:contracts:approve_line_staff", approveDirector: "edr_freight_app:contracts:approve_director", approveCeo: "edr_freight_app:contracts:approve_ceo", generateContract: "edr_freight_app:contracts:generate_contract", signStaff: "edr_freight_app:contracts:sign_staff", clearanceReview: "edr_freight_app:contracts:clearance_review", finalizeClearance: "edr_freight_app:contracts:finalize_clearance", createBooking: "edr_freight_app:contracts:create_booking", opsClearanceReview: "edr_freight_app:contracts:ops_clearance_review", clearanceDutyAdvise: "edr_freight_app:contracts:clearance_duty_advise", clearanceEtActions: "edr_freight_app:contracts:clearance_et_actions", clearanceDjActions: "edr_freight_app:contracts:clearance_dj_actions", }, trainScheduling: { view: "edr_freight_app:train_scheduling:view", manage: "edr_freight_app:train_scheduling:manage", }, fleet: { view: "edr_freight_app:fleet:view", manage: "edr_freight_app:fleet:manage", }, admin: "edr_freight_app:admin", allocation: { manage: "edr_freight_app:allocation:manage", }, } as const; const slugToResourceKey = (slug: RuleEngineResourceSlug): string => slug.replace(/-/g, "_"); export function getPermissionKeys(user: AuthUser | null | undefined): string[] { if (!user) return []; if (user.permissionKeys?.length) return user.permissionKeys; const keys = new Set(); for (const p of user.permissions ?? []) { if (p.key) keys.add(p.key); } for (const emp of user.employee ?? []) { for (const pos of emp.positions ?? []) { for (const p of pos.permissions ?? []) { if (p.key) keys.add(p.key); } } } return [...keys]; } /** Position keys held by the user (e.g. "ethiopian_gl", "djibouti_gl"). */ export function getPositionKeys(user: AuthUser | null | undefined): string[] { if (!user) return []; const keys = new Set(); for (const emp of user.employee ?? []) { for (const pos of emp.positions ?? []) { if (pos.key) keys.add(pos.key); } } return [...keys]; } export function hasPosition( user: AuthUser | null | undefined, positionKey: string, ): boolean { return getPositionKeys(user).includes(positionKey); } export const POSITION_KEYS = { ethiopianGl: "ethiopian_gl", djiboutiGl: "djibouti_gl", } as const; export function isEthiopianGl(user: AuthUser | null | undefined): boolean { return hasPosition(user, POSITION_KEYS.ethiopianGl); } export function isDjiboutiGl(user: AuthUser | null | undefined): boolean { return hasPosition(user, POSITION_KEYS.djiboutiGl); } export function isSuperAdmin(user: AuthUser | null | undefined): boolean { if (user?.isSuperAdmin) return true; return Boolean(user?.roles?.some((r) => r.key === "super_admin")); } /** Org-level admins may act on any approval step in the chain. */ export function isOrganizationAdmin( user: AuthUser | null | undefined, ): boolean { return Boolean(user?.roles?.some((r) => r.key === "organization_admin")); } export function isFreightApprovalAdmin( user: AuthUser | null | undefined, ): boolean { return isSuperAdmin(user) || isOrganizationAdmin(user); } export function hasPermission( user: AuthUser | null | undefined, key: string, ): boolean { if (!user) return false; if (isSuperAdmin(user)) return true; return getPermissionKeys(user).includes(key); } export function canAccessBookings(user: AuthUser | null | undefined): boolean { return hasPermission(user, FREIGHT_PERMS.bookings.view); } export function canAccessContracts(user: AuthUser | null | undefined): boolean { return hasPermission(user, FREIGHT_PERMS.contracts.view); } /** Can review the GL Ethiopia pre-booking contract clearance queue (Path B). */ export function canReviewContractClearance( user: AuthUser | null | undefined, ): boolean { return hasPermission(user, FREIGHT_PERMS.contracts.clearanceReview); } /** GL Ethiopia: can create a booking under a cleared contract (Path B). */ export function canCreateContractBooking( user: AuthUser | null | undefined, ): boolean { return hasPermission(user, FREIGHT_PERMS.contracts.createBooking); } /** Operations: can review the Path A self-clearance queue (non-customs). */ export function canReviewSelfClearance( user: AuthUser | null | undefined, ): boolean { return hasPermission(user, FREIGHT_PERMS.contracts.opsClearanceReview); } /** Can see/manage the customs document-clearance queue (Global Logistics). */ export function canViewClearance(user: AuthUser | null | undefined): boolean { return hasPermission(user, FREIGHT_PERMS.bookings.reviewDocuments); } export function canViewScheduling(user: AuthUser | null | undefined): boolean { return hasPermission(user, FREIGHT_PERMS.trainScheduling.view); } export function canManageScheduling(user: AuthUser | null | undefined): boolean { return hasPermission(user, FREIGHT_PERMS.trainScheduling.manage); } export function canViewFleet(user: AuthUser | null | undefined): boolean { return hasPermission(user, FREIGHT_PERMS.fleet.view); } export function isFreightAdmin(user: AuthUser | null | undefined): boolean { return hasPermission(user, FREIGHT_PERMS.admin); } export function ruleEngineViewKey(slug: RuleEngineResourceSlug): string { return `edr_freight_app:rule_engine:${slugToResourceKey(slug)}:view`; } export function ruleEngineManageKey(slug: RuleEngineResourceSlug): string { return `edr_freight_app:rule_engine:${slugToResourceKey(slug)}:manage`; } export function canAccessRuleEngineResource( user: AuthUser | null | undefined, slug: RuleEngineResourceSlug, mode: "view" | "manage", ): boolean { const key = mode === "manage" ? ruleEngineManageKey(slug) : ruleEngineViewKey(slug); return hasPermission(user, key); } export function canAccessAnyRuleEngineView( user: AuthUser | null | undefined, slugs: RuleEngineResourceSlug[], ): boolean { return slugs.some((slug) => canAccessRuleEngineResource(user, slug, "view")); }