@fayz-ai/admin 0.18.0 → 0.19.1

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.
Files changed (238) hide show
  1. package/dist/CommandPalette-GQ6SPITD.js +297 -0
  2. package/dist/CommandPalette-GQ6SPITD.js.map +1 -0
  3. package/dist/{ScheduleEditor-63TVSCJC.js → ScheduleEditor-YZPOCBTW.js} +6 -6
  4. package/dist/{ScheduleEditor-63TVSCJC.js.map → ScheduleEditor-YZPOCBTW.js.map} +1 -1
  5. package/dist/SubscriptionPage-JXJ56OOH.js +8 -0
  6. package/dist/{SubscriptionPage-5PJ25YAD.js.map → SubscriptionPage-JXJ56OOH.js.map} +1 -1
  7. package/dist/access/headless.d.ts +2 -2
  8. package/dist/access/limits-registry.d.ts +6 -3
  9. package/dist/access/limits-registry.d.ts.map +1 -1
  10. package/dist/app/AdminShell.d.ts.map +1 -1
  11. package/dist/app/admin-app.d.ts.map +1 -1
  12. package/dist/app/settings-tabs.store.d.ts +21 -0
  13. package/dist/app/settings-tabs.store.d.ts.map +1 -0
  14. package/dist/billing/index.js +2 -2
  15. package/dist/{chunk-7DFJEXCR.js → chunk-5GWUM4SM.js} +3 -3
  16. package/dist/{chunk-7DFJEXCR.js.map → chunk-5GWUM4SM.js.map} +1 -1
  17. package/dist/{chunk-ERDS4OJS.js → chunk-HYDNIBN6.js} +3 -3
  18. package/dist/{chunk-ERDS4OJS.js.map → chunk-HYDNIBN6.js.map} +1 -1
  19. package/dist/{chunk-WN6PGQSG.js → chunk-NB6X5O5L.js} +81 -10
  20. package/dist/chunk-NB6X5O5L.js.map +1 -0
  21. package/dist/{chunk-LZRLWKJ2.js → chunk-UHHEPU4A.js} +379 -88
  22. package/dist/chunk-UHHEPU4A.js.map +1 -0
  23. package/dist/{chunk-VTEP2AQX.js → chunk-WJ3H3RJN.js} +5 -3
  24. package/dist/chunk-WJ3H3RJN.js.map +1 -0
  25. package/dist/{chunk-G5PBC5OB.js → chunk-ZNV7Q2TO.js} +8 -8
  26. package/dist/chunk-ZNV7Q2TO.js.map +1 -0
  27. package/dist/components/GetStarted.d.ts +45 -0
  28. package/dist/components/GetStarted.d.ts.map +1 -0
  29. package/dist/components/RightRail.d.ts.map +1 -1
  30. package/dist/components/TeachMe.d.ts +83 -0
  31. package/dist/components/TeachMe.d.ts.map +1 -0
  32. package/dist/components/auth/SplitLogin.d.ts.map +1 -1
  33. package/dist/components/billing/SoftLimitProbes.d.ts +5 -0
  34. package/dist/components/billing/SoftLimitProbes.d.ts.map +1 -0
  35. package/dist/components/billing/SoftLimitWidget.d.ts +3 -0
  36. package/dist/components/billing/SoftLimitWidget.d.ts.map +1 -0
  37. package/dist/components/billing/index.d.ts +3 -1
  38. package/dist/components/billing/index.d.ts.map +1 -1
  39. package/dist/components/billing/soft-limit.store.d.ts +23 -0
  40. package/dist/components/billing/soft-limit.store.d.ts.map +1 -0
  41. package/dist/components/chat/ChatConversation.d.ts.map +1 -1
  42. package/dist/components/chat/ChatHistory.d.ts.map +1 -1
  43. package/dist/components/chat/ChatMessages.d.ts.map +1 -1
  44. package/dist/components/chat/ConfirmActionCard.d.ts +5 -1
  45. package/dist/components/chat/ConfirmActionCard.d.ts.map +1 -1
  46. package/dist/components/chat/index.d.ts +0 -1
  47. package/dist/components/chat/index.d.ts.map +1 -1
  48. package/dist/components/connect/ConnectorRuns.d.ts +1 -1
  49. package/dist/components/connect/ConnectorsPanel.d.ts.map +1 -1
  50. package/dist/components/connect/ConnectorsTab.d.ts.map +1 -1
  51. package/dist/components/connect/connector-status.d.ts +1 -1
  52. package/dist/components/connect/model.d.ts +1 -1
  53. package/dist/components/layout/CommandPalette.d.ts.map +1 -1
  54. package/dist/components/organization/PermissionProfilesTab.d.ts.map +1 -1
  55. package/dist/components/settings/LocationsCrudPage.d.ts.map +1 -1
  56. package/dist/components/settings/SettingsPage.d.ts.map +1 -1
  57. package/dist/components/shared/RecordPickerModal.d.ts +24 -1
  58. package/dist/components/shared/RecordPickerModal.d.ts.map +1 -1
  59. package/dist/components/survey/PublicSurveyPage.d.ts +8 -0
  60. package/dist/components/survey/PublicSurveyPage.d.ts.map +1 -0
  61. package/dist/crud/CrudDetailPage.d.ts.map +1 -1
  62. package/dist/crud/CrudFormPage.d.ts.map +1 -1
  63. package/dist/crud/CrudListView.d.ts +3 -1
  64. package/dist/crud/CrudListView.d.ts.map +1 -1
  65. package/dist/crud/CrudPage.d.ts.map +1 -1
  66. package/dist/crud/CrudRecordModal.d.ts.map +1 -1
  67. package/dist/crud/LookupCreateInline.d.ts.map +1 -1
  68. package/dist/crud/RelatedListTab.d.ts +10 -0
  69. package/dist/crud/RelatedListTab.d.ts.map +1 -0
  70. package/dist/crud/archetypes/BookableToggle.d.ts +12 -0
  71. package/dist/crud/archetypes/BookableToggle.d.ts.map +1 -0
  72. package/dist/crud/archetypes/DetailTabHeader.d.ts +23 -0
  73. package/dist/crud/archetypes/DetailTabHeader.d.ts.map +1 -0
  74. package/dist/crud/archetypes/KanbanBoard.d.ts +89 -0
  75. package/dist/crud/archetypes/KanbanBoard.d.ts.map +1 -0
  76. package/dist/crud/archetypes/OrderAmount.d.ts +25 -0
  77. package/dist/crud/archetypes/OrderAmount.d.ts.map +1 -0
  78. package/dist/crud/archetypes/OrderBoardView.d.ts +61 -0
  79. package/dist/crud/archetypes/OrderBoardView.d.ts.map +1 -0
  80. package/dist/crud/archetypes/OrderCreateScreen.d.ts +116 -0
  81. package/dist/crud/archetypes/OrderCreateScreen.d.ts.map +1 -0
  82. package/dist/crud/archetypes/OrderDetailPage.d.ts +35 -0
  83. package/dist/crud/archetypes/OrderDetailPage.d.ts.map +1 -0
  84. package/dist/crud/archetypes/OrderDetailRail.d.ts +97 -0
  85. package/dist/crud/archetypes/OrderDetailRail.d.ts.map +1 -0
  86. package/dist/crud/archetypes/OrderDetailView.d.ts.map +1 -1
  87. package/dist/crud/archetypes/OrderFormView.d.ts +20 -1
  88. package/dist/crud/archetypes/OrderFormView.d.ts.map +1 -1
  89. package/dist/crud/archetypes/OrderListView.d.ts +59 -1
  90. package/dist/crud/archetypes/OrderListView.d.ts.map +1 -1
  91. package/dist/crud/archetypes/OrderPaymentChip.d.ts +8 -0
  92. package/dist/crud/archetypes/OrderPaymentChip.d.ts.map +1 -0
  93. package/dist/crud/archetypes/PaymentStatusBadge.d.ts +47 -0
  94. package/dist/crud/archetypes/PaymentStatusBadge.d.ts.map +1 -0
  95. package/dist/crud/archetypes/PersonDetailTabs.d.ts.map +1 -1
  96. package/dist/crud/archetypes/orderVocabulary.d.ts +19 -0
  97. package/dist/crud/archetypes/orderVocabulary.d.ts.map +1 -0
  98. package/dist/crud/archetypes/useOrderEditor.d.ts +20 -0
  99. package/dist/crud/archetypes/useOrderEditor.d.ts.map +1 -0
  100. package/dist/crud/archetypes/useOrderReceivable.d.ts +46 -0
  101. package/dist/crud/archetypes/useOrderReceivable.d.ts.map +1 -0
  102. package/dist/crud/archetypes/useOrdersPaymentStatus.d.ts +15 -0
  103. package/dist/crud/archetypes/useOrdersPaymentStatus.d.ts.map +1 -0
  104. package/dist/crud/createCrudPage.d.ts +3 -0
  105. package/dist/crud/createCrudPage.d.ts.map +1 -1
  106. package/dist/crud/relation-field.d.ts.map +1 -1
  107. package/dist/directory/AppSwitcher.d.ts +48 -0
  108. package/dist/directory/AppSwitcher.d.ts.map +1 -0
  109. package/dist/directory/FamilyWordmark.d.ts +20 -0
  110. package/dist/directory/FamilyWordmark.d.ts.map +1 -0
  111. package/dist/directory/app-id.d.ts +21 -0
  112. package/dist/directory/app-id.d.ts.map +1 -0
  113. package/dist/directory/directory.store.d.ts +20 -0
  114. package/dist/directory/directory.store.d.ts.map +1 -0
  115. package/dist/directory/index.d.ts +7 -0
  116. package/dist/directory/index.d.ts.map +1 -0
  117. package/dist/directory/types.d.ts +43 -0
  118. package/dist/directory/types.d.ts.map +1 -0
  119. package/dist/directory/useAppDirectory.d.ts +14 -0
  120. package/dist/directory/useAppDirectory.d.ts.map +1 -0
  121. package/dist/hooks/useAITools.d.ts +7 -0
  122. package/dist/hooks/useAITools.d.ts.map +1 -1
  123. package/dist/hooks/useAppConfig.d.ts.map +1 -1
  124. package/dist/hooks/useChat.d.ts +4 -0
  125. package/dist/hooks/useChat.d.ts.map +1 -1
  126. package/dist/hooks/useTenant.d.ts +12 -12
  127. package/dist/hooks/useTenant.d.ts.map +1 -1
  128. package/dist/index.d.ts +43 -5
  129. package/dist/index.d.ts.map +1 -1
  130. package/dist/index.js +25069 -21491
  131. package/dist/index.js.map +1 -1
  132. package/dist/lib/agent-staff.d.ts +46 -96
  133. package/dist/lib/agent-staff.d.ts.map +1 -1
  134. package/dist/lib/ai-tool-handlers.d.ts +24 -7
  135. package/dist/lib/ai-tool-handlers.d.ts.map +1 -1
  136. package/dist/lib/assistant-invite.d.ts.map +1 -1
  137. package/dist/lib/bookable-service.d.ts +7 -0
  138. package/dist/lib/bookable-service.d.ts.map +1 -0
  139. package/dist/lib/core-ai-tools.d.ts +0 -17
  140. package/dist/lib/core-ai-tools.d.ts.map +1 -1
  141. package/dist/lib/fayz-agent.d.ts +2 -0
  142. package/dist/lib/fayz-agent.d.ts.map +1 -1
  143. package/dist/lib/product-name.d.ts +38 -0
  144. package/dist/lib/product-name.d.ts.map +1 -0
  145. package/dist/lib/tool-search.d.ts +82 -0
  146. package/dist/lib/tool-search.d.ts.map +1 -0
  147. package/dist/onboarding/ActivationAgentSurface.d.ts.map +1 -1
  148. package/dist/onboarding/ActivationChecklistCard.d.ts +11 -1
  149. package/dist/onboarding/ActivationChecklistCard.d.ts.map +1 -1
  150. package/dist/onboarding/ActivationProvider.d.ts.map +1 -1
  151. package/dist/onboarding/WorkspaceSetupFlow.d.ts.map +1 -1
  152. package/dist/onboarding/business-profile.d.ts +67 -0
  153. package/dist/onboarding/business-profile.d.ts.map +1 -0
  154. package/dist/onboarding/checklist.d.ts +10 -0
  155. package/dist/onboarding/checklist.d.ts.map +1 -1
  156. package/dist/onboarding/decide.d.ts +23 -0
  157. package/dist/onboarding/decide.d.ts.map +1 -1
  158. package/dist/onboarding/guided-runner.d.ts +11 -0
  159. package/dist/onboarding/guided-runner.d.ts.map +1 -1
  160. package/dist/onboarding/guided.d.ts +21 -1
  161. package/dist/onboarding/guided.d.ts.map +1 -1
  162. package/dist/onboarding/index.d.ts +4 -2
  163. package/dist/onboarding/index.d.ts.map +1 -1
  164. package/dist/onboarding/packs/retail.d.ts.map +1 -1
  165. package/dist/onboarding/programs.d.ts +25 -1
  166. package/dist/onboarding/programs.d.ts.map +1 -1
  167. package/dist/onboarding/useWorkspaceSetupGate.d.ts.map +1 -1
  168. package/dist/onboarding/welcome.d.ts +27 -0
  169. package/dist/onboarding/welcome.d.ts.map +1 -0
  170. package/dist/org/WorkspaceChooser.d.ts +20 -0
  171. package/dist/org/WorkspaceChooser.d.ts.map +1 -0
  172. package/dist/org/WorkspaceChooserGate.d.ts +21 -0
  173. package/dist/org/WorkspaceChooserGate.d.ts.map +1 -0
  174. package/dist/org/WorkspaceSwitching.d.ts +25 -0
  175. package/dist/org/WorkspaceSwitching.d.ts.map +1 -0
  176. package/dist/org/WorkspaceSwitchingHost.d.ts +11 -0
  177. package/dist/org/WorkspaceSwitchingHost.d.ts.map +1 -0
  178. package/dist/org/adapters/supabase.d.ts +1 -1
  179. package/dist/org/adapters/supabase.d.ts.map +1 -1
  180. package/dist/org/choice.d.ts +41 -0
  181. package/dist/org/choice.d.ts.map +1 -0
  182. package/dist/org/context.d.ts +8 -0
  183. package/dist/org/context.d.ts.map +1 -1
  184. package/dist/org/index.d.ts +12 -1
  185. package/dist/org/index.d.ts.map +1 -1
  186. package/dist/org/index.js +4 -4
  187. package/dist/org/self.d.ts.map +1 -1
  188. package/dist/org/store.d.ts +2 -1
  189. package/dist/org/store.d.ts.map +1 -1
  190. package/dist/org/switching.store.d.ts +27 -0
  191. package/dist/org/switching.store.d.ts.map +1 -0
  192. package/dist/permissions/context.d.ts +26 -0
  193. package/dist/permissions/context.d.ts.map +1 -1
  194. package/dist/permissions/index.js +1 -1
  195. package/dist/projects/SeuSiteWidget.d.ts.map +1 -1
  196. package/dist/setup/SetupAgentSurface.d.ts +2 -0
  197. package/dist/setup/SetupAgentSurface.d.ts.map +1 -0
  198. package/dist/setup/format.d.ts +21 -0
  199. package/dist/setup/format.d.ts.map +1 -0
  200. package/dist/setup/registry.d.ts +29 -0
  201. package/dist/setup/registry.d.ts.map +1 -0
  202. package/dist/setup/validate.d.ts +26 -0
  203. package/dist/setup/validate.d.ts.map +1 -0
  204. package/dist/stores/chat.store.d.ts +15 -18
  205. package/dist/stores/chat.store.d.ts.map +1 -1
  206. package/dist/stores/createCrudStore.d.ts +2 -0
  207. package/dist/stores/createCrudStore.d.ts.map +1 -1
  208. package/dist/tasks/components/TaskDetail.d.ts.map +1 -1
  209. package/dist/units/UnitMenuSection.d.ts.map +1 -1
  210. package/dist/units/UnitSwitcher.d.ts.map +1 -1
  211. package/dist/units/UnitSwitching.d.ts +24 -0
  212. package/dist/units/UnitSwitching.d.ts.map +1 -0
  213. package/dist/units/UnitSwitchingHost.d.ts +11 -0
  214. package/dist/units/UnitSwitchingHost.d.ts.map +1 -0
  215. package/dist/units/data.d.ts +30 -4
  216. package/dist/units/data.d.ts.map +1 -1
  217. package/dist/units/index.d.ts +2 -0
  218. package/dist/units/index.d.ts.map +1 -1
  219. package/dist/units/switching.store.d.ts +31 -0
  220. package/dist/units/switching.store.d.ts.map +1 -0
  221. package/package.json +7 -7
  222. package/dist/CommandPalette-XY3VOEAV.js +0 -291
  223. package/dist/CommandPalette-XY3VOEAV.js.map +0 -1
  224. package/dist/SubscriptionPage-5PJ25YAD.js +0 -8
  225. package/dist/chunk-G5PBC5OB.js.map +0 -1
  226. package/dist/chunk-LZRLWKJ2.js.map +0 -1
  227. package/dist/chunk-VTEP2AQX.js.map +0 -1
  228. package/dist/chunk-WN6PGQSG.js.map +0 -1
  229. package/dist/components/billing/SoftLimitBanner.d.ts +0 -5
  230. package/dist/components/billing/SoftLimitBanner.d.ts.map +0 -1
  231. package/dist/components/chat/StaffHireView.d.ts +0 -21
  232. package/dist/components/chat/StaffHireView.d.ts.map +0 -1
  233. package/dist/components/chat/StaffPitchCard.d.ts +0 -15
  234. package/dist/components/chat/StaffPitchCard.d.ts.map +0 -1
  235. package/dist/components/chat/StaffSwitcher.d.ts +0 -23
  236. package/dist/components/chat/StaffSwitcher.d.ts.map +0 -1
  237. package/dist/lib/staff-cards.d.ts +0 -11
  238. package/dist/lib/staff-cards.d.ts.map +0 -1
