@fayz-ai/core 0.31.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/app/app-config.d.ts +10 -0
  2. package/dist/app/app-config.d.ts.map +1 -1
  3. package/dist/{chunk-HVWFFFKN.js → chunk-MFFT663T.js} +25 -6
  4. package/dist/chunk-MFFT663T.js.map +1 -0
  5. package/dist/{chunk-XJGV7TWQ.js → chunk-OI5K5E33.js} +177 -15
  6. package/dist/chunk-OI5K5E33.js.map +1 -0
  7. package/dist/{chunk-7M4NWLIT.js → chunk-QZ22VPRZ.js} +3 -3
  8. package/dist/{chunk-7M4NWLIT.js.map → chunk-QZ22VPRZ.js.map} +1 -1
  9. package/dist/{chunk-ZGAGCTQM.js → chunk-X3GYBLGO.js} +3 -3
  10. package/dist/{chunk-ZGAGCTQM.js.map → chunk-X3GYBLGO.js.map} +1 -1
  11. package/dist/{chunk-ZNTO44TD.js → chunk-XCSAWLFX.js} +71 -6
  12. package/dist/chunk-XCSAWLFX.js.map +1 -0
  13. package/dist/data/archetype.d.ts.map +1 -1
  14. package/dist/data/attached-row.d.ts +26 -0
  15. package/dist/data/attached-row.d.ts.map +1 -0
  16. package/dist/data/index.js +2 -2
  17. package/dist/data/resolve.d.ts.map +1 -1
  18. package/dist/data/supabase.d.ts +1 -1
  19. package/dist/data/supabase.d.ts.map +1 -1
  20. package/dist/data/write-refused.d.ts +16 -0
  21. package/dist/data/write-refused.d.ts.map +1 -0
  22. package/dist/entity/payee-account-fields.d.ts +11 -0
  23. package/dist/entity/payee-account-fields.d.ts.map +1 -0
  24. package/dist/entity/record-rail.d.ts +61 -0
  25. package/dist/entity/record-rail.d.ts.map +1 -0
  26. package/dist/i18n/index.js +1 -1
  27. package/dist/i18n/shell-translations.en.d.ts.map +1 -1
  28. package/dist/i18n/shell-translations.pt-br.d.ts.map +1 -1
  29. package/dist/index.d.ts +17 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +277 -9
  32. package/dist/index.js.map +1 -1
  33. package/dist/integrations/index.js +2 -2
  34. package/dist/lib/cancel-replay.d.ts +25 -0
  35. package/dist/lib/cancel-replay.d.ts.map +1 -0
  36. package/dist/lib/channel-kind.d.ts +30 -0
  37. package/dist/lib/channel-kind.d.ts.map +1 -0
  38. package/dist/lib/discount-share.d.ts +23 -0
  39. package/dist/lib/discount-share.d.ts.map +1 -0
  40. package/dist/lib/document-br.d.ts +22 -0
  41. package/dist/lib/document-br.d.ts.map +1 -0
  42. package/dist/manifest/index.d.ts +1 -1
  43. package/dist/manifest/index.d.ts.map +1 -1
  44. package/dist/orders/index.d.ts +39 -0
  45. package/dist/orders/index.d.ts.map +1 -1
  46. package/dist/orders/index.js +41 -4
  47. package/dist/orders/index.js.map +1 -1
  48. package/dist/orders/openingServiceCharge.d.ts +16 -0
  49. package/dist/orders/openingServiceCharge.d.ts.map +1 -0
  50. package/dist/orders/paymentKey.d.ts +22 -0
  51. package/dist/orders/paymentKey.d.ts.map +1 -0
  52. package/dist/{shell-translations.pt-br-J5Y5TAJ4.js → shell-translations.pt-br-HZ2EK5ZG.js} +70 -5
  53. package/dist/shell-translations.pt-br-HZ2EK5ZG.js.map +1 -0
  54. package/dist/testing/index.js +3 -3
  55. package/dist/types/crud.d.ts +217 -2
  56. package/dist/types/crud.d.ts.map +1 -1
  57. package/package.json +1 -1
  58. package/dist/chunk-HVWFFFKN.js.map +0 -1
  59. package/dist/chunk-XJGV7TWQ.js.map +0 -1
  60. package/dist/chunk-ZNTO44TD.js.map +0 -1
  61. package/dist/shell-translations.pt-br-J5Y5TAJ4.js.map +0 -1
@@ -25,6 +25,16 @@ export interface AppConfigApp {
25
25
  icon: string | null;
26
26
  accent_color: string | null;
27
27
  url: string | null;
28
+ /**
29
+ * O tema do PRODUTO (138) — um `SaasTheme` inteiro, servido como dado.
30
+ *
31
+ * Sai de `app.apps.theme` e é a BASE que o shell pinta; a marca da conta
32
+ * entra por cima dela, e só até onde o plano permitir (ver `useAppTheme`).
33
+ * Tipado como `unknown` aqui de propósito: `@fayz-ai/core` não conhece
34
+ * `SaasTheme`, que é do shell, e inventar uma segunda declaração dele criaria
35
+ * duas formas da mesma coisa para divergirem.
36
+ */
37
+ theme?: unknown;
28
38
  /**
29
39
  * Which account to land in when this app is opened (008).
30
40
  *
@@ -1 +1 @@
1
- {"version":3,"file":"app-config.d.ts","sourceRoot":"","sources":["../../src/app/app-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app-config.d.ts","sourceRoot":"","sources":["../../src/app/app-config.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAE3D,wDAAwD;AACxD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,+DAA+D;IAC/D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAA;IAC7B,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,sDAAsD;IACtD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,oEAAoE;IACpE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,OAAO,CAAA;IACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,IAAI,CAAA;IACjD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,OAAO,EAAE,eAAe,EAAE,CAAA;IAC1B,IAAI,EAAE,YAAY,EAAE,CAAA;IACpB,GAAG,EAAE,iBAAiB,EAAE,CAAA;IACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,EAAE,SAMhB,CAAA;AAcf;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,OAAO,EACf,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GACnD,OAAO,CAAC,SAAS,CAAC,CAcpB;AAED,6EAA6E;AAC7E,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAG3D;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAcrE;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,mBAAmB,EAAE,CA2B/E;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EAChH,OAAO,EAAE,CAAC,EAAE,EACZ,GAAG,EAAE,iBAAiB,EAAE,GACvB,CAAC,EAAE,CA6BL;AAQD,6EAA6E;AAC7E,eAAO,MAAM,0BAA0B,0CAA2C,CAAA;AAElF,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,CAAC,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SAAE,CAAC,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CAC3H;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,SAAS,YAAY,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,GAAG,CAAC,CAoClG"}
@@ -1,6 +1,21 @@
1
1
  import { errorMessage } from './chunk-6TVRNKWW.js';
2
2
  import * as React from 'react';
3
3
 
4
+ // src/data/write-refused.ts
5
+ var WRITE_REFUSED_MESSAGE = "Sem permiss\xE3o para esta a\xE7\xE3o, ou o registro j\xE1 n\xE3o existe.";
6
+ var WriteRefusedError = class extends Error {
7
+ constructor(message = WRITE_REFUSED_MESSAGE) {
8
+ super(message);
9
+ /** Para quem quiser distinguir isto de uma falha de rede sem ler a mensagem. */
10
+ this.refused = true;
11
+ this.name = "WriteRefusedError";
12
+ }
13
+ };
14
+ function assertWrote(rows, message) {
15
+ if (rows && rows.length > 0) return;
16
+ throw new WriteRefusedError(message);
17
+ }
18
+
4
19
  // src/data/filters.ts
