/** Agency portfolio helpers — providers, role gates, service-role REST. */ export const INTEGRATION_PROVIDERS = [ { id: 'meta_ads', label: 'Meta Ads', group: 'paid', live: true }, { id: 'google_ads', label: 'Google Ads (MCC)', group: 'paid', live: true }, { id: 'ga4', label: 'Google Analytics 4', group: 'analytics', live: true }, { id: 'search_console', label: 'Search Console', group: 'analytics', live: true }, { id: 'tag_manager', label: 'Tag Manager', group: 'analytics', live: false }, { id: 'clientify', label: 'Clientify', group: 'crm', live: true }, { id: 'gohighlevel', label: 'GoHighLevel', group: 'crm', live: true }, { id: 'klaviyo', label: 'Klaviyo', group: 'email', live: false }, { id: 'mailchimp', label: 'Mailchimp', group: 'email', live: false }, { id: 'google_drive', label: 'Google Drive', group: 'files', live: true }, { id: 'wordpress', label: 'WordPress', group: 'cms', live: false }, { id: 'prestashop', label: 'PrestaShop', group: 'cms', live: false }, { id: 'shopify', label: 'Shopify', group: 'cms', live: true }, { id: 'woocommerce', label: 'WooCommerce', group: 'cms', live: true }, { id: 'instagram', label: 'Instagram', group: 'social', live: true }, { id: 'facebook', label: 'Facebook Page', group: 'social', live: true }, { id: 'tiktok', label: 'TikTok', group: 'social', live: false }, { id: 'linkedin', label: 'LinkedIn', group: 'social', live: false }, { id: 'superhuman_docs', label: 'Superhuman Docs', group: 'ops', live: true }, ] as const; export type IntegrationProviderId = (typeof INTEGRATION_PROVIDERS)[number]['id']; export type IntegrationStatus = | 'disconnected' | 'pending' | 'connected' | 'error'; export function isAgencyRole(role: string | undefined | null): boolean { return role === 'admin' || role === 'team'; } /** * Authorization role. Privileged roles (admin/team) ONLY from app_metadata * so clients cannot self-elevate via user_metadata.updateUser. */ export function userRole(user: { app_metadata?: Record; user_metadata?: Record; } | null): string { const app = (user?.app_metadata?.role as string | undefined)?.trim(); if (app === 'admin' || app === 'team' || app === 'client') return app; // Legacy clients may only have user_metadata.role=client — never admin/team. const um = (user?.user_metadata?.role as string | undefined)?.trim(); if (um === 'client') return 'client'; return 'client'; } export function homeTenantId(user: { app_metadata?: Record; user_metadata?: Record; } | null): string | null { const app = (user?.app_metadata?.tenant_id as string | undefined)?.trim(); if (app) return app; // Legacy client JWT may still carry tenant only in user_metadata. const um = (user?.user_metadata?.tenant_id as string | undefined)?.trim(); return um || null; } export function serviceHeaders(): | { apikey: string; Authorization: string } | null { const key = process.env.SUPABASE_SERVICE_ROLE_KEY?.trim(); if (!key) return null; return { apikey: key, Authorization: `Bearer ${key}` }; } export function supabaseUrl(): string { return ( process.env.NEXT_PUBLIC_SUPABASE_URL?.trim() || 'https://supabase.4ventures.es' ); } export const VIEW_TENANT_COOKIE = '4v_view_tenant_id'; export const VIEW_TENANT_SLUG_COOKIE = '4v_view_tenant_slug'; export const VIEW_TENANT_NAME_COOKIE = '4v_view_tenant_name';