@fayz-ai/admin 0.49.0 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ScheduleEditor-6YFOBHAE.js +6 -0
- package/dist/{ScheduleEditor-BXWJ7CMI.js.map → ScheduleEditor-6YFOBHAE.js.map} +1 -1
- package/dist/SubscriptionPage-DI6UV5LF.js +8 -0
- package/dist/{SubscriptionPage-VBDDRSVW.js.map → SubscriptionPage-DI6UV5LF.js.map} +1 -1
- package/dist/app/admin-app.d.ts.map +1 -1
- package/dist/app/config.d.ts +6 -0
- package/dist/app/config.d.ts.map +1 -1
- package/dist/billing/index.js +3 -3
- package/dist/{chunk-2Q6QHTZV.js → chunk-3S7UULIC.js} +4 -4
- package/dist/{chunk-2Q6QHTZV.js.map → chunk-3S7UULIC.js.map} +1 -1
- package/dist/{chunk-KVIINVY6.js → chunk-4RKG7YH5.js} +3 -3
- package/dist/{chunk-KVIINVY6.js.map → chunk-4RKG7YH5.js.map} +1 -1
- package/dist/{chunk-OEY3V6J3.js → chunk-DASJ4UF3.js} +3 -3
- package/dist/{chunk-OEY3V6J3.js.map → chunk-DASJ4UF3.js.map} +1 -1
- package/dist/{chunk-ZMP52ZHM.js → chunk-EOYE3ZAC.js} +3 -3
- package/dist/{chunk-ZMP52ZHM.js.map → chunk-EOYE3ZAC.js.map} +1 -1
- package/dist/{chunk-F346TYKO.js → chunk-TAN7UGC2.js} +5 -5
- package/dist/{chunk-F346TYKO.js.map → chunk-TAN7UGC2.js.map} +1 -1
- package/dist/{chunk-GZWX4ZIK.js → chunk-XQM74EP4.js} +37 -3
- package/dist/chunk-XQM74EP4.js.map +1 -0
- package/dist/data/client.d.ts +19 -0
- package/dist/data/client.d.ts.map +1 -1
- package/dist/index.js +14 -13
- package/dist/index.js.map +1 -1
- package/dist/org/index.js +2 -2
- package/package.json +7 -7
- package/dist/ScheduleEditor-BXWJ7CMI.js +0 -6
- package/dist/SubscriptionPage-VBDDRSVW.js +0 -8
- package/dist/chunk-GZWX4ZIK.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/org/team-rows.ts","../src/directory/app-id.ts","../src/org/adapters/supabase.ts","../src/org/adapters/mock.ts","../src/org/choice.ts","../src/stores/app-config.store.ts","../src/org/OrgMark.tsx","../src/units/data.ts","../src/units/cache.ts","../src/units/device.ts","../src/lib/dedup.ts","../src/units/entry.ts","../src/units/store.ts","../src/units/useHouseCurrencySync.ts","../src/org/cache.ts","../src/org/context.tsx","../src/org/workspace-search.ts","../src/org/WorkspaceChooser.tsx","../src/app/useDomainTenant.ts","../src/org/WorkspaceChooserGate.tsx","../src/org/switching.store.ts","../src/org/WorkspaceSwitching.tsx","../src/org/WorkspaceSwitchingHost.tsx"],"names":["capitalize","slugify","React","getSupabaseClientOptional","STORAGE_KEY","dedup","create","React2","client","VERSION","MAX_AGE_MS","MAX_BYTES","storage","cached","jsx","React4","jsxs","cn","useState","useEffect","React5","useTranslation","React6","Check"],"mappings":"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","file":"chunk-ZMP52ZHM.js","sourcesContent":["import type { TeamPerson } from '@fayz-ai/core'\n\n/** A `people` row as the team query selects it. */\nexport interface TeamPeopleRow {\n id: string\n name?: string | null\n kind?: string | null\n email?: string | null\n avatar_url?: string | null\n is_active?: boolean | null\n}\n\n/** A `tenant_members` row as the team query selects it. */\nexport interface TeamMemberRow {\n id: string\n user_id: string\n role?: string | null\n person_id?: string | null\n created_at?: string | null\n}\n\n/** A `profiles` row for a member's login. */\nexport interface TeamProfileRow {\n id: string\n full_name?: string | null\n email?: string | null\n avatar_url?: string | null\n}\n\n/** The signed-in user, used to name their own row when `profiles` has no row for them. */\nexport interface TeamCurrentUser {\n id: string\n email?: string | null\n fullName?: string | null\n}\n\nconst capitalize = (s: string) => (s ? s.charAt(0).toUpperCase() + s.slice(1) : s)\n\n/**\n * Fallback display name for a login with no person record. `profiles` is not\n * guaranteed to have a row (accounts created before the trigger, seeded demos),\n * and its RLS only ever exposes your own — so the session is the last resort for\n * your own row, and the email handle the one after that.\n */\nfunction loginName(profile: TeamProfileRow | undefined, session: TeamCurrentUser | undefined): string {\n const candidates = [profile?.full_name, session?.fullName, profile?.email, session?.email]\n for (const candidate of candidates) {\n const value = candidate?.trim()\n if (value) return value.includes('@') ? value.split('@')[0] : value\n }\n return ''\n}\n\n/**\n * Merges the two halves of the team into one list.\n *\n * People of the configured kinds are the roster; `tenant_members` is the access\n * overlay linked by `person_id`. But a login is not required to have a person\n * record — the owner who created the workspace never gets one — and dropping\n * those rows left the Team screen empty for every account that had not staffed\n * itself as a person. So memberships that match no listed person come back as\n * rows of their own, named from their login profile and carrying no `personId`.\n * Logins come first: whoever holds access is the answer to \"who is my team?\"\n * before the roster of people who may never sign in.\n */\nexport function buildTeamRows(\n people: TeamPeopleRow[],\n members: TeamMemberRow[],\n profiles: TeamProfileRow[],\n currentUser?: TeamCurrentUser | null,\n): TeamPerson[] {\n const personIds = new Set(people.map((p) => p.id))\n const byPerson = new Map<string, TeamMemberRow>()\n const unlinked: TeamMemberRow[] = []\n\n for (const m of members) {\n if (m.person_id && personIds.has(m.person_id)) byPerson.set(m.person_id, m)\n else unlinked.push(m)\n }\n\n const profileById = new Map(profiles.map((p) => [p.id, p]))\n\n const toMembership = (m: TeamMemberRow) => ({\n memberId: m.id,\n userId: m.user_id,\n profileId: (m.role as string) ?? '',\n profileName: capitalize((m.role as string) ?? ''),\n joinedAt: m.created_at ?? undefined,\n })\n\n const loginRows: TeamPerson[] = unlinked.map((m) => {\n const profile = profileById.get(m.user_id)\n const session = currentUser && currentUser.id === m.user_id ? currentUser : undefined\n return {\n name: loginName(profile, session),\n email: profile?.email ?? session?.email ?? undefined,\n avatarUrl: profile?.avatar_url ?? undefined,\n isActive: true,\n membership: toMembership(m),\n }\n })\n\n const personRows: TeamPerson[] = people.map((p) => {\n const m = byPerson.get(p.id)\n return {\n personId: p.id,\n name: p.name ?? '',\n kind: p.kind ?? undefined,\n email: p.email ?? undefined,\n avatarUrl: p.avatar_url ?? undefined,\n isActive: p.is_active ?? true,\n membership: m ? toMembership(m) : undefined,\n }\n })\n\n return [...loginRows, ...personRows]\n}\n","/**\n * Which application THIS bundle is.\n *\n * The switcher needs it for one thing only: to know which tile is the one you\n * are already looking at. Everything else about an app — its name, icon, colour\n * and URL — comes from the `app.apps` registry, so a rename is a row and not a\n * release.\n *\n * Until now the only identity an app carried was `VITE_FAYZ_PROJECT_ID`, a\n * platform project uuid. That is a poor answer to \"which product is this\": the\n * ids for the shop already disagree between the app's own `.env` and the\n * platform's seed script, and nothing would have caught it, because a uuid does\n * not look wrong. `VITE_APP_ID` is the registry key instead — it matches\n * `app.apps.id`, and a typo shows up as \"nothing is highlighted\" on the first\n * run rather than as a wrong tile months later.\n *\n * Unset is a legitimate answer: the switcher lists every app the account runs\n * and highlights none, which is right for a bundle nobody has claimed yet.\n */\nexport function resolveAppId(): string | null {\n const env = (import.meta as unknown as { env?: Record<string, string | undefined> }).env\n const id = env?.VITE_APP_ID ?? env?.PUBLIC_APP_ID\n const trimmed = id?.trim()\n return trimmed ? trimmed : null\n}\n","import type {\n OrgAdapter,\n Organization,\n OrgMember,\n OrgMembership,\n TeamPerson,\n CreateOrgOptions,\n Location,\n Invite,\n} from '@fayz-ai/core'\nimport type { PermissionProfile, SystemPermission, AuthAdapter } from '@fayz-ai/core'\nimport { getFayzSupabaseClient } from '../../data/client'\nimport { buildTeamRows } from '../team-rows'\nimport { resolveAppId } from '../../directory/app-id'\nimport type { TeamMemberRow, TeamPeopleRow, TeamProfileRow } from '../team-rows'\n\n// ---------------------------------------------------------------------------\n// Request dedup — prevents duplicate in-flight requests (React StrictMode etc.)\n// ---------------------------------------------------------------------------\n\nconst inflightRequests = new Map<string, Promise<unknown>>()\n\nfunction dedup<T>(key: string, fn: () => Promise<T>): Promise<T> {\n const existing = inflightRequests.get(key)\n if (existing) return existing as Promise<T>\n\n const promise = fn().finally(() => {\n inflightRequests.delete(key)\n })\n inflightRequests.set(key, promise)\n return promise\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction slugify(name: string): string {\n return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')\n}\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1)\n}\n\nfunction mapTenantToOrg(row: Record<string, unknown>): Organization {\n return {\n id: row['id'] as string,\n name: row['name'] as string,\n slug: row['slug'] as string,\n logoUrl: (row['logo_url'] as string | null) ?? undefined,\n verticalId: (row['vertical_id'] as string | null) ?? undefined,\n plan: (row['plan'] as string | null) ?? undefined,\n trialEndsAt: (row['trial_ends_at'] as string | null) ?? undefined,\n settings: (row['settings'] as Record<string, unknown> | null) ?? undefined,\n createdAt: row['created_at'] as string,\n updatedAt: row['updated_at'] as string,\n }\n}\n\n/**\n * Como um login ganha nome.\n *\n * Era só `public.profiles` — e num pool onde essa tabela está VAZIA (nenhum\n * gatilho a preencheu) a tela de Equipe inteira aparecia sem nome nenhum: seis\n * linhas com \"?\" no avatar e a coluna do membro em branco. Quem é a pessoa por\n * trás de um acesso é a pergunta que essa tela existe para responder.\n *\n * A ficha ligada à associação (`person_id`, sempre preenchida desde a #120)\n * responde melhor e é dado da própria conta: nome e e-mail que a equipe\n * mantém, não uma cópia do provedor de identidade. `profiles` fica como\n * complemento — é de lá que vem o avatar.\n */\nasync function namesForLogins(\n rows: Array<Record<string, unknown>>,\n db: { from: (table: string) => any },\n): Promise<Map<string, Record<string, unknown>>> {\n const out = new Map<string, Record<string, unknown>>()\n if (rows.length === 0) return out\n\n const userIds = rows.map((r) => r['user_id'] as string).filter(Boolean)\n const personIds = rows.map((r) => r['person_id'] as string | null).filter(Boolean) as string[]\n\n const [profilesResult, peopleResult] = await Promise.all([\n userIds.length ? db.from('profiles').select('id, full_name, avatar_url, email').in('id', userIds) : Promise.resolve({ data: [] }),\n personIds.length ? db.from('people').select('id, name, email, avatar_url, kind').in('id', personIds) : Promise.resolve({ data: [] }),\n ])\n\n const byProfile = new Map(\n ((profilesResult?.data ?? []) as Array<Record<string, unknown>>).map((p) => [p['id'] as string, p]),\n )\n const byPerson = new Map(\n ((peopleResult?.data ?? []) as Array<Record<string, unknown>>).map((p) => [p['id'] as string, p]),\n )\n\n for (const row of rows) {\n const userId = row['user_id'] as string\n const profile = byProfile.get(userId)\n const person = byPerson.get(row['person_id'] as string)\n out.set(userId, {\n id: userId,\n full_name: person?.['name'] ?? profile?.['full_name'] ?? '',\n email: person?.['email'] ?? profile?.['email'] ?? '',\n avatar_url: profile?.['avatar_url'] ?? person?.['avatar_url'] ?? null,\n // Viaja junto para a tela poder RESOLVER a rota da ficha: o registro de\n // rotas é indexado por `arquétipo:kind`, e sem o kind o \"abrir a ficha\"\n // não sabe para onde ir.\n kind: person?.['kind'] ?? null,\n })\n }\n return out\n}\n\nfunction mapMemberRow(row: Record<string, unknown>): OrgMember {\n const profile = (row['profile'] as Record<string, unknown>) ?? {}\n return {\n id: row['id'] as string,\n userId: row['user_id'] as string,\n orgId: row['tenant_id'] as string,\n profileId: row['role'] as string,\n profileName: capitalize(row['role'] as string),\n personId: (row['person_id'] as string | null) ?? undefined,\n personKind: (profile['kind'] as string | null) ?? undefined,\n user: {\n id: row['user_id'] as string,\n email: (profile['email'] as string) ?? '',\n fullName: (profile['full_name'] as string) ?? '',\n avatarUrl: (profile['avatar_url'] as string | null) ?? undefined,\n },\n // tenant_members has no `joined_at` column — it's `created_at`.\n joinedAt: (row['joined_at'] ?? row['created_at']) as string,\n }\n}\n\nfunction mapLocationRow(row: Record<string, unknown>): Location {\n return {\n id: row['id'] as string,\n tenantId: row['tenant_id'] as string,\n name: row['name'] as string,\n address: (row['address'] as string | null) ?? undefined,\n city: (row['city'] as string | null) ?? undefined,\n state: (row['state'] as string | null) ?? undefined,\n country: (row['country'] as string | null) ?? undefined,\n phone: (row['phone'] as string | null) ?? undefined,\n isHeadquarters: (row['is_headquarters'] as boolean) ?? false,\n isActive: (row['is_active'] as boolean) ?? true,\n createdAt: row['created_at'] as string,\n updatedAt: row['updated_at'] as string,\n }\n}\n\nfunction mapInviteRow(row: Record<string, unknown>): Invite {\n return {\n id: row['id'] as string,\n orgId: row['tenant_id'] as string,\n email: row['email'] as string,\n profileId: row['role'] as string,\n profileName: capitalize(row['role'] as string),\n invitedBy: row['invited_by'] as string,\n token: row['token'] as string,\n status: (row['status'] as Invite['status']) ?? 'pending',\n createdAt: row['created_at'] as string,\n expiresAt: row['expires_at'] as string,\n }\n}\n\n/** Minimal role identity the adapter needs to build profiles. Grants come from\n * the DB catalog; id/name/order/description come from what the app declares. */\nexport interface RoleIdentity {\n id: string\n name: string\n description?: string\n /** System roles are app-defined and static (not user-editable). Custom roles\n * (duplicated by users, stored in app.roles) are false. Defaults true. */\n isSystem?: boolean\n /** The app's declared grants; used to create the role in a tenant that lacks it. */\n grants?: Record<string, string[]>\n}\n\n// Matrix emits read/create/edit/delete; map back to DB action verbs. The\n// catalog spells the write verb `edit` — `update` matched no key, so any\n// matrix save with an edit box ticked was refused as an unknown permission.\nconst DB_ACTION: Record<string, string> = {\n read: 'read', create: 'create', edit: 'edit', write: 'create', manage: 'manage', delete: 'delete',\n}\n\n// Every working role needs these to load the tenant at all.\nconst SESSION_BASELINE = ['config.read', 'tenancy.read', 'tenant.read', 'units.read']\n\n// Matrix grants → catalog keys. Alias features go back to their canonical\n// domain, and features the catalog does not know are dropped: they gate\n// nothing server-side, and one unknown key makes role_set_permissions refuse\n// the whole set.\nexport function grantsToDbKeys(grants: Record<string, string[]>, catalog: Set<string>): string[] {\n const canonicalOf = new Map<string, string>()\n for (const [canonical, aliases] of Object.entries(FEATURE_ALIASES)) {\n for (const alias of aliases) canonicalOf.set(alias, canonical)\n }\n const keys = new Set<string>()\n for (const [feature, actions] of Object.entries(grants)) {\n for (const action of actions) {\n const verb = DB_ACTION[action] ?? action\n const direct = `${feature}.${verb}`\n const viaAlias = canonicalOf.has(feature) ? `${canonicalOf.get(feature)}.${verb}` : undefined\n if (catalog.has(direct)) keys.add(direct)\n else if (viaAlias && catalog.has(viaAlias)) keys.add(viaAlias)\n }\n }\n return [...keys]\n}\n\nfunction slugifyRole(name: string): string {\n return name.toLowerCase().normalize('NFD').replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') || 'role'\n}\n\n// Fallback role set when the host app declares none. The SDK is domain-agnostic:\n// each app defines its OWN business roles (a salon's roles ≠ an agency's) via\n// config.permissions.defaultProfiles. These five are only a back-compat default.\nconst DEFAULT_ROLES: RoleIdentity[] = [\n { id: 'owner', name: 'Owner' },\n { id: 'admin', name: 'Admin' },\n { id: 'manager', name: 'Manager' },\n { id: 'staff', name: 'Staff' },\n { id: 'viewer', name: 'Viewer' },\n]\n\n// DB permission ids that confer an org-management system permission.\n// The catalog names these `members.*` / `roles.*` / `settings.manage`; the\n// `team.*` / `settings.update` spellings never existed in it, which left the\n// Team and Permissions tabs owner-only even for Admin.\nconst SYSTEM_PERMISSION_MAP: Record<string, SystemPermission> = {\n 'members.manage': 'manage_team',\n 'roles.manage': 'manage_permissions',\n 'billing.manage': 'manage_billing',\n 'settings.manage': 'manage_settings',\n}\nconst ALL_SYSTEM_PERMISSIONS: SystemPermission[] = ['manage_team', 'manage_billing', 'manage_settings', 'manage_permissions']\n\n// The database names shared business domains; older UI surfaces still use\n// product-facing feature ids. Keep both until every plugin speaks the canonical\n// vocabulary so a valid database grant cannot hide an otherwise available page.\nconst FEATURE_ALIASES: Record<string, string[]> = {\n people: ['registry.customers', 'registry.suppliers'],\n catalog: ['services'],\n}\n\n// Map DB permission ids to feature action grants\nexport function buildPermissionProfiles(\n roles: RoleIdentity[],\n permissions: Array<{ id: string; category: string }>,\n rolePerms: Array<{ role: string; permission_id: string }>,\n overrides: Array<{ role: string; permission_id: string; granted: boolean }>,\n): PermissionProfile[] {\n const overrideMap = new Map<string, boolean>()\n for (const o of overrides) {\n overrideMap.set(`${o.role}:${o.permission_id}`, o.granted)\n }\n\n // The role SET comes from what the app declares — the SDK no longer bakes it in.\n const rolePermMap = new Map<string, Set<string>>()\n for (const r of roles) {\n rolePermMap.set(r.id, new Set())\n }\n // Convention: an 'owner' role (if declared) gets every permission implicitly.\n if (rolePermMap.has('owner')) {\n for (const p of permissions) rolePermMap.get('owner')!.add(p.id)\n }\n for (const rp of rolePerms) {\n rolePermMap.get(rp.role)?.add(rp.permission_id)\n }\n\n // Apply overrides\n for (const [key, granted] of overrideMap) {\n const colonIdx = key.indexOf(':')\n const role = key.slice(0, colonIdx)\n const permId = key.slice(colonIdx + 1)\n const perms = rolePermMap.get(role)\n if (!perms) continue\n if (granted) {\n perms.add(permId)\n } else {\n perms.delete(permId)\n }\n }\n\n // Align DB actions with the matrix's action vocabulary (read/create/edit/delete).\n //\n // `manage` IS KEPT, not folded into `edit`. profileHasPermission answers\n // `actions.includes(action) || actions.includes('manage')` — manage is the\n // wildcard that implies the rest. Collapsing it here destroyed that meaning\n // BEFORE the engine ever saw it: a role granted `financial.manage` stored\n // `['edit']`, which contains neither `read` nor `manage`, so the Financeiro\n // role could not open the Financeiro module — the nav gates on `read`. Same\n // for every other `X.manage` grant in the catalog.\n const actionMap: Record<string, string> = {\n read: 'read',\n create: 'create',\n update: 'edit',\n manage: 'manage',\n delete: 'delete',\n configure: 'edit',\n invite: 'create',\n }\n\n return roles.map(({ id: role, name, description, isSystem }) => {\n const permIds = rolePermMap.get(role)!\n const features: Record<string, string[]> = {}\n\n for (const permId of permIds) {\n // LAST dot, not the first: a feature id may contain dots (plugin-crm\n // declares `crm.leads`), an action never does. Splitting on the first one\n // read `crm.leads.read` as feature `crm` + action `leads.read`, which no\n // action map knows — so every dotted feature the matrix granted came back\n // empty on the next load, silently.\n const dotIdx = permId.lastIndexOf('.')\n if (dotIdx <= 0) continue\n const category = permId.slice(0, dotIdx)\n const action = permId.slice(dotIdx + 1)\n // A verb outside the CRUD map is a special action (`workforce.adjust_time`,\n // `financial.amend`): kept under its own name so a matrix save sends it\n // back instead of silently revoking it.\n const mappedAction = actionMap[action] ?? action\n\n for (const feature of [category, ...(FEATURE_ALIASES[category] ?? [])]) {\n if (!features[feature]) features[feature] = []\n if (!features[feature].includes(mappedAction)) {\n features[feature].push(mappedAction)\n }\n }\n }\n\n // Org-management system permissions, derived from team/billing/settings\n // grants (owner gets all four). These gate the Equipe/Permissões tabs.\n const systemPermissions: SystemPermission[] = []\n const source = role === 'owner' ? ALL_SYSTEM_PERMISSIONS : [...permIds].map((id) => SYSTEM_PERMISSION_MAP[id])\n for (const sp of source) {\n if (sp && !systemPermissions.includes(sp)) systemPermissions.push(sp)\n }\n\n return {\n id: role,\n name: name || capitalize(role),\n description,\n isSystem: isSystem ?? true,\n systemPermissions,\n grants: features,\n }\n })\n}\n\n// ---------------------------------------------------------------------------\n// Adapter factory\n// ---------------------------------------------------------------------------\n\nexport interface SupabaseOrgAdapterConfig {\n /** Deprecated — core tables now live in the public schema; this field is ignored. */\n coreSchema?: string\n /** Business roles the host app declares (config.permissions.defaultProfiles).\n * Falls back to the generic five when omitted. */\n roles?: RoleIdentity[]\n /** Auth adapter used to actually DELIVER invites (send the e-mail + create the\n * auth user) — the org adapter only records the audit row. Injected by the app;\n * when omitted, invites are recorded but not delivered. */\n authAdapter?: AuthAdapter\n /** Canonical, deployment-fixed origin baked into invite/magic-link redirects\n * (e.g. https://beauty-saas.live.fayz.ai). The container injects it as\n * VITE_APP_URL; the app wiring passes it here. Falls back to\n * window.location.origin, which is wrong when an admin invites from a preview\n * or localhost origin. Note: whatever origin ends up here must ALSO be in the\n * Supabase project's Redirect URLs allow-list, or Supabase silently swaps it\n * for its Site URL (default http://localhost:3000). */\n siteUrl?: string\n}\n\nexport function createSupabaseOrgAdapter(config?: SupabaseOrgAdapterConfig): OrgAdapter {\n const roles: RoleIdentity[] = config?.roles && config.roles.length > 0 ? config.roles : DEFAULT_ROLES\n const authAdapter = config?.authAdapter\n const originBase =\n config?.siteUrl?.replace(/\\/+$/, '') ??\n (typeof window !== 'undefined' ? window.location.origin : undefined)\n const inviteRedirectTo = originBase ? `${originBase}/` : undefined\n\n function supabase() {\n return getFayzSupabaseClient()\n }\n\n function core() {\n return supabase()\n }\n\n async function catalogKeys(): Promise<Set<string>> {\n const { data, error } = await core().from('v_authz_permissions').select('key')\n if (error) throw error\n return new Set(((data ?? []) as Array<{ key: string }>).map((p) => p.key))\n }\n\n // The picker offers every role the APP declares, but app.roles is per tenant\n // and only holds what its seed template wrote. Inviting into or editing a\n // declared role the tenant never got failed with \"unknown role key\"; create\n // it from the app's declared grants the first time it is used.\n async function ensureRole(orgId: string, key: string): Promise<string> {\n const found = await core()\n .from('v_authz_roles').select('id')\n .eq('tenant_id', orgId).eq('key', key).maybeSingle()\n if (found.error) throw found.error\n if (found.data) return (found.data as { id: string }).id\n\n const declared = roles.find((r) => r.id === key)\n if (!declared) throw new Error(`Profile not found: ${key}`)\n\n const existing = await core().from('v_authz_roles').select('key, is_system').eq('tenant_id', orgId)\n if (existing.error) throw existing.error\n const rows = (existing.data ?? []) as Array<{ key: string; is_system: boolean }>\n const seed = rows.find((r) => r.key === 'viewer')?.key ?? rows.find((r) => r.is_system && r.key !== 'owner')?.key\n if (!seed) throw new Error('ensureRole: the tenant has no role to clone from')\n\n const created = await core().rpc('role_create_from_template', {\n p_role_key: key,\n p_name: declared.name,\n p_template_role: seed,\n p_template: null,\n p_description: declared.description ?? null,\n })\n if (created.error) throw created.error\n const roleId = created.data as string\n\n const catalog = await catalogKeys()\n const keys = [\n ...SESSION_BASELINE.filter((k) => catalog.has(k)),\n ...grantsToDbKeys(declared.grants ?? {}, catalog),\n ]\n const set = await core().rpc('role_set_permissions', { p_role_id: roleId, p_keys: [...new Set(keys)] })\n if (set.error) throw set.error\n return roleId\n }\n\n return {\n async acceptPendingInvites(): Promise<number> {\n const { data, error } = await supabase().rpc('accept_pending_invitations')\n if (error) {\n // A pool still on the pre-022 spine has no such function. Not fatal —\n // the user just lands org-less, exactly as before this shipped.\n console.warn('[org] accept_pending_invitations failed:', error.message)\n return 0\n }\n return typeof data === 'number' ? data : 0\n },\n\n async listUserOrgs(userId: string): Promise<OrgMembership[]> {\n return dedup(`listUserOrgs:${userId}`, async () => {\n const { data, error } = await core()\n .from('v_team_members')\n .select('tenant_id, role, tenant:tenants(id, name, slug, logo_url)')\n .eq('user_id', userId)\n\n if (error) throw error\n\n let rows = (data ?? []) as Array<Record<string, unknown>>\n\n // Narrow to the accounts that run THIS app (008). A beauty account\n // listed inside the restaurant product is not a shortcut — it opens a\n // rail whose screens its data cannot fill. The app you are looking at\n // is the bundle's own fact (VITE_APP_ID); the database cannot infer it,\n // because one account may run several apps at once.\n //\n // Best-effort on purpose: no app id, no view (a pool predating 008), or\n // any error at all leaves the list exactly as it was. Hiding an account\n // because a filter failed is worse than showing one too many.\n const appId = resolveAppId()\n if (appId && rows.length > 1) {\n const { data: scoped, error: scopeError } = await core()\n .from('v_tenant_apps')\n .select('tenant_id')\n .eq('app_id', appId)\n if (!scopeError && Array.isArray(scoped)) {\n const runsThisApp = new Set(scoped.map((r) => (r as { tenant_id: string }).tenant_id))\n const kept = rows.filter((row) => runsThisApp.has(row['tenant_id'] as string))\n // An empty result would leave the person with no workspace at all\n // and no way to say so; the unfiltered list is the safer answer.\n if (kept.length > 0) rows = kept\n }\n }\n\n // Every field here is nullable in practice and none of them is worth\n // the whole list. A pool on the pre-014 spine answers this query with\n // `tenant` and `role` NULL — the workspace picker has to read across\n // accounts, and until 014 the policies on public.tenants and app.roles\n // were scoped to the account you had not chosen yet. `capitalize(null)`\n // threw, took listUserOrgs with it, and left a seven-workspace account\n // looking at \"you belong to none\". A missing name is a bad row; it is\n // not a reason to lose the six good ones next to it.\n return rows.map((row) => {\n const tenant = (row['tenant'] as Record<string, unknown> | null) ?? {}\n const role = (row['role'] as string | null) ?? ''\n return {\n orgId: row['tenant_id'] as string,\n orgName: (tenant['name'] as string) ?? '',\n orgSlug: (tenant['slug'] as string) ?? '',\n orgLogoUrl: (tenant['logo_url'] as string | null) ?? undefined,\n profileId: role,\n profileName: capitalize(role),\n }\n })\n })\n },\n\n async getOrg(orgId: string): Promise<Organization> {\n const { data, error } = await core()\n .from('tenants')\n .select('*')\n .eq('id', orgId)\n .single()\n\n if (error) throw error\n return mapTenantToOrg(data as Record<string, unknown>)\n },\n\n async createOrg(name: string, userId: string, options?: CreateOrgOptions): Promise<Organization> {\n const { data: tenant, error } = await supabase()\n .rpc('create_tenant_with_owner', {\n p_name: name,\n p_slug: slugify(name),\n p_user_id: userId,\n p_vertical_id: options?.verticalId ?? null,\n p_plan: 'free',\n p_settings: {\n timezone: options?.timezone ?? 'America/Sao_Paulo',\n currency: options?.currency ?? 'BRL',\n locale: options?.locale ?? 'pt-BR',\n teamSize: options?.teamSize ?? undefined,\n branding: options?.branding ?? {},\n },\n })\n\n if (error) throw error\n return mapTenantToOrg(tenant as Record<string, unknown>)\n },\n\n async updateOrg(orgId: string, updates: Partial<Organization>): Promise<Organization> {\n const row: Record<string, unknown> = {}\n if (updates.name !== undefined) row['name'] = updates.name\n if (updates.slug !== undefined) row['slug'] = updates.slug\n if (updates.logoUrl !== undefined) row['logo_url'] = updates.logoUrl\n if (updates.verticalId !== undefined) row['vertical_id'] = updates.verticalId\n if (updates.plan !== undefined) row['plan'] = updates.plan\n if (updates.settings !== undefined) row['settings'] = updates.settings\n\n const { data, error } = await core()\n .from('tenants')\n .update(row)\n .eq('id', orgId)\n .select()\n .single()\n\n if (error) throw error\n return mapTenantToOrg(data as Record<string, unknown>)\n },\n\n async listMembers(orgId: string): Promise<OrgMember[]> {\n const { data, error } = await core()\n .from('v_team_members')\n .select('*')\n .eq('tenant_id', orgId)\n\n if (error) throw error\n\n const rows = (data ?? []) as Array<Record<string, unknown>>\n const profileMap = await namesForLogins(rows, core())\n\n return rows.map((row) => {\n const profile = profileMap.get(row['user_id'] as string) ?? {}\n return mapMemberRow({ ...row, profile })\n })\n },\n\n // Person-first team list: people of `personKinds` are the roster and\n // `tenant_members` (login + role) is the overlay linked by person_id — plus\n // every membership that links to no listed person, so an account with access\n // is never missing from its own Team screen. See buildTeamRows.\n async listTeam(orgId: string, personKinds: string[]): Promise<TeamPerson[]> {\n if (!personKinds || personKinds.length === 0) return []\n\n const [peopleResult, membersResult] = await Promise.all([\n core()\n .from('people')\n .select('id, name, kind, email, avatar_url, is_active')\n .eq('tenant_id', orgId)\n .in('kind', personKinds)\n // Only people still on the roster. `not is false` rather than\n // `eq true` so a row that never set the flag stays visible — the\n // same `?? true` reading buildTeamRows applies. A deactivated\n // person who still holds a login does not vanish: their membership\n // stops matching a listed person and comes back as a login row,\n // which is the invariant that keeps access auditable.\n .not('is_active', 'is', false),\n core()\n .from('v_team_members')\n .select('id, user_id, role, person_id, created_at')\n .eq('tenant_id', orgId),\n ])\n if (peopleResult.error) throw peopleResult.error\n\n const people = (peopleResult.data ?? []) as TeamPeopleRow[]\n const members = (membersResult.data ?? []) as TeamMemberRow[]\n\n // Login-only rows are named from the person their membership points at,\n // falling back to the auth profile (see namesForLogins — `profiles` is\n // empty in some pools, which left this whole screen nameless). The\n // session is the last fallback, and only for your own row.\n const [nameMap, sessionResult] = await Promise.all([\n namesForLogins(members as unknown as Array<Record<string, unknown>>, core()),\n core().auth.getSession(),\n ])\n\n const sessionUser = sessionResult?.data?.session?.user\n const currentUser = sessionUser\n ? {\n id: sessionUser.id,\n email: sessionUser.email,\n fullName: (sessionUser.user_metadata?.['full_name'] as string | undefined) ?? undefined,\n }\n : null\n\n return buildTeamRows(people, members, [...nameMap.values()] as unknown as TeamProfileRow[], currentUser)\n },\n\n // Verbs, not writes into the projection: v_team_members is a JOINed view\n // and accepts neither UPDATE nor DELETE, and each RPC checks the permission\n // in one place. `_orgId` stays in the signature for the adapter contract —\n // the RPCs take the tenant from the session, not from a parameter.\n async updateMemberProfile(orgId: string, memberId: string, profileId: string): Promise<void> {\n await ensureRole(orgId, profileId)\n // member_set_role refuses to demote the last owner. This screen cannot\n // know it was the last one, which is exactly why the check moved.\n const { error } = await core().rpc('member_set_role', { p_membership: memberId, p_role: profileId })\n if (error) throw error\n },\n\n async removeMember(_orgId: string, memberId: string): Promise<void> {\n const { error } = await core().rpc('member_remove', { p_membership: memberId })\n if (error) throw error\n },\n\n // #136 moved authorization into app.*, reachable through the v_authz_*\n // views (security_invoker, so RLS still decides what a caller sees) and a\n // small set of RPCs. The four public mirrors this used to read and write —\n // permissions, role_permissions, tenant_roles, tenant_role_overrides — are\n // dropped by @fayz-ai/db 003.\n //\n // The RPCs take the tenant from the SESSION, not a parameter, so orgId is\n // asserted against the active tenant rather than passed down: writing to\n // one org while another is active was never possible and should fail\n // loudly rather than silently touch the wrong one.\n async listProfiles(orgId: string): Promise<PermissionProfile[]> {\n const [permsResult, rolesResult, grantsResult] = await Promise.all([\n core().from('v_authz_permissions').select('key, plugin'),\n core().from('v_authz_roles').select('id, key, name, description, is_system').eq('tenant_id', orgId),\n core().from('v_authz_role_permissions').select('role_id, permission').eq('tenant_id', orgId),\n ])\n\n if (permsResult.error) throw permsResult.error\n if (rolesResult.error) throw rolesResult.error\n if (grantsResult.error) throw grantsResult.error\n\n const dbRoles = (rolesResult.data ?? []) as Array<{\n id: string; key: string; name: string; description: string | null; is_system: boolean\n }>\n const keyOf = new Map(dbRoles.map((r) => [r.id, r.key]))\n\n // The app still declares its own role SET; the database now supplies the\n // custom ones a tenant created. A system role the DB knows and the app\n // does not is still shown — it holds grants either way.\n const declared: RoleIdentity[] = roles.map((r) => ({ ...r, isSystem: true }))\n const declaredIds = new Set(declared.map((r) => r.id))\n const fromDb: RoleIdentity[] = dbRoles\n .filter((r) => !declaredIds.has(r.key))\n .map((r) => ({ id: r.key, name: r.name, description: r.description ?? undefined, isSystem: r.is_system }))\n\n // app.role_permissions is per TENANT, so every grant is that tenant's own.\n // The global defaults table this used to read was documented as always\n // empty and measured empty in every pool, so there is no third source to\n // merge — the grants go in as overrides and the base layer is bare.\n const overrides = ((grantsResult.data ?? []) as Array<{ role_id: string; permission: string }>)\n .flatMap((g) => {\n const role = keyOf.get(g.role_id)\n return role ? [{ role, permission_id: g.permission, granted: true }] : []\n })\n\n return buildPermissionProfiles(\n [...declared, ...fromDb],\n ((permsResult.data ?? []) as Array<{ key: string; plugin: string }>)\n .map((p) => ({ id: p.key, category: p.plugin })),\n [],\n overrides,\n )\n },\n\n async createProfile(\n orgId: string,\n profile: Omit<PermissionProfile, 'id' | 'isSystem'>,\n ): Promise<PermissionProfile> {\n const existingRoles = await core().from('v_authz_roles').select('key, is_system').eq('tenant_id', orgId)\n if (existingRoles.error) throw existingRoles.error\n const rows = (existingRoles.data ?? []) as Array<{ key: string; is_system: boolean }>\n const existing = new Set(rows.map((r) => r.key))\n\n let key = slugifyRole(profile.name)\n if (existing.has(key) || roles.some((r) => r.id === key)) {\n let n = 2\n while (existing.has(`${key}-${n}`) || roles.some((r) => r.id === `${key}-${n}`)) n++\n key = `${key}-${n}`\n }\n\n // role_create_from_template always clones something — there is no \"empty\n // role\" verb. Cloning the narrowest role available and then setting the\n // grants explicitly lands on exactly the requested set either way, and\n // never on a role that briefly held more than it should.\n const seed = rows.find((r) => r.is_system && r.key === 'viewer')?.key\n ?? rows.find((r) => r.is_system)?.key\n ?? rows[0]?.key\n if (!seed) throw new Error('createProfile: the tenant has no role to clone from')\n\n const created = await core().rpc('role_create_from_template', {\n p_role_key: key,\n p_name: profile.name,\n p_template_role: seed,\n p_template: null,\n p_description: profile.description ?? null,\n })\n if (created.error) throw created.error\n const roleId = created.data as string\n\n const catalog = await catalogKeys()\n // Without the baseline a role made here cannot even load its tenant.\n const keys = [...new Set([...grantsToDbKeys(profile.grants ?? {}, catalog), ...SESSION_BASELINE.filter((k) => catalog.has(k))])]\n const set = await core().rpc('role_set_permissions', { p_role_id: roleId, p_keys: keys })\n if (set.error) throw set.error\n\n const profiles = await this.listProfiles(orgId)\n return profiles.find((p) => p.id === key) ?? {\n id: key, name: profile.name, description: profile.description, isSystem: false,\n systemPermissions: profile.systemPermissions ?? [], grants: profile.grants ?? {},\n }\n },\n\n async updateProfile(\n orgId: string,\n profileId: string,\n data: Partial<PermissionProfile>,\n ): Promise<PermissionProfile> {\n // The RPCs address a role by its uuid; the matrix addresses it by key.\n await ensureRole(orgId, profileId)\n const found = await core()\n .from('v_authz_roles').select('id, name, description, is_system')\n .eq('tenant_id', orgId).eq('key', profileId).maybeSingle()\n if (found.error) throw found.error\n if (!found.data) throw new Error(`Profile not found: ${profileId}`)\n const role = found.data as { id: string; name: string; description: string | null; is_system: boolean }\n\n if (data.name !== undefined || data.description !== undefined) {\n const { error } = await core().rpc('role_rename', {\n p_role_id: role.id,\n p_name: data.name ?? role.name,\n // Explicit, not coalesced: role_rename treats NULL as \"clear it\", so\n // an untouched description has to be sent back as it was.\n p_description: data.description !== undefined ? (data.description ?? null) : role.description,\n })\n if (error) throw error\n }\n\n if (data.grants) {\n const catalog = await catalogKeys()\n const keys = [...new Set([...grantsToDbKeys(data.grants, catalog), ...SESSION_BASELINE.filter((k) => catalog.has(k))])]\n // One call, not delete-then-insert: role_set_permissions reconciles to\n // the given set inside one transaction, so the role is never briefly\n // holding nothing.\n const { error } = await core().rpc('role_set_permissions', { p_role_id: role.id, p_keys: keys })\n if (error) throw error\n }\n\n const profiles = await this.listProfiles(orgId)\n const updated = profiles.find((p) => p.id === profileId)\n if (!updated) throw new Error(`Profile not found: ${profileId}`)\n return updated\n },\n\n async deleteProfile(orgId: string, profileId: string): Promise<void> {\n const found = await core()\n .from('v_authz_roles').select('id, is_system')\n .eq('tenant_id', orgId).eq('key', profileId).maybeSingle()\n if (found.error) throw found.error\n if (!found.data) throw new Error('System roles cannot be deleted.')\n const role = found.data as { id: string; is_system: boolean }\n if (role.is_system) throw new Error('System roles cannot be deleted.')\n\n // role_delete refuses a role an active member still holds, and says how\n // many. That refusal is the point: it used to demote them silently.\n const { error } = await core().rpc('role_delete', { p_role_id: role.id })\n if (error) throw error\n },\n\n async listInvites(orgId: string): Promise<Invite[]> {\n const { data, error } = await core()\n .from('invitations')\n .select('*')\n .eq('tenant_id', orgId)\n .order('created_at', { ascending: false })\n\n if (error) throw error\n return ((data ?? []) as Array<Record<string, unknown>>).map(mapInviteRow)\n },\n\n async createInvite(orgId: string, email: string, profileId: string, invitedBy: string): Promise<Invite> {\n await ensureRole(orgId, profileId)\n const { data, error } = await core()\n .from('invitations')\n .insert({\n tenant_id: orgId,\n email,\n role: profileId,\n invited_by: invitedBy,\n })\n .select()\n .single()\n\n if (error) throw error\n // Deliver via the auth abstraction (sends the e-mail + creates the auth user,\n // stamping tenant_id/role on its metadata for the accept-time membership trigger).\n await authAdapter?.inviteUser?.(email, {\n redirectTo: inviteRedirectTo,\n data: { tenant_id: orgId, role: profileId, invited_by: invitedBy },\n })\n return mapInviteRow(data as Record<string, unknown>)\n },\n\n async bulkInvite(orgId: string, emails: string[], profileId: string, invitedBy: string): Promise<Invite[]> {\n await ensureRole(orgId, profileId)\n const rows = emails.map((email) => ({\n tenant_id: orgId,\n email,\n role: profileId,\n invited_by: invitedBy,\n }))\n\n const { data, error } = await core().from('invitations').insert(rows).select()\n if (error) throw error\n await Promise.all(\n emails.map((email) =>\n authAdapter?.inviteUser?.(email, {\n redirectTo: inviteRedirectTo,\n data: { tenant_id: orgId, role: profileId, invited_by: invitedBy },\n }),\n ),\n )\n return ((data ?? []) as Array<Record<string, unknown>>).map(mapInviteRow)\n },\n\n async revokeInvite(orgId: string, inviteId: string): Promise<void> {\n const { error } = await core()\n .from('invitations')\n .update({ status: 'revoked' })\n .eq('id', inviteId)\n .eq('tenant_id', orgId)\n\n if (error) throw error\n },\n\n async resendInvite(orgId: string, inviteId: string): Promise<Invite> {\n const { data, error } = await core()\n .from('invitations')\n .update({\n status: 'pending',\n expires_at: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),\n })\n .eq('id', inviteId)\n .eq('tenant_id', orgId)\n .select()\n .single()\n\n if (error) throw error\n const row = data as Record<string, unknown>\n // Re-send the invite e-mail through the auth abstraction.\n await authAdapter?.inviteUser?.(row.email as string, {\n redirectTo: inviteRedirectTo,\n data: { tenant_id: orgId, role: row.role as string, invited_by: row.invited_by as string },\n })\n return mapInviteRow(row)\n },\n\n async listLocations(orgId: string): Promise<Location[]> {\n const { data, error } = await core()\n .from('v_units')\n .select('*')\n .eq('tenant_id', orgId)\n .order('is_headquarters', { ascending: false })\n .order('name')\n\n if (error) throw error\n return ((data ?? []) as Array<Record<string, unknown>>).map(mapLocationRow)\n },\n\n async createLocation(\n orgId: string,\n input: {\n name: string\n address?: string\n city?: string\n state?: string\n country?: string\n phone?: string\n isHeadquarters?: boolean\n },\n ): Promise<Location> {\n const { data, error } = await core()\n .rpc('unit_create', {\n p_name: input.name,\n p_kind: input.isHeadquarters ? 'hq' : 'branch',\n p_parent_unit: null,\n // app.units keeps a unit's contact details in metadata; v_units reads\n // them back out under the flat names this screen already uses.\n p_metadata: {\n address: input.address ?? null,\n city: input.city ?? null,\n state: input.state ?? null,\n country: input.country ?? 'BR',\n phone: input.phone ?? null,\n },\n })\n\n if (error) throw error\n const created = await core().from('v_units').select('*').eq('id', data as string).single()\n if (created.error) throw created.error\n return mapLocationRow(created.data as Record<string, unknown>)\n },\n }\n}\n","import type {\n OrgAdapter,\n Organization,\n OrgMember,\n OrgMembership,\n CreateOrgOptions,\n Location,\n Invite,\n} from '@fayz-ai/core'\nimport type { PermissionProfile } from '@fayz-ai/core'\n\nconst STORAGE_KEY = 'fayz:mock-orgs'\n\ninterface MockOrgData {\n orgs: Organization[]\n members: OrgMember[]\n profiles: Record<string, PermissionProfile[]>\n invites: Record<string, Invite[]>\n userOrgMap: Record<string, string[]>\n}\n\nfunction getStored(): MockOrgData {\n try {\n if (typeof localStorage === 'undefined') return empty()\n const raw = localStorage.getItem(STORAGE_KEY)\n if (raw) return JSON.parse(raw) as MockOrgData\n } catch {\n // ignore\n }\n return empty()\n}\n\nfunction empty(): MockOrgData {\n return { orgs: [], members: [], profiles: {}, invites: {}, userOrgMap: {} }\n}\n\nfunction setStored(data: MockOrgData): void {\n try {\n if (typeof localStorage === 'undefined') return\n localStorage.setItem(STORAGE_KEY, JSON.stringify(data))\n } catch {\n // ignore\n }\n}\n\nfunction slugify(name: string): string {\n return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')\n}\n\nexport function createMockOrgAdapter(defaultProfiles?: PermissionProfile[]): OrgAdapter {\n function seedOrgForUser(userId: string, userName?: string): MockOrgData {\n const data = getStored()\n if (data.userOrgMap[userId]?.length) return data\n\n const orgId = crypto.randomUUID()\n const memberId = crypto.randomUUID()\n const firstProfile = defaultProfiles?.[0]\n\n const org: Organization = {\n id: orgId,\n name: 'My Organization',\n slug: 'my-organization',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n }\n\n const member: OrgMember = {\n id: memberId,\n userId,\n orgId,\n profileId: firstProfile?.id ?? 'owner',\n profileName: firstProfile?.name ?? 'Owner',\n user: {\n id: userId,\n email: userName\n ? `${userName.toLowerCase().replace(/\\s+/g, '.')}@example.com`\n : 'user@example.com',\n fullName: userName ?? 'Current User',\n },\n joinedAt: new Date().toISOString(),\n }\n\n data.orgs.push(org)\n data.members.push(member)\n data.userOrgMap[userId] = [orgId]\n if (defaultProfiles) {\n data.profiles[orgId] = [...defaultProfiles]\n }\n data.invites[orgId] = []\n\n setStored(data)\n return data\n }\n\n return {\n async listUserOrgs(userId: string): Promise<OrgMembership[]> {\n const data = seedOrgForUser(userId)\n const orgIds = data.userOrgMap[userId] ?? []\n return orgIds.map((orgId) => {\n const org = data.orgs.find((o) => o.id === orgId)!\n const member = data.members.find((m) => m.orgId === orgId && m.userId === userId)\n return {\n orgId,\n orgName: org.name,\n orgSlug: org.slug,\n orgLogoUrl: org.logoUrl,\n profileId: member?.profileId ?? 'owner',\n profileName: member?.profileName ?? 'Owner',\n }\n })\n },\n\n async getOrg(orgId: string): Promise<Organization> {\n const data = getStored()\n const org = data.orgs.find((o) => o.id === orgId)\n if (!org) throw new Error(`Org not found: ${orgId}`)\n return org\n },\n\n async createOrg(name: string, userId: string, options?: CreateOrgOptions): Promise<Organization> {\n const data = getStored()\n const orgId = crypto.randomUUID()\n const firstProfile = defaultProfiles?.[0]\n\n const org: Organization = {\n id: orgId,\n name,\n slug: slugify(name),\n verticalId: options?.verticalId,\n plan: 'free',\n settings: {\n timezone: options?.timezone ?? 'America/Sao_Paulo',\n currency: options?.currency ?? 'BRL',\n locale: options?.locale ?? 'pt-BR',\n },\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n }\n\n const member: OrgMember = {\n id: crypto.randomUUID(),\n userId,\n orgId,\n profileId: firstProfile?.id ?? 'owner',\n profileName: firstProfile?.name ?? 'Owner',\n user: {\n id: userId,\n email: 'user@example.com',\n fullName: 'Current User',\n },\n joinedAt: new Date().toISOString(),\n }\n\n data.orgs.push(org)\n data.members.push(member)\n if (!data.userOrgMap[userId]) data.userOrgMap[userId] = []\n data.userOrgMap[userId].push(orgId)\n if (defaultProfiles) {\n data.profiles[orgId] = [...defaultProfiles]\n }\n data.invites[orgId] = []\n\n setStored(data)\n return org\n },\n\n async updateOrg(orgId: string, updates: Partial<Organization>): Promise<Organization> {\n const data = getStored()\n const idx = data.orgs.findIndex((o) => o.id === orgId)\n if (idx === -1) throw new Error(`Org not found: ${orgId}`)\n data.orgs[idx] = { ...data.orgs[idx], ...updates, updatedAt: new Date().toISOString() }\n setStored(data)\n return data.orgs[idx]\n },\n\n async listMembers(orgId: string): Promise<OrgMember[]> {\n const data = getStored()\n return data.members.filter((m) => m.orgId === orgId)\n },\n\n async updateMemberProfile(orgId: string, memberId: string, profileId: string): Promise<void> {\n const data = getStored()\n const member = data.members.find((m) => m.id === memberId && m.orgId === orgId)\n if (!member) throw new Error(`Member not found: ${memberId}`)\n const profiles = data.profiles[orgId] ?? []\n const profile = profiles.find((p) => p.id === profileId)\n member.profileId = profileId\n member.profileName = profile?.name ?? profileId\n setStored(data)\n },\n\n async removeMember(orgId: string, memberId: string): Promise<void> {\n const data = getStored()\n const memberIdx = data.members.findIndex((m) => m.id === memberId && m.orgId === orgId)\n if (memberIdx === -1) return\n const member = data.members[memberIdx]\n data.members.splice(memberIdx, 1)\n const userOrgs = data.userOrgMap[member.userId]\n if (userOrgs) {\n const orgIdx = userOrgs.indexOf(orgId)\n if (orgIdx !== -1) userOrgs.splice(orgIdx, 1)\n }\n setStored(data)\n },\n\n async listProfiles(orgId: string): Promise<PermissionProfile[]> {\n const data = getStored()\n return data.profiles[orgId] ?? defaultProfiles ?? []\n },\n\n async createProfile(\n orgId: string,\n profile: Omit<PermissionProfile, 'id' | 'isSystem'>,\n ): Promise<PermissionProfile> {\n const data = getStored()\n const newProfile: PermissionProfile = {\n ...profile,\n id: crypto.randomUUID(),\n isSystem: false,\n }\n if (!data.profiles[orgId]) {\n data.profiles[orgId] = defaultProfiles ? [...defaultProfiles] : []\n }\n data.profiles[orgId].push(newProfile)\n setStored(data)\n return newProfile\n },\n\n async updateProfile(\n orgId: string,\n profileId: string,\n updates: Partial<PermissionProfile>,\n ): Promise<PermissionProfile> {\n const data = getStored()\n const profiles = data.profiles[orgId] ?? []\n const idx = profiles.findIndex((p) => p.id === profileId)\n if (idx === -1) throw new Error(`Profile not found: ${profileId}`)\n profiles[idx] = { ...profiles[idx], ...updates }\n data.profiles[orgId] = profiles\n setStored(data)\n return profiles[idx]\n },\n\n async deleteProfile(orgId: string, profileId: string): Promise<void> {\n const data = getStored()\n const profiles = data.profiles[orgId] ?? []\n const profile = profiles.find((p) => p.id === profileId)\n if (profile?.isSystem) throw new Error('Cannot delete system profile')\n data.profiles[orgId] = profiles.filter((p) => p.id !== profileId)\n setStored(data)\n },\n\n async listInvites(orgId: string): Promise<Invite[]> {\n const data = getStored()\n return data.invites[orgId] ?? []\n },\n\n async createInvite(\n orgId: string,\n email: string,\n profileId: string,\n invitedBy: string,\n ): Promise<Invite> {\n const data = getStored()\n const profiles = data.profiles[orgId] ?? defaultProfiles ?? []\n const profile = profiles.find((p) => p.id === profileId)\n\n const invite: Invite = {\n id: crypto.randomUUID(),\n orgId,\n email,\n profileId,\n profileName: profile?.name ?? profileId,\n invitedBy,\n token: crypto.randomUUID(),\n status: 'pending',\n createdAt: new Date().toISOString(),\n expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),\n }\n\n if (!data.invites[orgId]) data.invites[orgId] = []\n data.invites[orgId].push(invite)\n setStored(data)\n return invite\n },\n\n async bulkInvite(\n orgId: string,\n emails: string[],\n profileId: string,\n invitedBy: string,\n ): Promise<Invite[]> {\n const results: Invite[] = []\n for (const email of emails) {\n results.push(await this.createInvite(orgId, email, profileId, invitedBy))\n }\n return results\n },\n\n async revokeInvite(orgId: string, inviteId: string): Promise<void> {\n const data = getStored()\n const invites = data.invites[orgId] ?? []\n const invite = invites.find((i) => i.id === inviteId)\n if (invite) {\n invite.status = 'expired'\n setStored(data)\n }\n },\n\n async resendInvite(orgId: string, inviteId: string): Promise<Invite> {\n const data = getStored()\n const invites = data.invites[orgId] ?? []\n const invite = invites.find((i) => i.id === inviteId)\n if (!invite) throw new Error(`Invite not found: ${inviteId}`)\n invite.expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString()\n invite.status = 'pending'\n setStored(data)\n return invite\n },\n\n async listLocations(_orgId: string): Promise<Location[]> {\n return []\n },\n\n async createLocation(\n orgId: string,\n input: {\n name: string\n address?: string\n city?: string\n state?: string\n country?: string\n phone?: string\n isHeadquarters?: boolean\n },\n ): Promise<Location> {\n return {\n id: crypto.randomUUID(),\n tenantId: orgId,\n name: input.name,\n address: input.address,\n city: input.city,\n state: input.state,\n country: input.country ?? 'BR',\n phone: input.phone,\n isHeadquarters: input.isHeadquarters ?? false,\n isActive: true,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n }\n },\n }\n}\n","import type { OrgMembership } from '@fayz-ai/core'\n\n/**\n * Which workspace this account lands in, when it belongs to more than one.\n *\n * The provider used to answer this by itself — `handoff ?? pinned ?? first` —\n * and that last fallback is a guess with no way to correct it: an account in\n * seven workspaces opened whichever one sorted first and never learnt that the\n * other six existed. The rule below keeps every branch that IS an answer and\n * hands the remaining case to the person, once.\n */\n\nconst AUTOPICK_KEY = 'fayz:workspace-autopick'\n\n/**\n * The workspace a switch already committed to, surviving exactly one reload.\n *\n * Changing workspace ends in a full page reload — the only way to guarantee\n * that every plugin store, cache and open screen is rebuilt against the new\n * tenant instead of showing the previous one's rows. That reload comes back\n * through the same boot path as a fresh login, so without this marker the\n * picker would open and ask a question the user answered one second ago.\n *\n * sessionStorage, not local: it is about THIS navigation, and a tab opened\n * tomorrow should ask again.\n */\nconst SWITCHING_KEY = 'fayz:workspace-switching'\n\n/** Records the destination, for the boot that happens after the reload. */\nexport function markWorkspaceSwitch(orgId: string): void {\n try {\n if (typeof sessionStorage === 'undefined') return\n sessionStorage.setItem(SWITCHING_KEY, orgId)\n } catch {\n // ignore\n }\n}\n\n/** Reads the destination and consumes it — it is good for one boot only. */\nexport function takeWorkspaceSwitch(): string | null {\n try {\n if (typeof sessionStorage === 'undefined') return null\n const v = sessionStorage.getItem(SWITCHING_KEY)\n if (v) sessionStorage.removeItem(SWITCHING_KEY)\n return v\n } catch {\n return null\n }\n}\n\n/** Whether the last explicit choice stands in for every future login. */\nexport function getAutoPick(): boolean {\n try {\n if (typeof localStorage === 'undefined') return false\n return localStorage.getItem(AUTOPICK_KEY) === '1'\n } catch {\n return false\n }\n}\n\nexport function setAutoPick(on: boolean): void {\n try {\n if (typeof localStorage === 'undefined') return\n if (on) localStorage.setItem(AUTOPICK_KEY, '1')\n else localStorage.removeItem(AUTOPICK_KEY)\n } catch {\n // ignore\n }\n}\n\nexport interface WorkspaceChoiceInput {\n /** Every workspace this account belongs to, as the membership list read it. */\n memberships: OrgMembership[]\n /** A switch that is completing across a reload — already answered, once. */\n switchingToId?: string | null\n /** A sibling app's switcher named a workspace on the way in (008). */\n handoffId: string | null\n /** `fayz:current-org` — the last workspace this browser was in. */\n pinnedId: string | null\n /** \"Não perguntar novamente\" is on for this browser. */\n autoPick: boolean\n}\n\nexport type WorkspaceChoice =\n /** Open this one without asking. */\n | { kind: 'resolved'; orgId: string }\n /** Put the picker on screen; `suggestedId` is the row to pre-select. */\n | { kind: 'ask'; suggestedId: string | null }\n /** No workspace at all — the first-run setup flow's business, not ours. */\n | { kind: 'none' }\n\n/**\n * The decision, as a function, so the one piece of logic that decides what a\n * multi-workspace account sees after login can be tested without a browser.\n */\nexport function decideWorkspaceChoice({\n memberships,\n switchingToId = null,\n handoffId,\n pinnedId,\n autoPick,\n}: WorkspaceChoiceInput): WorkspaceChoice {\n if (memberships.length === 0) return { kind: 'none' }\n\n const has = (id: string | null): string | null =>\n id && memberships.some((m) => m.orgId === id) ? id : null\n\n // The freshest answer there is: this reload IS the switch completing.\n const switching = has(switchingToId)\n if (switching) return { kind: 'resolved', orgId: switching }\n\n // A handoff is somebody clicking a specific account in a sibling app's\n // switcher one second ago. That is a fresher answer than anything stored\n // here, and asking again would be asking a question already answered.\n const handoff = has(handoffId)\n if (handoff) return { kind: 'resolved', orgId: handoff }\n\n // One workspace is not a choice.\n if (memberships.length === 1) return { kind: 'resolved', orgId: memberships[0]!.orgId }\n\n // The pin is a HINT, always re-validated against the list we just read: a\n // workspace someone was removed from falls through to the question instead of\n // opening an account they can no longer see.\n const pinned = has(pinnedId)\n if (pinned && autoPick) return { kind: 'resolved', orgId: pinned }\n\n return { kind: 'ask', suggestedId: pinned }\n}\n","import { create } from 'zustand'\nimport { EMPTY_APP_CONFIG, type AppConfig } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// app-config.store — what THIS tenant has, as the database says it (#280).\n//\n// The shell used to learn what to render from `app.manifest.json`, a file that\n// shipped next to the code. That is why eleven applications needed eleven\n// repositories, and why turning a feature on for one customer was a deploy.\n// Since migration 150 the answer is a row, and `app_config()` returns branding,\n// activations, menu composition and the caller's permissions in one stamped\n// round trip.\n//\n// ── Why the manifest still matters ──────────────────────────────────────────\n// It says what a plugin CAN do; this says what this tenant HAS. Neither\n// replaces the other, and confusing them is how a plugin ends up shipping a\n// customer's configuration.\n//\n// ── Why `stale` and not `loading` alone ─────────────────────────────────────\n// Config drives the frame of the app, so re-fetching it must not blank the\n// screen. A refresh keeps the previous answer readable and marks it stale; only\n// the very first load has nothing to show.\n//\n// ── Por que o config sabe DE QUEM ele é ─────────────────────────────────────\n// Trocar de conta não é atualizar: é outra resposta. Sem `tenantId` aqui, o\n// shell pintava a conta nova com a configuração da anterior (ou com o padrão do\n// bundle) até a chamada voltar — rail curto, e o guarda de rota negando com\n// \"acesso restrito\" porque o perfil ainda não tinha chegado. Depois tudo\n// trocava de uma vez, e o que o usuário via era um pisca.\n//\n// Com o dono anotado, quem renderiza consegue perguntar \"isto é sobre a conta\n// em que eu estou?\" — e, quando não é, esperar mostrando esqueleto em vez de\n// mostrar outra coisa.\n// ---------------------------------------------------------------------------\n\ninterface AppConfigStore {\n config: AppConfig\n /** De quem é a configuração em `config`. `null` = nenhuma ainda. */\n tenantId: string | null\n /** True until the first answer arrives — not on every refresh. */\n initializing: boolean\n /** A refresh is in flight; the config on screen is the previous one. */\n stale: boolean\n /** The read failed. The shell still renders: an empty config is legible. */\n error: string | null\n setConfig: (config: AppConfig, tenantId?: string | null) => void\n /** Uma conta nova entrou em cena: o que está em tela não é sobre ela. */\n beginTenant: (tenantId: string | null) => void\n setStale: (stale: boolean) => void\n setError: (error: string | null) => void\n reset: () => void\n}\n\nconst initialState = {\n config: EMPTY_APP_CONFIG,\n tenantId: null,\n initializing: true,\n stale: false,\n error: null,\n}\n\nexport const useAppConfigStore = create<AppConfigStore>((set) => ({\n ...initialState,\n setConfig: (config, tenantId) =>\n set({\n config,\n tenantId: tenantId === undefined ? config.tenant_id ?? null : tenantId,\n initializing: false,\n stale: false,\n error: null,\n }),\n // Não limpa o que está em tela: quem espera desenha esqueleto, e um esqueleto\n // sobre a última resposta é melhor que um branco.\n beginTenant: (tenantId) => set({ tenantId, initializing: true, error: null }),\n setStale: (stale) => set({ stale }),\n setError: (error) => set({ error, initializing: false, stale: false }),\n reset: () => set(initialState),\n}))\n\n/** Active plugin ids, facets folded in — what a screen asks before rendering. */\nexport function activePluginIds(config: AppConfig): string[] {\n return [...new Set(config.plugins.filter((p) => p.status === 'active').map((p) => p.plugin))]\n}\n\n/**\n * Is this plugin — or one named part of it — on for this tenant?\n *\n * The facet argument is what makes a plugin with free and paid halves possible:\n * `has('financial')` asks about the plugin, `has('financial', 'reconciliation')`\n * asks about the part somebody pays for.\n */\nexport function hasPlugin(config: AppConfig, plugin: string, facet?: string): boolean {\n const wanted = facet ?? ''\n return config.plugins.some(\n (p) => p.plugin === plugin && (p.facet ?? '') === wanted && p.status === 'active',\n )\n}\n","import * as React from 'react'\nimport { Building2 } from 'lucide-react'\nimport { cn } from '../lib/cn'\nimport { useAppConfigStore } from '../stores/app-config.store'\n\n/**\n * A cara de uma conta: a marca dela, ou as iniciais.\n *\n * Existia em TRÊS cópias — o gatilho do rail, o seletor pós-login e o diálogo\n * de troca — e cada uma aprendeu as regras abaixo separado. As duas primeiras\n * cortavam a marca (`object-cover`), e só uma delas sabia da arte por\n * superfície. Um componente, uma regra.\n *\n * ── As três regras ─────────────────────────────────────────────────────────\n *\n * 1. **Contido, nunca cortado.** O que chega aqui costuma ser um wordmark\n * largo, e cortar o meio dele é o que fazia \"Espaço Facial\" virar \"aço\".\n *\n * 2. **O ladrilho JÁ VEM PRONTO na imagem.** `markUrl` aponta para um quadrado\n * acabado — fundo escuro, cantos arredondados, glifo claro dentro — gerado\n * uma vez e guardado. A alternativa era o componente montar isso a cada\n * render (fundo por classe, glifo por cima, uma regra de contraste por\n * superfície), que foi o que fez a marca sumir duas vezes, em direções\n * opostas. Uma imagem pronta lê igual no rail, no popover e no seletor\n * pós-login, e não tem regra para errar.\n *\n * 3. **A marca do documento é só da conta ATIVA.** `app_config()` descreve o\n * inquilino em que a sessão está. Usá-la nas linhas da lista pinta todas as\n * contas com o ícone de uma — e o seletor pós-login nem tem conta ativa\n * ainda, então lá cada linha usa sempre a arte da própria conta.\n */\nexport interface OrgMarkProps {\n name: string\n /** A marca da conta, como a lista a conhece (`tenants.logo_url`). */\n logoUrl?: string\n className?: string\n /** A superfície onde o ladrilho está. O popover é claro mesmo num rail escuro. */\n tone?: 'sidebar' | 'popover'\n /** Este ladrilho é o da conta ativa — só ele pode usar o documento de marca. */\n current?: boolean\n}\n\n/** Duas letras no máximo: primeira + última palavra (\"Artorius Steakhouse\" → AS). */\nexport function orgInitials(name: string): string {\n const words = name.trim().split(/\\s+/).filter(Boolean)\n if (!words.length) return '?'\n if (words.length === 1) return words[0]!.slice(0, 2).toUpperCase()\n return (words[0]![0]! + words[words.length - 1]![0]!).toUpperCase()\n}\n\nexport function OrgMark({ name, logoUrl, className, tone = 'sidebar', current = false }: OrgMarkProps) {\n const identity = useAppConfigStore((state) => (state.config.branding as { identity?: Record<string, unknown> })?.identity)\n const pick = (key: string) => (typeof identity?.[key] === 'string' ? (identity[key] as string) : undefined)\n const src = (current ? pick('markUrl') : undefined) ?? logoUrl\n\n const [status, setStatus] = React.useState<'loading' | 'ok' | 'error'>('loading')\n const imgRef = React.useRef<HTMLImageElement>(null)\n // Imagem já em cache termina ANTES do React pendurar o `onLoad`, e esse\n // evento nunca dispara — o esqueleto ficaria pulsando para sempre sobre uma\n // marca pronta. `complete` num layout effect é quem pergunta isso a tempo.\n // O mesmo efeito volta a esperar quando a marca TROCA (troca de conta, ou o\n // `markUrl` que só chega depois do config): manter `ok` mostrava a marca\n // anterior por um quadro. Um efeito só, porque um passivo logo em seguida\n // desfazia o que este acabou de decidir.\n React.useLayoutEffect(() => {\n const el = imgRef.current\n setStatus(el?.complete ? (el.naturalWidth > 0 ? 'ok' : 'error') : 'loading')\n }, [src])\n\n // Squircle com um fio de contorno, para a marca manter a forma agora que nada\n // à volta dela é delineado — o único objeto sólido no topo do rail.\n const base = cn(\n 'shrink-0 overflow-hidden rounded-lg ring-1 ring-inset',\n tone === 'popover' ? 'ring-black/5' : 'ring-white/10',\n className ?? 'h-6 w-6',\n )\n\n // `cover` porque a arte já é o ladrilho inteiro: quadrada, com fundo e com a\n // margem que ela mesma escolheu. Nada a compor aqui.\n //\n // Enquanto ela não chega, um quadrado cinza no lugar exato que ela vai\n // ocupar. Sem isso o gatilho do rail e cada linha do seletor nasciam com um\n // buraco — a lista aparecia montada e as marcas pingavam depois, cada uma no\n // seu tempo, e o topo do rail pulava quando a primeira entrava. O esqueleto\n // reserva o espaço desde o primeiro quadro; e se a imagem falhar, o que fica\n // é a iniciais — a mesma coisa que uma conta sem marca nenhuma mostra.\n if (src && status !== 'error') {\n return (\n <span className={cn(base, 'relative block')}>\n <img\n ref={imgRef}\n src={src}\n alt=\"\"\n onLoad={() => setStatus('ok')}\n onError={() => setStatus('error')}\n className={cn(\n 'h-full w-full object-cover transition-opacity duration-200',\n status === 'ok' ? 'opacity-100' : 'opacity-0',\n )}\n />\n {status === 'loading' && (\n <span\n aria-hidden\n className={cn(\n 'absolute inset-0 animate-pulse',\n tone === 'popover' ? 'bg-muted' : 'bg-sidebar-accent',\n )}\n />\n )}\n </span>\n )\n }\n\n return (\n <span\n aria-hidden\n className={cn(\n base,\n 'flex items-center justify-center text-[10px] font-semibold uppercase leading-none tracking-tight',\n tone === 'popover' ? 'bg-muted text-foreground' : 'bg-sidebar-accent text-sidebar-accent-foreground',\n )}\n >\n {orgInitials(name) || <Building2 className=\"h-3.5 w-3.5\" />}\n </span>\n )\n}\n","import {\n emitDomainEvent, getActiveTenantId, getSupabaseClientOptional,\n isKnownMissing, rememberIfMissing,\n} from '@fayz-ai/core'\nimport type { Location } from '../types/tenant'\n\n// ---------------------------------------------------------------------------\n// Reading the unit tree.\n//\n// Deliberately NOT part of OrgAdapter: a unit is a security dimension, not an\n// org-settings screen, and bolting five more methods onto an interface every\n// app implements would make every app care. Everything here goes through the\n// global Supabase client, and degrades to \"no units\" when there isn't one —\n// which is exactly right for an app running on mock data.\n// ---------------------------------------------------------------------------\n\nexport interface Unit extends Location {\n parentId?: string | null\n code?: string | null\n /** Opcionais, e só servem para oferecer \"a mais perto de mim\" na entrada. */\n latitude?: number | null\n longitude?: number | null\n}\n\nexport interface UnitBinding {\n locationId: string\n role: string | null\n}\n\n/** `core.unit-access.changed` — alguém entrou ou saiu de uma unidade.\n *\n * Mesma forma dos fatos de cadastro (`registry.<entidade>.created`): quem\n * escuta usa `useDataVersion` e relê, e a auditoria vê este fato sem ninguém\n * ter que inscrevê-la. */\n// Pools drift, and a pool without the unit-scoping migrations answers the same\n// three questions with the same 404 on every boot. Asked once per page load.\nconst UNIT_BOOTSTRAP_OBJECT = 'rpc:unit_bootstrap'\nconst UNIT_MODE_OBJECT = 'tenants.unit_scoping_enabled'\nconst SCOPED_RESOURCES_OBJECT = 'scoped_resources'\n\nexport const UNIT_ACCESS_CHANGED = 'core.unit-access.changed'\n\nfunction emitUnitAccessChanged(userId: string | null, unitId: string): void {\n emitDomainEvent(\n UNIT_ACCESS_CHANGED,\n { user_id: userId, unit_id: unitId },\n { tenantId: getActiveTenantId() ?? null, subject: { type: 'location', id: unitId } },\n )\n}\n\nfunction client() {\n return getSupabaseClientOptional() as {\n from: (t: string) => any\n rpc: (fn: string, args?: Record<string, unknown>) => Promise<{ data: any; error: any }>\n } | null\n}\n\nfunction mapUnit(row: Record<string, any>): Unit {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n kind: row.kind ?? 'branch',\n name: row.name,\n email: row.email ?? undefined,\n phone: row.phone ?? undefined,\n address: row.address ?? undefined,\n city: row.city ?? undefined,\n state: row.state ?? undefined,\n country: row.country ?? 'BR',\n postalCode: row.postal_code ?? undefined,\n isHeadquarters: Boolean(row.is_headquarters),\n isActive: row.is_active !== false,\n tags: row.tags ?? [],\n notes: row.notes ?? undefined,\n metadata: row.metadata ?? {},\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n parentId: row.parent_id ?? null,\n code: row.code ?? null,\n // numeric do Postgres chega como string no PostgREST; a aritmética de\n // distância precisa de número, e `Number(null)` é 0, que é uma coordenada\n // real no golfo da Guiné.\n latitude: row.latitude == null ? null : Number(row.latitude),\n longitude: row.longitude == null ? null : Number(row.longitude),\n }\n}\n\n/** Every unit of the tenant. Readable tenant-wide even under scoping: a unit's\n * NAME is not its data, and the switcher has to be able to say it. */\nexport async function fetchUnits(tenantId: string): Promise<Unit[]> {\n const db = client()\n if (!db) return []\n const { data, error } = await db\n .from('v_units')\n .select('*')\n .eq('tenant_id', tenantId)\n .order('is_headquarters', { ascending: false })\n .order('name')\n // A pool that has not taken migration 039 has no `parent_id`; the screen must\n // degrade to \"no units\" rather than throw a red boundary over the whole app.\n if (error) return []\n return (data ?? []).map(mapUnit)\n}\n\n/** Which units the signed-in person is bound to IN THIS WORKSPACE. The DATABASE\n * decides what they may read; this only decides what the switcher offers.\n *\n * The tenant filter is not redundant with RLS. `membership_units_select` lets\n * you see your OWN rows unconditionally (`user_id = auth.uid() OR …`) — it has\n * to, or you could not find yourself — and \"your own rows\" spans every account\n * you belong to. Without the filter, a binding in one workspace came back while\n * standing in another, and `reachable` in UnitMenuSection then narrowed the\n * list to a unit that is not in this tenant's tree: the Unidades section\n * rendered its heading with NOTHING under it, on a tenant with four active\n * units. Reported as \"Espaço Facial não lista as unidades\". */\nexport async function fetchMyBindings(userId: string, tenantId: string): Promise<UnitBinding[]> {\n const db = client()\n if (!db) return []\n const { data, error } = await db\n .from('v_unit_members')\n .select('location_id, role')\n .eq('user_id', userId)\n .eq('tenant_id', tenantId)\n if (error) return []\n return (data ?? []).map((r: any) => ({ locationId: r.location_id, role: r.role ?? null }))\n}\n\nexport interface UnitBootstrap {\n mode: boolean\n units: Unit[]\n /** O vínculo EXPLÍCITO — o que a aba \"Unidades\" de uma pessoa edita. */\n bindings: UnitBinding[]\n /**\n * O que a pessoa ALCANÇA de verdade nesta conta (#018), incluindo quem entra\n * pela conta inteira e por isso não tem vínculo explícito nenhum.\n *\n * São coisas diferentes e a diferença é o bug: `bindings` é a intenção que\n * alguém digitou, `reachable` é o alcance que o banco reconhece — e só o\n * segundo responde \"posso ficar nesta unidade?\". Medir o pino de entrada\n * contra `bindings` fazia o dono do Espaço Facial, que alcança as quatro\n * unidades e não tem vínculo em nenhuma, cair em \"todas\" a cada F5.\n *\n * `undefined` num pool sem a 018 — quem chama recua para `bindings`.\n */\n reachable?: string[]\n scoped: Record<string, { unitColumn: string; shareable: boolean }>\n /** O que esta máquina abriu por último. `set` distingue \"escolheu todas\" de\n * \"nunca escolheu\" — sem isso, quem escolhe \"todas\" leva o palpite de volta\n * na entrada seguinte, para sempre. */\n devicePin: { set: boolean; unitId: string | null }\n /** O que esta pessoa abriu por último em qualquer aparelho. */\n accountPin: { set: boolean; unitId: string | null }\n}\n\n/**\n * Tudo que a entrada precisa, numa viagem.\n *\n * Eram cinco: chave da conta, árvore, vínculos, registro de tabelas escopadas e\n * o pino. Em rede móvel isso é o intervalo inteiro entre o login e a primeira\n * lista — e durante ele a lista já pintou sem unidade nenhuma, mostrando linhas\n * que o seletor está prestes a dizer que não está mostrando.\n *\n * Devolve `null` quando a função não existe (pool sem a 045), e quem chama cai\n * nas consultas soltas. Um app não pode quebrar por causa de uma otimização.\n */\nexport async function fetchUnitBootstrap(\n tenantId: string,\n deviceId: string | undefined,\n): Promise<UnitBootstrap | null> {\n const db = client()\n if (!db) return null\n if (isKnownMissing(UNIT_BOOTSTRAP_OBJECT)) return null\n const { data, error } = await (db as any).rpc('unit_bootstrap', {\n p_tenant_id: tenantId,\n p_device_id: deviceId ?? null,\n })\n if (error) {\n rememberIfMissing(UNIT_BOOTSTRAP_OBJECT, error)\n return null\n }\n if (!data) return null\n const raw = data as Record<string, any>\n return {\n mode: Boolean(raw.mode),\n units: (raw.units ?? []).map(mapUnit),\n bindings: (raw.bindings ?? []).map((r: any) => ({\n locationId: r.location_id, role: r.role ?? null,\n })),\n scoped: Object.fromEntries(\n Object.entries(raw.scoped ?? {}).map(([table, v]: [string, any]) => [\n table, { unitColumn: v?.unit_column ?? 'unit_id', shareable: v?.shareable !== false },\n ]),\n ),\n // user_unit_ids_in walks the tree with UNION over (id, depth): a branch\n // reached directly AND through its HQ comes back twice.\n reachable: Array.isArray(raw.reachable) ? [...new Set(raw.reachable as string[])] : undefined,\n devicePin: { set: Boolean(raw.device_pin_set), unitId: raw.device_pin ?? null },\n accountPin: { set: Boolean(raw.account_pin_set), unitId: raw.account_pin ?? null },\n }\n}\n\n/**\n * Guarda onde a pessoa está, para ela não ter que dizer de novo amanhã.\n *\n * No servidor e não só no navegador, porque o hábito é da pessoa e a máquina é\n * um detalhe: trocar de computador não devia custar uma escolha. Silencioso de\n * propósito — falhar em gravar uma preferência não é assunto de quem só queria\n * abrir a agenda, e a próxima entrada simplesmente pergunta de novo.\n */\nexport async function saveEntryUnit(\n tenantId: string,\n unitId: string | undefined,\n deviceId: string | undefined,\n): Promise<void> {\n const db = client()\n if (!db || !deviceId) return\n await (db as any).rpc('set_entry_unit', {\n p_tenant_id: tenantId,\n p_unit_id: unitId ?? null,\n p_device_id: deviceId,\n })\n}\n\nexport interface UnitMemberRow {\n id: string\n userId: string\n role: string | null\n /** When this person was given access to this unit (migration 044). */\n since: string | null\n}\n\nexport async function fetchUnitMembers(unitId: string): Promise<UnitMemberRow[]> {\n const db = client()\n if (!db) return []\n const { data, error } = await db\n .from('v_unit_members')\n .select('id, user_id, role, created_at')\n .eq('location_id', unitId)\n .order('created_at')\n if (error) return []\n return (data ?? []).map((r: any) => ({\n id: r.id, userId: r.user_id, role: r.role ?? null, since: r.created_at ?? null,\n }))\n}\n\n/** Last sign-in per member, for admins of this tenant only.\n *\n * Through an RPC because `auth.users` is not readable by any client role, and\n * must not be: the same table holds password hashes. The function returns the\n * two harmless columns and nothing else. */\nexport async function fetchMemberActivity(tenantId: string): Promise<Record<string, { lastSignInAt: string | null; signedUpAt: string | null }>> {\n const db = client()\n if (!db) return {}\n const { data, error } = await (db as any).rpc('tenant_member_activity', { p_tenant_id: tenantId })\n if (error) return {}\n const out: Record<string, { lastSignInAt: string | null; signedUpAt: string | null }> = {}\n for (const r of data ?? []) {\n out[(r as any).user_id] = {\n lastSignInAt: (r as any).last_sign_in_at ?? null,\n signedUpAt: (r as any).signed_up_at ?? null,\n }\n }\n return out\n}\n\n/** A member's bindings, for the team screens. The workspace defaults to the\n * active one: every caller is a screen rendered inside it, and asking each to\n * thread a tenant id it already stands in is how one of them forgets. */\nexport async function fetchMemberUnits(userId: string, tenantId?: string): Promise<UnitBinding[]> {\n const tenant = tenantId ?? getActiveTenantId()\n if (!tenant) return []\n return fetchMyBindings(userId, tenant)\n}\n\nexport async function bindUserToUnit(unitId: string, userId: string, role: string | null): Promise<void> {\n const db = client()\n if (!db) throw new Error('sem conexão')\n // An RPC, not an upsert: v_unit_members is a JOINED view, so PostgREST has no\n // unique constraint to conflict on. unit_member_set checks members.manage and\n // refuses an unknown role rather than writing a dangling override.\n const { error } = await db.rpc('unit_member_set', { p_unit: unitId, p_user: userId, p_role: role })\n if (error) throw error\n // Aqui dentro, e não em quem chama: a mesma verdade está em quatro telas, e\n // a que esquecer de avisar é a que fica mentindo. Pelo barramento de eventos\n // de domínio, que é por onde todo fato do sistema já passa — um contador só\n // para unidades seria um terceiro mecanismo para uma ideia que já tem um.\n emitUnitAccessChanged(userId, unitId)\n}\n\nexport async function unbindUserFromUnit(unitId: string, userId: string): Promise<void> {\n const db = client()\n if (!db) throw new Error('sem conexão')\n const { error } = await db.rpc('unit_member_remove', { p_unit: unitId, p_user: userId })\n if (error) throw error\n emitUnitAccessChanged(userId, unitId)\n}\n\n/** The login behind a person record, if there is one.\n *\n * A unit binding is keyed by the auth user, not by the person: a professional\n * with no login has nowhere to bind access TO. `tenant_members.person_id` is\n * the link, and it is nullable on both sides on purpose — plenty of people in a\n * salon's staff list never sign in. */\nexport async function fetchUserIdForPerson(personId: string): Promise<string | null> {\n const db = client()\n if (!db) return null\n const { data, error } = await db\n .from('v_team_members')\n .select('user_id')\n .eq('person_id', personId)\n .maybeSingle()\n if (error || !data) return null\n return (data as any).user_id ?? null\n}\n\n/** Which tables carry a unit, and under which column — the client's mirror of\n * what the policies actually enforce. Read rather than restated, so a table\n * added to the model in SQL cannot be forgotten in TypeScript. */\nexport async function fetchScopedResources(): Promise<Record<string, { unitColumn: string; shareable: boolean }>> {\n const db = client()\n if (!db) return {}\n if (isKnownMissing(SCOPED_RESOURCES_OBJECT)) return {}\n const { data, error } = await db.from('scoped_resources').select('resource_table, unit_column, shareable')\n if (error) {\n rememberIfMissing(SCOPED_RESOURCES_OBJECT, error)\n return {}\n }\n const out: Record<string, { unitColumn: string; shareable: boolean }> = {}\n for (const r of data ?? []) {\n out[(r as any).resource_table] = {\n unitColumn: (r as any).unit_column ?? 'unit_id',\n shareable: (r as any).shareable !== false,\n }\n }\n return out\n}\n\n/**\n * Whether this tenant works with units, and whether the question is even\n * answerable here.\n *\n * `installed: false` means the pool never took migration 039 — the column is\n * not there, so units do not exist in this deployment at all. That is a\n * different fact from \"the tenant has units switched off\", and collapsing the\n * two (as `false` alone did) is what made the boot fan out to `locations`,\n * `location_members` and `scoped_resources` on pools that have none of them.\n */\nexport async function fetchUnitMode(tenantId: string): Promise<{ installed: boolean; on: boolean }> {\n const db = client()\n if (!db) return { installed: false, on: false }\n if (isKnownMissing(UNIT_MODE_OBJECT)) return { installed: false, on: false }\n const { data, error } = await db\n .from('tenants')\n .select('unit_scoping_enabled')\n .eq('id', tenantId)\n .maybeSingle()\n if (error) {\n rememberIfMissing(UNIT_MODE_OBJECT, error)\n return { installed: false, on: false }\n }\n // A tenant row that is simply not readable is still a pool WITH the feature;\n // reporting it as absent would hide a policy problem behind a deploy story.\n return { installed: true, on: Boolean(data?.unit_scoping_enabled) }\n}\n\nexport async function setUnitModeRemote(tenantId: string, on: boolean): Promise<void> {\n const db = client()\n if (!db) throw new Error('sem conexão')\n const { error } = await db.from('tenants').update({ unit_scoping_enabled: on }).eq('id', tenantId)\n if (error) throw error\n}\n\n/** Bind every current member of the tenant to one unit. The \"link everyone to\n * the head office\" checkbox on the switch-on dialog — the difference between a\n * feature people try and one that locks a team out on a Tuesday. */\nexport async function bindAllMembersTo(tenantId: string, unitId: string): Promise<number> {\n const db = client()\n if (!db) return 0\n const { data } = await db.from('v_team_members').select('user_id').eq('tenant_id', tenantId)\n const userIds = (data ?? []).map((m: any) => m.user_id as string)\n if (userIds.length === 0) return 0\n // One call per member. The bulk upsert this replaces was one round trip, but\n // it wrote through a projection that no longer exists — and a partial failure\n // here names the member it failed on, which the bulk form never could.\n for (const userId of userIds) {\n const { error } = await db.rpc('unit_member_set', { p_unit: unitId, p_user: userId, p_role: null })\n if (error) throw error\n }\n // Vinculou a conta inteira de uma vez: sem uma pessoa para citar, o fato é o\n // mesmo e quem escuta relê. Uma releitura à toa custa menos do que uma tela\n // afirmando que ninguém tem acesso.\n emitUnitAccessChanged(null, unitId)\n return userIds.length\n}\n\n/** How many members have no unit at all — the number the switch-on dialog shows,\n * and the one that predicts the \"everything disappeared\" support ticket. */\nexport async function countUnboundMembers(tenantId: string): Promise<number> {\n const db = client()\n if (!db) return 0\n const { data: members } = await db.from('v_team_members').select('user_id').eq('tenant_id', tenantId)\n const { data: units } = await db.from('v_units').select('id').eq('tenant_id', tenantId)\n const unitIds = (units ?? []).map((u: any) => u.id)\n if (unitIds.length === 0) return (members ?? []).length\n const { data: bound } = await db.from('v_unit_members').select('user_id').in('location_id', unitIds)\n const boundSet = new Set((bound ?? []).map((b: any) => b.user_id))\n return (members ?? []).filter((m: any) => !boundSet.has(m.user_id)).length\n}\n","import type { Unit, UnitBinding } from './data'\n\n/**\n * O que a sessão sabia sobre unidades da última vez, para saber de novo antes\n * do primeiro pixel.\n *\n * Aqui isso vale mais do que na organização, e por um motivo que não é\n * velocidade: enquanto a unidade não resolve, a unidade ativa é \"nenhuma\" — e\n * \"nenhuma\" significa TODAS. A lista já pintou mostrando linhas de quinze lojas\n * quando o seletor vai dizer \"Ipanema\", e quando a resposta chega ela troca o\n * escopo e derruba o cache inteiro, refazendo toda consulta da tela. O usuário\n * vê a mesma página duas vezes, com conteúdos diferentes, e a segunda é a certa.\n *\n * Com o retrato, a unidade está resolvida antes do primeiro render: nada pisca\n * e nada refaz, porque `setActiveUnitId` já sai cedo quando o valor não mudou.\n *\n * ISTO NÃO É AUTORIZAÇÃO, e não pode virar. O que a pessoa alcança é decidido\n * no Postgres a cada consulta; o que está aqui é só \"onde eu estava\". Um\n * retrato adulterado à mão esconde linha, o que é chato, e não revela nenhuma,\n * que é o ponto.\n */\n\nconst STORAGE_KEY = 'fayz:units-snapshot'\nconst VERSION = 1\n\n/** Mais velho que isto e o retrato é descartado em vez de pintado. */\nconst MAX_AGE_MS = 24 * 60 * 60 * 1000\n/** Uma rede grande com árvore longa — melhor não pintar do que estourar a cota. */\nconst MAX_BYTES = 256 * 1024\n\nexport interface UnitSnapshot {\n version: number\n /** De quem é o retrato. Outra pessoa na mesma máquina começa do zero. */\n userId: string\n /** De qual conta. Trocar de workspace descarta em vez de traduzir. */\n tenantId: string\n savedAt: number\n mode: boolean\n units: Unit[]\n myUnitIds: string[]\n bindings: UnitBinding[]\n activeUnitId: string | null\n scoped: Record<string, { unitColumn: string; shareable: boolean }>\n}\n\nexport type UnitSnapshotInput = Omit<UnitSnapshot, 'version' | 'savedAt'>\n\nfunction storage(): Storage | null {\n try {\n if (typeof localStorage === 'undefined') return null\n return localStorage\n } catch {\n return null\n }\n}\n\nexport function readUnitSnapshot(): UnitSnapshot | null {\n const store = storage()\n if (!store) return null\n try {\n const raw = store.getItem(STORAGE_KEY)\n if (!raw) return null\n const snapshot = JSON.parse(raw) as UnitSnapshot\n if (snapshot?.version !== VERSION || !snapshot.tenantId || !snapshot.userId) return null\n const age = Date.now() - snapshot.savedAt\n // Um relógio que andou para trás não devolve um cache eternamente novo.\n if (age < 0 || age > MAX_AGE_MS) {\n store.removeItem(STORAGE_KEY)\n return null\n }\n return snapshot\n } catch {\n return null\n }\n}\n\nexport function saveUnitSnapshot(input: UnitSnapshotInput): void {\n const store = storage()\n if (!store) return\n try {\n const raw = JSON.stringify({ ...input, version: VERSION, savedAt: Date.now() })\n if (raw.length > MAX_BYTES) return\n store.setItem(STORAGE_KEY, raw)\n } catch {\n // Cota ou serialização — o retrato é otimização, não estado.\n }\n}\n\n/** Trocar a unidade ativa sem reiniciar a janela de validade: a escolha é do\n * usuário, e não é uma leitura nova do servidor. */\nexport function patchUnitSnapshotActive(activeUnitId: string | null): void {\n const store = storage()\n const current = readUnitSnapshot()\n if (!store || !current) return\n try {\n store.setItem(STORAGE_KEY, JSON.stringify({ ...current, activeUnitId }))\n } catch {\n // idem\n }\n}\n\nexport function clearUnitSnapshot(): void {\n try {\n storage()?.removeItem(STORAGE_KEY)\n } catch {\n // ignore\n }\n}\n","/**\n * Qual máquina é esta.\n *\n * A recepcionista do balcão da Ipanema usa sempre o mesmo computador, e esse\n * computador fica na Ipanema. É o sinal mais forte que existe sobre onde ela\n * está, e o único que não custa um pedido de permissão nem uma pergunta.\n *\n * É um número sorteado, não uma impressão digital. Não olha resolução de tela,\n * fontes instaladas, canvas nem user-agent — nada que descreva o aparelho ou\n * que sirva para reconhecê-lo em outro lugar. Um identificador que não descreve\n * nada não pode ser usado para mais nada, e essa é a diferença entre lembrar de\n * uma preferência e rastrear alguém.\n *\n * Some quando a pessoa limpa o navegador, e isso está certo: uma máquina que\n * esqueceu tudo é uma máquina nova, e a preferência da conta assume.\n */\n\nconst STORAGE_KEY = 'fayz:device-id'\n\nlet cached: string | null = null\n\nfunction randomId(): string {\n try {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n } catch {\n // segue para o caminho de baixo\n }\n return `d-${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`\n}\n\n/**\n * O identificador desta máquina, criado na primeira vez que alguém pergunta.\n *\n * Devolve `undefined` quando não há onde guardar (modo privado, SSR). Nesse\n * caso a entrada cai na preferência da conta, que é a resposta certa: sortear\n * um identificador novo a cada carregamento encheria a tabela de dispositivos\n * que nunca mais voltam.\n */\nexport function getDeviceId(): string | undefined {\n if (cached) return cached\n try {\n if (typeof localStorage === 'undefined') return undefined\n const existing = localStorage.getItem(STORAGE_KEY)\n if (existing) {\n cached = existing\n return existing\n }\n const fresh = randomId()\n localStorage.setItem(STORAGE_KEY, fresh)\n cached = fresh\n return fresh\n } catch {\n return undefined\n }\n}\n","/**\n * Request deduplication — prevents duplicate in-flight requests with the same key.\n * If a request with the same key is already in-flight, returns the existing promise.\n *\n * O que se compartilha aqui é o RESULTADO da leitura, nunca o EFEITO dela.\n *\n * O mapa é global ao aplicativo e a chave é só a consulta — a loja que pediu\n * não entra nela. Quem chega em segundo recebe a MESMA promessa que já está no\n * ar, e a função passada NÃO roda de novo. Então escrever numa loja lá dentro\n * significa escrever na loja de QUEM CHEGOU PRIMEIRO, e quem chegou depois fica\n * com a tela vazia e a bandeira de carregando ligada para sempre.\n *\n * Isso não é caso de borda: o manifesto de um plugin é reconstruído com a\n * configuração da conta (ver `PluginRebuild`), e uma loja nova nasce com ele.\n *\n * // não\n * dedup(key, async () => { set({ rows: await api.list() }) })\n * // sim\n * set({ rows: await dedup(key, () => api.list()) })\n */\nconst inflight = new Map<string, Promise<any>>()\n\nexport function dedup<T>(key: string, fn: () => Promise<T>): Promise<T> {\n const existing = inflight.get(key)\n if (existing) return existing as Promise<T>\n\n const promise = fn().finally(() => {\n inflight.delete(key)\n })\n\n inflight.set(key, promise)\n return promise\n}\n","/**\n * Onde a pessoa entra, e por quê.\n *\n * Puro de propósito: é a única regra da entrada que decide alguma coisa, e uma\n * regra que só se observa abrindo o navegador é uma regra que ninguém revisa.\n * Nada aqui lê disco, rede ou relógio.\n */\n\n/** Por que a unidade ativa é a que é — o que a tela responde quando alguém\n * pergunta \"por que abriu na Ipanema?\". Sem isso a resolução automática vira\n * mágica, e mágica em cima de escopo de dado é o que faz gente desconfiar da\n * lista que está vendo. */\nexport type UnitEntryReason =\n | 'device' // esta máquina abriu esta unidade por último\n | 'account' // esta pessoa abriu esta unidade por último, em outro aparelho\n | 'only' // é a única que ela alcança\n | 'manual' // ela acabou de escolher\n | 'nearest' // ela pediu \"a mais perto\" e aceitou\n | 'all' // todas as unidades, por escolha ou por não haver o que decidir\n\n/** `set` distingue \"escolheu todas\" de \"nunca escolheu\". Sem essa diferença,\n * quem escolhe \"todas\" leva o palpite de volta na entrada seguinte, para\n * sempre — e a escolha dela nunca pega. */\nexport interface EntryPin {\n set: boolean\n unitId: string | null\n}\n\nexport interface EntryPins {\n device?: EntryPin\n account?: EntryPin\n /** O pino local anterior a tudo isto, lido uma vez para quem já usava não\n * perder a unidade na primeira atualização. */\n legacy?: string\n}\n\nexport interface EntryResolution {\n unitId: string | undefined\n reason: UnitEntryReason\n /** Alcança mais de uma unidade e nunca escolheu nenhuma: é o único caso em\n * que oferecer \"a mais perto de mim\" responde alguma coisa. */\n needsChoice: boolean\n}\n\n/**\n * A ordem não é arbitrária.\n *\n * A MÁQUINA vem antes da CONTA porque o computador do balcão fica na loja e a\n * pessoa não: o mesmo gerente abre o Leblon no celular de casa à noite e a\n * Ipanema no balcão de manhã, e o aparelho é o melhor sinal de qual das duas é\n * agora. Depois vem a aritmética — quem alcança uma unidade só não tem escolha\n * a fazer, e mostrar um seletor para ela é pedir trabalho para confirmar o\n * óbvio.\n *\n * Um pino fora do alcance é ignorado em silêncio, nunca corrigido com um aviso:\n * ele aparece quando alguém perdeu acesso a uma loja, e \"você não tem mais\n * acesso à Ipanema\" é uma conversa com o gerente, não um alerta na tela.\n *\n * NADA AQUI CONCEDE. Um pino aponta, e o Postgres decide — o pior que um erro\n * nesta função faz é esconder linha, que é chato, e nunca revelar uma.\n */\nexport function resolveEntry(reachable: string[], pins: EntryPins): EntryResolution {\n const canStand = (id: string | null | undefined) => id != null && reachable.includes(id)\n\n const ladder: Array<[EntryPin | undefined, UnitEntryReason]> = [\n [pins.device, 'device'],\n [pins.account, 'account'],\n ]\n for (const [pin, reason] of ladder) {\n if (!pin?.set) continue\n if (pin.unitId === null) return { unitId: undefined, reason: 'all', needsChoice: false }\n if (canStand(pin.unitId)) return { unitId: pin.unitId, reason, needsChoice: false }\n }\n\n if (canStand(pins.legacy)) return { unitId: pins.legacy, reason: 'device', needsChoice: false }\n\n if (reachable.length === 1) return { unitId: reachable[0], reason: 'only', needsChoice: false }\n\n // Ninguém é parado na porta. Alcançar quinze lojas e não ter dito qual é uma\n // resposta legítima — \"todas\" — e a oferta de escolher fica dentro do menu,\n // onde custa um clique de quem quiser e nada de quem não quiser.\n return { unitId: undefined, reason: 'all', needsChoice: reachable.length > 1 }\n}\n","import { create } from 'zustand'\nimport { setActiveUnitId, setUnitMode, resetActiveUnit, setScopedResources } from '@fayz-ai/core'\nimport { readOrgSnapshot } from '../org'\nimport type { Unit, UnitBinding } from './data'\nimport {\n fetchUnits, fetchMyBindings, fetchUnitMode, fetchScopedResources,\n fetchUnitBootstrap, saveEntryUnit,\n} from './data'\nimport { readUnitSnapshot, saveUnitSnapshot, patchUnitSnapshotActive, clearUnitSnapshot } from './cache'\nimport { getDeviceId } from './device'\nimport { dedup } from '../lib/dedup'\n\n/** O pino local anterior a este arquivo. Lido uma vez, para quem já usava não\n * perder a unidade na primeira atualização; nada novo escreve nele. */\nconst LEGACY_KEY = 'saas-core:current-location'\n\nimport { resolveEntry, type UnitEntryReason } from './entry'\n\nexport interface UnitNode extends Unit {\n children: UnitNode[]\n}\n\nexport type { UnitEntryReason }\n\ninterface UnitStore {\n units: Unit[]\n byId: Record<string, Unit>\n tree: UnitNode[]\n /** As unidades a que esta pessoa está vinculada, expandidas pela árvore. */\n myUnitIds: string[]\n myBindings: UnitBinding[]\n /** undefined = \"todas as unidades\". */\n activeUnitId: string | undefined\n entryReason: UnitEntryReason\n unitMode: boolean\n loading: boolean\n /** Já temos uma resposta — do retrato ou do servidor — e a tela pode desenhar\n * a linha de identidade em vez de um esqueleto. */\n resolved: boolean\n /** Alcança mais de uma unidade e nunca escolheu nenhuma: é o único caso em\n * que oferecer \"a mais perto de mim\" responde alguma coisa. */\n needsChoice: boolean\n loadedFor: string | null\n\n load: (tenantId: string, userId: string | undefined) => Promise<void>\n setActive: (unitId: string | undefined, reason?: UnitEntryReason) => void\n setMode: (on: boolean) => void\n reset: () => void\n}\n\nfunction legacyPin(): string | undefined {\n try {\n return localStorage.getItem(LEGACY_KEY) ?? undefined\n } catch {\n return undefined\n }\n}\n\nfunction buildTree(units: Unit[]): UnitNode[] {\n const nodes = new Map<string, UnitNode>()\n for (const u of units) nodes.set(u.id, { ...u, children: [] })\n const roots: UnitNode[] = []\n for (const node of nodes.values()) {\n const parent = node.parentId ? nodes.get(node.parentId) : undefined\n // Um pai que não está na lista (filtrado, ou uma aresta quebrada) não pode\n // engolir o filho — um órfão na raiz é visível e consertável, um sumido não\n // é nem uma coisa nem outra.\n if (parent && parent.id !== node.id) parent.children.push(node)\n else roots.push(node)\n }\n return roots\n}\n\n/** Um vínculo alcança tudo abaixo dele. Espelha `public.user_unit_ids()` — e só\n * decide o que o SELETOR oferece, nunca o que é lido. */\nfunction expandDown(units: Unit[], seeds: string[]): string[] {\n const childrenOf = new Map<string, string[]>()\n for (const u of units) {\n if (!u.parentId) continue\n const list = childrenOf.get(u.parentId) ?? []\n list.push(u.id)\n childrenOf.set(u.parentId, list)\n }\n const out = new Set<string>()\n const queue = [...seeds]\n while (queue.length > 0) {\n const id = queue.shift()!\n if (out.has(id)) continue\n out.add(id)\n for (const child of childrenOf.get(id) ?? []) queue.push(child)\n }\n return [...out]\n}\n\n/** Só uma filial pode ser habitada. Uma região é agrupamento — ficar \"dentro\"\n * dela significaria enumerar as filhas como filtro no navegador, que é a única\n * coisa que este desenho se recusa a fazer. */\nfunction branchesOnly(ids: string[], byId: Record<string, Unit>): string[] {\n return ids.filter((id) => byId[id]?.kind !== 'region')\n}\n\nexport const useUnitStore = create<UnitStore>((set, get) => ({\n units: [],\n byId: {},\n tree: [],\n myUnitIds: [],\n myBindings: [],\n activeUnitId: undefined,\n entryReason: 'all',\n unitMode: false,\n loading: false,\n resolved: false,\n needsChoice: false,\n loadedFor: null,\n\n // Uma chamada por conta, por mais telas que peçam.\n //\n // Dez componentes chamam `useUnitBootstrap` — o seletor, a linha de\n // identidade, o rodapé do registro, a aba de unidades de uma pessoa — e todos\n // montam no mesmo quadro. A guarda anterior era `loadedFor === tenantId &&\n // !loading`, que deixa passar exatamente enquanto a primeira chamada está no\n // ar: o segundo componente via a conta já marcada, via `loading` ligado, e a\n // condição inteira dava falso. Resultado: uma requisição por tela, todas\n // idênticas. Juntar cinco viagens numa e depois disparar essa uma cinco vezes\n // não economiza nada.\n //\n // `dedup` é o mesmo utilitário que a tela de equipe já usa: quem chegar\n // enquanto a primeira está no ar recebe a MESMA promessa em vez de abrir\n // outra.\n async load(tenantId, userId) {\n if (!tenantId) return\n if (get().loadedFor === tenantId && !get().loading) return\n return dedup(`units:${tenantId}:${userId ?? ''}`, () => loadOnce(tenantId, userId, set, get))\n },\n\n setActive(unitId, reason = 'manual') {\n // Sem recarregar a página. Trocar de CONTA — uma mudança de escopo\n // estritamente maior — já não recarrega; dois mecanismos para um conceito é\n // o bug. `setActiveUnitId` limpa o cache de leitura e acorda os inscritos.\n setActiveUnitId(unitId)\n set({ activeUnitId: unitId, entryReason: reason, needsChoice: false })\n patchUnitSnapshotActive(unitId ?? null)\n\n // O servidor guarda o hábito para a próxima máquina; o retrato local guarda\n // a pintura para o próximo carregamento. Silencioso: falhar em gravar uma\n // preferência não é assunto de quem só queria trocar de loja.\n const tenantId = get().loadedFor\n if (tenantId) void saveEntryUnit(tenantId, unitId, getDeviceId())\n },\n\n setMode(on) {\n setUnitMode(on)\n set({ unitMode: on })\n if (!on) {\n setActiveUnitId(undefined)\n set({ activeUnitId: undefined, entryReason: 'all', needsChoice: false })\n patchUnitSnapshotActive(null)\n }\n },\n\n reset() {\n clearUnitSnapshot()\n resetActiveUnit()\n set({\n units: [], byId: {}, tree: [], myUnitIds: [], myBindings: [],\n activeUnitId: undefined, entryReason: 'all', unitMode: false,\n loading: false, resolved: false, needsChoice: false, loadedFor: null,\n })\n },\n}))\n\ntype SetState = (partial: Partial<UnitStore>) => void\ntype GetState = () => UnitStore\n\nasync function loadOnce(\n tenantId: string,\n userId: string | undefined,\n set: SetState,\n get: GetState,\n): Promise<void> {\n set({ loading: true, loadedFor: tenantId })\n try {\n const deviceId = getDeviceId()\n\n // Uma viagem quando o pool tem a 045; as de antes quando não tem. Um app não\n // pode quebrar por causa de uma otimização, e a versão do banco não é\n // assunto da tela.\n const boot = await fetchUnitBootstrap(tenantId, deviceId)\n\n let mode: boolean\n let units: Unit[]\n let bindings: UnitBinding[]\n let scoped: Record<string, { unitColumn: string; shareable: boolean }>\n // O alcance dito pelo servidor (#018). `undefined` num pool sem a migration,\n // e aí a conta antiga a partir dos vínculos explícitos volta a valer.\n let reachableFromServer: string[] | undefined\n\n if (boot) {\n ;[mode, units, bindings, scoped] = [boot.mode, boot.units, boot.bindings, boot.scoped]\n reachableFromServer = boot.reachable\n } else {\n // O modo primeiro, e sozinho. As outras três perguntas só fazem sentido\n // se este pool tiver unidades: num pool sem a 039 as quatro saíam juntas\n // e três voltavam 404/400 — em toda entrada, para sempre, por uma\n // funcionalidade que aquele banco não tem.\n const modeResult = await fetchUnitMode(tenantId)\n mode = modeResult.on\n if (!modeResult.installed) {\n units = []\n bindings = []\n scoped = {}\n } else {\n // A árvore vem mesmo com o modo desligado: é ela que o cartão de ligar\n // unidades conta antes de alguém ligar. O registro de tabelas escopadas\n // não — sem escopo ligado ele não narra nada.\n ;[units, bindings, scoped] = await Promise.all([\n fetchUnits(tenantId),\n userId ? fetchMyBindings(userId, tenantId) : Promise.resolve([] as UnitBinding[]),\n mode ? fetchScopedResources() : Promise.resolve({}),\n ])\n }\n }\n\n // Publica a lista de tabelas escopadas do próprio banco, para uma entidade\n // não ter que lembrar de se inscrever e o cliente não poder discordar da\n // policy.\n setScopedResources(scoped)\n\n const byId: Record<string, Unit> = {}\n for (const u of units) byId[u.id] = u\n\n // QUEM DECIDE O ALCANCE É O SERVIDOR.\n //\n // A conta antiga partia dos vínculos EXPLÍCITOS (`membership_units`), e quem\n // alcança a conta inteira não tem nenhum: o alcance saía vazio, `resolveEntry`\n // não conseguia validar pino nenhum e a entrada caía em \"todas as unidades\"\n // toda vez. Ela fica como recuo para um pool que ainda não tem a 018.\n const reachable = reachableFromServer\n ? branchesOnly(reachableFromServer.filter((id) => byId[id]), byId)\n : branchesOnly(expandDown(units, bindings.map((b) => b.locationId)), byId)\n const entry = resolveEntry(reachable, {\n device: boot?.devicePin, account: boot?.accountPin, legacy: legacyPin(),\n })\n\n setUnitMode(mode)\n setActiveUnitId(entry.unitId)\n\n set({\n units, byId,\n tree: buildTree(units),\n myUnitIds: reachable,\n myBindings: bindings,\n unitMode: mode,\n activeUnitId: entry.unitId,\n entryReason: entry.reason,\n needsChoice: entry.needsChoice,\n loading: false,\n resolved: true,\n })\n\n if (userId) {\n saveUnitSnapshot({\n userId, tenantId, mode, units, bindings,\n myUnitIds: reachable,\n activeUnitId: entry.unitId ?? null,\n scoped,\n })\n }\n } finally {\n // Sem isto, uma falha no meio deixa `loading` ligado para sempre e a guarda\n // de \"já carreguei\" nunca mais fecha — cada tela que montar tenta de novo.\n if (get().loading) set({ loading: false })\n }\n}\n\n\n// ---------------------------------------------------------------------------\n// Hidratação, e por que ela roda aqui e não num efeito.\n//\n// Enquanto a unidade não resolve, a unidade ativa é \"nenhuma\" — e \"nenhuma\"\n// quer dizer TODAS. Um efeito roda depois do primeiro render, então a primeira\n// lista já saiu do forno mostrando as quinze lojas, e quando a resposta chega o\n// escopo muda, o cache é derrubado e toda consulta da tela refaz. O usuário vê\n// a mesma página duas vezes com conteúdos diferentes, e só a segunda está certa.\n//\n// Rodando na avaliação do módulo — antes do primeiro render, antes da primeira\n// consulta — a unidade já está resolvida quando a lista pergunta, e quando o\n// servidor confirma o mesmo valor `setActiveUnitId` sai cedo e nada refaz.\n// ---------------------------------------------------------------------------\n;(function hydrate() {\n const snapshot = readUnitSnapshot()\n if (!snapshot) return\n // O retrato é de uma conta; o app pode ter aberto em outra. Descartar é a\n // resposta certa — traduzir unidade entre contas não existe.\n const org = readOrgSnapshot()\n if (!org || org.org?.id !== snapshot.tenantId || org.userId !== snapshot.userId) {\n clearUnitSnapshot()\n return\n }\n\n const byId: Record<string, Unit> = {}\n for (const u of snapshot.units) byId[u.id] = u\n const active = snapshot.activeUnitId ?? undefined\n // Mesmo vindo do próprio disco, o pino só vale se a pessoa ainda alcança a\n // unidade. `load` vai reconfirmar contra o servidor logo em seguida.\n const standable = active && snapshot.myUnitIds.includes(active) ? active : undefined\n\n setScopedResources(snapshot.scoped)\n setUnitMode(snapshot.mode)\n setActiveUnitId(standable)\n\n useUnitStore.setState({\n units: snapshot.units,\n byId,\n tree: buildTree(snapshot.units),\n myUnitIds: snapshot.myUnitIds,\n myBindings: snapshot.bindings,\n unitMode: snapshot.mode,\n activeUnitId: standable,\n entryReason: standable ? 'device' : 'all',\n resolved: true,\n })\n})()\n","import * as React from 'react'\nimport { getSupabaseClientOptional, setHouseCurrency } from '@fayz-ai/core'\nimport { useUnitStore } from './store'\n\n/**\n * Keeps the house currency current: the unit the person is standing in, else\n * the tenant's. Mounted once by the workspace provider, so every screen — and\n * every plugin's `config.currency` — prints in it without asking.\n */\nexport function useHouseCurrencySync(orgId: string | undefined, tenantCurrency: string | undefined): void {\n const activeUnitId = useUnitStore((s) => s.activeUnitId)\n React.useEffect(() => {\n if (!orgId) { setHouseCurrency(null); return }\n setHouseCurrency(tenantCurrency ?? null)\n if (!activeUnitId) return\n let alive = true\n void unitCurrency(orgId, activeUnitId).then((code) => { if (alive && code) setHouseCurrency(code) })\n return () => { alive = false }\n }, [orgId, activeUnitId, tenantCurrency])\n}\n\nconst unitCurrencyCache = new Map<string, Promise<string | null>>()\nfunction unitCurrency(orgId: string, unitId: string): Promise<string | null> {\n const key = `${orgId}:${unitId}`\n let pending = unitCurrencyCache.get(key)\n if (!pending) {\n const client = getSupabaseClientOptional() as any\n pending = client\n ? Promise.resolve(client.rpc('my_unit_currency', { p_unit: unitId }))\n .then((res: { data?: unknown; error?: unknown }) => (res.error || typeof res.data !== 'string' ? null : res.data))\n .catch(() => null)\n : Promise.resolve(null)\n unitCurrencyCache.set(key, pending!)\n }\n return pending!\n}\n\n/** A unit's currency was changed on screen: the next read must not be the cached one. */\nexport function forgetUnitCurrency(): void {\n unitCurrencyCache.clear()\n}\n","import type { Organization, OrgMember, OrgMembership, PermissionProfile } from '@fayz-ai/core'\n\n/**\n * Snapshot of the org bootstrap (org + memberships + members + permission\n * profiles) so a page reload doesn't wait on the whole chain again.\n *\n * Every mount used to pay `acceptPendingInvites → listUserOrgs → getOrg →\n * listMembers + listProfiles` before `org.id` existed, and every screen keyed\n * off the tenant (Conectores, plugin tabs, permission gates) sat idle until\n * then. The snapshot paints that state synchronously and the network is only\n * touched again once it goes stale.\n */\n\nconst STORAGE_KEY = 'fayz:org-snapshot'\nconst VERSION = 1\n\n/** Served without touching the network. */\nexport const ORG_CACHE_TTL_MS = 5 * 60 * 1000\n/** Older than this and the snapshot is dropped instead of painted. */\nconst MAX_AGE_MS = 24 * 60 * 60 * 1000\n/** Bigger than this (huge member lists) and we skip persisting rather than blow the quota. */\nconst MAX_BYTES = 512 * 1024\n\nexport interface OrgSnapshot {\n version: number\n /** Who the snapshot belongs to — a different user gets a cold load. */\n userId: string\n /** When the data last came from the server (store patches don't move it). */\n savedAt: number\n org: Organization\n userOrgs: OrgMembership[]\n members: OrgMember[]\n profiles: PermissionProfile[]\n currentProfileId: string | null\n}\n\nexport type OrgSnapshotInput = Omit<OrgSnapshot, 'version' | 'savedAt'>\n\nfunction storage(): Storage | null {\n try {\n if (typeof localStorage === 'undefined') return null\n return localStorage\n } catch {\n return null\n }\n}\n\nexport function readOrgSnapshot(): OrgSnapshot | null {\n const store = storage()\n if (!store) return null\n try {\n const raw = store.getItem(STORAGE_KEY)\n if (!raw) return null\n const snapshot = JSON.parse(raw) as OrgSnapshot\n if (snapshot?.version !== VERSION || !snapshot.org?.id || !snapshot.userId) return null\n if (snapshotAge(snapshot) > MAX_AGE_MS) {\n store.removeItem(STORAGE_KEY)\n return null\n }\n return snapshot\n } catch {\n return null\n }\n}\n\nexport function snapshotAge(snapshot: OrgSnapshot): number {\n const age = Date.now() - snapshot.savedAt\n // A clock that moved backwards shouldn't hand out an eternally fresh cache.\n return age < 0 ? Number.POSITIVE_INFINITY : age\n}\n\nexport function isSnapshotFresh(snapshot: OrgSnapshot, ttlMs: number): boolean {\n return snapshotAge(snapshot) < ttlMs\n}\n\n/** Record a fresh server read — restarts the TTL window. */\nexport function saveOrgSnapshot(input: OrgSnapshotInput): void {\n write({ ...input, version: VERSION, savedAt: Date.now() })\n}\n\n/**\n * Keep the snapshot in step with store writes made outside the provider\n * (renaming the org in Settings, editing a role) WITHOUT restarting the TTL —\n * otherwise a UI-only change would push the next revalidation out forever.\n */\nexport function patchOrgSnapshot(input: OrgSnapshotInput): void {\n const current = readOrgSnapshot()\n if (!current || current.userId !== input.userId) return\n write({ ...input, version: VERSION, savedAt: current.savedAt })\n}\n\nexport function clearOrgSnapshot(): void {\n try {\n storage()?.removeItem(STORAGE_KEY)\n } catch {\n // ignore\n }\n}\n\nfunction write(snapshot: OrgSnapshot): void {\n const store = storage()\n if (!store) return\n try {\n const raw = JSON.stringify(snapshot)\n if (raw.length > MAX_BYTES) return\n store.setItem(STORAGE_KEY, raw)\n } catch {\n // Quota or serialization failure — the cache is an optimization, not state.\n }\n}\n","import * as React from 'react'\nimport { errorMessage, isImpersonating, type OrgAdapter, type Organization, type OrgMembership } from '@fayz-ai/core'\nimport { useAuthStore, readAppHandoff } from '@fayz-ai/auth'\nimport { useOrganizationStore, getPersistedOrgId } from './store'\nimport { decideWorkspaceChoice, getAutoPick, takeWorkspaceSwitch } from './choice'\nimport { usePermissionsStore } from '../permissions'\nimport { useHouseCurrencySync } from '../units/useHouseCurrencySync'\nimport {\n ORG_CACHE_TTL_MS,\n clearOrgSnapshot,\n isSnapshotFresh,\n patchOrgSnapshot,\n readOrgSnapshot,\n saveOrgSnapshot,\n type OrgSnapshot,\n} from './cache'\n\n// ---------------------------------------------------------------------------\n// Adapter context\n// ---------------------------------------------------------------------------\n\nconst OrgAdapterContext = React.createContext<OrgAdapter | null>(null)\n\nexport function useOrgAdapter(): OrgAdapter {\n const adapter = React.useContext(OrgAdapterContext)\n if (!adapter) {\n throw new Error('useOrgAdapter must be used within an <OrgProvider>')\n }\n return adapter\n}\n\nexport function useOrgAdapterOptional(): OrgAdapter | null {\n return React.useContext(OrgAdapterContext)\n}\n\n// ---------------------------------------------------------------------------\n// Tenant / org hook\n// ---------------------------------------------------------------------------\n\nexport interface TenantContext {\n /** The currently active organization */\n org: Organization | null\n /** All orgs the current user belongs to */\n userOrgs: OrgMembership[]\n loading: boolean\n /**\n * The bootstrap has finished at least once, so `org === null` now MEANS\n * \"belongs to no workspace\" instead of \"we have not looked yet\".\n *\n * `loading` cannot answer that: it starts `false`, before the effect that\n * loads anything has run. Anything deciding what to render from an empty org\n * — the setup gate — reads this, or it decides during the gap and flips its\n * mind a frame later.\n */\n settled: boolean\n /**\n * The membership list was actually READ for this account, and answered.\n *\n * Distinct from `settled`, which only says the wait is over — it is set in a\n * `finally`, so a failed `listUserOrgs` settles too. Anything that treats\n * \"no orgs\" as a FACT (the first-run setup gate) has to ask this instead.\n */\n orgsKnown: boolean\n /**\n * A leitura das contas FALHOU — e falhou é diferente de \"não tem nenhuma\".\n *\n * `orgsKnown: false` já dizia \"não sabemos\", mas dizia isso também no\n * instante antes de saber, então ninguém podia agir nele. Sem esta mensagem\n * um erro de rede chegava na tela como um sistema de uma linha só e um\n * seletor oferecendo \"criar área de trabalho\" — a resposta errada,\n * apresentada com a mesma cara da certa.\n */\n loadError: string | null\n /** Tenta ler as contas de novo, depois de uma falha. */\n retryOrgs: () => void\n /** Switch the active org */\n switchOrg: (orgId: string) => Promise<void>\n /** Refresh the current org from the adapter */\n refreshOrg: () => Promise<void>\n}\n\nconst TenantContext = React.createContext<TenantContext | null>(null)\n\n/**\n * Access the current tenant / organization.\n * Must be used inside <OrgProvider>.\n */\nexport function useTenant(): TenantContext {\n const ctx = React.useContext(TenantContext)\n if (!ctx) {\n throw new Error('useTenant must be used inside <OrgProvider>')\n }\n return ctx\n}\n\nexport function useTenantOptional(): TenantContext | null {\n return React.useContext(TenantContext)\n}\n\n// ---------------------------------------------------------------------------\n// Provider\n// ---------------------------------------------------------------------------\n\nexport interface OrgProviderProps {\n adapter: OrgAdapter\n /** When true, automatically creates an org if the user has none */\n autoCreate?: boolean\n /**\n * How long the cached org bootstrap is served before the provider goes back\n * to the network (default 5 min). A cached load paints synchronously, so\n * screens that key off `org.id` don't wait a round trip on every reload.\n * `0` disables the cache and restores the always-fetch behaviour.\n */\n cacheTtlMs?: number\n children: React.ReactNode\n}\n\nconst useIsomorphicLayoutEffect =\n typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect\n\nexport function OrgProvider({\n adapter,\n autoCreate = false,\n cacheTtlMs = ORG_CACHE_TTL_MS,\n children,\n}: OrgProviderProps) {\n const { user, isLoading: authLoading } = useAuthStore()\n const { currentOrg, userOrgs, loading, setCurrentOrg, paintCurrentOrg, setUserOrgs, setMembers, setLoading, reset } =\n useOrganizationStore()\n const setProfiles = usePermissionsStore((s) => s.setProfiles)\n const setCurrentProfile = usePermissionsStore((s) => s.setCurrentProfile)\n const setProfileKnownFor = usePermissionsStore((s) => s.setProfileKnownFor)\n\n const adapterRef = React.useRef(adapter)\n adapterRef.current = adapter\n\n const [snapshot] = React.useState<OrgSnapshot | null>(() =>\n cacheTtlMs > 0 ? readOrgSnapshot() : null,\n )\n // One load per signed-in user per mount — auth reports `isLoading` and `user`\n // in two separate store writes, so the effect would otherwise fire twice.\n const loadedForRef = React.useRef<string | null>(null)\n\n // WHOSE bootstrap has finished, not whether one has. A boolean could not tell\n // the difference between \"we know this account has no workspace\" and \"we knew\n // that about the account that just signed out\" — which is what flashed the\n // setup flow over every login: sign-out settled it, and sign-in kept the\n // stale `true` for the whole round trip.\n //\n // A painted snapshot is already an answer for its own user: that account HAS a\n // workspace, and revalidation will not turn that into \"has none\".\n const [settledFor, setSettledFor] = React.useState<string | null>(() =>\n snapshot?.org ? snapshot.userId : null,\n )\n // Same shape, different question: WHOSE membership list came back. Seeded\n // from a painted snapshot for the same reason — that account's list was read\n // once and cached, and revalidation cannot turn \"has one\" into \"has none\".\n const [orgsReadFor, setOrgsReadFor] = React.useState<string | null>(() =>\n snapshot?.org ? snapshot.userId : null,\n )\n // Signed out there is nothing to wait for; signed in, only this user's answer counts.\n const [loadError, setLoadError] = React.useState<string | null>(null)\n const [retryTick, setRetryTick] = React.useState(0)\n const retryOrgs = React.useCallback(() => {\n // `loadedForRef` é o que impede a releitura; zerá-lo é o que faz o efeito\n // abaixo rodar de novo para o mesmo usuário.\n loadedForRef.current = null\n setLoadError(null)\n setRetryTick((n) => n + 1)\n }, [])\n\n const settled = user ? settledFor === user.id : !authLoading\n const orgsKnown = !!user && orgsReadFor === user.id\n\n // Paint the last known org before the first child renders. The stores are\n // filled in a layout effect, so nothing gets a frame with `org === null`.\n useIsomorphicLayoutEffect(() => {\n if (!snapshot) return\n setUserOrgs(snapshot.userOrgs)\n // PINTA, não decide. Ver `paintCurrentOrg`: gravar o pino aqui fazia o\n // cache vencer a escolha, e a conta voltava sozinha a cada boot.\n paintCurrentOrg(snapshot.org)\n setMembers(snapshot.members)\n setProfiles(snapshot.profiles)\n setCurrentProfile(snapshot.profiles.find((p) => p.id === snapshot.currentProfileId) ?? null)\n // O snapshot É uma resposta: quem entra por ele já sabe quem é.\n setProfileKnownFor(snapshot.org.id)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n // Keep the snapshot in step with store writes made outside this provider —\n // renaming the org in Settings, editing a role — so the cache never serves a\n // value the user already changed on screen. Patching leaves `savedAt` alone:\n // a UI-only edit must not push the next revalidation further out.\n React.useEffect(() => {\n if (cacheTtlMs <= 0 || !user) return\n const uid = user.id\n const sync = () => {\n const org = useOrganizationStore.getState()\n if (!org.currentOrg) return\n const perms = usePermissionsStore.getState()\n patchOrgSnapshot({\n userId: uid,\n org: org.currentOrg,\n userOrgs: org.userOrgs,\n members: org.members,\n profiles: perms.profiles,\n // realProfile, not currentProfile: an impersonation preview is not\n // something to cache back as the user's own role.\n currentProfileId: perms.realProfile?.id ?? null,\n })\n }\n const unsubscribeOrg = useOrganizationStore.subscribe(sync)\n const unsubscribePerms = usePermissionsStore.subscribe(sync)\n return () => {\n unsubscribeOrg()\n unsubscribePerms()\n }\n }, [user?.id, cacheTtlMs])\n\n // Load the org's members + permission profiles into the shared stores whenever\n // an org resolves. This is what makes the role list, the invite dialog's role\n // dropdown, and permission checks work — previously nothing loaded them here,\n // so those surfaces came up empty. Also resolves the signed-in user's own role.\n const hydrateOrg = React.useCallback(\n async (org: Organization, memberships: OrgMembership[], uid: string | undefined) => {\n try {\n const [members, profiles] = await Promise.all([\n adapterRef.current.listMembers(org.id),\n adapterRef.current.listProfiles(org.id),\n ])\n setMembers(members)\n setProfiles(profiles)\n const myMembership = uid ? members.find((m) => m.userId === uid) : undefined\n const profile = profiles.find((p) => p.id === myMembership?.profileId) ?? null\n setCurrentProfile(profile)\n // Everything the next reload needs, stamped now — this is the only\n // place the TTL window restarts.\n if (cacheTtlMs > 0 && uid) {\n saveOrgSnapshot({\n userId: uid,\n org,\n userOrgs: memberships,\n members,\n profiles,\n currentProfileId: profile?.id ?? null,\n })\n }\n } catch {\n // Non-fatal — leave stores as-is if the load fails.\n } finally {\n // Respondida é respondida, mesmo que a resposta seja \"nenhum papel\" ou\n // que a leitura tenha falhado. Segurar a tela para sempre esperando uma\n // resposta que não vem é pior que mostrar o que se sabe.\n setProfileKnownFor(org.id)\n }\n },\n [setMembers, setProfiles, setCurrentProfile, setProfileKnownFor, cacheTtlMs],\n )\n\n // Load orgs when user is authenticated\n React.useEffect(() => {\n if (!user) {\n // A cold load reports `user === null` while the session hydrates — that's\n // not a sign-out, so the painted snapshot stands until auth settles.\n if (authLoading) return\n loadedForRef.current = null\n reset()\n clearOrgSnapshot()\n setSettledFor(null)\n setOrgsReadFor(null)\n return\n }\n\n const cached = snapshot?.userId === user.id ? snapshot : null\n\n // Already painted and still inside its window: skip the whole bootstrap.\n if (cached && isSnapshotFresh(cached, cacheTtlMs)) {\n setSettledFor(user.id)\n setOrgsReadFor(user.id)\n return\n }\n\n // A snapshot from another account was painted — drop it before loading.\n if (snapshot && snapshot.userId !== user.id && loadedForRef.current === null) {\n reset()\n clearOrgSnapshot()\n }\n\n if (loadedForRef.current === user.id) return\n loadedForRef.current = user.id\n\n // Stale but painted: revalidate quietly, so screens keep the data they're\n // showing instead of flipping back to a skeleton.\n const silent = !!cached\n\n let cancelled = false\n\n async function loadOrgs() {\n if (!silent) setLoading(true)\n try {\n // Redeem invites first — an invitee has no membership until this runs,\n // and without it autoCreate below would hand them a personal org\n // instead of the one that invited them.\n let accepted = 0\n try {\n // Viewing as someone must not redeem THEIR pending invites.\n if (!isImpersonating()) accepted = (await adapterRef.current.acceptPendingInvites?.()) ?? 0\n } catch {\n // Non-fatal: fall through and load whatever memberships exist.\n }\n\n if (cancelled) return\n\n let memberships = await adapterRef.current.listUserOrgs(user!.id)\n\n // An empty list right after accepting means the read was deduped onto a\n // request that started before the invite landed. Ask once more.\n if (memberships.length === 0 && accepted > 0) {\n memberships = await adapterRef.current.listUserOrgs(user!.id)\n }\n\n // UMA LISTA VAZIA É A ÚNICA RESPOSTA QUE MERECE DÚVIDA.\n //\n // Ela é a que decide se esta conta entra no aplicativo ou no fluxo de\n // criação de área de trabalho — e é também a única que a infraestrutura\n // consegue produzir por engano. A leitura passa por RLS: sem a sessão\n // ainda aplicada, a política simplesmente não casa com nenhuma linha e\n // a resposta é `200 []`, indistinguível de \"esta conta não tem nenhuma\".\n // Logo depois do login essa janela existe, e o sintoma é exatamente o\n // relatado: o assistente de criação aparece sozinho e some no refresh.\n //\n // Perguntar de novo é o único jeito de separar as duas. Custa duas\n // requisições e menos de um segundo, e só para quem de fato não tem\n // workspace nenhum — que é uma vez na vida da conta. O erro na outra\n // direção custa o aplicativo inteiro coberto por um fluxo do qual não\n // se sai.\n for (let attempt = 0; memberships.length === 0 && attempt < 2; attempt++) {\n await new Promise((resolve) => setTimeout(resolve, 250 * (attempt + 1)))\n if (cancelled) return\n memberships = await adapterRef.current.listUserOrgs(user!.id)\n }\n\n if (cancelled) return\n\n setUserOrgs(memberships)\n // The read answered. Everything after this can still fail without\n // turning \"this account has no workspace\" into a guess.\n setOrgsReadFor(user!.id)\n\n // Auto-create org if user has none\n if (memberships.length === 0 && accepted === 0 && autoCreate) {\n const newOrg = await adapterRef.current.createOrg(\n user!.fullName ? `${user!.fullName}'s Organization` : 'My Organization',\n user!.id,\n )\n if (!cancelled) {\n const ownMembership: OrgMembership[] = [\n {\n orgId: newOrg.id,\n orgName: newOrg.name,\n orgSlug: newOrg.slug,\n profileId: 'owner',\n profileName: 'Owner',\n },\n ]\n setUserOrgs(ownMembership)\n setCurrentOrg(newOrg)\n await hydrateOrg(newOrg, ownMembership, user!.id)\n }\n return\n }\n\n // Which workspace to open — or whether to open one at all. The ladder\n // lives in `decideWorkspaceChoice`; the only branch that changed shape\n // here is the last one. It used to be `?? memberships[0]`, which turned\n // \"we do not know which of your seven accounts you meant\" into a silent\n // guess the user could not see, let alone correct.\n const choice = decideWorkspaceChoice({\n memberships,\n // Consumed here, and only here: this is the one boot the marker was\n // written for, and leaving it behind would pin the next one too.\n switchingToId: takeWorkspaceSwitch(),\n handoffId: readAppHandoff()?.tenantId ?? null,\n pinnedId: getPersistedOrgId(),\n autoPick: getAutoPick(),\n })\n\n // Leaving `currentOrg` null IS the ask: the chooser gate reads exactly\n // this state — a membership list we have read, more than one row in it,\n // and no active workspace — so no extra flag has to be kept in sync.\n if (choice.kind !== 'resolved') return\n\n if (!cancelled) {\n const org = await adapterRef.current.getOrg(choice.orgId)\n if (!cancelled) {\n setCurrentOrg(org)\n await hydrateOrg(org, memberships, user!.id)\n }\n }\n } catch (err) {\n // Engolir aqui era o defeito: a lista ficava vazia, `orgsKnown` ficava\n // falso, e a tela não tinha como distinguir isso de uma conta nova.\n if (!cancelled) setLoadError(errorMessage(err))\n } finally {\n if (!cancelled && !silent) setLoading(false)\n // Settled even when the load threw: the answer is then \"we asked and\n // could not tell\", and holding the screen forever is worse than showing\n // the app. It is about the wait being over, not about success.\n if (!cancelled) setSettledFor(user!.id)\n }\n }\n\n void loadOrgs()\n\n return () => {\n cancelled = true\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [user?.id, authLoading, retryTick])\n\n async function switchOrg(orgId: string): Promise<void> {\n setLoading(true)\n try {\n const org = await adapterRef.current.getOrg(orgId)\n setCurrentOrg(org)\n await hydrateOrg(org, useOrganizationStore.getState().userOrgs, user?.id)\n } finally {\n setLoading(false)\n }\n }\n\n // Explicit refresh always goes to the network and restarts the cache window.\n async function refreshOrg(): Promise<void> {\n if (!currentOrg) return\n setLoading(true)\n try {\n const org = await adapterRef.current.getOrg(currentOrg.id)\n setCurrentOrg(org)\n await hydrateOrg(org, useOrganizationStore.getState().userOrgs, user?.id)\n } finally {\n setLoading(false)\n }\n }\n\n useHouseCurrencySync(currentOrg?.id, (currentOrg?.settings as { currency?: string } | undefined)?.currency)\n\n const tenantValue: TenantContext = {\n org: currentOrg,\n userOrgs,\n loading,\n settled,\n orgsKnown,\n loadError,\n retryOrgs,\n switchOrg,\n refreshOrg,\n }\n\n return (\n <OrgAdapterContext.Provider value={adapter}>\n <TenantContext.Provider value={tenantValue}>\n {children}\n </TenantContext.Provider>\n </OrgAdapterContext.Provider>\n )\n}\n","// ---------------------------------------------------------------------------\n// workspace-search — achar a conta numa lista que não cabe na tela.\n//\n// Com quinze contas o seletor já passava do rodapé: a lista empurrava \"Nova\n// área de trabalho\" e a seção de Unidades para fora da janela, e achar uma\n// conta virava rolar um menu procurando por reconhecimento visual. Numa rede de\n// franquias isso não é quinze, é duzentas.\n//\n// ── Por que um teto E uma busca, e não só um deles ─────────────────────────\n// Só teto esconde contas sem oferecer caminho. Só busca obriga a digitar mesmo\n// quando há três contas. Juntos: quem tem poucas contas nunca vê a caixa, e\n// quem tem muitas vê as primeiras e um campo — que é como todo seletor de conta\n// grande funciona.\n// ---------------------------------------------------------------------------\n\n/** Acima disto o seletor oferece busca. Abaixo, a lista inteira cabe. */\nexport const WORKSPACE_SEARCH_THRESHOLD = 8\n\n/** Quantas linhas o menu mostra de uma vez quando há busca. */\nexport const WORKSPACE_VISIBLE_LIMIT = 7\n\n/** Sem acento e sem caixa: quem procura \"Espaco\" tem de achar \"Espaço\". */\nexport function foldName(value: string): string {\n return value.normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase()\n}\n\nexport interface SearchableWorkspace {\n orgId: string\n orgName: string\n}\n\nexport interface WorkspaceSearchResult<T extends SearchableWorkspace> {\n /** As linhas a desenhar agora. */\n visible: T[]\n /** Quantas ficaram de fora do teto — 0 quando a lista coube inteira. */\n hidden: number\n /** A busca vale a pena nesta lista? */\n searchable: boolean\n}\n\n/**\n * Filtra e corta, mantendo a conta ATIVA sempre visível.\n *\n * Ela fica visível mesmo fora do teto e mesmo fora do filtro: o menu é também\n * onde se lê em que conta se está, e esconder a resposta dessa pergunta para\n * caber mais linha é trocar a pergunta principal pela secundária.\n */\nexport function searchWorkspaces<T extends SearchableWorkspace>(\n all: T[],\n query: string,\n currentId?: string | null,\n limit = WORKSPACE_VISIBLE_LIMIT,\n): WorkspaceSearchResult<T> {\n const searchable = all.length > WORKSPACE_SEARCH_THRESHOLD\n if (!searchable) return { visible: all, hidden: 0, searchable: false }\n\n const q = foldName(query.trim())\n const matched = q ? all.filter((w) => foldName(w.orgName).includes(q)) : all\n\n const current = all.find((w) => w.orgId === currentId)\n const head = current && !matched.includes(current) ? [current] : []\n const rest = matched.filter((w) => w.orgId !== current?.orgId)\n const ordered = current && matched.includes(current) ? [current, ...rest] : [...head, ...rest]\n\n return {\n visible: ordered.slice(0, limit),\n hidden: Math.max(0, ordered.length - limit),\n searchable: true,\n }\n}\n","import * as React from 'react'\nimport { OrgMark } from './OrgMark'\nimport type { OrgMembership } from '@fayz-ai/core'\nimport { useTranslation } from '@fayz-ai/core'\nimport { Button, Checkbox, cn, Input } from '@fayz-ai/ui'\nimport { Building2, Check } from 'lucide-react'\nimport { useTenant } from './context'\nimport { setAutoPick } from './choice'\nimport { searchWorkspaces } from './workspace-search'\n\nexport interface WorkspaceChooserProps {\n /** Every workspace this account can open in THIS app. */\n memberships: OrgMembership[]\n /** The last one this browser was in — pre-selected, not auto-entered. */\n suggestedId: string | null\n /** Present only when there is a workspace to go back to (the switcher route). */\n onCancel?: () => void\n}\n\n/**\n * \"Which of your workspaces?\" — asked once, on the way in.\n *\n * Deliberately a full screen rather than a dialog. Behind it the shell would be\n * rendering an account nobody has chosen yet, and every plugin on it would be\n * firing tenant-scoped requests against that guess; a dialog implies there is\n * something valid underneath, and there is not.\n */\nexport function WorkspaceChooser({ memberships, suggestedId, onCancel }: WorkspaceChooserProps) {\n const t = useTranslation()\n const tr = (key: string, fallback: string) => {\n const v = t(key)\n return !v || v === key ? fallback : v\n }\n\n const { switchOrg } = useTenant()\n const [selected, setSelected] = React.useState<string | null>(\n suggestedId ?? memberships[0]?.orgId ?? null,\n )\n // Off by default, deliberately, for as long as this flow is being validated:\n // asking every time is a second of friction, and silently opening the wrong\n // account is a support ticket. Opting out stays available; it is just not\n // something anyone gets handed without choosing it.\n const [remember, setRemember] = React.useState(false)\n const [query, setQuery] = React.useState('')\n // Teto MAIOR que o do menu: aqui a lista é a tela inteira, não um popover\n // espremido entre o gatilho e o rodapé.\n const search = React.useMemo(\n () => searchWorkspaces(memberships, query, selected, 12),\n [memberships, query, selected],\n )\n const [entering, setEntering] = React.useState(false)\n\n const enter = async (orgId: string) => {\n if (entering) return\n setEntering(true)\n // The preference is written BEFORE the switch: switchOrg re-renders this\n // component out of existence, so anything queued after it may never run.\n setAutoPick(remember)\n try {\n await switchOrg(orgId)\n } finally {\n setEntering(false)\n }\n }\n\n return (\n <div className=\"flex min-h-screen items-center justify-center bg-background p-4\">\n <div className=\"w-full max-w-md\">\n <div className=\"mb-6 text-center\">\n <h1 className=\"text-xl font-semibold text-foreground\">\n {tr('organization.chooseWorkspace', 'Escolha uma área de trabalho')}\n </h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {tr(\n 'organization.chooseWorkspaceDescription',\n 'Você tem acesso a mais de uma. Selecione em qual deseja entrar.',\n )}\n </p>\n </div>\n\n {/* A lista cresce com a rede de franquias; a tela, não. Ver\n ./workspace-search — e a mesma caixa está no seletor do rail, de\n propósito: é a mesma pergunta, feita antes e depois de entrar. */}\n {search.searchable && (\n <Input\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={tr('organization.searchWorkspace', 'Buscar conta…')}\n autoFocus\n wrapperClassName=\"mb-3\"\n className=\"rounded-lg border-border shadow-none focus:border-primary focus-visible:ring-0 focus-visible:ring-offset-0\"\n />\n )}\n\n <div\n role=\"radiogroup\"\n aria-label={tr('organization.workspaces', 'Workspaces')}\n className=\"space-y-2\"\n >\n {search.visible.length === 0 && (\n <p className=\"py-6 text-center text-sm text-muted-foreground\">\n {tr('organization.noWorkspaceMatch', 'Nenhuma conta com esse nome.')}\n </p>\n )}\n {search.visible.map((m) => {\n const isSelected = m.orgId === selected\n const isSuggested = m.orgId === suggestedId\n return (\n <Button\n variant=\"bare\"\n size=\"bare\"\n key={m.orgId}\n type=\"button\"\n role=\"radio\"\n aria-checked={isSelected}\n disabled={entering}\n onClick={() => setSelected(m.orgId)}\n // A double click should not have to become a click and a\n // journey down to the button.\n onDoubleClick={() => void enter(m.orgId)}\n className={cn(\n 'flex w-full items-center gap-3 rounded-lg border p-3 text-left transition-colors justify-start whitespace-normal text-[length:inherit] font-normal',\n 'disabled:opacity-60',\n isSelected\n ? 'border-primary bg-primary/5'\n : 'border-border hover:border-primary/50 hover:bg-muted/50',\n )}\n >\n <OrgMark name={m.orgName} logoUrl={m.orgLogoUrl} tone=\"popover\" className=\"h-9 w-9\" />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm font-medium text-foreground\">\n {m.orgName || m.orgSlug || m.orgId}\n </span>\n <span className=\"block truncate text-xs text-muted-foreground\">\n {m.profileName}\n {isSuggested && ` · ${tr('organization.lastUsed', 'último acesso')}`}\n </span>\n </span>\n {isSelected && <Check className=\"h-4 w-4 shrink-0 text-primary\" />}\n </Button>\n )\n })}\n </div>\n {search.hidden > 0 && (\n <p className=\"mt-3 text-center text-xs text-muted-foreground\">\n {tr('organization.moreWorkspaces', 'mais {n} — busque pelo nome').replace('{n}', String(search.hidden))}\n </p>\n )}\n\n {/* Not a <label>: Checkbox renders a <button>, and a label does not\n forward its click to one. The text carries its own handler instead,\n outside the button, so neither click double-toggles the other. */}\n <div className=\"mt-5 flex items-center gap-2.5 text-sm text-muted-foreground\">\n <Checkbox\n checked={remember}\n onChange={setRemember}\n disabled={entering}\n aria-label={tr('organization.rememberChoice', 'Não perguntar novamente neste dispositivo')}\n />\n <span className=\"cursor-pointer select-none\" onClick={() => !entering && setRemember(!remember)}>\n {tr('organization.rememberChoice', 'Não perguntar novamente neste dispositivo')}\n </span>\n </div>\n\n <div className=\"mt-5 flex gap-2\">\n {onCancel && (\n <Button variant=\"outline\" className=\"flex-1\" onClick={onCancel} disabled={entering}>\n {tr('common.cancel', 'Cancelar')}\n </Button>\n )}\n <Button\n className=\"flex-1\"\n disabled={!selected || entering}\n onClick={() => selected && void enter(selected)}\n >\n {entering ? tr('common.loading', 'Entrando…') : tr('organization.enter', 'Entrar')}\n </Button>\n </div>\n\n {/* The escape hatch for the checkbox above: somebody who ticked it and\n later needs a different workspace has to be told where the question\n went, or \"do not ask again\" reads as \"never again\". */}\n <p className=\"mt-4 text-center text-xs text-muted-foreground\">\n {tr(\n 'organization.switchLaterHint',\n 'Você pode trocar a qualquer momento pelo seletor no topo da tela.',\n )}\n </p>\n </div>\n </div>\n )\n}\n\n/** The workspace's face, at picker size: its logo, or its initials. */\n","import { useEffect, useState } from 'react'\nimport { getSupabaseClientOptional } from '../lib/supabase'\n\n/**\n * De quem é este endereço.\n *\n * Um inquilino com domínio próprio não deveria escolher conta: ele digitou o\n * endereço DELE. O seletor \"escolha uma área de trabalho\" é a resposta certa\n * para quem entra por `app.fayz.ai` com cinco contas; para quem entra por\n * `sistema.espacofacial.com.br` ele é uma pergunta cuja resposta já está na\n * barra de endereço.\n *\n * A porta é `tenant_branding_public`: anônima de propósito, porque a pergunta\n * vem ANTES da sessão — é ela que dá marca à tela de login e à loja pública.\n * Ela devolve só o recorte público (nome, slug, logo, cor, domínio); nada de\n * módulos, nada de ajustes, nada que não esteja na fachada do prédio.\n *\n * ── Em desenvolvimento ─────────────────────────────────────────────────────\n * `localhost` não tem domínio para resolver, então `?domain=` simula um. Só em\n * DEV: em produção o endereço é a única fonte, e um parâmetro que troca de\n * conta seria uma porta aberta na frente da casa.\n */\nexport interface DomainTenant {\n tenantId: string\n name: string | null\n slug: string | null\n logoUrl: string | null\n primaryColor: string | null\n}\n\nconst LOCAL = /^(localhost|127\\.0\\.0\\.1|\\[::1\\])$/\n\nexport function resolveHostname(): string | null {\n if (typeof window === 'undefined') return null\n const host = window.location.hostname\n if (!LOCAL.test(host)) return host\n if (!import.meta.env?.DEV) return null\n return new URLSearchParams(window.location.search).get('domain')\n}\n\nexport function useDomainTenant(): { tenant: DomainTenant | null; resolving: boolean } {\n const [tenant, setTenant] = useState<DomainTenant | null>(null)\n const [resolving, setResolving] = useState(true)\n\n useEffect(() => {\n const host = resolveHostname()\n const supabase = getSupabaseClientOptional()\n if (!host || !supabase) {\n setResolving(false)\n return\n }\n let cancelled = false\n void (async () => {\n try {\n const { data } = await supabase.rpc('tenant_branding_public', { p_domain: host })\n const row = data as Record<string, unknown> | null\n const id = typeof row?.tenant_id === 'string' ? row.tenant_id : null\n if (!cancelled && id) {\n setTenant({\n tenantId: id,\n name: (row?.name as string) ?? null,\n slug: (row?.slug as string) ?? null,\n logoUrl: (row?.logo_url as string) ?? null,\n primaryColor: (row?.primary_color as string) ?? null,\n })\n }\n } catch {\n // Um domínio que não resolve não é erro: é o caso comum de quem entra\n // pelo endereço do produto. O seletor segue sendo a resposta.\n } finally {\n if (!cancelled) setResolving(false)\n }\n })()\n return () => {\n cancelled = true\n }\n }, [])\n\n return { tenant, resolving }\n}\n","import * as React from 'react'\nimport { getPersistedOrgId } from './store'\nimport { useTenantOptional } from './context'\nimport { WorkspaceChooser } from './WorkspaceChooser'\nimport { useDomainTenant } from '../app/useDomainTenant'\n\nexport interface WorkspaceChooserGateProps {\n /** Held on screen while the membership list is still in flight. */\n fallback?: React.ReactNode\n children: React.ReactNode\n}\n\n/**\n * Puts the workspace picker in front of the shell when this account owes a\n * choice, and gets out of the way when it does not.\n *\n * There is no new state to keep: `decideWorkspaceChoice` already refuses to\n * pick for the provider in exactly this case, so \"a list we have read, more\n * than one row in it, and no active workspace\" IS the question being open.\n * A separate flag would be a second copy of that fact, free to disagree.\n *\n * Mounted between the setup gate and the shell: an account with NO workspace\n * belongs to the setup flow (there is nothing to choose from), and an account\n * with one never sees this at all.\n */\nexport function WorkspaceChooserGate({ fallback, children }: WorkspaceChooserGateProps) {\n const tenant = useTenantOptional()\n // Quem entra pelo PRÓPRIO domínio não escolhe conta: ele já respondeu a\n // pergunta na barra de endereço. Ver ../app/useDomainTenant.ts.\n const { tenant: byDomain, resolving: resolvingDomain } = useDomainTenant()\n const switchOrg = tenant?.switchOrg\n const entering = React.useRef(false)\n\n React.useEffect(() => {\n if (!byDomain || !tenant?.orgsKnown || tenant.org || !switchOrg || entering.current) return\n // Só entra se a pessoa for MEMBRO. O domínio diz de quem é a casa; quem\n // pode entrar continua sendo a membership — um endereço nunca concede\n // acesso, só escolhe entre as contas que já são dela.\n if (!tenant.userOrgs.some((m) => m.orgId === byDomain.tenantId)) return\n // Pelo MESMO caminho do seletor. Montar a organização à mão aqui deixava de\n // fora `settings` — e sem settings não há marca, não há tema, e o shell\n // ficava preso na moldura do bundle.\n entering.current = true\n void switchOrg(byDomain.tenantId)\n }, [byDomain, tenant?.orgsKnown, tenant?.org, tenant?.userOrgs, switchOrg])\n\n if (!tenant) return <>{children}</>\n\n const { org, userOrgs, orgsKnown, settled } = tenant\n\n // Already in a workspace — nothing to ask.\n if (org) return <>{children}</>\n\n // Hold rather than hand over, for the same reason the setup gate does: the\n // shell would paint an account-shaped app and fire every plugin's\n // tenant-scoped request against no tenant, then be replaced.\n if (!settled) return <>{fallback ?? null}</>\n\n // \"We asked and could not tell\" is not \"you have several\". Only a list we\n // actually read can raise this screen; anything else falls through to the\n // shell, which is where the existing empty-switcher behaviour already lives.\n if (!orgsKnown || userOrgs.length <= 1) return <>{children}</>\n\n // O domínio ainda está sendo resolvido, ou já resolveu numa conta que a\n // pessoa tem: segurar em vez de perguntar. Mostrar o seletor e trocá-lo por\n // uma conta um instante depois é a pergunta feita e respondida sozinha.\n if (resolvingDomain) return <>{fallback ?? null}</>\n if (byDomain && userOrgs.some((m) => m.orgId === byDomain.tenantId)) return <>{fallback ?? null}</>\n\n return (\n <WorkspaceChooser\n memberships={userOrgs}\n suggestedId={\n userOrgs.some((m) => m.orgId === getPersistedOrgId()) ? getPersistedOrgId() : null\n }\n />\n )\n}\n","import { create } from 'zustand'\nimport { clearOrgSnapshot } from './cache'\nimport { markWorkspaceSwitch } from './choice'\nimport { persistOrgId } from './store'\n\nexport interface SwitchTarget {\n orgId: string\n orgName: string\n /** So the transition shows the same mark the switcher row did. */\n orgLogoUrl?: string\n}\n\nexport interface WorkspaceSwitchingStore {\n /** The workspace being entered, while the transition is on screen. */\n target: SwitchTarget | null\n /** Commit to a workspace and raise the transition. Ends in a reload. */\n begin: (target: SwitchTarget) => void\n cancel: () => void\n}\n\n/**\n * Changing workspace, as a two-phase move: commit now, rebuild on the far side\n * of a reload.\n *\n * Switching in place was the alternative and it does not work. `switchOrg`\n * swaps the active tenant and re-hydrates the org, but every plugin store, the\n * offline cache and whatever screen is open still hold the PREVIOUS tenant's\n * rows, and nothing invalidates them centrally. The result is a shell that says\n * one workspace while the table under it lists another's — a tenant boundary\n * failure as far as anyone reading the screen is concerned, even though the\n * database never leaked a row.\n */\nexport const useWorkspaceSwitchingStore = create<WorkspaceSwitchingStore>((set) => ({\n target: null,\n\n begin: (target) => {\n // Order matters, and all three have to happen BEFORE the reload:\n // the marker — so the picker does not re-ask what was just answered\n // the pin — so \"last used\" is the workspace being entered\n // the snapshot— or the cached bootstrap of the OLD workspace paints\n // first on the far side and the switch silently undoes\n // itself.\n markWorkspaceSwitch(target.orgId)\n persistOrgId(target.orgId)\n clearOrgSnapshot()\n // ...e a paleta de boot, que é a QUARTA coisa que atravessa o reload.\n //\n // O `@fayz-ai/sdk` guarda a paleta resolvida para o boot seguinte pintar na\n // cor do aplicativo em vez de num cinza neutro. Numa troca de conta essa\n // paleta é a da conta ANTERIOR: sem limpá-la, o primeiro quadro do lado de\n // lá é a marca de quem se acabou de sair — e agora que a casca de boot\n // desenha a trilha, essa cor errada ocupa um quinto da tela.\n try { localStorage.removeItem('fayz:boot-theme') } catch { /* modo privado */ }\n set({ target })\n },\n\n cancel: () => set({ target: null }),\n}))\n","import * as React from 'react'\nimport { OrgMark } from './OrgMark'\nimport { useTranslation } from '@fayz-ai/core'\nimport { Check, ShieldCheck, Building2 } from 'lucide-react'\nimport { cn } from '@fayz-ai/ui'\n\n/** How long each step holds before the next one starts. */\nconst STEP_MS = 850\n\nexport interface WorkspaceSwitchingProps {\n /** The workspace being entered, named — the one fact that makes this concrete. */\n orgName: string\n /** Its logo, when it has one. */\n orgLogoUrl?: string\n /** Runs once the last step has been shown. Reloads the page, in practice. */\n onDone: () => void\n}\n\n/**\n * The screen between two workspaces.\n *\n * Changing tenant ends in a full reload, because half the app holds the old\n * tenant's rows in plugin stores and caches that nothing else invalidates. A\n * reload with no cover reads as a crash — the app blanks, comes back, and the\n * numbers are different. This covers it and says what is happening, so the\n * second it costs is spent visibly rather than suspiciously.\n *\n * Sized like a moment, not a toast: the workspace name is the largest thing on\n * screen because it is the answer to the only question anyone has here — where\n * am I about to be. The steps are honest about the order of operations, and the\n * last one is a security claim, so it gets an icon rather than another dot.\n */\nexport function WorkspaceSwitching({ orgName, orgLogoUrl, onDone }: WorkspaceSwitchingProps) {\n const t = useTranslation()\n const tr = (key: string, fallback: string) => {\n const v = t(key)\n return !v || v === key ? fallback : v\n }\n\n const steps = React.useMemo(\n () => [\n tr('organization.switching.step1', 'Alterando organização'),\n tr('organization.switching.step2', 'Garantindo segurança dos dados'),\n tr('organization.switching.step3', 'Carregando suas informações'),\n ],\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n )\n\n const [step, setStep] = React.useState(0)\n\n // One timer that advances, then hands over — not one timer per step, which\n // would leak a reload if the component unmounted between two of them.\n const doneRef = React.useRef(onDone)\n doneRef.current = onDone\n React.useEffect(() => {\n const id = window.setInterval(() => {\n setStep((s) => {\n if (s < steps.length - 1) return s + 1\n window.clearInterval(id)\n // Out of the interval callback: the reload tears down this tree, and\n // React does not want that happening inside a state updater.\n window.setTimeout(() => doneRef.current(), STEP_MS)\n return s\n })\n }, STEP_MS)\n return () => window.clearInterval(id)\n }, [steps.length])\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-label={`${steps[step]} — ${orgName}`}\n className=\"saas-switch-veil fixed inset-0 z-[100] flex items-center justify-center bg-background px-6\"\n >\n <div className=\"saas-switch-rise flex w-full max-w-sm flex-col items-center\">\n {/* The mark, with the loading indicator as a ring around it rather than\n a spinner beside it — one object doing both jobs. */}\n <div className=\"relative flex h-20 w-20 items-center justify-center\">\n <span\n aria-hidden\n className=\"saas-switch-pulse absolute inset-0 rounded-2xl bg-primary/25\"\n />\n <OrgMark name={orgName} logoUrl={orgLogoUrl} tone=\"popover\" className=\"h-16 w-16 rounded-2xl shadow-sm\" />\n </div>\n\n <p className=\"mt-7 text-xs font-medium uppercase tracking-[0.14em] text-muted-foreground\">\n {tr('organization.switching.eyebrow', 'Entrando em')}\n </p>\n {/* The largest thing here on purpose. Balanced leading and a wrap\n rather than an ellipsis: a truncated workspace name is exactly the\n reassurance this screen exists to give, cut in half. */}\n <h1 className=\"mt-1.5 text-pretty text-center text-3xl font-semibold leading-tight tracking-tight text-foreground sm:text-4xl\">\n {orgName}\n </h1>\n\n {/* Reserved height, top-aligned: the rows are written one at a time,\n and without a floor for the full list each arrival would shove the\n name and mark upward. The block stays put; only the list fills. */}\n <ul className=\"mt-9 flex w-full min-h-[7.5rem] flex-col items-start sm:min-h-[8.5rem]\">\n {steps.slice(0, step + 1).map((label, i) => {\n const done = i < step\n const isSecurity = i === 1\n return (\n <li key={label} className=\"saas-switch-step flex w-full gap-3\">\n {/* The rail: a thread down from the step above, then this\n step's own marker. */}\n <span className=\"flex w-6 shrink-0 flex-col items-center\">\n {i > 0 && (\n // Tinted, not `bg-border`: on a light surface the border\n // token is invisible at 1px, and this thread is the part\n // that makes three rows read as one advancing sequence\n // rather than three unrelated lines.\n <span aria-hidden className=\"saas-switch-link h-5 w-0.5 rounded-full bg-primary/30\" />\n )}\n <span className=\"flex h-7 w-6 items-center justify-center\">\n {done ? (\n <Check className=\"h-5 w-5 text-primary\" strokeWidth={2.5} />\n ) : isSecurity ? (\n <ShieldCheck className=\"saas-switch-dot h-5 w-5 text-primary\" strokeWidth={2} />\n ) : (\n <span className=\"saas-switch-dot h-2 w-2 rounded-full bg-primary\" />\n )}\n </span>\n </span>\n <span\n className={cn(\n 'flex h-7 items-center text-base transition-colors duration-300 sm:text-lg',\n // Only ever two states now — done, or happening. Nothing is\n // on screen before its turn, so there is no \"ahead\" tone.\n done ? 'text-muted-foreground' : 'font-medium text-foreground',\n // Push the label down past the connector so it stays level\n // with its own marker rather than with the thread above it.\n i > 0 && 'mt-5',\n )}\n >\n {label}\n </span>\n </li>\n )\n })}\n </ul>\n </div>\n </div>\n )\n}\n\n","import * as React from 'react'\nimport { useWorkspaceSwitchingStore } from './switching.store'\nimport { WorkspaceSwitching } from './WorkspaceSwitching'\n\n/**\n * Renders the workspace transition over whatever is on screen, and performs the\n * reload it exists to cover.\n *\n * Mounted once, high in the shell: the switch can be started from the topbar\n * picker or from anywhere else that grows one, and none of those places should\n * own a full-screen overlay.\n */\nexport function WorkspaceSwitchingHost() {\n const target = useWorkspaceSwitchingStore((s) => s.target)\n if (!target) return null\n\n return (\n <WorkspaceSwitching\n orgName={target.orgName}\n orgLogoUrl={target.orgLogoUrl}\n // A full reload, not a router navigation: the point is to discard every\n // plugin store and cache still holding the previous tenant's rows, and\n // only a fresh document does that. `reload()` keeps the current URL, so\n // whoever switched lands on the same screen in the new workspace.\n onDone={() => window.location.reload()}\n />\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/org/team-rows.ts","../src/directory/app-id.ts","../src/org/adapters/supabase.ts","../src/org/adapters/mock.ts","../src/org/choice.ts","../src/stores/app-config.store.ts","../src/org/OrgMark.tsx","../src/units/data.ts","../src/units/cache.ts","../src/units/device.ts","../src/lib/dedup.ts","../src/units/entry.ts","../src/units/store.ts","../src/units/useHouseCurrencySync.ts","../src/org/cache.ts","../src/org/context.tsx","../src/org/workspace-search.ts","../src/org/WorkspaceChooser.tsx","../src/app/useDomainTenant.ts","../src/org/WorkspaceChooserGate.tsx","../src/org/switching.store.ts","../src/org/WorkspaceSwitching.tsx","../src/org/WorkspaceSwitchingHost.tsx"],"names":["capitalize","slugify","React","getSupabaseClientOptional","STORAGE_KEY","dedup","create","React2","client","VERSION","MAX_AGE_MS","MAX_BYTES","storage","cached","jsx","React4","jsxs","cn","useState","useEffect","React5","useTranslation","React6","Check"],"mappings":"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","file":"chunk-EOYE3ZAC.js","sourcesContent":["import type { TeamPerson } from '@fayz-ai/core'\n\n/** A `people` row as the team query selects it. */\nexport interface TeamPeopleRow {\n id: string\n name?: string | null\n kind?: string | null\n email?: string | null\n avatar_url?: string | null\n is_active?: boolean | null\n}\n\n/** A `tenant_members` row as the team query selects it. */\nexport interface TeamMemberRow {\n id: string\n user_id: string\n role?: string | null\n person_id?: string | null\n created_at?: string | null\n}\n\n/** A `profiles` row for a member's login. */\nexport interface TeamProfileRow {\n id: string\n full_name?: string | null\n email?: string | null\n avatar_url?: string | null\n}\n\n/** The signed-in user, used to name their own row when `profiles` has no row for them. */\nexport interface TeamCurrentUser {\n id: string\n email?: string | null\n fullName?: string | null\n}\n\nconst capitalize = (s: string) => (s ? s.charAt(0).toUpperCase() + s.slice(1) : s)\n\n/**\n * Fallback display name for a login with no person record. `profiles` is not\n * guaranteed to have a row (accounts created before the trigger, seeded demos),\n * and its RLS only ever exposes your own — so the session is the last resort for\n * your own row, and the email handle the one after that.\n */\nfunction loginName(profile: TeamProfileRow | undefined, session: TeamCurrentUser | undefined): string {\n const candidates = [profile?.full_name, session?.fullName, profile?.email, session?.email]\n for (const candidate of candidates) {\n const value = candidate?.trim()\n if (value) return value.includes('@') ? value.split('@')[0] : value\n }\n return ''\n}\n\n/**\n * Merges the two halves of the team into one list.\n *\n * People of the configured kinds are the roster; `tenant_members` is the access\n * overlay linked by `person_id`. But a login is not required to have a person\n * record — the owner who created the workspace never gets one — and dropping\n * those rows left the Team screen empty for every account that had not staffed\n * itself as a person. So memberships that match no listed person come back as\n * rows of their own, named from their login profile and carrying no `personId`.\n * Logins come first: whoever holds access is the answer to \"who is my team?\"\n * before the roster of people who may never sign in.\n */\nexport function buildTeamRows(\n people: TeamPeopleRow[],\n members: TeamMemberRow[],\n profiles: TeamProfileRow[],\n currentUser?: TeamCurrentUser | null,\n): TeamPerson[] {\n const personIds = new Set(people.map((p) => p.id))\n const byPerson = new Map<string, TeamMemberRow>()\n const unlinked: TeamMemberRow[] = []\n\n for (const m of members) {\n if (m.person_id && personIds.has(m.person_id)) byPerson.set(m.person_id, m)\n else unlinked.push(m)\n }\n\n const profileById = new Map(profiles.map((p) => [p.id, p]))\n\n const toMembership = (m: TeamMemberRow) => ({\n memberId: m.id,\n userId: m.user_id,\n profileId: (m.role as string) ?? '',\n profileName: capitalize((m.role as string) ?? ''),\n joinedAt: m.created_at ?? undefined,\n })\n\n const loginRows: TeamPerson[] = unlinked.map((m) => {\n const profile = profileById.get(m.user_id)\n const session = currentUser && currentUser.id === m.user_id ? currentUser : undefined\n return {\n name: loginName(profile, session),\n email: profile?.email ?? session?.email ?? undefined,\n avatarUrl: profile?.avatar_url ?? undefined,\n isActive: true,\n membership: toMembership(m),\n }\n })\n\n const personRows: TeamPerson[] = people.map((p) => {\n const m = byPerson.get(p.id)\n return {\n personId: p.id,\n name: p.name ?? '',\n kind: p.kind ?? undefined,\n email: p.email ?? undefined,\n avatarUrl: p.avatar_url ?? undefined,\n isActive: p.is_active ?? true,\n membership: m ? toMembership(m) : undefined,\n }\n })\n\n return [...loginRows, ...personRows]\n}\n","/**\n * Which application THIS bundle is.\n *\n * The switcher needs it for one thing only: to know which tile is the one you\n * are already looking at. Everything else about an app — its name, icon, colour\n * and URL — comes from the `app.apps` registry, so a rename is a row and not a\n * release.\n *\n * Until now the only identity an app carried was `VITE_FAYZ_PROJECT_ID`, a\n * platform project uuid. That is a poor answer to \"which product is this\": the\n * ids for the shop already disagree between the app's own `.env` and the\n * platform's seed script, and nothing would have caught it, because a uuid does\n * not look wrong. `VITE_APP_ID` is the registry key instead — it matches\n * `app.apps.id`, and a typo shows up as \"nothing is highlighted\" on the first\n * run rather than as a wrong tile months later.\n *\n * Unset is a legitimate answer: the switcher lists every app the account runs\n * and highlights none, which is right for a bundle nobody has claimed yet.\n */\nexport function resolveAppId(): string | null {\n const env = (import.meta as unknown as { env?: Record<string, string | undefined> }).env\n const id = env?.VITE_APP_ID ?? env?.PUBLIC_APP_ID\n const trimmed = id?.trim()\n return trimmed ? trimmed : null\n}\n","import type {\n OrgAdapter,\n Organization,\n OrgMember,\n OrgMembership,\n TeamPerson,\n CreateOrgOptions,\n Location,\n Invite,\n} from '@fayz-ai/core'\nimport type { PermissionProfile, SystemPermission, AuthAdapter } from '@fayz-ai/core'\nimport { getFayzSupabaseClient } from '../../data/client'\nimport { buildTeamRows } from '../team-rows'\nimport { resolveAppId } from '../../directory/app-id'\nimport type { TeamMemberRow, TeamPeopleRow, TeamProfileRow } from '../team-rows'\n\n// ---------------------------------------------------------------------------\n// Request dedup — prevents duplicate in-flight requests (React StrictMode etc.)\n// ---------------------------------------------------------------------------\n\nconst inflightRequests = new Map<string, Promise<unknown>>()\n\nfunction dedup<T>(key: string, fn: () => Promise<T>): Promise<T> {\n const existing = inflightRequests.get(key)\n if (existing) return existing as Promise<T>\n\n const promise = fn().finally(() => {\n inflightRequests.delete(key)\n })\n inflightRequests.set(key, promise)\n return promise\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction slugify(name: string): string {\n return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')\n}\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1)\n}\n\nfunction mapTenantToOrg(row: Record<string, unknown>): Organization {\n return {\n id: row['id'] as string,\n name: row['name'] as string,\n slug: row['slug'] as string,\n logoUrl: (row['logo_url'] as string | null) ?? undefined,\n verticalId: (row['vertical_id'] as string | null) ?? undefined,\n plan: (row['plan'] as string | null) ?? undefined,\n trialEndsAt: (row['trial_ends_at'] as string | null) ?? undefined,\n settings: (row['settings'] as Record<string, unknown> | null) ?? undefined,\n createdAt: row['created_at'] as string,\n updatedAt: row['updated_at'] as string,\n }\n}\n\n/**\n * Como um login ganha nome.\n *\n * Era só `public.profiles` — e num pool onde essa tabela está VAZIA (nenhum\n * gatilho a preencheu) a tela de Equipe inteira aparecia sem nome nenhum: seis\n * linhas com \"?\" no avatar e a coluna do membro em branco. Quem é a pessoa por\n * trás de um acesso é a pergunta que essa tela existe para responder.\n *\n * A ficha ligada à associação (`person_id`, sempre preenchida desde a #120)\n * responde melhor e é dado da própria conta: nome e e-mail que a equipe\n * mantém, não uma cópia do provedor de identidade. `profiles` fica como\n * complemento — é de lá que vem o avatar.\n */\nasync function namesForLogins(\n rows: Array<Record<string, unknown>>,\n db: { from: (table: string) => any },\n): Promise<Map<string, Record<string, unknown>>> {\n const out = new Map<string, Record<string, unknown>>()\n if (rows.length === 0) return out\n\n const userIds = rows.map((r) => r['user_id'] as string).filter(Boolean)\n const personIds = rows.map((r) => r['person_id'] as string | null).filter(Boolean) as string[]\n\n const [profilesResult, peopleResult] = await Promise.all([\n userIds.length ? db.from('profiles').select('id, full_name, avatar_url, email').in('id', userIds) : Promise.resolve({ data: [] }),\n personIds.length ? db.from('people').select('id, name, email, avatar_url, kind').in('id', personIds) : Promise.resolve({ data: [] }),\n ])\n\n const byProfile = new Map(\n ((profilesResult?.data ?? []) as Array<Record<string, unknown>>).map((p) => [p['id'] as string, p]),\n )\n const byPerson = new Map(\n ((peopleResult?.data ?? []) as Array<Record<string, unknown>>).map((p) => [p['id'] as string, p]),\n )\n\n for (const row of rows) {\n const userId = row['user_id'] as string\n const profile = byProfile.get(userId)\n const person = byPerson.get(row['person_id'] as string)\n out.set(userId, {\n id: userId,\n full_name: person?.['name'] ?? profile?.['full_name'] ?? '',\n email: person?.['email'] ?? profile?.['email'] ?? '',\n avatar_url: profile?.['avatar_url'] ?? person?.['avatar_url'] ?? null,\n // Viaja junto para a tela poder RESOLVER a rota da ficha: o registro de\n // rotas é indexado por `arquétipo:kind`, e sem o kind o \"abrir a ficha\"\n // não sabe para onde ir.\n kind: person?.['kind'] ?? null,\n })\n }\n return out\n}\n\nfunction mapMemberRow(row: Record<string, unknown>): OrgMember {\n const profile = (row['profile'] as Record<string, unknown>) ?? {}\n return {\n id: row['id'] as string,\n userId: row['user_id'] as string,\n orgId: row['tenant_id'] as string,\n profileId: row['role'] as string,\n profileName: capitalize(row['role'] as string),\n personId: (row['person_id'] as string | null) ?? undefined,\n personKind: (profile['kind'] as string | null) ?? undefined,\n user: {\n id: row['user_id'] as string,\n email: (profile['email'] as string) ?? '',\n fullName: (profile['full_name'] as string) ?? '',\n avatarUrl: (profile['avatar_url'] as string | null) ?? undefined,\n },\n // tenant_members has no `joined_at` column — it's `created_at`.\n joinedAt: (row['joined_at'] ?? row['created_at']) as string,\n }\n}\n\nfunction mapLocationRow(row: Record<string, unknown>): Location {\n return {\n id: row['id'] as string,\n tenantId: row['tenant_id'] as string,\n name: row['name'] as string,\n address: (row['address'] as string | null) ?? undefined,\n city: (row['city'] as string | null) ?? undefined,\n state: (row['state'] as string | null) ?? undefined,\n country: (row['country'] as string | null) ?? undefined,\n phone: (row['phone'] as string | null) ?? undefined,\n isHeadquarters: (row['is_headquarters'] as boolean) ?? false,\n isActive: (row['is_active'] as boolean) ?? true,\n createdAt: row['created_at'] as string,\n updatedAt: row['updated_at'] as string,\n }\n}\n\nfunction mapInviteRow(row: Record<string, unknown>): Invite {\n return {\n id: row['id'] as string,\n orgId: row['tenant_id'] as string,\n email: row['email'] as string,\n profileId: row['role'] as string,\n profileName: capitalize(row['role'] as string),\n invitedBy: row['invited_by'] as string,\n token: row['token'] as string,\n status: (row['status'] as Invite['status']) ?? 'pending',\n createdAt: row['created_at'] as string,\n expiresAt: row['expires_at'] as string,\n }\n}\n\n/** Minimal role identity the adapter needs to build profiles. Grants come from\n * the DB catalog; id/name/order/description come from what the app declares. */\nexport interface RoleIdentity {\n id: string\n name: string\n description?: string\n /** System roles are app-defined and static (not user-editable). Custom roles\n * (duplicated by users, stored in app.roles) are false. Defaults true. */\n isSystem?: boolean\n /** The app's declared grants; used to create the role in a tenant that lacks it. */\n grants?: Record<string, string[]>\n}\n\n// Matrix emits read/create/edit/delete; map back to DB action verbs. The\n// catalog spells the write verb `edit` — `update` matched no key, so any\n// matrix save with an edit box ticked was refused as an unknown permission.\nconst DB_ACTION: Record<string, string> = {\n read: 'read', create: 'create', edit: 'edit', write: 'create', manage: 'manage', delete: 'delete',\n}\n\n// Every working role needs these to load the tenant at all.\nconst SESSION_BASELINE = ['config.read', 'tenancy.read', 'tenant.read', 'units.read']\n\n// Matrix grants → catalog keys. Alias features go back to their canonical\n// domain, and features the catalog does not know are dropped: they gate\n// nothing server-side, and one unknown key makes role_set_permissions refuse\n// the whole set.\nexport function grantsToDbKeys(grants: Record<string, string[]>, catalog: Set<string>): string[] {\n const canonicalOf = new Map<string, string>()\n for (const [canonical, aliases] of Object.entries(FEATURE_ALIASES)) {\n for (const alias of aliases) canonicalOf.set(alias, canonical)\n }\n const keys = new Set<string>()\n for (const [feature, actions] of Object.entries(grants)) {\n for (const action of actions) {\n const verb = DB_ACTION[action] ?? action\n const direct = `${feature}.${verb}`\n const viaAlias = canonicalOf.has(feature) ? `${canonicalOf.get(feature)}.${verb}` : undefined\n if (catalog.has(direct)) keys.add(direct)\n else if (viaAlias && catalog.has(viaAlias)) keys.add(viaAlias)\n }\n }\n return [...keys]\n}\n\nfunction slugifyRole(name: string): string {\n return name.toLowerCase().normalize('NFD').replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') || 'role'\n}\n\n// Fallback role set when the host app declares none. The SDK is domain-agnostic:\n// each app defines its OWN business roles (a salon's roles ≠ an agency's) via\n// config.permissions.defaultProfiles. These five are only a back-compat default.\nconst DEFAULT_ROLES: RoleIdentity[] = [\n { id: 'owner', name: 'Owner' },\n { id: 'admin', name: 'Admin' },\n { id: 'manager', name: 'Manager' },\n { id: 'staff', name: 'Staff' },\n { id: 'viewer', name: 'Viewer' },\n]\n\n// DB permission ids that confer an org-management system permission.\n// The catalog names these `members.*` / `roles.*` / `settings.manage`; the\n// `team.*` / `settings.update` spellings never existed in it, which left the\n// Team and Permissions tabs owner-only even for Admin.\nconst SYSTEM_PERMISSION_MAP: Record<string, SystemPermission> = {\n 'members.manage': 'manage_team',\n 'roles.manage': 'manage_permissions',\n 'billing.manage': 'manage_billing',\n 'settings.manage': 'manage_settings',\n}\nconst ALL_SYSTEM_PERMISSIONS: SystemPermission[] = ['manage_team', 'manage_billing', 'manage_settings', 'manage_permissions']\n\n// The database names shared business domains; older UI surfaces still use\n// product-facing feature ids. Keep both until every plugin speaks the canonical\n// vocabulary so a valid database grant cannot hide an otherwise available page.\nconst FEATURE_ALIASES: Record<string, string[]> = {\n people: ['registry.customers', 'registry.suppliers'],\n catalog: ['services'],\n}\n\n// Map DB permission ids to feature action grants\nexport function buildPermissionProfiles(\n roles: RoleIdentity[],\n permissions: Array<{ id: string; category: string }>,\n rolePerms: Array<{ role: string; permission_id: string }>,\n overrides: Array<{ role: string; permission_id: string; granted: boolean }>,\n): PermissionProfile[] {\n const overrideMap = new Map<string, boolean>()\n for (const o of overrides) {\n overrideMap.set(`${o.role}:${o.permission_id}`, o.granted)\n }\n\n // The role SET comes from what the app declares — the SDK no longer bakes it in.\n const rolePermMap = new Map<string, Set<string>>()\n for (const r of roles) {\n rolePermMap.set(r.id, new Set())\n }\n // Convention: an 'owner' role (if declared) gets every permission implicitly.\n if (rolePermMap.has('owner')) {\n for (const p of permissions) rolePermMap.get('owner')!.add(p.id)\n }\n for (const rp of rolePerms) {\n rolePermMap.get(rp.role)?.add(rp.permission_id)\n }\n\n // Apply overrides\n for (const [key, granted] of overrideMap) {\n const colonIdx = key.indexOf(':')\n const role = key.slice(0, colonIdx)\n const permId = key.slice(colonIdx + 1)\n const perms = rolePermMap.get(role)\n if (!perms) continue\n if (granted) {\n perms.add(permId)\n } else {\n perms.delete(permId)\n }\n }\n\n // Align DB actions with the matrix's action vocabulary (read/create/edit/delete).\n //\n // `manage` IS KEPT, not folded into `edit`. profileHasPermission answers\n // `actions.includes(action) || actions.includes('manage')` — manage is the\n // wildcard that implies the rest. Collapsing it here destroyed that meaning\n // BEFORE the engine ever saw it: a role granted `financial.manage` stored\n // `['edit']`, which contains neither `read` nor `manage`, so the Financeiro\n // role could not open the Financeiro module — the nav gates on `read`. Same\n // for every other `X.manage` grant in the catalog.\n const actionMap: Record<string, string> = {\n read: 'read',\n create: 'create',\n update: 'edit',\n manage: 'manage',\n delete: 'delete',\n configure: 'edit',\n invite: 'create',\n }\n\n return roles.map(({ id: role, name, description, isSystem }) => {\n const permIds = rolePermMap.get(role)!\n const features: Record<string, string[]> = {}\n\n for (const permId of permIds) {\n // LAST dot, not the first: a feature id may contain dots (plugin-crm\n // declares `crm.leads`), an action never does. Splitting on the first one\n // read `crm.leads.read` as feature `crm` + action `leads.read`, which no\n // action map knows — so every dotted feature the matrix granted came back\n // empty on the next load, silently.\n const dotIdx = permId.lastIndexOf('.')\n if (dotIdx <= 0) continue\n const category = permId.slice(0, dotIdx)\n const action = permId.slice(dotIdx + 1)\n // A verb outside the CRUD map is a special action (`workforce.adjust_time`,\n // `financial.amend`): kept under its own name so a matrix save sends it\n // back instead of silently revoking it.\n const mappedAction = actionMap[action] ?? action\n\n for (const feature of [category, ...(FEATURE_ALIASES[category] ?? [])]) {\n if (!features[feature]) features[feature] = []\n if (!features[feature].includes(mappedAction)) {\n features[feature].push(mappedAction)\n }\n }\n }\n\n // Org-management system permissions, derived from team/billing/settings\n // grants (owner gets all four). These gate the Equipe/Permissões tabs.\n const systemPermissions: SystemPermission[] = []\n const source = role === 'owner' ? ALL_SYSTEM_PERMISSIONS : [...permIds].map((id) => SYSTEM_PERMISSION_MAP[id])\n for (const sp of source) {\n if (sp && !systemPermissions.includes(sp)) systemPermissions.push(sp)\n }\n\n return {\n id: role,\n name: name || capitalize(role),\n description,\n isSystem: isSystem ?? true,\n systemPermissions,\n grants: features,\n }\n })\n}\n\n// ---------------------------------------------------------------------------\n// Adapter factory\n// ---------------------------------------------------------------------------\n\nexport interface SupabaseOrgAdapterConfig {\n /** Deprecated — core tables now live in the public schema; this field is ignored. */\n coreSchema?: string\n /** Business roles the host app declares (config.permissions.defaultProfiles).\n * Falls back to the generic five when omitted. */\n roles?: RoleIdentity[]\n /** Auth adapter used to actually DELIVER invites (send the e-mail + create the\n * auth user) — the org adapter only records the audit row. Injected by the app;\n * when omitted, invites are recorded but not delivered. */\n authAdapter?: AuthAdapter\n /** Canonical, deployment-fixed origin baked into invite/magic-link redirects\n * (e.g. https://beauty-saas.live.fayz.ai). The container injects it as\n * VITE_APP_URL; the app wiring passes it here. Falls back to\n * window.location.origin, which is wrong when an admin invites from a preview\n * or localhost origin. Note: whatever origin ends up here must ALSO be in the\n * Supabase project's Redirect URLs allow-list, or Supabase silently swaps it\n * for its Site URL (default http://localhost:3000). */\n siteUrl?: string\n}\n\nexport function createSupabaseOrgAdapter(config?: SupabaseOrgAdapterConfig): OrgAdapter {\n const roles: RoleIdentity[] = config?.roles && config.roles.length > 0 ? config.roles : DEFAULT_ROLES\n const authAdapter = config?.authAdapter\n const originBase =\n config?.siteUrl?.replace(/\\/+$/, '') ??\n (typeof window !== 'undefined' ? window.location.origin : undefined)\n const inviteRedirectTo = originBase ? `${originBase}/` : undefined\n\n function supabase() {\n return getFayzSupabaseClient()\n }\n\n function core() {\n return supabase()\n }\n\n async function catalogKeys(): Promise<Set<string>> {\n const { data, error } = await core().from('v_authz_permissions').select('key')\n if (error) throw error\n return new Set(((data ?? []) as Array<{ key: string }>).map((p) => p.key))\n }\n\n // The picker offers every role the APP declares, but app.roles is per tenant\n // and only holds what its seed template wrote. Inviting into or editing a\n // declared role the tenant never got failed with \"unknown role key\"; create\n // it from the app's declared grants the first time it is used.\n async function ensureRole(orgId: string, key: string): Promise<string> {\n const found = await core()\n .from('v_authz_roles').select('id')\n .eq('tenant_id', orgId).eq('key', key).maybeSingle()\n if (found.error) throw found.error\n if (found.data) return (found.data as { id: string }).id\n\n const declared = roles.find((r) => r.id === key)\n if (!declared) throw new Error(`Profile not found: ${key}`)\n\n const existing = await core().from('v_authz_roles').select('key, is_system').eq('tenant_id', orgId)\n if (existing.error) throw existing.error\n const rows = (existing.data ?? []) as Array<{ key: string; is_system: boolean }>\n const seed = rows.find((r) => r.key === 'viewer')?.key ?? rows.find((r) => r.is_system && r.key !== 'owner')?.key\n if (!seed) throw new Error('ensureRole: the tenant has no role to clone from')\n\n const created = await core().rpc('role_create_from_template', {\n p_role_key: key,\n p_name: declared.name,\n p_template_role: seed,\n p_template: null,\n p_description: declared.description ?? null,\n })\n if (created.error) throw created.error\n const roleId = created.data as string\n\n const catalog = await catalogKeys()\n const keys = [\n ...SESSION_BASELINE.filter((k) => catalog.has(k)),\n ...grantsToDbKeys(declared.grants ?? {}, catalog),\n ]\n const set = await core().rpc('role_set_permissions', { p_role_id: roleId, p_keys: [...new Set(keys)] })\n if (set.error) throw set.error\n return roleId\n }\n\n return {\n async acceptPendingInvites(): Promise<number> {\n const { data, error } = await supabase().rpc('accept_pending_invitations')\n if (error) {\n // A pool still on the pre-022 spine has no such function. Not fatal —\n // the user just lands org-less, exactly as before this shipped.\n console.warn('[org] accept_pending_invitations failed:', error.message)\n return 0\n }\n return typeof data === 'number' ? data : 0\n },\n\n async listUserOrgs(userId: string): Promise<OrgMembership[]> {\n return dedup(`listUserOrgs:${userId}`, async () => {\n const { data, error } = await core()\n .from('v_team_members')\n .select('tenant_id, role, tenant:tenants(id, name, slug, logo_url)')\n .eq('user_id', userId)\n\n if (error) throw error\n\n let rows = (data ?? []) as Array<Record<string, unknown>>\n\n // Narrow to the accounts that run THIS app (008). A beauty account\n // listed inside the restaurant product is not a shortcut — it opens a\n // rail whose screens its data cannot fill. The app you are looking at\n // is the bundle's own fact (VITE_APP_ID); the database cannot infer it,\n // because one account may run several apps at once.\n //\n // Best-effort on purpose: no app id, no view (a pool predating 008), or\n // any error at all leaves the list exactly as it was. Hiding an account\n // because a filter failed is worse than showing one too many.\n const appId = resolveAppId()\n if (appId && rows.length > 1) {\n const { data: scoped, error: scopeError } = await core()\n .from('v_tenant_apps')\n .select('tenant_id')\n .eq('app_id', appId)\n if (!scopeError && Array.isArray(scoped)) {\n const runsThisApp = new Set(scoped.map((r) => (r as { tenant_id: string }).tenant_id))\n const kept = rows.filter((row) => runsThisApp.has(row['tenant_id'] as string))\n // An empty result would leave the person with no workspace at all\n // and no way to say so; the unfiltered list is the safer answer.\n if (kept.length > 0) rows = kept\n }\n }\n\n // Every field here is nullable in practice and none of them is worth\n // the whole list. A pool on the pre-014 spine answers this query with\n // `tenant` and `role` NULL — the workspace picker has to read across\n // accounts, and until 014 the policies on public.tenants and app.roles\n // were scoped to the account you had not chosen yet. `capitalize(null)`\n // threw, took listUserOrgs with it, and left a seven-workspace account\n // looking at \"you belong to none\". A missing name is a bad row; it is\n // not a reason to lose the six good ones next to it.\n return rows.map((row) => {\n const tenant = (row['tenant'] as Record<string, unknown> | null) ?? {}\n const role = (row['role'] as string | null) ?? ''\n return {\n orgId: row['tenant_id'] as string,\n orgName: (tenant['name'] as string) ?? '',\n orgSlug: (tenant['slug'] as string) ?? '',\n orgLogoUrl: (tenant['logo_url'] as string | null) ?? undefined,\n profileId: role,\n profileName: capitalize(role),\n }\n })\n })\n },\n\n async getOrg(orgId: string): Promise<Organization> {\n const { data, error } = await core()\n .from('tenants')\n .select('*')\n .eq('id', orgId)\n .single()\n\n if (error) throw error\n return mapTenantToOrg(data as Record<string, unknown>)\n },\n\n async createOrg(name: string, userId: string, options?: CreateOrgOptions): Promise<Organization> {\n const { data: tenant, error } = await supabase()\n .rpc('create_tenant_with_owner', {\n p_name: name,\n p_slug: slugify(name),\n p_user_id: userId,\n p_vertical_id: options?.verticalId ?? null,\n p_plan: 'free',\n p_settings: {\n timezone: options?.timezone ?? 'America/Sao_Paulo',\n currency: options?.currency ?? 'BRL',\n locale: options?.locale ?? 'pt-BR',\n teamSize: options?.teamSize ?? undefined,\n branding: options?.branding ?? {},\n },\n })\n\n if (error) throw error\n return mapTenantToOrg(tenant as Record<string, unknown>)\n },\n\n async updateOrg(orgId: string, updates: Partial<Organization>): Promise<Organization> {\n const row: Record<string, unknown> = {}\n if (updates.name !== undefined) row['name'] = updates.name\n if (updates.slug !== undefined) row['slug'] = updates.slug\n if (updates.logoUrl !== undefined) row['logo_url'] = updates.logoUrl\n if (updates.verticalId !== undefined) row['vertical_id'] = updates.verticalId\n if (updates.plan !== undefined) row['plan'] = updates.plan\n if (updates.settings !== undefined) row['settings'] = updates.settings\n\n const { data, error } = await core()\n .from('tenants')\n .update(row)\n .eq('id', orgId)\n .select()\n .single()\n\n if (error) throw error\n return mapTenantToOrg(data as Record<string, unknown>)\n },\n\n async listMembers(orgId: string): Promise<OrgMember[]> {\n const { data, error } = await core()\n .from('v_team_members')\n .select('*')\n .eq('tenant_id', orgId)\n\n if (error) throw error\n\n const rows = (data ?? []) as Array<Record<string, unknown>>\n const profileMap = await namesForLogins(rows, core())\n\n return rows.map((row) => {\n const profile = profileMap.get(row['user_id'] as string) ?? {}\n return mapMemberRow({ ...row, profile })\n })\n },\n\n // Person-first team list: people of `personKinds` are the roster and\n // `tenant_members` (login + role) is the overlay linked by person_id — plus\n // every membership that links to no listed person, so an account with access\n // is never missing from its own Team screen. See buildTeamRows.\n async listTeam(orgId: string, personKinds: string[]): Promise<TeamPerson[]> {\n if (!personKinds || personKinds.length === 0) return []\n\n const [peopleResult, membersResult] = await Promise.all([\n core()\n .from('people')\n .select('id, name, kind, email, avatar_url, is_active')\n .eq('tenant_id', orgId)\n .in('kind', personKinds)\n // Only people still on the roster. `not is false` rather than\n // `eq true` so a row that never set the flag stays visible — the\n // same `?? true` reading buildTeamRows applies. A deactivated\n // person who still holds a login does not vanish: their membership\n // stops matching a listed person and comes back as a login row,\n // which is the invariant that keeps access auditable.\n .not('is_active', 'is', false),\n core()\n .from('v_team_members')\n .select('id, user_id, role, person_id, created_at')\n .eq('tenant_id', orgId),\n ])\n if (peopleResult.error) throw peopleResult.error\n\n const people = (peopleResult.data ?? []) as TeamPeopleRow[]\n const members = (membersResult.data ?? []) as TeamMemberRow[]\n\n // Login-only rows are named from the person their membership points at,\n // falling back to the auth profile (see namesForLogins — `profiles` is\n // empty in some pools, which left this whole screen nameless). The\n // session is the last fallback, and only for your own row.\n const [nameMap, sessionResult] = await Promise.all([\n namesForLogins(members as unknown as Array<Record<string, unknown>>, core()),\n core().auth.getSession(),\n ])\n\n const sessionUser = sessionResult?.data?.session?.user\n const currentUser = sessionUser\n ? {\n id: sessionUser.id,\n email: sessionUser.email,\n fullName: (sessionUser.user_metadata?.['full_name'] as string | undefined) ?? undefined,\n }\n : null\n\n return buildTeamRows(people, members, [...nameMap.values()] as unknown as TeamProfileRow[], currentUser)\n },\n\n // Verbs, not writes into the projection: v_team_members is a JOINed view\n // and accepts neither UPDATE nor DELETE, and each RPC checks the permission\n // in one place. `_orgId` stays in the signature for the adapter contract —\n // the RPCs take the tenant from the session, not from a parameter.\n async updateMemberProfile(orgId: string, memberId: string, profileId: string): Promise<void> {\n await ensureRole(orgId, profileId)\n // member_set_role refuses to demote the last owner. This screen cannot\n // know it was the last one, which is exactly why the check moved.\n const { error } = await core().rpc('member_set_role', { p_membership: memberId, p_role: profileId })\n if (error) throw error\n },\n\n async removeMember(_orgId: string, memberId: string): Promise<void> {\n const { error } = await core().rpc('member_remove', { p_membership: memberId })\n if (error) throw error\n },\n\n // #136 moved authorization into app.*, reachable through the v_authz_*\n // views (security_invoker, so RLS still decides what a caller sees) and a\n // small set of RPCs. The four public mirrors this used to read and write —\n // permissions, role_permissions, tenant_roles, tenant_role_overrides — are\n // dropped by @fayz-ai/db 003.\n //\n // The RPCs take the tenant from the SESSION, not a parameter, so orgId is\n // asserted against the active tenant rather than passed down: writing to\n // one org while another is active was never possible and should fail\n // loudly rather than silently touch the wrong one.\n async listProfiles(orgId: string): Promise<PermissionProfile[]> {\n const [permsResult, rolesResult, grantsResult] = await Promise.all([\n core().from('v_authz_permissions').select('key, plugin'),\n core().from('v_authz_roles').select('id, key, name, description, is_system').eq('tenant_id', orgId),\n core().from('v_authz_role_permissions').select('role_id, permission').eq('tenant_id', orgId),\n ])\n\n if (permsResult.error) throw permsResult.error\n if (rolesResult.error) throw rolesResult.error\n if (grantsResult.error) throw grantsResult.error\n\n const dbRoles = (rolesResult.data ?? []) as Array<{\n id: string; key: string; name: string; description: string | null; is_system: boolean\n }>\n const keyOf = new Map(dbRoles.map((r) => [r.id, r.key]))\n\n // The app still declares its own role SET; the database now supplies the\n // custom ones a tenant created. A system role the DB knows and the app\n // does not is still shown — it holds grants either way.\n const declared: RoleIdentity[] = roles.map((r) => ({ ...r, isSystem: true }))\n const declaredIds = new Set(declared.map((r) => r.id))\n const fromDb: RoleIdentity[] = dbRoles\n .filter((r) => !declaredIds.has(r.key))\n .map((r) => ({ id: r.key, name: r.name, description: r.description ?? undefined, isSystem: r.is_system }))\n\n // app.role_permissions is per TENANT, so every grant is that tenant's own.\n // The global defaults table this used to read was documented as always\n // empty and measured empty in every pool, so there is no third source to\n // merge — the grants go in as overrides and the base layer is bare.\n const overrides = ((grantsResult.data ?? []) as Array<{ role_id: string; permission: string }>)\n .flatMap((g) => {\n const role = keyOf.get(g.role_id)\n return role ? [{ role, permission_id: g.permission, granted: true }] : []\n })\n\n return buildPermissionProfiles(\n [...declared, ...fromDb],\n ((permsResult.data ?? []) as Array<{ key: string; plugin: string }>)\n .map((p) => ({ id: p.key, category: p.plugin })),\n [],\n overrides,\n )\n },\n\n async createProfile(\n orgId: string,\n profile: Omit<PermissionProfile, 'id' | 'isSystem'>,\n ): Promise<PermissionProfile> {\n const existingRoles = await core().from('v_authz_roles').select('key, is_system').eq('tenant_id', orgId)\n if (existingRoles.error) throw existingRoles.error\n const rows = (existingRoles.data ?? []) as Array<{ key: string; is_system: boolean }>\n const existing = new Set(rows.map((r) => r.key))\n\n let key = slugifyRole(profile.name)\n if (existing.has(key) || roles.some((r) => r.id === key)) {\n let n = 2\n while (existing.has(`${key}-${n}`) || roles.some((r) => r.id === `${key}-${n}`)) n++\n key = `${key}-${n}`\n }\n\n // role_create_from_template always clones something — there is no \"empty\n // role\" verb. Cloning the narrowest role available and then setting the\n // grants explicitly lands on exactly the requested set either way, and\n // never on a role that briefly held more than it should.\n const seed = rows.find((r) => r.is_system && r.key === 'viewer')?.key\n ?? rows.find((r) => r.is_system)?.key\n ?? rows[0]?.key\n if (!seed) throw new Error('createProfile: the tenant has no role to clone from')\n\n const created = await core().rpc('role_create_from_template', {\n p_role_key: key,\n p_name: profile.name,\n p_template_role: seed,\n p_template: null,\n p_description: profile.description ?? null,\n })\n if (created.error) throw created.error\n const roleId = created.data as string\n\n const catalog = await catalogKeys()\n // Without the baseline a role made here cannot even load its tenant.\n const keys = [...new Set([...grantsToDbKeys(profile.grants ?? {}, catalog), ...SESSION_BASELINE.filter((k) => catalog.has(k))])]\n const set = await core().rpc('role_set_permissions', { p_role_id: roleId, p_keys: keys })\n if (set.error) throw set.error\n\n const profiles = await this.listProfiles(orgId)\n return profiles.find((p) => p.id === key) ?? {\n id: key, name: profile.name, description: profile.description, isSystem: false,\n systemPermissions: profile.systemPermissions ?? [], grants: profile.grants ?? {},\n }\n },\n\n async updateProfile(\n orgId: string,\n profileId: string,\n data: Partial<PermissionProfile>,\n ): Promise<PermissionProfile> {\n // The RPCs address a role by its uuid; the matrix addresses it by key.\n await ensureRole(orgId, profileId)\n const found = await core()\n .from('v_authz_roles').select('id, name, description, is_system')\n .eq('tenant_id', orgId).eq('key', profileId).maybeSingle()\n if (found.error) throw found.error\n if (!found.data) throw new Error(`Profile not found: ${profileId}`)\n const role = found.data as { id: string; name: string; description: string | null; is_system: boolean }\n\n if (data.name !== undefined || data.description !== undefined) {\n const { error } = await core().rpc('role_rename', {\n p_role_id: role.id,\n p_name: data.name ?? role.name,\n // Explicit, not coalesced: role_rename treats NULL as \"clear it\", so\n // an untouched description has to be sent back as it was.\n p_description: data.description !== undefined ? (data.description ?? null) : role.description,\n })\n if (error) throw error\n }\n\n if (data.grants) {\n const catalog = await catalogKeys()\n const keys = [...new Set([...grantsToDbKeys(data.grants, catalog), ...SESSION_BASELINE.filter((k) => catalog.has(k))])]\n // One call, not delete-then-insert: role_set_permissions reconciles to\n // the given set inside one transaction, so the role is never briefly\n // holding nothing.\n const { error } = await core().rpc('role_set_permissions', { p_role_id: role.id, p_keys: keys })\n if (error) throw error\n }\n\n const profiles = await this.listProfiles(orgId)\n const updated = profiles.find((p) => p.id === profileId)\n if (!updated) throw new Error(`Profile not found: ${profileId}`)\n return updated\n },\n\n async deleteProfile(orgId: string, profileId: string): Promise<void> {\n const found = await core()\n .from('v_authz_roles').select('id, is_system')\n .eq('tenant_id', orgId).eq('key', profileId).maybeSingle()\n if (found.error) throw found.error\n if (!found.data) throw new Error('System roles cannot be deleted.')\n const role = found.data as { id: string; is_system: boolean }\n if (role.is_system) throw new Error('System roles cannot be deleted.')\n\n // role_delete refuses a role an active member still holds, and says how\n // many. That refusal is the point: it used to demote them silently.\n const { error } = await core().rpc('role_delete', { p_role_id: role.id })\n if (error) throw error\n },\n\n async listInvites(orgId: string): Promise<Invite[]> {\n const { data, error } = await core()\n .from('invitations')\n .select('*')\n .eq('tenant_id', orgId)\n .order('created_at', { ascending: false })\n\n if (error) throw error\n return ((data ?? []) as Array<Record<string, unknown>>).map(mapInviteRow)\n },\n\n async createInvite(orgId: string, email: string, profileId: string, invitedBy: string): Promise<Invite> {\n await ensureRole(orgId, profileId)\n const { data, error } = await core()\n .from('invitations')\n .insert({\n tenant_id: orgId,\n email,\n role: profileId,\n invited_by: invitedBy,\n })\n .select()\n .single()\n\n if (error) throw error\n // Deliver via the auth abstraction (sends the e-mail + creates the auth user,\n // stamping tenant_id/role on its metadata for the accept-time membership trigger).\n await authAdapter?.inviteUser?.(email, {\n redirectTo: inviteRedirectTo,\n data: { tenant_id: orgId, role: profileId, invited_by: invitedBy },\n })\n return mapInviteRow(data as Record<string, unknown>)\n },\n\n async bulkInvite(orgId: string, emails: string[], profileId: string, invitedBy: string): Promise<Invite[]> {\n await ensureRole(orgId, profileId)\n const rows = emails.map((email) => ({\n tenant_id: orgId,\n email,\n role: profileId,\n invited_by: invitedBy,\n }))\n\n const { data, error } = await core().from('invitations').insert(rows).select()\n if (error) throw error\n await Promise.all(\n emails.map((email) =>\n authAdapter?.inviteUser?.(email, {\n redirectTo: inviteRedirectTo,\n data: { tenant_id: orgId, role: profileId, invited_by: invitedBy },\n }),\n ),\n )\n return ((data ?? []) as Array<Record<string, unknown>>).map(mapInviteRow)\n },\n\n async revokeInvite(orgId: string, inviteId: string): Promise<void> {\n const { error } = await core()\n .from('invitations')\n .update({ status: 'revoked' })\n .eq('id', inviteId)\n .eq('tenant_id', orgId)\n\n if (error) throw error\n },\n\n async resendInvite(orgId: string, inviteId: string): Promise<Invite> {\n const { data, error } = await core()\n .from('invitations')\n .update({\n status: 'pending',\n expires_at: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),\n })\n .eq('id', inviteId)\n .eq('tenant_id', orgId)\n .select()\n .single()\n\n if (error) throw error\n const row = data as Record<string, unknown>\n // Re-send the invite e-mail through the auth abstraction.\n await authAdapter?.inviteUser?.(row.email as string, {\n redirectTo: inviteRedirectTo,\n data: { tenant_id: orgId, role: row.role as string, invited_by: row.invited_by as string },\n })\n return mapInviteRow(row)\n },\n\n async listLocations(orgId: string): Promise<Location[]> {\n const { data, error } = await core()\n .from('v_units')\n .select('*')\n .eq('tenant_id', orgId)\n .order('is_headquarters', { ascending: false })\n .order('name')\n\n if (error) throw error\n return ((data ?? []) as Array<Record<string, unknown>>).map(mapLocationRow)\n },\n\n async createLocation(\n orgId: string,\n input: {\n name: string\n address?: string\n city?: string\n state?: string\n country?: string\n phone?: string\n isHeadquarters?: boolean\n },\n ): Promise<Location> {\n const { data, error } = await core()\n .rpc('unit_create', {\n p_name: input.name,\n p_kind: input.isHeadquarters ? 'hq' : 'branch',\n p_parent_unit: null,\n // app.units keeps a unit's contact details in metadata; v_units reads\n // them back out under the flat names this screen already uses.\n p_metadata: {\n address: input.address ?? null,\n city: input.city ?? null,\n state: input.state ?? null,\n country: input.country ?? 'BR',\n phone: input.phone ?? null,\n },\n })\n\n if (error) throw error\n const created = await core().from('v_units').select('*').eq('id', data as string).single()\n if (created.error) throw created.error\n return mapLocationRow(created.data as Record<string, unknown>)\n },\n }\n}\n","import type {\n OrgAdapter,\n Organization,\n OrgMember,\n OrgMembership,\n CreateOrgOptions,\n Location,\n Invite,\n} from '@fayz-ai/core'\nimport type { PermissionProfile } from '@fayz-ai/core'\n\nconst STORAGE_KEY = 'fayz:mock-orgs'\n\ninterface MockOrgData {\n orgs: Organization[]\n members: OrgMember[]\n profiles: Record<string, PermissionProfile[]>\n invites: Record<string, Invite[]>\n userOrgMap: Record<string, string[]>\n}\n\nfunction getStored(): MockOrgData {\n try {\n if (typeof localStorage === 'undefined') return empty()\n const raw = localStorage.getItem(STORAGE_KEY)\n if (raw) return JSON.parse(raw) as MockOrgData\n } catch {\n // ignore\n }\n return empty()\n}\n\nfunction empty(): MockOrgData {\n return { orgs: [], members: [], profiles: {}, invites: {}, userOrgMap: {} }\n}\n\nfunction setStored(data: MockOrgData): void {\n try {\n if (typeof localStorage === 'undefined') return\n localStorage.setItem(STORAGE_KEY, JSON.stringify(data))\n } catch {\n // ignore\n }\n}\n\nfunction slugify(name: string): string {\n return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')\n}\n\nexport function createMockOrgAdapter(defaultProfiles?: PermissionProfile[]): OrgAdapter {\n function seedOrgForUser(userId: string, userName?: string): MockOrgData {\n const data = getStored()\n if (data.userOrgMap[userId]?.length) return data\n\n const orgId = crypto.randomUUID()\n const memberId = crypto.randomUUID()\n const firstProfile = defaultProfiles?.[0]\n\n const org: Organization = {\n id: orgId,\n name: 'My Organization',\n slug: 'my-organization',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n }\n\n const member: OrgMember = {\n id: memberId,\n userId,\n orgId,\n profileId: firstProfile?.id ?? 'owner',\n profileName: firstProfile?.name ?? 'Owner',\n user: {\n id: userId,\n email: userName\n ? `${userName.toLowerCase().replace(/\\s+/g, '.')}@example.com`\n : 'user@example.com',\n fullName: userName ?? 'Current User',\n },\n joinedAt: new Date().toISOString(),\n }\n\n data.orgs.push(org)\n data.members.push(member)\n data.userOrgMap[userId] = [orgId]\n if (defaultProfiles) {\n data.profiles[orgId] = [...defaultProfiles]\n }\n data.invites[orgId] = []\n\n setStored(data)\n return data\n }\n\n return {\n async listUserOrgs(userId: string): Promise<OrgMembership[]> {\n const data = seedOrgForUser(userId)\n const orgIds = data.userOrgMap[userId] ?? []\n return orgIds.map((orgId) => {\n const org = data.orgs.find((o) => o.id === orgId)!\n const member = data.members.find((m) => m.orgId === orgId && m.userId === userId)\n return {\n orgId,\n orgName: org.name,\n orgSlug: org.slug,\n orgLogoUrl: org.logoUrl,\n profileId: member?.profileId ?? 'owner',\n profileName: member?.profileName ?? 'Owner',\n }\n })\n },\n\n async getOrg(orgId: string): Promise<Organization> {\n const data = getStored()\n const org = data.orgs.find((o) => o.id === orgId)\n if (!org) throw new Error(`Org not found: ${orgId}`)\n return org\n },\n\n async createOrg(name: string, userId: string, options?: CreateOrgOptions): Promise<Organization> {\n const data = getStored()\n const orgId = crypto.randomUUID()\n const firstProfile = defaultProfiles?.[0]\n\n const org: Organization = {\n id: orgId,\n name,\n slug: slugify(name),\n verticalId: options?.verticalId,\n plan: 'free',\n settings: {\n timezone: options?.timezone ?? 'America/Sao_Paulo',\n currency: options?.currency ?? 'BRL',\n locale: options?.locale ?? 'pt-BR',\n },\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n }\n\n const member: OrgMember = {\n id: crypto.randomUUID(),\n userId,\n orgId,\n profileId: firstProfile?.id ?? 'owner',\n profileName: firstProfile?.name ?? 'Owner',\n user: {\n id: userId,\n email: 'user@example.com',\n fullName: 'Current User',\n },\n joinedAt: new Date().toISOString(),\n }\n\n data.orgs.push(org)\n data.members.push(member)\n if (!data.userOrgMap[userId]) data.userOrgMap[userId] = []\n data.userOrgMap[userId].push(orgId)\n if (defaultProfiles) {\n data.profiles[orgId] = [...defaultProfiles]\n }\n data.invites[orgId] = []\n\n setStored(data)\n return org\n },\n\n async updateOrg(orgId: string, updates: Partial<Organization>): Promise<Organization> {\n const data = getStored()\n const idx = data.orgs.findIndex((o) => o.id === orgId)\n if (idx === -1) throw new Error(`Org not found: ${orgId}`)\n data.orgs[idx] = { ...data.orgs[idx], ...updates, updatedAt: new Date().toISOString() }\n setStored(data)\n return data.orgs[idx]\n },\n\n async listMembers(orgId: string): Promise<OrgMember[]> {\n const data = getStored()\n return data.members.filter((m) => m.orgId === orgId)\n },\n\n async updateMemberProfile(orgId: string, memberId: string, profileId: string): Promise<void> {\n const data = getStored()\n const member = data.members.find((m) => m.id === memberId && m.orgId === orgId)\n if (!member) throw new Error(`Member not found: ${memberId}`)\n const profiles = data.profiles[orgId] ?? []\n const profile = profiles.find((p) => p.id === profileId)\n member.profileId = profileId\n member.profileName = profile?.name ?? profileId\n setStored(data)\n },\n\n async removeMember(orgId: string, memberId: string): Promise<void> {\n const data = getStored()\n const memberIdx = data.members.findIndex((m) => m.id === memberId && m.orgId === orgId)\n if (memberIdx === -1) return\n const member = data.members[memberIdx]\n data.members.splice(memberIdx, 1)\n const userOrgs = data.userOrgMap[member.userId]\n if (userOrgs) {\n const orgIdx = userOrgs.indexOf(orgId)\n if (orgIdx !== -1) userOrgs.splice(orgIdx, 1)\n }\n setStored(data)\n },\n\n async listProfiles(orgId: string): Promise<PermissionProfile[]> {\n const data = getStored()\n return data.profiles[orgId] ?? defaultProfiles ?? []\n },\n\n async createProfile(\n orgId: string,\n profile: Omit<PermissionProfile, 'id' | 'isSystem'>,\n ): Promise<PermissionProfile> {\n const data = getStored()\n const newProfile: PermissionProfile = {\n ...profile,\n id: crypto.randomUUID(),\n isSystem: false,\n }\n if (!data.profiles[orgId]) {\n data.profiles[orgId] = defaultProfiles ? [...defaultProfiles] : []\n }\n data.profiles[orgId].push(newProfile)\n setStored(data)\n return newProfile\n },\n\n async updateProfile(\n orgId: string,\n profileId: string,\n updates: Partial<PermissionProfile>,\n ): Promise<PermissionProfile> {\n const data = getStored()\n const profiles = data.profiles[orgId] ?? []\n const idx = profiles.findIndex((p) => p.id === profileId)\n if (idx === -1) throw new Error(`Profile not found: ${profileId}`)\n profiles[idx] = { ...profiles[idx], ...updates }\n data.profiles[orgId] = profiles\n setStored(data)\n return profiles[idx]\n },\n\n async deleteProfile(orgId: string, profileId: string): Promise<void> {\n const data = getStored()\n const profiles = data.profiles[orgId] ?? []\n const profile = profiles.find((p) => p.id === profileId)\n if (profile?.isSystem) throw new Error('Cannot delete system profile')\n data.profiles[orgId] = profiles.filter((p) => p.id !== profileId)\n setStored(data)\n },\n\n async listInvites(orgId: string): Promise<Invite[]> {\n const data = getStored()\n return data.invites[orgId] ?? []\n },\n\n async createInvite(\n orgId: string,\n email: string,\n profileId: string,\n invitedBy: string,\n ): Promise<Invite> {\n const data = getStored()\n const profiles = data.profiles[orgId] ?? defaultProfiles ?? []\n const profile = profiles.find((p) => p.id === profileId)\n\n const invite: Invite = {\n id: crypto.randomUUID(),\n orgId,\n email,\n profileId,\n profileName: profile?.name ?? profileId,\n invitedBy,\n token: crypto.randomUUID(),\n status: 'pending',\n createdAt: new Date().toISOString(),\n expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),\n }\n\n if (!data.invites[orgId]) data.invites[orgId] = []\n data.invites[orgId].push(invite)\n setStored(data)\n return invite\n },\n\n async bulkInvite(\n orgId: string,\n emails: string[],\n profileId: string,\n invitedBy: string,\n ): Promise<Invite[]> {\n const results: Invite[] = []\n for (const email of emails) {\n results.push(await this.createInvite(orgId, email, profileId, invitedBy))\n }\n return results\n },\n\n async revokeInvite(orgId: string, inviteId: string): Promise<void> {\n const data = getStored()\n const invites = data.invites[orgId] ?? []\n const invite = invites.find((i) => i.id === inviteId)\n if (invite) {\n invite.status = 'expired'\n setStored(data)\n }\n },\n\n async resendInvite(orgId: string, inviteId: string): Promise<Invite> {\n const data = getStored()\n const invites = data.invites[orgId] ?? []\n const invite = invites.find((i) => i.id === inviteId)\n if (!invite) throw new Error(`Invite not found: ${inviteId}`)\n invite.expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString()\n invite.status = 'pending'\n setStored(data)\n return invite\n },\n\n async listLocations(_orgId: string): Promise<Location[]> {\n return []\n },\n\n async createLocation(\n orgId: string,\n input: {\n name: string\n address?: string\n city?: string\n state?: string\n country?: string\n phone?: string\n isHeadquarters?: boolean\n },\n ): Promise<Location> {\n return {\n id: crypto.randomUUID(),\n tenantId: orgId,\n name: input.name,\n address: input.address,\n city: input.city,\n state: input.state,\n country: input.country ?? 'BR',\n phone: input.phone,\n isHeadquarters: input.isHeadquarters ?? false,\n isActive: true,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n }\n },\n }\n}\n","import type { OrgMembership } from '@fayz-ai/core'\n\n/**\n * Which workspace this account lands in, when it belongs to more than one.\n *\n * The provider used to answer this by itself — `handoff ?? pinned ?? first` —\n * and that last fallback is a guess with no way to correct it: an account in\n * seven workspaces opened whichever one sorted first and never learnt that the\n * other six existed. The rule below keeps every branch that IS an answer and\n * hands the remaining case to the person, once.\n */\n\nconst AUTOPICK_KEY = 'fayz:workspace-autopick'\n\n/**\n * The workspace a switch already committed to, surviving exactly one reload.\n *\n * Changing workspace ends in a full page reload — the only way to guarantee\n * that every plugin store, cache and open screen is rebuilt against the new\n * tenant instead of showing the previous one's rows. That reload comes back\n * through the same boot path as a fresh login, so without this marker the\n * picker would open and ask a question the user answered one second ago.\n *\n * sessionStorage, not local: it is about THIS navigation, and a tab opened\n * tomorrow should ask again.\n */\nconst SWITCHING_KEY = 'fayz:workspace-switching'\n\n/** Records the destination, for the boot that happens after the reload. */\nexport function markWorkspaceSwitch(orgId: string): void {\n try {\n if (typeof sessionStorage === 'undefined') return\n sessionStorage.setItem(SWITCHING_KEY, orgId)\n } catch {\n // ignore\n }\n}\n\n/** Reads the destination and consumes it — it is good for one boot only. */\nexport function takeWorkspaceSwitch(): string | null {\n try {\n if (typeof sessionStorage === 'undefined') return null\n const v = sessionStorage.getItem(SWITCHING_KEY)\n if (v) sessionStorage.removeItem(SWITCHING_KEY)\n return v\n } catch {\n return null\n }\n}\n\n/** Whether the last explicit choice stands in for every future login. */\nexport function getAutoPick(): boolean {\n try {\n if (typeof localStorage === 'undefined') return false\n return localStorage.getItem(AUTOPICK_KEY) === '1'\n } catch {\n return false\n }\n}\n\nexport function setAutoPick(on: boolean): void {\n try {\n if (typeof localStorage === 'undefined') return\n if (on) localStorage.setItem(AUTOPICK_KEY, '1')\n else localStorage.removeItem(AUTOPICK_KEY)\n } catch {\n // ignore\n }\n}\n\nexport interface WorkspaceChoiceInput {\n /** Every workspace this account belongs to, as the membership list read it. */\n memberships: OrgMembership[]\n /** A switch that is completing across a reload — already answered, once. */\n switchingToId?: string | null\n /** A sibling app's switcher named a workspace on the way in (008). */\n handoffId: string | null\n /** `fayz:current-org` — the last workspace this browser was in. */\n pinnedId: string | null\n /** \"Não perguntar novamente\" is on for this browser. */\n autoPick: boolean\n}\n\nexport type WorkspaceChoice =\n /** Open this one without asking. */\n | { kind: 'resolved'; orgId: string }\n /** Put the picker on screen; `suggestedId` is the row to pre-select. */\n | { kind: 'ask'; suggestedId: string | null }\n /** No workspace at all — the first-run setup flow's business, not ours. */\n | { kind: 'none' }\n\n/**\n * The decision, as a function, so the one piece of logic that decides what a\n * multi-workspace account sees after login can be tested without a browser.\n */\nexport function decideWorkspaceChoice({\n memberships,\n switchingToId = null,\n handoffId,\n pinnedId,\n autoPick,\n}: WorkspaceChoiceInput): WorkspaceChoice {\n if (memberships.length === 0) return { kind: 'none' }\n\n const has = (id: string | null): string | null =>\n id && memberships.some((m) => m.orgId === id) ? id : null\n\n // The freshest answer there is: this reload IS the switch completing.\n const switching = has(switchingToId)\n if (switching) return { kind: 'resolved', orgId: switching }\n\n // A handoff is somebody clicking a specific account in a sibling app's\n // switcher one second ago. That is a fresher answer than anything stored\n // here, and asking again would be asking a question already answered.\n const handoff = has(handoffId)\n if (handoff) return { kind: 'resolved', orgId: handoff }\n\n // One workspace is not a choice.\n if (memberships.length === 1) return { kind: 'resolved', orgId: memberships[0]!.orgId }\n\n // The pin is a HINT, always re-validated against the list we just read: a\n // workspace someone was removed from falls through to the question instead of\n // opening an account they can no longer see.\n const pinned = has(pinnedId)\n if (pinned && autoPick) return { kind: 'resolved', orgId: pinned }\n\n return { kind: 'ask', suggestedId: pinned }\n}\n","import { create } from 'zustand'\nimport { EMPTY_APP_CONFIG, type AppConfig } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// app-config.store — what THIS tenant has, as the database says it (#280).\n//\n// The shell used to learn what to render from `app.manifest.json`, a file that\n// shipped next to the code. That is why eleven applications needed eleven\n// repositories, and why turning a feature on for one customer was a deploy.\n// Since migration 150 the answer is a row, and `app_config()` returns branding,\n// activations, menu composition and the caller's permissions in one stamped\n// round trip.\n//\n// ── Why the manifest still matters ──────────────────────────────────────────\n// It says what a plugin CAN do; this says what this tenant HAS. Neither\n// replaces the other, and confusing them is how a plugin ends up shipping a\n// customer's configuration.\n//\n// ── Why `stale` and not `loading` alone ─────────────────────────────────────\n// Config drives the frame of the app, so re-fetching it must not blank the\n// screen. A refresh keeps the previous answer readable and marks it stale; only\n// the very first load has nothing to show.\n//\n// ── Por que o config sabe DE QUEM ele é ─────────────────────────────────────\n// Trocar de conta não é atualizar: é outra resposta. Sem `tenantId` aqui, o\n// shell pintava a conta nova com a configuração da anterior (ou com o padrão do\n// bundle) até a chamada voltar — rail curto, e o guarda de rota negando com\n// \"acesso restrito\" porque o perfil ainda não tinha chegado. Depois tudo\n// trocava de uma vez, e o que o usuário via era um pisca.\n//\n// Com o dono anotado, quem renderiza consegue perguntar \"isto é sobre a conta\n// em que eu estou?\" — e, quando não é, esperar mostrando esqueleto em vez de\n// mostrar outra coisa.\n// ---------------------------------------------------------------------------\n\ninterface AppConfigStore {\n config: AppConfig\n /** De quem é a configuração em `config`. `null` = nenhuma ainda. */\n tenantId: string | null\n /** True until the first answer arrives — not on every refresh. */\n initializing: boolean\n /** A refresh is in flight; the config on screen is the previous one. */\n stale: boolean\n /** The read failed. The shell still renders: an empty config is legible. */\n error: string | null\n setConfig: (config: AppConfig, tenantId?: string | null) => void\n /** Uma conta nova entrou em cena: o que está em tela não é sobre ela. */\n beginTenant: (tenantId: string | null) => void\n setStale: (stale: boolean) => void\n setError: (error: string | null) => void\n reset: () => void\n}\n\nconst initialState = {\n config: EMPTY_APP_CONFIG,\n tenantId: null,\n initializing: true,\n stale: false,\n error: null,\n}\n\nexport const useAppConfigStore = create<AppConfigStore>((set) => ({\n ...initialState,\n setConfig: (config, tenantId) =>\n set({\n config,\n tenantId: tenantId === undefined ? config.tenant_id ?? null : tenantId,\n initializing: false,\n stale: false,\n error: null,\n }),\n // Não limpa o que está em tela: quem espera desenha esqueleto, e um esqueleto\n // sobre a última resposta é melhor que um branco.\n beginTenant: (tenantId) => set({ tenantId, initializing: true, error: null }),\n setStale: (stale) => set({ stale }),\n setError: (error) => set({ error, initializing: false, stale: false }),\n reset: () => set(initialState),\n}))\n\n/** Active plugin ids, facets folded in — what a screen asks before rendering. */\nexport function activePluginIds(config: AppConfig): string[] {\n return [...new Set(config.plugins.filter((p) => p.status === 'active').map((p) => p.plugin))]\n}\n\n/**\n * Is this plugin — or one named part of it — on for this tenant?\n *\n * The facet argument is what makes a plugin with free and paid halves possible:\n * `has('financial')` asks about the plugin, `has('financial', 'reconciliation')`\n * asks about the part somebody pays for.\n */\nexport function hasPlugin(config: AppConfig, plugin: string, facet?: string): boolean {\n const wanted = facet ?? ''\n return config.plugins.some(\n (p) => p.plugin === plugin && (p.facet ?? '') === wanted && p.status === 'active',\n )\n}\n","import * as React from 'react'\nimport { Building2 } from 'lucide-react'\nimport { cn } from '../lib/cn'\nimport { useAppConfigStore } from '../stores/app-config.store'\n\n/**\n * A cara de uma conta: a marca dela, ou as iniciais.\n *\n * Existia em TRÊS cópias — o gatilho do rail, o seletor pós-login e o diálogo\n * de troca — e cada uma aprendeu as regras abaixo separado. As duas primeiras\n * cortavam a marca (`object-cover`), e só uma delas sabia da arte por\n * superfície. Um componente, uma regra.\n *\n * ── As três regras ─────────────────────────────────────────────────────────\n *\n * 1. **Contido, nunca cortado.** O que chega aqui costuma ser um wordmark\n * largo, e cortar o meio dele é o que fazia \"Espaço Facial\" virar \"aço\".\n *\n * 2. **O ladrilho JÁ VEM PRONTO na imagem.** `markUrl` aponta para um quadrado\n * acabado — fundo escuro, cantos arredondados, glifo claro dentro — gerado\n * uma vez e guardado. A alternativa era o componente montar isso a cada\n * render (fundo por classe, glifo por cima, uma regra de contraste por\n * superfície), que foi o que fez a marca sumir duas vezes, em direções\n * opostas. Uma imagem pronta lê igual no rail, no popover e no seletor\n * pós-login, e não tem regra para errar.\n *\n * 3. **A marca do documento é só da conta ATIVA.** `app_config()` descreve o\n * inquilino em que a sessão está. Usá-la nas linhas da lista pinta todas as\n * contas com o ícone de uma — e o seletor pós-login nem tem conta ativa\n * ainda, então lá cada linha usa sempre a arte da própria conta.\n */\nexport interface OrgMarkProps {\n name: string\n /** A marca da conta, como a lista a conhece (`tenants.logo_url`). */\n logoUrl?: string\n className?: string\n /** A superfície onde o ladrilho está. O popover é claro mesmo num rail escuro. */\n tone?: 'sidebar' | 'popover'\n /** Este ladrilho é o da conta ativa — só ele pode usar o documento de marca. */\n current?: boolean\n}\n\n/** Duas letras no máximo: primeira + última palavra (\"Artorius Steakhouse\" → AS). */\nexport function orgInitials(name: string): string {\n const words = name.trim().split(/\\s+/).filter(Boolean)\n if (!words.length) return '?'\n if (words.length === 1) return words[0]!.slice(0, 2).toUpperCase()\n return (words[0]![0]! + words[words.length - 1]![0]!).toUpperCase()\n}\n\nexport function OrgMark({ name, logoUrl, className, tone = 'sidebar', current = false }: OrgMarkProps) {\n const identity = useAppConfigStore((state) => (state.config.branding as { identity?: Record<string, unknown> })?.identity)\n const pick = (key: string) => (typeof identity?.[key] === 'string' ? (identity[key] as string) : undefined)\n const src = (current ? pick('markUrl') : undefined) ?? logoUrl\n\n const [status, setStatus] = React.useState<'loading' | 'ok' | 'error'>('loading')\n const imgRef = React.useRef<HTMLImageElement>(null)\n // Imagem já em cache termina ANTES do React pendurar o `onLoad`, e esse\n // evento nunca dispara — o esqueleto ficaria pulsando para sempre sobre uma\n // marca pronta. `complete` num layout effect é quem pergunta isso a tempo.\n // O mesmo efeito volta a esperar quando a marca TROCA (troca de conta, ou o\n // `markUrl` que só chega depois do config): manter `ok` mostrava a marca\n // anterior por um quadro. Um efeito só, porque um passivo logo em seguida\n // desfazia o que este acabou de decidir.\n React.useLayoutEffect(() => {\n const el = imgRef.current\n setStatus(el?.complete ? (el.naturalWidth > 0 ? 'ok' : 'error') : 'loading')\n }, [src])\n\n // Squircle com um fio de contorno, para a marca manter a forma agora que nada\n // à volta dela é delineado — o único objeto sólido no topo do rail.\n const base = cn(\n 'shrink-0 overflow-hidden rounded-lg ring-1 ring-inset',\n tone === 'popover' ? 'ring-black/5' : 'ring-white/10',\n className ?? 'h-6 w-6',\n )\n\n // `cover` porque a arte já é o ladrilho inteiro: quadrada, com fundo e com a\n // margem que ela mesma escolheu. Nada a compor aqui.\n //\n // Enquanto ela não chega, um quadrado cinza no lugar exato que ela vai\n // ocupar. Sem isso o gatilho do rail e cada linha do seletor nasciam com um\n // buraco — a lista aparecia montada e as marcas pingavam depois, cada uma no\n // seu tempo, e o topo do rail pulava quando a primeira entrava. O esqueleto\n // reserva o espaço desde o primeiro quadro; e se a imagem falhar, o que fica\n // é a iniciais — a mesma coisa que uma conta sem marca nenhuma mostra.\n if (src && status !== 'error') {\n return (\n <span className={cn(base, 'relative block')}>\n <img\n ref={imgRef}\n src={src}\n alt=\"\"\n onLoad={() => setStatus('ok')}\n onError={() => setStatus('error')}\n className={cn(\n 'h-full w-full object-cover transition-opacity duration-200',\n status === 'ok' ? 'opacity-100' : 'opacity-0',\n )}\n />\n {status === 'loading' && (\n <span\n aria-hidden\n className={cn(\n 'absolute inset-0 animate-pulse',\n tone === 'popover' ? 'bg-muted' : 'bg-sidebar-accent',\n )}\n />\n )}\n </span>\n )\n }\n\n return (\n <span\n aria-hidden\n className={cn(\n base,\n 'flex items-center justify-center text-[10px] font-semibold uppercase leading-none tracking-tight',\n tone === 'popover' ? 'bg-muted text-foreground' : 'bg-sidebar-accent text-sidebar-accent-foreground',\n )}\n >\n {orgInitials(name) || <Building2 className=\"h-3.5 w-3.5\" />}\n </span>\n )\n}\n","import {\n emitDomainEvent, getActiveTenantId, getSupabaseClientOptional,\n isKnownMissing, rememberIfMissing,\n} from '@fayz-ai/core'\nimport type { Location } from '../types/tenant'\n\n// ---------------------------------------------------------------------------\n// Reading the unit tree.\n//\n// Deliberately NOT part of OrgAdapter: a unit is a security dimension, not an\n// org-settings screen, and bolting five more methods onto an interface every\n// app implements would make every app care. Everything here goes through the\n// global Supabase client, and degrades to \"no units\" when there isn't one —\n// which is exactly right for an app running on mock data.\n// ---------------------------------------------------------------------------\n\nexport interface Unit extends Location {\n parentId?: string | null\n code?: string | null\n /** Opcionais, e só servem para oferecer \"a mais perto de mim\" na entrada. */\n latitude?: number | null\n longitude?: number | null\n}\n\nexport interface UnitBinding {\n locationId: string\n role: string | null\n}\n\n/** `core.unit-access.changed` — alguém entrou ou saiu de uma unidade.\n *\n * Mesma forma dos fatos de cadastro (`registry.<entidade>.created`): quem\n * escuta usa `useDataVersion` e relê, e a auditoria vê este fato sem ninguém\n * ter que inscrevê-la. */\n// Pools drift, and a pool without the unit-scoping migrations answers the same\n// three questions with the same 404 on every boot. Asked once per page load.\nconst UNIT_BOOTSTRAP_OBJECT = 'rpc:unit_bootstrap'\nconst UNIT_MODE_OBJECT = 'tenants.unit_scoping_enabled'\nconst SCOPED_RESOURCES_OBJECT = 'scoped_resources'\n\nexport const UNIT_ACCESS_CHANGED = 'core.unit-access.changed'\n\nfunction emitUnitAccessChanged(userId: string | null, unitId: string): void {\n emitDomainEvent(\n UNIT_ACCESS_CHANGED,\n { user_id: userId, unit_id: unitId },\n { tenantId: getActiveTenantId() ?? null, subject: { type: 'location', id: unitId } },\n )\n}\n\nfunction client() {\n return getSupabaseClientOptional() as {\n from: (t: string) => any\n rpc: (fn: string, args?: Record<string, unknown>) => Promise<{ data: any; error: any }>\n } | null\n}\n\nfunction mapUnit(row: Record<string, any>): Unit {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n kind: row.kind ?? 'branch',\n name: row.name,\n email: row.email ?? undefined,\n phone: row.phone ?? undefined,\n address: row.address ?? undefined,\n city: row.city ?? undefined,\n state: row.state ?? undefined,\n country: row.country ?? 'BR',\n postalCode: row.postal_code ?? undefined,\n isHeadquarters: Boolean(row.is_headquarters),\n isActive: row.is_active !== false,\n tags: row.tags ?? [],\n notes: row.notes ?? undefined,\n metadata: row.metadata ?? {},\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n parentId: row.parent_id ?? null,\n code: row.code ?? null,\n // numeric do Postgres chega como string no PostgREST; a aritmética de\n // distância precisa de número, e `Number(null)` é 0, que é uma coordenada\n // real no golfo da Guiné.\n latitude: row.latitude == null ? null : Number(row.latitude),\n longitude: row.longitude == null ? null : Number(row.longitude),\n }\n}\n\n/** Every unit of the tenant. Readable tenant-wide even under scoping: a unit's\n * NAME is not its data, and the switcher has to be able to say it. */\nexport async function fetchUnits(tenantId: string): Promise<Unit[]> {\n const db = client()\n if (!db) return []\n const { data, error } = await db\n .from('v_units')\n .select('*')\n .eq('tenant_id', tenantId)\n .order('is_headquarters', { ascending: false })\n .order('name')\n // A pool that has not taken migration 039 has no `parent_id`; the screen must\n // degrade to \"no units\" rather than throw a red boundary over the whole app.\n if (error) return []\n return (data ?? []).map(mapUnit)\n}\n\n/** Which units the signed-in person is bound to IN THIS WORKSPACE. The DATABASE\n * decides what they may read; this only decides what the switcher offers.\n *\n * The tenant filter is not redundant with RLS. `membership_units_select` lets\n * you see your OWN rows unconditionally (`user_id = auth.uid() OR …`) — it has\n * to, or you could not find yourself — and \"your own rows\" spans every account\n * you belong to. Without the filter, a binding in one workspace came back while\n * standing in another, and `reachable` in UnitMenuSection then narrowed the\n * list to a unit that is not in this tenant's tree: the Unidades section\n * rendered its heading with NOTHING under it, on a tenant with four active\n * units. Reported as \"Espaço Facial não lista as unidades\". */\nexport async function fetchMyBindings(userId: string, tenantId: string): Promise<UnitBinding[]> {\n const db = client()\n if (!db) return []\n const { data, error } = await db\n .from('v_unit_members')\n .select('location_id, role')\n .eq('user_id', userId)\n .eq('tenant_id', tenantId)\n if (error) return []\n return (data ?? []).map((r: any) => ({ locationId: r.location_id, role: r.role ?? null }))\n}\n\nexport interface UnitBootstrap {\n mode: boolean\n units: Unit[]\n /** O vínculo EXPLÍCITO — o que a aba \"Unidades\" de uma pessoa edita. */\n bindings: UnitBinding[]\n /**\n * O que a pessoa ALCANÇA de verdade nesta conta (#018), incluindo quem entra\n * pela conta inteira e por isso não tem vínculo explícito nenhum.\n *\n * São coisas diferentes e a diferença é o bug: `bindings` é a intenção que\n * alguém digitou, `reachable` é o alcance que o banco reconhece — e só o\n * segundo responde \"posso ficar nesta unidade?\". Medir o pino de entrada\n * contra `bindings` fazia o dono do Espaço Facial, que alcança as quatro\n * unidades e não tem vínculo em nenhuma, cair em \"todas\" a cada F5.\n *\n * `undefined` num pool sem a 018 — quem chama recua para `bindings`.\n */\n reachable?: string[]\n scoped: Record<string, { unitColumn: string; shareable: boolean }>\n /** O que esta máquina abriu por último. `set` distingue \"escolheu todas\" de\n * \"nunca escolheu\" — sem isso, quem escolhe \"todas\" leva o palpite de volta\n * na entrada seguinte, para sempre. */\n devicePin: { set: boolean; unitId: string | null }\n /** O que esta pessoa abriu por último em qualquer aparelho. */\n accountPin: { set: boolean; unitId: string | null }\n}\n\n/**\n * Tudo que a entrada precisa, numa viagem.\n *\n * Eram cinco: chave da conta, árvore, vínculos, registro de tabelas escopadas e\n * o pino. Em rede móvel isso é o intervalo inteiro entre o login e a primeira\n * lista — e durante ele a lista já pintou sem unidade nenhuma, mostrando linhas\n * que o seletor está prestes a dizer que não está mostrando.\n *\n * Devolve `null` quando a função não existe (pool sem a 045), e quem chama cai\n * nas consultas soltas. Um app não pode quebrar por causa de uma otimização.\n */\nexport async function fetchUnitBootstrap(\n tenantId: string,\n deviceId: string | undefined,\n): Promise<UnitBootstrap | null> {\n const db = client()\n if (!db) return null\n if (isKnownMissing(UNIT_BOOTSTRAP_OBJECT)) return null\n const { data, error } = await (db as any).rpc('unit_bootstrap', {\n p_tenant_id: tenantId,\n p_device_id: deviceId ?? null,\n })\n if (error) {\n rememberIfMissing(UNIT_BOOTSTRAP_OBJECT, error)\n return null\n }\n if (!data) return null\n const raw = data as Record<string, any>\n return {\n mode: Boolean(raw.mode),\n units: (raw.units ?? []).map(mapUnit),\n bindings: (raw.bindings ?? []).map((r: any) => ({\n locationId: r.location_id, role: r.role ?? null,\n })),\n scoped: Object.fromEntries(\n Object.entries(raw.scoped ?? {}).map(([table, v]: [string, any]) => [\n table, { unitColumn: v?.unit_column ?? 'unit_id', shareable: v?.shareable !== false },\n ]),\n ),\n // user_unit_ids_in walks the tree with UNION over (id, depth): a branch\n // reached directly AND through its HQ comes back twice.\n reachable: Array.isArray(raw.reachable) ? [...new Set(raw.reachable as string[])] : undefined,\n devicePin: { set: Boolean(raw.device_pin_set), unitId: raw.device_pin ?? null },\n accountPin: { set: Boolean(raw.account_pin_set), unitId: raw.account_pin ?? null },\n }\n}\n\n/**\n * Guarda onde a pessoa está, para ela não ter que dizer de novo amanhã.\n *\n * No servidor e não só no navegador, porque o hábito é da pessoa e a máquina é\n * um detalhe: trocar de computador não devia custar uma escolha. Silencioso de\n * propósito — falhar em gravar uma preferência não é assunto de quem só queria\n * abrir a agenda, e a próxima entrada simplesmente pergunta de novo.\n */\nexport async function saveEntryUnit(\n tenantId: string,\n unitId: string | undefined,\n deviceId: string | undefined,\n): Promise<void> {\n const db = client()\n if (!db || !deviceId) return\n await (db as any).rpc('set_entry_unit', {\n p_tenant_id: tenantId,\n p_unit_id: unitId ?? null,\n p_device_id: deviceId,\n })\n}\n\nexport interface UnitMemberRow {\n id: string\n userId: string\n role: string | null\n /** When this person was given access to this unit (migration 044). */\n since: string | null\n}\n\nexport async function fetchUnitMembers(unitId: string): Promise<UnitMemberRow[]> {\n const db = client()\n if (!db) return []\n const { data, error } = await db\n .from('v_unit_members')\n .select('id, user_id, role, created_at')\n .eq('location_id', unitId)\n .order('created_at')\n if (error) return []\n return (data ?? []).map((r: any) => ({\n id: r.id, userId: r.user_id, role: r.role ?? null, since: r.created_at ?? null,\n }))\n}\n\n/** Last sign-in per member, for admins of this tenant only.\n *\n * Through an RPC because `auth.users` is not readable by any client role, and\n * must not be: the same table holds password hashes. The function returns the\n * two harmless columns and nothing else. */\nexport async function fetchMemberActivity(tenantId: string): Promise<Record<string, { lastSignInAt: string | null; signedUpAt: string | null }>> {\n const db = client()\n if (!db) return {}\n const { data, error } = await (db as any).rpc('tenant_member_activity', { p_tenant_id: tenantId })\n if (error) return {}\n const out: Record<string, { lastSignInAt: string | null; signedUpAt: string | null }> = {}\n for (const r of data ?? []) {\n out[(r as any).user_id] = {\n lastSignInAt: (r as any).last_sign_in_at ?? null,\n signedUpAt: (r as any).signed_up_at ?? null,\n }\n }\n return out\n}\n\n/** A member's bindings, for the team screens. The workspace defaults to the\n * active one: every caller is a screen rendered inside it, and asking each to\n * thread a tenant id it already stands in is how one of them forgets. */\nexport async function fetchMemberUnits(userId: string, tenantId?: string): Promise<UnitBinding[]> {\n const tenant = tenantId ?? getActiveTenantId()\n if (!tenant) return []\n return fetchMyBindings(userId, tenant)\n}\n\nexport async function bindUserToUnit(unitId: string, userId: string, role: string | null): Promise<void> {\n const db = client()\n if (!db) throw new Error('sem conexão')\n // An RPC, not an upsert: v_unit_members is a JOINED view, so PostgREST has no\n // unique constraint to conflict on. unit_member_set checks members.manage and\n // refuses an unknown role rather than writing a dangling override.\n const { error } = await db.rpc('unit_member_set', { p_unit: unitId, p_user: userId, p_role: role })\n if (error) throw error\n // Aqui dentro, e não em quem chama: a mesma verdade está em quatro telas, e\n // a que esquecer de avisar é a que fica mentindo. Pelo barramento de eventos\n // de domínio, que é por onde todo fato do sistema já passa — um contador só\n // para unidades seria um terceiro mecanismo para uma ideia que já tem um.\n emitUnitAccessChanged(userId, unitId)\n}\n\nexport async function unbindUserFromUnit(unitId: string, userId: string): Promise<void> {\n const db = client()\n if (!db) throw new Error('sem conexão')\n const { error } = await db.rpc('unit_member_remove', { p_unit: unitId, p_user: userId })\n if (error) throw error\n emitUnitAccessChanged(userId, unitId)\n}\n\n/** The login behind a person record, if there is one.\n *\n * A unit binding is keyed by the auth user, not by the person: a professional\n * with no login has nowhere to bind access TO. `tenant_members.person_id` is\n * the link, and it is nullable on both sides on purpose — plenty of people in a\n * salon's staff list never sign in. */\nexport async function fetchUserIdForPerson(personId: string): Promise<string | null> {\n const db = client()\n if (!db) return null\n const { data, error } = await db\n .from('v_team_members')\n .select('user_id')\n .eq('person_id', personId)\n .maybeSingle()\n if (error || !data) return null\n return (data as any).user_id ?? null\n}\n\n/** Which tables carry a unit, and under which column — the client's mirror of\n * what the policies actually enforce. Read rather than restated, so a table\n * added to the model in SQL cannot be forgotten in TypeScript. */\nexport async function fetchScopedResources(): Promise<Record<string, { unitColumn: string; shareable: boolean }>> {\n const db = client()\n if (!db) return {}\n if (isKnownMissing(SCOPED_RESOURCES_OBJECT)) return {}\n const { data, error } = await db.from('scoped_resources').select('resource_table, unit_column, shareable')\n if (error) {\n rememberIfMissing(SCOPED_RESOURCES_OBJECT, error)\n return {}\n }\n const out: Record<string, { unitColumn: string; shareable: boolean }> = {}\n for (const r of data ?? []) {\n out[(r as any).resource_table] = {\n unitColumn: (r as any).unit_column ?? 'unit_id',\n shareable: (r as any).shareable !== false,\n }\n }\n return out\n}\n\n/**\n * Whether this tenant works with units, and whether the question is even\n * answerable here.\n *\n * `installed: false` means the pool never took migration 039 — the column is\n * not there, so units do not exist in this deployment at all. That is a\n * different fact from \"the tenant has units switched off\", and collapsing the\n * two (as `false` alone did) is what made the boot fan out to `locations`,\n * `location_members` and `scoped_resources` on pools that have none of them.\n */\nexport async function fetchUnitMode(tenantId: string): Promise<{ installed: boolean; on: boolean }> {\n const db = client()\n if (!db) return { installed: false, on: false }\n if (isKnownMissing(UNIT_MODE_OBJECT)) return { installed: false, on: false }\n const { data, error } = await db\n .from('tenants')\n .select('unit_scoping_enabled')\n .eq('id', tenantId)\n .maybeSingle()\n if (error) {\n rememberIfMissing(UNIT_MODE_OBJECT, error)\n return { installed: false, on: false }\n }\n // A tenant row that is simply not readable is still a pool WITH the feature;\n // reporting it as absent would hide a policy problem behind a deploy story.\n return { installed: true, on: Boolean(data?.unit_scoping_enabled) }\n}\n\nexport async function setUnitModeRemote(tenantId: string, on: boolean): Promise<void> {\n const db = client()\n if (!db) throw new Error('sem conexão')\n const { error } = await db.from('tenants').update({ unit_scoping_enabled: on }).eq('id', tenantId)\n if (error) throw error\n}\n\n/** Bind every current member of the tenant to one unit. The \"link everyone to\n * the head office\" checkbox on the switch-on dialog — the difference between a\n * feature people try and one that locks a team out on a Tuesday. */\nexport async function bindAllMembersTo(tenantId: string, unitId: string): Promise<number> {\n const db = client()\n if (!db) return 0\n const { data } = await db.from('v_team_members').select('user_id').eq('tenant_id', tenantId)\n const userIds = (data ?? []).map((m: any) => m.user_id as string)\n if (userIds.length === 0) return 0\n // One call per member. The bulk upsert this replaces was one round trip, but\n // it wrote through a projection that no longer exists — and a partial failure\n // here names the member it failed on, which the bulk form never could.\n for (const userId of userIds) {\n const { error } = await db.rpc('unit_member_set', { p_unit: unitId, p_user: userId, p_role: null })\n if (error) throw error\n }\n // Vinculou a conta inteira de uma vez: sem uma pessoa para citar, o fato é o\n // mesmo e quem escuta relê. Uma releitura à toa custa menos do que uma tela\n // afirmando que ninguém tem acesso.\n emitUnitAccessChanged(null, unitId)\n return userIds.length\n}\n\n/** How many members have no unit at all — the number the switch-on dialog shows,\n * and the one that predicts the \"everything disappeared\" support ticket. */\nexport async function countUnboundMembers(tenantId: string): Promise<number> {\n const db = client()\n if (!db) return 0\n const { data: members } = await db.from('v_team_members').select('user_id').eq('tenant_id', tenantId)\n const { data: units } = await db.from('v_units').select('id').eq('tenant_id', tenantId)\n const unitIds = (units ?? []).map((u: any) => u.id)\n if (unitIds.length === 0) return (members ?? []).length\n const { data: bound } = await db.from('v_unit_members').select('user_id').in('location_id', unitIds)\n const boundSet = new Set((bound ?? []).map((b: any) => b.user_id))\n return (members ?? []).filter((m: any) => !boundSet.has(m.user_id)).length\n}\n","import type { Unit, UnitBinding } from './data'\n\n/**\n * O que a sessão sabia sobre unidades da última vez, para saber de novo antes\n * do primeiro pixel.\n *\n * Aqui isso vale mais do que na organização, e por um motivo que não é\n * velocidade: enquanto a unidade não resolve, a unidade ativa é \"nenhuma\" — e\n * \"nenhuma\" significa TODAS. A lista já pintou mostrando linhas de quinze lojas\n * quando o seletor vai dizer \"Ipanema\", e quando a resposta chega ela troca o\n * escopo e derruba o cache inteiro, refazendo toda consulta da tela. O usuário\n * vê a mesma página duas vezes, com conteúdos diferentes, e a segunda é a certa.\n *\n * Com o retrato, a unidade está resolvida antes do primeiro render: nada pisca\n * e nada refaz, porque `setActiveUnitId` já sai cedo quando o valor não mudou.\n *\n * ISTO NÃO É AUTORIZAÇÃO, e não pode virar. O que a pessoa alcança é decidido\n * no Postgres a cada consulta; o que está aqui é só \"onde eu estava\". Um\n * retrato adulterado à mão esconde linha, o que é chato, e não revela nenhuma,\n * que é o ponto.\n */\n\nconst STORAGE_KEY = 'fayz:units-snapshot'\nconst VERSION = 1\n\n/** Mais velho que isto e o retrato é descartado em vez de pintado. */\nconst MAX_AGE_MS = 24 * 60 * 60 * 1000\n/** Uma rede grande com árvore longa — melhor não pintar do que estourar a cota. */\nconst MAX_BYTES = 256 * 1024\n\nexport interface UnitSnapshot {\n version: number\n /** De quem é o retrato. Outra pessoa na mesma máquina começa do zero. */\n userId: string\n /** De qual conta. Trocar de workspace descarta em vez de traduzir. */\n tenantId: string\n savedAt: number\n mode: boolean\n units: Unit[]\n myUnitIds: string[]\n bindings: UnitBinding[]\n activeUnitId: string | null\n scoped: Record<string, { unitColumn: string; shareable: boolean }>\n}\n\nexport type UnitSnapshotInput = Omit<UnitSnapshot, 'version' | 'savedAt'>\n\nfunction storage(): Storage | null {\n try {\n if (typeof localStorage === 'undefined') return null\n return localStorage\n } catch {\n return null\n }\n}\n\nexport function readUnitSnapshot(): UnitSnapshot | null {\n const store = storage()\n if (!store) return null\n try {\n const raw = store.getItem(STORAGE_KEY)\n if (!raw) return null\n const snapshot = JSON.parse(raw) as UnitSnapshot\n if (snapshot?.version !== VERSION || !snapshot.tenantId || !snapshot.userId) return null\n const age = Date.now() - snapshot.savedAt\n // Um relógio que andou para trás não devolve um cache eternamente novo.\n if (age < 0 || age > MAX_AGE_MS) {\n store.removeItem(STORAGE_KEY)\n return null\n }\n return snapshot\n } catch {\n return null\n }\n}\n\nexport function saveUnitSnapshot(input: UnitSnapshotInput): void {\n const store = storage()\n if (!store) return\n try {\n const raw = JSON.stringify({ ...input, version: VERSION, savedAt: Date.now() })\n if (raw.length > MAX_BYTES) return\n store.setItem(STORAGE_KEY, raw)\n } catch {\n // Cota ou serialização — o retrato é otimização, não estado.\n }\n}\n\n/** Trocar a unidade ativa sem reiniciar a janela de validade: a escolha é do\n * usuário, e não é uma leitura nova do servidor. */\nexport function patchUnitSnapshotActive(activeUnitId: string | null): void {\n const store = storage()\n const current = readUnitSnapshot()\n if (!store || !current) return\n try {\n store.setItem(STORAGE_KEY, JSON.stringify({ ...current, activeUnitId }))\n } catch {\n // idem\n }\n}\n\nexport function clearUnitSnapshot(): void {\n try {\n storage()?.removeItem(STORAGE_KEY)\n } catch {\n // ignore\n }\n}\n","/**\n * Qual máquina é esta.\n *\n * A recepcionista do balcão da Ipanema usa sempre o mesmo computador, e esse\n * computador fica na Ipanema. É o sinal mais forte que existe sobre onde ela\n * está, e o único que não custa um pedido de permissão nem uma pergunta.\n *\n * É um número sorteado, não uma impressão digital. Não olha resolução de tela,\n * fontes instaladas, canvas nem user-agent — nada que descreva o aparelho ou\n * que sirva para reconhecê-lo em outro lugar. Um identificador que não descreve\n * nada não pode ser usado para mais nada, e essa é a diferença entre lembrar de\n * uma preferência e rastrear alguém.\n *\n * Some quando a pessoa limpa o navegador, e isso está certo: uma máquina que\n * esqueceu tudo é uma máquina nova, e a preferência da conta assume.\n */\n\nconst STORAGE_KEY = 'fayz:device-id'\n\nlet cached: string | null = null\n\nfunction randomId(): string {\n try {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n } catch {\n // segue para o caminho de baixo\n }\n return `d-${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`\n}\n\n/**\n * O identificador desta máquina, criado na primeira vez que alguém pergunta.\n *\n * Devolve `undefined` quando não há onde guardar (modo privado, SSR). Nesse\n * caso a entrada cai na preferência da conta, que é a resposta certa: sortear\n * um identificador novo a cada carregamento encheria a tabela de dispositivos\n * que nunca mais voltam.\n */\nexport function getDeviceId(): string | undefined {\n if (cached) return cached\n try {\n if (typeof localStorage === 'undefined') return undefined\n const existing = localStorage.getItem(STORAGE_KEY)\n if (existing) {\n cached = existing\n return existing\n }\n const fresh = randomId()\n localStorage.setItem(STORAGE_KEY, fresh)\n cached = fresh\n return fresh\n } catch {\n return undefined\n }\n}\n","/**\n * Request deduplication — prevents duplicate in-flight requests with the same key.\n * If a request with the same key is already in-flight, returns the existing promise.\n *\n * O que se compartilha aqui é o RESULTADO da leitura, nunca o EFEITO dela.\n *\n * O mapa é global ao aplicativo e a chave é só a consulta — a loja que pediu\n * não entra nela. Quem chega em segundo recebe a MESMA promessa que já está no\n * ar, e a função passada NÃO roda de novo. Então escrever numa loja lá dentro\n * significa escrever na loja de QUEM CHEGOU PRIMEIRO, e quem chegou depois fica\n * com a tela vazia e a bandeira de carregando ligada para sempre.\n *\n * Isso não é caso de borda: o manifesto de um plugin é reconstruído com a\n * configuração da conta (ver `PluginRebuild`), e uma loja nova nasce com ele.\n *\n * // não\n * dedup(key, async () => { set({ rows: await api.list() }) })\n * // sim\n * set({ rows: await dedup(key, () => api.list()) })\n */\nconst inflight = new Map<string, Promise<any>>()\n\nexport function dedup<T>(key: string, fn: () => Promise<T>): Promise<T> {\n const existing = inflight.get(key)\n if (existing) return existing as Promise<T>\n\n const promise = fn().finally(() => {\n inflight.delete(key)\n })\n\n inflight.set(key, promise)\n return promise\n}\n","/**\n * Onde a pessoa entra, e por quê.\n *\n * Puro de propósito: é a única regra da entrada que decide alguma coisa, e uma\n * regra que só se observa abrindo o navegador é uma regra que ninguém revisa.\n * Nada aqui lê disco, rede ou relógio.\n */\n\n/** Por que a unidade ativa é a que é — o que a tela responde quando alguém\n * pergunta \"por que abriu na Ipanema?\". Sem isso a resolução automática vira\n * mágica, e mágica em cima de escopo de dado é o que faz gente desconfiar da\n * lista que está vendo. */\nexport type UnitEntryReason =\n | 'device' // esta máquina abriu esta unidade por último\n | 'account' // esta pessoa abriu esta unidade por último, em outro aparelho\n | 'only' // é a única que ela alcança\n | 'manual' // ela acabou de escolher\n | 'nearest' // ela pediu \"a mais perto\" e aceitou\n | 'all' // todas as unidades, por escolha ou por não haver o que decidir\n\n/** `set` distingue \"escolheu todas\" de \"nunca escolheu\". Sem essa diferença,\n * quem escolhe \"todas\" leva o palpite de volta na entrada seguinte, para\n * sempre — e a escolha dela nunca pega. */\nexport interface EntryPin {\n set: boolean\n unitId: string | null\n}\n\nexport interface EntryPins {\n device?: EntryPin\n account?: EntryPin\n /** O pino local anterior a tudo isto, lido uma vez para quem já usava não\n * perder a unidade na primeira atualização. */\n legacy?: string\n}\n\nexport interface EntryResolution {\n unitId: string | undefined\n reason: UnitEntryReason\n /** Alcança mais de uma unidade e nunca escolheu nenhuma: é o único caso em\n * que oferecer \"a mais perto de mim\" responde alguma coisa. */\n needsChoice: boolean\n}\n\n/**\n * A ordem não é arbitrária.\n *\n * A MÁQUINA vem antes da CONTA porque o computador do balcão fica na loja e a\n * pessoa não: o mesmo gerente abre o Leblon no celular de casa à noite e a\n * Ipanema no balcão de manhã, e o aparelho é o melhor sinal de qual das duas é\n * agora. Depois vem a aritmética — quem alcança uma unidade só não tem escolha\n * a fazer, e mostrar um seletor para ela é pedir trabalho para confirmar o\n * óbvio.\n *\n * Um pino fora do alcance é ignorado em silêncio, nunca corrigido com um aviso:\n * ele aparece quando alguém perdeu acesso a uma loja, e \"você não tem mais\n * acesso à Ipanema\" é uma conversa com o gerente, não um alerta na tela.\n *\n * NADA AQUI CONCEDE. Um pino aponta, e o Postgres decide — o pior que um erro\n * nesta função faz é esconder linha, que é chato, e nunca revelar uma.\n */\nexport function resolveEntry(reachable: string[], pins: EntryPins): EntryResolution {\n const canStand = (id: string | null | undefined) => id != null && reachable.includes(id)\n\n const ladder: Array<[EntryPin | undefined, UnitEntryReason]> = [\n [pins.device, 'device'],\n [pins.account, 'account'],\n ]\n for (const [pin, reason] of ladder) {\n if (!pin?.set) continue\n if (pin.unitId === null) return { unitId: undefined, reason: 'all', needsChoice: false }\n if (canStand(pin.unitId)) return { unitId: pin.unitId, reason, needsChoice: false }\n }\n\n if (canStand(pins.legacy)) return { unitId: pins.legacy, reason: 'device', needsChoice: false }\n\n if (reachable.length === 1) return { unitId: reachable[0], reason: 'only', needsChoice: false }\n\n // Ninguém é parado na porta. Alcançar quinze lojas e não ter dito qual é uma\n // resposta legítima — \"todas\" — e a oferta de escolher fica dentro do menu,\n // onde custa um clique de quem quiser e nada de quem não quiser.\n return { unitId: undefined, reason: 'all', needsChoice: reachable.length > 1 }\n}\n","import { create } from 'zustand'\nimport { setActiveUnitId, setUnitMode, resetActiveUnit, setScopedResources } from '@fayz-ai/core'\nimport { readOrgSnapshot } from '../org'\nimport type { Unit, UnitBinding } from './data'\nimport {\n fetchUnits, fetchMyBindings, fetchUnitMode, fetchScopedResources,\n fetchUnitBootstrap, saveEntryUnit,\n} from './data'\nimport { readUnitSnapshot, saveUnitSnapshot, patchUnitSnapshotActive, clearUnitSnapshot } from './cache'\nimport { getDeviceId } from './device'\nimport { dedup } from '../lib/dedup'\n\n/** O pino local anterior a este arquivo. Lido uma vez, para quem já usava não\n * perder a unidade na primeira atualização; nada novo escreve nele. */\nconst LEGACY_KEY = 'saas-core:current-location'\n\nimport { resolveEntry, type UnitEntryReason } from './entry'\n\nexport interface UnitNode extends Unit {\n children: UnitNode[]\n}\n\nexport type { UnitEntryReason }\n\ninterface UnitStore {\n units: Unit[]\n byId: Record<string, Unit>\n tree: UnitNode[]\n /** As unidades a que esta pessoa está vinculada, expandidas pela árvore. */\n myUnitIds: string[]\n myBindings: UnitBinding[]\n /** undefined = \"todas as unidades\". */\n activeUnitId: string | undefined\n entryReason: UnitEntryReason\n unitMode: boolean\n loading: boolean\n /** Já temos uma resposta — do retrato ou do servidor — e a tela pode desenhar\n * a linha de identidade em vez de um esqueleto. */\n resolved: boolean\n /** Alcança mais de uma unidade e nunca escolheu nenhuma: é o único caso em\n * que oferecer \"a mais perto de mim\" responde alguma coisa. */\n needsChoice: boolean\n loadedFor: string | null\n\n load: (tenantId: string, userId: string | undefined) => Promise<void>\n setActive: (unitId: string | undefined, reason?: UnitEntryReason) => void\n setMode: (on: boolean) => void\n reset: () => void\n}\n\nfunction legacyPin(): string | undefined {\n try {\n return localStorage.getItem(LEGACY_KEY) ?? undefined\n } catch {\n return undefined\n }\n}\n\nfunction buildTree(units: Unit[]): UnitNode[] {\n const nodes = new Map<string, UnitNode>()\n for (const u of units) nodes.set(u.id, { ...u, children: [] })\n const roots: UnitNode[] = []\n for (const node of nodes.values()) {\n const parent = node.parentId ? nodes.get(node.parentId) : undefined\n // Um pai que não está na lista (filtrado, ou uma aresta quebrada) não pode\n // engolir o filho — um órfão na raiz é visível e consertável, um sumido não\n // é nem uma coisa nem outra.\n if (parent && parent.id !== node.id) parent.children.push(node)\n else roots.push(node)\n }\n return roots\n}\n\n/** Um vínculo alcança tudo abaixo dele. Espelha `public.user_unit_ids()` — e só\n * decide o que o SELETOR oferece, nunca o que é lido. */\nfunction expandDown(units: Unit[], seeds: string[]): string[] {\n const childrenOf = new Map<string, string[]>()\n for (const u of units) {\n if (!u.parentId) continue\n const list = childrenOf.get(u.parentId) ?? []\n list.push(u.id)\n childrenOf.set(u.parentId, list)\n }\n const out = new Set<string>()\n const queue = [...seeds]\n while (queue.length > 0) {\n const id = queue.shift()!\n if (out.has(id)) continue\n out.add(id)\n for (const child of childrenOf.get(id) ?? []) queue.push(child)\n }\n return [...out]\n}\n\n/** Só uma filial pode ser habitada. Uma região é agrupamento — ficar \"dentro\"\n * dela significaria enumerar as filhas como filtro no navegador, que é a única\n * coisa que este desenho se recusa a fazer. */\nfunction branchesOnly(ids: string[], byId: Record<string, Unit>): string[] {\n return ids.filter((id) => byId[id]?.kind !== 'region')\n}\n\nexport const useUnitStore = create<UnitStore>((set, get) => ({\n units: [],\n byId: {},\n tree: [],\n myUnitIds: [],\n myBindings: [],\n activeUnitId: undefined,\n entryReason: 'all',\n unitMode: false,\n loading: false,\n resolved: false,\n needsChoice: false,\n loadedFor: null,\n\n // Uma chamada por conta, por mais telas que peçam.\n //\n // Dez componentes chamam `useUnitBootstrap` — o seletor, a linha de\n // identidade, o rodapé do registro, a aba de unidades de uma pessoa — e todos\n // montam no mesmo quadro. A guarda anterior era `loadedFor === tenantId &&\n // !loading`, que deixa passar exatamente enquanto a primeira chamada está no\n // ar: o segundo componente via a conta já marcada, via `loading` ligado, e a\n // condição inteira dava falso. Resultado: uma requisição por tela, todas\n // idênticas. Juntar cinco viagens numa e depois disparar essa uma cinco vezes\n // não economiza nada.\n //\n // `dedup` é o mesmo utilitário que a tela de equipe já usa: quem chegar\n // enquanto a primeira está no ar recebe a MESMA promessa em vez de abrir\n // outra.\n async load(tenantId, userId) {\n if (!tenantId) return\n if (get().loadedFor === tenantId && !get().loading) return\n return dedup(`units:${tenantId}:${userId ?? ''}`, () => loadOnce(tenantId, userId, set, get))\n },\n\n setActive(unitId, reason = 'manual') {\n // Sem recarregar a página. Trocar de CONTA — uma mudança de escopo\n // estritamente maior — já não recarrega; dois mecanismos para um conceito é\n // o bug. `setActiveUnitId` limpa o cache de leitura e acorda os inscritos.\n setActiveUnitId(unitId)\n set({ activeUnitId: unitId, entryReason: reason, needsChoice: false })\n patchUnitSnapshotActive(unitId ?? null)\n\n // O servidor guarda o hábito para a próxima máquina; o retrato local guarda\n // a pintura para o próximo carregamento. Silencioso: falhar em gravar uma\n // preferência não é assunto de quem só queria trocar de loja.\n const tenantId = get().loadedFor\n if (tenantId) void saveEntryUnit(tenantId, unitId, getDeviceId())\n },\n\n setMode(on) {\n setUnitMode(on)\n set({ unitMode: on })\n if (!on) {\n setActiveUnitId(undefined)\n set({ activeUnitId: undefined, entryReason: 'all', needsChoice: false })\n patchUnitSnapshotActive(null)\n }\n },\n\n reset() {\n clearUnitSnapshot()\n resetActiveUnit()\n set({\n units: [], byId: {}, tree: [], myUnitIds: [], myBindings: [],\n activeUnitId: undefined, entryReason: 'all', unitMode: false,\n loading: false, resolved: false, needsChoice: false, loadedFor: null,\n })\n },\n}))\n\ntype SetState = (partial: Partial<UnitStore>) => void\ntype GetState = () => UnitStore\n\nasync function loadOnce(\n tenantId: string,\n userId: string | undefined,\n set: SetState,\n get: GetState,\n): Promise<void> {\n set({ loading: true, loadedFor: tenantId })\n try {\n const deviceId = getDeviceId()\n\n // Uma viagem quando o pool tem a 045; as de antes quando não tem. Um app não\n // pode quebrar por causa de uma otimização, e a versão do banco não é\n // assunto da tela.\n const boot = await fetchUnitBootstrap(tenantId, deviceId)\n\n let mode: boolean\n let units: Unit[]\n let bindings: UnitBinding[]\n let scoped: Record<string, { unitColumn: string; shareable: boolean }>\n // O alcance dito pelo servidor (#018). `undefined` num pool sem a migration,\n // e aí a conta antiga a partir dos vínculos explícitos volta a valer.\n let reachableFromServer: string[] | undefined\n\n if (boot) {\n ;[mode, units, bindings, scoped] = [boot.mode, boot.units, boot.bindings, boot.scoped]\n reachableFromServer = boot.reachable\n } else {\n // O modo primeiro, e sozinho. As outras três perguntas só fazem sentido\n // se este pool tiver unidades: num pool sem a 039 as quatro saíam juntas\n // e três voltavam 404/400 — em toda entrada, para sempre, por uma\n // funcionalidade que aquele banco não tem.\n const modeResult = await fetchUnitMode(tenantId)\n mode = modeResult.on\n if (!modeResult.installed) {\n units = []\n bindings = []\n scoped = {}\n } else {\n // A árvore vem mesmo com o modo desligado: é ela que o cartão de ligar\n // unidades conta antes de alguém ligar. O registro de tabelas escopadas\n // não — sem escopo ligado ele não narra nada.\n ;[units, bindings, scoped] = await Promise.all([\n fetchUnits(tenantId),\n userId ? fetchMyBindings(userId, tenantId) : Promise.resolve([] as UnitBinding[]),\n mode ? fetchScopedResources() : Promise.resolve({}),\n ])\n }\n }\n\n // Publica a lista de tabelas escopadas do próprio banco, para uma entidade\n // não ter que lembrar de se inscrever e o cliente não poder discordar da\n // policy.\n setScopedResources(scoped)\n\n const byId: Record<string, Unit> = {}\n for (const u of units) byId[u.id] = u\n\n // QUEM DECIDE O ALCANCE É O SERVIDOR.\n //\n // A conta antiga partia dos vínculos EXPLÍCITOS (`membership_units`), e quem\n // alcança a conta inteira não tem nenhum: o alcance saía vazio, `resolveEntry`\n // não conseguia validar pino nenhum e a entrada caía em \"todas as unidades\"\n // toda vez. Ela fica como recuo para um pool que ainda não tem a 018.\n const reachable = reachableFromServer\n ? branchesOnly(reachableFromServer.filter((id) => byId[id]), byId)\n : branchesOnly(expandDown(units, bindings.map((b) => b.locationId)), byId)\n const entry = resolveEntry(reachable, {\n device: boot?.devicePin, account: boot?.accountPin, legacy: legacyPin(),\n })\n\n setUnitMode(mode)\n setActiveUnitId(entry.unitId)\n\n set({\n units, byId,\n tree: buildTree(units),\n myUnitIds: reachable,\n myBindings: bindings,\n unitMode: mode,\n activeUnitId: entry.unitId,\n entryReason: entry.reason,\n needsChoice: entry.needsChoice,\n loading: false,\n resolved: true,\n })\n\n if (userId) {\n saveUnitSnapshot({\n userId, tenantId, mode, units, bindings,\n myUnitIds: reachable,\n activeUnitId: entry.unitId ?? null,\n scoped,\n })\n }\n } finally {\n // Sem isto, uma falha no meio deixa `loading` ligado para sempre e a guarda\n // de \"já carreguei\" nunca mais fecha — cada tela que montar tenta de novo.\n if (get().loading) set({ loading: false })\n }\n}\n\n\n// ---------------------------------------------------------------------------\n// Hidratação, e por que ela roda aqui e não num efeito.\n//\n// Enquanto a unidade não resolve, a unidade ativa é \"nenhuma\" — e \"nenhuma\"\n// quer dizer TODAS. Um efeito roda depois do primeiro render, então a primeira\n// lista já saiu do forno mostrando as quinze lojas, e quando a resposta chega o\n// escopo muda, o cache é derrubado e toda consulta da tela refaz. O usuário vê\n// a mesma página duas vezes com conteúdos diferentes, e só a segunda está certa.\n//\n// Rodando na avaliação do módulo — antes do primeiro render, antes da primeira\n// consulta — a unidade já está resolvida quando a lista pergunta, e quando o\n// servidor confirma o mesmo valor `setActiveUnitId` sai cedo e nada refaz.\n// ---------------------------------------------------------------------------\n;(function hydrate() {\n const snapshot = readUnitSnapshot()\n if (!snapshot) return\n // O retrato é de uma conta; o app pode ter aberto em outra. Descartar é a\n // resposta certa — traduzir unidade entre contas não existe.\n const org = readOrgSnapshot()\n if (!org || org.org?.id !== snapshot.tenantId || org.userId !== snapshot.userId) {\n clearUnitSnapshot()\n return\n }\n\n const byId: Record<string, Unit> = {}\n for (const u of snapshot.units) byId[u.id] = u\n const active = snapshot.activeUnitId ?? undefined\n // Mesmo vindo do próprio disco, o pino só vale se a pessoa ainda alcança a\n // unidade. `load` vai reconfirmar contra o servidor logo em seguida.\n const standable = active && snapshot.myUnitIds.includes(active) ? active : undefined\n\n setScopedResources(snapshot.scoped)\n setUnitMode(snapshot.mode)\n setActiveUnitId(standable)\n\n useUnitStore.setState({\n units: snapshot.units,\n byId,\n tree: buildTree(snapshot.units),\n myUnitIds: snapshot.myUnitIds,\n myBindings: snapshot.bindings,\n unitMode: snapshot.mode,\n activeUnitId: standable,\n entryReason: standable ? 'device' : 'all',\n resolved: true,\n })\n})()\n","import * as React from 'react'\nimport { getSupabaseClientOptional, setHouseCurrency } from '@fayz-ai/core'\nimport { useUnitStore } from './store'\n\n/**\n * Keeps the house currency current: the unit the person is standing in, else\n * the tenant's. Mounted once by the workspace provider, so every screen — and\n * every plugin's `config.currency` — prints in it without asking.\n */\nexport function useHouseCurrencySync(orgId: string | undefined, tenantCurrency: string | undefined): void {\n const activeUnitId = useUnitStore((s) => s.activeUnitId)\n React.useEffect(() => {\n if (!orgId) { setHouseCurrency(null); return }\n setHouseCurrency(tenantCurrency ?? null)\n if (!activeUnitId) return\n let alive = true\n void unitCurrency(orgId, activeUnitId).then((code) => { if (alive && code) setHouseCurrency(code) })\n return () => { alive = false }\n }, [orgId, activeUnitId, tenantCurrency])\n}\n\nconst unitCurrencyCache = new Map<string, Promise<string | null>>()\nfunction unitCurrency(orgId: string, unitId: string): Promise<string | null> {\n const key = `${orgId}:${unitId}`\n let pending = unitCurrencyCache.get(key)\n if (!pending) {\n const client = getSupabaseClientOptional() as any\n pending = client\n ? Promise.resolve(client.rpc('my_unit_currency', { p_unit: unitId }))\n .then((res: { data?: unknown; error?: unknown }) => (res.error || typeof res.data !== 'string' ? null : res.data))\n .catch(() => null)\n : Promise.resolve(null)\n unitCurrencyCache.set(key, pending!)\n }\n return pending!\n}\n\n/** A unit's currency was changed on screen: the next read must not be the cached one. */\nexport function forgetUnitCurrency(): void {\n unitCurrencyCache.clear()\n}\n","import type { Organization, OrgMember, OrgMembership, PermissionProfile } from '@fayz-ai/core'\n\n/**\n * Snapshot of the org bootstrap (org + memberships + members + permission\n * profiles) so a page reload doesn't wait on the whole chain again.\n *\n * Every mount used to pay `acceptPendingInvites → listUserOrgs → getOrg →\n * listMembers + listProfiles` before `org.id` existed, and every screen keyed\n * off the tenant (Conectores, plugin tabs, permission gates) sat idle until\n * then. The snapshot paints that state synchronously and the network is only\n * touched again once it goes stale.\n */\n\nconst STORAGE_KEY = 'fayz:org-snapshot'\nconst VERSION = 1\n\n/** Served without touching the network. */\nexport const ORG_CACHE_TTL_MS = 5 * 60 * 1000\n/** Older than this and the snapshot is dropped instead of painted. */\nconst MAX_AGE_MS = 24 * 60 * 60 * 1000\n/** Bigger than this (huge member lists) and we skip persisting rather than blow the quota. */\nconst MAX_BYTES = 512 * 1024\n\nexport interface OrgSnapshot {\n version: number\n /** Who the snapshot belongs to — a different user gets a cold load. */\n userId: string\n /** When the data last came from the server (store patches don't move it). */\n savedAt: number\n org: Organization\n userOrgs: OrgMembership[]\n members: OrgMember[]\n profiles: PermissionProfile[]\n currentProfileId: string | null\n}\n\nexport type OrgSnapshotInput = Omit<OrgSnapshot, 'version' | 'savedAt'>\n\nfunction storage(): Storage | null {\n try {\n if (typeof localStorage === 'undefined') return null\n return localStorage\n } catch {\n return null\n }\n}\n\nexport function readOrgSnapshot(): OrgSnapshot | null {\n const store = storage()\n if (!store) return null\n try {\n const raw = store.getItem(STORAGE_KEY)\n if (!raw) return null\n const snapshot = JSON.parse(raw) as OrgSnapshot\n if (snapshot?.version !== VERSION || !snapshot.org?.id || !snapshot.userId) return null\n if (snapshotAge(snapshot) > MAX_AGE_MS) {\n store.removeItem(STORAGE_KEY)\n return null\n }\n return snapshot\n } catch {\n return null\n }\n}\n\nexport function snapshotAge(snapshot: OrgSnapshot): number {\n const age = Date.now() - snapshot.savedAt\n // A clock that moved backwards shouldn't hand out an eternally fresh cache.\n return age < 0 ? Number.POSITIVE_INFINITY : age\n}\n\nexport function isSnapshotFresh(snapshot: OrgSnapshot, ttlMs: number): boolean {\n return snapshotAge(snapshot) < ttlMs\n}\n\n/** Record a fresh server read — restarts the TTL window. */\nexport function saveOrgSnapshot(input: OrgSnapshotInput): void {\n write({ ...input, version: VERSION, savedAt: Date.now() })\n}\n\n/**\n * Keep the snapshot in step with store writes made outside the provider\n * (renaming the org in Settings, editing a role) WITHOUT restarting the TTL —\n * otherwise a UI-only change would push the next revalidation out forever.\n */\nexport function patchOrgSnapshot(input: OrgSnapshotInput): void {\n const current = readOrgSnapshot()\n if (!current || current.userId !== input.userId) return\n write({ ...input, version: VERSION, savedAt: current.savedAt })\n}\n\nexport function clearOrgSnapshot(): void {\n try {\n storage()?.removeItem(STORAGE_KEY)\n } catch {\n // ignore\n }\n}\n\nfunction write(snapshot: OrgSnapshot): void {\n const store = storage()\n if (!store) return\n try {\n const raw = JSON.stringify(snapshot)\n if (raw.length > MAX_BYTES) return\n store.setItem(STORAGE_KEY, raw)\n } catch {\n // Quota or serialization failure — the cache is an optimization, not state.\n }\n}\n","import * as React from 'react'\nimport { errorMessage, isImpersonating, type OrgAdapter, type Organization, type OrgMembership } from '@fayz-ai/core'\nimport { useAuthStore, readAppHandoff } from '@fayz-ai/auth'\nimport { useOrganizationStore, getPersistedOrgId } from './store'\nimport { decideWorkspaceChoice, getAutoPick, takeWorkspaceSwitch } from './choice'\nimport { usePermissionsStore } from '../permissions'\nimport { useHouseCurrencySync } from '../units/useHouseCurrencySync'\nimport {\n ORG_CACHE_TTL_MS,\n clearOrgSnapshot,\n isSnapshotFresh,\n patchOrgSnapshot,\n readOrgSnapshot,\n saveOrgSnapshot,\n type OrgSnapshot,\n} from './cache'\n\n// ---------------------------------------------------------------------------\n// Adapter context\n// ---------------------------------------------------------------------------\n\nconst OrgAdapterContext = React.createContext<OrgAdapter | null>(null)\n\nexport function useOrgAdapter(): OrgAdapter {\n const adapter = React.useContext(OrgAdapterContext)\n if (!adapter) {\n throw new Error('useOrgAdapter must be used within an <OrgProvider>')\n }\n return adapter\n}\n\nexport function useOrgAdapterOptional(): OrgAdapter | null {\n return React.useContext(OrgAdapterContext)\n}\n\n// ---------------------------------------------------------------------------\n// Tenant / org hook\n// ---------------------------------------------------------------------------\n\nexport interface TenantContext {\n /** The currently active organization */\n org: Organization | null\n /** All orgs the current user belongs to */\n userOrgs: OrgMembership[]\n loading: boolean\n /**\n * The bootstrap has finished at least once, so `org === null` now MEANS\n * \"belongs to no workspace\" instead of \"we have not looked yet\".\n *\n * `loading` cannot answer that: it starts `false`, before the effect that\n * loads anything has run. Anything deciding what to render from an empty org\n * — the setup gate — reads this, or it decides during the gap and flips its\n * mind a frame later.\n */\n settled: boolean\n /**\n * The membership list was actually READ for this account, and answered.\n *\n * Distinct from `settled`, which only says the wait is over — it is set in a\n * `finally`, so a failed `listUserOrgs` settles too. Anything that treats\n * \"no orgs\" as a FACT (the first-run setup gate) has to ask this instead.\n */\n orgsKnown: boolean\n /**\n * A leitura das contas FALHOU — e falhou é diferente de \"não tem nenhuma\".\n *\n * `orgsKnown: false` já dizia \"não sabemos\", mas dizia isso também no\n * instante antes de saber, então ninguém podia agir nele. Sem esta mensagem\n * um erro de rede chegava na tela como um sistema de uma linha só e um\n * seletor oferecendo \"criar área de trabalho\" — a resposta errada,\n * apresentada com a mesma cara da certa.\n */\n loadError: string | null\n /** Tenta ler as contas de novo, depois de uma falha. */\n retryOrgs: () => void\n /** Switch the active org */\n switchOrg: (orgId: string) => Promise<void>\n /** Refresh the current org from the adapter */\n refreshOrg: () => Promise<void>\n}\n\nconst TenantContext = React.createContext<TenantContext | null>(null)\n\n/**\n * Access the current tenant / organization.\n * Must be used inside <OrgProvider>.\n */\nexport function useTenant(): TenantContext {\n const ctx = React.useContext(TenantContext)\n if (!ctx) {\n throw new Error('useTenant must be used inside <OrgProvider>')\n }\n return ctx\n}\n\nexport function useTenantOptional(): TenantContext | null {\n return React.useContext(TenantContext)\n}\n\n// ---------------------------------------------------------------------------\n// Provider\n// ---------------------------------------------------------------------------\n\nexport interface OrgProviderProps {\n adapter: OrgAdapter\n /** When true, automatically creates an org if the user has none */\n autoCreate?: boolean\n /**\n * How long the cached org bootstrap is served before the provider goes back\n * to the network (default 5 min). A cached load paints synchronously, so\n * screens that key off `org.id` don't wait a round trip on every reload.\n * `0` disables the cache and restores the always-fetch behaviour.\n */\n cacheTtlMs?: number\n children: React.ReactNode\n}\n\nconst useIsomorphicLayoutEffect =\n typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect\n\nexport function OrgProvider({\n adapter,\n autoCreate = false,\n cacheTtlMs = ORG_CACHE_TTL_MS,\n children,\n}: OrgProviderProps) {\n const { user, isLoading: authLoading } = useAuthStore()\n const { currentOrg, userOrgs, loading, setCurrentOrg, paintCurrentOrg, setUserOrgs, setMembers, setLoading, reset } =\n useOrganizationStore()\n const setProfiles = usePermissionsStore((s) => s.setProfiles)\n const setCurrentProfile = usePermissionsStore((s) => s.setCurrentProfile)\n const setProfileKnownFor = usePermissionsStore((s) => s.setProfileKnownFor)\n\n const adapterRef = React.useRef(adapter)\n adapterRef.current = adapter\n\n const [snapshot] = React.useState<OrgSnapshot | null>(() =>\n cacheTtlMs > 0 ? readOrgSnapshot() : null,\n )\n // One load per signed-in user per mount — auth reports `isLoading` and `user`\n // in two separate store writes, so the effect would otherwise fire twice.\n const loadedForRef = React.useRef<string | null>(null)\n\n // WHOSE bootstrap has finished, not whether one has. A boolean could not tell\n // the difference between \"we know this account has no workspace\" and \"we knew\n // that about the account that just signed out\" — which is what flashed the\n // setup flow over every login: sign-out settled it, and sign-in kept the\n // stale `true` for the whole round trip.\n //\n // A painted snapshot is already an answer for its own user: that account HAS a\n // workspace, and revalidation will not turn that into \"has none\".\n const [settledFor, setSettledFor] = React.useState<string | null>(() =>\n snapshot?.org ? snapshot.userId : null,\n )\n // Same shape, different question: WHOSE membership list came back. Seeded\n // from a painted snapshot for the same reason — that account's list was read\n // once and cached, and revalidation cannot turn \"has one\" into \"has none\".\n const [orgsReadFor, setOrgsReadFor] = React.useState<string | null>(() =>\n snapshot?.org ? snapshot.userId : null,\n )\n // Signed out there is nothing to wait for; signed in, only this user's answer counts.\n const [loadError, setLoadError] = React.useState<string | null>(null)\n const [retryTick, setRetryTick] = React.useState(0)\n const retryOrgs = React.useCallback(() => {\n // `loadedForRef` é o que impede a releitura; zerá-lo é o que faz o efeito\n // abaixo rodar de novo para o mesmo usuário.\n loadedForRef.current = null\n setLoadError(null)\n setRetryTick((n) => n + 1)\n }, [])\n\n const settled = user ? settledFor === user.id : !authLoading\n const orgsKnown = !!user && orgsReadFor === user.id\n\n // Paint the last known org before the first child renders. The stores are\n // filled in a layout effect, so nothing gets a frame with `org === null`.\n useIsomorphicLayoutEffect(() => {\n if (!snapshot) return\n setUserOrgs(snapshot.userOrgs)\n // PINTA, não decide. Ver `paintCurrentOrg`: gravar o pino aqui fazia o\n // cache vencer a escolha, e a conta voltava sozinha a cada boot.\n paintCurrentOrg(snapshot.org)\n setMembers(snapshot.members)\n setProfiles(snapshot.profiles)\n setCurrentProfile(snapshot.profiles.find((p) => p.id === snapshot.currentProfileId) ?? null)\n // O snapshot É uma resposta: quem entra por ele já sabe quem é.\n setProfileKnownFor(snapshot.org.id)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n // Keep the snapshot in step with store writes made outside this provider —\n // renaming the org in Settings, editing a role — so the cache never serves a\n // value the user already changed on screen. Patching leaves `savedAt` alone:\n // a UI-only edit must not push the next revalidation further out.\n React.useEffect(() => {\n if (cacheTtlMs <= 0 || !user) return\n const uid = user.id\n const sync = () => {\n const org = useOrganizationStore.getState()\n if (!org.currentOrg) return\n const perms = usePermissionsStore.getState()\n patchOrgSnapshot({\n userId: uid,\n org: org.currentOrg,\n userOrgs: org.userOrgs,\n members: org.members,\n profiles: perms.profiles,\n // realProfile, not currentProfile: an impersonation preview is not\n // something to cache back as the user's own role.\n currentProfileId: perms.realProfile?.id ?? null,\n })\n }\n const unsubscribeOrg = useOrganizationStore.subscribe(sync)\n const unsubscribePerms = usePermissionsStore.subscribe(sync)\n return () => {\n unsubscribeOrg()\n unsubscribePerms()\n }\n }, [user?.id, cacheTtlMs])\n\n // Load the org's members + permission profiles into the shared stores whenever\n // an org resolves. This is what makes the role list, the invite dialog's role\n // dropdown, and permission checks work — previously nothing loaded them here,\n // so those surfaces came up empty. Also resolves the signed-in user's own role.\n const hydrateOrg = React.useCallback(\n async (org: Organization, memberships: OrgMembership[], uid: string | undefined) => {\n try {\n const [members, profiles] = await Promise.all([\n adapterRef.current.listMembers(org.id),\n adapterRef.current.listProfiles(org.id),\n ])\n setMembers(members)\n setProfiles(profiles)\n const myMembership = uid ? members.find((m) => m.userId === uid) : undefined\n const profile = profiles.find((p) => p.id === myMembership?.profileId) ?? null\n setCurrentProfile(profile)\n // Everything the next reload needs, stamped now — this is the only\n // place the TTL window restarts.\n if (cacheTtlMs > 0 && uid) {\n saveOrgSnapshot({\n userId: uid,\n org,\n userOrgs: memberships,\n members,\n profiles,\n currentProfileId: profile?.id ?? null,\n })\n }\n } catch {\n // Non-fatal — leave stores as-is if the load fails.\n } finally {\n // Respondida é respondida, mesmo que a resposta seja \"nenhum papel\" ou\n // que a leitura tenha falhado. Segurar a tela para sempre esperando uma\n // resposta que não vem é pior que mostrar o que se sabe.\n setProfileKnownFor(org.id)\n }\n },\n [setMembers, setProfiles, setCurrentProfile, setProfileKnownFor, cacheTtlMs],\n )\n\n // Load orgs when user is authenticated\n React.useEffect(() => {\n if (!user) {\n // A cold load reports `user === null` while the session hydrates — that's\n // not a sign-out, so the painted snapshot stands until auth settles.\n if (authLoading) return\n loadedForRef.current = null\n reset()\n clearOrgSnapshot()\n setSettledFor(null)\n setOrgsReadFor(null)\n return\n }\n\n const cached = snapshot?.userId === user.id ? snapshot : null\n\n // Already painted and still inside its window: skip the whole bootstrap.\n if (cached && isSnapshotFresh(cached, cacheTtlMs)) {\n setSettledFor(user.id)\n setOrgsReadFor(user.id)\n return\n }\n\n // A snapshot from another account was painted — drop it before loading.\n if (snapshot && snapshot.userId !== user.id && loadedForRef.current === null) {\n reset()\n clearOrgSnapshot()\n }\n\n if (loadedForRef.current === user.id) return\n loadedForRef.current = user.id\n\n // Stale but painted: revalidate quietly, so screens keep the data they're\n // showing instead of flipping back to a skeleton.\n const silent = !!cached\n\n let cancelled = false\n\n async function loadOrgs() {\n if (!silent) setLoading(true)\n try {\n // Redeem invites first — an invitee has no membership until this runs,\n // and without it autoCreate below would hand them a personal org\n // instead of the one that invited them.\n let accepted = 0\n try {\n // Viewing as someone must not redeem THEIR pending invites.\n if (!isImpersonating()) accepted = (await adapterRef.current.acceptPendingInvites?.()) ?? 0\n } catch {\n // Non-fatal: fall through and load whatever memberships exist.\n }\n\n if (cancelled) return\n\n let memberships = await adapterRef.current.listUserOrgs(user!.id)\n\n // An empty list right after accepting means the read was deduped onto a\n // request that started before the invite landed. Ask once more.\n if (memberships.length === 0 && accepted > 0) {\n memberships = await adapterRef.current.listUserOrgs(user!.id)\n }\n\n // UMA LISTA VAZIA É A ÚNICA RESPOSTA QUE MERECE DÚVIDA.\n //\n // Ela é a que decide se esta conta entra no aplicativo ou no fluxo de\n // criação de área de trabalho — e é também a única que a infraestrutura\n // consegue produzir por engano. A leitura passa por RLS: sem a sessão\n // ainda aplicada, a política simplesmente não casa com nenhuma linha e\n // a resposta é `200 []`, indistinguível de \"esta conta não tem nenhuma\".\n // Logo depois do login essa janela existe, e o sintoma é exatamente o\n // relatado: o assistente de criação aparece sozinho e some no refresh.\n //\n // Perguntar de novo é o único jeito de separar as duas. Custa duas\n // requisições e menos de um segundo, e só para quem de fato não tem\n // workspace nenhum — que é uma vez na vida da conta. O erro na outra\n // direção custa o aplicativo inteiro coberto por um fluxo do qual não\n // se sai.\n for (let attempt = 0; memberships.length === 0 && attempt < 2; attempt++) {\n await new Promise((resolve) => setTimeout(resolve, 250 * (attempt + 1)))\n if (cancelled) return\n memberships = await adapterRef.current.listUserOrgs(user!.id)\n }\n\n if (cancelled) return\n\n setUserOrgs(memberships)\n // The read answered. Everything after this can still fail without\n // turning \"this account has no workspace\" into a guess.\n setOrgsReadFor(user!.id)\n\n // Auto-create org if user has none\n if (memberships.length === 0 && accepted === 0 && autoCreate) {\n const newOrg = await adapterRef.current.createOrg(\n user!.fullName ? `${user!.fullName}'s Organization` : 'My Organization',\n user!.id,\n )\n if (!cancelled) {\n const ownMembership: OrgMembership[] = [\n {\n orgId: newOrg.id,\n orgName: newOrg.name,\n orgSlug: newOrg.slug,\n profileId: 'owner',\n profileName: 'Owner',\n },\n ]\n setUserOrgs(ownMembership)\n setCurrentOrg(newOrg)\n await hydrateOrg(newOrg, ownMembership, user!.id)\n }\n return\n }\n\n // Which workspace to open — or whether to open one at all. The ladder\n // lives in `decideWorkspaceChoice`; the only branch that changed shape\n // here is the last one. It used to be `?? memberships[0]`, which turned\n // \"we do not know which of your seven accounts you meant\" into a silent\n // guess the user could not see, let alone correct.\n const choice = decideWorkspaceChoice({\n memberships,\n // Consumed here, and only here: this is the one boot the marker was\n // written for, and leaving it behind would pin the next one too.\n switchingToId: takeWorkspaceSwitch(),\n handoffId: readAppHandoff()?.tenantId ?? null,\n pinnedId: getPersistedOrgId(),\n autoPick: getAutoPick(),\n })\n\n // Leaving `currentOrg` null IS the ask: the chooser gate reads exactly\n // this state — a membership list we have read, more than one row in it,\n // and no active workspace — so no extra flag has to be kept in sync.\n if (choice.kind !== 'resolved') return\n\n if (!cancelled) {\n const org = await adapterRef.current.getOrg(choice.orgId)\n if (!cancelled) {\n setCurrentOrg(org)\n await hydrateOrg(org, memberships, user!.id)\n }\n }\n } catch (err) {\n // Engolir aqui era o defeito: a lista ficava vazia, `orgsKnown` ficava\n // falso, e a tela não tinha como distinguir isso de uma conta nova.\n if (!cancelled) setLoadError(errorMessage(err))\n } finally {\n if (!cancelled && !silent) setLoading(false)\n // Settled even when the load threw: the answer is then \"we asked and\n // could not tell\", and holding the screen forever is worse than showing\n // the app. It is about the wait being over, not about success.\n if (!cancelled) setSettledFor(user!.id)\n }\n }\n\n void loadOrgs()\n\n return () => {\n cancelled = true\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [user?.id, authLoading, retryTick])\n\n async function switchOrg(orgId: string): Promise<void> {\n setLoading(true)\n try {\n const org = await adapterRef.current.getOrg(orgId)\n setCurrentOrg(org)\n await hydrateOrg(org, useOrganizationStore.getState().userOrgs, user?.id)\n } finally {\n setLoading(false)\n }\n }\n\n // Explicit refresh always goes to the network and restarts the cache window.\n async function refreshOrg(): Promise<void> {\n if (!currentOrg) return\n setLoading(true)\n try {\n const org = await adapterRef.current.getOrg(currentOrg.id)\n setCurrentOrg(org)\n await hydrateOrg(org, useOrganizationStore.getState().userOrgs, user?.id)\n } finally {\n setLoading(false)\n }\n }\n\n useHouseCurrencySync(currentOrg?.id, (currentOrg?.settings as { currency?: string } | undefined)?.currency)\n\n const tenantValue: TenantContext = {\n org: currentOrg,\n userOrgs,\n loading,\n settled,\n orgsKnown,\n loadError,\n retryOrgs,\n switchOrg,\n refreshOrg,\n }\n\n return (\n <OrgAdapterContext.Provider value={adapter}>\n <TenantContext.Provider value={tenantValue}>\n {children}\n </TenantContext.Provider>\n </OrgAdapterContext.Provider>\n )\n}\n","// ---------------------------------------------------------------------------\n// workspace-search — achar a conta numa lista que não cabe na tela.\n//\n// Com quinze contas o seletor já passava do rodapé: a lista empurrava \"Nova\n// área de trabalho\" e a seção de Unidades para fora da janela, e achar uma\n// conta virava rolar um menu procurando por reconhecimento visual. Numa rede de\n// franquias isso não é quinze, é duzentas.\n//\n// ── Por que um teto E uma busca, e não só um deles ─────────────────────────\n// Só teto esconde contas sem oferecer caminho. Só busca obriga a digitar mesmo\n// quando há três contas. Juntos: quem tem poucas contas nunca vê a caixa, e\n// quem tem muitas vê as primeiras e um campo — que é como todo seletor de conta\n// grande funciona.\n// ---------------------------------------------------------------------------\n\n/** Acima disto o seletor oferece busca. Abaixo, a lista inteira cabe. */\nexport const WORKSPACE_SEARCH_THRESHOLD = 8\n\n/** Quantas linhas o menu mostra de uma vez quando há busca. */\nexport const WORKSPACE_VISIBLE_LIMIT = 7\n\n/** Sem acento e sem caixa: quem procura \"Espaco\" tem de achar \"Espaço\". */\nexport function foldName(value: string): string {\n return value.normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase()\n}\n\nexport interface SearchableWorkspace {\n orgId: string\n orgName: string\n}\n\nexport interface WorkspaceSearchResult<T extends SearchableWorkspace> {\n /** As linhas a desenhar agora. */\n visible: T[]\n /** Quantas ficaram de fora do teto — 0 quando a lista coube inteira. */\n hidden: number\n /** A busca vale a pena nesta lista? */\n searchable: boolean\n}\n\n/**\n * Filtra e corta, mantendo a conta ATIVA sempre visível.\n *\n * Ela fica visível mesmo fora do teto e mesmo fora do filtro: o menu é também\n * onde se lê em que conta se está, e esconder a resposta dessa pergunta para\n * caber mais linha é trocar a pergunta principal pela secundária.\n */\nexport function searchWorkspaces<T extends SearchableWorkspace>(\n all: T[],\n query: string,\n currentId?: string | null,\n limit = WORKSPACE_VISIBLE_LIMIT,\n): WorkspaceSearchResult<T> {\n const searchable = all.length > WORKSPACE_SEARCH_THRESHOLD\n if (!searchable) return { visible: all, hidden: 0, searchable: false }\n\n const q = foldName(query.trim())\n const matched = q ? all.filter((w) => foldName(w.orgName).includes(q)) : all\n\n const current = all.find((w) => w.orgId === currentId)\n const head = current && !matched.includes(current) ? [current] : []\n const rest = matched.filter((w) => w.orgId !== current?.orgId)\n const ordered = current && matched.includes(current) ? [current, ...rest] : [...head, ...rest]\n\n return {\n visible: ordered.slice(0, limit),\n hidden: Math.max(0, ordered.length - limit),\n searchable: true,\n }\n}\n","import * as React from 'react'\nimport { OrgMark } from './OrgMark'\nimport type { OrgMembership } from '@fayz-ai/core'\nimport { useTranslation } from '@fayz-ai/core'\nimport { Button, Checkbox, cn, Input } from '@fayz-ai/ui'\nimport { Building2, Check } from 'lucide-react'\nimport { useTenant } from './context'\nimport { setAutoPick } from './choice'\nimport { searchWorkspaces } from './workspace-search'\n\nexport interface WorkspaceChooserProps {\n /** Every workspace this account can open in THIS app. */\n memberships: OrgMembership[]\n /** The last one this browser was in — pre-selected, not auto-entered. */\n suggestedId: string | null\n /** Present only when there is a workspace to go back to (the switcher route). */\n onCancel?: () => void\n}\n\n/**\n * \"Which of your workspaces?\" — asked once, on the way in.\n *\n * Deliberately a full screen rather than a dialog. Behind it the shell would be\n * rendering an account nobody has chosen yet, and every plugin on it would be\n * firing tenant-scoped requests against that guess; a dialog implies there is\n * something valid underneath, and there is not.\n */\nexport function WorkspaceChooser({ memberships, suggestedId, onCancel }: WorkspaceChooserProps) {\n const t = useTranslation()\n const tr = (key: string, fallback: string) => {\n const v = t(key)\n return !v || v === key ? fallback : v\n }\n\n const { switchOrg } = useTenant()\n const [selected, setSelected] = React.useState<string | null>(\n suggestedId ?? memberships[0]?.orgId ?? null,\n )\n // Off by default, deliberately, for as long as this flow is being validated:\n // asking every time is a second of friction, and silently opening the wrong\n // account is a support ticket. Opting out stays available; it is just not\n // something anyone gets handed without choosing it.\n const [remember, setRemember] = React.useState(false)\n const [query, setQuery] = React.useState('')\n // Teto MAIOR que o do menu: aqui a lista é a tela inteira, não um popover\n // espremido entre o gatilho e o rodapé.\n const search = React.useMemo(\n () => searchWorkspaces(memberships, query, selected, 12),\n [memberships, query, selected],\n )\n const [entering, setEntering] = React.useState(false)\n\n const enter = async (orgId: string) => {\n if (entering) return\n setEntering(true)\n // The preference is written BEFORE the switch: switchOrg re-renders this\n // component out of existence, so anything queued after it may never run.\n setAutoPick(remember)\n try {\n await switchOrg(orgId)\n } finally {\n setEntering(false)\n }\n }\n\n return (\n <div className=\"flex min-h-screen items-center justify-center bg-background p-4\">\n <div className=\"w-full max-w-md\">\n <div className=\"mb-6 text-center\">\n <h1 className=\"text-xl font-semibold text-foreground\">\n {tr('organization.chooseWorkspace', 'Escolha uma área de trabalho')}\n </h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {tr(\n 'organization.chooseWorkspaceDescription',\n 'Você tem acesso a mais de uma. Selecione em qual deseja entrar.',\n )}\n </p>\n </div>\n\n {/* A lista cresce com a rede de franquias; a tela, não. Ver\n ./workspace-search — e a mesma caixa está no seletor do rail, de\n propósito: é a mesma pergunta, feita antes e depois de entrar. */}\n {search.searchable && (\n <Input\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={tr('organization.searchWorkspace', 'Buscar conta…')}\n autoFocus\n wrapperClassName=\"mb-3\"\n className=\"rounded-lg border-border shadow-none focus:border-primary focus-visible:ring-0 focus-visible:ring-offset-0\"\n />\n )}\n\n <div\n role=\"radiogroup\"\n aria-label={tr('organization.workspaces', 'Workspaces')}\n className=\"space-y-2\"\n >\n {search.visible.length === 0 && (\n <p className=\"py-6 text-center text-sm text-muted-foreground\">\n {tr('organization.noWorkspaceMatch', 'Nenhuma conta com esse nome.')}\n </p>\n )}\n {search.visible.map((m) => {\n const isSelected = m.orgId === selected\n const isSuggested = m.orgId === suggestedId\n return (\n <Button\n variant=\"bare\"\n size=\"bare\"\n key={m.orgId}\n type=\"button\"\n role=\"radio\"\n aria-checked={isSelected}\n disabled={entering}\n onClick={() => setSelected(m.orgId)}\n // A double click should not have to become a click and a\n // journey down to the button.\n onDoubleClick={() => void enter(m.orgId)}\n className={cn(\n 'flex w-full items-center gap-3 rounded-lg border p-3 text-left transition-colors justify-start whitespace-normal text-[length:inherit] font-normal',\n 'disabled:opacity-60',\n isSelected\n ? 'border-primary bg-primary/5'\n : 'border-border hover:border-primary/50 hover:bg-muted/50',\n )}\n >\n <OrgMark name={m.orgName} logoUrl={m.orgLogoUrl} tone=\"popover\" className=\"h-9 w-9\" />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm font-medium text-foreground\">\n {m.orgName || m.orgSlug || m.orgId}\n </span>\n <span className=\"block truncate text-xs text-muted-foreground\">\n {m.profileName}\n {isSuggested && ` · ${tr('organization.lastUsed', 'último acesso')}`}\n </span>\n </span>\n {isSelected && <Check className=\"h-4 w-4 shrink-0 text-primary\" />}\n </Button>\n )\n })}\n </div>\n {search.hidden > 0 && (\n <p className=\"mt-3 text-center text-xs text-muted-foreground\">\n {tr('organization.moreWorkspaces', 'mais {n} — busque pelo nome').replace('{n}', String(search.hidden))}\n </p>\n )}\n\n {/* Not a <label>: Checkbox renders a <button>, and a label does not\n forward its click to one. The text carries its own handler instead,\n outside the button, so neither click double-toggles the other. */}\n <div className=\"mt-5 flex items-center gap-2.5 text-sm text-muted-foreground\">\n <Checkbox\n checked={remember}\n onChange={setRemember}\n disabled={entering}\n aria-label={tr('organization.rememberChoice', 'Não perguntar novamente neste dispositivo')}\n />\n <span className=\"cursor-pointer select-none\" onClick={() => !entering && setRemember(!remember)}>\n {tr('organization.rememberChoice', 'Não perguntar novamente neste dispositivo')}\n </span>\n </div>\n\n <div className=\"mt-5 flex gap-2\">\n {onCancel && (\n <Button variant=\"outline\" className=\"flex-1\" onClick={onCancel} disabled={entering}>\n {tr('common.cancel', 'Cancelar')}\n </Button>\n )}\n <Button\n className=\"flex-1\"\n disabled={!selected || entering}\n onClick={() => selected && void enter(selected)}\n >\n {entering ? tr('common.loading', 'Entrando…') : tr('organization.enter', 'Entrar')}\n </Button>\n </div>\n\n {/* The escape hatch for the checkbox above: somebody who ticked it and\n later needs a different workspace has to be told where the question\n went, or \"do not ask again\" reads as \"never again\". */}\n <p className=\"mt-4 text-center text-xs text-muted-foreground\">\n {tr(\n 'organization.switchLaterHint',\n 'Você pode trocar a qualquer momento pelo seletor no topo da tela.',\n )}\n </p>\n </div>\n </div>\n )\n}\n\n/** The workspace's face, at picker size: its logo, or its initials. */\n","import { useEffect, useState } from 'react'\nimport { getSupabaseClientOptional } from '../lib/supabase'\n\n/**\n * De quem é este endereço.\n *\n * Um inquilino com domínio próprio não deveria escolher conta: ele digitou o\n * endereço DELE. O seletor \"escolha uma área de trabalho\" é a resposta certa\n * para quem entra por `app.fayz.ai` com cinco contas; para quem entra por\n * `sistema.espacofacial.com.br` ele é uma pergunta cuja resposta já está na\n * barra de endereço.\n *\n * A porta é `tenant_branding_public`: anônima de propósito, porque a pergunta\n * vem ANTES da sessão — é ela que dá marca à tela de login e à loja pública.\n * Ela devolve só o recorte público (nome, slug, logo, cor, domínio); nada de\n * módulos, nada de ajustes, nada que não esteja na fachada do prédio.\n *\n * ── Em desenvolvimento ─────────────────────────────────────────────────────\n * `localhost` não tem domínio para resolver, então `?domain=` simula um. Só em\n * DEV: em produção o endereço é a única fonte, e um parâmetro que troca de\n * conta seria uma porta aberta na frente da casa.\n */\nexport interface DomainTenant {\n tenantId: string\n name: string | null\n slug: string | null\n logoUrl: string | null\n primaryColor: string | null\n}\n\nconst LOCAL = /^(localhost|127\\.0\\.0\\.1|\\[::1\\])$/\n\nexport function resolveHostname(): string | null {\n if (typeof window === 'undefined') return null\n const host = window.location.hostname\n if (!LOCAL.test(host)) return host\n if (!import.meta.env?.DEV) return null\n return new URLSearchParams(window.location.search).get('domain')\n}\n\nexport function useDomainTenant(): { tenant: DomainTenant | null; resolving: boolean } {\n const [tenant, setTenant] = useState<DomainTenant | null>(null)\n const [resolving, setResolving] = useState(true)\n\n useEffect(() => {\n const host = resolveHostname()\n const supabase = getSupabaseClientOptional()\n if (!host || !supabase) {\n setResolving(false)\n return\n }\n let cancelled = false\n void (async () => {\n try {\n const { data } = await supabase.rpc('tenant_branding_public', { p_domain: host })\n const row = data as Record<string, unknown> | null\n const id = typeof row?.tenant_id === 'string' ? row.tenant_id : null\n if (!cancelled && id) {\n setTenant({\n tenantId: id,\n name: (row?.name as string) ?? null,\n slug: (row?.slug as string) ?? null,\n logoUrl: (row?.logo_url as string) ?? null,\n primaryColor: (row?.primary_color as string) ?? null,\n })\n }\n } catch {\n // Um domínio que não resolve não é erro: é o caso comum de quem entra\n // pelo endereço do produto. O seletor segue sendo a resposta.\n } finally {\n if (!cancelled) setResolving(false)\n }\n })()\n return () => {\n cancelled = true\n }\n }, [])\n\n return { tenant, resolving }\n}\n","import * as React from 'react'\nimport { getPersistedOrgId } from './store'\nimport { useTenantOptional } from './context'\nimport { WorkspaceChooser } from './WorkspaceChooser'\nimport { useDomainTenant } from '../app/useDomainTenant'\n\nexport interface WorkspaceChooserGateProps {\n /** Held on screen while the membership list is still in flight. */\n fallback?: React.ReactNode\n children: React.ReactNode\n}\n\n/**\n * Puts the workspace picker in front of the shell when this account owes a\n * choice, and gets out of the way when it does not.\n *\n * There is no new state to keep: `decideWorkspaceChoice` already refuses to\n * pick for the provider in exactly this case, so \"a list we have read, more\n * than one row in it, and no active workspace\" IS the question being open.\n * A separate flag would be a second copy of that fact, free to disagree.\n *\n * Mounted between the setup gate and the shell: an account with NO workspace\n * belongs to the setup flow (there is nothing to choose from), and an account\n * with one never sees this at all.\n */\nexport function WorkspaceChooserGate({ fallback, children }: WorkspaceChooserGateProps) {\n const tenant = useTenantOptional()\n // Quem entra pelo PRÓPRIO domínio não escolhe conta: ele já respondeu a\n // pergunta na barra de endereço. Ver ../app/useDomainTenant.ts.\n const { tenant: byDomain, resolving: resolvingDomain } = useDomainTenant()\n const switchOrg = tenant?.switchOrg\n const entering = React.useRef(false)\n\n React.useEffect(() => {\n if (!byDomain || !tenant?.orgsKnown || tenant.org || !switchOrg || entering.current) return\n // Só entra se a pessoa for MEMBRO. O domínio diz de quem é a casa; quem\n // pode entrar continua sendo a membership — um endereço nunca concede\n // acesso, só escolhe entre as contas que já são dela.\n if (!tenant.userOrgs.some((m) => m.orgId === byDomain.tenantId)) return\n // Pelo MESMO caminho do seletor. Montar a organização à mão aqui deixava de\n // fora `settings` — e sem settings não há marca, não há tema, e o shell\n // ficava preso na moldura do bundle.\n entering.current = true\n void switchOrg(byDomain.tenantId)\n }, [byDomain, tenant?.orgsKnown, tenant?.org, tenant?.userOrgs, switchOrg])\n\n if (!tenant) return <>{children}</>\n\n const { org, userOrgs, orgsKnown, settled } = tenant\n\n // Already in a workspace — nothing to ask.\n if (org) return <>{children}</>\n\n // Hold rather than hand over, for the same reason the setup gate does: the\n // shell would paint an account-shaped app and fire every plugin's\n // tenant-scoped request against no tenant, then be replaced.\n if (!settled) return <>{fallback ?? null}</>\n\n // \"We asked and could not tell\" is not \"you have several\". Only a list we\n // actually read can raise this screen; anything else falls through to the\n // shell, which is where the existing empty-switcher behaviour already lives.\n if (!orgsKnown || userOrgs.length <= 1) return <>{children}</>\n\n // O domínio ainda está sendo resolvido, ou já resolveu numa conta que a\n // pessoa tem: segurar em vez de perguntar. Mostrar o seletor e trocá-lo por\n // uma conta um instante depois é a pergunta feita e respondida sozinha.\n if (resolvingDomain) return <>{fallback ?? null}</>\n if (byDomain && userOrgs.some((m) => m.orgId === byDomain.tenantId)) return <>{fallback ?? null}</>\n\n return (\n <WorkspaceChooser\n memberships={userOrgs}\n suggestedId={\n userOrgs.some((m) => m.orgId === getPersistedOrgId()) ? getPersistedOrgId() : null\n }\n />\n )\n}\n","import { create } from 'zustand'\nimport { clearOrgSnapshot } from './cache'\nimport { markWorkspaceSwitch } from './choice'\nimport { persistOrgId } from './store'\n\nexport interface SwitchTarget {\n orgId: string\n orgName: string\n /** So the transition shows the same mark the switcher row did. */\n orgLogoUrl?: string\n}\n\nexport interface WorkspaceSwitchingStore {\n /** The workspace being entered, while the transition is on screen. */\n target: SwitchTarget | null\n /** Commit to a workspace and raise the transition. Ends in a reload. */\n begin: (target: SwitchTarget) => void\n cancel: () => void\n}\n\n/**\n * Changing workspace, as a two-phase move: commit now, rebuild on the far side\n * of a reload.\n *\n * Switching in place was the alternative and it does not work. `switchOrg`\n * swaps the active tenant and re-hydrates the org, but every plugin store, the\n * offline cache and whatever screen is open still hold the PREVIOUS tenant's\n * rows, and nothing invalidates them centrally. The result is a shell that says\n * one workspace while the table under it lists another's — a tenant boundary\n * failure as far as anyone reading the screen is concerned, even though the\n * database never leaked a row.\n */\nexport const useWorkspaceSwitchingStore = create<WorkspaceSwitchingStore>((set) => ({\n target: null,\n\n begin: (target) => {\n // Order matters, and all three have to happen BEFORE the reload:\n // the marker — so the picker does not re-ask what was just answered\n // the pin — so \"last used\" is the workspace being entered\n // the snapshot— or the cached bootstrap of the OLD workspace paints\n // first on the far side and the switch silently undoes\n // itself.\n markWorkspaceSwitch(target.orgId)\n persistOrgId(target.orgId)\n clearOrgSnapshot()\n // ...e a paleta de boot, que é a QUARTA coisa que atravessa o reload.\n //\n // O `@fayz-ai/sdk` guarda a paleta resolvida para o boot seguinte pintar na\n // cor do aplicativo em vez de num cinza neutro. Numa troca de conta essa\n // paleta é a da conta ANTERIOR: sem limpá-la, o primeiro quadro do lado de\n // lá é a marca de quem se acabou de sair — e agora que a casca de boot\n // desenha a trilha, essa cor errada ocupa um quinto da tela.\n try { localStorage.removeItem('fayz:boot-theme') } catch { /* modo privado */ }\n set({ target })\n },\n\n cancel: () => set({ target: null }),\n}))\n","import * as React from 'react'\nimport { OrgMark } from './OrgMark'\nimport { useTranslation } from '@fayz-ai/core'\nimport { Check, ShieldCheck, Building2 } from 'lucide-react'\nimport { cn } from '@fayz-ai/ui'\n\n/** How long each step holds before the next one starts. */\nconst STEP_MS = 850\n\nexport interface WorkspaceSwitchingProps {\n /** The workspace being entered, named — the one fact that makes this concrete. */\n orgName: string\n /** Its logo, when it has one. */\n orgLogoUrl?: string\n /** Runs once the last step has been shown. Reloads the page, in practice. */\n onDone: () => void\n}\n\n/**\n * The screen between two workspaces.\n *\n * Changing tenant ends in a full reload, because half the app holds the old\n * tenant's rows in plugin stores and caches that nothing else invalidates. A\n * reload with no cover reads as a crash — the app blanks, comes back, and the\n * numbers are different. This covers it and says what is happening, so the\n * second it costs is spent visibly rather than suspiciously.\n *\n * Sized like a moment, not a toast: the workspace name is the largest thing on\n * screen because it is the answer to the only question anyone has here — where\n * am I about to be. The steps are honest about the order of operations, and the\n * last one is a security claim, so it gets an icon rather than another dot.\n */\nexport function WorkspaceSwitching({ orgName, orgLogoUrl, onDone }: WorkspaceSwitchingProps) {\n const t = useTranslation()\n const tr = (key: string, fallback: string) => {\n const v = t(key)\n return !v || v === key ? fallback : v\n }\n\n const steps = React.useMemo(\n () => [\n tr('organization.switching.step1', 'Alterando organização'),\n tr('organization.switching.step2', 'Garantindo segurança dos dados'),\n tr('organization.switching.step3', 'Carregando suas informações'),\n ],\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n )\n\n const [step, setStep] = React.useState(0)\n\n // One timer that advances, then hands over — not one timer per step, which\n // would leak a reload if the component unmounted between two of them.\n const doneRef = React.useRef(onDone)\n doneRef.current = onDone\n React.useEffect(() => {\n const id = window.setInterval(() => {\n setStep((s) => {\n if (s < steps.length - 1) return s + 1\n window.clearInterval(id)\n // Out of the interval callback: the reload tears down this tree, and\n // React does not want that happening inside a state updater.\n window.setTimeout(() => doneRef.current(), STEP_MS)\n return s\n })\n }, STEP_MS)\n return () => window.clearInterval(id)\n }, [steps.length])\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-label={`${steps[step]} — ${orgName}`}\n className=\"saas-switch-veil fixed inset-0 z-[100] flex items-center justify-center bg-background px-6\"\n >\n <div className=\"saas-switch-rise flex w-full max-w-sm flex-col items-center\">\n {/* The mark, with the loading indicator as a ring around it rather than\n a spinner beside it — one object doing both jobs. */}\n <div className=\"relative flex h-20 w-20 items-center justify-center\">\n <span\n aria-hidden\n className=\"saas-switch-pulse absolute inset-0 rounded-2xl bg-primary/25\"\n />\n <OrgMark name={orgName} logoUrl={orgLogoUrl} tone=\"popover\" className=\"h-16 w-16 rounded-2xl shadow-sm\" />\n </div>\n\n <p className=\"mt-7 text-xs font-medium uppercase tracking-[0.14em] text-muted-foreground\">\n {tr('organization.switching.eyebrow', 'Entrando em')}\n </p>\n {/* The largest thing here on purpose. Balanced leading and a wrap\n rather than an ellipsis: a truncated workspace name is exactly the\n reassurance this screen exists to give, cut in half. */}\n <h1 className=\"mt-1.5 text-pretty text-center text-3xl font-semibold leading-tight tracking-tight text-foreground sm:text-4xl\">\n {orgName}\n </h1>\n\n {/* Reserved height, top-aligned: the rows are written one at a time,\n and without a floor for the full list each arrival would shove the\n name and mark upward. The block stays put; only the list fills. */}\n <ul className=\"mt-9 flex w-full min-h-[7.5rem] flex-col items-start sm:min-h-[8.5rem]\">\n {steps.slice(0, step + 1).map((label, i) => {\n const done = i < step\n const isSecurity = i === 1\n return (\n <li key={label} className=\"saas-switch-step flex w-full gap-3\">\n {/* The rail: a thread down from the step above, then this\n step's own marker. */}\n <span className=\"flex w-6 shrink-0 flex-col items-center\">\n {i > 0 && (\n // Tinted, not `bg-border`: on a light surface the border\n // token is invisible at 1px, and this thread is the part\n // that makes three rows read as one advancing sequence\n // rather than three unrelated lines.\n <span aria-hidden className=\"saas-switch-link h-5 w-0.5 rounded-full bg-primary/30\" />\n )}\n <span className=\"flex h-7 w-6 items-center justify-center\">\n {done ? (\n <Check className=\"h-5 w-5 text-primary\" strokeWidth={2.5} />\n ) : isSecurity ? (\n <ShieldCheck className=\"saas-switch-dot h-5 w-5 text-primary\" strokeWidth={2} />\n ) : (\n <span className=\"saas-switch-dot h-2 w-2 rounded-full bg-primary\" />\n )}\n </span>\n </span>\n <span\n className={cn(\n 'flex h-7 items-center text-base transition-colors duration-300 sm:text-lg',\n // Only ever two states now — done, or happening. Nothing is\n // on screen before its turn, so there is no \"ahead\" tone.\n done ? 'text-muted-foreground' : 'font-medium text-foreground',\n // Push the label down past the connector so it stays level\n // with its own marker rather than with the thread above it.\n i > 0 && 'mt-5',\n )}\n >\n {label}\n </span>\n </li>\n )\n })}\n </ul>\n </div>\n </div>\n )\n}\n\n","import * as React from 'react'\nimport { useWorkspaceSwitchingStore } from './switching.store'\nimport { WorkspaceSwitching } from './WorkspaceSwitching'\n\n/**\n * Renders the workspace transition over whatever is on screen, and performs the\n * reload it exists to cover.\n *\n * Mounted once, high in the shell: the switch can be started from the topbar\n * picker or from anywhere else that grows one, and none of those places should\n * own a full-screen overlay.\n */\nexport function WorkspaceSwitchingHost() {\n const target = useWorkspaceSwitchingStore((s) => s.target)\n if (!target) return null\n\n return (\n <WorkspaceSwitching\n orgName={target.orgName}\n orgLogoUrl={target.orgLogoUrl}\n // A full reload, not a router navigation: the point is to discard every\n // plugin store and cache still holding the previous tenant's rows, and\n // only a fresh document does that. `reload()` keeps the current URL, so\n // whoever switched lands on the same screen in the new workspace.\n onDone={() => window.location.reload()}\n />\n )\n}\n"]}
|