export const FEATURES = [ { key: "stats", label: "My Stats", description: "View personal viewing history, reports and request report emails." }, { key: "requests", label: "My Requests", description: "View existing requests, their progress and request actions." }, { key: "new_requests", label: "New Requests", description: "Search for movies and TV shows and submit new requests.", }, { key: "issues", label: "Issues", description: "Report problems, follow up on issues and use available repair tools.", }, { key: "invites", label: "Invites", description: "Create and manage invitations within the existing invite limits." }, { key: "ignore_profile_limits", label: "Ignore profile limits", description: "Allow explicit manual downloads outside quality, size, language or custom-format limits. Automatic searches keep the assigned profile.", }, ] as const; export type Feature = (typeof FEATURES)[number]["key"]; export type FeatureAccess = Record; export function featureForPath(path: string): Feature | undefined { if (path === "/insights" || path.startsWith("/insights/")) return "stats"; if (path === "/" || path.startsWith("/requests/")) return "requests"; if (path === "/new-requests") return "new_requests"; if (path.startsWith("/issues/confirm/") || path.startsWith("/portal/issues")) return "issues"; if (path.startsWith("/profile/invites")) return "invites"; if (path === "/portal/requests") return "requests"; } export function canAccess( user: { role?: string; features?: Partial; invite_management_enabled?: boolean } | null, feature?: Feature, ) { if (!feature) return true; if (!user) return false; if (user.role === "admin") return true; return ( user.features?.[feature] ?? (feature === "invites" ? Boolean(user.invite_management_enabled) : feature !== "ignore_profile_limits") ); }