@@ -1,8 +1,14 @@
1
+ import { markWorkspaceSwitch, clearOrgSnapshot, useTenant, useTenantOptional, setAutoPick } from './chunk-NB6X5O5L.js';
2
+ import { persistOrgId, getPersistedOrgId } from './chunk-5GWUM4SM.js';
1
3
  import { createClient } from '@supabase/supabase-js';
2
- import { getActiveUnitId, getActiveTenantId, setGlobalSupabaseClient } from '@fayz-ai/core';
4
+ import { getActiveUnitId, getActiveTenantId, setGlobalSupabaseClient, useTranslation } from '@fayz-ai/core';
3
5
  import { createDedupedFetch } from '@fayz-ai/sdk';
6
+ import * as React2 from 'react';
7
+ import { cn, Checkbox, Button } from '@fayz-ai/ui';
8
+ import { Check, Building2, ShieldCheck } from 'lucide-react';
9
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
10
+ import { create } from 'zustand';
4
11
 
5
- // src/data/client.ts
6
12
  var _client = null;
7
13
  function requestUrl(input) {
8
14
  if (typeof input === "string") return input;
@@ -110,6 +116,14 @@ function buildTeamRows(people, members, profiles, currentUser) {
110
116
  return [...loginRows, ...personRows];
111
117
  }
112
118
 
119
+ // src/directory/app-id.ts
120
+ function resolveAppId() {
121
+ const env = import.meta.env;
122
+ const id = env?.VITE_APP_ID ?? env?.PUBLIC_APP_ID;
123
+ const trimmed = id?.trim();
124
+ return trimmed ? trimmed : null;
125
+ }
126
+
113
127
  // src/org/adapters/supabase.ts
114
128
  var inflightRequests = /* @__PURE__ */ new Map();
115
129
  function dedup(key, fn) {
@@ -249,7 +263,7 @@ function buildPermissionProfiles(roles, permissions, rolePerms, overrides) {
249
263
  read: "read",
250
264
  create: "create",
251
265
  update: "edit",
252
- manage: "edit",
266
+ manage: "manage",
253
267
  delete: "delete",
254
268
  configure: "edit",
255
269
  invite: "create"
@@ -306,16 +320,30 @@ function createSupabaseOrgAdapter(config) {
306
320
  },
307
321
  async listUserOrgs(userId) {
308
322
  return dedup(`listUserOrgs:${userId}`, async () => {
309
- const { data, error } = await core().from("tenant_members").select("tenant_id, role, tenant:tenants(id, name, slug, logo_url)").eq("user_id", userId);
323
+ const { data, error } = await core().from("v_team_members").select("tenant_id, role, tenant:tenants(id, name, slug, logo_url)").eq("user_id", userId);
310
324
  if (error) throw error;
311
- return (data ?? []).map((row) => ({
312
- orgId: row["tenant_id"],
313
- orgName: row["tenant"]?.["name"] ?? "",
314
- orgSlug: row["tenant"]?.["slug"] ?? "",
315
- orgLogoUrl: row["tenant"]?.["logo_url"] ?? void 0,
316
- profileId: row["role"],
317
- profileName: capitalize2(row["role"])
318
- }));
325
+ let rows = data ?? [];
326
+ const appId = resolveAppId();
327
+ if (appId && rows.length > 1) {
328
+ const { data: scoped, error: scopeError } = await core().from("v_tenant_apps").select("tenant_id").eq("app_id", appId);
329
+ if (!scopeError && Array.isArray(scoped)) {
330
+ const runsThisApp = new Set(scoped.map((r) => r.tenant_id));
331
+ const kept = rows.filter((row) => runsThisApp.has(row["tenant_id"]));
332
+ if (kept.length > 0) rows = kept;
333
+ }
334
+ }
335
+ return rows.map((row) => {
336
+ const tenant = row["tenant"] ?? {};
337
+ const role = row["role"] ?? "";
338
+ return {
339
+ orgId: row["tenant_id"],
340
+ orgName: tenant["name"] ?? "",
341
+ orgSlug: tenant["slug"] ?? "",
342
+ orgLogoUrl: tenant["logo_url"] ?? void 0,
343
+ profileId: role,
344
+ profileName: capitalize2(role)
345
+ };
346
+ });
319
347
  });
320
348
  },
321
349
  async getOrg(orgId) {
@@ -354,7 +382,7 @@ function createSupabaseOrgAdapter(config) {
354
382
  return mapTenantToOrg(data);
355
383
  },
356
384
  async listMembers(orgId) {
357
- const { data, error } = await core().from("tenant_members").select("*").eq("tenant_id", orgId);
385
+ const { data, error } = await core().from("v_team_members").select("*").eq("tenant_id", orgId);
358
386
  if (error) throw error;
359
387
  const userIds = (data ?? []).map((m) => m["user_id"]);
360
388
  const { data: profiles } = userIds.length > 0 ? await core().from("profiles").select("id, full_name, avatar_url, email").in("id", userIds) : { data: [] };
@@ -374,7 +402,7 @@ function createSupabaseOrgAdapter(config) {
374
402
  if (!personKinds || personKinds.length === 0) return [];
375
403
  const [peopleResult, membersResult] = await Promise.all([
376
404
  core().from("people").select("id, name, kind, email, avatar_url, is_active").eq("tenant_id", orgId).in("kind", personKinds).not("is_active", "is", false),
377
- core().from("tenant_members").select("id, user_id, role, person_id, created_at").eq("tenant_id", orgId)
405
+ core().from("v_team_members").select("id, user_id, role, person_id, created_at").eq("tenant_id", orgId)
378
406
  ]);
379
407
  if (peopleResult.error) throw peopleResult.error;
380
408
  const people = peopleResult.data ?? [];
@@ -392,64 +420,80 @@ function createSupabaseOrgAdapter(config) {
392
420
  } : null;
393
421
  return buildTeamRows(people, members, profilesResult.data ?? [], currentUser);
394
422
  },
395
- async updateMemberProfile(orgId, memberId, profileId) {
396
- const { error } = await core().from("tenant_members").update({ role: profileId }).eq("id", memberId).eq("tenant_id", orgId);
423
+ // Verbs, not writes into the projection: v_team_members is a JOINed view
424
+ // and accepts neither UPDATE nor DELETE, and each RPC checks the permission
425
+ // in one place. `_orgId` stays in the signature for the adapter contract —
426
+ // the RPCs take the tenant from the session, not from a parameter.
427
+ async updateMemberProfile(_orgId, memberId, profileId) {
428
+ const { error } = await core().rpc("member_set_role", { p_membership: memberId, p_role: profileId });
397
429
  if (error) throw error;
398
430
  },
399
- async removeMember(orgId, memberId) {
400
- const { error } = await core().from("tenant_members").delete().eq("id", memberId).eq("tenant_id", orgId);
431
+ async removeMember(_orgId, memberId) {
432
+ const { error } = await core().rpc("member_remove", { p_membership: memberId });
401
433
  if (error) throw error;
402
434
  },
435
+ // #136 moved authorization into app.*, reachable through the v_authz_*
436
+ // views (security_invoker, so RLS still decides what a caller sees) and a
437
+ // small set of RPCs. The four public mirrors this used to read and write —
438
+ // permissions, role_permissions, tenant_roles, tenant_role_overrides — are
439
+ // dropped by @fayz-ai/db 003.
440
+ //
441
+ // The RPCs take the tenant from the SESSION, not a parameter, so orgId is
442
+ // asserted against the active tenant rather than passed down: writing to
443
+ // one org while another is active was never possible and should fail
444
+ // loudly rather than silently touch the wrong one.
403
445
  async listProfiles(orgId) {
404
- const [permsResult, rolePermsResult, overridesResult, customResult] = await Promise.all([
405
- core().from("permissions").select("id, category"),
406
- core().from("role_permissions").select("role, permission_id"),
407
- core().from("tenant_role_overrides").select("role, permission_id, granted").eq("tenant_id", orgId),
408
- // Custom roles the tenant created by duplicating a system role. Tolerate a
409
- // missing table (pre-seed) — just show the system roles in that case.
410
- core().from("tenant_roles").select("key, name, description").eq("tenant_id", orgId)
446
+ const [permsResult, rolesResult, grantsResult] = await Promise.all([
447
+ core().from("v_authz_permissions").select("key, plugin"),
448
+ core().from("v_authz_roles").select("id, key, name, description, is_system").eq("tenant_id", orgId),
449
+ core().from("v_authz_role_permissions").select("role_id, permission").eq("tenant_id", orgId)
411
450
  ]);
412
451
  if (permsResult.error) throw permsResult.error;
413
- if (rolePermsResult.error) throw rolePermsResult.error;
414
- if (overridesResult.error) throw overridesResult.error;
415
- const systemRoles = roles.map((r) => ({ ...r, isSystem: true }));
416
- const customRoles = customResult.error ? [] : (customResult.data ?? []).map((r) => ({
417
- id: r.key,
418
- name: r.name,
419
- description: r.description ?? void 0,
420
- isSystem: false
421
- }));
452
+ if (rolesResult.error) throw rolesResult.error;
453
+ if (grantsResult.error) throw grantsResult.error;
454
+ const dbRoles = rolesResult.data ?? [];
455
+ const keyOf = new Map(dbRoles.map((r) => [r.id, r.key]));
456
+ const declared = roles.map((r) => ({ ...r, isSystem: true }));
457
+ const declaredIds = new Set(declared.map((r) => r.id));
458
+ const fromDb = dbRoles.filter((r) => !declaredIds.has(r.key)).map((r) => ({ id: r.key, name: r.name, description: r.description ?? void 0, isSystem: r.is_system }));
459
+ const overrides = (grantsResult.data ?? []).flatMap((g) => {
460
+ const role = keyOf.get(g.role_id);
461
+ return role ? [{ role, permission_id: g.permission, granted: true }] : [];
462
+ });
422
463
  return buildPermissionProfiles(
423
- [...systemRoles, ...customRoles],
424
- permsResult.data ?? [],
425
- rolePermsResult.data ?? [],
426
- overridesResult.data ?? []
464
+ [...declared, ...fromDb],
465
+ (permsResult.data ?? []).map((p) => ({ id: p.key, category: p.plugin })),
466
+ [],
467
+ overrides
427
468
  );
428
469
  },
429
470
  async createProfile(orgId, profile) {
430
- const existing = new Set(
431
- ((await core().from("tenant_roles").select("key").eq("tenant_id", orgId)).data ?? []).map((r) => r.key)
432
- );
471
+ const existingRoles = await core().from("v_authz_roles").select("key, is_system").eq("tenant_id", orgId);
472
+ if (existingRoles.error) throw existingRoles.error;
473
+ const rows = existingRoles.data ?? [];
474
+ const existing = new Set(rows.map((r) => r.key));
433
475
  let key = slugifyRole(profile.name);
434
476
  if (existing.has(key) || roles.some((r) => r.id === key)) {
435
477
  let n = 2;
436
478
  while (existing.has(`${key}-${n}`) || roles.some((r) => r.id === `${key}-${n}`)) n++;
437
479
  key = `${key}-${n}`;
438
480
  }
439
- const insertRole = await core().from("tenant_roles").insert({ tenant_id: orgId, key, name: profile.name, description: profile.description ?? null });
440
- if (insertRole.error) throw insertRole.error;
441
- const overrides = Object.entries(profile.grants ?? {}).flatMap(
442
- ([category, actions]) => actions.map((action) => ({
443
- tenant_id: orgId,
444
- role: key,
445
- permission_id: `${category}.${DB_ACTION[action] ?? action}`,
446
- granted: true
447
- }))
481
+ const seed = rows.find((r) => r.is_system && r.key === "viewer")?.key ?? rows.find((r) => r.is_system)?.key ?? rows[0]?.key;
482
+ if (!seed) throw new Error("createProfile: the tenant has no role to clone from");
483
+ const created = await core().rpc("role_create_from_template", {
484
+ p_role_key: key,
485
+ p_name: profile.name,
486
+ p_template_role: seed,
487
+ p_template: null,
488
+ p_description: profile.description ?? null
489
+ });
490
+ if (created.error) throw created.error;
491
+ const roleId = created.data;
492
+ const keys = Object.entries(profile.grants ?? {}).flatMap(
493
+ ([category, actions]) => actions.map((action) => `${category}.${DB_ACTION[action] ?? action}`)
448
494
  );
449
- if (overrides.length > 0) {
450
- const { error } = await core().from("tenant_role_overrides").insert(overrides);
451
- if (error) throw error;
452
- }
495
+ const set = await core().rpc("role_set_permissions", { p_role_id: roleId, p_keys: keys });
496
+ if (set.error) throw set.error;
453
497
  const profiles = await this.listProfiles(orgId);
454
498
  return profiles.find((p) => p.id === key) ?? {
455
499
  id: key,
@@ -461,27 +505,26 @@ function createSupabaseOrgAdapter(config) {
461
505
  };
462
506
  },
463
507
  async updateProfile(orgId, profileId, data) {
508
+ const found = await core().from("v_authz_roles").select("id, name, description, is_system").eq("tenant_id", orgId).eq("key", profileId).maybeSingle();
509
+ if (found.error) throw found.error;
510
+ if (!found.data) throw new Error(`Profile not found: ${profileId}`);
511
+ const role = found.data;
464
512
  if (data.name !== void 0 || data.description !== void 0) {
465
- const patch = {};
466
- if (data.name !== void 0) patch.name = data.name;
467
- if (data.description !== void 0) patch.description = data.description ?? null;
468
- const { error } = await core().from("tenant_roles").update(patch).eq("tenant_id", orgId).eq("key", profileId);
513
+ const { error } = await core().rpc("role_rename", {
514
+ p_role_id: role.id,
515
+ p_name: data.name ?? role.name,
516
+ // Explicit, not coalesced: role_rename treats NULL as "clear it", so
517
+ // an untouched description has to be sent back as it was.
518
+ p_description: data.description !== void 0 ? data.description ?? null : role.description
519
+ });
469
520
  if (error) throw error;
470
521
  }
471
522
  if (data.grants) {
472
- await core().from("tenant_role_overrides").delete().eq("tenant_id", orgId).eq("role", profileId);
473
- const overrides = Object.entries(data.grants).flatMap(
474
- ([category, actions]) => actions.map((action) => ({
475
- tenant_id: orgId,
476
- role: profileId,
477
- permission_id: `${category}.${DB_ACTION[action] ?? action}`,
478
- granted: true
479
- }))
523
+ const keys = Object.entries(data.grants).flatMap(
524
+ ([category, actions]) => actions.map((action) => `${category}.${DB_ACTION[action] ?? action}`)
480
525
  );
481
- if (overrides.length > 0) {
482
- const { error } = await core().from("tenant_role_overrides").insert(overrides);
483
- if (error) throw error;
484
- }
526
+ const { error } = await core().rpc("role_set_permissions", { p_role_id: role.id, p_keys: keys });
527
+ if (error) throw error;
485
528
  }
486
529
  const profiles = await this.listProfiles(orgId);
487
530
  const updated = profiles.find((p) => p.id === profileId);
@@ -489,11 +532,12 @@ function createSupabaseOrgAdapter(config) {
489
532
  return updated;
490
533
  },
491
534
  async deleteProfile(orgId, profileId) {
492
- const found = await core().from("tenant_roles").select("key").eq("tenant_id", orgId).eq("key", profileId).maybeSingle();
535
+ const found = await core().from("v_authz_roles").select("id, is_system").eq("tenant_id", orgId).eq("key", profileId).maybeSingle();
493
536
  if (found.error) throw found.error;
494
537
  if (!found.data) throw new Error("System roles cannot be deleted.");
495
- await core().from("tenant_role_overrides").delete().eq("tenant_id", orgId).eq("role", profileId);
496
- const { error } = await core().from("tenant_roles").delete().eq("tenant_id", orgId).eq("key", profileId);
538
+ const role = found.data;
539
+ if (role.is_system) throw new Error("System roles cannot be deleted.");
540
+ const { error } = await core().rpc("role_delete", { p_role_id: role.id });
497
541
  if (error) throw error;
498
542
  },
499
543
  async listInvites(orgId) {
@@ -552,23 +596,29 @@ function createSupabaseOrgAdapter(config) {
552
596
  return mapInviteRow(row);
553
597
  },
554
598
  async listLocations(orgId) {
555
- const { data, error } = await core().from("locations").select("*").eq("tenant_id", orgId).order("is_headquarters", { ascending: false }).order("name");
599
+ const { data, error } = await core().from("v_units").select("*").eq("tenant_id", orgId).order("is_headquarters", { ascending: false }).order("name");
556
600
  if (error) throw error;
557
601
  return (data ?? []).map(mapLocationRow);
558
602
  },
559
603
  async createLocation(orgId, input) {
560
- const { data, error } = await core().from("locations").insert({
561
- tenant_id: orgId,
562
- name: input.name,
563
- address: input.address ?? null,
564
- city: input.city ?? null,
565
- state: input.state ?? null,
566
- country: input.country ?? "BR",
567
- phone: input.phone ?? null,
568
- is_headquarters: input.isHeadquarters ?? false
569
- }).select().single();
604
+ const { data, error } = await core().rpc("unit_create", {
605
+ p_name: input.name,
606
+ p_kind: input.isHeadquarters ? "hq" : "branch",
607
+ p_parent_unit: null,
608
+ // app.units keeps a unit's contact details in metadata; v_units reads
609
+ // them back out under the flat names this screen already uses.
610
+ p_metadata: {
611
+ address: input.address ?? null,
612
+ city: input.city ?? null,
613
+ state: input.state ?? null,
614
+ country: input.country ?? "BR",
615
+ phone: input.phone ?? null
616
+ }
617
+ });
570
618
  if (error) throw error;
571
- return mapLocationRow(data);
619
+ const created = await core().from("v_units").select("*").eq("id", data).single();
620
+ if (created.error) throw created.error;
621
+ return mapLocationRow(created.data);
572
622
  }
573
623
  };
574
624
  }
@@ -842,7 +892,248 @@ function createMockOrgAdapter(defaultProfiles) {
842
892
  }
843
893
  };
844
894
  }
895
+ function WorkspaceChooser({ memberships, suggestedId, onCancel }) {
896
+ const t = useTranslation();
897
+ const tr = (key, fallback) => {
898
+ const v = t(key);
899
+ return !v || v === key ? fallback : v;
900
+ };
901
+ const { switchOrg } = useTenant();
902
+ const [selected, setSelected] = React2.useState(
903
+ suggestedId ?? memberships[0]?.orgId ?? null
904
+ );
905
+ const [remember, setRemember] = React2.useState(false);
906
+ const [entering, setEntering] = React2.useState(false);
907
+ const enter = async (orgId) => {
908
+ if (entering) return;
909
+ setEntering(true);
910
+ setAutoPick(remember);
911
+ try {
912
+ await switchOrg(orgId);
913
+ } finally {
914
+ setEntering(false);
915
+ }
916
+ };
917
+ return /* @__PURE__ */ jsx("div", { className: "flex min-h-screen items-center justify-center bg-background p-4", children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-md", children: [
918
+ /* @__PURE__ */ jsxs("div", { className: "mb-6 text-center", children: [
919
+ /* @__PURE__ */ jsx("h1", { className: "text-xl font-semibold text-foreground", children: tr("organization.chooseWorkspace", "Escolha uma \xE1rea de trabalho") }),
920
+ /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: tr(
921
+ "organization.chooseWorkspaceDescription",
922
+ "Voc\xEA tem acesso a mais de uma. Selecione em qual deseja entrar."
923
+ ) })
924
+ ] }),
925
+ /* @__PURE__ */ jsx(
926
+ "div",
927
+ {
928
+ role: "radiogroup",
929
+ "aria-label": tr("organization.workspaces", "Workspaces"),
930
+ className: "space-y-2",
931
+ children: memberships.map((m) => {
932
+ const isSelected = m.orgId === selected;
933
+ const isSuggested = m.orgId === suggestedId;
934
+ return /* @__PURE__ */ jsxs(
935
+ "button",
936
+ {
937
+ type: "button",
938
+ role: "radio",
939
+ "aria-checked": isSelected,
940
+ disabled: entering,
941
+ onClick: () => setSelected(m.orgId),
942
+ onDoubleClick: () => void enter(m.orgId),
943
+ className: cn(
944
+ "flex w-full items-center gap-3 rounded-lg border p-3 text-left transition-colors",
945
+ "disabled:opacity-60",
946
+ isSelected ? "border-primary bg-primary/5" : "border-border hover:border-primary/50 hover:bg-muted/50"
947
+ ),
948
+ children: [
949
+ /* @__PURE__ */ jsx(WorkspaceMark, { name: m.orgName, logoUrl: m.orgLogoUrl }),
950
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
951
+ /* @__PURE__ */ jsx("span", { className: "block truncate text-sm font-medium text-foreground", children: m.orgName || m.orgSlug || m.orgId }),
952
+ /* @__PURE__ */ jsxs("span", { className: "block truncate text-xs text-muted-foreground", children: [
953
+ m.profileName,
954
+ isSuggested && ` \xB7 ${tr("organization.lastUsed", "\xFAltimo acesso")}`
955
+ ] })
956
+ ] }),
957
+ isSelected && /* @__PURE__ */ jsx(Check, { className: "h-4 w-4 shrink-0 text-primary" })
958
+ ]
959
+ },
960
+ m.orgId
961
+ );
962
+ })
963
+ }
964
+ ),
965
+ /* @__PURE__ */ jsxs("div", { className: "mt-5 flex items-center gap-2.5 text-sm text-muted-foreground", children: [
966
+ /* @__PURE__ */ jsx(
967
+ Checkbox,
968
+ {
969
+ checked: remember,
970
+ onChange: setRemember,
971
+ disabled: entering,
972
+ "aria-label": tr("organization.rememberChoice", "N\xE3o perguntar novamente neste dispositivo")
973
+ }
974
+ ),
975
+ /* @__PURE__ */ jsx("span", { className: "cursor-pointer select-none", onClick: () => !entering && setRemember(!remember), children: tr("organization.rememberChoice", "N\xE3o perguntar novamente neste dispositivo") })
976
+ ] }),
977
+ /* @__PURE__ */ jsxs("div", { className: "mt-5 flex gap-2", children: [
978
+ onCancel && /* @__PURE__ */ jsx(Button, { variant: "outline", className: "flex-1", onClick: onCancel, disabled: entering, children: tr("common.cancel", "Cancelar") }),
979
+ /* @__PURE__ */ jsx(
980
+ Button,
981
+ {
982
+ className: "flex-1",
983
+ disabled: !selected || entering,
984
+ onClick: () => selected && void enter(selected),
985
+ children: entering ? tr("common.loading", "Entrando\u2026") : tr("organization.enter", "Entrar")
986
+ }
987
+ )
988
+ ] }),
989
+ /* @__PURE__ */ jsx("p", { className: "mt-4 text-center text-xs text-muted-foreground", children: tr(
990
+ "organization.switchLaterHint",
991
+ "Voc\xEA pode trocar a qualquer momento pelo seletor no topo da tela."
992
+ ) })
993
+ ] }) });
994
+ }
995
+ function WorkspaceMark({ name, logoUrl }) {
996
+ if (logoUrl) {
997
+ return /* @__PURE__ */ jsx("img", { src: logoUrl, alt: "", className: "h-9 w-9 shrink-0 rounded-lg object-cover" });
998
+ }
999
+ const initials = name.split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0]).join("").toUpperCase();
1000
+ return /* @__PURE__ */ jsx("span", { className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-xs font-semibold text-primary", children: initials || /* @__PURE__ */ jsx(Building2, { className: "h-4 w-4" }) });
1001
+ }
1002
+ function WorkspaceChooserGate({ fallback, children }) {
1003
+ const tenant = useTenantOptional();
1004
+ if (!tenant) return /* @__PURE__ */ jsx(Fragment, { children });
1005
+ const { org, userOrgs, orgsKnown, settled } = tenant;
1006
+ if (org) return /* @__PURE__ */ jsx(Fragment, { children });
1007
+ if (!settled) return /* @__PURE__ */ jsx(Fragment, { children: fallback ?? null });
1008
+ if (!orgsKnown || userOrgs.length <= 1) return /* @__PURE__ */ jsx(Fragment, { children });
1009
+ return /* @__PURE__ */ jsx(
1010
+ WorkspaceChooser,
1011
+ {
1012
+ memberships: userOrgs,
1013
+ suggestedId: userOrgs.some((m) => m.orgId === getPersistedOrgId()) ? getPersistedOrgId() : null
1014
+ }
1015
+ );
1016
+ }
1017
+ var useWorkspaceSwitchingStore = create((set) => ({
1018
+ target: null,
1019
+ begin: (target) => {
1020
+ markWorkspaceSwitch(target.orgId);
1021
+ persistOrgId(target.orgId);
1022
+ clearOrgSnapshot();
1023
+ set({ target });
1024
+ },
1025
+ cancel: () => set({ target: null })
1026
+ }));
1027
+ var STEP_MS = 850;
1028
+ function WorkspaceSwitching({ orgName, orgLogoUrl, onDone }) {
1029
+ const t = useTranslation();
1030
+ const tr = (key, fallback) => {
1031
+ const v = t(key);
1032
+ return !v || v === key ? fallback : v;
1033
+ };
1034
+ const steps = React2.useMemo(
1035
+ () => [
1036
+ tr("organization.switching.step1", "Alterando organiza\xE7\xE3o"),
1037
+ tr("organization.switching.step2", "Garantindo seguran\xE7a dos dados"),
1038
+ tr("organization.switching.step3", "Carregando suas informa\xE7\xF5es")
1039
+ ],
1040
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1041
+ []
1042
+ );
1043
+ const [step, setStep] = React2.useState(0);
1044
+ const doneRef = React2.useRef(onDone);
1045
+ doneRef.current = onDone;
1046
+ React2.useEffect(() => {
1047
+ const id = window.setInterval(() => {
1048
+ setStep((s) => {
1049
+ if (s < steps.length - 1) return s + 1;
1050
+ window.clearInterval(id);
1051
+ window.setTimeout(() => doneRef.current(), STEP_MS);
1052
+ return s;
1053
+ });
1054
+ }, STEP_MS);
1055
+ return () => window.clearInterval(id);
1056
+ }, [steps.length]);
1057
+ return /* @__PURE__ */ jsx(
1058
+ "div",
1059
+ {
1060
+ role: "status",
1061
+ "aria-live": "polite",
1062
+ "aria-label": `${steps[step]} \u2014 ${orgName}`,
1063
+ className: "saas-switch-veil fixed inset-0 z-[100] flex items-center justify-center bg-background px-6",
1064
+ children: /* @__PURE__ */ jsxs("div", { className: "saas-switch-rise flex w-full max-w-sm flex-col items-center", children: [
1065
+ /* @__PURE__ */ jsxs("div", { className: "relative flex h-20 w-20 items-center justify-center", children: [
1066
+ /* @__PURE__ */ jsx(
1067
+ "span",
1068
+ {
1069
+ "aria-hidden": true,
1070
+ className: "saas-switch-pulse absolute inset-0 rounded-2xl bg-primary/25"
1071
+ }
1072
+ ),
1073
+ /* @__PURE__ */ jsx(WorkspaceMark2, { name: orgName, logoUrl: orgLogoUrl })
1074
+ ] }),
1075
+ /* @__PURE__ */ jsx("p", { className: "mt-7 text-xs font-medium uppercase tracking-[0.14em] text-muted-foreground", children: tr("organization.switching.eyebrow", "Entrando em") }),
1076
+ /* @__PURE__ */ jsx("h1", { className: "mt-1.5 text-pretty text-center text-3xl font-semibold leading-tight tracking-tight text-foreground sm:text-4xl", children: orgName }),
1077
+ /* @__PURE__ */ jsx("ul", { className: "mt-9 flex w-full min-h-[7.5rem] flex-col items-start sm:min-h-[8.5rem]", children: steps.slice(0, step + 1).map((label, i) => {
1078
+ const done = i < step;
1079
+ const isSecurity = i === 1;
1080
+ return /* @__PURE__ */ jsxs("li", { className: "saas-switch-step flex w-full gap-3", children: [
1081
+ /* @__PURE__ */ jsxs("span", { className: "flex w-6 shrink-0 flex-col items-center", children: [
1082
+ i > 0 && // Tinted, not `bg-border`: on a light surface the border
1083
+ // token is invisible at 1px, and this thread is the part
1084
+ // that makes three rows read as one advancing sequence
1085
+ // rather than three unrelated lines.
1086
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "saas-switch-link h-5 w-0.5 rounded-full bg-primary/30" }),
1087
+ /* @__PURE__ */ jsx("span", { className: "flex h-7 w-6 items-center justify-center", children: done ? /* @__PURE__ */ jsx(Check, { className: "h-5 w-5 text-primary", strokeWidth: 2.5 }) : isSecurity ? /* @__PURE__ */ jsx(ShieldCheck, { className: "saas-switch-dot h-5 w-5 text-primary", strokeWidth: 2 }) : /* @__PURE__ */ jsx("span", { className: "saas-switch-dot h-2 w-2 rounded-full bg-primary" }) })
1088
+ ] }),
1089
+ /* @__PURE__ */ jsx(
1090
+ "span",
1091
+ {
1092
+ className: cn(
1093
+ "flex h-7 items-center text-base transition-colors duration-300 sm:text-lg",
1094
+ // Only ever two states now — done, or happening. Nothing is
1095
+ // on screen before its turn, so there is no "ahead" tone.
1096
+ done ? "text-muted-foreground" : "font-medium text-foreground",
1097
+ // Push the label down past the connector so it stays level
1098
+ // with its own marker rather than with the thread above it.
1099
+ i > 0 && "mt-5"
1100
+ ),
1101
+ children: label
1102
+ }
1103
+ )
1104
+ ] }, label);
1105
+ }) })
1106
+ ] })
1107
+ }
1108
+ );
1109
+ }
1110
+ function WorkspaceMark2({ name, logoUrl }) {
1111
+ if (logoUrl) {
1112
+ return /* @__PURE__ */ jsx(
1113
+ "img",
1114
+ {
1115
+ src: logoUrl,
1116
+ alt: "",
1117
+ className: "relative h-16 w-16 rounded-2xl object-cover shadow-sm"
1118
+ }
1119
+ );
1120
+ }
1121
+ const initials = name.split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0]).join("").toUpperCase();
1122
+ return /* @__PURE__ */ jsx("span", { className: "relative flex h-16 w-16 items-center justify-center rounded-2xl bg-primary text-xl font-semibold text-primary-foreground shadow-sm", children: initials || /* @__PURE__ */ jsx(Building2, { className: "h-7 w-7" }) });
1123
+ }
1124
+ function WorkspaceSwitchingHost() {
1125
+ const target = useWorkspaceSwitchingStore((s) => s.target);
1126
+ if (!target) return null;
1127
+ return /* @__PURE__ */ jsx(
1128
+ WorkspaceSwitching,
1129
+ {
1130
+ orgName: target.orgName,
1131
+ orgLogoUrl: target.orgLogoUrl,
1132
+ onDone: () => window.location.reload()
1133
+ }
1134
+ );
1135
+ }
845
1136
 
846
- export { createFayzSupabaseClient, createMockOrgAdapter, createSupabaseOrgAdapter, getFayzSupabaseClient, getFayzSupabaseClientOptional };
847
- //# sourceMappingURL=chunk-LZRLWKJ2.js.map
848
- //# sourceMappingURL=chunk-LZRLWKJ2.js.map
1137
+ export { WorkspaceChooser, WorkspaceChooserGate, WorkspaceSwitching, WorkspaceSwitchingHost, createFayzSupabaseClient, createMockOrgAdapter, createSupabaseOrgAdapter, getFayzSupabaseClient, getFayzSupabaseClientOptional, resolveAppId, useWorkspaceSwitchingStore };
1138
+ //# sourceMappingURL=chunk-UHHEPU4A.js.map
1139
+ //# sourceMappingURL=chunk-UHHEPU4A.js.map