5
20
  var LOWER_INCLUSIVE = ["from", "gte", "start", "after", "since", "min"];
6
21
  var LOWER_EXCLUSIVE = ["gt"];
@@ -146,7 +161,7 @@ function createSupabaseProvider(table, config) {
146
161
  q = applyUnitScope(q, unitScope());
147
162
  if (config?.filters) {
148
163
  for (const [col, val] of Object.entries(config.filters)) {
149
- q = q.eq(col, val);
164
+ q = Array.isArray(val) ? q.in(col, val) : q.eq(col, val);
150
165
  }
151
166
  }
152
167
  if (query.filters) {
@@ -246,14 +261,18 @@ function createSupabaseProvider(table, config) {
246
261
  if (error) throw error;
247
262
  return mapRow(updated, columnMap);
248
263
  },
264
+ // `.select('id')` e não um delete mudo — ver data/write-refused: a RLS
265
+ // recusa com 204 e zero linhas, que sem isto chega aqui como sucesso.
249
266
  async remove(id) {
250
- const { error } = await getClient().from(table).delete().eq("id", id);
267
+ const { data, error } = await getClient().from(table).delete().eq("id", id).select("id");
251
268
  if (error) throw error;
269
+ assertWrote(data);
252
270
  },
253
271
  async removeMany(ids) {
254
272
  if (!ids.length) return;
255
- const { error } = await getClient().from(table).delete().in("id", ids);
273
+ const { data, error } = await getClient().from(table).delete().in("id", ids).select("id");
256
274
  if (error) throw error;
275
+ assertWrote(data);
257
276
  }
258
277
  };
259
278
  }
@@ -349,6 +368,6 @@ function useActiveTenantId() {
349
368
  return React.useSyncExternalStore(subscribeActiveTenant, getActiveTenantId, getActiveTenantId);
350
369
  }
351
370
 
