import type { UserAccess } from "./auth-policy"; /** * What each access level may reach inside the Plant Clock app (/clock and /api/clock). * * full everything in the main app, and Employees / Fuel / Job cards in the clock app (not Slips) * clock clock-in user: Employees, Fuel, Job cards * mechanic Fuel and Job cards only — no clock in/out * office Slips only (photo of a cash-card slip) — and ONLY office sees Slips * * Pure and dependency-free so the proxy, the bottom nav and the tests share one rule. */ export type ClockTab = { href: string; label: string }; export const CLOCK_TABS: Record = { full: [{ href: "/clock", label: "Employees" }, { href: "/clock/stock", label: "Fuel" }, { href: "/clock/job-cards", label: "Job cards" }], clock: [{ href: "/clock", label: "Employees" }, { href: "/clock/stock", label: "Fuel" }, { href: "/clock/job-cards", label: "Job cards" }], mechanic: [{ href: "/clock/stock", label: "Fuel" }, { href: "/clock/job-cards", label: "Job cards" }], office: [{ href: "/clock/slips", label: "Slips" }], }; /** Where a user lands when they open the clock app. */ export const clockHome = (access: UserAccess): string => (access === "mechanic" ? "/clock/job-cards" : access === "office" ? "/clock/slips" : "/clock"); const under = (path: string, base: string) => path === base || path.startsWith(`${base}/`); // Pages and APIs a restricted role may use, besides the sign-in / password screens. const ALLOWED: Partial> = { mechanic: ["/clock/stock", "/clock/job-cards", "/api/clock/stock-out", "/api/clock/oil-out", "/api/clock/job-start", "/api/clock/job-finish"], office: ["/clock/slips", "/api/clock/slip", "/api/clock/cash-float"], }; // The slip scanner belongs to the Office role alone. (The cash-float opening-balance call is also // open to full users, because the main Cash Floats page makes it.) const SLIPS = ["/clock/slips", "/api/clock/slip"]; const ALWAYS = ["/clock/login", "/clock/change-password"]; export function clockPathAllowed(access: UserAccess, path: string): boolean { if (ALWAYS.some((p) => under(path, p))) return true; if (access === "full") return !SLIPS.some((p) => under(path, p)); if (access === "clock") return ![...SLIPS, "/api/clock/cash-float"].some((p) => under(path, p)); return (ALLOWED[access] ?? []).some((p) => under(path, p)); }