@fayz-ai/plugin-registry 0.11.0 → 0.12.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
@@ -12,6 +12,7 @@ declare const SCREENS: readonly [{
12
12
  readonly entity: EntityDef<Record<string, unknown>>;
13
13
  readonly icon: "Tag";
14
14
  readonly feature: "services";
15
+ readonly nested: true;
15
16
  }, {
16
17
  readonly id: "locations";
17
18
  readonly path: "/registry/locations";
@@ -24,6 +25,7 @@ declare const SCREENS: readonly [{
24
25
  readonly entity: EntityDef<Record<string, unknown>>;
25
26
  readonly icon: "Map";
26
27
  readonly feature: "services";
28
+ readonly nested: true;
27
29
  }, {
28
30
  readonly id: "staff";
29
31
  readonly path: "/registry/staff";
@@ -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;AAmCvF,sEAAsE;AACtE,QAAA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWH,CAAA;AAEV,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAA;AAE7D,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;;;;;;OAMG;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,CA+CpF;AAED,OAAO,EACL,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,EAC9E,YAAY,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,mBAAmB,EAC/E,aAAa,GACd,MAAM,gBAAgB,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;AAoCvF,sEAAsE;AACtE,QAAA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWH,CAAA;AAEV,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAA;AAY7D,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;;;;;;OAMG;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,CAqDpF;AAED,OAAO,EACL,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,EAC9E,YAAY,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,mBAAmB,EAC/E,aAAa,GACd,MAAM,gBAAgB,CAAA"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- import { createCrudPage } from '@fayz-ai/admin';
1
+ import { Briefcase, Tag, MapPin, Map } from 'lucide-react';
2
+ import { createCrudPage, adminNavigateTo } from '@fayz-ai/admin';
2
3
  import { tl } from '@fayz-ai/core';
3
4
 
4
5
  // src/index.ts
@@ -64,12 +65,34 @@ var supplierEntity = {
64
65
  layout: "person",
65
66
  displayField: "name",
66
67
  defaultSort: "name",
68
+ formColumns: 2,
69
+ fieldGroups: [
70
+ { id: "identity", label: tl("Identity", "Identifica\xE7\xE3o"), columns: 2 },
71
+ { id: "contact", label: tl("Contact", "Contato"), columns: 2 },
72
+ { id: "record", label: tl("Record", "Cadastro"), columns: 1, column: "side" }
73
+ ],
67
74
  fields: [
68
- { key: "name", label: tl("Name", "Nome"), type: "text", required: true, showInTable: true, searchable: true },
69
- { key: "email", label: "E-mail", type: "email", showInTable: true },
70
- { key: "phone", label: tl("Phone", "Telefone"), type: "phone", showInTable: true },
71
- { key: "notes", label: tl("Notes", "Observa\xE7\xF5es"), type: "textarea", showInTable: false },
72
- { key: "isActive", label: tl("Active", "Ativo"), type: "boolean", showInTable: true, defaultValue: true, inlineToggle: true }
75
+ { key: "name", label: tl("Legal name / Name", "Raz\xE3o social / Nome"), type: "text", required: true, showInTable: true, searchable: true, group: "identity", span: 2 },
76
+ {
77
+ key: "serviceProviderType",
78
+ label: tl("Service provider type", "Tipo de prestador de servi\xE7o"),
79
+ type: "segmented",
80
+ required: true,
81
+ defaultValue: "pj",
82
+ group: "identity",
83
+ span: 2,
84
+ options: [
85
+ { value: "pj", label: tl("Company", "Pessoa jur\xEDdica") },
86
+ { value: "pf", label: tl("Individual", "Pessoa f\xEDsica") },
87
+ { value: "autonomo", label: tl("Self-employed", "Aut\xF4nomo") }
88
+ ]
89
+ },
90
+ { key: "documentNumber", label: "CNPJ / CPF", type: "text", searchable: true, showInTable: true, group: "identity" },
91
+ { key: "registrationNumber", label: tl("State / municipal registration", "Inscri\xE7\xE3o estadual / municipal"), type: "text", group: "identity" },
92
+ { key: "email", label: "E-mail", type: "email", showInTable: true, searchable: true, group: "contact" },
93
+ { key: "phone", label: tl("Phone", "Telefone"), type: "phone", showInTable: true, searchable: true, group: "contact" },
94
+ { key: "isActive", label: tl("Active", "Ativo"), type: "boolean", showInTable: true, defaultValue: true, inlineToggle: true, group: "record" },
95
+ { key: "notes", label: tl("Notes", "Observa\xE7\xF5es"), type: "textarea", showInTable: false, group: "record" }
73
96
  ],
74
97
  data: {
75
98
  table: "people",
@@ -78,7 +101,9 @@ var supplierEntity = {
78
101
  archetype: "person",
79
102
  archetypeKind: "supplier",
80
103
  filters: { kind: "supplier" },
81
- defaults: { kind: "supplier" }
104
+ defaults: { kind: "supplier" },
105
+ customFields: ["serviceProviderType", "registrationNumber"],
106
+ searchColumns: ["name", "email", "phone", "document_number"]
82
107
  }
83
108
  };
84
109
  var contactEntity = {
@@ -280,9 +305,9 @@ var serviceEntity = {
280
305
  // src/index.ts
281
306
  var SCREENS = [
282
307
  { id: "services", path: "/registry/services", entity: serviceEntity, icon: "Briefcase", feature: "services" },
283
- { id: "serviceCategories", path: "/registry/categories", entity: serviceCategoryEntity, icon: "Tag", feature: "services" },
308
+ { id: "serviceCategories", path: "/registry/categories", entity: serviceCategoryEntity, icon: "Tag", feature: "services", nested: true },
284
309
  { id: "locations", path: "/registry/locations", entity: serviceLocationEntity, icon: "MapPin", feature: "services" },
285
- { id: "locationGroups", path: "/registry/location-groups", entity: locationGroupEntity, icon: "Map", feature: "services" },
310
+ { id: "locationGroups", path: "/registry/location-groups", entity: locationGroupEntity, icon: "Map", feature: "services", nested: true },
286
311
  { id: "staff", path: "/registry/staff", entity: staffEntity, icon: "UserCog" },
287
312
  { id: "contacts", path: "/registry/contacts", entity: contactEntity, icon: "Contact" },
288
313
  { id: "suppliers", path: "/registry/suppliers", entity: supplierEntity, icon: "Building2" },
@@ -290,6 +315,14 @@ var SCREENS = [
290
315
  { id: "equipment", path: "/registry/equipment", entity: equipmentEntity, icon: "Wrench" },
291
316
  { id: "origins", path: "/registry/origins", entity: originEntity, icon: "Globe" }
292
317
  ];
318
+ var serviceTabs = () => [
319
+ { id: "services", label: serviceEntity.namePlural ?? serviceEntity.name, icon: Briefcase, onSelect: () => adminNavigateTo("/registry/services") },
320
+ { id: "serviceCategories", label: serviceCategoryEntity.namePlural ?? serviceCategoryEntity.name, icon: Tag, onSelect: () => adminNavigateTo("/registry/categories") }
321
+ ];
322
+ var locationTabs = () => [
323
+ { id: "locations", label: serviceLocationEntity.namePlural ?? serviceLocationEntity.name, icon: MapPin, onSelect: () => adminNavigateTo("/registry/locations") },
324
+ { id: "locationGroups", label: locationGroupEntity.namePlural ?? locationGroupEntity.name, icon: Map, onSelect: () => adminNavigateTo("/registry/location-groups") }
325
+ ];
293
326
  function createRegistryPlugin(options) {
294
327
  const section = options?.navSection ?? "main";
295
328
  const base = options?.navPosition ?? 80;
@@ -297,11 +330,12 @@ function createRegistryPlugin(options) {
297
330
  const pages = active.map((screen, index) => {
298
331
  const entity = options?.entities?.[screen.id] ?? screen.entity;
299
332
  const feature = screen.feature;
333
+ const grouped = screen.id === "services" || screen.id === "serviceCategories" ? { navTabs: serviceTabs, activeNavTab: screen.id } : screen.id === "locations" || screen.id === "locationGroups" ? { navTabs: locationTabs, activeNavTab: screen.id } : {};
300
334
  return {
301
335
  screen,
302
336
  entity,
303
337
  position: base + index * 0.1,
304
- component: createCrudPage(entity, feature ? { feature } : void 0),
338
+ component: createCrudPage(entity, { ...feature ? { feature } : {}, ...grouped }),
305
339
  permission: feature ? { feature, action: "read" } : void 0
306
340
  };
307
341
  });
@@ -318,7 +352,7 @@ function createRegistryPlugin(options) {
318
352
  // ordem, e com que nome — é o `rail` do ofício. Ver packages/admin
319
353
  // rail-preset.ts: o ofício AGRUPA, o plugin NOMEIA, e o `labels` do preset
320
354
  // é a casa dizendo que ali a ficha se chama outra coisa.
321
- navigation: pages.map((page) => ({
355
+ navigation: pages.filter((page) => !("nested" in page.screen && page.screen.nested)).map((page) => ({
322
356
  section,
323
357
  position: page.position,
324
358
  label: page.entity.namePlural ?? page.entity.name,
@@ -329,6 +363,7 @@ function createRegistryPlugin(options) {
329
363
  routes: pages.map((page) => ({
330
364
  path: page.screen.path,
331
365
  component: page.component,
366
+ title: page.entity.namePlural ?? page.entity.name,
332
367
  ...page.permission ? { permission: page.permission } : {}
333
368
  }))
334
369
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/entities.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { tl } from '@fayz-ai/core'\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 displayField: 'name',\n defaultSort: 'name',\n fieldGroups: [\n { id: 'professional', label: tl('Professional Info', 'Informações Profissionais'), columns: 2 },\n ],\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'email', label: 'E-mail', type: 'email', showInTable: true, searchable: true },\n { key: 'phone', label: tl('Phone', 'Telefone'), type: 'phone', showInTable: true },\n { key: 'profession', label: tl('Profession', 'Profissão'), type: 'text', showInTable: true, group: 'professional' },\n { key: 'commissionRate', label: tl('Commission (%)', 'Comissão (%)'), type: 'number', showInTable: true, group: 'professional', defaultValue: 0 },\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, inlineToggle: true, group: 'professional',\n hint: tl(\n 'Clients can be booked with this person.',\n 'Clientes podem ser marcados com esta pessoa.',\n ),\n },\n { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\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 // A extensão `staff_members` e a view `v_staff` não existem mais.\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: ['profession', 'commissionRate'],\n searchColumns: ['name', 'email', 'phone'],\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 displayField: 'name',\n defaultSort: 'name',\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'email', label: 'E-mail', type: 'email', showInTable: true },\n { key: 'phone', label: tl('Phone', 'Telefone'), type: 'phone', showInTable: true },\n { key: 'notes', label: tl('Notes', 'Observações'), type: 'textarea', showInTable: false },\n { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\n ],\n data: {\n table: 'people',\n schema: 'public',\n tenantScoped: true,\n archetype: 'person',\n archetypeKind: 'supplier',\n filters: { kind: 'supplier' },\n defaults: { kind: 'supplier' },\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 displayField: 'name',\n defaultSort: 'name',\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'email', label: 'E-mail', type: 'email', showInTable: true, searchable: true },\n { key: 'phone', label: tl('Phone', 'Telefone'), type: 'phone', showInTable: true, searchable: true },\n { key: 'notes', label: tl('Notes', 'Observações'), type: 'textarea', showInTable: false },\n { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\n ],\n data: {\n table: 'people',\n schema: 'public',\n tenantScoped: true,\n archetype: 'person',\n archetypeKind: 'contact',\n filters: { kind: 'contact' },\n defaults: { kind: 'contact' },\n searchColumns: ['name', 'email', 'phone'],\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 displayField: 'name',\n defaultSort: 'name',\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'phone', label: tl('Phone', 'Telefone'), type: 'phone', showInTable: true },\n { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\n ],\n data: {\n table: 'people',\n schema: 'public',\n tenantScoped: true,\n archetype: 'person',\n archetypeKind: 'partner',\n filters: { kind: 'partner' },\n defaults: { kind: 'partner' },\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 fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'description', label: tl('Model', 'Modelo'), type: 'text', showInTable: true },\n { key: 'sku', label: tl('Serial Number', 'Número de Série'), type: 'text', showInTable: true },\n { key: 'status', label: 'Status', type: 'select', options: ['active', 'maintenance', 'retired'], showInTable: true, defaultValue: 'active' },\n ],\n data: {\n table: 'products',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'asset' },\n defaults: { kind: 'asset' },\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 fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\n ],\n data: {\n table: 'categories',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'origin' },\n defaults: { kind: 'origin' },\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 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 { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\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// ---------------------------------------------------------------------------\nexport const serviceLocationEntity: EntityDef = {\n name: tl('Service Location', 'Local de Atendimento'),\n namePlural: tl('Service Locations', 'Locais de Atendimento'),\n icon: 'MapPin',\n layout: 'location',\n displayField: 'name',\n subtitleField: 'city',\n defaultSort: 'name',\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'phone', label: tl('Phone', 'Telefone'), type: 'phone', showInTable: true },\n { key: 'city', label: tl('City', 'Cidade'), type: 'text', showInTable: true, searchable: true },\n { key: 'state', label: tl('State', 'Estado'), type: 'text', showInTable: true },\n { key: 'address', label: tl('Address', 'Endereço'), type: 'text' },\n { key: 'country', label: tl('Country', 'País'), type: 'text', defaultValue: 'BR' },\n { key: 'postalCode', label: tl('Postal Code', 'CEP'), type: 'text' },\n { key: 'email', label: 'E-mail', type: 'email' },\n { key: 'isHeadquarters', label: tl('Headquarters', 'Matriz'), type: 'boolean', showInTable: true, defaultValue: false },\n { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\n { key: 'notes', label: tl('Notes', 'Observações'), type: 'textarea' },\n ],\n data: {\n // A filial É a unidade. `v_units` é a ponte pública para o schema `app`, e\n // traz exatamente os campos desta tela (nome, contato, endereço, matriz,\n // ativo, observações). A tabela `locations` não existe mais.\n table: 'v_units',\n tenantScoped: true,\n archetype: 'location',\n archetypeKind: 'branch',\n searchColumns: ['name', 'city', 'state'],\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 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 { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\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 icon: 'Briefcase',\n layout: 'service',\n displayField: 'name',\n defaultSort: 'name',\n fields: [\n { key: 'name', label: tl('Service Name', 'Nome do Serviço'), type: 'text', required: true, searchable: true, showInTable: true },\n { key: 'description', label: tl('Description', 'Descrição'), type: 'textarea', showInTable: false },\n { key: 'durationMinutes', label: tl('Duration (min)', 'Duração (min)'), type: 'number', required: true, showInTable: true },\n { key: 'price', label: tl('Price', 'Preço'), type: 'currency', required: true, showInTable: true },\n // A pergunta que o BeautySoft responde com `service_kind`: isto se MARCA,\n // ou se VENDE? O tratamento entra num pacote e o que vai para a agenda é o\n // passo — a avaliação, a revisão, a entrega do que foi comprado antes.\n // Ver a migration 120 do spine.\n {\n key: 'isBookable', label: tl('Appears in the calendar', 'Aparece na agenda'), type: 'boolean',\n showInTable: true, defaultValue: true, inlineToggle: true,\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 { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\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","import type { PluginManifest, PluginScope, VerticalId, EntityDef } from '@fayz-ai/core'\nimport { createCrudPage } from '@fayz-ai/admin'\n\nimport {\n staffEntity, supplierEntity, contactEntity, partnershipEntity, equipmentEntity,\n originEntity, serviceCategoryEntity, serviceLocationEntity, locationGroupEntity,\n serviceEntity,\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' },\n { id: 'locations', path: '/registry/locations', entity: serviceLocationEntity, icon: 'MapPin', feature: 'services' },\n { id: 'locationGroups', path: '/registry/location-groups', entity: locationGroupEntity, icon: 'Map', feature: 'services' },\n { id: 'staff', path: '/registry/staff', entity: staffEntity, icon: 'UserCog' },\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] as const\n\nexport type RegistryScreenId = (typeof SCREENS)[number]['id']\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.\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 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) => options?.modules?.[screen.id] !== false)\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 return {\n screen,\n entity,\n position: base + index * 0.1,\n component: createCrudPage(entity, feature ? { feature } : undefined),\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.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 routes: pages.map((page) => ({\n path: page.screen.path,\n component: page.component as React.ComponentType<unknown>,\n ...(page.permission ? { permission: page.permission } : {}),\n })),\n }\n}\n\nexport {\n staffEntity, supplierEntity, contactEntity, partnershipEntity, equipmentEntity,\n originEntity, serviceCategoryEntity, serviceLocationEntity, locationGroupEntity,\n serviceEntity,\n} from './lib/entities'\n"]}
1
+ {"version":3,"sources":["../src/lib/entities.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { tl } from '@fayz-ai/core'\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 displayField: 'name',\n defaultSort: 'name',\n fieldGroups: [\n { id: 'professional', label: tl('Professional Info', 'Informações Profissionais'), columns: 2 },\n ],\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'email', label: 'E-mail', type: 'email', showInTable: true, searchable: true },\n { key: 'phone', label: tl('Phone', 'Telefone'), type: 'phone', showInTable: true },\n { key: 'profession', label: tl('Profession', 'Profissão'), type: 'text', showInTable: true, group: 'professional' },\n { key: 'commissionRate', label: tl('Commission (%)', 'Comissão (%)'), type: 'number', showInTable: true, group: 'professional', defaultValue: 0 },\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, inlineToggle: true, group: 'professional',\n hint: tl(\n 'Clients can be booked with this person.',\n 'Clientes podem ser marcados com esta pessoa.',\n ),\n },\n { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\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 // A extensão `staff_members` e a view `v_staff` não existem mais.\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: ['profession', 'commissionRate'],\n searchColumns: ['name', 'email', 'phone'],\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 displayField: 'name',\n defaultSort: 'name',\n formColumns: 2,\n fieldGroups: [\n { id: 'identity', label: tl('Identity', 'Identificação'), columns: 2 },\n { id: 'contact', label: tl('Contact', 'Contato'), columns: 2 },\n { id: 'record', label: tl('Record', 'Cadastro'), columns: 1, column: 'side' },\n ],\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 {\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 { key: 'documentNumber', label: 'CNPJ / CPF', type: 'text', searchable: true, showInTable: true, group: 'identity' },\n { key: 'registrationNumber', label: tl('State / municipal registration', 'Inscrição estadual / municipal'), type: 'text', group: 'identity' },\n { key: 'email', label: 'E-mail', type: 'email', showInTable: true, searchable: true, group: 'contact' },\n { key: 'phone', label: tl('Phone', 'Telefone'), type: 'phone', showInTable: true, searchable: true, group: 'contact' },\n { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true, group: 'record' },\n { key: 'notes', label: tl('Notes', 'Observações'), type: 'textarea', showInTable: false, group: 'record' },\n ],\n data: {\n table: 'people',\n schema: 'public',\n tenantScoped: true,\n archetype: 'person',\n archetypeKind: 'supplier',\n filters: { kind: 'supplier' },\n defaults: { kind: 'supplier' },\n customFields: ['serviceProviderType', 'registrationNumber'],\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 displayField: 'name',\n defaultSort: 'name',\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'email', label: 'E-mail', type: 'email', showInTable: true, searchable: true },\n { key: 'phone', label: tl('Phone', 'Telefone'), type: 'phone', showInTable: true, searchable: true },\n { key: 'notes', label: tl('Notes', 'Observações'), type: 'textarea', showInTable: false },\n { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\n ],\n data: {\n table: 'people',\n schema: 'public',\n tenantScoped: true,\n archetype: 'person',\n archetypeKind: 'contact',\n filters: { kind: 'contact' },\n defaults: { kind: 'contact' },\n searchColumns: ['name', 'email', 'phone'],\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 displayField: 'name',\n defaultSort: 'name',\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'phone', label: tl('Phone', 'Telefone'), type: 'phone', showInTable: true },\n { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\n ],\n data: {\n table: 'people',\n schema: 'public',\n tenantScoped: true,\n archetype: 'person',\n archetypeKind: 'partner',\n filters: { kind: 'partner' },\n defaults: { kind: 'partner' },\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 fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'description', label: tl('Model', 'Modelo'), type: 'text', showInTable: true },\n { key: 'sku', label: tl('Serial Number', 'Número de Série'), type: 'text', showInTable: true },\n { key: 'status', label: 'Status', type: 'select', options: ['active', 'maintenance', 'retired'], showInTable: true, defaultValue: 'active' },\n ],\n data: {\n table: 'products',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'asset' },\n defaults: { kind: 'asset' },\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 fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\n ],\n data: {\n table: 'categories',\n schema: 'public',\n tenantScoped: true,\n filters: { kind: 'origin' },\n defaults: { kind: 'origin' },\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 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 { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\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// ---------------------------------------------------------------------------\nexport const serviceLocationEntity: EntityDef = {\n name: tl('Service Location', 'Local de Atendimento'),\n namePlural: tl('Service Locations', 'Locais de Atendimento'),\n icon: 'MapPin',\n layout: 'location',\n displayField: 'name',\n subtitleField: 'city',\n defaultSort: 'name',\n fields: [\n { key: 'name', label: tl('Name', 'Nome'), type: 'text', required: true, showInTable: true, searchable: true },\n { key: 'phone', label: tl('Phone', 'Telefone'), type: 'phone', showInTable: true },\n { key: 'city', label: tl('City', 'Cidade'), type: 'text', showInTable: true, searchable: true },\n { key: 'state', label: tl('State', 'Estado'), type: 'text', showInTable: true },\n { key: 'address', label: tl('Address', 'Endereço'), type: 'text' },\n { key: 'country', label: tl('Country', 'País'), type: 'text', defaultValue: 'BR' },\n { key: 'postalCode', label: tl('Postal Code', 'CEP'), type: 'text' },\n { key: 'email', label: 'E-mail', type: 'email' },\n { key: 'isHeadquarters', label: tl('Headquarters', 'Matriz'), type: 'boolean', showInTable: true, defaultValue: false },\n { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\n { key: 'notes', label: tl('Notes', 'Observações'), type: 'textarea' },\n ],\n data: {\n // A filial É a unidade. `v_units` é a ponte pública para o schema `app`, e\n // traz exatamente os campos desta tela (nome, contato, endereço, matriz,\n // ativo, observações). A tabela `locations` não existe mais.\n table: 'v_units',\n tenantScoped: true,\n archetype: 'location',\n archetypeKind: 'branch',\n searchColumns: ['name', 'city', 'state'],\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 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 { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\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 icon: 'Briefcase',\n layout: 'service',\n displayField: 'name',\n defaultSort: 'name',\n fields: [\n { key: 'name', label: tl('Service Name', 'Nome do Serviço'), type: 'text', required: true, searchable: true, showInTable: true },\n { key: 'description', label: tl('Description', 'Descrição'), type: 'textarea', showInTable: false },\n { key: 'durationMinutes', label: tl('Duration (min)', 'Duração (min)'), type: 'number', required: true, showInTable: true },\n { key: 'price', label: tl('Price', 'Preço'), type: 'currency', required: true, showInTable: true },\n // A pergunta que o BeautySoft responde com `service_kind`: isto se MARCA,\n // ou se VENDE? O tratamento entra num pacote e o que vai para a agenda é o\n // passo — a avaliação, a revisão, a entrega do que foi comprado antes.\n // Ver a migration 120 do spine.\n {\n key: 'isBookable', label: tl('Appears in the calendar', 'Aparece na agenda'), type: 'boolean',\n showInTable: true, defaultValue: true, inlineToggle: true,\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 { key: 'isActive', label: tl('Active', 'Ativo'), type: 'boolean', showInTable: true, defaultValue: true, inlineToggle: true },\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","import type { PluginManifest, PluginScope, VerticalId, EntityDef } from '@fayz-ai/core'\nimport { Briefcase, Map, MapPin, Tag } from 'lucide-react'\nimport { adminNavigateTo, createCrudPage, type CrudNavTab } from '@fayz-ai/admin'\n\nimport {\n staffEntity, supplierEntity, contactEntity, partnershipEntity, equipmentEntity,\n originEntity, serviceCategoryEntity, serviceLocationEntity, locationGroupEntity,\n serviceEntity,\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 { id: 'locations', path: '/registry/locations', entity: serviceLocationEntity, icon: 'MapPin', feature: 'services' },\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: '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] as const\n\nexport type RegistryScreenId = (typeof SCREENS)[number]['id']\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]\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.\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 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) => options?.modules?.[screen.id] !== false)\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'\n ? { navTabs: serviceTabs, activeNavTab: screen.id }\n : screen.id === 'locations' || screen.id === 'locationGroups'\n ? { navTabs: locationTabs, 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 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 serviceEntity,\n} from './lib/entities'\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/lib/entities.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAsB9C,eAAO,MAAM,WAAW,EAAE,SAiDzB,CAAA;AAKD,eAAO,MAAM,cAAc,EAAE,SAuB5B,CAAA;AAKD,eAAO,MAAM,aAAa,EAAE,SAwB3B,CAAA;AAKD,eAAO,MAAM,iBAAiB,EAAE,SAqB/B,CAAA;AAKD,eAAO,MAAM,eAAe,EAAE,SAoB7B,CAAA;AAKD,eAAO,MAAM,YAAY,EAAE,SAiB1B,CAAA;AAKD,eAAO,MAAM,qBAAqB,EAAE,SAkBnC,CAAA;AAKD,eAAO,MAAM,qBAAqB,EAAE,SA+BnC,CAAA;AAKD,eAAO,MAAM,mBAAmB,EAAE,SAmBjC,CAAA;AAKD,eAAO,MAAM,aAAa,EAAE,SAiC3B,CAAA"}
1
+ {"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/lib/entities.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAsB9C,eAAO,MAAM,WAAW,EAAE,SAiDzB,CAAA;AAKD,eAAO,MAAM,cAAc,EAAE,SA0C5B,CAAA;AAKD,eAAO,MAAM,aAAa,EAAE,SAwB3B,CAAA;AAKD,eAAO,MAAM,iBAAiB,EAAE,SAqB/B,CAAA;AAKD,eAAO,MAAM,eAAe,EAAE,SAoB7B,CAAA;AAKD,eAAO,MAAM,YAAY,EAAE,SAiB1B,CAAA;AAKD,eAAO,MAAM,qBAAqB,EAAE,SAkBnC,CAAA;AAKD,eAAO,MAAM,qBAAqB,EAAE,SA+BnC,CAAA;AAKD,eAAO,MAAM,mBAAmB,EAAE,SAmBjC,CAAA;AAKD,eAAO,MAAM,aAAa,EAAE,SAiC3B,CAAA"}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "status": "beta",
5
5
  "dependencies": []
6
6
  },
7
- "version": "0.11.0",
7
+ "version": "0.12.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.30.0",
31
- "@fayz-ai/admin": "^0.30.0"
30
+ "@fayz-ai/core": "^0.31.0",
31
+ "@fayz-ai/admin": "^0.31.0"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/react": "^18.3.0",