352
- export { DEFAULT_CACHE_TTL, applyRangeToQuery, applyUnitScope, clearGlobalCache, createCacheStore, createSupabaseProvider, getActiveTenantId, getScopedResource, getSupabaseClientOptional, globalCache, isFilterObject, matchesRange, parseRangeFilter, resolveUnitScope, setActiveTenantId, setGlobalSupabaseClient, setScopedResources, stableKey, subscribeActiveTenant, useActiveTenantId };
353
- //# sourceMappingURL=chunk-HVWFFFKN.js.map
354
- //# sourceMappingURL=chunk-HVWFFFKN.js.map
371
+ export { DEFAULT_CACHE_TTL, WRITE_REFUSED_MESSAGE, WriteRefusedError, applyRangeToQuery, applyUnitScope, assertWrote, clearGlobalCache, createCacheStore, createSupabaseProvider, getActiveTenantId, getScopedResource, getSupabaseClientOptional, globalCache, isFilterObject, matchesRange, parseRangeFilter, resolveUnitScope, setActiveTenantId, setGlobalSupabaseClient, setScopedResources, stableKey, subscribeActiveTenant, useActiveTenantId };
372
+ //# sourceMappingURL=chunk-MFFT663T.js.map
373
+ //# sourceMappingURL=chunk-MFFT663T.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/data/write-refused.ts","../src/data/filters.ts","../src/data/unit-scope.ts","../src/data/supabase.ts","../src/lib/cache.ts","../src/lib/tenant.ts"],"names":[],"mappings":"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","file":"chunk-MFFT663T.js","sourcesContent":["// ---------------------------------------------------------------------------\n// UMA ESCRITA QUE NÃO PEGOU LINHA NENHUMA NÃO É UM SUCESSO.\n//\n// O PostgREST responde **204** a um DELETE que a RLS recusou — a política não\n// dá erro, ela apenas não deixa a linha entrar no `USING`, e a instrução apaga\n// zero linhas. Do lado do cliente, `error` volta `null`. Todo provider deste\n// SDK lia isso como \"apagado\".\n//\n// O que isso produz na tela é a pior forma de falha que existe: a de sucesso.\n// O diálogo fecha, o brinde diz \"Agendamento excluído\", a lista recarrega\n// inteira — e o agendamento continua lá. Foi assim que chegaram, no mesmo dia,\n// \"não consigo excluir o cliente\" e \"não consigo excluir o agendamento\": o\n// mesmo 204, em dois cadastros diferentes, com a mesma causa — o papel não tem\n// a permissão de exclusão e nada na tela diz isso.\n//\n// A correção é pedir as linhas de volta (`.select('id')`) e tratar a lista\n// vazia como recusa. Custa um campo no corpo da resposta e transforma um\n// engano silencioso numa mensagem.\n//\n// ── Por que a mensagem fala de DUAS causas ────────────────────────────────\n//\n// De fora, \"a RLS recusou\" e \"a linha não existe mais\" são indistinguíveis —\n// as duas apagam zero linhas. Chutar uma delas seria mandar o operador para o\n// lugar errado metade das vezes; dizer as duas o manda para a pergunta certa\n// (\"quem eu sou aqui?\" ou \"alguém já apagou?\").\n// ---------------------------------------------------------------------------\n\n/** O texto que a tela mostra quando uma escrita não pegou linha nenhuma. */\nexport const WRITE_REFUSED_MESSAGE =\n 'Sem permissão para esta ação, ou o registro já não existe.'\n\nexport class WriteRefusedError extends Error {\n /** Para quem quiser distinguir isto de uma falha de rede sem ler a mensagem. */\n readonly refused = true\n constructor(message: string = WRITE_REFUSED_MESSAGE) {\n super(message)\n this.name = 'WriteRefusedError'\n }\n}\n\n/**\n * Confirma que a escrita pegou pelo menos uma linha.\n *\n * `rows` é o que `.select(...)` devolveu. `null` conta como recusa — é o que o\n * PostgREST devolve quando não se pediu representação nenhuma, e nesse caso o\n * chamador não deveria estar usando esta função.\n */\nexport function assertWrote(rows: unknown[] | null | undefined, message?: string): void {\n if (rows && rows.length > 0) return\n throw new WriteRefusedError(message)\n}\n","/**\n * ONE filter grammar, shared by the providers and by the agent's data tools.\n *\n * Models express ranges in whatever dialect they were trained on — `{from,to}`,\n * `{gte,lte}`, Mongo's `{$gte,$lt}`. When only some of those are recognised the\n * unrecognised one falls through to an equality compare against\n * \"[object Object]\", which matches nothing and reads as \"there are no\n * appointments today\" instead of \"I did not understand that filter\".\n */\n\nexport interface RangeFilter {\n gte?: unknown\n gt?: unknown\n lte?: unknown\n lt?: unknown\n}\n\nconst LOWER_INCLUSIVE = ['from', 'gte', 'start', 'after', 'since', 'min']\nconst LOWER_EXCLUSIVE = ['gt']\nconst UPPER_INCLUSIVE = ['to', 'lte', 'end', 'until', 'before', 'max']\nconst UPPER_EXCLUSIVE = ['lt']\n\nfunction pick(source: Record<string, unknown>, names: string[]): unknown {\n for (const name of names) {\n if (source[name] !== undefined && source[name] !== null) return source[name]\n const dollar = `$${name}`\n if (source[dollar] !== undefined && source[dollar] !== null) return source[dollar]\n }\n return undefined\n}\n\n/**\n * Parse a filter value into a range, or return null when it is a plain\n * (equality) value. An object that looks like a filter but carries no\n * recognised bound returns `null` too — callers treat that as \"invalid\",\n * never as \"matches nothing\".\n */\nexport function parseRangeFilter(value: unknown): RangeFilter | null {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return null\n const source = value as Record<string, unknown>\n const range: RangeFilter = {}\n const gte = pick(source, LOWER_INCLUSIVE)\n const gt = pick(source, LOWER_EXCLUSIVE)\n const lte = pick(source, UPPER_INCLUSIVE)\n const lt = pick(source, UPPER_EXCLUSIVE)\n if (gte !== undefined) range.gte = gte\n if (gt !== undefined) range.gt = gt\n if (lte !== undefined) range.lte = lte\n if (lt !== undefined) range.lt = lt\n return Object.keys(range).length ? range : null\n}\n\n/** True for any object value — including ones no bound could be read from. */\nexport function isFilterObject(value: unknown): boolean {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction comparable(value: unknown): number {\n if (typeof value === 'number') return value\n if (value instanceof Date) return value.getTime()\n const ts = Date.parse(String(value))\n if (!Number.isNaN(ts)) return ts\n return Number(value)\n}\n\n/** Client-side counterpart of the range a provider would push to SQL. */\nexport function matchesRange(raw: unknown, range: RangeFilter): boolean {\n const value = comparable(raw)\n if (Number.isNaN(value)) return false\n if (range.gte !== undefined && value < comparable(range.gte)) return false\n if (range.gt !== undefined && value <= comparable(range.gt)) return false\n if (range.lte !== undefined && value > comparable(range.lte)) return false\n if (range.lt !== undefined && value >= comparable(range.lt)) return false\n return true\n}\n\n/** Apply a range to a PostgREST query builder. */\nexport function applyRangeToQuery<Q>(\n query: Q,\n column: string,\n range: RangeFilter,\n): Q {\n let q = query as Record<string, (c: string, v: unknown) => unknown>\n for (const op of ['gte', 'gt', 'lte', 'lt'] as const) {\n const bound = range[op]\n if (bound === undefined) continue\n q = q[op](column, bound) as Record<string, (c: string, v: unknown) => unknown>\n }\n return q as Q\n}\n","// ---------------------------------------------------------------------------\n// The one place that turns \"the user is looking at Ipanema\" into a filter.\n//\n// This is a NARROWING and nothing else. Which units a person may reach is\n// decided by row-level security; if this file were deleted the app would show\n// more rows than the switcher promises, and still not one row the database\n// would have refused. That asymmetry is deliberate — it is what lets the filter\n// live in the client at all.\n// ---------------------------------------------------------------------------\n\nexport interface UnitScope {\n column: string\n id: string\n /** Whether rows with no unit (\"belongs to the whole organization\") come too. */\n includeShared: boolean\n}\n\n/** One row of `public.scoped_resources` — which tables carry a unit, and under\n * which column. */\nexport interface ScopedResource {\n unitColumn: string\n shareable: boolean\n}\n\n// The registry, mirrored from the database rather than restated here.\n//\n// The list of scoped tables and their unit columns lives in ONE place —\n// `public.scoped_resources`, seeded by migration 041 — and the shell publishes\n// it at boot. A second copy in TypeScript would drift on the first table anyone\n// adds, and the failure mode of that drift is a screen that quietly stops\n// narrowing while the database still does.\nlet _scoped: Record<string, ScopedResource> = {}\n\nexport function setScopedResources(map: Record<string, ScopedResource>): void {\n _scoped = map\n}\n\nexport function getScopedResource(table: string | undefined): ScopedResource | undefined {\n if (!table) return undefined\n return _scoped[table]\n}\n\nexport interface UnitScopeConfig {\n unitScoped?: boolean\n unitColumn?: string\n /**\n * Default true. A row with no unit belongs to the brand and must survive a\n * unit selection — the Botox that is sold everywhere still shows in Ipanema.\n *\n * False for ledgers and aggregations, where a shared row summed into every\n * unit is a wrong number stated confidently, which is worse than a missing\n * one.\n */\n includeSharedRows?: boolean\n unitId?: () => string | undefined\n}\n\n/**\n * `null` means \"do not narrow\" — unit mode off, \"todas as unidades\", or an\n * entity that never opted in. Callers treat null as a no-op, which is what\n * keeps every provider's behaviour identical for entities that are not scoped.\n */\nexport function resolveUnitScope(config: UnitScopeConfig): UnitScope | null {\n if (!config.unitScoped) return null\n const id = config.unitId?.()\n if (!id) return null\n return {\n column: config.unitColumn ?? 'unit_id',\n id,\n includeShared: config.includeSharedRows !== false,\n }\n}\n\n/**\n * Applies the scope to a PostgREST builder.\n *\n * The shared form is `or(unit.eq.X,unit.is.null)`. Multiple `or=` params AND\n * together in PostgREST, so this composes correctly with the search `.or()` the\n * providers already emit: (name matches) AND (unit is mine or nobody's).\n *\n * Note what is NOT here: an `.in(column, [...myUnits])`. Enumerating the user's\n * units in the browser is the exact mistake this whole design exists to avoid —\n * it would put the answer to \"which units may I see\" in the client, where it\n * can be edited.\n */\nexport function applyUnitScope<Q>(builder: Q, scope: UnitScope | null): Q {\n if (!scope) return builder\n const q = builder as unknown as {\n or: (f: string) => unknown\n eq: (c: string, v: unknown) => unknown\n }\n return (scope.includeShared\n ? q.or(`${scope.column}.eq.${scope.id},${scope.column}.is.null`)\n : q.eq(scope.column, scope.id)) as unknown as Q\n}\n","import { errorMessage } from '../lib/error-message'\nimport { assertWrote } from './write-refused'\nimport type { DataProvider, CrudQuery, CrudResult } from './types'\nimport { applyRangeToQuery, isFilterObject, parseRangeFilter } from './filters'\nimport { applyUnitScope, resolveUnitScope } from './unit-scope'\n\nexport interface SupabaseProviderConfig {\n schema?: string\n tenantId?: string | (() => string | undefined)\n tenantIdColumn?: string\n searchColumns?: string[]\n selectColumns?: string\n columnMap?: Record<string, string>\n filters?: Record<string, string | string[]>\n defaults?: Record<string, unknown>\n supabaseClient?: unknown\n /** Franchise scoping. Absent (every entity today) ⇒ nothing below changes. */\n unitScoped?: boolean\n unitColumn?: string\n includeSharedRows?: boolean\n unitId?: () => string | undefined\n}\n\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (c) => '_' + c.toLowerCase())\n}\n\nfunction snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase())\n}\n\nfunction mapRow<T>(row: Record<string, unknown>, columnMap?: Record<string, string>): T {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(row)) {\n const camelKey = columnMap?.[key] ?? snakeToCamel(key)\n result[camelKey] = value\n }\n return result as T\n}\n\nfunction mapEntity(entity: Record<string, unknown>, columnMap?: Record<string, string>): Record<string, unknown> {\n const reverseMap: Record<string, string> = {}\n if (columnMap) {\n for (const [snake, camel] of Object.entries(columnMap)) {\n reverseMap[camel] = snake\n }\n }\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(entity)) {\n // `createdBy` entra na lista: quem o escreve é o gatilho do banco, com\n // `auth.uid()`. Deixá-lo passar daria à interface a chance de dizer quem\n // cadastrou — e um autor que o próprio formulário pode escolher não vale\n // como procedência. Ver packages/db/migrations/025_created_by.sql.\n // `ownerId` for the same reason: 041's trigger decides who a record belongs\n // to, and a form that could set it would be handing records to other people.\n if (key === 'id' || key === 'createdAt' || key === 'updatedAt' || key === 'tenantId' || key === 'createdBy' || key === 'ownerId') continue\n const snakeKey = reverseMap[key] ?? camelToSnake(key)\n result[snakeKey] = value\n }\n return result\n}\n\n// Global Supabase client registry — set once via createFayzApp\nlet _globalSupabaseClient: unknown | null = null\n\nexport function setGlobalSupabaseClient(client: unknown): void {\n _globalSupabaseClient = client\n}\n\nexport function getSupabaseClientOptional(): unknown | null {\n return _globalSupabaseClient\n}\n\nexport function createSupabaseProvider<T extends { id: string }>(\n table: string,\n config?: SupabaseProviderConfig,\n): DataProvider<T> {\n const schema = config?.schema ?? 'public'\n const tenantIdCol = config?.tenantIdColumn ?? 'tenant_id'\n const searchCols = config?.searchColumns ?? []\n const selectCols = config?.selectColumns ?? '*'\n const columnMap = config?.columnMap\n\n function resolveTenantId(): string | undefined {\n if (!config?.tenantId) return undefined\n return typeof config.tenantId === 'function' ? config.tenantId() : config.tenantId\n }\n\n function unitScope() {\n return resolveUnitScope(config ?? {})\n }\n\n function getClient() {\n const supabase = (config?.supabaseClient ?? _globalSupabaseClient) as {\n schema: (s: string) => unknown\n from: (t: string) => unknown\n } | null\n if (!supabase) throw new Error(`[@fayz-ai/core] Supabase client not available. Call createFayzApp with a provider first.`)\n return schema === 'public' ? (supabase as { from: (t: string) => unknown }) : (supabase.schema(schema) as { from: (t: string) => unknown })\n }\n\n return {\n async list(query: CrudQuery): Promise<CrudResult<T>> {\n // 'none' skips PostgREST's count aggregate entirely — see CrudQuery.countMode.\n const wantCount = query.countMode !== 'none'\n let q = (getClient().from(table) as { select: (...args: unknown[]) => unknown })\n .select(selectCols, wantCount ? { count: 'exact' } : undefined) as Record<string, unknown>\n\n const tenantId = resolveTenantId()\n if (tenantId) q = (q as { eq: (col: string, val: string) => unknown }).eq(tenantIdCol, tenantId) as Record<string, unknown>\n\n // Narrowing only — the boundary itself is the restrictive policy in the\n // database. Placed before the search `.or()` because PostgREST ANDs the\n // two `or=` params, which is what makes them compose.\n q = applyUnitScope(q, unitScope()) as Record<string, unknown>\n\n if (config?.filters) {\n for (const [col, val] of Object.entries(config.filters)) {\n // UMA LISTA é `in`, não `eq`.\n //\n // Com `eq`, um array vira `kind=eq.a,b,c` — um valor único com\n // vírgulas, que não casa com nada e devolve lista vazia. E o caso que\n // pediu isto não é teórico: `plg_financial_accounts` guarda as contas\n // do RAZÃO, e no Pertinho são 122.224 linhas `person` ao lado de 233\n // contas bancárias de verdade. A tela de contas precisa das cinco\n // espécies de conta bancária, e sem `in` ela lista a casa inteira.\n q = Array.isArray(val)\n ? (q as { in: (c: string, v: readonly string[]) => unknown }).in(col, val) as Record<string, unknown>\n : (q as { eq: (c: string, v: string) => unknown }).eq(col, val) as Record<string, unknown>\n }\n }\n\n // Faceted / dynamic filters from the query, mapped to columns. Equality\n // by default; a range object ({from,to} / {gte,lt} / {$gte,$lt}) becomes\n // real SQL bounds instead of an equality compare against \"[object Object]\".\n if (query.filters) {\n for (const [key, val] of Object.entries(query.filters)) {\n if (val == null || val === '') continue\n const col = columnMap?.[key] ?? camelToSnake(key)\n const range = parseRangeFilter(val)\n if (range) {\n q = applyRangeToQuery(q, col, range)\n continue\n }\n if (isFilterObject(val)) {\n throw new Error(\n `[@fayz-ai/core] Filter \"${key}\" is an object with no recognised bound. ` +\n 'Use {from,to} / {gte,lte,gt,lt} for ranges, or a plain value for equality.',\n )\n }\n q = (q as { eq: (c: string, v: unknown) => unknown }).eq(col, val) as Record<string, unknown>\n }\n }\n\n if (query.search && searchCols.length > 0) {\n const term = `%${query.search}%`\n const orClause = searchCols.map((col) => `${camelToSnake(col)}.ilike.${term}`).join(',')\n q = (q as { or: (c: string) => unknown }).or(orClause) as Record<string, unknown>\n }\n\n if (query.sortBy) {\n q = (q as { order: (col: string, opts: unknown) => unknown })\n .order(camelToSnake(query.sortBy), { ascending: query.sortDir !== 'desc' }) as Record<string, unknown>\n } else {\n q = (q as { order: (col: string, opts: unknown) => unknown })\n .order('created_at', { ascending: false }) as Record<string, unknown>\n }\n\n const page = query.page ?? 1\n const pageSize = query.pageSize ?? 50\n const from = (page - 1) * pageSize\n q = (q as { range: (f: number, t: number) => unknown }).range(from, from + pageSize - 1) as Record<string, unknown>\n\n const { data, error, count } = await q as { data: Record<string, unknown>[] | null; error: unknown; count: number | null }\n if (error) throw error\n\n return {\n data: (data ?? []).map((row) => mapRow<T>(row, columnMap)),\n total: count ?? 0,\n }\n },\n\n async create(data) {\n const row = mapEntity(data as Record<string, unknown>, columnMap)\n const tenantId = resolveTenantId()\n if (tenantId) row[tenantIdCol] = tenantId\n const scope = unitScope()\n if (scope && row[scope.column] === undefined) row[scope.column] = scope.id\n if (config?.defaults) {\n for (const [col, val] of Object.entries(config.defaults)) {\n if (row[col] === undefined) row[col] = val\n }\n }\n\n const { data: created, error } = (await (getClient().from(table) as {\n insert: (r: unknown) => { select: () => { single: () => Promise<{ data: unknown; error: unknown }> } }\n }).insert(row).select().single()) as { data: Record<string, unknown> | null; error: unknown }\n\n if (error) throw error\n return mapRow<T>(created!, columnMap)\n },\n\n async createMany(rows, options) {\n const tenantId = resolveTenantId()\n const size = Math.max(1, options?.chunkSize ?? 200)\n const scope = unitScope()\n const prepared = rows.map((r) => {\n const row = mapEntity(r as Record<string, unknown>, columnMap)\n if (tenantId) row[tenantIdCol] = tenantId\n if (scope && row[scope.column] === undefined) row[scope.column] = scope.id\n if (config?.defaults) {\n for (const [col, val] of Object.entries(config.defaults)) {\n if (row[col] === undefined) row[col] = val\n }\n }\n return row\n })\n\n let created = 0\n const failed: Array<{ index: number; message: string }> = []\n for (let start = 0; start < prepared.length; start += size) {\n const chunk = prepared.slice(start, start + size)\n const { error } = (await (getClient().from(table) as {\n insert: (r: unknown) => Promise<{ error: unknown }>\n }).insert(chunk)) as { error: unknown }\n if (!error) {\n created += chunk.length\n } else {\n // One bad row rejects its whole chunk. Retrying it row by row keeps\n // the other 199 — an import that loses 200 records over one malformed\n // phone number is worse than no import.\n const message = errorMessage(error)\n for (let i = 0; i < chunk.length; i++) {\n const { error: rowError } = (await (getClient().from(table) as {\n insert: (r: unknown) => Promise<{ error: unknown }>\n }).insert(chunk[i])) as { error: unknown }\n if (rowError) {\n failed.push({\n index: start + i,\n message: rowError instanceof Error ? rowError.message : String(rowError ?? message),\n })\n } else created += 1\n }\n }\n options?.onProgress?.(Math.min(start + chunk.length, prepared.length), prepared.length)\n }\n return { created, failed }\n },\n\n async update(id, data) {\n const row = mapEntity(data as Record<string, unknown>, columnMap)\n const { data: updated, error } = (await (getClient().from(table) as {\n update: (r: unknown) => { eq: (c: string, v: string) => { select: () => { single: () => Promise<{ data: unknown; error: unknown }> } } }\n }).update(row).eq('id', id).select().single()) as { data: Record<string, unknown> | null; error: unknown }\n\n if (error) throw error\n return mapRow<T>(updated!, columnMap)\n },\n\n // `.select('id')` e não um delete mudo — ver data/write-refused: a RLS\n // recusa com 204 e zero linhas, que sem isto chega aqui como sucesso.\n async remove(id) {\n const { data, error } = (await (getClient().from(table) as {\n delete: () => { eq: (c: string, v: string) => { select: (c: string) => Promise<{ data: unknown[] | null; error: unknown }> } }\n }).delete().eq('id', id).select('id')) as { data: unknown[] | null; error: unknown }\n if (error) throw error\n assertWrote(data)\n },\n\n async removeMany(ids) {\n if (!ids.length) return\n const { data, error } = (await (getClient().from(table) as {\n delete: () => { in: (c: string, v: string[]) => { select: (c: string) => Promise<{ data: unknown[] | null; error: unknown }> } }\n }).delete().in('id', ids).select('id')) as { data: unknown[] | null; error: unknown }\n if (error) throw error\n assertWrote(data)\n },\n }\n}\n","// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface CacheEntry<T = unknown> {\n data: T\n expiresAt: number\n lastAccess: number\n}\n\nexport interface CacheStore {\n get<T>(key: string): T | undefined\n set<T>(key: string, data: T, ttl?: number): void\n /** Clear all entries whose key starts with `prefix` */\n invalidate(prefix: string): void\n clear(): void\n size(): number\n}\n\nexport interface CacheConfig {\n /** Default time-to-live in ms (default: 60 000 — 1 minute) */\n defaultTTL?: number\n /** Maximum cached entries before LRU eviction (default: 500) */\n maxEntries?: number\n}\n\n// ---------------------------------------------------------------------------\n// Stable key helper — deterministic JSON for cache keys\n// ---------------------------------------------------------------------------\n\nfunction sortDeep(value: unknown): unknown {\n if (value === null || value === undefined || typeof value !== 'object') return value\n if (Array.isArray(value)) return value.map(sortDeep)\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[k] = sortDeep((value as Record<string, unknown>)[k])\n }\n return sorted\n}\n\nexport function stableKey(...parts: unknown[]): string {\n return parts.map((p) => (typeof p === 'string' ? p : JSON.stringify(sortDeep(p)))).join(':')\n}\n\n// ---------------------------------------------------------------------------\n// CacheStore implementation\n// ---------------------------------------------------------------------------\n\n/** Shared so the persistent layer can reconstruct the same `expiresAt` L1 computed. */\nexport const DEFAULT_CACHE_TTL = 60_000\n\nexport function createCacheStore(config?: CacheConfig): CacheStore {\n const defaultTTL = config?.defaultTTL ?? DEFAULT_CACHE_TTL\n const maxEntries = config?.maxEntries ?? 500\n const entries = new Map<string, CacheEntry>()\n\n function evictLRU() {\n if (entries.size <= maxEntries) return\n // Find the entry with the oldest lastAccess\n let oldestKey: string | null = null\n let oldestAccess = Infinity\n for (const [key, entry] of entries) {\n if (entry.lastAccess < oldestAccess) {\n oldestAccess = entry.lastAccess\n oldestKey = key\n }\n }\n if (oldestKey) entries.delete(oldestKey)\n }\n\n return {\n get<T>(key: string): T | undefined {\n const entry = entries.get(key)\n if (!entry) return undefined\n if (Date.now() > entry.expiresAt) {\n entries.delete(key)\n return undefined\n }\n entry.lastAccess = Date.now()\n return entry.data as T\n },\n\n set<T>(key: string, data: T, ttl?: number): void {\n const now = Date.now()\n entries.set(key, {\n data,\n expiresAt: now + (ttl ?? defaultTTL),\n lastAccess: now,\n })\n evictLRU()\n },\n\n invalidate(prefix: string): void {\n for (const key of entries.keys()) {\n if (key.startsWith(prefix)) {\n entries.delete(key)\n }\n }\n },\n\n clear(): void {\n entries.clear()\n },\n\n size(): number {\n return entries.size\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Global singleton — auto-flushes on tenant/org switch\n// ---------------------------------------------------------------------------\n\nexport const globalCache = createCacheStore()\n\n/** Flush the global cache — called by the tenant accessor when the active\n * tenant changes (replaces the old org-store subscription). */\nexport function clearGlobalCache(): void {\n globalCache.clear()\n}\n","// Active tenant context — a global accessor the data layer reads for tenant\n// scoping and cache keying. The host (saas shell / app) sets it from its org\n// store via setActiveTenantId; the data providers stay decoupled from any\n// specific org-store implementation (runtime DI).\nimport * as React from 'react'\nimport { clearGlobalCache } from './cache'\n\nlet _activeTenantId: string | undefined\nconst listeners = new Set<() => void>()\n\nexport function setActiveTenantId(id: string | undefined): void {\n if (id !== _activeTenantId) {\n _activeTenantId = id\n clearGlobalCache()\n for (const l of listeners) l()\n }\n}\n\nexport function getActiveTenantId(): string | undefined {\n return _activeTenantId\n}\n\n/**\n * Subscribes to tenant changes. A getter alone makes every read a race with the\n * shell: a view that mounts before the org store resolves reads `undefined`,\n * and a tenant-scoped fetch that answers \"no tenant\" looks exactly like \"no\n * rows\" — it never retries and the screen stays empty until a remount.\n */\nexport function subscribeActiveTenant(listener: () => void): () => void {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n}\n\n/** The active tenant, re-rendering when it resolves or changes. Use this to key\n * effects that fetch tenant-scoped data. */\nexport function useActiveTenantId(): string | undefined {\n return React.useSyncExternalStore(subscribeActiveTenant, getActiveTenantId, getActiveTenantId)\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { globalCache, getActiveTenantId, getSupabaseClientOptional, parseRangeFilter, matchesRange, stableKey, DEFAULT_CACHE_TTL, getScopedResource, createSupabaseProvider, resolveUnitScope, applyUnitScope, applyRangeToQuery, isFilterObject, clearGlobalCache } from './chunk-HVWFFFKN.js';
1
+ import { globalCache, getActiveTenantId, getSupabaseClientOptional, parseRangeFilter, matchesRange, assertWrote, stableKey, DEFAULT_CACHE_TTL, getScopedResource, createSupabaseProvider, resolveUnitScope, applyUnitScope, applyRangeToQuery, isFilterObject, clearGlobalCache } from './chunk-MFFT663T.js';
2
2
  import { declaredCustomFields, validateEntityRecordData } from './chunk-EWKX4VUM.js';
