@fayz-ai/plugin-registry 0.16.1 → 0.17.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.
package/dist/index.d.ts CHANGED
@@ -108,6 +108,12 @@ export interface RegistryPluginOptions {
108
108
  * acabaram dentro de um aplicativo.
109
109
  */
110
110
  entities?: Partial<Record<RegistryScreenId, EntityDef>>;
111
+ /**
112
+ * Permission feature that gates a screen (route, rail line and CRUD actions).
113
+ * Most screens ship ungated, so every role sees them; an app whose roles split
114
+ * by these registries names the feature here. `null` removes a default gate.
115
+ */
116
+ features?: Partial<Record<RegistryScreenId, string | null>>;
111
117
  }
112
118
  export declare function createRegistryPlugin(options?: RegistryPluginOptions): PluginManifest;
113
119
  export { staffEntity, supplierEntity, contactEntity, partnershipEntity, equipmentEntity, originEntity, serviceCategoryEntity, serviceLocationEntity, locationGroupEntity, professionEntity, petSpeciesEntity, servicePackageEntity, serviceEntity, teamEntity, } from './lib/entities';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAuCvF,sEAAsE;AACtE,QAAA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBH,CAAA;AAEV,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAA;AAsC7D,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAAA;IAC9C;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAA;IACpD;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC,CAAA;CACxD;AAED,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,cAAc,CAmEpF;AAED,OAAO,EACL,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,EAC9E,YAAY,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,mBAAmB,EAC/E,gBAAgB,EAAE,gBAAgB,EAAE,oBAAoB,EACxD,aAAa,EAAE,UAAU,GAC1B,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAuCvF,sEAAsE;AACtE,QAAA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBH,CAAA;AAEV,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAA;AAsC7D,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAAA;IAC9C;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAA;IACpD;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC,CAAA;IACvD;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAA;CAC5D;AAED,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,cAAc,CAoEpF;AAED,OAAO,EACL,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,EAC9E,YAAY,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,mBAAmB,EAC/E,gBAAgB,EAAE,gBAAgB,EAAE,oBAAoB,EACxD,aAAa,EAAE,UAAU,GAC1B,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAA"}
package/dist/index.js CHANGED
@@ -640,7 +640,7 @@ var serviceEntity = {
640
640
  relation: { table: "categories", labelField: "name", filter: { kind: "service_category" } }
641
641
  },
642
642
  // A COR identifica o serviço na grade da agenda, onde não cabe o nome.
643
- { key: "color", label: tl("Colour", "Cor de identifica\xE7\xE3o"), type: "color", showInTable: false, group: "identity" },
643
+ { key: "color", label: tl("Colour", "Cor"), type: "color", showInTable: true, group: "identity" },
644
644
  { key: "description", label: tl("Description", "Descri\xE7\xE3o"), type: "textarea", showInTable: false, group: "identity", span: 2 },
645
645
  { key: "price", label: tl("Price", "Pre\xE7o"), type: "currency", required: true, showInTable: true, group: "pricing" },
646
646
  { key: "durationMinutes", label: tl("Duration (min)", "Dura\xE7\xE3o (min)"), type: "number", required: true, showInTable: true, group: "pricing" },
@@ -671,7 +671,19 @@ var serviceEntity = {
671
671
  table: "services",
672
672
  schema: "public",
673
673
  tenantScoped: true,
674
- searchColumns: ["name"]
674
+ searchColumns: ["name"],
675
+ // None of these is a column of `services`: the V1 import keeps them in metadata (colour in
676
+ // `catalog.color`, which the agenda paints from). Without the map every save failed on a
677
+ // missing column.
678
+ metadataFields: {
679
+ color: "catalog.color",
680
+ validityDays: "catalog.validity_days",
681
+ internalCode: "internal_code",
682
+ schedulingAlertText: "beauty.scheduling_alert_text",
683
+ reminderText: "beauty.reminder_text",
684
+ contractText: "beauty.contract_text",
685
+ postServiceText: "beauty.post_service_text"
686
+ }
675
687
  }
676
688
  };
