@fayz-ai/admin 0.62.0 → 0.65.2
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/{CommandPalette-B5PMQFDG.js → CommandPalette-XDJJ5E3O.js} +3 -3
- package/dist/{CommandPalette-B5PMQFDG.js.map → CommandPalette-XDJJ5E3O.js.map} +1 -1
- package/dist/ConnectedBrandingSettings-43ZM3HCI.js +680 -0
- package/dist/ConnectedBrandingSettings-43ZM3HCI.js.map +1 -0
- package/dist/ConnectedCompanySettings-I4MALI2Q.js +197 -0
- package/dist/ConnectedCompanySettings-I4MALI2Q.js.map +1 -0
- package/dist/ConnectedModulesSettings-A2VJ5BMJ.js +563 -0
- package/dist/ConnectedModulesSettings-A2VJ5BMJ.js.map +1 -0
- package/dist/ConnectedSecuritySettings-25AHA4HJ.js +189 -0
- package/dist/ConnectedSecuritySettings-25AHA4HJ.js.map +1 -0
- package/dist/ConnectedUserProfile-E7USJRUE.js +424 -0
- package/dist/ConnectedUserProfile-E7USJRUE.js.map +1 -0
- package/dist/FieldRulesEditor-YGIPKI5T.js +129 -0
- package/dist/FieldRulesEditor-YGIPKI5T.js.map +1 -0
- package/dist/GettingStartedWidget-HMIJ3Y24.js +12 -0
- package/dist/GettingStartedWidget-HMIJ3Y24.js.map +1 -0
- package/dist/PermissionProfilesTab-3ZPRCHMZ.js +548 -0
- package/dist/PermissionProfilesTab-3ZPRCHMZ.js.map +1 -0
- package/dist/PersonTimeline-HQZT527S.js +3 -0
- package/dist/{PersonTimeline-X7JTPUWJ.js.map → PersonTimeline-HQZT527S.js.map} +1 -1
- package/dist/ProjectsSettings-7O2F27MD.js +5 -0
- package/dist/ProjectsSettings-7O2F27MD.js.map +1 -0
- package/dist/ScheduleEditor-54ELWR45.js +8 -0
- package/dist/{ScheduleEditor-L2UJXKMY.js.map → ScheduleEditor-54ELWR45.js.map} +1 -1
- package/dist/SeuSiteWidget-QLSUVC63.js +6 -0
- package/dist/SeuSiteWidget-QLSUVC63.js.map +1 -0
- package/dist/SubscriptionPage-5GE5HFJK.js +17 -0
- package/dist/{SubscriptionPage-IDVEFLZ5.js.map → SubscriptionPage-5GE5HFJK.js.map} +1 -1
- package/dist/TeamTab-6RAULFLW.js +502 -0
- package/dist/TeamTab-6RAULFLW.js.map +1 -0
- package/dist/TrialWidget-Z6CLUCU3.js +7 -0
- package/dist/TrialWidget-Z6CLUCU3.js.map +1 -0
- package/dist/app/AdminShell.d.ts.map +1 -1
- package/dist/app/admin-app.d.ts.map +1 -1
- package/dist/app/config.d.ts +14 -0
- package/dist/app/config.d.ts.map +1 -1
- package/dist/app/routing.d.ts +6 -0
- package/dist/app/routing.d.ts.map +1 -1
- package/dist/app/scaffold.d.ts.map +1 -1
- package/dist/billing/index.js +9 -4
- package/dist/chunk-2H46WDG5.js +53 -0
- package/dist/chunk-2H46WDG5.js.map +1 -0
- package/dist/chunk-3HLX7YB2.js +94 -0
- package/dist/chunk-3HLX7YB2.js.map +1 -0
- package/dist/chunk-3OUD4XBK.js +3 -0
- package/dist/chunk-3OUD4XBK.js.map +1 -0
- package/dist/{chunk-IXSY4GPK.js → chunk-5D5QLMOQ.js} +5 -3
- package/dist/chunk-5D5QLMOQ.js.map +1 -0
- package/dist/chunk-5WR62X2R.js +1081 -0
- package/dist/chunk-5WR62X2R.js.map +1 -0
- package/dist/{chunk-KPYRTOCK.js → chunk-6CQFGMEO.js} +4 -140
- package/dist/chunk-6CQFGMEO.js.map +1 -0
- package/dist/chunk-6MMSYC2I.js +116 -0
- package/dist/chunk-6MMSYC2I.js.map +1 -0
- package/dist/chunk-6QFOE3UD.js +1466 -0
- package/dist/chunk-6QFOE3UD.js.map +1 -0
- package/dist/chunk-6UUFVQ2E.js +283 -0
- package/dist/chunk-6UUFVQ2E.js.map +1 -0
- package/dist/chunk-7WNLL3F6.js +7889 -0
- package/dist/chunk-7WNLL3F6.js.map +1 -0
- package/dist/chunk-A74IHAQE.js +439 -0
- package/dist/chunk-A74IHAQE.js.map +1 -0
- package/dist/{chunk-JOBRLBIQ.js → chunk-AFA6IO23.js} +4 -3
- package/dist/chunk-AFA6IO23.js.map +1 -0
- package/dist/{chunk-P5UIGQFY.js → chunk-ALCSIN3Z.js} +5 -5
- package/dist/chunk-ALCSIN3Z.js.map +1 -0
- package/dist/chunk-AWM4AMBS.js +39 -0
- package/dist/chunk-AWM4AMBS.js.map +1 -0
- package/dist/{chunk-OQARLKZN.js → chunk-BG5Z6KLN.js} +6 -18
- package/dist/chunk-BG5Z6KLN.js.map +1 -0
- package/dist/chunk-DPNFZONC.js +19 -0
- package/dist/chunk-DPNFZONC.js.map +1 -0
- package/dist/chunk-DRCV643L.js +193 -0
- package/dist/chunk-DRCV643L.js.map +1 -0
- package/dist/chunk-E6DF3VR6.js +206 -0
- package/dist/chunk-E6DF3VR6.js.map +1 -0
- package/dist/chunk-ENHCVGXZ.js +120 -0
- package/dist/chunk-ENHCVGXZ.js.map +1 -0
- package/dist/chunk-FK6RHGI7.js +56 -0
- package/dist/chunk-FK6RHGI7.js.map +1 -0
- package/dist/chunk-G5HNA5QK.js +233 -0
- package/dist/chunk-G5HNA5QK.js.map +1 -0
- package/dist/chunk-HCFO4Z6A.js +53 -0
- package/dist/chunk-HCFO4Z6A.js.map +1 -0
- package/dist/chunk-JFIU6NQP.js +51 -0
- package/dist/chunk-JFIU6NQP.js.map +1 -0
- package/dist/chunk-JRZJBMOY.js +3 -0
- package/dist/chunk-JRZJBMOY.js.map +1 -0
- package/dist/{chunk-3YP7KW47.js → chunk-JVVOL4BB.js} +41 -512
- package/dist/chunk-JVVOL4BB.js.map +1 -0
- package/dist/chunk-KAQ3UIAA.js +415 -0
- package/dist/chunk-KAQ3UIAA.js.map +1 -0
- package/dist/{chunk-P6XUDT2P.js → chunk-KJELMULA.js} +4 -51
- package/dist/chunk-KJELMULA.js.map +1 -0
- package/dist/chunk-KLO7DKXX.js +1651 -0
- package/dist/chunk-KLO7DKXX.js.map +1 -0
- package/dist/chunk-M2CMDWUI.js +75 -0
- package/dist/chunk-M2CMDWUI.js.map +1 -0
- package/dist/chunk-PQ47MLTH.js +255 -0
- package/dist/chunk-PQ47MLTH.js.map +1 -0
- package/dist/{chunk-VX3WJLKK.js → chunk-QD7BMUDF.js} +17 -8
- package/dist/chunk-QD7BMUDF.js.map +1 -0
- package/dist/{chunk-E4MESMNR.js → chunk-QTSKCPSW.js} +7 -10
- package/dist/chunk-QTSKCPSW.js.map +1 -0
- package/dist/chunk-S56FQKPL.js +186 -0
- package/dist/chunk-S56FQKPL.js.map +1 -0
- package/dist/chunk-SGAFPNMA.js +75 -0
- package/dist/chunk-SGAFPNMA.js.map +1 -0
- package/dist/{chunk-OD7P4L3D.js → chunk-SOKCLVM4.js} +3 -3
- package/dist/{chunk-OD7P4L3D.js.map → chunk-SOKCLVM4.js.map} +1 -1
- package/dist/chunk-TL42NKTH.js +3 -0
- package/dist/chunk-TL42NKTH.js.map +1 -0
- package/dist/chunk-U6ZCO2PS.js +2964 -0
- package/dist/chunk-U6ZCO2PS.js.map +1 -0
- package/dist/chunk-VSXNROYH.js +16 -0
- package/dist/chunk-VSXNROYH.js.map +1 -0
- package/dist/chunk-WPFZCYZL.js +619 -0
- package/dist/chunk-WPFZCYZL.js.map +1 -0
- package/dist/chunk-XFTNIBDW.js +23 -0
- package/dist/chunk-XFTNIBDW.js.map +1 -0
- package/dist/chunk-Y66JDL6I.js +1020 -0
- package/dist/chunk-Y66JDL6I.js.map +1 -0
- package/dist/chunk-YEHIBPIX.js +137 -0
- package/dist/chunk-YEHIBPIX.js.map +1 -0
- package/dist/chunk-YKPPCV2Z.js +53 -0
- package/dist/chunk-YKPPCV2Z.js.map +1 -0
- package/dist/components/chat/markdown.d.ts.map +1 -1
- package/dist/components/plugins/PluginSettingsPanel.d.ts.map +1 -1
- package/dist/components/settings/SettingsPage.d.ts.map +1 -1
- package/dist/connect-XKQJOWR7.js +18 -0
- package/dist/connect-XKQJOWR7.js.map +1 -0
- package/dist/crud/CrudDetailPage.d.ts.map +1 -1
- package/dist/crud/CrudListView.d.ts.map +1 -1
- package/dist/crud/CrudPage.d.ts.map +1 -1
- package/dist/crud/RelatedListTab.d.ts.map +1 -1
- package/dist/crud/archetypes/EntityLink.d.ts +1 -1
- package/dist/crud/archetypes/EntityLink.d.ts.map +1 -1
- package/dist/crud/record-chrome.d.ts.map +1 -1
- package/dist/entity-routes-PGU7EHAD.js +4 -0
- package/dist/{entity-routes-LXOBW5IB.js.map → entity-routes-PGU7EHAD.js.map} +1 -1
- package/dist/hooks/useModuleNavigation.d.ts.map +1 -1
- package/dist/impersonation/ImpersonateDialog.d.ts.map +1 -1
- package/dist/impersonation/session.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11951 -33576
- package/dist/index.js.map +1 -1
- package/dist/lib/attention.d.ts +6 -0
- package/dist/lib/attention.d.ts.map +1 -1
- package/dist/lib/entity-routes.d.ts.map +1 -1
- package/dist/org/index.js +4 -2
- package/dist/plugins/PluginRegistryManager.d.ts.map +1 -1
- package/dist/settings/MessageTemplateRow.d.ts.map +1 -1
- package/dist/timeline/PersonTimeline.d.ts.map +1 -1
- package/dist/timeline/TimelineList.d.ts.map +1 -1
- package/dist/units/UnitRailPage.d.ts.map +1 -1
- package/dist/units/useUnitFilter.d.ts.map +1 -1
- package/package.json +5 -5
- package/dist/PersonTimeline-X7JTPUWJ.js +0 -3
- package/dist/ScheduleEditor-L2UJXKMY.js +0 -6
- package/dist/SubscriptionPage-IDVEFLZ5.js +0 -8
- package/dist/chunk-3YP7KW47.js.map +0 -1
- package/dist/chunk-E4MESMNR.js.map +0 -1
- package/dist/chunk-IXSY4GPK.js.map +0 -1
- package/dist/chunk-JOBRLBIQ.js.map +0 -1
- package/dist/chunk-KPYRTOCK.js.map +0 -1
- package/dist/chunk-OQARLKZN.js.map +0 -1
- package/dist/chunk-P5UIGQFY.js.map +0 -1
- package/dist/chunk-P6XUDT2P.js.map +0 -1
- package/dist/chunk-VX3WJLKK.js.map +0 -1
- package/dist/entity-routes-LXOBW5IB.js +0 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/billing/module-pricing.ts"],"names":["units"],"mappings":"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","file":"chunk-6CQFGMEO.js","sourcesContent":["import { tl } from '@fayz-ai/core'\n\n/**\n * Module pricing — the account pays for what it turns on, scaled by how big\n * the operation is. Rationale and the worked examples live in\n * docs/saas/MODULE-PRICING.md; this file is the one place the numbers live.\n */\n\nexport type PriceBasis = 'unit' | 'account'\n\nexport interface PriceEntry {\n /** Monthly list price (BRL) for the first unit, or once for an account-wide item. */\n price: number\n /** `unit`: each unit uses it on its own (a till, a kitchen, a time clock).\n * `account`: one copy serves the whole group (the client base, the DRE). */\n per: PriceBasis\n /** [English, Portuguese] — resolved when quoted, not at import. */\n label: readonly [string, string]\n /** A proposed price for a module not built yet: listed, never billed. */\n comingSoon?: boolean\n}\n\n/** Keyed `plugin` for the module, `plugin.facet` for a paid part of it. Modules\n * not listed cost nothing on their own — they are the floor every account has. */\nexport const PRICE_BOOK: Record<string, PriceEntry> = {\n // Selling and the floor\n orders: { price: 99, per: 'unit', label: ['Orders & POS', 'Pedidos e PDV'] },\n 'orders.scale': { price: 29, per: 'unit', label: ['Scale & sale by weight', 'Balança e venda por peso'] },\n // The orders facet that takes delivery-app orders (iFood, 99Food…).\n 'orders.delivery': { price: 39, per: 'unit', label: ['Delivery & iFood', 'Delivery e iFood'] },\n tables: { price: 79, per: 'unit', label: ['Tables & tabs', 'Salão e mesas'] },\n 'tables.tablets': { price: 39, per: 'unit', label: ['Table tablets', 'Tablets de mesa'] },\n 'tables.waitlist': { price: 29, per: 'unit', label: ['Waitlist', 'Fila de espera'] },\n reservations: { price: 29, per: 'unit', label: ['Reservations', 'Reservas'] },\n menu: { price: 39, per: 'unit', label: ['Menu', 'Cardápio'] },\n 'menu.qr_menu': { price: 29, per: 'unit', label: ['QR menu', 'Cardápio digital (QR)'] },\n production: { price: 49, per: 'unit', label: ['Kitchen (KDS)', 'Cozinha (KDS)'] },\n // The resto preset mounts the kitchen as `kitchen`; same price, never both on.\n kitchen: { price: 49, per: 'unit', label: ['Kitchen (KDS)', 'Cozinha (KDS)'] },\n shop: { price: 79, per: 'account', label: ['Online store', 'Loja online'] },\n // Services\n agenda: { price: 79, per: 'unit', label: ['Schedule', 'Agenda'] },\n 'agenda.public_booking': { price: 29, per: 'unit', label: ['Online booking', 'Agendamento online'] },\n 'agenda.smart_fit': { price: 29, per: 'unit', label: ['Smart fit', 'Encaixe inteligente'] },\n 'agenda.kiosk': { price: 39, per: 'unit', label: ['Kiosks', 'Totens'] },\n clinical: { price: 79, per: 'unit', label: ['Clinical records', 'Prontuário'] },\n // Back office\n inventory: { price: 69, per: 'unit', label: ['Inventory', 'Estoque'] },\n 'inventory.costing': { price: 29, per: 'unit', label: ['Recipe costing & margin', 'Ficha técnica e CMV'] },\n 'inventory.purchasing': { price: 39, per: 'unit', label: ['Purchasing', 'Compras e reposição'] },\n financial: { price: 79, per: 'unit', label: ['Financial', 'Financeiro'] },\n 'financial.reconciliation': { price: 39, per: 'unit', label: ['Bank reconciliation', 'Conciliação bancária'] },\n 'financial.dre': { price: 19, per: 'account', label: ['P&L and cash flow', 'DRE e fluxo de caixa'] },\n 'fiscal-br': { price: 59, per: 'unit', label: ['Invoicing (NFC-e/NF-e)', 'Fiscal (NFC-e/NF-e)'] },\n openbanking: { price: 29, per: 'account', label: ['Open banking', 'Open banking'] },\n workforce: { price: 49, per: 'unit', label: ['Team & shifts', 'Equipe e escala'] },\n 'workforce.time_clock': { price: 39, per: 'unit', label: ['Time clock', 'Ponto eletrônico'] },\n // Clients and growth — one client base for the whole group\n crm: { price: 39, per: 'account', label: ['Clients (CRM)', 'Clientes (CRM)'] },\n 'crm.pipeline': { price: 19, per: 'account', label: ['Sales pipeline', 'Funil de vendas'] },\n 'crm.automation': { price: 29, per: 'account', label: ['Pipeline automations', 'Automações de funil'] },\n 'crm.loyalty': { price: 39, per: 'account', label: ['Club & cashback', 'Clube e Cashback'] },\n conversations: { price: 49, per: 'account', label: ['Conversations (WhatsApp)', 'Conversas (WhatsApp)'] },\n // The upsell every trade gets: an AI attendant answering each unit's WhatsApp.\n // Below a generic AI agent (R$ 500+) and a fraction of a receptionist.\n 'conversations.atendeai': { price: 149, per: 'unit', label: ['AI attendant', 'AtendeAI'] },\n marketing: { price: 49, per: 'account', label: ['Marketing', 'Marketing'] },\n automations: { price: 39, per: 'account', label: ['Automations', 'Automações'] },\n forms: { price: 29, per: 'account', label: ['Forms & contracts', 'Formulários e contratos'] },\n // The forms plugin's runtime id.\n custom_forms: { price: 29, per: 'account', label: ['Forms & contracts', 'Formulários e contratos'] },\n scribe: { price: 49, per: 'account', label: ['AI scribe', 'Escriba (IA)'] },\n reports: { price: 29, per: 'account', label: ['Reports', 'Relatórios'] },\n reputation: { price: 29, per: 'account', label: ['Reviews', 'Avaliações'] },\n sites: { price: 29, per: 'account', label: ['Website', 'Site'] },\n courses: { price: 49, per: 'account', label: ['Courses', 'Cursos'] },\n // Coming soon — proposed prices (docs/saas/PRICING-COMPETITORS.md), never billed.\n tiss: { price: 99, per: 'unit', label: ['Health-plan billing (TISS)', 'Faturamento de Convênio (TISS)'], comingSoon: true },\n 'pet.grooming': { price: 79, per: 'unit', label: ['Bath & grooming', 'Banho e tosa'], comingSoon: true },\n 'pet.vet': { price: 99, per: 'unit', label: ['Vet records', 'Prontuário veterinário'], comingSoon: true },\n 'pet.lodging': { price: 49, per: 'unit', label: ['Pet hotel & daycare', 'Hotel e creche'], comingSoon: true },\n 'pet.packages': { price: 29, per: 'account', label: ['Pet packages', 'Pacotes pet'], comingSoon: true },\n marketplaces: { price: 79, per: 'account', label: ['Marketplaces (Mercado Livre…)', 'Marketplaces (Mercado Livre…)'], comingSoon: true },\n}\n\n/** Modules on the price list that do not exist yet. */\nexport const COMING_SOON_MODULES: readonly string[] = Object.keys(PRICE_BOOK).filter((k) => PRICE_BOOK[k]!.comingSoon)\n\n/** Each extra unit costs less than the one before it: the first pays full, the\n * network's fiftieth pays the price of what it actually adds. */\nexport const UNIT_TIERS: ReadonlyArray<{ from: number; factor: number }> = [\n { from: 1, factor: 1 },\n { from: 2, factor: 0.85 },\n { from: 6, factor: 0.65 },\n { from: 21, factor: 0.45 },\n]\n\nexport const EXTRA_SEAT_PRICE = 19\n\n// ── The base package ───────────────────────────────────────────────────────\n// What a trade's product sells as one line, per unit: ChefControl is the\n// counter, the dining room and the back office; what a house adds on top\n// (delivery, scale, kitchen screen, invoicing, time clock, AI…) is an extra.\n// The lists are data, one place, edited per product — not a flag on a module:\n// Pedidos comes in ChefControl and StoreControl and is an extra for a salon\n// that also sells at a counter.\n\nexport interface BasePackage {\n id: string\n /** The product name the line carries (\"ChefControl · 3 unidades\"). */\n name: string\n /** Per unit, a month; units after the first take the multi-unit discount. */\n unitPrice: number\n /** Modules (and facets, when listed) that come in the package. */\n includes: readonly string[]\n}\n\nconst BACK_OFFICE = ['financial', 'inventory', 'crm', 'forms', 'custom_forms', 'marketing', 'automations', 'reports'] as const\n\nexport const BASE_PACKAGES: Readonly<Record<string, BasePackage>> = {\n // Calibrated so the 3-unit restaurant archetype lands at R$ 1.950 on Scale,\n // the price of the first proposal sent.\n chefcontrol: { id: 'chefcontrol', name: 'ChefControl', unitPrice: 328, includes: [...BACK_OFFICE, 'orders', 'tables', 'menu', 'reservations'] },\n beautycontrol: { id: 'beautycontrol', name: 'BeautyControl', unitPrice: 199, includes: [...BACK_OFFICE, 'agenda'] },\n storecontrol: { id: 'storecontrol', name: 'StoreControl', unitPrice: 189, includes: [...BACK_OFFICE, 'shop', 'orders'] },\n gocontrol: { id: 'gocontrol', name: 'GoControl', unitPrice: 149, includes: [...BACK_OFFICE] },\n}\n\n/** Which package each trade buys. Trades without a product of their own buy GoControl. */\nexport const PACKAGE_BY_TRADE: Readonly<Record<string, string>> = {\n food: 'chefcontrol', beauty: 'beautycontrol', commerce: 'storecontrol',\n}\n\n/** The package for an operation: the one named, else the trade's, else read\n * from what it runs (a counter → ChefControl, a schedule → BeautyControl). */\nexport function packageFor(opts: { package?: string; trades?: readonly string[]; modules?: readonly string[] } = {}): BasePackage {\n if (opts.package && BASE_PACKAGES[opts.package]) return BASE_PACKAGES[opts.package]!\n for (const t of opts.trades ?? []) {\n const id = PACKAGE_BY_TRADE[t]\n if (id) return BASE_PACKAGES[id]!\n }\n const on = new Set(opts.modules ?? [])\n if (['tables', 'menu', 'kitchen', 'production', 'reservations'].some((k) => on.has(k))) return BASE_PACKAGES.chefcontrol!\n if (['agenda', 'clinical'].some((k) => on.has(k))) return BASE_PACKAGES.beautycontrol!\n if (on.has('shop')) return BASE_PACKAGES.storecontrol!\n return BASE_PACKAGES.gocontrol!\n}\n\n/** A module or facet the package covers. A facet is covered only when listed:\n * Pedidos is in ChefControl, Balança (orders.scale) is still an extra. */\nexport function includedIn(pkg: BasePackage | null | undefined, key: string, extra?: readonly string[]): boolean {\n return !!pkg && (pkg.includes.includes(key) || !!extra?.includes(key))\n}\n\nexport interface PricingPlan {\n id: string\n name: readonly [string, string]\n /** Platform fee: login, registries, dashboard, support. Paid once. */\n platformFee: number\n /** Logins included per unit; `null` is unlimited. */\n seatsPerUnit: number | null\n /** Off the modules subtotal (after unit tiers). */\n discount: number\n /** AI assistant credits included a month. */\n aiCredits?: number\n}\n\n/** Credits a free plan includes when the app does not say. */\nexport const FREE_AI_CREDITS = 30\n\n/** Proposal (docs/saas/MODULE-PRICING.md): extra assistant credits, monthly packs. */\n/** The add-on the screen offers when it is off. */\nexport const UPSELL_KEY = 'conversations.atendeai'\n\nexport const EXTRA_AI_CREDITS: ReadonlyArray<{ credits: number; price: number }> = [\n { credits: 100, price: 19 },\n { credits: 1000, price: 149 },\n]\n\n/** `a-la-carte` is the price without a plan; the other ids are the ones\n * `app.plan_grants` uses. */\nexport const PRICING_PLANS: readonly PricingPlan[] = [\n { id: 'a-la-carte', name: ['À la carte', 'Avulso'], platformFee: 99, seatsPerUnit: 3, discount: 0, aiCredits: 50 },\n { id: 'essential', name: ['Essential', 'Essencial'], platformFee: 79, seatsPerUnit: 5, discount: 0, aiCredits: 100 },\n // Pro is the natural middle: a lower fee and a real discount make it the\n // cheapest choice once a salon or restaurant outgrows five logins.\n { id: 'pro', name: ['Pro', 'Pro'], platformFee: 119, seatsPerUnit: 7, discount: 0.08, aiCredits: 300 },\n { id: 'scale', name: ['Scale', 'Scale'], platformFee: 449, seatsPerUnit: null, discount: 0.1, aiCredits: 1000 },\n]\n\n/** One unit and the per-unit modules it actually runs: a dark kitchen has no\n * dining room, so it does not pay for one. */\nexport interface UnitFootprint {\n id: string\n name: string\n modules: readonly string[]\n}\n\nexport interface OperationSize {\n /** Units (stores, branches). At least 1 is charged. */\n units: number\n /** What each unit runs. Absent, every unit runs every per-unit module on. */\n unitModules?: readonly UnitFootprint[]\n /** People with a login. */\n users: number\n /** Active modules and paid facets: `plugin` or `plugin.facet`. */\n modules: readonly string[]\n /** The base package (`BASE_PACKAGES` id). Absent, read from the trade or the modules. */\n package?: string\n /** The trades this operation runs, when known. */\n trades?: readonly string[]\n /** Extras negotiated into the package for this account. */\n alsoIncluded?: readonly string[]\n}\n\nexport type QuoteLineKind = 'platform' | 'package' | 'module' | 'unit' | 'tier' | 'seats' | 'discount' | 'credits'\n\nexport interface QuoteLine {\n kind: QuoteLineKind\n key: string\n label: string\n /** Human formula: \"R$ 79 × 3 unidades\". */\n detail: string\n amount: number\n}\n\nexport interface Quote {\n planId: string\n planName: string\n lines: QuoteLine[]\n total: number\n}\n\nconst round = (n: number) => Math.round(n * 100) / 100\nconst brl = (n: number) => `R$ ${n.toLocaleString('pt-BR', { minimumFractionDigits: 0, maximumFractionDigits: 2 })}`\n\n/** \"Pedidos e PDV, Salão e mesas, … e Análises\" — the package's priced contents. */\nexport function packageSummary(pkg: BasePackage): string {\n const seen = new Set<string>()\n const names = pkg.includes\n .filter((k) => PRICE_BOOK[k])\n .map((k) => tl(...PRICE_BOOK[k]!.label))\n .filter((n) => (seen.has(n) ? false : (seen.add(n), true)))\n return names.length > 1 ? `${names.slice(0, -1).join(', ')} ${tl('and', 'e')} ${names[names.length - 1]}` : names.join('')\n}\n\n/** The share the n-th unit (1-based) pays of its per-unit modules. */\nexport function tierFactorAt(n: number): number {\n let factor = UNIT_TIERS[0]!.factor\n for (const tier of UNIT_TIERS) if (n >= tier.from) factor = tier.factor\n return factor\n}\n\n/** Sum of the tier factors for `units` units: 3 units → 1 + 0.85 + 0.85. */\nexport function unitFactor(units: number): number {\n const n = Math.max(1, Math.floor(units))\n let sum = 0\n for (let i = 1; i <= n; i++) {\n let factor = UNIT_TIERS[0]!.factor\n for (const tier of UNIT_TIERS) if (i >= tier.from) factor = tier.factor\n sum += factor\n }\n return sum\n}\n\n/** Only priced keys, once each, in price-book order. */\nexport function billableModules(modules: readonly string[], pkg?: BasePackage | null, alsoIncluded?: readonly string[]): string[] {\n const on = new Set(modules)\n return Object.keys(PRICE_BOOK).filter((key) => {\n if (!on.has(key) || PRICE_BOOK[key]!.comingSoon || includedIn(pkg, key, alsoIncluded)) return false\n // A facet without its module is not running, so it is not billed.\n const dot = key.indexOf('.')\n return dot < 0 || on.has(key.slice(0, dot))\n })\n}\n\nexport function quote(size: OperationSize, plan: PricingPlan): Quote {\n const units = Math.max(1, Math.floor(size.unitModules?.length || size.units))\n const lines: QuoteLine[] = [{\n kind: 'platform', key: 'platform', label: tl('Platform', 'Plataforma'),\n detail: tl('Login, registries, dashboard and support', 'Acesso, cadastros, painel e suporte'),\n amount: plan.platformFee,\n }]\n\n const footprints = size.unitModules?.length ? size.unitModules : null\n const all = [...size.modules, ...(footprints ?? []).flatMap((u) => u.modules)]\n const pkg = packageFor({ package: size.package, trades: size.trades, modules: all })\n const negotiated = size.alsoIncluded\n\n // The package is ONE line: every unit pays it, the next ones less.\n const base = pkg.unitPrice * unitFactor(units)\n let modules = base\n let tierOff = 0\n lines.push({\n kind: 'package', key: `package:${pkg.id}`,\n label: `${pkg.name} · ${units} ${units === 1 ? tl('unit', 'unidade') : tl('units', 'unidades')}`,\n detail: `${tl('Includes', 'Inclui')} ${packageSummary(pkg)} · ${brl(pkg.unitPrice)} ${tl('the first unit, less for the next', 'a primeira unidade, menos nas seguintes')}`,\n amount: round(base),\n })\n // A unit's add-on switches on its account-wide module too (AtendeAI → Conversas), billed once.\n const on = billableModules(all, pkg, negotiated)\n\n if (footprints) {\n // Each unit is a line with what it runs; the unit that spends most pays in\n // full and the others take the multi-unit discount by their position.\n const perUnit = footprints.map((u) => {\n const keys = billableModules(u.modules, pkg, negotiated).filter((k) => PRICE_BOOK[k]!.per === 'unit')\n return { u, keys, list: keys.reduce((sum, k) => sum + PRICE_BOOK[k]!.price, 0) }\n }).sort((a, b) => b.list - a.list)\n perUnit.forEach(({ u, keys, list }, i) => {\n modules += list\n tierOff += list * (1 - tierFactorAt(i + 1))\n // A unit that runs only the package adds nothing to say.\n if (!keys.length) return\n lines.push({\n kind: 'unit', key: `unit:${u.id}`, label: u.name,\n detail: keys.map((k) => tl(...PRICE_BOOK[k]!.label)).join(' · ') || tl('No per-unit module', 'Nenhum módulo por unidade'),\n amount: list,\n })\n })\n }\n\n let perUnitList = 0\n for (const key of on) {\n const entry = PRICE_BOOK[key]!\n if (footprints && entry.per === 'unit') continue\n const amount = entry.per === 'unit' ? entry.price * units : entry.price\n if (entry.per === 'unit') perUnitList += entry.price\n modules += amount\n lines.push({\n kind: 'module', key, label: tl(...entry.label),\n detail: entry.per === 'unit' && units > 1\n ? `${brl(entry.price)} × ${units} ${tl('units', 'unidades')}`\n : entry.per === 'unit' ? tl('per unit', 'por unidade') : tl('whole group', 'grupo todo'),\n amount,\n })\n }\n\n // Volume: units beyond the first pay a smaller share of the per-unit modules.\n if (!footprints) tierOff = perUnitList * (units - unitFactor(units))\n tierOff = round(tierOff)\n if (tierOff > 0) {\n lines.push({\n kind: 'tier', key: 'unit-tiers', label: tl('Multi-unit discount', 'Desconto por unidade adicional'),\n detail: tl('Units 2–5 pay 85%, 6–20 pay 65%, 21+ pay 45%', 'Unidades 2–5 pagam 85%, 6–20 pagam 65%, 21+ pagam 45%'),\n amount: -tierOff,\n })\n }\n\n if (plan.discount > 0 && modules > 0) {\n const off = round((modules - tierOff) * plan.discount)\n lines.push({\n kind: 'discount', key: 'plan-discount', label: `${tl('Plan discount', 'Desconto do plano')} ${tl(...plan.name)}`,\n detail: `${Math.round(plan.discount * 100)}% ${tl('off the modules', 'sobre os módulos')}`,\n amount: -off,\n })\n }\n\n if (plan.seatsPerUnit === null) {\n lines.push({ kind: 'seats', key: 'seats', label: tl('Users', 'Usuários'), detail: tl('Unlimited', 'Ilimitados'), amount: 0 })\n } else {\n const included = plan.seatsPerUnit * units\n const extra = Math.max(0, Math.floor(size.users) - included)\n lines.push({\n kind: 'seats', key: 'seats', label: tl('Users', 'Usuários'),\n detail: extra > 0\n ? `${extra} ${tl('beyond the', 'além dos')} ${included} ${tl('included', 'incluídos')} × ${brl(EXTRA_SEAT_PRICE)}`\n : `${Math.floor(size.users)} ${tl('of', 'de')} ${included} ${tl('included', 'incluídos')}`,\n amount: extra * EXTRA_SEAT_PRICE,\n })\n }\n\n if (plan.aiCredits) {\n lines.push({\n kind: 'credits', key: 'ai-credits', label: tl('AI assistant', 'Assistente de IA'),\n detail: `${plan.aiCredits.toLocaleString('pt-BR')} ${tl('credits/mo included', 'créditos/mês incluídos')}`,\n amount: 0,\n })\n }\n\n const total = round(lines.reduce((sum, line) => sum + line.amount, 0))\n return { planId: plan.id, planName: tl(...plan.name), lines, total }\n}\n\n/** Every plan for one operation, cheapest first marked by the caller. */\nexport function quoteAll(size: OperationSize, plans: readonly PricingPlan[] = PRICING_PLANS): Quote[] {\n return plans.map((plan) => quote(size, plan))\n}\n\n/** The plugin runtime's view of what is on, as price-book keys. */\n/** The plugin runtime's view of what is on, as price-book keys. A plugin\n * running only because another needs it (orders under a salon's agenda) is not\n * something the account chose, so it is not billed; with `trades`/`offered`,\n * only what the account's trade offers counts. */\nexport function activeModuleKeys(\n plugins: ReadonlyArray<{ id: string; isActive?: boolean; activationReason?: string; config?: { facets?: unknown } | null }>,\n opts: { trades?: readonly Trade[]; offered?: readonly string[] } = {},\n): string[] {\n const out: string[] = []\n for (const plugin of plugins) {\n if (!plugin.isActive || plugin.activationReason === 'dependency') continue\n if (opts.offered?.length && !opts.offered.includes(plugin.id)) continue\n const keys = [plugin.id]\n const facets = (plugin.config?.facets ?? {}) as Record<string, boolean>\n for (const [facet, on] of Object.entries(facets)) if (on) keys.push(`${plugin.id}.${facet}`)\n out.push(...(opts.trades?.length ? keys.filter((k) => moduleFitsTrades(k, opts.trades!)) : keys))\n }\n return out\n}\n\n// ── Which trade a module belongs to ────────────────────────────────────────\n// One place for the rule \"o ofício oferece\": the pricing sheet and the Módulos\n// page both read it. A salon never sees Pedidos e PDV; a restaurant books\n// through Reservas, never Agenda.\n\n/** The same vocabulary as `tenants.vertical_id` (097). */\n// `pet` has no app yet; it tags the coming-soon pet modules.\nexport type Trade = 'food' | 'beauty' | 'commerce' | 'education' | 'events' | 'accounting' | 'generic' | 'pet'\n\nconst FOOD_COMMERCE: readonly Trade[] = ['food', 'commerce']\nconst SERVICES: readonly Trade[] = ['beauty', 'education']\n\n/** Keys missing here (financial, crm, inventory…) serve every trade. */\nexport const MODULE_TRADES: Readonly<Record<string, readonly Trade[]>> = {\n orders: FOOD_COMMERCE,\n 'orders.scale': FOOD_COMMERCE,\n 'orders.delivery': FOOD_COMMERCE,\n shop: ['commerce', 'food'],\n tables: ['food'],\n 'tables.tablets': ['food'],\n 'tables.waitlist': ['food'],\n reservations: ['food'],\n menu: ['food'],\n 'menu.qr_menu': ['food'],\n production: ['food'],\n kitchen: ['food'],\n 'inventory.costing': ['food'],\n agenda: SERVICES,\n 'agenda.public_booking': SERVICES,\n 'agenda.smart_fit': SERVICES,\n 'agenda.kiosk': SERVICES,\n clinical: ['beauty'],\n scribe: ['beauty'],\n courses: ['education'],\n tiss: ['beauty'],\n 'pet.grooming': ['pet'],\n 'pet.vet': ['pet'],\n 'pet.lodging': ['pet'],\n 'pet.packages': ['pet'],\n marketplaces: ['commerce'],\n}\n\n/** The trade each app (`app.apps.id`) sells to — 097's table. */\nexport const TRADE_BY_APP: Readonly<Record<string, Trade>> = {\n resto: 'food', beauty: 'beauty', shop: 'commerce', school: 'education',\n ticket: 'events', fiscal: 'accounting', full: 'generic',\n}\n\n/** A module (or facet) that serves at least one of `trades`. */\nexport function moduleFitsTrades(key: string, trades: readonly Trade[]): boolean {\n const own = MODULE_TRADES[key] ?? MODULE_TRADES[key.split('.')[0]!]\n return !own || own.some((t) => trades.includes(t))\n}\n\n/** Every priced key this trade can turn on, in price-book order. */\nexport function modulesForTrade(trade: Trade): string[] {\n return Object.keys(PRICE_BOOK).filter((k) => moduleFitsTrades(k, [trade]))\n}\n\n/** The per-unit priced modules among `modules`, for a unit's footprint. */\nexport function perUnitModules(modules: readonly string[], pkg?: BasePackage | null): string[] {\n return billableModules(modules, pkg).filter((k) => PRICE_BOOK[k]!.per === 'unit')\n}\n\n/** Generic operations the Assinatura screen prices next to the account's own.\n * Shipped to every tenant: archetypes only, never a customer's name or size. */\nexport type ScenarioVertical = 'food' | 'beauty' | 'commerce' | 'generic'\n\nexport interface PricingScenario {\n id: string\n name: readonly [string, string]\n vertical: ScenarioVertical\n assumptions?: readonly string[]\n size: OperationSize\n}\n\nexport const SCENARIO_VERTICAL_LABELS: Record<ScenarioVertical, readonly [string, string]> = {\n food: ['Food service', 'Alimentação'],\n beauty: ['Beauty & clinics', 'Beleza e clínicas'],\n commerce: ['Retail & e-commerce', 'Varejo e loja online'],\n generic: ['Other', 'Outros'],\n}\n\nconst BEAUTY_UNIT = ['agenda', 'inventory', 'financial', 'fiscal-br', 'workforce'] as const\nconst BEAUTY_ACCOUNT = ['crm', 'marketing', 'automations', 'custom_forms', 'reports'] as const\nconst RESTAURANT_UNIT = ['orders', 'orders.delivery', 'tables', 'reservations', 'menu', 'menu.qr_menu', 'kitchen', 'inventory', 'inventory.costing', 'financial', 'fiscal-br', 'workforce'] as const\nconst units = (n: number, prefix: string, modules: readonly string[]): UnitFootprint[] =>\n Array.from({ length: n }, (_, i) => ({ id: `${prefix}-${i + 1}`, name: `${prefix === 'u' ? 'Unidade' : prefix} ${i + 1}`, modules }))\n\nexport const PRICING_SCENARIOS: ReadonlyArray<PricingScenario> = [\n {\n // Calibration point: a three-format restaurant group lands near R$ 1.950 on the top plan.\n id: 'restaurante-3-unidades',\n name: ['Restaurant group, 3 units (store, dining room, dark kitchen)', 'Restaurante com 3 unidades (empório, salão, dark kitchen)'],\n vertical: 'food',\n assumptions: ['Usuários ilimitados no plano de cima; 40 pessoas com login.'],\n size: {\n units: 3,\n users: 40,\n modules: ['crm', 'financial', 'financial.dre', 'reports'],\n unitModules: [\n { id: 'emporio', name: 'Empório', modules: ['orders', 'orders.scale', 'orders.delivery', 'inventory', 'inventory.purchasing', 'financial', 'financial.reconciliation', 'fiscal-br', 'workforce', 'workforce.time_clock'] },\n { id: 'salao', name: 'Restaurante com salão', modules: ['tables', 'reservations', 'menu', 'menu.qr_menu', 'orders', 'orders.delivery', 'production', 'inventory', 'inventory.costing', 'financial', 'fiscal-br', 'workforce', 'workforce.time_clock'] },\n { id: 'dark', name: 'Dark kitchen', modules: ['orders', 'orders.delivery', 'production', 'inventory', 'inventory.costing', 'financial', 'fiscal-br', 'workforce', 'workforce.time_clock'] },\n ],\n },\n },\n {\n id: 'cafe',\n name: ['Café, 1 unit', 'Café de 1 unidade'],\n vertical: 'food',\n size: { units: 1, users: 4, modules: ['orders', 'financial', 'inventory', 'fiscal-br'] },\n },\n {\n id: 'rede-10',\n name: ['Restaurant network, 10 units', 'Rede de restaurantes, 10 unidades'],\n vertical: 'food',\n size: {\n units: 10,\n users: 120,\n modules: ['orders', 'orders.delivery', 'menu', 'menu.qr_menu', 'production', 'inventory', 'inventory.costing', 'financial', 'financial.dre', 'fiscal-br', 'workforce', 'workforce.time_clock', 'crm', 'crm.loyalty', 'reports'],\n },\n },\n {\n id: 'restaurante-e-servicos',\n name: ['Restaurant + back office, 2 units', 'Restaurante + escritório, 2 unidades'],\n vertical: 'food',\n assumptions: ['Uma unidade com toda a operação; a outra só com financeiro, equipe e ponto.'],\n size: {\n units: 2,\n users: 25,\n modules: ['crm', 'financial', 'financial.dre', 'reports'],\n unitModules: [\n { id: 'restaurante', name: 'Restaurante', modules: [...RESTAURANT_UNIT] },\n { id: 'escritorio', name: 'Escritório', modules: ['financial', 'workforce', 'workforce.time_clock'] },\n ],\n },\n },\n {\n id: 'rede-estetica-60',\n name: ['Beauty network, 60 units', 'Rede de estética, 60 unidades'],\n vertical: 'beauty',\n assumptions: ['Todas as unidades com agenda, prontuário, estoque, financeiro, fiscal e equipe; 6 logins por unidade.'],\n size: { units: 60, users: 360, modules: [...BEAUTY_ACCOUNT, 'financial', 'financial.dre'], unitModules: units(60, 'u', [...BEAUTY_UNIT, 'clinical']) },\n },\n {\n id: 'saloes-3',\n name: ['Salon chain, 3 units', 'Rede de salões, 3 unidades'],\n vertical: 'beauty',\n size: { units: 3, users: 24, modules: [...BEAUTY_ACCOUNT, 'financial', 'financial.dre'], unitModules: units(3, 'u', [...BEAUTY_UNIT]) },\n },\n {\n id: 'salao-1',\n name: ['Salon, 1 unit', 'Salão de 1 unidade'],\n vertical: 'beauty',\n size: { units: 1, users: 6, modules: [...BEAUTY_UNIT, ...BEAUTY_ACCOUNT] },\n },\n {\n id: 'clinica-1',\n name: ['Aesthetic clinic, 1 unit', 'Clínica de estética, 1 unidade'],\n vertical: 'beauty',\n size: { units: 1, users: 5, modules: ['agenda', 'clinical', 'financial', 'fiscal-br', 'crm', 'custom_forms'] },\n },\n {\n id: 'cozinha-loja-online',\n name: ['Central kitchen + online store', 'Cozinha central + loja online'],\n vertical: 'food',\n size: { units: 1, users: 9, modules: ['shop', 'orders', 'kitchen', 'inventory', 'inventory.costing', 'inventory.purchasing', 'financial', 'fiscal-br', 'crm'] },\n },\n {\n id: 'loja-online-fisica',\n name: ['Online store + physical store', 'Loja online + loja física'],\n vertical: 'commerce',\n size: {\n units: 2,\n users: 4,\n modules: ['shop', 'financial', 'crm'],\n unitModules: [\n { id: 'online', name: 'Loja online', modules: ['orders', 'inventory', 'financial'] },\n { id: 'fisica', name: 'Loja física', modules: ['orders', 'inventory', 'financial', 'fiscal-br'] },\n ],\n },\n },\n]\n\n/** The slice of an app plan the price model reads. */\nexport interface PricedPlanSource {\n id: string\n name: string\n price: number\n pricing?: { platformFee: number; seatsPerUnit: number | null; discount: number; aiCredits?: number }\n entitlements?: { limits?: Record<string, number> }\n}\n\n/**\n * Price-model parameters for each app plan, in the same order. A plan's own\n * `pricing` wins; otherwise paid plans take the model's tiers from the top\n * (the richest plan is Scale) and a free plan stays free (`null`).\n */\nexport function pricingForPlans(plans: readonly PricedPlanSource[]): Array<PricingPlan | null> {\n const tiers = PRICING_PLANS.filter((p) => p.id !== 'a-la-carte')\n const paid = plans.filter((p) => p.price > 0 && !p.pricing).sort((a, b) => a.price - b.price)\n return plans.map((plan) => {\n const declared = plan.entitlements?.limits?.ai_credits_month\n const credits = declared !== undefined && declared >= 0 ? { aiCredits: declared } : {}\n if (plan.pricing) return { id: plan.id, name: [plan.name, plan.name], ...plan.pricing, ...credits }\n if (plan.price <= 0) return null\n const rank = paid.indexOf(plan) - paid.length + tiers.length\n const tier = tiers[Math.max(0, rank)]!\n return { ...tier, id: plan.id, name: [plan.name, plan.name], ...credits }\n })\n}\n\nexport type PlanFit = { fits: true } | { fits: false; limit: 'locations' | 'users'; max: number; have: number }\n\n/** AI credits a plan includes a month: what the app declares, else the mapped\n * tier, else the free allowance. */\nexport function aiCreditsFor(plan: PricedPlanSource, pricing: PricingPlan | null): number {\n const declared = plan.entitlements?.limits?.ai_credits_month\n if (declared !== undefined && declared >= 0) return declared\n return pricing?.aiCredits ?? FREE_AI_CREDITS\n}\n\n/** Whether the operation fits the plan's caps (units, logins); -1 is unlimited. */\nexport function planFit(plan: PricedPlanSource, size: Pick<OperationSize, 'units' | 'users' | 'unitModules'>): PlanFit {\n const limits = plan.entitlements?.limits ?? {}\n const units = size.unitModules?.length || size.units\n const checks: Array<['locations' | 'users', number]> = [['locations', units], ['users', size.users]]\n for (const [limit, have] of checks) {\n const max = limits[limit]\n if (max !== undefined && max >= 0 && have > max) return { fits: false, limit, max, have }\n }\n return { fits: true }\n}\n"]}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { useOrganizationStore } from './chunk-YKPPCV2Z.js';
|
|
2
|
+
import { getSupabaseClientOptional, getActiveTenantId } from '@fayz-ai/core';
|
|
3
|
+
import { create } from 'zustand';
|
|
4
|
+
|
|
5
|
+
var TABLE = "published_sites";
|
|
6
|
+
function db() {
|
|
7
|
+
const client = getSupabaseClientOptional();
|
|
8
|
+
if (!client) throw new Error("[fayz-projects] Supabase not initialized");
|
|
9
|
+
return client;
|
|
10
|
+
}
|
|
11
|
+
function tenantId() {
|
|
12
|
+
return useOrganizationStore.getState().currentOrg?.id ?? getActiveTenantId();
|
|
13
|
+
}
|
|
14
|
+
function rowToProject(row) {
|
|
15
|
+
return {
|
|
16
|
+
id: row.id,
|
|
17
|
+
tenantId: row.tenant_id,
|
|
18
|
+
fayzProjectId: row.provider_site_id ?? null,
|
|
19
|
+
appId: row.app_id ?? null,
|
|
20
|
+
name: row.name,
|
|
21
|
+
kind: row.kind ?? "site",
|
|
22
|
+
isDefault: row.is_default ?? false,
|
|
23
|
+
storefrontEnabled: row.storefront_enabled ?? false,
|
|
24
|
+
previewUrl: row.preview_url ?? null,
|
|
25
|
+
editorUrl: row.editor_url ?? null,
|
|
26
|
+
slug: row.slug ?? null,
|
|
27
|
+
metadata: row.metadata ?? {},
|
|
28
|
+
createdAt: row.created_at,
|
|
29
|
+
updatedAt: row.updated_at
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function inputToRow(input) {
|
|
33
|
+
const row = {};
|
|
34
|
+
if ("name" in input && input.name !== void 0) row.name = input.name;
|
|
35
|
+
if (input.kind !== void 0) row.kind = input.kind;
|
|
36
|
+
if (input.fayzProjectId !== void 0) row.provider_site_id = input.fayzProjectId;
|
|
37
|
+
if (input.appId !== void 0) row.app_id = input.appId;
|
|
38
|
+
if (input.isDefault !== void 0) row.is_default = input.isDefault;
|
|
39
|
+
if (input.storefrontEnabled !== void 0) row.storefront_enabled = input.storefrontEnabled;
|
|
40
|
+
if (input.previewUrl !== void 0) row.preview_url = input.previewUrl;
|
|
41
|
+
if (input.editorUrl !== void 0) row.editor_url = input.editorUrl;
|
|
42
|
+
if (input.slug !== void 0) row.slug = input.slug;
|
|
43
|
+
return row;
|
|
44
|
+
}
|
|
45
|
+
async function listFayzProjects() {
|
|
46
|
+
const tid = tenantId();
|
|
47
|
+
let q = db().from(TABLE).select("*").order("is_default", { ascending: false }).order("created_at", { ascending: true });
|
|
48
|
+
if (tid) q = q.eq("tenant_id", tid);
|
|
49
|
+
const { data, error } = await q;
|
|
50
|
+
if (error) throw error;
|
|
51
|
+
return (data ?? []).map(rowToProject);
|
|
52
|
+
}
|
|
53
|
+
async function getDefaultFayzProject() {
|
|
54
|
+
const projects = await listFayzProjects();
|
|
55
|
+
return projects.find((p) => p.isDefault) ?? projects[0] ?? null;
|
|
56
|
+
}
|
|
57
|
+
async function createFayzProject(input) {
|
|
58
|
+
if (input.isDefault) await clearDefault();
|
|
59
|
+
const { data, error } = await db().from(TABLE).insert({ tenant_id: tenantId(), ...inputToRow(input) }).select().single();
|
|
60
|
+
if (error) throw error;
|
|
61
|
+
return rowToProject(data);
|
|
62
|
+
}
|
|
63
|
+
async function updateFayzProject(id, input) {
|
|
64
|
+
if (input.isDefault) await clearDefault(id);
|
|
65
|
+
const { data, error } = await db().from(TABLE).update(inputToRow(input)).eq("id", id).select().single();
|
|
66
|
+
if (error) throw error;
|
|
67
|
+
return rowToProject(data);
|
|
68
|
+
}
|
|
69
|
+
async function deleteFayzProject(id) {
|
|
70
|
+
const { error } = await db().from(TABLE).delete().eq("id", id);
|
|
71
|
+
if (error) throw error;
|
|
72
|
+
}
|
|
73
|
+
async function clearDefault(keepId) {
|
|
74
|
+
const tid = tenantId();
|
|
75
|
+
let q = db().from(TABLE).update({ is_default: false }).eq("is_default", true);
|
|
76
|
+
if (tid) q = q.eq("tenant_id", tid);
|
|
77
|
+
if (keepId) q = q.neq("id", keepId);
|
|
78
|
+
await q;
|
|
79
|
+
}
|
|
80
|
+
var useFayzProjectsStore = create((set, get) => ({
|
|
81
|
+
projects: [],
|
|
82
|
+
loading: false,
|
|
83
|
+
loadedFor: null,
|
|
84
|
+
load: async (tenantId2) => {
|
|
85
|
+
if (!getSupabaseClientOptional()) {
|
|
86
|
+
set({ projects: [], loading: false, loadedFor: tenantId2 ?? null });
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
set({ loading: true });
|
|
90
|
+
try {
|
|
91
|
+
const projects = await listFayzProjects();
|
|
92
|
+
set({ projects, loading: false, loadedFor: tenantId2 ?? null });
|
|
93
|
+
} catch {
|
|
94
|
+
set({ projects: [], loading: false, loadedFor: tenantId2 ?? null });
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
refresh: async () => {
|
|
98
|
+
try {
|
|
99
|
+
const projects = await listFayzProjects();
|
|
100
|
+
set({ projects });
|
|
101
|
+
} catch {
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}));
|
|
105
|
+
function defaultProjectOf(projects) {
|
|
106
|
+
return projects.find((p) => p.isDefault) ?? projects[0] ?? null;
|
|
107
|
+
}
|
|
108
|
+
var EDITOR_BASE = "https://fayz.ai/editor";
|
|
109
|
+
function editorUrlOf(p) {
|
|
110
|
+
if (p.editorUrl) return p.editorUrl;
|
|
111
|
+
return p.fayzProjectId ? `${EDITOR_BASE}/${p.fayzProjectId}` : null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export { createFayzProject, defaultProjectOf, deleteFayzProject, editorUrlOf, getDefaultFayzProject, listFayzProjects, updateFayzProject, useFayzProjectsStore };
|
|
115
|
+
//# sourceMappingURL=chunk-6MMSYC2I.js.map
|
|
116
|
+
//# sourceMappingURL=chunk-6MMSYC2I.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/projects/provider.ts","../src/projects/store.ts"],"names":["tenantId","getSupabaseClientOptional"],"mappings":"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","file":"chunk-6MMSYC2I.js","sourcesContent":["import { getSupabaseClientOptional, getActiveTenantId } from '@fayz-ai/core'\nimport { useOrganizationStore } from '../org/store'\nimport type { FayzProject, CreateFayzProjectInput, UpdateFayzProjectInput } from './types'\n\n// Supabase-backed access to public.fayz_projects, scoped to the current tenant.\n// No dedicated provider abstraction: this is a thin, single-table CRUD the shell\n// owns. Reads go through the authenticated client so RLS (tenant_id IN\n// user_tenant_ids()) applies.\n\nconst TABLE = 'published_sites'\n\nfunction db(): any {\n const client = getSupabaseClientOptional() as any\n if (!client) throw new Error('[fayz-projects] Supabase not initialized')\n return client\n}\n\n/** Current tenant id: the selected workspace, falling back to the core active tenant. */\nfunction tenantId(): string | undefined {\n return useOrganizationStore.getState().currentOrg?.id ?? getActiveTenantId()\n}\n\nfunction rowToProject(row: any): FayzProject {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n fayzProjectId: row.provider_site_id ?? null,\n appId: row.app_id ?? null,\n name: row.name,\n kind: row.kind ?? 'site',\n isDefault: row.is_default ?? false,\n storefrontEnabled: row.storefront_enabled ?? false,\n previewUrl: row.preview_url ?? null,\n editorUrl: row.editor_url ?? null,\n slug: row.slug ?? null,\n metadata: row.metadata ?? {},\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n }\n}\n\nfunction inputToRow(input: CreateFayzProjectInput | UpdateFayzProjectInput): Record<string, unknown> {\n const row: Record<string, unknown> = {}\n if ('name' in input && input.name !== undefined) row.name = input.name\n if (input.kind !== undefined) row.kind = input.kind\n if (input.fayzProjectId !== undefined) row.provider_site_id = input.fayzProjectId\n if (input.appId !== undefined) row.app_id = input.appId\n if (input.isDefault !== undefined) row.is_default = input.isDefault\n if (input.storefrontEnabled !== undefined) row.storefront_enabled = input.storefrontEnabled\n if (input.previewUrl !== undefined) row.preview_url = input.previewUrl\n if (input.editorUrl !== undefined) row.editor_url = input.editorUrl\n if (input.slug !== undefined) row.slug = input.slug\n return row\n}\n\nexport async function listFayzProjects(): Promise<FayzProject[]> {\n const tid = tenantId()\n let q = db().from(TABLE).select('*').order('is_default', { ascending: false }).order('created_at', { ascending: true })\n if (tid) q = q.eq('tenant_id', tid)\n const { data, error } = await q\n if (error) throw error\n return (data ?? []).map(rowToProject)\n}\n\n/** The tenant's default project, or the first one when none is flagged default. */\nexport async function getDefaultFayzProject(): Promise<FayzProject | null> {\n const projects = await listFayzProjects()\n return projects.find((p) => p.isDefault) ?? projects[0] ?? null\n}\n\nexport async function createFayzProject(input: CreateFayzProjectInput): Promise<FayzProject> {\n // A tenant keeps at most one default (partial unique index). Clearing the old\n // default first keeps the insert from tripping it.\n if (input.isDefault) await clearDefault()\n const { data, error } = await db().from(TABLE)\n .insert({ tenant_id: tenantId(), ...inputToRow(input) })\n .select().single()\n if (error) throw error\n return rowToProject(data)\n}\n\nexport async function updateFayzProject(id: string, input: UpdateFayzProjectInput): Promise<FayzProject> {\n if (input.isDefault) await clearDefault(id)\n const { data, error } = await db().from(TABLE).update(inputToRow(input)).eq('id', id).select().single()\n if (error) throw error\n return rowToProject(data)\n}\n\nexport async function deleteFayzProject(id: string): Promise<void> {\n const { error } = await db().from(TABLE).delete().eq('id', id)\n if (error) throw error\n}\n\n/** Demote the current default for this tenant (except `keepId`), so a new default\n * can be set without violating fayz_projects_one_default_per_tenant. */\nasync function clearDefault(keepId?: string): Promise<void> {\n const tid = tenantId()\n let q = db().from(TABLE).update({ is_default: false }).eq('is_default', true)\n if (tid) q = q.eq('tenant_id', tid)\n if (keepId) q = q.neq('id', keepId)\n await q\n}\n","import { create } from 'zustand'\nimport { getSupabaseClientOptional } from '@fayz-ai/core'\nimport { listFayzProjects } from './provider'\nimport type { FayzProject } from './types'\n\n// Shared, tenant-scoped cache of the current workspace's fayz projects. The\n// \"Seu site\" sidebar widget and the Projetos settings tab read from here; a\n// settings edit calls refresh() so the widget updates without a reload.\n\ninterface FayzProjectsState {\n projects: FayzProject[]\n loading: boolean\n /** Tenant the current projects were loaded for — guards against stale loads. */\n loadedFor: string | null\n load: (tenantId: string | undefined) => Promise<void>\n refresh: () => Promise<void>\n}\n\nexport const useFayzProjectsStore = create<FayzProjectsState>((set, get) => ({\n projects: [],\n loading: false,\n loadedFor: null,\n load: async (tenantId) => {\n // No supabase (mock apps) → nothing to load; the widget self-hides.\n if (!getSupabaseClientOptional()) {\n set({ projects: [], loading: false, loadedFor: tenantId ?? null })\n return\n }\n set({ loading: true })\n try {\n const projects = await listFayzProjects()\n set({ projects, loading: false, loadedFor: tenantId ?? null })\n } catch {\n // Table not provisioned yet, or a transient read error: contribute nothing.\n set({ projects: [], loading: false, loadedFor: tenantId ?? null })\n }\n },\n refresh: async () => {\n try {\n const projects = await listFayzProjects()\n set({ projects })\n } catch {\n /* ignore */\n }\n },\n}))\n\nexport function defaultProjectOf(projects: FayzProject[]): FayzProject | null {\n return projects.find((p) => p.isDefault) ?? projects[0] ?? null\n}\n\n/** Fayz editor base — the platform surface that opens a project for editing. */\nconst EDITOR_BASE = 'https://fayz.ai/editor'\n\n/** The project's editor URL: the explicit editor_url, else derived from the\n * platform convention (fayz.ai/editor/{projectId}). Null when neither applies. */\nexport function editorUrlOf(p: Pick<FayzProject, 'editorUrl' | 'fayzProjectId'>): string | null {\n if (p.editorUrl) return p.editorUrl\n return p.fayzProjectId ? `${EDITOR_BASE}/${p.fayzProjectId}` : null\n}\n"]}
|