3
3
  import { errorMessage } from './chunk-6TVRNKWW.js';
4
4
  import * as React from 'react';
@@ -531,14 +531,19 @@ function createArchetypeProvider(config) {
531
531
  delete flat[fkColumn];
532
532
  return mapRow(liftCustom(flat));
533
533
  },
534
+ // `.select('id')` e não um delete mudo: a RLS recusa devolvendo 204 com
535
+ // zero linhas, e sem pedir as linhas de volta isso chega aqui como sucesso.
536
+ // Ver data/write-refused.
534
537
  async remove(id) {
535
- const { error } = await coreClient().from(ac.table).delete().eq("id", id);
538
+ const { data, error } = await coreClient().from(ac.table).delete().eq("id", id).select("id");
536
539
  if (error) throw error;
540
+ assertWrote(data);
537
541
  },
538
542
  async removeMany(ids) {
539
543
  if (!ids.length) return;
540
- const { error } = await coreClient().from(ac.table).delete().in("id", ids);
544
+ const { data, error } = await coreClient().from(ac.table).delete().in("id", ids).select("id");
541
545
  if (error) throw error;
546
+ assertWrote(data);
542
547
  }
543
548
  };
544
549
  }
@@ -849,9 +854,9 @@ function attachPersistentCache(store = globalCache, options = {}) {
849
854
  dbPromise = new Promise((resolve, reject) => {
850
855
  const request = indexedDB.open(dbName, DB_VERSION);
851
856
  request.onupgradeneeded = () => {
852
- const db = request.result;
853
- if (!db.objectStoreNames.contains(STORE_ENTRIES)) db.createObjectStore(STORE_ENTRIES);
854
- if (!db.objectStoreNames.contains(STORE_REPLICAS)) db.createObjectStore(STORE_REPLICAS);
857
+ const db2 = request.result;
858
+ if (!db2.objectStoreNames.contains(STORE_ENTRIES)) db2.createObjectStore(STORE_ENTRIES);
859
+ if (!db2.objectStoreNames.contains(STORE_REPLICAS)) db2.createObjectStore(STORE_REPLICAS);
855
860
  };
856
861
  request.onsuccess = () => resolve(request.result);
857
862
  request.onerror = () => reject(request.error ?? new Error("cache database failed to open"));
@@ -866,8 +871,8 @@ function attachPersistentCache(store = globalCache, options = {}) {
866
871
  });
867
872
  }
868
873
  async function transact(names, mode, run) {
869
- const db = await openDb();
870
- const tx = db.transaction(names, mode);
874
+ const db2 = await openDb();
875
+ const tx = db2.transaction(names, mode);
871
876
  const done = new Promise((resolve, reject) => {
872
877
  tx.oncomplete = () => resolve();
873
878
  tx.onerror = () => reject(tx.error ?? new Error("cache transaction failed"));
@@ -1094,7 +1099,7 @@ function attachPersistentCache(store = globalCache, options = {}) {
1094
1099
  store.invalidate = originalInvalidate;
1095
1100
  store.clear = originalClear;
1096
1101
  if (attached === handle) attached = null;
1097
- void dbPromise?.then((db) => db.close()).catch(() => {
1102
+ void dbPromise?.then((db2) => db2.close()).catch(() => {
1098
1103
  });
1099
1104
  dbPromise = null;
1100
1105
  }
@@ -1404,6 +1409,153 @@ function withCustomFields(provider, reference) {
1404
1409
  };
1405
1410
  }
1406
1411
 
1412
+ // src/data/attached-row.ts
1413
+ function db() {
1414
+ return getSupabaseClientOptional();
1415
+ }
1416
+ function withAttachedRow(provider, config) {
1417
+ const { fieldKey, table, ownerType, tenantId, toRow, toValue, isWritable } = config;
1418
+ async function save(ownerId, value) {
1419
+ const client = db();
1420
+ if (!client || !ownerId) return;
1421
+ const row = toRow(value);
1422
+ if (!isWritable(row)) return;
1423
+ const tid = tenantId();
1424
+ if (!tid) return;
1425
+ try {
1426
+ const { data: existing } = await client.from(table).select("id").eq("owner_type", ownerType).eq("owner_id", ownerId).eq("is_default", true).limit(1);
1427
+ const id = existing?.[0]?.id;
1428
+ if (id) await client.from(table).update(row).eq("id", id);
1429
+ else {
1430
+ await client.from(table).insert({
1431
+ ...row,
1432
+ ...config.defaults ?? {},
1433
+ tenant_id: tid,
1434
+ owner_type: ownerType,
1435
+ owner_id: ownerId,
1436
+ is_default: true
1437
+ });
1438
+ }
1439
+ } catch {
1440
+ }
1441
+ }
1442
+ async function attach(rows) {
1443
+ const client = db();
1444
+ if (!client || rows.length === 0) return;
1445
+ const ids = rows.map((r) => r.id).filter(Boolean);
1446
+ if (ids.length === 0) return;
1447
+ try {
1448
+ const { data } = await client.from(table).select("*").eq("owner_type", ownerType).in("owner_id", ids).eq("is_default", true);
1449
+ const byOwner = /* @__PURE__ */ new Map();
1450
+ for (const a of data ?? []) byOwner.set(String(a.owner_id), a);
1451
+ for (const r of rows) {
1452
+ const a = byOwner.get(String(r.id));
1453
+ if (a) r[fieldKey] = toValue(a);
1454
+ }
1455
+ } catch {
1456
+ }
1457
+ }
1458
+ function split(data) {
1459
+ const d = { ...data };
1460
+ const v = d[fieldKey];
1461
+ delete d[fieldKey];
1462
+ return { rest: d, value: v && typeof v === "object" ? v : void 0 };
1463
+ }
1464
+ return {
1465
+ ...provider,
1466
+ async list(query) {
1467
+ const result = await provider.list(query);
1468
+ await attach(result.data);
1469
+ return result;
1470
+ },
1471
+ async create(data) {
1472
+ const { rest, value } = split(data);
1473
+ const row = await provider.create(rest);
1474
+ if (value) await save(row.id, value);
1475
+ return value ? { ...row, [fieldKey]: value } : row;
1476
+ },
1477
+ async update(id, data) {
1478
+ const { rest, value } = split(data);
1479
+ const row = Object.keys(rest).length > 0 ? await provider.update(id, rest) : { id };
1480
+ if (value) await save(id, value);
1481
+ return value ? { ...row, [fieldKey]: value } : row;
1482
+ }
1483
+ };
1484
+ }
1485
+ var txtOf = (value) => (k) => {
1486
+ const v = value[k];
1487
+ const s = v == null ? "" : String(v).trim();
1488
+ return s === "" ? null : s;
1489
+ };
1490
+ var ADDRESS_ATTACHED = {
1491
+ table: "addresses",
1492
+ defaults: { kind: "both", label: "Principal" },
1493
+ toRow(value) {
1494
+ const t = txtOf(value);
1495
+ return {
1496
+ postal_code: t("postalCode"),
1497
+ street: t("street"),
1498
+ number: t("number"),
1499
+ complement: t("complement"),
1500
+ district: t("district"),
1501
+ city: t("city"),
1502
+ state: t("state"),
1503
+ country: t("country") ?? "BR"
1504
+ };
1505
+ },
1506
+ toValue(row) {
1507
+ return {
1508
+ postalCode: row.postal_code ?? "",
1509
+ street: row.street ?? "",
1510
+ number: row.number ?? "",
1511
+ complement: row.complement ?? "",
1512
+ district: row.district ?? "",
1513
+ city: row.city ?? "",
1514
+ state: row.state ?? "",
1515
+ country: row.country ?? "BR"
1516
+ };
1517
+ },
1518
+ /** CEP, rua, cidade e UF são NOT NULL em `addresses`. */
1519
+ isWritable: (row) => !!row.postal_code && !!row.street && !!row.city && !!row.state
1520
+ };
1521
+ var PAYEE_ACCOUNT_ATTACHED = {
1522
+ table: "payee_accounts",
1523
+ defaults: { label: "Principal" },
1524
+ toRow(value) {
1525
+ const t = txtOf(value);
1526
+ return {
1527
+ bank_code: t("bankCode"),
1528
+ bank_name: t("bankName"),
1529
+ agency_number: t("agencyNumber"),
1530
+ agency_digit: t("agencyDigit"),
1531
+ account_number: t("accountNumber"),
1532
+ account_digit: t("accountDigit"),
1533
+ account_type: t("accountType"),
1534
+ pix_key: t("pixKey"),
1535
+ pix_key_type: t("pixKeyType"),
1536
+ holder_name: t("holderName"),
1537
+ holder_document: t("holderDocument")
1538
+ };
1539
+ },
1540
+ toValue(row) {
1541
+ return {
1542
+ bankCode: row.bank_code ?? "",
1543
+ bankName: row.bank_name ?? "",
1544
+ agencyNumber: row.agency_number ?? "",
1545
+ agencyDigit: row.agency_digit ?? "",
1546
+ accountNumber: row.account_number ?? "",
1547
+ accountDigit: row.account_digit ?? "",
1548
+ accountType: row.account_type ?? "",
1549
+ pixKey: row.pix_key ?? "",
1550
+ pixKeyType: row.pix_key_type ?? "",
1551
+ holderName: row.holder_name ?? "",
1552
+ holderDocument: row.holder_document ?? ""
1553
+ };
1554
+ },
1555
+ /** O CHECK da 149: uma linha sem conta E sem PIX não é um dado. */
1556
+ isWritable: (row) => !!row.account_number || !!row.pix_key
1557
+ };
1558
+
1407
1559
  // src/data/resolve.ts
1408
1560
  function resolveDataProvider(entityDef, mockData, options = {}) {
1409
1561
  const backend = options.backend;
@@ -1457,8 +1609,18 @@ function resolveDataProvider(entityDef, mockData, options = {}) {
1457
1609
  const withL1 = options.cache === false ? p : withCache(p, cacheOptions);
1458
1610
  return withOffline(withL1, { ...cacheOptions, policy: offlinePolicy, entityDef });
1459
1611
  };
1612
+ const ownerType = entityDef.data?.addressOwnerType ?? "person";
1613
+ const attached2 = [];
1614
+ for (const f of entityDef.fields) {
1615
+ if (f.type === "address") attached2.push({ key: f.key, spec: ADDRESS_ATTACHED });
1616
+ if (f.type === "bank") attached2.push({ key: f.key, spec: PAYEE_ACCOUNT_ATTACHED });
1617
+ }
1618
+ const withAddress = (p) => attached2.reduce(
1619
+ (acc, a) => withAttachedRow(acc, { ...a.spec, fieldKey: a.key, ownerType, tenantId }),
1620
+ p
1621
+ );
1460
1622
  if (entityDef.data.archetype && entityDef.data.archetypeKind && !entityDef.data.schema) {
1461
- return cached(withCustomFields(createArchetypeProvider({
1623
+ return cached(withAddress(withCustomFields(createArchetypeProvider({
1462
1624
  archetype: entityDef.data.archetype,
1463
1625
  archetypeKind: entityDef.data.archetypeKind,
1464
1626
  projectTable: entityDef.data.table,
@@ -1466,9 +1628,9 @@ function resolveDataProvider(entityDef, mockData, options = {}) {
1466
1628
  tenantId,
1467
1629
  searchColumns: entityDef.data.searchColumns ?? entityDef.fields.filter((field) => field.searchable).map((field) => field.key),
1468
1630
  ...unitConfig
1469
- }), entityDef.data.archetype));
1631
+ }), entityDef.data.archetype)));
1470
1632
  }
1471
- return cached(createSupabaseProvider(entityDef.data.table, {
1633
+ return cached(withAddress(createSupabaseProvider(entityDef.data.table, {
1472
1634
  schema: entityDef.data.schema,
1473
1635
  tenantId: entityDef.data.tenantScoped === false ? void 0 : tenantId,
1474
1636
  tenantIdColumn: entityDef.data.tenantIdColumn,
@@ -1478,7 +1640,7 @@ function resolveDataProvider(entityDef, mockData, options = {}) {
1478
1640
  filters: entityDef.data.filters,
1479
1641
  defaults: entityDef.data.defaults,
1480
1642
  ...unitConfig
1481
- }));
1643
+ })));
1482
1644
  }
1483
1645
  if (entityDef.data?.table) {
1484
1646
  console.warn(
@@ -1768,5 +1930,5 @@ async function bulkRemove(provider, ids, options) {
1768
1930
  }
1769
1931
 
1770
1932
  export { CustomFieldsError, DATA_CHANGED_EVENT, DataError, FIELDS_TABLE, attachPersistentCache, bulkCreate, bulkRemove, cacheKeyFor, cachePrefixFor, clearCustomFieldsCache, countByTenant, createArchetypeProvider, createEventBus, createFayzApiProvider, createMockProvider, dataCall, dataQuery, emitDataChanged, eventBus, getActiveUnitId, getPersistentCache, invalidateCount, isKnownMissing, isUnitMode, localList, matchesDataChange, mergeCustomFields, registerDataTelemetry, rememberIfMissing, replicaKeyFor, resetActiveUnit, resetMissingObjects, resolveCustomFields, resolveDataProvider, setActiveUnitId, setUnitMode, subscribeActiveUnit, syncReplica, toDataError, useActiveUnitId, useDataChanged, useUnitMode, validateCustomFields, withCache, withOffline };
1771
- //# sourceMappingURL=chunk-XJGV7TWQ.js.map
1772
- //# sourceMappingURL=chunk-XJGV7TWQ.js.map
1933
+ //# sourceMappingURL=chunk-OI5K5E33.js.map
1934
+ //# sourceMappingURL=chunk-OI5K5E33.js.map