677
689
  var professionEntity = {
@@ -1171,7 +1183,8 @@ function createRegistryPlugin(options) {
1171
1183
  const active = SCREENS.filter((screen) => OPT_IN.has(screen.id) ? options?.modules?.[screen.id] === true : options?.modules?.[screen.id] !== false);
1172
1184
  const pages = active.map((screen, index) => {
1173
1185
  const entity = options?.entities?.[screen.id] ?? screen.entity;
1174
- const feature = screen.feature;
1186
+ const override = options?.features?.[screen.id];
1187
+ const feature = override === void 0 ? screen.feature : override ?? void 0;
1175
1188
  const grouped = screen.id === "services" || screen.id === "serviceCategories" || screen.id === "servicePackages" ? { navTabs: serviceTabs, activeNavTab: screen.id } : screen.id === "locations" || screen.id === "locationGroups" ? { navTabs: locationTabs, activeNavTab: screen.id } : screen.id === "staff" || screen.id === "teams" ? { navTabs: staffTabs, activeNavTab: screen.id } : {};
1176
1189
  return {
1177
1190
  screen,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/person-fields.ts","../src/lib/entities.ts","../src/views/UnitRoomsWidget.tsx","../src/lib/package-lookup.ts","../src/index.ts"],"names":["tl","RECORD_GROUP","recordRailFields","money","Map"],"mappings":"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","file":"index.js","sourcesContent":["import { tl, RECORD_GROUP, recordRailFields, activeFacet } from '@fayz-ai/core'\nimport type { FieldDef, FieldGroup } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// O que TODA ficha de pessoa deste módulo pergunta.\n//\n// No V1 estes cadastros são LITERALMENTE a mesma tabela: Contatos é a visão\n// completa de `contacts`, e Fornecedores e Parcerias são a mesma tabela\n// pré-filtrada por `contact_type`. O V2 já modela isso certo — `people` com\n// `kind` —, e aqui a consequência é declarar os campos uma vez em vez de três.\n//\n// O que NÃO entra: o que distingue uma espécie da outra. Fornecedor tem tipo de\n// prestador e inscrição estadual; parceria tem escopo de unidades. Esses ficam\n// na entidade que os tem, que é onde alguém vai procurar por eles.\n// ---------------------------------------------------------------------------\n\nexport const PERSON_GROUPS: FieldGroup[] = [\n // Nome e documento NÃO entram: o arquétipo `person` os hasteia para o\n // cabeçalho da ficha, ao lado da foto. O que sobra é o resto da pessoa.\n { id: 'identity', label: tl('Personal', 'Dados pessoais'), columns: 2 },\n { id: 'contact', label: tl('Contact', 'Contato'), columns: 2 },\n { id: 'where', label: tl('Address', 'Endereço'), columns: 1 },\n {\n id: 'banking', label: tl('Banking', 'Dados bancários'), columns: 1,\n description: tl(\n 'Where money goes OUT to this person — not an account of the house.',\n 'Para onde o dinheiro SAI para esta pessoa — não é conta da casa.',\n ),\n },\n { ...RECORD_GROUP, label: tl('Record', 'Situação') },\n]\n\n/** A lista abre em «Ativos», como toda lista de cadastro do V1. */\nexport const ACTIVE_FACET = activeFacet({\n active: tl('Active', 'Ativos'),\n inactive: tl('Inactive', 'Inativos'),\n all: tl('All', 'Todos'),\n})\n\n/**\n * Os canais de contato.\n *\n * Telefone e CELULAR são dois campos, e é o celular que leva o WhatsApp — a\n * régua de comunicação procura este, não o fixo.\n *\n * O V1 tem um SEGUNDO de cada (telefone 2, celular 2, e-mail 2), e eles estão\n * desligados: seis caixas de contato num cadastro cuja resposta costuma ser um\n * número e um e-mail são cinco perguntas a mais para a recepção rolar. As\n * chaves continuam declaradas em `customFields` de propósito — quem já tem o\n * segundo telefone gravado não o perde, e religar é descomentar três linhas.\n */\nexport function contactChannelFields(): FieldDef[] {\n return [\n { key: 'phone', label: tl('Phone', 'Telefone'), type: 'phone', showInTable: true, searchable: true, group: 'contact' },\n { key: 'mobile', label: tl('Mobile', 'Celular'), type: 'phone', showInTable: true, group: 'contact' },\n { key: 'email', label: 'E-mail', type: 'email', showInTable: true, searchable: true, group: 'contact', span: 2 },\n // Desligados — ver acima.\n // { key: 'phone2', label: tl('Phone 2', 'Telefone 2'), type: 'phone', showInTable: false, group: 'contact' },\n // { key: 'mobile2', label: tl('Mobile 2', 'Celular 2'), type: 'phone', showInTable: false, group: 'contact' },\n // { key: 'email2', label: tl('E-mail 2', 'E-mail 2'), type: 'email', showInTable: false, group: 'contact' },\n ]\n}\n\n/**\n * Endereço e conta, os dois campos que são UMA LINHA DE OUTRA TABELA\n * (`public.addresses` e `public.payee_accounts`).\n *\n * `showInDetail: false` nos dois: a ficha tem as seções completas logo abaixo,\n * que listam TODAS as linhas, editam e excluem. O campo existe para o momento\n * em que a seção não pode existir — a criação, quando ainda não há id.\n */\nexport function attachedFields(): FieldDef[] {\n return [\n { key: 'address', label: tl('Address', 'Endereço'), type: 'address', showInTable: false, showInDetail: false, group: 'where' },\n { key: 'payeeAccount', label: tl('Bank account', 'Conta bancária'), type: 'bank', showInTable: false, showInDetail: false, group: 'banking' },\n ]\n}\n\n/**\n * O rail direito, IGUAL em todo cadastro.\n *\n * A ordem é fixa de propósito: quem procura o interruptor «Ativo» não pode\n * ter de caçá-lo numa altura diferente a cada tela. Unidade e o interruptor\n * dividem a primeira linha — a unidade responde «de quem é» e o interruptor\n * «vale ou não», que é o par que se lê junto —, e embaixo vêm as duas coisas\n * que se ESCREVE sobre o registro: o texto solto e as etiquetas.\n *\n * As etiquetas são o recorte que a casa inventa e o produto não prevê\n * («cliente VIP», «fornecedor homologado»). Sem elas isso vai para\n * Observações, onde não filtra e não conta.\n */\nexport function recordFields(table = 'people', options: { unit?: boolean } = {}): FieldDef[] {\n return recordRailFields({\n tagsTable: table,\n activeLabel: tl('Active', 'Ativo'),\n // Um cadastro que já pergunta o ESCOPO de unidades não pergunta também a\n // unidade padrão: são duas perguntas parecidas e respostas diferentes, e\n // na tela viravam dois seletores de unidade — um multi à esquerda e um\n // único à direita — sem nada dizendo qual manda.\n unit: options.unit,\n })\n}\n\n/** O sexo, que no V1 é pergunta de contato e de cliente. */\nexport function genderField(): FieldDef {\n return {\n key: 'gender', label: tl('Gender', 'Sexo'), type: 'select', showInTable: false, group: 'identity',\n options: [\n { value: 'masculino', label: tl('Male', 'Masculino') },\n { value: 'feminino', label: tl('Female', 'Feminino') },\n { value: 'outro', label: tl('Other', 'Outro') },\n ],\n }\n}\n\n/**\n * As chaves que não são coluna de `people` e moram em `custom_fields`.\n *\n * `phone2`, `mobile2` e `email2` continuam aqui mesmo com os campos\n * desligados: é isto que faz o segundo telefone JÁ GRAVADO continuar sendo\n * lido, em vez de virar lixo no jsonb no dia em que o campo voltar.\n */\nexport const PERSON_CUSTOM_FIELDS = ['gender', 'mobile', 'phone2', 'mobile2', 'email2']\n","import { tl, RECORD_GROUP, recordRailFields } from '@fayz-ai/core'\nimport {\n PERSON_GROUPS, ACTIVE_FACET, PERSON_CUSTOM_FIELDS,\n contactChannelFields, attachedFields, recordFields, genderField,\n} from './person-fields'\nimport type { EntityDef } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// entities — as fichas de referência, iguais em qualquer ofício.\n// ---------------------------------------------------------------------------\n// Estas dez definições estavam escritas à mão dentro de UM aplicativo\n// (beauty-saas/src/types/registry.ts), e por isso os Cadastros existiam só lá:\n// o aplicativo central abria a mesma conta, com os mesmos dados, e o menu não\n// tinha a rubrica — não porque ela estivesse escondida, mas porque as telas\n// não existiam para serem agrupadas.\n//\n// Nada aqui é de salão. São as tabelas da espinha vistas por dez recortes:\n// `people` por papel (equipe, fornecedor, contato, parceiro), `products` como\n// patrimônio, `categories` por tipo (origem, categoria de serviço, grupo de\n// locais), `services`, e `v_units` — a filial. Um restaurante tem fornecedor e\n// equipamento; uma escola tem contato e origem. O que muda por ofício é o\n// NOME de cada linha no menu, e isso o preset do banco já resolve.\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Staff — person archetype + extension table\n// ---------------------------------------------------------------------------\nexport const staffEntity: EntityDef = {\n name: tl('Staff', 'Profissional'),\n namePlural: tl('Staff', 'Profissionais'),\n icon: 'UserCog',\n // staff_members is an extension table (no name column) — useless to the\n // agent's generic reader. The agent sees professionals through the\n // beauty:professionals read-model (people kind='staff') instead.\n agentHidden: true,\n layout: 'person',\n // The agenda already showed `avatar_url`; the record itself fell back to an initial.\n imageField: 'avatarUrl',\n displayField: 'name',\n subtitleField: 'profession',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n ...PERSON_GROUPS.filter((g) => g.id !== 'record'),\n {\n id: 'work', label: tl('Work', 'Trabalho'), columns: 2,\n description: tl(\n 'What this person does here, and how the calendar and the payroll see them.',\n 'O que esta pessoa faz aqui, e como a agenda e a folha a enxergam.',\n ),\n },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Full name', 'Nome completo'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity', span: 2 },\n { key: 'documentNumber', label: 'CPF', type: 'text', showInTable: true, searchable: true, group: 'identity' },\n // RG: o V1 pede os dois documentos na ficha de quem trabalha aqui, e a\n // folha usa ambos.\n { key: 'rg', label: 'RG', type: 'text', showInTable: false, group: 'identity' },\n { key: 'dateOfBirth', label: tl('Date of birth', 'Data de nascimento'), type: 'date', showInTable: false, group: 'identity' },\n genderField(),\n ...contactChannelFields(),\n ...attachedFields(),\n\n { key: 'profession', label: tl('Profession', 'Profissão'), type: 'text', showInTable: true, group: 'work' },\n // O VÍNCULO muda o que a folha e o fisco esperam — um autônomo emite RPA,\n // um CLT entra na folha, um PJ manda nota.\n {\n key: 'employmentType', label: tl('Employment type', 'Tipo de vínculo'), type: 'select', showInTable: false, group: 'work',\n options: [\n { value: 'clt', label: 'CLT' },\n { value: 'pj', label: 'Pessoa jurídica' },\n { value: 'autonomo', label: 'Autônomo' },\n { value: 'estagio', label: 'Estágio' },\n { value: 'socio', label: 'Sócio' },\n ],\n },\n // CBO é o código que a folha e o eSocial pedem. Texto porque a tabela\n // oficial tem ~2.500 entradas e um seletor delas seria pior que o campo.\n { key: 'cboCode', label: tl('CBO code', 'CBO'), type: 'text', showInTable: false, group: 'work',\n hint: tl('Brazilian occupation code, used by payroll.', 'Classificação Brasileira de Ocupações — a folha pede.') },\n {\n key: 'teamId', label: tl('Team', 'Equipe'), type: 'relation',\n showInTable: true, group: 'work',\n relation: { table: 'categories', filter: { kind: 'staff_team', is_active: true } },\n hint: tl('Where this person works — reception, aesthetics, sales.', 'Onde esta pessoa trabalha — recepção, estética, vendas.'),\n },\n { key: 'commissionRate', label: tl('Commission (%)', 'Comissão (%)'), type: 'number', showInTable: true, group: 'work', defaultValue: 0 },\n // O CENTRO DE CUSTO da pessoa é o que permite alocar o custo dela por\n // área — é assim que a folha vira despesa de Operação e não um bolo só.\n {\n key: 'costCenterId', label: tl('Cost centre', 'Centro de custo'), type: 'relation', showInTable: false, group: 'work',\n relation: { table: 'plg_financial_cost_centers', labelField: 'name' },\n },\n // Trabalhar aqui não é atender cliente: a recepção e o financeiro entram\n // por esta mesma tela. Sem a escolha no cadastro, todo mundo nascia com\n // coluna na grade da semana e horário livre para marcarem em cima.\n {\n key: 'isBookable', label: tl('Appears in the calendar', 'Aparece na agenda'), type: 'boolean',\n showInTable: true, defaultValue: true, group: 'work',\n hint: tl(\n 'Clients can be booked with this person.',\n 'Clientes podem ser marcados com esta pessoa.',\n ),\n },\n // O que a recepção precisa saber ANTES de marcar com esta pessoa.\n { key: 'agendaNotes', label: tl('Calendar notes', 'Informações para a agenda'), type: 'textarea', showInTable: false, group: 'work', span: 2 },\n\n ...recordFields(),\n ],\n // No custom documents tab: the `person` archetype supplies the shared\n // custom_forms documents widget (same as clients / school-saas).\n data: {\n // Pessoa pura, como no resto-saas: quem é da equipe é `people.kind='staff'`.\n table: 'people',\n tenantScoped: true,\n archetype: 'person',\n archetypeKind: 'staff',\n // `profession` e `commissionRate` eram colunas da extensão. A comissão de\n // verdade é a do motor de regras do Financeiro (plg_financial_commission_*),\n // que sabe dividir por serviço e por profissional; este número aqui é o\n // resquício de quando havia um só. Fica em custom_fields para não sumir.\n customFields: [\n ...PERSON_CUSTOM_FIELDS,\n 'profession', 'commissionRate', 'teamId', 'employmentType', 'cboCode', 'agendaNotes',\n 'rg', 'costCenterId',\n ],\n searchColumns: ['name', 'email', 'phone', 'document_number'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Suppliers — person archetype, direct query\n// ---------------------------------------------------------------------------\nexport const supplierEntity: EntityDef = {\n name: tl('Supplier', 'Fornecedor'),\n namePlural: tl('Suppliers', 'Fornecedores'),\n icon: 'Building2',\n layout: 'person',\n // The agenda already showed `avatar_url`; the record itself fell back to an initial.\n imageField: 'avatarUrl',\n displayField: 'name',\n subtitleField: 'documentNumber',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: PERSON_GROUPS,\n fields: [\n { key: 'name', label: tl('Legal name / Name', 'Razão social / Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity', span: 2 },\n // O tipo de prestador MUDA o documento: um autônomo assina com CPF, uma\n // empresa com CNPJ, e a inscrição estadual só existe para quem é inscrito.\n {\n key: 'serviceProviderType', label: tl('Service provider type', 'Tipo de prestador de serviço'), type: 'segmented',\n required: true, defaultValue: 'pj', group: 'identity', span: 2,\n options: [\n { value: 'pj', label: tl('Company', 'Pessoa jurídica') },\n { value: 'pf', label: tl('Individual', 'Pessoa física') },\n { value: 'autonomo', label: tl('Self-employed', 'Autônomo') },\n ],\n },\n {\n key: 'documentNumber', type: 'text', searchable: true, showInTable: true, group: 'identity',\n label: 'CNPJ / CPF',\n // Rotular sempre «CNPJ / CPF» faz o operador parar para escolher qual é.\n // Ele já escolheu na linha de cima.\n labelWhen: (v) => (v.serviceProviderType === 'pj' ? 'CNPJ' : 'CPF'),\n },\n {\n key: 'registrationNumber', label: tl('State / municipal registration', 'Inscrição estadual / municipal'), type: 'text', group: 'identity',\n // Pessoa física não tem inscrição estadual. Perguntar é convidar a\n // preencher o que ninguém vai ler.\n visibleWhen: (v) => v.serviceProviderType !== 'pf',\n },\n // O GRUPO do V1 («Grupo 1», «Grupo 2»): como a casa separa os fornecedores\n // dela. Texto livre porque no V1 é isso mesmo — uma taxonomia por conta\n // viraria um cadastro que ninguém pediu.\n { key: 'groupName', label: tl('Group', 'Grupo'), type: 'text', showInTable: false, group: 'identity' },\n ...contactChannelFields(),\n ...attachedFields(),\n ...recordFields(),\n ],\n data: {\n table: 'people',\n tenantScoped: true,\n archetype: 'person',\n archetypeKind: 'supplier',\n filters: { kind: 'supplier' },\n defaults: { kind: 'supplier' },\n customFields: [...PERSON_CUSTOM_FIELDS, 'serviceProviderType', 'registrationNumber', 'groupName'],\n searchColumns: ['name', 'email', 'phone', 'document_number'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Contacts — person archetype, direct query\n// ---------------------------------------------------------------------------\nexport const contactEntity: EntityDef = {\n name: tl('Contact', 'Contato'),\n namePlural: tl('Contacts', 'Contatos'),\n icon: 'Contact',\n layout: 'person',\n // The agenda already showed `avatar_url`; the record itself fell back to an initial.\n imageField: 'avatarUrl',\n displayField: 'name',\n subtitleField: 'documentNumber',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: PERSON_GROUPS,\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity', span: 2 },\n { key: 'documentNumber', label: 'CPF / CNPJ', type: 'text', showInTable: true, searchable: true, group: 'identity' },\n genderField(),\n ...contactChannelFields(),\n ...attachedFields(),\n ...recordFields(),\n ],\n data: {\n table: 'people',\n // Sem `schema`, de propósito: com ele a entidade resolvia para o provider\n // genérico de tabela, que não sabe ler nem gravar `custom_fields` — e\n // metade desta ficha mora lá. `public` já é o padrão.\n tenantScoped: true,\n archetype: 'person',\n archetypeKind: 'contact',\n filters: { kind: 'contact' },\n defaults: { kind: 'contact' },\n customFields: PERSON_CUSTOM_FIELDS,\n searchColumns: ['name', 'email', 'phone', 'document_number'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Partnerships — person archetype, direct query\n// ---------------------------------------------------------------------------\nexport const partnershipEntity: EntityDef = {\n name: tl('Partnership', 'Parceria'),\n namePlural: tl('Partnerships', 'Parcerias'),\n icon: 'Handshake',\n layout: 'person',\n // The agenda already showed `avatar_url`; the record itself fell back to an initial.\n imageField: 'avatarUrl',\n displayField: 'name',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: PERSON_GROUPS,\n fields: [\n { key: 'name', label: tl('Partnership name', 'Nome da parceria'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity', span: 2 },\n { key: 'documentNumber', label: 'CNPJ / CPF', type: 'text', showInTable: true, searchable: true, group: 'identity' },\n // O ESCOPO de unidades, que no V1 é o par «Limitar unidades? → quais».\n // Escolher «Todas» e ainda ver a lista de unidades é oferecer uma resposta\n // que não vale; por isso a lista só aparece depois da escolha.\n {\n key: 'unitScope', label: tl('Units', 'Unidades'), type: 'segmented',\n defaultValue: 'all', group: 'identity', span: 2,\n options: [\n { value: 'all', label: tl('All units', 'Todas as unidades') },\n { value: 'selected', label: tl('Pick units', 'Selecionar unidades') },\n ],\n },\n {\n key: 'units', label: tl('Selected units', 'Unidades selecionadas'), type: 'relation',\n showInTable: false, group: 'identity', span: 2,\n relation: { table: 'v_units', labelField: 'name' },\n visibleWhen: (v) => v.unitScope === 'selected',\n },\n ...contactChannelFields(),\n ...attachedFields(),\n ...recordFields('people', { unit: false }),\n ],\n data: {\n table: 'people',\n tenantScoped: true,\n archetype: 'person',\n archetypeKind: 'partner',\n filters: { kind: 'partner' },\n defaults: { kind: 'partner' },\n customFields: [...PERSON_CUSTOM_FIELDS, 'unitScope', 'units'],\n searchColumns: ['name', 'email', 'phone', 'document_number'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Equipment — product archetype, direct query\n// ---------------------------------------------------------------------------\nexport const equipmentEntity: EntityDef = {\n name: tl('Equipment', 'Equipamento'),\n namePlural: tl('Equipment', 'Equipamentos'),\n icon: 'Wrench',\n layout: 'product',\n displayField: 'name',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n { id: 'identity', label: tl('Identification', 'Identificação'), columns: 2 },\n { id: 'purchase', label: tl('Purchase', 'Compra e garantia'), columns: 2 },\n {\n id: 'maintenance', label: tl('Maintenance', 'Manutenção'), columns: 2,\n description: tl(\n 'The next date is what a list of equipment is FOR.',\n 'A próxima data é para o que uma lista de equipamentos serve.',\n ),\n },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity', span: 2 },\n { key: 'brand', label: tl('Brand', 'Marca'), type: 'text', showInTable: true, group: 'identity' },\n { key: 'model', label: tl('Model', 'Modelo'), type: 'text', showInTable: true, group: 'identity' },\n // O NÚMERO DE SÉRIE é o que a assistência técnica pede e o que distingue\n // dois aparelhos iguais na mesma sala.\n { key: 'sku', label: tl('Serial number', 'Número de série'), type: 'text', showInTable: false, searchable: true, group: 'identity' },\n {\n key: 'status', label: 'Status', type: 'select', showInTable: true, defaultValue: 'active', group: 'identity',\n options: [\n { value: 'active', label: tl('Active', 'Ativo') },\n { value: 'maintenance', label: tl('In maintenance', 'Em manutenção') },\n { value: 'inactive', label: tl('Retired', 'Inativo') },\n ],\n },\n // A SALA onde ele está. Aponta para o cadastro de Locais.\n { key: 'serviceLocationId', label: tl('Location', 'Local'), type: 'relation', showInTable: true, group: 'identity',\n relation: { table: 'v_units', labelField: 'name' } },\n { key: 'purchaseDate', label: tl('Purchase date', 'Data de compra'), type: 'date', showInTable: false, group: 'purchase' },\n { key: 'purchaseValue', label: tl('Purchase value', 'Valor de compra'), type: 'currency', showInTable: false, group: 'purchase' },\n { key: 'warrantyExpiration', label: tl('Warranty ends', 'Vencimento da garantia'), type: 'date', showInTable: false, group: 'purchase' },\n { key: 'lastMaintenanceDate', label: tl('Last maintenance', 'Última manutenção'), type: 'date', showInTable: false, group: 'maintenance' },\n // A COLUNA que justifica a lista: quem abre «Equipamentos» está quase\n // sempre perguntando o que vence agora.\n { key: 'nextMaintenanceDate', label: tl('Next maintenance', 'Próxima manutenção'), type: 'date', showInTable: true, group: 'maintenance' },\n { key: 'maintenanceNotes', label: tl('Maintenance notes', 'Notas de manutenção'), type: 'textarea', showInTable: false, group: 'maintenance', span: 2 },\n { key: 'description', label: tl('Description', 'Descrição'), type: 'textarea', showInTable: false, group: 'identity', span: 2 },\n ...recordRailFields({ tagsTable: 'products', activeLabel: tl('Active', 'Ativo') }),\n ],\n data: {\n table: 'products',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'asset' },\n defaults: { kind: 'asset' },\n searchColumns: ['name', 'sku'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Origins — category archetype, direct query\n// ---------------------------------------------------------------------------\nexport const originEntity: EntityDef = {\n name: tl('Origin', 'Origem'),\n namePlural: tl('Origins', 'Origens'),\n icon: 'Globe',\n displayField: 'name',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n { id: 'identity', label: tl('Identification', 'Identificação'), columns: 1 },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity' },\n // «SOLICITAR PESSOA» é uma regra que vale do OUTRO lado: ligada, escolher\n // esta origem no cadastro de cliente passa a exigir quem indicou. Sem ela,\n // «indicação de amigo» vira uma estatística sem nome nenhum atrás.\n {\n key: 'requiresPerson', label: tl('Ask who referred', 'Solicitar pessoa'), type: 'boolean',\n showInTable: true, defaultValue: false, group: 'identity',\n hint: tl(\n 'Choosing this origin on a client will require naming who referred them.',\n 'Escolher esta origem num cliente passa a exigir dizer quem indicou.',\n ),\n },\n // A DESCRIÇÃO da origem é a observação: `categories` não tem coluna\n // separada, e duas colunas para uma frase é invenção. Ela vai para a\n // lista porque é o que distingue «Indicação» de «Indicação de parceiro».\n ...recordRailFields({ tagsTable: 'categories', activeLabel: tl('Active', 'Ativo'), unit: false, notesInTable: true }),\n ],\n data: {\n table: 'categories',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'origin' },\n defaults: { kind: 'origin' },\n customFields: ['requiresPerson'],\n searchColumns: ['name'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Teams — category archetype, direct query\n// ---------------------------------------------------------------------------\n// O agrupamento da EQUIPE, irmão da categoria de serviço: mesma tabela, mesma\n// forma, outra espécie (`staff_team`, declarada pela 139 do espinha). Quem é\n// de qual equipe é escolha da ficha — ver `teamId` em `staffEntity`.\n//\n// Não confundir com `v_team_members`, que apesar do nome são os MEMBROS DO\n// TENANT (quem entra no sistema). Aqui é a ficha: a casa tem recepção e\n// estética antes de ter dois logins.\nexport const teamEntity: EntityDef = {\n name: tl('Team', 'Equipe'),\n namePlural: tl('Teams', 'Equipes'),\n icon: 'Users',\n displayField: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [{ ...RECORD_GROUP }],\n defaultSort: 'sortOrder',\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n // A cor é o que faz a equipe se reconhecer de relance na grade da semana e\n // no quadro — é o mesmo papel que ela tem na etiqueta.\n { key: 'color', label: tl('Colour', 'Cor'), type: 'color', showInTable: true },\n { key: 'sortOrder', label: tl('Order', 'Ordem'), type: 'number', showInTable: true, defaultValue: 0 },\n ...recordRailFields({ tagsTable: 'categories', activeLabel: tl('Active', 'Ativo'), unit: false }),\n ],\n data: {\n table: 'categories',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'staff_team' },\n defaults: { kind: 'staff_team' },\n searchColumns: ['name'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Service Categories — category archetype, direct query\n// ---------------------------------------------------------------------------\nexport const serviceCategoryEntity: EntityDef = {\n name: tl('Service Category', 'Categoria de Serviço'),\n namePlural: tl('Service Categories', 'Categorias de Serviço'),\n icon: 'Tag',\n displayField: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [{ ...RECORD_GROUP }],\n defaultSort: 'sortOrder',\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'sortOrder', label: tl('Order', 'Ordem'), type: 'number', showInTable: true, defaultValue: 0 },\n ...recordRailFields({ tagsTable: 'categories', activeLabel: tl('Active', 'Ativo'), unit: false }),\n ],\n data: {\n table: 'categories',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'service_category' },\n defaults: { kind: 'service_category' },\n },\n}\n\n// ---------------------------------------------------------------------------\n// Service Locations — location archetype, direct query\n// ---------------------------------------------------------------------------\n// ---------------------------------------------------------------------------\n// Locais — a SALA, cadeira ou box onde se atende, DENTRO de uma unidade.\n//\n// Isto é o «Local Operacional» do V1, e é o que esta tela sempre deveria ter\n// sido. Ela apontava para `v_units` — a FILIAL —, que já tem a própria tela em\n// Configurações → Unidades: duas telas para o prédio, nenhuma para a sala.\n//\n// A diferença importa porque uma sala não é uma unidade em miniatura: ela não\n// tem caixa, não tem estoque e não recorta permissão. O que ela tem é LOTAÇÃO,\n// e é por isso que ela existe — ver a migration 153.\n// ---------------------------------------------------------------------------\nexport const serviceLocationEntity: EntityDef = {\n name: tl('Location', 'Local'),\n namePlural: tl('Locations', 'Locais'),\n icon: 'MapPin',\n displayField: 'name',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n {\n id: 'identity', label: tl('The location', 'O local'), columns: 2,\n description: tl(\n 'Where you attend, inside a unit. Not a unit: no till, no stock, no permission of its own.',\n 'Onde se atende, dentro de uma unidade. Não é unidade: não tem caixa, não tem estoque e não recorta permissão.',\n ),\n },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity' },\n { key: 'code', label: tl('Code', 'Código'), type: 'text', showInTable: true, searchable: true, group: 'identity' },\n {\n key: 'groupId', label: tl('Group', 'Grupo'), type: 'relation', showInTable: true, group: 'identity',\n relation: { table: 'categories', labelField: 'name', filter: { kind: 'location_group' } },\n },\n // A LOTAÇÃO é o que impede a agenda de marcar cinco pessoas às 14h onde\n // cabem quatro. Sem ela o local é só um rótulo.\n {\n key: 'capacity', label: tl('Capacity', 'Máximo de clientes simultâneos'), type: 'number',\n min: 1, defaultValue: 1, showInTable: true, group: 'identity',\n hint: tl('One chair is 1. A tanning room with four beds is 4.', 'Uma cadeira é 1. Uma sala de bronzeamento com quatro macas é 4.'),\n },\n // A unidade vem do RAIL, com todos os outros «de quem é este registro» —\n // e obrigatória, porque um local sem prédio não existe.\n ...recordRailFields({ tagsTable: 'rooms', activeLabel: tl('Active', 'Ativo'), unitRequired: true }),\n ],\n data: {\n table: 'rooms',\n schema: 'public',\n tenantScoped: true,\n searchColumns: ['name', 'code'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Location Groups — category archetype, direct query\n// ---------------------------------------------------------------------------\nexport const locationGroupEntity: EntityDef = {\n name: tl('Location Group', 'Grupo de Locais'),\n namePlural: tl('Location Groups', 'Grupos de Locais'),\n icon: 'Map',\n displayField: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [{ ...RECORD_GROUP }],\n defaultSort: 'sortOrder',\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'sortOrder', label: tl('Order', 'Ordem'), type: 'number', showInTable: true, defaultValue: 0 },\n ...recordRailFields({ tagsTable: 'categories', activeLabel: tl('Active', 'Ativo'), unit: false }),\n ],\n data: {\n table: 'categories',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'location_group' },\n defaults: { kind: 'location_group' },\n searchColumns: ['name'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Services — service archetype, direct query on public.services\n// ---------------------------------------------------------------------------\nexport const serviceEntity: EntityDef = {\n name: tl('Service', 'Serviço'),\n namePlural: tl('Services', 'Serviços'),\n icon: 'Briefcase',\n layout: 'service',\n displayField: 'name',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n { id: 'identity', label: tl('Identification', 'Identificação'), columns: 2 },\n { id: 'pricing', label: tl('Price and time', 'Preço e tempo'), columns: 2 },\n {\n id: 'texts', label: tl('What the client reads', 'O que o cliente lê'), columns: 1,\n description: tl(\n 'Written once here, sent every time the service is booked or finished.',\n 'Escrito uma vez aqui, enviado toda vez que o serviço é marcado ou concluído.',\n ),\n },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Service name', 'Nome do serviço'), type: 'text', required: true, searchable: true, showInTable: true, group: 'identity', span: 2 },\n // O CÓDIGO INTERNO é como a casa chama o serviço na comanda e no relatório\n // — e é por ele que se procura quando o nome tem três variações.\n { key: 'internalCode', label: tl('Internal code', 'Código interno'), type: 'text', showInTable: true, searchable: true, group: 'identity' },\n { key: 'categoryId', label: tl('Category', 'Categoria'), type: 'relation', showInTable: true, group: 'identity',\n relation: { table: 'categories', labelField: 'name', filter: { kind: 'service_category' } } },\n // A COR identifica o serviço na grade da agenda, onde não cabe o nome.\n { key: 'color', label: tl('Colour', 'Cor de identificação'), type: 'color', showInTable: false, group: 'identity' },\n { key: 'description', label: tl('Description', 'Descrição'), type: 'textarea', showInTable: false, group: 'identity', span: 2 },\n\n { key: 'price', label: tl('Price', 'Preço'), type: 'currency', required: true, showInTable: true, group: 'pricing' },\n { key: 'durationMinutes', label: tl('Duration (min)', 'Duração (min)'), type: 'number', required: true, showInTable: true, group: 'pricing' },\n // VALIDADE em dias: quanto tempo o cliente tem para executar o que\n // comprou. É o que faz um pacote expirar, e sem ela ele nunca expira.\n { key: 'validityDays', label: tl('Validity (days)', 'Validade (dias)'), type: 'number', showInTable: false, group: 'pricing' },\n {\n key: 'isBookable', label: tl('Appears in the calendar', 'Aparece na agenda'), type: 'boolean',\n showInTable: true, defaultValue: true, group: 'pricing',\n hint: tl(\n 'Can be picked when booking an appointment. Turn off for what is sold in a package and never booked on its own.',\n 'Pode ser escolhido ao marcar um horário. Desligue para o que é vendido em pacote e nunca se marca sozinho.',\n ),\n },\n\n { key: 'schedulingAlertText', label: tl('Booking alert', 'Alertas para agendamento'), type: 'textarea', showInTable: false, group: 'texts' },\n { key: 'reminderText', label: tl('Reminder text', 'Texto do lembrete'), type: 'textarea', showInTable: false, group: 'texts' },\n { key: 'contractText', label: tl('Contract text', 'Texto para contrato'), type: 'textarea', showInTable: false, group: 'texts' },\n { key: 'postServiceText', label: tl('After-service text', 'Texto de pós-atendimento'), type: 'textarea', showInTable: false, group: 'texts' },\n\n ...recordRailFields({ tagsTable: 'services', activeLabel: tl('Active', 'Ativo') }),\n ],\n // Services are their own Ring-0 archetype table (public.services), not a\n // kind of product. Direct query by table+schema (no kind filter).\n data: {\n table: 'services',\n schema: 'public',\n tenantScoped: true,\n searchColumns: ['name'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Profissões — categoria, o `professions` do V1\n// ---------------------------------------------------------------------------\nexport const professionEntity: EntityDef = {\n name: tl('Profession', 'Profissão'),\n namePlural: tl('Professions', 'Profissões'),\n icon: 'BriefcaseBusiness',\n displayField: 'name',\n defaultSort: 'sortOrder',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n {\n id: 'identity', label: tl('Identification', 'Identificação'), columns: 2,\n description: tl(\n 'The list the house keeps, so a rota does not depend on how someone typed it.',\n 'A lista que a casa mantém, para a escala não depender de como alguém digitou.',\n ),\n },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity', span: 2 },\n { key: 'sortOrder', label: tl('Order', 'Ordem'), type: 'number', showInTable: true, defaultValue: 0, group: 'identity' },\n ...recordRailFields({ tagsTable: 'categories', activeLabel: tl('Active', 'Ativo'), unit: false, notesInTable: true }),\n ],\n data: {\n table: 'categories',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'profession' },\n defaults: { kind: 'profession' },\n searchColumns: ['name'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Espécies de pet — categoria, o `pet_species` do V1\n// ---------------------------------------------------------------------------\nexport const petSpeciesEntity: EntityDef = {\n name: tl('Species', 'Espécie'),\n namePlural: tl('Animal species', 'Tipos de animais'),\n icon: 'PawPrint',\n displayField: 'name',\n defaultSort: 'sortOrder',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n { id: 'identity', label: tl('Identification', 'Identificação'), columns: 2 },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity', span: 2 },\n // A ORDEM existe porque a espécie mais atendida tem de estar em cima: um\n // hotel para aves não quer «cachorro» na primeira posição.\n { key: 'sortOrder', label: tl('Order', 'Ordem'), type: 'number', showInTable: true, defaultValue: 0, group: 'identity' },\n ...recordRailFields({ tagsTable: 'categories', activeLabel: tl('Active', 'Ativo'), unit: false }),\n ],\n data: {\n table: 'categories',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'pet_species' },\n defaults: { kind: 'pet_species' },\n searchColumns: ['name'],\n },\n}\n\n\n// ---------------------------------------------------------------------------\n// Pacotes de serviço — o conjunto vendido junto\n// ---------------------------------------------------------------------------\n//\n// As tabelas (`service_packages`, `service_package_items`) vieram inteiras do\n// porte do V1 e nunca tiveram tela: o pacote existia no banco de toda conta\n// migrada e não havia por onde abri-lo. Isto é a porta.\n//\n// O ITEM é uma lista relacionada, não uma aba inventada: `package_id` já diz\n// a relação, e `RelatedList` monta dela a mesma tela de CRUD que o item teria\n// sozinho, filtrada pelo pacote de onde foi aberta.\n// ---------------------------------------------------------------------------\n\nconst servicePackageItemEntity: EntityDef = {\n name: tl('Item', 'Item'),\n namePlural: tl('Items', 'Serviços do pacote'),\n icon: 'ListChecks',\n displayField: 'productId',\n defaultSort: 'sortOrder',\n fields: [\n // O TIPO vem ANTES do item, como no V1: ele é quem decide de qual catálogo o\n // campo seguinte lê. Um pacote de estética vende sessão e vende o creme que\n // vai junto, e os dois moram em `products` com `kind` diferente.\n {\n key: 'itemType', label: tl('Type', 'Tipo'), type: 'select', required: true, defaultValue: 'service', showInTable: true,\n options: [\n { value: 'service', label: tl('Service', 'Serviço') },\n { value: 'product', label: tl('Product', 'Produto') },\n ],\n },\n {\n // `products` e não o espelho `public.services`: a 191 aposentou o espelho\n // e a FK da linha já aponta para `products`. Ler do espelho funcionava por\n // coincidência — mesmos ids — e devolveria zero no pool em que ele não foi\n // criado.\n //\n // O recorte vem do «Tipo» ao lado (`filterFrom`), e `product` da tela é\n // `good` na coluna — o vocabulário do V1 de um lado, o do catálogo do\n // outro. `priceField` põe o preço à direita de cada opção: escolher entre\n // dois serviços num pacote é escolher também entre dois preços.\n key: 'productId', label: tl('Package item', 'Item do pacote'), type: 'relation', required: true, showInTable: true,\n relation: {\n table: 'products',\n labelField: 'name',\n priceField: 'price',\n filterFrom: { kind: { field: 'itemType', map: { service: 'service', product: 'good' } } },\n },\n },\n // QUANTAS VEZES este serviço entra no pacote. «10 sessões de drenagem» é\n // uma linha com quantidade 10, não dez linhas.\n { key: 'quantity', label: tl('Quantity', 'Quantidade'), type: 'number', min: 1, defaultValue: 1, showInTable: true },\n // ── OS DOIS PREÇOS, que é o que faz um pacote ser um pacote ────────────\n //\n // O de TABELA é a base da comissão do profissional e o lado esquerdo da\n // economia; o DO PACOTE é o que o cliente paga por esta linha, e a soma\n // deles é o preço do pacote (a 166 mantém isso no banco).\n //\n // Separados porque o desconto não cai igual em todo serviço: a casa decide\n // qual linha o absorve, e com um preço só esse desconto vira regra de três.\n // Os dois nascem com o preço de tabela do que foi escolhido ao lado (o\n // trigger da 166 faz o mesmo no banco, para quem insere por outra porta):\n // começar em zero obriga a redigitar o que o catálogo já sabe, e uma linha\n // esquecida em zero não cobra nada e não paga comissão nenhuma.\n {\n key: 'unitPrice', label: tl('List price', 'Valor unit.'), type: 'currency', defaultValue: 0, showInTable: true,\n fillFrom: { field: 'productId', source: 'price' },\n hint: tl('Base for the commission. Zero pays none.', 'Base da comissão. Zero não paga comissão.'),\n },\n {\n key: 'packagePrice', label: tl('In-package price', 'Valor no pacote'), type: 'currency', defaultValue: 0, showInTable: true,\n fillFrom: { field: 'productId', source: 'price' },\n hint: tl('What the client pays for this line.', 'O que o cliente paga por esta linha.'),\n },\n // Só a casa que emite nota por CONSUMO precisa separá-lo; vazio usa o do\n // pacote.\n { key: 'fiscalUnitPrice', label: tl('Fiscal unit price', 'Valor unit. fiscal'), type: 'currency', showInTable: true },\n { key: 'sortOrder', label: tl('Order', 'Ordem'), type: 'number', defaultValue: 0, showInTable: false },\n ],\n data: { table: 'service_package_items', schema: 'public', tenantScoped: true },\n}\n\nexport const servicePackageEntity: EntityDef = {\n name: tl('Package', 'Pacote'),\n namePlural: tl('Packages', 'Pacotes'),\n icon: 'PackageCheck',\n duplicable: true,\n displayField: 'name',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n { id: 'identity', label: tl('Identification', 'Identificação'), columns: 1 },\n {\n id: 'pricing', label: tl('Price and validity', 'Preço e validade'), columns: 2,\n description: tl(\n 'What the client pays once, and until when they can use it.',\n 'O que o cliente paga de uma vez, e até quando pode usar.',\n ),\n },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity' },\n { key: 'description', label: tl('Description', 'Descrição'), type: 'textarea', showInTable: false, group: 'identity' },\n // O recibo sai sem o valor — pacote de cortesia, ou cliente que não quer o\n // preço impresso no papel que leva para casa.\n { key: 'hideValueOnReceipt', label: tl('Hide value on the receipt', 'Não exibir valor no recibo'), type: 'boolean', defaultValue: false, showInTable: false, group: 'identity' },\n // O PREÇO É A SOMA DAS LINHAS quando há linhas: a 166 o mantém assim no\n // banco, pelo mesmo motivo do V1 — dois números para a mesma coisa só\n // sobrevivem se ninguém puder escrever um sem o outro. Digitável porque o\n // pacote SEM itens é um bloco solto de sessões, e aí ele é a única resposta.\n {\n // SEM `required`: com serviços listados abaixo este campo é a SOMA deles\n // (a 166 a mantém no banco), e cobrar que alguém digite um número que o\n // formulário vai descartar trava o cadastro na própria resposta certa.\n // `defaultValue: 0` e não vazio: a coluna é NOT NULL, e um campo de\n // dinheiro em que ninguém tocou chegava ao banco como `null` — o cadastro\n // morria num erro de constraint falando de uma coluna que a tela nem pediu.\n key: 'price', label: tl('Price', 'Preço'), type: 'currency', defaultValue: 0, showInTable: true, group: 'pricing',\n hint: tl(\n 'With services listed below, this is their sum.',\n 'Com serviços listados abaixo, este é a soma deles.',\n ),\n },\n // DERIVADO — quanto o pacote tira do preço de tabela. Só leitura: quem o\n // muda é a linha, não este campo.\n { key: 'discountPercentage', label: tl('Discount (%)', 'Desconto (%)'), type: 'number', showInTable: true, showInForm: false, group: 'pricing' },\n // O TOTAL DE SESSÕES é o que o cliente comprou; os itens dizem de QUÊ.\n // Os dois existem porque um pacote pode vender «10 sessões» escolhendo o\n // serviço na hora, e outro pode listar exatamente o que entra.\n { key: 'sessionsTotal', label: tl('Sessions', 'Total de sessões'), type: 'number', min: 1, showInTable: true, group: 'pricing' },\n // A VALIDADE É UMA ESCOLHA, não um campo vazio: «nunca vence» e «ainda não\n // preenchi» são respostas diferentes, e só o interruptor as separa.\n { key: 'validityEnabled', label: tl('Expires', 'Ativar validade'), type: 'boolean', defaultValue: false, showInTable: false, group: 'pricing' },\n {\n key: 'validityMonths', label: tl('Valid for (months)', 'Válido por (meses)'), type: 'number', min: 1, showInTable: true, group: 'pricing',\n hint: tl('Counted from the sale.', 'Contados a partir da venda.'),\n },\n // Quanto o vendedor ganha por vender ESTE pacote — diferente da comissão\n // de executar cada sessão, que sai do valor de tabela da linha.\n { key: 'commissionPercent', label: tl('Sales commission (%)', '% de comissão sobre venda'), type: 'number', min: 0, max: 100, defaultValue: 0, showInTable: false, group: 'pricing' },\n // Sem isto o balcão não tem como fechar um pacote com o desconto que o\n // dono autorizou de boca.\n { key: 'allowPriceEditOnSale', label: tl('Price can be edited at sale time', 'Permitir edição do valor na hora da venda'), type: 'boolean', defaultValue: false, showInTable: false, group: 'pricing' },\n ...recordRailFields({ tagsTable: 'service_packages', activeLabel: tl('Active', 'Ativo') }),\n ],\n // SEÇÃO, e não aba: o que entra no pacote é a definição dele, não um assunto\n // ao lado. Como aba, montar um pacote de três serviços era abrir a aba, abrir\n // uma sub-página por linha e voltar três vezes — e a página de edição do\n // pacote, que é onde se decide, não mostrava nada do que ele contém.\n //\n // `grid` porque a linha tem três respostas e todas se corrigem o tempo todo:\n // é a grade «Itens do Pacote» do V1, editável onde é lida.\n relatedSections: [\n { id: 'package-services', entity: servicePackageItemEntity, foreignKey: 'packageId', icon: 'ListChecks', display: 'grid',\n // Same service twice with different in-package prices is a real package\n // (e.g. first session full price, the rest discounted).\n duplicable: true,\n emptyHint: tl(\n 'No service in this package yet — it will be sold as a loose block of sessions.',\n 'Nenhum serviço neste pacote ainda — ele será vendido como um bloco solto de sessões.',\n ),\n // Os dois totais lado a lado são a decisão do pacote: o da esquerda é o\n // que custaria avulso, o da direita é o que o cliente paga. A distância\n // entre eles é a oferta.\n footer: (rows) => {\n const money = (v: number) => {\n try { return new Intl.NumberFormat(undefined, { style: 'currency', currency: 'BRL' }).format(v) }\n catch { return v.toFixed(2) }\n }\n const soma = (key: string) => rows.reduce(\n (total, r) => total + (Number(r[key]) || 0) * (Number(r.quantity) || 0), 0,\n )\n return [\n { label: tl('Items total', 'Total em itens'), value: money(soma('unitPrice')) },\n { label: tl('In package', 'No pacote'), value: money(soma('packagePrice')), tone: 'positive' as const },\n ]\n },\n },\n ],\n data: {\n table: 'service_packages',\n schema: 'public',\n tenantScoped: true,\n searchColumns: ['name'],\n },\n}\n","import React from 'react'\nimport type { EntityDef } from '@fayz-ai/core'\nimport { RelatedListTab } from '@fayz-ai/admin'\nimport { serviceLocationEntity } from '../lib/entities'\n\n/**\n * \"Locais Operacionais\" of the V1 company form: the rooms of THIS unit, with the\n * same create/edit as Cadastros → Locais. The unit comes from the parent, so the\n * rail field is dropped by RelatedListTab and every new room is born here.\n */\nexport function UnitRoomsWidget({ item }: { item?: { id?: string } }) {\n if (!item?.id) return null\n return (\n <RelatedListTab\n item={item}\n entityDef={serviceLocationEntity as EntityDef}\n parentTabId=\"locations\"\n related={{\n id: 'rooms', label: 'Locais operacionais', entity: serviceLocationEntity, foreignKey: 'unitId',\n emptyHint: 'Nenhuma sala, cadeira ou box nesta unidade ainda. Sem elas a agenda não sabe onde cabe cada atendimento.',\n }}\n />\n )\n}\n","import { tl, getSupabaseClientOptional } from '@fayz-ai/core'\nimport { createArchetypeLookup, type EntityLookup, type EntityLookupLine, type EntityLookupManage, type EntityLookupResult } from '@fayz-ai/admin'\nimport type { EntityDef } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// O PACOTE COMO LINHA DE DOCUMENTO.\n//\n// O cadastro do pacote é uma coisa; vendê-lo é outra. Uma conta a receber\n// pergunta o TIPO da linha — Produto, Serviço, Outro — e o pacote é um quarto\n// tipo com catálogo próprio: `service_packages`, não `products`. Sem esta\n// busca, quem vende «10 sessões de drenagem» digita o nome à mão e o preço de\n// cabeça, e o mesmo pacote entra com três nomes e três preços.\n//\n// Não há arquétipo de pacote — nem deveria haver, porque a tabela não é da\n// espinha de catálogo. O que isto reaproveita do arquétipo de produto é só a\n// MECÂNICA: busca, contagem, cadastro rápido e cache por conta. A origem, os\n// campos e o formulário vêm daqui.\n//\n// A contagem é o que faz o tipo SUMIR na casa que não vende pacote (ver\n// useStockedItemTypes no financeiro): o restaurante recebe a opção junto com o\n// plugin e nunca a vê, porque `service_packages` dele tem zero linhas.\n// ---------------------------------------------------------------------------\n\n/** O cadastro rápido, em COLUNAS da tabela — ele escreve direto, sem a camada\n * camelCase do provider. Só o que faz um pacote existir: nome, preço e\n * quantas sessões ele vale. */\nconst quickCreateDef: EntityDef = {\n name: tl('Package', 'Pacote'),\n namePlural: tl('Packages', 'Pacotes'),\n icon: 'PackageCheck',\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true },\n { key: 'price', label: tl('Price', 'Preço'), type: 'currency', required: true },\n { key: 'sessions_total', label: tl('Sessions', 'Total de sessões'), type: 'number', min: 1 },\n {\n key: 'validity_months', label: tl('Valid for (months)', 'Válido por (meses)'), type: 'number', min: 1,\n hint: tl('Empty means it never expires.', 'Vazio significa que nunca vence.'),\n },\n ],\n}\n\nconst cents = (v: number) => Math.round(v * 100)\n\n/** Uma linha do pacote, já com os dois preços que a 166 trouxe. */\ntype Membro = {\n packageId: string\n productId: string\n quantity: number\n /** O valor de tabela — base da comissão. */\n unitPrice: number\n /** Quanto ele vale DENTRO do pacote — o que o cliente paga. */\n packagePrice: number\n}\n\nasync function membersOf(packageIds: string[]): Promise<Map<string, Membro[]>> {\n const out = new Map<string, Membro[]>()\n const supabase = getSupabaseClientOptional() as any\n if (!supabase || !packageIds.length) return out\n const { data } = await supabase\n .from('service_package_items')\n .select('package_id, product_id, quantity, unit_price, package_price, sort_order')\n .in('package_id', packageIds)\n .order('sort_order', { ascending: true })\n for (const row of (data ?? []) as any[]) {\n const key = String(row.package_id)\n const list = out.get(key) ?? []\n list.push({\n packageId: key,\n productId: String(row.product_id),\n quantity: Number(row.quantity) || 1,\n unitPrice: Number(row.unit_price) || 0,\n packagePrice: Number(row.package_price) || 0,\n })\n out.set(key, list)\n }\n return out\n}\n\nasync function productsById(ids: string[]): Promise<Map<string, { name: string; price: number }>> {\n const out = new Map<string, { name: string; price: number }>()\n const supabase = getSupabaseClientOptional() as any\n if (!supabase || !ids.length) return out\n const { data } = await supabase.from('products').select('id, name, price').in('id', ids)\n for (const p of (data ?? []) as any[]) {\n out.set(String(p.id), { name: String(p.name ?? ''), price: Number(p.price) || 0 })\n }\n return out\n}\n\nfunction money(value: number, currency: string): string {\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(value)\n } catch {\n return value.toFixed(2)\n }\n}\n\n// ---------------------------------------------------------------------------\n// O QUE TEM DENTRO, NA HORA DE ESCOLHER.\n//\n// O V1 não oferece pacote numa lista de nomes: ele mostra um cartão com o que\n// entra («10x Psicoterapia») e os dois preços — o de tabela riscado e o do\n// pacote. Os dois são a decisão: sem o conteúdo não dá para saber o que se está\n// vendendo, e sem a comparação não dá para dizer ao cliente quanto ele economiza.\n//\n// Aqui isso vira o SUBTÍTULO da opção, que é onde esta tela tem espaço. Uma\n// consulta para os itens de todos os pacotes da lista e outra para os nomes —\n// duas, e não duas por pacote.\n// ---------------------------------------------------------------------------\nasync function describe(rows: EntityLookupResult[]): Promise<EntityLookupResult[]> {\n if (!rows.length) return rows\n const membros = await membersOf(rows.map((r) => r.id))\n const todos = [...new Set([...membros.values()].flat().map((m) => m.productId))]\n const produtos = await productsById(todos)\n\n return rows.map((row) => {\n const lista = membros.get(row.id) ?? []\n if (!lista.length) return row\n const partes = lista.map((m) => {\n const p = produtos.get(m.productId)\n // Serviço que saiu do catálogo depois de entrar no pacote: o V1 escreve\n // «Serviço não encontrado» em vez de omitir a linha, e está certo — some\n // dali o aviso de que o pacote precisa de conserto.\n return `${m.quantity}x ${p?.name || tl('Service not found', 'Serviço não encontrado')}`\n })\n const tabela = lista.reduce(\n (s, m) => s + m.quantity * (m.unitPrice || produtos.get(m.productId)?.price || 0),\n 0,\n )\n const preco = row.price ?? 0\n const moeda = String((row.data as Record<string, unknown> | undefined)?.currency ?? 'BRL')\n const resumo = partes.length > 3 ? [...partes.slice(0, 3), `+${partes.length - 3}`] : partes\n const economia = tabela > preco ? ` · ${money(tabela, moeda)} → ${money(preco, moeda)}` : ''\n return { ...row, subtitle: `${resumo.join(' · ')}${economia}` }\n })\n}\n\n// ---------------------------------------------------------------------------\n// O preço do pacote repartido entre os serviços dele — SÓ quando ele não disse.\n//\n// Desde a 166 cada linha carrega `package_price`: a casa decide quanto cada\n// serviço vale dentro do pacote, e vender é só copiar esses números. O rateio\n// abaixo é o caminho de trás, para a linha que ainda não tem preço — pacote\n// cadastrado antes da 166 e nunca reaberto.\n//\n// O arredondamento sobra: dez linhas de centavos quebrados não somam de volta\n// ao preço do pacote. O resto vai inteiro para a PRIMEIRA linha, como desconto\n// ou acréscimo, porque o que não pode fechar errado é o total.\n// ---------------------------------------------------------------------------\nfunction split(\n packagePrice: number,\n lines: Array<{ referenceId: string; description: string; quantity: number; catalogPrice: number }>,\n): EntityLookupLine[] {\n const weights = lines.map((l) => l.quantity * l.catalogPrice)\n const totalWeight = weights.reduce((s, w) => s + w, 0)\n // Catálogo sem preço (ou tudo zerado) divide por quantidade: é a única outra\n // resposta possível, e é melhor que jogar o pacote inteiro na primeira linha.\n const fallback = lines.map((l) => l.quantity)\n const totalFallback = fallback.reduce((s, w) => s + w, 0)\n const use = totalWeight > 0 ? weights : fallback\n const total = totalWeight > 0 ? totalWeight : totalFallback\n if (total <= 0) return []\n\n const out: EntityLookupLine[] = lines.map((l, i) => {\n const share = (packagePrice * use[i]!) / total\n return {\n referenceId: l.referenceId,\n description: l.description,\n quantity: l.quantity,\n unitPrice: Math.round((share / l.quantity) * 100) / 100,\n itemKind: 'service',\n }\n })\n\n const sobra = cents(packagePrice) - out.reduce((s, l) => s + cents(l.unitPrice * l.quantity), 0)\n if (sobra !== 0 && out[0]) {\n out[0] = sobra > 0\n ? { ...out[0], surcharge: sobra / 100 }\n : { ...out[0], discount: -sobra / 100 }\n }\n return out\n}\n\n/** Os serviços de um pacote, com o que o cliente paga por cada um. */\nasync function expandPackage(packageId: string): Promise<EntityLookupLine[]> {\n const supabase = getSupabaseClientOptional() as any\n if (!supabase) return []\n\n const { data: pkg } = await supabase\n .from('service_packages')\n .select('id, name, price')\n .eq('id', packageId)\n .maybeSingle()\n if (!pkg) return []\n\n const membros = (await membersOf([packageId])).get(packageId) ?? []\n // Pacote que não declara o que entra nele continua sendo UMA linha: o nome do\n // pacote é tudo que se sabe, e inventar serviço nenhum é a resposta certa.\n if (!membros.length) return []\n\n const produtos = await productsById(membros.map((m) => m.productId))\n const base = membros\n .map((m) => {\n const produto = produtos.get(m.productId)\n if (!produto) return null\n return { ...m, name: produto.name, catalogPrice: produto.price }\n })\n .filter(Boolean) as Array<Membro & { name: string; catalogPrice: number }>\n if (!base.length) return []\n\n const metadata = (m: Membro) => ({\n packageId: String(pkg.id),\n packageName: String(pkg.name ?? ''),\n // A base da COMISSÃO viaja com a linha: o que o cliente paga é o preço do\n // pacote, e o que o profissional recebe sai do valor de tabela.\n listUnitPrice: m.unitPrice,\n })\n\n // O caminho normal: a casa já disse quanto cada serviço vale aqui dentro.\n if (base.some((m) => m.packagePrice > 0)) {\n return base.map((m) => ({\n referenceId: m.productId,\n description: m.name,\n quantity: m.quantity,\n unitPrice: m.packagePrice,\n itemKind: 'service',\n metadata: metadata(m),\n }))\n }\n\n // Linha anterior à 166: reparte o preço do pacote, como antes.\n return split(\n Number(pkg.price) || 0,\n base.map((m) => ({\n referenceId: m.productId,\n description: m.name,\n quantity: m.quantity,\n catalogPrice: m.unitPrice || m.catalogPrice,\n })),\n ).map((l, i) => ({ ...l, metadata: metadata(base[i]!) }))\n}\n\n/** A busca de pacotes de serviço, para `entityLookups.package`. */\nexport function createServicePackageLookup(options: { manage?: EntityLookupManage } = {}): EntityLookup {\n const base = createArchetypeLookup({\n archetype: 'product',\n manage: options.manage,\n table: 'service_packages',\n subtitleFields: ['description'],\n searchFields: ['name', 'description'],\n entityDef: quickCreateDef,\n })\n return {\n ...base,\n expand: expandPackage,\n search: async (query: string) => describe(await base.search(query)),\n list: base.list ? async () => describe(await base.list!()) : undefined,\n }\n}\n","import type { PluginManifest, PluginScope, VerticalId, EntityDef } from '@fayz-ai/core'\nimport { Briefcase, Map, MapPin, PackageCheck, Tag, UserCog, Users } from 'lucide-react'\nimport { adminNavigateTo, createCrudPage, UNIT_DETAIL_ZONES, type CrudNavTab } from '@fayz-ai/admin'\nimport type React from 'react'\nimport { UnitRoomsWidget } from './views/UnitRoomsWidget'\n\nimport {\n staffEntity, supplierEntity, contactEntity, partnershipEntity, equipmentEntity,\n originEntity, serviceCategoryEntity, serviceLocationEntity, locationGroupEntity,\n professionEntity, petSpeciesEntity, servicePackageEntity,\n serviceEntity, teamEntity,\n} from './lib/entities'\n\n// ---------------------------------------------------------------------------\n// plugin-registry — os Cadastros.\n// ---------------------------------------------------------------------------\n// ── O buraco que ele fecha ─────────────────────────────────────────────────\n// O aplicativo central carrega o ofício de quem entra, e para o Espaço Facial\n// ele carregava tudo MENOS os Cadastros: a rubrica não desenhava porque as dez\n// telas dela não existiam ali. Elas estavam escritas dentro do beauty-saas, em\n// `src/config/pages.tsx` — um aplicativo só, e portanto uma conta só.\n//\n// Era o mesmo defeito que o preset resolveu para a ORDEM e a 118 para o NOME,\n// um degrau abaixo: não adianta o ofício saber agrupar e nomear se ninguém\n// serve a tela. Quem serve tela é plugin.\n//\n// ── Por que um plugin, e não mais uma pasta no aplicativo ──────────────────\n// Nenhuma destas fichas é de salão. Fornecedor, contato, equipamento, origem e\n// filial são o que QUALQUER casa cadastra; o restaurante compra de fornecedor\n// e a escola registra origem de matrícula. O que muda por ofício é o nome da\n// linha no menu — \"Funcionários\" no BeautySoft, \"Equipe\" no resto — e disso\n// cuida o `labels` do preset, no banco.\n//\n// ── O ofício liga o que usa ────────────────────────────────────────────────\n// `modules` desliga tela a tela: uma loja sem atendimento não quer Serviços\n// nem Categorias de Serviço, e uma rubrica cujos filhos saíram todos não\n// desenha. É o mesmo contrato dos outros plugins — oferecer, não impor.\n// ---------------------------------------------------------------------------\n\n/** Cada tela de cadastro, na ORDEM em que o menu as lê por padrão. */\nconst SCREENS = [\n { id: 'services', path: '/registry/services', entity: serviceEntity, icon: 'Briefcase', feature: 'services' },\n { id: 'serviceCategories', path: '/registry/categories', entity: serviceCategoryEntity, icon: 'Tag', feature: 'services', nested: true },\n // O pacote é catálogo como o serviço — aninhado nele, porque é um jeito de\n // vender serviço e não um assunto novo no menu.\n { id: 'servicePackages', path: '/registry/service-packages', entity: servicePackageEntity, icon: 'PackageCheck', feature: 'services', nested: true },\n { id: 'locations', path: '/registry/locations', entity: serviceLocationEntity, icon: 'MapPin', feature: 'services' },\n // A SALA, aninhada na unidade: ela é onde se atende dentro do prédio, e uma\n // linha solta no menu ao lado de «Unidades» repetiria a confusão que a 153\n // acabou de desfazer.\n { id: 'locationGroups', path: '/registry/location-groups', entity: locationGroupEntity, icon: 'Map', feature: 'services', nested: true },\n { id: 'staff', path: '/registry/staff', entity: staffEntity, icon: 'UserCog' },\n { id: 'teams', path: '/registry/teams', entity: teamEntity, icon: 'Users', nested: true },\n // Aninhada em Profissionais: a profissão é o vocabulário DELES, e uma linha\n // solta no menu para uma lista de cinco palavras custa mais do que vale.\n { id: 'professions', path: '/registry/professions', entity: professionEntity, icon: 'BriefcaseBusiness', nested: true },\n { id: 'contacts', path: '/registry/contacts', entity: contactEntity, icon: 'Contact' },\n { id: 'suppliers', path: '/registry/suppliers', entity: supplierEntity, icon: 'Building2' },\n { id: 'partnerships', path: '/registry/partnerships', entity: partnershipEntity, icon: 'Handshake' },\n { id: 'equipment', path: '/registry/equipment', entity: equipmentEntity, icon: 'Wrench' },\n { id: 'origins', path: '/registry/origins', entity: originEntity, icon: 'Globe' },\n // Só faz sentido em casa que atende pet — ver OPT_IN.\n { id: 'petSpecies', path: '/registry/pet-species', entity: petSpeciesEntity, icon: 'PawPrint', feature: 'pets' },\n] as const\n\nexport type RegistryScreenId = (typeof SCREENS)[number]['id']\n\n// ---------------------------------------------------------------------------\n// AS TELAS QUE NASCEM DESLIGADAS.\n//\n// A regra do `modules` é «ausente = tem», e ela está certa para o cadastro que\n// qualquer casa reconhece: publicar uma ficha nova não pode ser o dia em que\n// ela some de toda conta que não a listou.\n//\n// Só que \"Tipos de animais\" não é uma ficha que qualquer casa reconhece — é o\n// vocabulário de UM ofício. Nascendo ligada, ela apareceu em Cadastros do\n// restaurante, do salão, da clínica, da escola e da bilheteria, e em nenhuma\n// delas alguém vai cadastrar «cachorro». O padrão certo para a tela de um\n// ofício é o contrário: quem a quer, pede.\n//\n// `modules: { petSpecies: true }` liga — é o que o ofício de pet passa, do\n// mesmo jeito que hoje uma loja passa `services: false`.\n// ---------------------------------------------------------------------------\nconst OPT_IN = new Set<RegistryScreenId>(['petSpecies'])\n\nconst serviceTabs = (): CrudNavTab[] => [\n { id: 'services', label: serviceEntity.namePlural ?? serviceEntity.name, icon: Briefcase, onSelect: () => adminNavigateTo('/registry/services') },\n { id: 'serviceCategories', label: serviceCategoryEntity.namePlural ?? serviceCategoryEntity.name, icon: Tag, onSelect: () => adminNavigateTo('/registry/categories') },\n // A tela do pacote existia e não tinha porta: a rota estava registrada, a\n // ficha também, e nenhuma faixa de aba a listava. Esta linha é a porta.\n { id: 'servicePackages', label: servicePackageEntity.namePlural ?? servicePackageEntity.name, icon: PackageCheck, onSelect: () => adminNavigateTo('/registry/service-packages') },\n]\n\nconst staffTabs = (): CrudNavTab[] => [\n { id: 'staff', label: staffEntity.namePlural ?? staffEntity.name, icon: UserCog, onSelect: () => adminNavigateTo('/registry/staff') },\n { id: 'teams', label: teamEntity.namePlural ?? teamEntity.name, icon: Users, onSelect: () => adminNavigateTo('/registry/teams') },\n]\n\nconst locationTabs = (): CrudNavTab[] => [\n { id: 'locations', label: serviceLocationEntity.namePlural ?? serviceLocationEntity.name, icon: MapPin, onSelect: () => adminNavigateTo('/registry/locations') },\n { id: 'locationGroups', label: locationGroupEntity.namePlural ?? locationGroupEntity.name, icon: Map, onSelect: () => adminNavigateTo('/registry/location-groups') },\n]\n\nexport interface RegistryPluginOptions {\n scope?: PluginScope\n verticalId?: VerticalId\n /** Onde a primeira linha cai no rail. As demais vêm em degraus de 0,1. */\n navPosition?: number\n navSection?: 'main' | 'secondary' | 'settings'\n /**\n * Quais telas esta casa tem. Ausente = todas, menos as de ofício.\n *\n * `false` é a única forma de negar: uma chave que ninguém respondeu cai no\n * padrão, não em \"não\" — do contrário, publicar uma ficha nova seria o dia\n * em que ela some de toda conta que não a listou.\n *\n * A exceção é a tela que só um ofício reconhece (ver `OPT_IN`): essa nasce\n * desligada, e `true` é o que a liga.\n */\n modules?: Partial<Record<RegistryScreenId, boolean>>\n /**\n * Troca a definição de uma ficha sem trocar a tela.\n *\n * A casa que precisa de um campo a mais no fornecedor passa o EntityDef dela\n * aqui em vez de reimplementar a rota — que foi exatamente como as dez\n * acabaram dentro de um aplicativo.\n */\n entities?: Partial<Record<RegistryScreenId, EntityDef>>\n}\n\nexport function createRegistryPlugin(options?: RegistryPluginOptions): PluginManifest {\n const section = options?.navSection ?? 'main'\n const base = options?.navPosition ?? 80\n\n const active = SCREENS.filter((screen) => (\n OPT_IN.has(screen.id)\n ? options?.modules?.[screen.id] === true\n : options?.modules?.[screen.id] !== false\n ))\n\n const pages = active.map((screen, index) => {\n const entity = options?.entities?.[screen.id] ?? (screen.entity as EntityDef)\n const feature = (screen as { feature?: string }).feature\n const grouped = screen.id === 'services' || screen.id === 'serviceCategories' || screen.id === 'servicePackages'\n ? { navTabs: serviceTabs, activeNavTab: screen.id }\n : screen.id === 'locations' || screen.id === 'locationGroups'\n ? { navTabs: locationTabs, activeNavTab: screen.id }\n : screen.id === 'staff' || screen.id === 'teams'\n ? { navTabs: staffTabs, activeNavTab: screen.id }\n : {}\n return {\n screen,\n entity,\n position: base + index * 0.1,\n component: createCrudPage(entity, { ...(feature ? { feature } : {}), ...grouped }),\n permission: feature ? { feature, action: 'read' as const } : undefined,\n }\n })\n\n return {\n id: 'registry',\n name: 'Cadastros',\n icon: 'ClipboardList',\n version: '1.0.0',\n scope: options?.scope ?? 'universal',\n verticalId: options?.verticalId,\n defaultEnabled: true,\n dependencies: [],\n\n // Uma linha por ficha, plana. Quem as junta sob \"Cadastros\" — e em que\n // ordem, e com que nome — é o `rail` do ofício. Ver packages/admin\n // rail-preset.ts: o ofício AGRUPA, o plugin NOMEIA, e o `labels` do preset\n // é a casa dizendo que ali a ficha se chama outra coisa.\n navigation: pages.filter((page) => !('nested' in page.screen && page.screen.nested)).map((page) => ({\n section,\n position: page.position,\n label: page.entity.namePlural ?? page.entity.name,\n route: page.screen.path,\n icon: page.screen.icon,\n ...(page.permission ? { permission: page.permission } : {}),\n })),\n\n widgets: [\n {\n id: 'registry-unit-rooms',\n zone: UNIT_DETAIL_ZONES.rooms,\n component: UnitRoomsWidget as unknown as React.ComponentType<unknown>,\n order: 0,\n },\n ],\n routes: pages.map((page) => ({\n path: page.screen.path,\n component: page.component as React.ComponentType<unknown>,\n title: page.entity.namePlural ?? page.entity.name,\n ...(page.permission ? { permission: page.permission } : {}),\n })),\n }\n}\n\nexport {\n staffEntity, supplierEntity, contactEntity, partnershipEntity, equipmentEntity,\n originEntity, serviceCategoryEntity, serviceLocationEntity, locationGroupEntity,\n professionEntity, petSpeciesEntity, servicePackageEntity,\n serviceEntity, teamEntity,\n} from './lib/entities'\n\nexport { createServicePackageLookup } from './lib/package-lookup'\n"]}
1
+ {"version":3,"sources":["../src/lib/person-fields.ts","../src/lib/entities.ts","../src/views/UnitRoomsWidget.tsx","../src/lib/package-lookup.ts","../src/index.ts"],"names":["tl","RECORD_GROUP","recordRailFields","money","Map"],"mappings":"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","file":"index.js","sourcesContent":["import { tl, RECORD_GROUP, recordRailFields, activeFacet } from '@fayz-ai/core'\nimport type { FieldDef, FieldGroup } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// O que TODA ficha de pessoa deste módulo pergunta.\n//\n// No V1 estes cadastros são LITERALMENTE a mesma tabela: Contatos é a visão\n// completa de `contacts`, e Fornecedores e Parcerias são a mesma tabela\n// pré-filtrada por `contact_type`. O V2 já modela isso certo — `people` com\n// `kind` —, e aqui a consequência é declarar os campos uma vez em vez de três.\n//\n// O que NÃO entra: o que distingue uma espécie da outra. Fornecedor tem tipo de\n// prestador e inscrição estadual; parceria tem escopo de unidades. Esses ficam\n// na entidade que os tem, que é onde alguém vai procurar por eles.\n// ---------------------------------------------------------------------------\n\nexport const PERSON_GROUPS: FieldGroup[] = [\n // Nome e documento NÃO entram: o arquétipo `person` os hasteia para o\n // cabeçalho da ficha, ao lado da foto. O que sobra é o resto da pessoa.\n { id: 'identity', label: tl('Personal', 'Dados pessoais'), columns: 2 },\n { id: 'contact', label: tl('Contact', 'Contato'), columns: 2 },\n { id: 'where', label: tl('Address', 'Endereço'), columns: 1 },\n {\n id: 'banking', label: tl('Banking', 'Dados bancários'), columns: 1,\n description: tl(\n 'Where money goes OUT to this person — not an account of the house.',\n 'Para onde o dinheiro SAI para esta pessoa — não é conta da casa.',\n ),\n },\n { ...RECORD_GROUP, label: tl('Record', 'Situação') },\n]\n\n/** A lista abre em «Ativos», como toda lista de cadastro do V1. */\nexport const ACTIVE_FACET = activeFacet({\n active: tl('Active', 'Ativos'),\n inactive: tl('Inactive', 'Inativos'),\n all: tl('All', 'Todos'),\n})\n\n/**\n * Os canais de contato.\n *\n * Telefone e CELULAR são dois campos, e é o celular que leva o WhatsApp — a\n * régua de comunicação procura este, não o fixo.\n *\n * O V1 tem um SEGUNDO de cada (telefone 2, celular 2, e-mail 2), e eles estão\n * desligados: seis caixas de contato num cadastro cuja resposta costuma ser um\n * número e um e-mail são cinco perguntas a mais para a recepção rolar. As\n * chaves continuam declaradas em `customFields` de propósito — quem já tem o\n * segundo telefone gravado não o perde, e religar é descomentar três linhas.\n */\nexport function contactChannelFields(): FieldDef[] {\n return [\n { key: 'phone', label: tl('Phone', 'Telefone'), type: 'phone', showInTable: true, searchable: true, group: 'contact' },\n { key: 'mobile', label: tl('Mobile', 'Celular'), type: 'phone', showInTable: true, group: 'contact' },\n { key: 'email', label: 'E-mail', type: 'email', showInTable: true, searchable: true, group: 'contact', span: 2 },\n // Desligados — ver acima.\n // { key: 'phone2', label: tl('Phone 2', 'Telefone 2'), type: 'phone', showInTable: false, group: 'contact' },\n // { key: 'mobile2', label: tl('Mobile 2', 'Celular 2'), type: 'phone', showInTable: false, group: 'contact' },\n // { key: 'email2', label: tl('E-mail 2', 'E-mail 2'), type: 'email', showInTable: false, group: 'contact' },\n ]\n}\n\n/**\n * Endereço e conta, os dois campos que são UMA LINHA DE OUTRA TABELA\n * (`public.addresses` e `public.payee_accounts`).\n *\n * `showInDetail: false` nos dois: a ficha tem as seções completas logo abaixo,\n * que listam TODAS as linhas, editam e excluem. O campo existe para o momento\n * em que a seção não pode existir — a criação, quando ainda não há id.\n */\nexport function attachedFields(): FieldDef[] {\n return [\n { key: 'address', label: tl('Address', 'Endereço'), type: 'address', showInTable: false, showInDetail: false, group: 'where' },\n { key: 'payeeAccount', label: tl('Bank account', 'Conta bancária'), type: 'bank', showInTable: false, showInDetail: false, group: 'banking' },\n ]\n}\n\n/**\n * O rail direito, IGUAL em todo cadastro.\n *\n * A ordem é fixa de propósito: quem procura o interruptor «Ativo» não pode\n * ter de caçá-lo numa altura diferente a cada tela. Unidade e o interruptor\n * dividem a primeira linha — a unidade responde «de quem é» e o interruptor\n * «vale ou não», que é o par que se lê junto —, e embaixo vêm as duas coisas\n * que se ESCREVE sobre o registro: o texto solto e as etiquetas.\n *\n * As etiquetas são o recorte que a casa inventa e o produto não prevê\n * («cliente VIP», «fornecedor homologado»). Sem elas isso vai para\n * Observações, onde não filtra e não conta.\n */\nexport function recordFields(table = 'people', options: { unit?: boolean } = {}): FieldDef[] {\n return recordRailFields({\n tagsTable: table,\n activeLabel: tl('Active', 'Ativo'),\n // Um cadastro que já pergunta o ESCOPO de unidades não pergunta também a\n // unidade padrão: são duas perguntas parecidas e respostas diferentes, e\n // na tela viravam dois seletores de unidade — um multi à esquerda e um\n // único à direita — sem nada dizendo qual manda.\n unit: options.unit,\n })\n}\n\n/** O sexo, que no V1 é pergunta de contato e de cliente. */\nexport function genderField(): FieldDef {\n return {\n key: 'gender', label: tl('Gender', 'Sexo'), type: 'select', showInTable: false, group: 'identity',\n options: [\n { value: 'masculino', label: tl('Male', 'Masculino') },\n { value: 'feminino', label: tl('Female', 'Feminino') },\n { value: 'outro', label: tl('Other', 'Outro') },\n ],\n }\n}\n\n/**\n * As chaves que não são coluna de `people` e moram em `custom_fields`.\n *\n * `phone2`, `mobile2` e `email2` continuam aqui mesmo com os campos\n * desligados: é isto que faz o segundo telefone JÁ GRAVADO continuar sendo\n * lido, em vez de virar lixo no jsonb no dia em que o campo voltar.\n */\nexport const PERSON_CUSTOM_FIELDS = ['gender', 'mobile', 'phone2', 'mobile2', 'email2']\n","import { tl, RECORD_GROUP, recordRailFields } from '@fayz-ai/core'\nimport {\n PERSON_GROUPS, ACTIVE_FACET, PERSON_CUSTOM_FIELDS,\n contactChannelFields, attachedFields, recordFields, genderField,\n} from './person-fields'\nimport type { EntityDef } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// entities — as fichas de referência, iguais em qualquer ofício.\n// ---------------------------------------------------------------------------\n// Estas dez definições estavam escritas à mão dentro de UM aplicativo\n// (beauty-saas/src/types/registry.ts), e por isso os Cadastros existiam só lá:\n// o aplicativo central abria a mesma conta, com os mesmos dados, e o menu não\n// tinha a rubrica — não porque ela estivesse escondida, mas porque as telas\n// não existiam para serem agrupadas.\n//\n// Nada aqui é de salão. São as tabelas da espinha vistas por dez recortes:\n// `people` por papel (equipe, fornecedor, contato, parceiro), `products` como\n// patrimônio, `categories` por tipo (origem, categoria de serviço, grupo de\n// locais), `services`, e `v_units` — a filial. Um restaurante tem fornecedor e\n// equipamento; uma escola tem contato e origem. O que muda por ofício é o\n// NOME de cada linha no menu, e isso o preset do banco já resolve.\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Staff — person archetype + extension table\n// ---------------------------------------------------------------------------\nexport const staffEntity: EntityDef = {\n name: tl('Staff', 'Profissional'),\n namePlural: tl('Staff', 'Profissionais'),\n icon: 'UserCog',\n // staff_members is an extension table (no name column) — useless to the\n // agent's generic reader. The agent sees professionals through the\n // beauty:professionals read-model (people kind='staff') instead.\n agentHidden: true,\n layout: 'person',\n // The agenda already showed `avatar_url`; the record itself fell back to an initial.\n imageField: 'avatarUrl',\n displayField: 'name',\n subtitleField: 'profession',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n ...PERSON_GROUPS.filter((g) => g.id !== 'record'),\n {\n id: 'work', label: tl('Work', 'Trabalho'), columns: 2,\n description: tl(\n 'What this person does here, and how the calendar and the payroll see them.',\n 'O que esta pessoa faz aqui, e como a agenda e a folha a enxergam.',\n ),\n },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Full name', 'Nome completo'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity', span: 2 },\n { key: 'documentNumber', label: 'CPF', type: 'text', showInTable: true, searchable: true, group: 'identity' },\n // RG: o V1 pede os dois documentos na ficha de quem trabalha aqui, e a\n // folha usa ambos.\n { key: 'rg', label: 'RG', type: 'text', showInTable: false, group: 'identity' },\n { key: 'dateOfBirth', label: tl('Date of birth', 'Data de nascimento'), type: 'date', showInTable: false, group: 'identity' },\n genderField(),\n ...contactChannelFields(),\n ...attachedFields(),\n\n { key: 'profession', label: tl('Profession', 'Profissão'), type: 'text', showInTable: true, group: 'work' },\n // O VÍNCULO muda o que a folha e o fisco esperam — um autônomo emite RPA,\n // um CLT entra na folha, um PJ manda nota.\n {\n key: 'employmentType', label: tl('Employment type', 'Tipo de vínculo'), type: 'select', showInTable: false, group: 'work',\n options: [\n { value: 'clt', label: 'CLT' },\n { value: 'pj', label: 'Pessoa jurídica' },\n { value: 'autonomo', label: 'Autônomo' },\n { value: 'estagio', label: 'Estágio' },\n { value: 'socio', label: 'Sócio' },\n ],\n },\n // CBO é o código que a folha e o eSocial pedem. Texto porque a tabela\n // oficial tem ~2.500 entradas e um seletor delas seria pior que o campo.\n { key: 'cboCode', label: tl('CBO code', 'CBO'), type: 'text', showInTable: false, group: 'work',\n hint: tl('Brazilian occupation code, used by payroll.', 'Classificação Brasileira de Ocupações — a folha pede.') },\n {\n key: 'teamId', label: tl('Team', 'Equipe'), type: 'relation',\n showInTable: true, group: 'work',\n relation: { table: 'categories', filter: { kind: 'staff_team', is_active: true } },\n hint: tl('Where this person works — reception, aesthetics, sales.', 'Onde esta pessoa trabalha — recepção, estética, vendas.'),\n },\n { key: 'commissionRate', label: tl('Commission (%)', 'Comissão (%)'), type: 'number', showInTable: true, group: 'work', defaultValue: 0 },\n // O CENTRO DE CUSTO da pessoa é o que permite alocar o custo dela por\n // área — é assim que a folha vira despesa de Operação e não um bolo só.\n {\n key: 'costCenterId', label: tl('Cost centre', 'Centro de custo'), type: 'relation', showInTable: false, group: 'work',\n relation: { table: 'plg_financial_cost_centers', labelField: 'name' },\n },\n // Trabalhar aqui não é atender cliente: a recepção e o financeiro entram\n // por esta mesma tela. Sem a escolha no cadastro, todo mundo nascia com\n // coluna na grade da semana e horário livre para marcarem em cima.\n {\n key: 'isBookable', label: tl('Appears in the calendar', 'Aparece na agenda'), type: 'boolean',\n showInTable: true, defaultValue: true, group: 'work',\n hint: tl(\n 'Clients can be booked with this person.',\n 'Clientes podem ser marcados com esta pessoa.',\n ),\n },\n // O que a recepção precisa saber ANTES de marcar com esta pessoa.\n { key: 'agendaNotes', label: tl('Calendar notes', 'Informações para a agenda'), type: 'textarea', showInTable: false, group: 'work', span: 2 },\n\n ...recordFields(),\n ],\n // No custom documents tab: the `person` archetype supplies the shared\n // custom_forms documents widget (same as clients / school-saas).\n data: {\n // Pessoa pura, como no resto-saas: quem é da equipe é `people.kind='staff'`.\n table: 'people',\n tenantScoped: true,\n archetype: 'person',\n archetypeKind: 'staff',\n // `profession` e `commissionRate` eram colunas da extensão. A comissão de\n // verdade é a do motor de regras do Financeiro (plg_financial_commission_*),\n // que sabe dividir por serviço e por profissional; este número aqui é o\n // resquício de quando havia um só. Fica em custom_fields para não sumir.\n customFields: [\n ...PERSON_CUSTOM_FIELDS,\n 'profession', 'commissionRate', 'teamId', 'employmentType', 'cboCode', 'agendaNotes',\n 'rg', 'costCenterId',\n ],\n searchColumns: ['name', 'email', 'phone', 'document_number'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Suppliers — person archetype, direct query\n// ---------------------------------------------------------------------------\nexport const supplierEntity: EntityDef = {\n name: tl('Supplier', 'Fornecedor'),\n namePlural: tl('Suppliers', 'Fornecedores'),\n icon: 'Building2',\n layout: 'person',\n // The agenda already showed `avatar_url`; the record itself fell back to an initial.\n imageField: 'avatarUrl',\n displayField: 'name',\n subtitleField: 'documentNumber',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: PERSON_GROUPS,\n fields: [\n { key: 'name', label: tl('Legal name / Name', 'Razão social / Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity', span: 2 },\n // O tipo de prestador MUDA o documento: um autônomo assina com CPF, uma\n // empresa com CNPJ, e a inscrição estadual só existe para quem é inscrito.\n {\n key: 'serviceProviderType', label: tl('Service provider type', 'Tipo de prestador de serviço'), type: 'segmented',\n required: true, defaultValue: 'pj', group: 'identity', span: 2,\n options: [\n { value: 'pj', label: tl('Company', 'Pessoa jurídica') },\n { value: 'pf', label: tl('Individual', 'Pessoa física') },\n { value: 'autonomo', label: tl('Self-employed', 'Autônomo') },\n ],\n },\n {\n key: 'documentNumber', type: 'text', searchable: true, showInTable: true, group: 'identity',\n label: 'CNPJ / CPF',\n // Rotular sempre «CNPJ / CPF» faz o operador parar para escolher qual é.\n // Ele já escolheu na linha de cima.\n labelWhen: (v) => (v.serviceProviderType === 'pj' ? 'CNPJ' : 'CPF'),\n },\n {\n key: 'registrationNumber', label: tl('State / municipal registration', 'Inscrição estadual / municipal'), type: 'text', group: 'identity',\n // Pessoa física não tem inscrição estadual. Perguntar é convidar a\n // preencher o que ninguém vai ler.\n visibleWhen: (v) => v.serviceProviderType !== 'pf',\n },\n // O GRUPO do V1 («Grupo 1», «Grupo 2»): como a casa separa os fornecedores\n // dela. Texto livre porque no V1 é isso mesmo — uma taxonomia por conta\n // viraria um cadastro que ninguém pediu.\n { key: 'groupName', label: tl('Group', 'Grupo'), type: 'text', showInTable: false, group: 'identity' },\n ...contactChannelFields(),\n ...attachedFields(),\n ...recordFields(),\n ],\n data: {\n table: 'people',\n tenantScoped: true,\n archetype: 'person',\n archetypeKind: 'supplier',\n filters: { kind: 'supplier' },\n defaults: { kind: 'supplier' },\n customFields: [...PERSON_CUSTOM_FIELDS, 'serviceProviderType', 'registrationNumber', 'groupName'],\n searchColumns: ['name', 'email', 'phone', 'document_number'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Contacts — person archetype, direct query\n// ---------------------------------------------------------------------------\nexport const contactEntity: EntityDef = {\n name: tl('Contact', 'Contato'),\n namePlural: tl('Contacts', 'Contatos'),\n icon: 'Contact',\n layout: 'person',\n // The agenda already showed `avatar_url`; the record itself fell back to an initial.\n imageField: 'avatarUrl',\n displayField: 'name',\n subtitleField: 'documentNumber',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: PERSON_GROUPS,\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity', span: 2 },\n { key: 'documentNumber', label: 'CPF / CNPJ', type: 'text', showInTable: true, searchable: true, group: 'identity' },\n genderField(),\n ...contactChannelFields(),\n ...attachedFields(),\n ...recordFields(),\n ],\n data: {\n table: 'people',\n // Sem `schema`, de propósito: com ele a entidade resolvia para o provider\n // genérico de tabela, que não sabe ler nem gravar `custom_fields` — e\n // metade desta ficha mora lá. `public` já é o padrão.\n tenantScoped: true,\n archetype: 'person',\n archetypeKind: 'contact',\n filters: { kind: 'contact' },\n defaults: { kind: 'contact' },\n customFields: PERSON_CUSTOM_FIELDS,\n searchColumns: ['name', 'email', 'phone', 'document_number'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Partnerships — person archetype, direct query\n// ---------------------------------------------------------------------------\nexport const partnershipEntity: EntityDef = {\n name: tl('Partnership', 'Parceria'),\n namePlural: tl('Partnerships', 'Parcerias'),\n icon: 'Handshake',\n layout: 'person',\n // The agenda already showed `avatar_url`; the record itself fell back to an initial.\n imageField: 'avatarUrl',\n displayField: 'name',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: PERSON_GROUPS,\n fields: [\n { key: 'name', label: tl('Partnership name', 'Nome da parceria'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity', span: 2 },\n { key: 'documentNumber', label: 'CNPJ / CPF', type: 'text', showInTable: true, searchable: true, group: 'identity' },\n // O ESCOPO de unidades, que no V1 é o par «Limitar unidades? → quais».\n // Escolher «Todas» e ainda ver a lista de unidades é oferecer uma resposta\n // que não vale; por isso a lista só aparece depois da escolha.\n {\n key: 'unitScope', label: tl('Units', 'Unidades'), type: 'segmented',\n defaultValue: 'all', group: 'identity', span: 2,\n options: [\n { value: 'all', label: tl('All units', 'Todas as unidades') },\n { value: 'selected', label: tl('Pick units', 'Selecionar unidades') },\n ],\n },\n {\n key: 'units', label: tl('Selected units', 'Unidades selecionadas'), type: 'relation',\n showInTable: false, group: 'identity', span: 2,\n relation: { table: 'v_units', labelField: 'name' },\n visibleWhen: (v) => v.unitScope === 'selected',\n },\n ...contactChannelFields(),\n ...attachedFields(),\n ...recordFields('people', { unit: false }),\n ],\n data: {\n table: 'people',\n tenantScoped: true,\n archetype: 'person',\n archetypeKind: 'partner',\n filters: { kind: 'partner' },\n defaults: { kind: 'partner' },\n customFields: [...PERSON_CUSTOM_FIELDS, 'unitScope', 'units'],\n searchColumns: ['name', 'email', 'phone', 'document_number'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Equipment — product archetype, direct query\n// ---------------------------------------------------------------------------\nexport const equipmentEntity: EntityDef = {\n name: tl('Equipment', 'Equipamento'),\n namePlural: tl('Equipment', 'Equipamentos'),\n icon: 'Wrench',\n layout: 'product',\n displayField: 'name',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n { id: 'identity', label: tl('Identification', 'Identificação'), columns: 2 },\n { id: 'purchase', label: tl('Purchase', 'Compra e garantia'), columns: 2 },\n {\n id: 'maintenance', label: tl('Maintenance', 'Manutenção'), columns: 2,\n description: tl(\n 'The next date is what a list of equipment is FOR.',\n 'A próxima data é para o que uma lista de equipamentos serve.',\n ),\n },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity', span: 2 },\n { key: 'brand', label: tl('Brand', 'Marca'), type: 'text', showInTable: true, group: 'identity' },\n { key: 'model', label: tl('Model', 'Modelo'), type: 'text', showInTable: true, group: 'identity' },\n // O NÚMERO DE SÉRIE é o que a assistência técnica pede e o que distingue\n // dois aparelhos iguais na mesma sala.\n { key: 'sku', label: tl('Serial number', 'Número de série'), type: 'text', showInTable: false, searchable: true, group: 'identity' },\n {\n key: 'status', label: 'Status', type: 'select', showInTable: true, defaultValue: 'active', group: 'identity',\n options: [\n { value: 'active', label: tl('Active', 'Ativo') },\n { value: 'maintenance', label: tl('In maintenance', 'Em manutenção') },\n { value: 'inactive', label: tl('Retired', 'Inativo') },\n ],\n },\n // A SALA onde ele está. Aponta para o cadastro de Locais.\n { key: 'serviceLocationId', label: tl('Location', 'Local'), type: 'relation', showInTable: true, group: 'identity',\n relation: { table: 'v_units', labelField: 'name' } },\n { key: 'purchaseDate', label: tl('Purchase date', 'Data de compra'), type: 'date', showInTable: false, group: 'purchase' },\n { key: 'purchaseValue', label: tl('Purchase value', 'Valor de compra'), type: 'currency', showInTable: false, group: 'purchase' },\n { key: 'warrantyExpiration', label: tl('Warranty ends', 'Vencimento da garantia'), type: 'date', showInTable: false, group: 'purchase' },\n { key: 'lastMaintenanceDate', label: tl('Last maintenance', 'Última manutenção'), type: 'date', showInTable: false, group: 'maintenance' },\n // A COLUNA que justifica a lista: quem abre «Equipamentos» está quase\n // sempre perguntando o que vence agora.\n { key: 'nextMaintenanceDate', label: tl('Next maintenance', 'Próxima manutenção'), type: 'date', showInTable: true, group: 'maintenance' },\n { key: 'maintenanceNotes', label: tl('Maintenance notes', 'Notas de manutenção'), type: 'textarea', showInTable: false, group: 'maintenance', span: 2 },\n { key: 'description', label: tl('Description', 'Descrição'), type: 'textarea', showInTable: false, group: 'identity', span: 2 },\n ...recordRailFields({ tagsTable: 'products', activeLabel: tl('Active', 'Ativo') }),\n ],\n data: {\n table: 'products',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'asset' },\n defaults: { kind: 'asset' },\n searchColumns: ['name', 'sku'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Origins — category archetype, direct query\n// ---------------------------------------------------------------------------\nexport const originEntity: EntityDef = {\n name: tl('Origin', 'Origem'),\n namePlural: tl('Origins', 'Origens'),\n icon: 'Globe',\n displayField: 'name',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n { id: 'identity', label: tl('Identification', 'Identificação'), columns: 1 },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity' },\n // «SOLICITAR PESSOA» é uma regra que vale do OUTRO lado: ligada, escolher\n // esta origem no cadastro de cliente passa a exigir quem indicou. Sem ela,\n // «indicação de amigo» vira uma estatística sem nome nenhum atrás.\n {\n key: 'requiresPerson', label: tl('Ask who referred', 'Solicitar pessoa'), type: 'boolean',\n showInTable: true, defaultValue: false, group: 'identity',\n hint: tl(\n 'Choosing this origin on a client will require naming who referred them.',\n 'Escolher esta origem num cliente passa a exigir dizer quem indicou.',\n ),\n },\n // A DESCRIÇÃO da origem é a observação: `categories` não tem coluna\n // separada, e duas colunas para uma frase é invenção. Ela vai para a\n // lista porque é o que distingue «Indicação» de «Indicação de parceiro».\n ...recordRailFields({ tagsTable: 'categories', activeLabel: tl('Active', 'Ativo'), unit: false, notesInTable: true }),\n ],\n data: {\n table: 'categories',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'origin' },\n defaults: { kind: 'origin' },\n customFields: ['requiresPerson'],\n searchColumns: ['name'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Teams — category archetype, direct query\n// ---------------------------------------------------------------------------\n// O agrupamento da EQUIPE, irmão da categoria de serviço: mesma tabela, mesma\n// forma, outra espécie (`staff_team`, declarada pela 139 do espinha). Quem é\n// de qual equipe é escolha da ficha — ver `teamId` em `staffEntity`.\n//\n// Não confundir com `v_team_members`, que apesar do nome são os MEMBROS DO\n// TENANT (quem entra no sistema). Aqui é a ficha: a casa tem recepção e\n// estética antes de ter dois logins.\nexport const teamEntity: EntityDef = {\n name: tl('Team', 'Equipe'),\n namePlural: tl('Teams', 'Equipes'),\n icon: 'Users',\n displayField: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [{ ...RECORD_GROUP }],\n defaultSort: 'sortOrder',\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n // A cor é o que faz a equipe se reconhecer de relance na grade da semana e\n // no quadro — é o mesmo papel que ela tem na etiqueta.\n { key: 'color', label: tl('Colour', 'Cor'), type: 'color', showInTable: true },\n { key: 'sortOrder', label: tl('Order', 'Ordem'), type: 'number', showInTable: true, defaultValue: 0 },\n ...recordRailFields({ tagsTable: 'categories', activeLabel: tl('Active', 'Ativo'), unit: false }),\n ],\n data: {\n table: 'categories',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'staff_team' },\n defaults: { kind: 'staff_team' },\n searchColumns: ['name'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Service Categories — category archetype, direct query\n// ---------------------------------------------------------------------------\nexport const serviceCategoryEntity: EntityDef = {\n name: tl('Service Category', 'Categoria de Serviço'),\n namePlural: tl('Service Categories', 'Categorias de Serviço'),\n icon: 'Tag',\n displayField: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [{ ...RECORD_GROUP }],\n defaultSort: 'sortOrder',\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'sortOrder', label: tl('Order', 'Ordem'), type: 'number', showInTable: true, defaultValue: 0 },\n ...recordRailFields({ tagsTable: 'categories', activeLabel: tl('Active', 'Ativo'), unit: false }),\n ],\n data: {\n table: 'categories',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'service_category' },\n defaults: { kind: 'service_category' },\n },\n}\n\n// ---------------------------------------------------------------------------\n// Service Locations — location archetype, direct query\n// ---------------------------------------------------------------------------\n// ---------------------------------------------------------------------------\n// Locais — a SALA, cadeira ou box onde se atende, DENTRO de uma unidade.\n//\n// Isto é o «Local Operacional» do V1, e é o que esta tela sempre deveria ter\n// sido. Ela apontava para `v_units` — a FILIAL —, que já tem a própria tela em\n// Configurações → Unidades: duas telas para o prédio, nenhuma para a sala.\n//\n// A diferença importa porque uma sala não é uma unidade em miniatura: ela não\n// tem caixa, não tem estoque e não recorta permissão. O que ela tem é LOTAÇÃO,\n// e é por isso que ela existe — ver a migration 153.\n// ---------------------------------------------------------------------------\nexport const serviceLocationEntity: EntityDef = {\n name: tl('Location', 'Local'),\n namePlural: tl('Locations', 'Locais'),\n icon: 'MapPin',\n displayField: 'name',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n {\n id: 'identity', label: tl('The location', 'O local'), columns: 2,\n description: tl(\n 'Where you attend, inside a unit. Not a unit: no till, no stock, no permission of its own.',\n 'Onde se atende, dentro de uma unidade. Não é unidade: não tem caixa, não tem estoque e não recorta permissão.',\n ),\n },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity' },\n { key: 'code', label: tl('Code', 'Código'), type: 'text', showInTable: true, searchable: true, group: 'identity' },\n {\n key: 'groupId', label: tl('Group', 'Grupo'), type: 'relation', showInTable: true, group: 'identity',\n relation: { table: 'categories', labelField: 'name', filter: { kind: 'location_group' } },\n },\n // A LOTAÇÃO é o que impede a agenda de marcar cinco pessoas às 14h onde\n // cabem quatro. Sem ela o local é só um rótulo.\n {\n key: 'capacity', label: tl('Capacity', 'Máximo de clientes simultâneos'), type: 'number',\n min: 1, defaultValue: 1, showInTable: true, group: 'identity',\n hint: tl('One chair is 1. A tanning room with four beds is 4.', 'Uma cadeira é 1. Uma sala de bronzeamento com quatro macas é 4.'),\n },\n // A unidade vem do RAIL, com todos os outros «de quem é este registro» —\n // e obrigatória, porque um local sem prédio não existe.\n ...recordRailFields({ tagsTable: 'rooms', activeLabel: tl('Active', 'Ativo'), unitRequired: true }),\n ],\n data: {\n table: 'rooms',\n schema: 'public',\n tenantScoped: true,\n searchColumns: ['name', 'code'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Location Groups — category archetype, direct query\n// ---------------------------------------------------------------------------\nexport const locationGroupEntity: EntityDef = {\n name: tl('Location Group', 'Grupo de Locais'),\n namePlural: tl('Location Groups', 'Grupos de Locais'),\n icon: 'Map',\n displayField: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [{ ...RECORD_GROUP }],\n defaultSort: 'sortOrder',\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'sortOrder', label: tl('Order', 'Ordem'), type: 'number', showInTable: true, defaultValue: 0 },\n ...recordRailFields({ tagsTable: 'categories', activeLabel: tl('Active', 'Ativo'), unit: false }),\n ],\n data: {\n table: 'categories',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'location_group' },\n defaults: { kind: 'location_group' },\n searchColumns: ['name'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Services — service archetype, direct query on public.services\n// ---------------------------------------------------------------------------\nexport const serviceEntity: EntityDef = {\n name: tl('Service', 'Serviço'),\n namePlural: tl('Services', 'Serviços'),\n icon: 'Briefcase',\n layout: 'service',\n displayField: 'name',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n { id: 'identity', label: tl('Identification', 'Identificação'), columns: 2 },\n { id: 'pricing', label: tl('Price and time', 'Preço e tempo'), columns: 2 },\n {\n id: 'texts', label: tl('What the client reads', 'O que o cliente lê'), columns: 1,\n description: tl(\n 'Written once here, sent every time the service is booked or finished.',\n 'Escrito uma vez aqui, enviado toda vez que o serviço é marcado ou concluído.',\n ),\n },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Service name', 'Nome do serviço'), type: 'text', required: true, searchable: true, showInTable: true, group: 'identity', span: 2 },\n // O CÓDIGO INTERNO é como a casa chama o serviço na comanda e no relatório\n // — e é por ele que se procura quando o nome tem três variações.\n { key: 'internalCode', label: tl('Internal code', 'Código interno'), type: 'text', showInTable: true, searchable: true, group: 'identity' },\n { key: 'categoryId', label: tl('Category', 'Categoria'), type: 'relation', showInTable: true, group: 'identity',\n relation: { table: 'categories', labelField: 'name', filter: { kind: 'service_category' } } },\n // A COR identifica o serviço na grade da agenda, onde não cabe o nome.\n { key: 'color', label: tl('Colour', 'Cor'), type: 'color', showInTable: true, group: 'identity' },\n { key: 'description', label: tl('Description', 'Descrição'), type: 'textarea', showInTable: false, group: 'identity', span: 2 },\n\n { key: 'price', label: tl('Price', 'Preço'), type: 'currency', required: true, showInTable: true, group: 'pricing' },\n { key: 'durationMinutes', label: tl('Duration (min)', 'Duração (min)'), type: 'number', required: true, showInTable: true, group: 'pricing' },\n // VALIDADE em dias: quanto tempo o cliente tem para executar o que\n // comprou. É o que faz um pacote expirar, e sem ela ele nunca expira.\n { key: 'validityDays', label: tl('Validity (days)', 'Validade (dias)'), type: 'number', showInTable: false, group: 'pricing' },\n {\n key: 'isBookable', label: tl('Appears in the calendar', 'Aparece na agenda'), type: 'boolean',\n showInTable: true, defaultValue: true, group: 'pricing',\n hint: tl(\n 'Can be picked when booking an appointment. Turn off for what is sold in a package and never booked on its own.',\n 'Pode ser escolhido ao marcar um horário. Desligue para o que é vendido em pacote e nunca se marca sozinho.',\n ),\n },\n\n { key: 'schedulingAlertText', label: tl('Booking alert', 'Alertas para agendamento'), type: 'textarea', showInTable: false, group: 'texts' },\n { key: 'reminderText', label: tl('Reminder text', 'Texto do lembrete'), type: 'textarea', showInTable: false, group: 'texts' },\n { key: 'contractText', label: tl('Contract text', 'Texto para contrato'), type: 'textarea', showInTable: false, group: 'texts' },\n { key: 'postServiceText', label: tl('After-service text', 'Texto de pós-atendimento'), type: 'textarea', showInTable: false, group: 'texts' },\n\n ...recordRailFields({ tagsTable: 'services', activeLabel: tl('Active', 'Ativo') }),\n ],\n // Services are their own Ring-0 archetype table (public.services), not a\n // kind of product. Direct query by table+schema (no kind filter).\n data: {\n table: 'services',\n schema: 'public',\n tenantScoped: true,\n searchColumns: ['name'],\n // None of these is a column of `services`: the V1 import keeps them in metadata (colour in\n // `catalog.color`, which the agenda paints from). Without the map every save failed on a\n // missing column.\n metadataFields: {\n color: 'catalog.color',\n validityDays: 'catalog.validity_days',\n internalCode: 'internal_code',\n schedulingAlertText: 'beauty.scheduling_alert_text',\n reminderText: 'beauty.reminder_text',\n contractText: 'beauty.contract_text',\n postServiceText: 'beauty.post_service_text',\n },\n },\n}\n\n// ---------------------------------------------------------------------------\n// Profissões — categoria, o `professions` do V1\n// ---------------------------------------------------------------------------\nexport const professionEntity: EntityDef = {\n name: tl('Profession', 'Profissão'),\n namePlural: tl('Professions', 'Profissões'),\n icon: 'BriefcaseBusiness',\n displayField: 'name',\n defaultSort: 'sortOrder',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n {\n id: 'identity', label: tl('Identification', 'Identificação'), columns: 2,\n description: tl(\n 'The list the house keeps, so a rota does not depend on how someone typed it.',\n 'A lista que a casa mantém, para a escala não depender de como alguém digitou.',\n ),\n },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity', span: 2 },\n { key: 'sortOrder', label: tl('Order', 'Ordem'), type: 'number', showInTable: true, defaultValue: 0, group: 'identity' },\n ...recordRailFields({ tagsTable: 'categories', activeLabel: tl('Active', 'Ativo'), unit: false, notesInTable: true }),\n ],\n data: {\n table: 'categories',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'profession' },\n defaults: { kind: 'profession' },\n searchColumns: ['name'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// Espécies de pet — categoria, o `pet_species` do V1\n// ---------------------------------------------------------------------------\nexport const petSpeciesEntity: EntityDef = {\n name: tl('Species', 'Espécie'),\n namePlural: tl('Animal species', 'Tipos de animais'),\n icon: 'PawPrint',\n displayField: 'name',\n defaultSort: 'sortOrder',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n { id: 'identity', label: tl('Identification', 'Identificação'), columns: 2 },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity', span: 2 },\n // A ORDEM existe porque a espécie mais atendida tem de estar em cima: um\n // hotel para aves não quer «cachorro» na primeira posição.\n { key: 'sortOrder', label: tl('Order', 'Ordem'), type: 'number', showInTable: true, defaultValue: 0, group: 'identity' },\n ...recordRailFields({ tagsTable: 'categories', activeLabel: tl('Active', 'Ativo'), unit: false }),\n ],\n data: {\n table: 'categories',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'pet_species' },\n defaults: { kind: 'pet_species' },\n searchColumns: ['name'],\n },\n}\n\n\n// ---------------------------------------------------------------------------\n// Pacotes de serviço — o conjunto vendido junto\n// ---------------------------------------------------------------------------\n//\n// As tabelas (`service_packages`, `service_package_items`) vieram inteiras do\n// porte do V1 e nunca tiveram tela: o pacote existia no banco de toda conta\n// migrada e não havia por onde abri-lo. Isto é a porta.\n//\n// O ITEM é uma lista relacionada, não uma aba inventada: `package_id` já diz\n// a relação, e `RelatedList` monta dela a mesma tela de CRUD que o item teria\n// sozinho, filtrada pelo pacote de onde foi aberta.\n// ---------------------------------------------------------------------------\n\nconst servicePackageItemEntity: EntityDef = {\n name: tl('Item', 'Item'),\n namePlural: tl('Items', 'Serviços do pacote'),\n icon: 'ListChecks',\n displayField: 'productId',\n defaultSort: 'sortOrder',\n fields: [\n // O TIPO vem ANTES do item, como no V1: ele é quem decide de qual catálogo o\n // campo seguinte lê. Um pacote de estética vende sessão e vende o creme que\n // vai junto, e os dois moram em `products` com `kind` diferente.\n {\n key: 'itemType', label: tl('Type', 'Tipo'), type: 'select', required: true, defaultValue: 'service', showInTable: true,\n options: [\n { value: 'service', label: tl('Service', 'Serviço') },\n { value: 'product', label: tl('Product', 'Produto') },\n ],\n },\n {\n // `products` e não o espelho `public.services`: a 191 aposentou o espelho\n // e a FK da linha já aponta para `products`. Ler do espelho funcionava por\n // coincidência — mesmos ids — e devolveria zero no pool em que ele não foi\n // criado.\n //\n // O recorte vem do «Tipo» ao lado (`filterFrom`), e `product` da tela é\n // `good` na coluna — o vocabulário do V1 de um lado, o do catálogo do\n // outro. `priceField` põe o preço à direita de cada opção: escolher entre\n // dois serviços num pacote é escolher também entre dois preços.\n key: 'productId', label: tl('Package item', 'Item do pacote'), type: 'relation', required: true, showInTable: true,\n relation: {\n table: 'products',\n labelField: 'name',\n priceField: 'price',\n filterFrom: { kind: { field: 'itemType', map: { service: 'service', product: 'good' } } },\n },\n },\n // QUANTAS VEZES este serviço entra no pacote. «10 sessões de drenagem» é\n // uma linha com quantidade 10, não dez linhas.\n { key: 'quantity', label: tl('Quantity', 'Quantidade'), type: 'number', min: 1, defaultValue: 1, showInTable: true },\n // ── OS DOIS PREÇOS, que é o que faz um pacote ser um pacote ────────────\n //\n // O de TABELA é a base da comissão do profissional e o lado esquerdo da\n // economia; o DO PACOTE é o que o cliente paga por esta linha, e a soma\n // deles é o preço do pacote (a 166 mantém isso no banco).\n //\n // Separados porque o desconto não cai igual em todo serviço: a casa decide\n // qual linha o absorve, e com um preço só esse desconto vira regra de três.\n // Os dois nascem com o preço de tabela do que foi escolhido ao lado (o\n // trigger da 166 faz o mesmo no banco, para quem insere por outra porta):\n // começar em zero obriga a redigitar o que o catálogo já sabe, e uma linha\n // esquecida em zero não cobra nada e não paga comissão nenhuma.\n {\n key: 'unitPrice', label: tl('List price', 'Valor unit.'), type: 'currency', defaultValue: 0, showInTable: true,\n fillFrom: { field: 'productId', source: 'price' },\n hint: tl('Base for the commission. Zero pays none.', 'Base da comissão. Zero não paga comissão.'),\n },\n {\n key: 'packagePrice', label: tl('In-package price', 'Valor no pacote'), type: 'currency', defaultValue: 0, showInTable: true,\n fillFrom: { field: 'productId', source: 'price' },\n hint: tl('What the client pays for this line.', 'O que o cliente paga por esta linha.'),\n },\n // Só a casa que emite nota por CONSUMO precisa separá-lo; vazio usa o do\n // pacote.\n { key: 'fiscalUnitPrice', label: tl('Fiscal unit price', 'Valor unit. fiscal'), type: 'currency', showInTable: true },\n { key: 'sortOrder', label: tl('Order', 'Ordem'), type: 'number', defaultValue: 0, showInTable: false },\n ],\n data: { table: 'service_package_items', schema: 'public', tenantScoped: true },\n}\n\nexport const servicePackageEntity: EntityDef = {\n name: tl('Package', 'Pacote'),\n namePlural: tl('Packages', 'Pacotes'),\n icon: 'PackageCheck',\n duplicable: true,\n displayField: 'name',\n defaultSort: 'name',\n formColumns: 2,\n facets: [ACTIVE_FACET],\n fieldGroups: [\n { id: 'identity', label: tl('Identification', 'Identificação'), columns: 1 },\n {\n id: 'pricing', label: tl('Price and validity', 'Preço e validade'), columns: 2,\n description: tl(\n 'What the client pays once, and until when they can use it.',\n 'O que o cliente paga de uma vez, e até quando pode usar.',\n ),\n },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true, group: 'identity' },\n { key: 'description', label: tl('Description', 'Descrição'), type: 'textarea', showInTable: false, group: 'identity' },\n // O recibo sai sem o valor — pacote de cortesia, ou cliente que não quer o\n // preço impresso no papel que leva para casa.\n { key: 'hideValueOnReceipt', label: tl('Hide value on the receipt', 'Não exibir valor no recibo'), type: 'boolean', defaultValue: false, showInTable: false, group: 'identity' },\n // O PREÇO É A SOMA DAS LINHAS quando há linhas: a 166 o mantém assim no\n // banco, pelo mesmo motivo do V1 — dois números para a mesma coisa só\n // sobrevivem se ninguém puder escrever um sem o outro. Digitável porque o\n // pacote SEM itens é um bloco solto de sessões, e aí ele é a única resposta.\n {\n // SEM `required`: com serviços listados abaixo este campo é a SOMA deles\n // (a 166 a mantém no banco), e cobrar que alguém digite um número que o\n // formulário vai descartar trava o cadastro na própria resposta certa.\n // `defaultValue: 0` e não vazio: a coluna é NOT NULL, e um campo de\n // dinheiro em que ninguém tocou chegava ao banco como `null` — o cadastro\n // morria num erro de constraint falando de uma coluna que a tela nem pediu.\n key: 'price', label: tl('Price', 'Preço'), type: 'currency', defaultValue: 0, showInTable: true, group: 'pricing',\n hint: tl(\n 'With services listed below, this is their sum.',\n 'Com serviços listados abaixo, este é a soma deles.',\n ),\n },\n // DERIVADO — quanto o pacote tira do preço de tabela. Só leitura: quem o\n // muda é a linha, não este campo.\n { key: 'discountPercentage', label: tl('Discount (%)', 'Desconto (%)'), type: 'number', showInTable: true, showInForm: false, group: 'pricing' },\n // O TOTAL DE SESSÕES é o que o cliente comprou; os itens dizem de QUÊ.\n // Os dois existem porque um pacote pode vender «10 sessões» escolhendo o\n // serviço na hora, e outro pode listar exatamente o que entra.\n { key: 'sessionsTotal', label: tl('Sessions', 'Total de sessões'), type: 'number', min: 1, showInTable: true, group: 'pricing' },\n // A VALIDADE É UMA ESCOLHA, não um campo vazio: «nunca vence» e «ainda não\n // preenchi» são respostas diferentes, e só o interruptor as separa.\n { key: 'validityEnabled', label: tl('Expires', 'Ativar validade'), type: 'boolean', defaultValue: false, showInTable: false, group: 'pricing' },\n {\n key: 'validityMonths', label: tl('Valid for (months)', 'Válido por (meses)'), type: 'number', min: 1, showInTable: true, group: 'pricing',\n hint: tl('Counted from the sale.', 'Contados a partir da venda.'),\n },\n // Quanto o vendedor ganha por vender ESTE pacote — diferente da comissão\n // de executar cada sessão, que sai do valor de tabela da linha.\n { key: 'commissionPercent', label: tl('Sales commission (%)', '% de comissão sobre venda'), type: 'number', min: 0, max: 100, defaultValue: 0, showInTable: false, group: 'pricing' },\n // Sem isto o balcão não tem como fechar um pacote com o desconto que o\n // dono autorizou de boca.\n { key: 'allowPriceEditOnSale', label: tl('Price can be edited at sale time', 'Permitir edição do valor na hora da venda'), type: 'boolean', defaultValue: false, showInTable: false, group: 'pricing' },\n ...recordRailFields({ tagsTable: 'service_packages', activeLabel: tl('Active', 'Ativo') }),\n ],\n // SEÇÃO, e não aba: o que entra no pacote é a definição dele, não um assunto\n // ao lado. Como aba, montar um pacote de três serviços era abrir a aba, abrir\n // uma sub-página por linha e voltar três vezes — e a página de edição do\n // pacote, que é onde se decide, não mostrava nada do que ele contém.\n //\n // `grid` porque a linha tem três respostas e todas se corrigem o tempo todo:\n // é a grade «Itens do Pacote» do V1, editável onde é lida.\n relatedSections: [\n { id: 'package-services', entity: servicePackageItemEntity, foreignKey: 'packageId', icon: 'ListChecks', display: 'grid',\n // Same service twice with different in-package prices is a real package\n // (e.g. first session full price, the rest discounted).\n duplicable: true,\n emptyHint: tl(\n 'No service in this package yet — it will be sold as a loose block of sessions.',\n 'Nenhum serviço neste pacote ainda — ele será vendido como um bloco solto de sessões.',\n ),\n // Os dois totais lado a lado são a decisão do pacote: o da esquerda é o\n // que custaria avulso, o da direita é o que o cliente paga. A distância\n // entre eles é a oferta.\n footer: (rows) => {\n const money = (v: number) => {\n try { return new Intl.NumberFormat(undefined, { style: 'currency', currency: 'BRL' }).format(v) }\n catch { return v.toFixed(2) }\n }\n const soma = (key: string) => rows.reduce(\n (total, r) => total + (Number(r[key]) || 0) * (Number(r.quantity) || 0), 0,\n )\n return [\n { label: tl('Items total', 'Total em itens'), value: money(soma('unitPrice')) },\n { label: tl('In package', 'No pacote'), value: money(soma('packagePrice')), tone: 'positive' as const },\n ]\n },\n },\n ],\n data: {\n table: 'service_packages',\n schema: 'public',\n tenantScoped: true,\n searchColumns: ['name'],\n },\n}\n","import React from 'react'\nimport type { EntityDef } from '@fayz-ai/core'\nimport { RelatedListTab } from '@fayz-ai/admin'\nimport { serviceLocationEntity } from '../lib/entities'\n\n/**\n * \"Locais Operacionais\" of the V1 company form: the rooms of THIS unit, with the\n * same create/edit as Cadastros → Locais. The unit comes from the parent, so the\n * rail field is dropped by RelatedListTab and every new room is born here.\n */\nexport function UnitRoomsWidget({ item }: { item?: { id?: string } }) {\n if (!item?.id) return null\n return (\n <RelatedListTab\n item={item}\n entityDef={serviceLocationEntity as EntityDef}\n parentTabId=\"locations\"\n related={{\n id: 'rooms', label: 'Locais operacionais', entity: serviceLocationEntity, foreignKey: 'unitId',\n emptyHint: 'Nenhuma sala, cadeira ou box nesta unidade ainda. Sem elas a agenda não sabe onde cabe cada atendimento.',\n }}\n />\n )\n}\n","import { tl, getSupabaseClientOptional } from '@fayz-ai/core'\nimport { createArchetypeLookup, type EntityLookup, type EntityLookupLine, type EntityLookupManage, type EntityLookupResult } from '@fayz-ai/admin'\nimport type { EntityDef } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// O PACOTE COMO LINHA DE DOCUMENTO.\n//\n// O cadastro do pacote é uma coisa; vendê-lo é outra. Uma conta a receber\n// pergunta o TIPO da linha — Produto, Serviço, Outro — e o pacote é um quarto\n// tipo com catálogo próprio: `service_packages`, não `products`. Sem esta\n// busca, quem vende «10 sessões de drenagem» digita o nome à mão e o preço de\n// cabeça, e o mesmo pacote entra com três nomes e três preços.\n//\n// Não há arquétipo de pacote — nem deveria haver, porque a tabela não é da\n// espinha de catálogo. O que isto reaproveita do arquétipo de produto é só a\n// MECÂNICA: busca, contagem, cadastro rápido e cache por conta. A origem, os\n// campos e o formulário vêm daqui.\n//\n// A contagem é o que faz o tipo SUMIR na casa que não vende pacote (ver\n// useStockedItemTypes no financeiro): o restaurante recebe a opção junto com o\n// plugin e nunca a vê, porque `service_packages` dele tem zero linhas.\n// ---------------------------------------------------------------------------\n\n/** O cadastro rápido, em COLUNAS da tabela — ele escreve direto, sem a camada\n * camelCase do provider. Só o que faz um pacote existir: nome, preço e\n * quantas sessões ele vale. */\nconst quickCreateDef: EntityDef = {\n name: tl('Package', 'Pacote'),\n namePlural: tl('Packages', 'Pacotes'),\n icon: 'PackageCheck',\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true },\n { key: 'price', label: tl('Price', 'Preço'), type: 'currency', required: true },\n { key: 'sessions_total', label: tl('Sessions', 'Total de sessões'), type: 'number', min: 1 },\n {\n key: 'validity_months', label: tl('Valid for (months)', 'Válido por (meses)'), type: 'number', min: 1,\n hint: tl('Empty means it never expires.', 'Vazio significa que nunca vence.'),\n },\n ],\n}\n\nconst cents = (v: number) => Math.round(v * 100)\n\n/** Uma linha do pacote, já com os dois preços que a 166 trouxe. */\ntype Membro = {\n packageId: string\n productId: string\n quantity: number\n /** O valor de tabela — base da comissão. */\n unitPrice: number\n /** Quanto ele vale DENTRO do pacote — o que o cliente paga. */\n packagePrice: number\n}\n\nasync function membersOf(packageIds: string[]): Promise<Map<string, Membro[]>> {\n const out = new Map<string, Membro[]>()\n const supabase = getSupabaseClientOptional() as any\n if (!supabase || !packageIds.length) return out\n const { data } = await supabase\n .from('service_package_items')\n .select('package_id, product_id, quantity, unit_price, package_price, sort_order')\n .in('package_id', packageIds)\n .order('sort_order', { ascending: true })\n for (const row of (data ?? []) as any[]) {\n const key = String(row.package_id)\n const list = out.get(key) ?? []\n list.push({\n packageId: key,\n productId: String(row.product_id),\n quantity: Number(row.quantity) || 1,\n unitPrice: Number(row.unit_price) || 0,\n packagePrice: Number(row.package_price) || 0,\n })\n out.set(key, list)\n }\n return out\n}\n\nasync function productsById(ids: string[]): Promise<Map<string, { name: string; price: number }>> {\n const out = new Map<string, { name: string; price: number }>()\n const supabase = getSupabaseClientOptional() as any\n if (!supabase || !ids.length) return out\n const { data } = await supabase.from('products').select('id, name, price').in('id', ids)\n for (const p of (data ?? []) as any[]) {\n out.set(String(p.id), { name: String(p.name ?? ''), price: Number(p.price) || 0 })\n }\n return out\n}\n\nfunction money(value: number, currency: string): string {\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(value)\n } catch {\n return value.toFixed(2)\n }\n}\n\n// ---------------------------------------------------------------------------\n// O QUE TEM DENTRO, NA HORA DE ESCOLHER.\n//\n// O V1 não oferece pacote numa lista de nomes: ele mostra um cartão com o que\n// entra («10x Psicoterapia») e os dois preços — o de tabela riscado e o do\n// pacote. Os dois são a decisão: sem o conteúdo não dá para saber o que se está\n// vendendo, e sem a comparação não dá para dizer ao cliente quanto ele economiza.\n//\n// Aqui isso vira o SUBTÍTULO da opção, que é onde esta tela tem espaço. Uma\n// consulta para os itens de todos os pacotes da lista e outra para os nomes —\n// duas, e não duas por pacote.\n// ---------------------------------------------------------------------------\nasync function describe(rows: EntityLookupResult[]): Promise<EntityLookupResult[]> {\n if (!rows.length) return rows\n const membros = await membersOf(rows.map((r) => r.id))\n const todos = [...new Set([...membros.values()].flat().map((m) => m.productId))]\n const produtos = await productsById(todos)\n\n return rows.map((row) => {\n const lista = membros.get(row.id) ?? []\n if (!lista.length) return row\n const partes = lista.map((m) => {\n const p = produtos.get(m.productId)\n // Serviço que saiu do catálogo depois de entrar no pacote: o V1 escreve\n // «Serviço não encontrado» em vez de omitir a linha, e está certo — some\n // dali o aviso de que o pacote precisa de conserto.\n return `${m.quantity}x ${p?.name || tl('Service not found', 'Serviço não encontrado')}`\n })\n const tabela = lista.reduce(\n (s, m) => s + m.quantity * (m.unitPrice || produtos.get(m.productId)?.price || 0),\n 0,\n )\n const preco = row.price ?? 0\n const moeda = String((row.data as Record<string, unknown> | undefined)?.currency ?? 'BRL')\n const resumo = partes.length > 3 ? [...partes.slice(0, 3), `+${partes.length - 3}`] : partes\n const economia = tabela > preco ? ` · ${money(tabela, moeda)} → ${money(preco, moeda)}` : ''\n return { ...row, subtitle: `${resumo.join(' · ')}${economia}` }\n })\n}\n\n// ---------------------------------------------------------------------------\n// O preço do pacote repartido entre os serviços dele — SÓ quando ele não disse.\n//\n// Desde a 166 cada linha carrega `package_price`: a casa decide quanto cada\n// serviço vale dentro do pacote, e vender é só copiar esses números. O rateio\n// abaixo é o caminho de trás, para a linha que ainda não tem preço — pacote\n// cadastrado antes da 166 e nunca reaberto.\n//\n// O arredondamento sobra: dez linhas de centavos quebrados não somam de volta\n// ao preço do pacote. O resto vai inteiro para a PRIMEIRA linha, como desconto\n// ou acréscimo, porque o que não pode fechar errado é o total.\n// ---------------------------------------------------------------------------\nfunction split(\n packagePrice: number,\n lines: Array<{ referenceId: string; description: string; quantity: number; catalogPrice: number }>,\n): EntityLookupLine[] {\n const weights = lines.map((l) => l.quantity * l.catalogPrice)\n const totalWeight = weights.reduce((s, w) => s + w, 0)\n // Catálogo sem preço (ou tudo zerado) divide por quantidade: é a única outra\n // resposta possível, e é melhor que jogar o pacote inteiro na primeira linha.\n const fallback = lines.map((l) => l.quantity)\n const totalFallback = fallback.reduce((s, w) => s + w, 0)\n const use = totalWeight > 0 ? weights : fallback\n const total = totalWeight > 0 ? totalWeight : totalFallback\n if (total <= 0) return []\n\n const out: EntityLookupLine[] = lines.map((l, i) => {\n const share = (packagePrice * use[i]!) / total\n return {\n referenceId: l.referenceId,\n description: l.description,\n quantity: l.quantity,\n unitPrice: Math.round((share / l.quantity) * 100) / 100,\n itemKind: 'service',\n }\n })\n\n const sobra = cents(packagePrice) - out.reduce((s, l) => s + cents(l.unitPrice * l.quantity), 0)\n if (sobra !== 0 && out[0]) {\n out[0] = sobra > 0\n ? { ...out[0], surcharge: sobra / 100 }\n : { ...out[0], discount: -sobra / 100 }\n }\n return out\n}\n\n/** Os serviços de um pacote, com o que o cliente paga por cada um. */\nasync function expandPackage(packageId: string): Promise<EntityLookupLine[]> {\n const supabase = getSupabaseClientOptional() as any\n if (!supabase) return []\n\n const { data: pkg } = await supabase\n .from('service_packages')\n .select('id, name, price')\n .eq('id', packageId)\n .maybeSingle()\n if (!pkg) return []\n\n const membros = (await membersOf([packageId])).get(packageId) ?? []\n // Pacote que não declara o que entra nele continua sendo UMA linha: o nome do\n // pacote é tudo que se sabe, e inventar serviço nenhum é a resposta certa.\n if (!membros.length) return []\n\n const produtos = await productsById(membros.map((m) => m.productId))\n const base = membros\n .map((m) => {\n const produto = produtos.get(m.productId)\n if (!produto) return null\n return { ...m, name: produto.name, catalogPrice: produto.price }\n })\n .filter(Boolean) as Array<Membro & { name: string; catalogPrice: number }>\n if (!base.length) return []\n\n const metadata = (m: Membro) => ({\n packageId: String(pkg.id),\n packageName: String(pkg.name ?? ''),\n // A base da COMISSÃO viaja com a linha: o que o cliente paga é o preço do\n // pacote, e o que o profissional recebe sai do valor de tabela.\n listUnitPrice: m.unitPrice,\n })\n\n // O caminho normal: a casa já disse quanto cada serviço vale aqui dentro.\n if (base.some((m) => m.packagePrice > 0)) {\n return base.map((m) => ({\n referenceId: m.productId,\n description: m.name,\n quantity: m.quantity,\n unitPrice: m.packagePrice,\n itemKind: 'service',\n metadata: metadata(m),\n }))\n }\n\n // Linha anterior à 166: reparte o preço do pacote, como antes.\n return split(\n Number(pkg.price) || 0,\n base.map((m) => ({\n referenceId: m.productId,\n description: m.name,\n quantity: m.quantity,\n catalogPrice: m.unitPrice || m.catalogPrice,\n })),\n ).map((l, i) => ({ ...l, metadata: metadata(base[i]!) }))\n}\n\n/** A busca de pacotes de serviço, para `entityLookups.package`. */\nexport function createServicePackageLookup(options: { manage?: EntityLookupManage } = {}): EntityLookup {\n const base = createArchetypeLookup({\n archetype: 'product',\n manage: options.manage,\n table: 'service_packages',\n subtitleFields: ['description'],\n searchFields: ['name', 'description'],\n entityDef: quickCreateDef,\n })\n return {\n ...base,\n expand: expandPackage,\n search: async (query: string) => describe(await base.search(query)),\n list: base.list ? async () => describe(await base.list!()) : undefined,\n }\n}\n","import type { PluginManifest, PluginScope, VerticalId, EntityDef } from '@fayz-ai/core'\nimport { Briefcase, Map, MapPin, PackageCheck, Tag, UserCog, Users } from 'lucide-react'\nimport { adminNavigateTo, createCrudPage, UNIT_DETAIL_ZONES, type CrudNavTab } from '@fayz-ai/admin'\nimport type React from 'react'\nimport { UnitRoomsWidget } from './views/UnitRoomsWidget'\n\nimport {\n staffEntity, supplierEntity, contactEntity, partnershipEntity, equipmentEntity,\n originEntity, serviceCategoryEntity, serviceLocationEntity, locationGroupEntity,\n professionEntity, petSpeciesEntity, servicePackageEntity,\n serviceEntity, teamEntity,\n} from './lib/entities'\n\n// ---------------------------------------------------------------------------\n// plugin-registry — os Cadastros.\n// ---------------------------------------------------------------------------\n// ── O buraco que ele fecha ─────────────────────────────────────────────────\n// O aplicativo central carrega o ofício de quem entra, e para o Espaço Facial\n// ele carregava tudo MENOS os Cadastros: a rubrica não desenhava porque as dez\n// telas dela não existiam ali. Elas estavam escritas dentro do beauty-saas, em\n// `src/config/pages.tsx` — um aplicativo só, e portanto uma conta só.\n//\n// Era o mesmo defeito que o preset resolveu para a ORDEM e a 118 para o NOME,\n// um degrau abaixo: não adianta o ofício saber agrupar e nomear se ninguém\n// serve a tela. Quem serve tela é plugin.\n//\n// ── Por que um plugin, e não mais uma pasta no aplicativo ──────────────────\n// Nenhuma destas fichas é de salão. Fornecedor, contato, equipamento, origem e\n// filial são o que QUALQUER casa cadastra; o restaurante compra de fornecedor\n// e a escola registra origem de matrícula. O que muda por ofício é o nome da\n// linha no menu — \"Funcionários\" no BeautySoft, \"Equipe\" no resto — e disso\n// cuida o `labels` do preset, no banco.\n//\n// ── O ofício liga o que usa ────────────────────────────────────────────────\n// `modules` desliga tela a tela: uma loja sem atendimento não quer Serviços\n// nem Categorias de Serviço, e uma rubrica cujos filhos saíram todos não\n// desenha. É o mesmo contrato dos outros plugins — oferecer, não impor.\n// ---------------------------------------------------------------------------\n\n/** Cada tela de cadastro, na ORDEM em que o menu as lê por padrão. */\nconst SCREENS = [\n { id: 'services', path: '/registry/services', entity: serviceEntity, icon: 'Briefcase', feature: 'services' },\n { id: 'serviceCategories', path: '/registry/categories', entity: serviceCategoryEntity, icon: 'Tag', feature: 'services', nested: true },\n // O pacote é catálogo como o serviço — aninhado nele, porque é um jeito de\n // vender serviço e não um assunto novo no menu.\n { id: 'servicePackages', path: '/registry/service-packages', entity: servicePackageEntity, icon: 'PackageCheck', feature: 'services', nested: true },\n { id: 'locations', path: '/registry/locations', entity: serviceLocationEntity, icon: 'MapPin', feature: 'services' },\n // A SALA, aninhada na unidade: ela é onde se atende dentro do prédio, e uma\n // linha solta no menu ao lado de «Unidades» repetiria a confusão que a 153\n // acabou de desfazer.\n { id: 'locationGroups', path: '/registry/location-groups', entity: locationGroupEntity, icon: 'Map', feature: 'services', nested: true },\n { id: 'staff', path: '/registry/staff', entity: staffEntity, icon: 'UserCog' },\n { id: 'teams', path: '/registry/teams', entity: teamEntity, icon: 'Users', nested: true },\n // Aninhada em Profissionais: a profissão é o vocabulário DELES, e uma linha\n // solta no menu para uma lista de cinco palavras custa mais do que vale.\n { id: 'professions', path: '/registry/professions', entity: professionEntity, icon: 'BriefcaseBusiness', nested: true },\n { id: 'contacts', path: '/registry/contacts', entity: contactEntity, icon: 'Contact' },\n { id: 'suppliers', path: '/registry/suppliers', entity: supplierEntity, icon: 'Building2' },\n { id: 'partnerships', path: '/registry/partnerships', entity: partnershipEntity, icon: 'Handshake' },\n { id: 'equipment', path: '/registry/equipment', entity: equipmentEntity, icon: 'Wrench' },\n { id: 'origins', path: '/registry/origins', entity: originEntity, icon: 'Globe' },\n // Só faz sentido em casa que atende pet — ver OPT_IN.\n { id: 'petSpecies', path: '/registry/pet-species', entity: petSpeciesEntity, icon: 'PawPrint', feature: 'pets' },\n] as const\n\nexport type RegistryScreenId = (typeof SCREENS)[number]['id']\n\n// ---------------------------------------------------------------------------\n// AS TELAS QUE NASCEM DESLIGADAS.\n//\n// A regra do `modules` é «ausente = tem», e ela está certa para o cadastro que\n// qualquer casa reconhece: publicar uma ficha nova não pode ser o dia em que\n// ela some de toda conta que não a listou.\n//\n// Só que \"Tipos de animais\" não é uma ficha que qualquer casa reconhece — é o\n// vocabulário de UM ofício. Nascendo ligada, ela apareceu em Cadastros do\n// restaurante, do salão, da clínica, da escola e da bilheteria, e em nenhuma\n// delas alguém vai cadastrar «cachorro». O padrão certo para a tela de um\n// ofício é o contrário: quem a quer, pede.\n//\n// `modules: { petSpecies: true }` liga — é o que o ofício de pet passa, do\n// mesmo jeito que hoje uma loja passa `services: false`.\n// ---------------------------------------------------------------------------\nconst OPT_IN = new Set<RegistryScreenId>(['petSpecies'])\n\nconst serviceTabs = (): CrudNavTab[] => [\n { id: 'services', label: serviceEntity.namePlural ?? serviceEntity.name, icon: Briefcase, onSelect: () => adminNavigateTo('/registry/services') },\n { id: 'serviceCategories', label: serviceCategoryEntity.namePlural ?? serviceCategoryEntity.name, icon: Tag, onSelect: () => adminNavigateTo('/registry/categories') },\n // A tela do pacote existia e não tinha porta: a rota estava registrada, a\n // ficha também, e nenhuma faixa de aba a listava. Esta linha é a porta.\n { id: 'servicePackages', label: servicePackageEntity.namePlural ?? servicePackageEntity.name, icon: PackageCheck, onSelect: () => adminNavigateTo('/registry/service-packages') },\n]\n\nconst staffTabs = (): CrudNavTab[] => [\n { id: 'staff', label: staffEntity.namePlural ?? staffEntity.name, icon: UserCog, onSelect: () => adminNavigateTo('/registry/staff') },\n { id: 'teams', label: teamEntity.namePlural ?? teamEntity.name, icon: Users, onSelect: () => adminNavigateTo('/registry/teams') },\n]\n\nconst locationTabs = (): CrudNavTab[] => [\n { id: 'locations', label: serviceLocationEntity.namePlural ?? serviceLocationEntity.name, icon: MapPin, onSelect: () => adminNavigateTo('/registry/locations') },\n { id: 'locationGroups', label: locationGroupEntity.namePlural ?? locationGroupEntity.name, icon: Map, onSelect: () => adminNavigateTo('/registry/location-groups') },\n]\n\nexport interface RegistryPluginOptions {\n scope?: PluginScope\n verticalId?: VerticalId\n /** Onde a primeira linha cai no rail. As demais vêm em degraus de 0,1. */\n navPosition?: number\n navSection?: 'main' | 'secondary' | 'settings'\n /**\n * Quais telas esta casa tem. Ausente = todas, menos as de ofício.\n *\n * `false` é a única forma de negar: uma chave que ninguém respondeu cai no\n * padrão, não em \"não\" — do contrário, publicar uma ficha nova seria o dia\n * em que ela some de toda conta que não a listou.\n *\n * A exceção é a tela que só um ofício reconhece (ver `OPT_IN`): essa nasce\n * desligada, e `true` é o que a liga.\n */\n modules?: Partial<Record<RegistryScreenId, boolean>>\n /**\n * Troca a definição de uma ficha sem trocar a tela.\n *\n * A casa que precisa de um campo a mais no fornecedor passa o EntityDef dela\n * aqui em vez de reimplementar a rota — que foi exatamente como as dez\n * acabaram dentro de um aplicativo.\n */\n entities?: Partial<Record<RegistryScreenId, EntityDef>>\n /**\n * Permission feature that gates a screen (route, rail line and CRUD actions).\n * Most screens ship ungated, so every role sees them; an app whose roles split\n * by these registries names the feature here. `null` removes a default gate.\n */\n features?: Partial<Record<RegistryScreenId, string | null>>\n}\n\nexport function createRegistryPlugin(options?: RegistryPluginOptions): PluginManifest {\n const section = options?.navSection ?? 'main'\n const base = options?.navPosition ?? 80\n\n const active = SCREENS.filter((screen) => (\n OPT_IN.has(screen.id)\n ? options?.modules?.[screen.id] === true\n : options?.modules?.[screen.id] !== false\n ))\n\n const pages = active.map((screen, index) => {\n const entity = options?.entities?.[screen.id] ?? (screen.entity as EntityDef)\n const override = options?.features?.[screen.id]\n const feature = override === undefined ? (screen as { feature?: string }).feature : (override ?? undefined)\n const grouped = screen.id === 'services' || screen.id === 'serviceCategories' || screen.id === 'servicePackages'\n ? { navTabs: serviceTabs, activeNavTab: screen.id }\n : screen.id === 'locations' || screen.id === 'locationGroups'\n ? { navTabs: locationTabs, activeNavTab: screen.id }\n : screen.id === 'staff' || screen.id === 'teams'\n ? { navTabs: staffTabs, activeNavTab: screen.id }\n : {}\n return {\n screen,\n entity,\n position: base + index * 0.1,\n component: createCrudPage(entity, { ...(feature ? { feature } : {}), ...grouped }),\n permission: feature ? { feature, action: 'read' as const } : undefined,\n }\n })\n\n return {\n id: 'registry',\n name: 'Cadastros',\n icon: 'ClipboardList',\n version: '1.0.0',\n scope: options?.scope ?? 'universal',\n verticalId: options?.verticalId,\n defaultEnabled: true,\n dependencies: [],\n\n // Uma linha por ficha, plana. Quem as junta sob \"Cadastros\" — e em que\n // ordem, e com que nome — é o `rail` do ofício. Ver packages/admin\n // rail-preset.ts: o ofício AGRUPA, o plugin NOMEIA, e o `labels` do preset\n // é a casa dizendo que ali a ficha se chama outra coisa.\n navigation: pages.filter((page) => !('nested' in page.screen && page.screen.nested)).map((page) => ({\n section,\n position: page.position,\n label: page.entity.namePlural ?? page.entity.name,\n route: page.screen.path,\n icon: page.screen.icon,\n ...(page.permission ? { permission: page.permission } : {}),\n })),\n\n widgets: [\n {\n id: 'registry-unit-rooms',\n zone: UNIT_DETAIL_ZONES.rooms,\n component: UnitRoomsWidget as unknown as React.ComponentType<unknown>,\n order: 0,\n },\n ],\n routes: pages.map((page) => ({\n path: page.screen.path,\n component: page.component as React.ComponentType<unknown>,\n title: page.entity.namePlural ?? page.entity.name,\n ...(page.permission ? { permission: page.permission } : {}),\n })),\n }\n}\n\nexport {\n staffEntity, supplierEntity, contactEntity, partnershipEntity, equipmentEntity,\n originEntity, serviceCategoryEntity, serviceLocationEntity, locationGroupEntity,\n professionEntity, petSpeciesEntity, servicePackageEntity,\n serviceEntity, teamEntity,\n} from './lib/entities'\n\nexport { createServicePackageLookup } from './lib/package-lookup'\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/lib/entities.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAsB9C,eAAO,MAAM,WAAW,EAAE,SAuGzB,CAAA;AAKD,eAAO,MAAM,cAAc,EAAE,SAyD5B,CAAA;AAKD,eAAO,MAAM,aAAa,EAAE,SAkC3B,CAAA;AAKD,eAAO,MAAM,iBAAiB,EAAE,SA8C/B,CAAA;AAKD,eAAO,MAAM,eAAe,EAAE,SA0D7B,CAAA;AAKD,eAAO,MAAM,YAAY,EAAE,SAuC1B,CAAA;AAYD,eAAO,MAAM,UAAU,EAAE,SAyBxB,CAAA;AAKD,eAAO,MAAM,qBAAqB,EAAE,SAqBnC,CAAA;AAgBD,eAAO,MAAM,qBAAqB,EAAE,SA0CnC,CAAA;AAKD,eAAO,MAAM,mBAAmB,EAAE,SAsBjC,CAAA;AAKD,eAAO,MAAM,aAAa,EAAE,SA6D3B,CAAA;AAKD,eAAO,MAAM,gBAAgB,EAAE,SA+B9B,CAAA;AAKD,eAAO,MAAM,gBAAgB,EAAE,SA2B9B,CAAA;AAoFD,eAAO,MAAM,oBAAoB,EAAE,SAyGlC,CAAA"}
1
+ {"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/lib/entities.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAsB9C,eAAO,MAAM,WAAW,EAAE,SAuGzB,CAAA;AAKD,eAAO,MAAM,cAAc,EAAE,SAyD5B,CAAA;AAKD,eAAO,MAAM,aAAa,EAAE,SAkC3B,CAAA;AAKD,eAAO,MAAM,iBAAiB,EAAE,SA8C/B,CAAA;AAKD,eAAO,MAAM,eAAe,EAAE,SA0D7B,CAAA;AAKD,eAAO,MAAM,YAAY,EAAE,SAuC1B,CAAA;AAYD,eAAO,MAAM,UAAU,EAAE,SAyBxB,CAAA;AAKD,eAAO,MAAM,qBAAqB,EAAE,SAqBnC,CAAA;AAgBD,eAAO,MAAM,qBAAqB,EAAE,SA0CnC,CAAA;AAKD,eAAO,MAAM,mBAAmB,EAAE,SAsBjC,CAAA;AAKD,eAAO,MAAM,aAAa,EAAE,SAyE3B,CAAA;AAKD,eAAO,MAAM,gBAAgB,EAAE,SA+B9B,CAAA;AAKD,eAAO,MAAM,gBAAgB,EAAE,SA2B9B,CAAA;AAoFD,eAAO,MAAM,oBAAoB,EAAE,SAyGlC,CAAA"}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "status": "beta",
5
5
  "dependencies": []
6
6
  },
7
- "version": "0.16.1",
7
+ "version": "0.17.1",
8
8
  "description": "Fayz SDK — os Cadastros: as telas de referência que todo ofício tem",
9
9
  "type": "module",
10
10
  "sideEffects": false,
@@ -27,8 +27,8 @@
27
27
  "lucide-react": ">=0.400.0 <1.0.0"
28
28
  },
29
29
  "dependencies": {
30
- "@fayz-ai/core": "^0.38.0",
31
- "@fayz-ai/admin": "^0.38.0"
30
+ "@fayz-ai/core": "^0.40.0",
31
+ "@fayz-ai/admin": "^0.40.0"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/react": "^18.3.0",