@fayz-ai/core 0.18.0 → 0.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access/engine.d.ts +15 -1
- package/dist/access/engine.d.ts.map +1 -1
- package/dist/access/index.js +2 -2
- package/dist/access/index.js.map +1 -1
- package/dist/app/app-config.d.ts +25 -0
- package/dist/app/app-config.d.ts.map +1 -1
- package/dist/{chunk-ED6NBH6U.js → chunk-3TRR2YLM.js} +2 -2
- package/dist/{chunk-ED6NBH6U.js.map → chunk-3TRR2YLM.js.map} +1 -1
- package/dist/{chunk-AOIYRUTF.js → chunk-4SPEISNL.js} +19 -5
- package/dist/chunk-4SPEISNL.js.map +1 -0
- package/dist/chunk-6TVRNKWW.js +17 -0
- package/dist/chunk-6TVRNKWW.js.map +1 -0
- package/dist/{chunk-OHH26S4N.js → chunk-7M4NWLIT.js} +9 -8
- package/dist/chunk-7M4NWLIT.js.map +1 -0
- package/dist/{chunk-2VY5IJW7.js → chunk-H6XDQXN5.js} +42 -14
- package/dist/chunk-H6XDQXN5.js.map +1 -0
- package/dist/{chunk-BCI743RH.js → chunk-HVWFFFKN.js} +4 -3
- package/dist/chunk-HVWFFFKN.js.map +1 -0
- package/dist/chunk-RBPDK2WB.js +104 -0
- package/dist/chunk-RBPDK2WB.js.map +1 -0
- package/dist/{chunk-2ZAUJVYP.js → chunk-S3EEGDEK.js} +122 -48
- package/dist/chunk-S3EEGDEK.js.map +1 -0
- package/dist/{chunk-KJUD6JA5.js → chunk-ZGAGCTQM.js} +6 -5
- package/dist/chunk-ZGAGCTQM.js.map +1 -0
- package/dist/connector-runtime/index.js +1 -1
- package/dist/data/archetype.d.ts +16 -0
- package/dist/data/archetype.d.ts.map +1 -1
- package/dist/data/bulk.d.ts.map +1 -1
- package/dist/data/index.js +3 -2
- package/dist/data/resolve.d.ts.map +1 -1
- package/dist/data/supabase.d.ts.map +1 -1
- package/dist/data/types.d.ts +13 -0
- package/dist/data/types.d.ts.map +1 -1
- package/dist/events/log.d.ts +1 -1
- package/dist/events/log.d.ts.map +1 -1
- package/dist/fields/store.d.ts +1 -1
- package/dist/fields/store.d.ts.map +1 -1
- package/dist/i18n/index.d.ts +11 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/shell-translations.en.d.ts.map +1 -1
- package/dist/i18n/shell-translations.pt-br.d.ts.map +1 -1
- package/dist/index.d.ts +9 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -12
- package/dist/index.js.map +1 -1
- package/dist/integrations/index.d.ts +8 -8
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +4 -3
- package/dist/integrations/request.d.ts +2 -2
- package/dist/integrations/request.d.ts.map +1 -1
- package/dist/integrations/runtime.d.ts +1 -1
- package/dist/integrations/runtime.d.ts.map +1 -1
- package/dist/integrations/settings.d.ts +1 -1
- package/dist/integrations/settings.d.ts.map +1 -1
- package/dist/integrations/store.d.ts +7 -7
- package/dist/integrations/store.d.ts.map +1 -1
- package/dist/interaction/haptics.d.ts +5 -0
- package/dist/interaction/haptics.d.ts.map +1 -0
- package/dist/interaction/index.d.ts +7 -0
- package/dist/interaction/index.d.ts.map +1 -0
- package/dist/interaction/index.js +3 -0
- package/dist/interaction/index.js.map +1 -0
- package/dist/interaction/keymap.d.ts +17 -0
- package/dist/interaction/keymap.d.ts.map +1 -0
- package/dist/interaction/roving.d.ts +9 -0
- package/dist/interaction/roving.d.ts.map +1 -0
- package/dist/lib/error-message.d.ts +21 -0
- package/dist/lib/error-message.d.ts.map +1 -0
- package/dist/orders/index.d.ts +114 -0
- package/dist/orders/index.d.ts.map +1 -0
- package/dist/orders/index.js +168 -0
- package/dist/orders/index.js.map +1 -0
- package/dist/plugin/index.js +2 -1
- package/dist/plugin/runtime.d.ts.map +1 -1
- package/dist/registry/extension-points.d.ts.map +1 -1
- package/dist/{shell-translations.pt-br-ZSSVWG6H.js → shell-translations.pt-br-GFBWBZZJ.js} +28 -12
- package/dist/shell-translations.pt-br-GFBWBZZJ.js.map +1 -0
- package/dist/testing/index.js +5 -4
- package/dist/testing.d.ts.map +1 -1
- package/dist/types/auth.d.ts +12 -0
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/crud.d.ts +42 -0
- package/dist/types/crud.d.ts.map +1 -1
- package/dist/types/onboarding.d.ts +25 -0
- package/dist/types/onboarding.d.ts.map +1 -1
- package/dist/types/plugins.d.ts +43 -0
- package/dist/types/plugins.d.ts.map +1 -1
- package/dist/types/setup-guide.d.ts +120 -0
- package/dist/types/setup-guide.d.ts.map +1 -0
- package/package.json +13 -4
- package/dist/chunk-2VY5IJW7.js.map +0 -1
- package/dist/chunk-2ZAUJVYP.js.map +0 -1
- package/dist/chunk-AOIYRUTF.js.map +0 -1
- package/dist/chunk-BCI743RH.js.map +0 -1
- package/dist/chunk-KJUD6JA5.js.map +0 -1
- package/dist/chunk-OHH26S4N.js.map +0 -1
- package/dist/shell-translations.pt-br-ZSSVWG6H.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/integrations/events.ts","../src/integrations/permissions.ts","../src/integrations/runtime-token.ts","../src/integrations/settings.ts","../src/integrations/store.ts","../src/integrations/request.ts","../src/integrations/index.ts"],"names":[],"mappings":"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","file":"chunk-OHH26S4N.js","sourcesContent":["// Event-key matching, in its own module so ./permissions can use it without\n// importing the barrel that re-exports ./permissions.\n\n/**\n * Whether a subscription pattern covers an event key. One implementation on\n * purpose: the ingress, the settings UI and the docs' examples all have to agree\n * on what `blog.post.*` means, and a second matcher is a silent divergence.\n */\nexport function eventKeyMatches(pattern: string, key: string): boolean {\n if (pattern === '*') return true\n if (!pattern.endsWith('*')) return pattern === key\n const prefix = pattern.slice(0, -1)\n return key.startsWith(prefix)\n}\n","// ---------------------------------------------------------------------------\n// What a connector needs — one declaration, three consumers\n// ---------------------------------------------------------------------------\n// A connector already said fragments of this in four places: `entities` named\n// record types with no notion of read or write, `subscribesTo` named events with\n// no notion of why, `managedAutomations` named reactions, and `invokedAt` named\n// call sites. None of them could answer the question a tenant actually asks\n// before authorizing — *what will this thing be able to touch, and why?* — and\n// two of them could contradict each other without anything noticing.\n//\n// So there is one list now. It is written once and read three times:\n//\n// 1. the consent view, before the tenant authorizes (packages/admin);\n// 2. \"quando ele age\", which now says what each moment reaches;\n// 3. eventually the minted credential's scope — FAY-1348 §D7: *\"a credencial\n// autoriza só as RPCs declaradas do conector … 'o que este conector pode\n// tocar' vira lista legível, e é a mesma lista para a nossa edge function e\n// para o servidor do parceiro.\"*\n//\n// Consumer 3 DOES NOT EXIST YET. Nothing on this platform reads a permission and\n// refuses a call — the token minting that would (FAY-1381) landed only its\n// browser-initiated half. That is why {@link connectorGrantScopes} exists and why\n// nothing calls it: the scope string is the shape D7 will enforce, written down\n// now so the declaration is already the right shape when enforcement arrives.\n// Until then the copy in front of the tenant says this is what the connector\n// DECLARES, never what the platform GUARANTEES. See the `connectors.permissions.*`\n// strings in ../i18n.\n//\n// The grammar is OAuth consent's, because that is the one people can already\n// read: a permission names a RESOURCE, the ACTIONS it needs on it, and a REASON\n// short enough to judge. Grouped by resource, read told apart from write,\n// anything sensitive marked.\n\nimport { eventKeyMatches } from './events'\n\n/**\n * What a permission is about.\n *\n * Two kinds and not one, because the actions differ and conflating them is how a\n * declaration stops being checkable: you cannot `listen` to a record type, and\n * \"write\" to an event means emitting a new fact, which is a different act from\n * updating a row.\n */\nexport type ConnectorResourceKind =\n /** A canonical record type in this app — `booking`, `movement`, `product`. */\n | 'data'\n /** A domain fact — an exact event key or a `*`-suffixed prefix. */\n | 'event'\n\n/**\n * Everything a connector can ask for. Which of these are legal depends on the\n * resource kind — see {@link permissionActions}.\n *\n * The three event actions are the founder's own words, and they are three\n * genuinely different exposures: `read` is the history that already exists,\n * `listen` is every fact from now on, `emit` is the connector putting facts into\n * the app that the app's own automations will then act on.\n */\nexport type ConnectorPermissionAction =\n /** Data: reads rows. Event: reads facts already recorded. */\n | 'read'\n /** Data only: creates, updates or deletes rows. */\n | 'write'\n /** Event only: receives matching facts as they happen. */\n | 'listen'\n /** Event only: publishes facts into this app. */\n | 'emit'\n\nconst DATA_ACTIONS = ['read', 'write'] as const\nconst EVENT_ACTIONS = ['read', 'listen', 'emit'] as const\n\n/** The actions a resource kind admits. Closed, and the contract check reads it. */\nexport function permissionActions(kind: ConnectorResourceKind): readonly ConnectorPermissionAction[] {\n return kind === 'data' ? DATA_ACTIONS : EVENT_ACTIONS\n}\n\n/**\n * One thing a connector needs access to, and why.\n *\n * `reason` is required and it is the field that makes the rest worth showing. A\n * list of `booking: read, write` is a schema dump; *\"para criar o evento no\n * Google quando um horário é marcado\"* is something a salon owner can agree or\n * disagree with. Everything else on this screen is checkable by a machine; this\n * is the part only the tenant can judge, so it cannot be optional.\n */\nexport interface ConnectorPermission {\n kind: ConnectorResourceKind\n /** Entity name (`'booking'`) or event key/prefix (`'agenda.booking_created'`, `'blog.post.*'`). */\n resource: string\n /** What it needs to do. Non-empty, and legal for `kind`. */\n actions: ConnectorPermissionAction[]\n /** One sentence, in the tenant's language, that a tenant can judge. */\n reason: string\n /**\n * Money, identity, health, or anything a leak of which is a reportable event.\n * Marked because the reader scans this list rather than reading it, and a bank\n * statement should not look like a product name on the way past.\n */\n sensitive?: boolean\n}\n\n/** Whether a permission names a record type. */\nexport function isDataPermission(permission: ConnectorPermission): boolean {\n return permission.kind === 'data'\n}\n\n/** Whether a permission names a domain fact. */\nexport function isEventPermission(permission: ConnectorPermission): boolean {\n return permission.kind === 'event'\n}\n\n/** Whether a permission asks for an action. */\nexport function grants(permission: ConnectorPermission, action: ConnectorPermissionAction): boolean {\n return permission.actions.includes(action)\n}\n\n/** Anything that carries a permission list — a definition, or a plain object in a test. */\nexport interface PermissionBearing {\n permissions?: ConnectorPermission[]\n /** Legacy mirror of the `data` resources. See {@link connectorEntities}. */\n entities?: string[]\n /** Legacy mirror of the `listen` resources. See {@link connectorSubscribesTo}. */\n subscribesTo?: string[]\n}\n\n/** The permission list, or an empty one. Undeclared means the connector says nothing. */\nexport function connectorPermissions(def: PermissionBearing | undefined): ConnectorPermission[] {\n return def?.permissions ?? []\n}\n\n/**\n * The record types a connector touches — derived from `permissions`, falling\n * back to the legacy `entities` field.\n *\n * Derived and not duplicated: a connector that declares permissions must not\n * also maintain a parallel list of names, because the two would drift and the\n * screen would show one of them. A connector that declares BOTH is not merged —\n * the contract check refuses it unless they agree exactly, which is the whole\n * point of keeping the old field readable at all.\n */\nexport function connectorEntities(def: PermissionBearing | undefined): string[] {\n const declared = connectorPermissions(def).filter(isDataPermission).map((p) => p.resource)\n if (declared.length > 0) return unique(declared)\n return unique(def?.entities ?? [])\n}\n\n/**\n * The event patterns a connector wants delivered — derived from the `listen`\n * permissions, falling back to the legacy `subscribesTo` field.\n *\n * This is the ingress's filter, and it reads through here rather than off the\n * field so a connector that declares only `permissions` is still heard. Same\n * agreement rule as {@link connectorEntities}.\n */\nexport function connectorSubscribesTo(def: PermissionBearing | undefined): string[] {\n const declared = connectorPermissions(def)\n .filter((p) => isEventPermission(p) && grants(p, 'listen'))\n .map((p) => p.resource)\n if (declared.length > 0) return unique(declared)\n return unique(def?.subscribesTo ?? [])\n}\n\n/** Whether a connector asked to hear about this event. Undeclared = hears nothing. */\nexport function connectorSubscribes(def: PermissionBearing | undefined, key: string): boolean {\n return connectorSubscribesTo(def).some((pattern) => eventKeyMatches(pattern, key))\n}\n\n/** Whether the connector asks to change anything at all — data or events. */\nexport function permissionsWrite(def: PermissionBearing | undefined): boolean {\n return connectorPermissions(def).some((p) => grants(p, 'write') || grants(p, 'emit'))\n}\n\n/** Whether anything in the list was marked sensitive. */\nexport function hasSensitivePermission(def: PermissionBearing | undefined): boolean {\n return connectorPermissions(def).some((p) => p.sensitive === true)\n}\n\n/**\n * The list a consent view renders: data first, then events; within each,\n * sensitive first, then read-only, then alphabetical.\n *\n * Read-only last within a kind is deliberate. What a reader must not miss is\n * what changes their records, so the ordering puts the consequential rows where\n * the eye lands and leaves the harmless ones to be skimmed. Sorting is here and\n * not in the component so the order is assertable without rendering.\n */\nexport function sortedPermissions(def: PermissionBearing | undefined): ConnectorPermission[] {\n return [...connectorPermissions(def)].sort((a, b) => {\n if (a.kind !== b.kind) return a.kind === 'data' ? -1 : 1\n const sensitivity = Number(b.sensitive ?? false) - Number(a.sensitive ?? false)\n if (sensitivity !== 0) return sensitivity\n const mutating = Number(mutates(b)) - Number(mutates(a))\n if (mutating !== 0) return mutating\n return a.resource.localeCompare(b.resource)\n })\n}\n\nfunction mutates(permission: ConnectorPermission): boolean {\n return grants(permission, 'write') || grants(permission, 'emit')\n}\n\n/**\n * The permissions grouped as the consent view shows them.\n *\n * One entry per resource, because a resource is what a person reasons about — a\n * screen that lists `booking · leitura` and `booking · escrita` as two rows asks\n * the reader to do the grouping themselves.\n */\nexport function groupedPermissions(def: PermissionBearing | undefined): {\n data: ConnectorPermission[]\n events: ConnectorPermission[]\n} {\n const sorted = sortedPermissions(def)\n return {\n data: sorted.filter(isDataPermission),\n events: sorted.filter(isEventPermission),\n }\n}\n\n/**\n * The declaration as scope strings — `data:booking:write`, `event:blog.post.*:listen`.\n *\n * **Nothing enforces these today.** This is the third consumer from the header,\n * and it is written now for one reason: FAY-1348 §D7 says the minted credential\n * authorizes exactly the connector's declared list, and a list that has to be\n * reshaped when that lands is a list that will be reshaped wrongly. One resource\n * yields one scope per action, sorted, so the string set is stable enough to be\n * compared across a mint and a renewal.\n */\nexport function connectorGrantScopes(def: PermissionBearing | undefined): string[] {\n const scopes: string[] = []\n for (const permission of connectorPermissions(def)) {\n for (const action of permission.actions) scopes.push(`${permission.kind}:${permission.resource}:${action}`)\n }\n return unique(scopes).sort()\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values)]\n}\n","// ---------------------------------------------------------------------------\n// The runtime token, where a connector can reach it\n// ---------------------------------------------------------------------------\n// FAY-1389 gave the data plane a way to READ a credential\n// (`redeemConnectorCredential`) and was explicit about the constraint: an edge\n// function cannot mint a runtime token, it forwards the one the request\n// carried. Which leaves the question of who puts it on the request.\n//\n// For the two flows that already existed there was an answer, because the app\n// hands the token straight to the thing that needs it — `runtimeToken` is an\n// option of `createFayzConnectorCredentialSink` and of\n// `createFayzConnectorOAuthStarter`. A PULL connector has no such seam: it\n// invokes its own edge function from a panel, and until now had nowhere to ask.\n//\n// So this is a port, for the same reason the credential sink is one: who mints\n// the token is a DEPLOYMENT fact. The app that already writes\n//\n// const runtimeToken = createFayzRuntimeTokenSource({ projectId, supabase })\n// setConnectorCredentialSink(createFayzConnectorCredentialSink({ …, runtimeToken }))\n// setConnectorOAuthStarter(createFayzConnectorOAuthStarter({ …, runtimeToken }))\n//\n// adds one line with the handle it already has:\n//\n// setConnectorRuntimeTokenSource(runtimeToken)\n//\n// Installing none is a valid answer. A connector that needs one then refuses,\n// which is the correct behaviour for an app whose data plane could not prove\n// which tenant it is running for — the alternative is an edge function that\n// answers without knowing, and that is the whole thing FAY-1389 closed.\n//\n// It lives in `@fayz-ai/core` rather than in `@fayz-ai/sdk` because the callers\n// are plugins, and plugins already depend on core. Nothing here mints, caches\n// or validates a token: the source does all three (see\n// `createFayzRuntimeTokenSource`), and duplicating any of it would be a second\n// cache to go stale.\n\n/** What the hub knows about who is asking — a SELECTOR, never an assertion. */\nexport interface ConnectorRuntimeTokenRequest {\n /**\n * Which of the caller's own organizations this call is for.\n *\n * The platform proves membership from the session behind the token and\n * refuses anything outside it, so naming one narrows and can never widen.\n * Without it, an operator who belongs to two schools cannot be told apart\n * from one who belongs to neither.\n */\n tenantId?: string\n}\n\n/** A token, or something that produces one. Same shape the SDK's source has. */\nexport type ConnectorRuntimeTokenSource =\n | string\n | ((\n request?: ConnectorRuntimeTokenRequest,\n ) => string | undefined | null | Promise<string | undefined | null>)\n\n/** No token, so the call was not made. Distinct from a call that was refused. */\nexport class ConnectorRuntimeTokenUnavailableError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ConnectorRuntimeTokenUnavailableError'\n }\n}\n\nlet _source: ConnectorRuntimeTokenSource | null = null\n\nexport function setConnectorRuntimeTokenSource(source: ConnectorRuntimeTokenSource | null): void {\n _source = source\n}\n\n/** Null when the app configured none — callers must refuse, never fall back. */\nexport function getConnectorRuntimeTokenSource(): ConnectorRuntimeTokenSource | null {\n return _source\n}\n\n/**\n * The token to forward to a data plane, or a refusal.\n *\n * Throws rather than returning empty on both failure modes, and they are told\n * apart in the message: no source configured is a deployment that was never\n * wired, an empty answer is a session that cannot mint one right now. A caller\n * that treated either as \"carry on\" would send an unauthenticated request to a\n * function that must not answer it.\n */\nexport async function connectorRuntimeToken(request?: ConnectorRuntimeTokenRequest): Promise<string> {\n const source = _source\n if (!source) {\n throw new ConnectorRuntimeTokenUnavailableError(\n 'This app installed no connector runtime-token source, so the data plane cannot prove which tenant it is for',\n )\n }\n const value = typeof source === 'function' ? await source(request) : source\n const token = typeof value === 'string' ? value.trim() : ''\n if (!token) {\n throw new ConnectorRuntimeTokenUnavailableError(\n 'No runtime token is available for this session, so the call was not made',\n )\n }\n return token\n}\n\n// The header both halves name. It is DECLARED in ./runtime.ts and re-exported\n// here: the edge function that reads it cannot import this module (React and\n// supabase-js come with it), and `@fayz-ai/core/connector-runtime` is the entry\n// built to load under Deno. One constant, two importers, no second spelling.\nexport { CONNECTOR_RUNTIME_TOKEN_HEADER } from './runtime'\n","// ---------------------------------------------------------------------------\n// Operational settings — what a connector needs to WORK, not to be authorized\n// ---------------------------------------------------------------------------\n// `ConnectorField` used to carry two unrelated things. \"Qual é a sua chave\" is\n// needed to CONNECT: one-time, and the connection cannot exist without it.\n// \"Quais formas de pagamento você aceita\" is needed to OPERATE: it changes with\n// the season, and asking for it on the connect screen makes a merchant decide\n// commercial policy before they are allowed to plug the provider in. Worse, it\n// made \"aceito boleto agora\" look like re-authorizing the account.\n//\n// So they are two declarations. `fields` stays the credential form; `settings`\n// is this — asked for AFTER the connection exists, rendered through the same\n// settings rows every plugin's Settings tab already uses.\n//\n// Two consequences the types carry rather than a convention:\n//\n// 1. There is no `password` setting type, and there never will be. A settings\n// key is written to `plg_connections.settings`, a jsonb any member of the\n// tenant can read; the credential path is `fields` + the platform sink and\n// it is the only one.\n// 2. A setting can be REQUIRED TO OPERATE without being required to connect.\n// Melhor Envio quotes nothing without an origin postcode, but refusing the\n// connection over it is the very conflation this file undoes. The\n// connection is made and reported as `pending` — \"conectado, falta\n// configurar\" — which is a state `plg_connections.status` already has.\n//\n// This module is imported by BOTH ./index.ts (the contract) and ./store.ts (the\n// persistence), so it declares no dependency on either.\n\n/**\n * How a setting is asked for.\n *\n * Closed, and short on purpose: each member is a control someone has to build,\n * localize and test. It grew to exactly what the two real cases needed — a\n * multi-select for payment methods, a constrained text for a postcode — and the\n * next one is added by whoever has the next real case.\n */\nexport type ConnectorSettingType =\n /** One line, optionally shaped by `pattern` (a postcode, a CNPJ). */\n | 'text'\n /** Exactly one of `options`. */\n | 'select'\n /** Any number of `options`; persisted as a `string[]`. */\n | 'multi-select'\n /** On/off; persisted as a boolean. */\n | 'toggle'\n\n/** One choice of a `select` / `multi-select`. */\nexport interface ConnectorSettingOption {\n value: string\n label: string\n}\n\n/** A value a setting can hold. Never a secret — see the module header. */\nexport type ConnectorSettingValue = string | string[] | boolean\n\n/**\n * One operational setting a connector exposes once it is connected.\n *\n * The declaration is what kills the free-text box: \"pix, boleto, credit_card\"\n * typed into an input is three chances to misspell a value the storefront then\n * silently does not offer. A `multi-select` over declared options cannot be\n * misspelled, and it is the same declaration the store validates writes against.\n */\nexport interface ConnectorSetting {\n /** Key inside `plg_connections.settings`. Must not collide with a credential field. */\n key: string\n label: string\n /** The sentence under the label — the same affordance every settings row has. */\n description?: string\n type: ConnectorSettingType\n /** Required for `select` and `multi-select`, meaningless elsewhere. */\n options?: ConnectorSettingOption[]\n /** `text` only. */\n placeholder?: string\n /**\n * `text` only: the shape the value must have, as a RegExp source anchored by\n * the renderer. A postcode is eight digits or it is not a postcode, and\n * finding that out at the first quote is finding it out from a buyer.\n */\n pattern?: string\n /** What the reader is told when `pattern` refuses. Required whenever `pattern` is set. */\n patternHint?: string\n /**\n * The connector cannot do its job until this is chosen — and is still\n * connectable without it. See the module header.\n */\n requiredToOperate?: boolean\n /** Offered when the connection has no value yet. Never written on its own. */\n defaultValue?: ConnectorSettingValue\n}\n\n/**\n * A setting counts as chosen when it holds something.\n *\n * `''` and `[]` are not values: an empty multi-select is a merchant who accepts\n * no payment method, which is indistinguishable from one who has not decided,\n * and treating it as decided is what would let a store go live accepting\n * nothing. `false` IS a value — a toggle turned off was answered.\n */\nexport function isSettingSet(value: unknown): boolean {\n if (value === undefined || value === null) return false\n if (typeof value === 'string') return value.trim().length > 0\n if (Array.isArray(value)) return value.length > 0\n return true\n}\n\n/** The declared settings of a connector, or none. */\nexport function connectorSettings(def: { settings?: ConnectorSetting[] }): ConnectorSetting[] {\n return def.settings ?? []\n}\n\n/**\n * Which required-to-operate settings this connection has not got.\n *\n * Keys, never values — the answer is rendered as copy and persisted into\n * `status_detail`, and neither is a place for what the tenant typed.\n */\nexport function missingRequiredSettings(\n settings: ConnectorSetting[] | undefined,\n values: Record<string, unknown> | undefined | null,\n): string[] {\n return (settings ?? [])\n .filter((setting) => setting.requiredToOperate && !isSettingSet(values?.[setting.key]))\n .map((setting) => setting.key)\n}\n\n/** What {@link settingsStatus} contributes to a `ConnectorStatus`. */\nexport interface SettingsReadiness {\n /** Connected, and unable to work until something is chosen. */\n needsSetup: boolean\n /** The keys that are missing. Present only when `needsSetup`. */\n missingSettings?: string[]\n}\n\n/**\n * The setup half of a connector's status, derived from the row the list already\n * read.\n *\n * Derived and not merely read back from `status`, because the declaration is the\n * truth: a connector that gains a required setting in a new version must report\n * \"falta configurar\" on connections saved before that version existed, and no\n * write happened to those rows to say so.\n */\nexport function settingsStatus(\n settings: ConnectorSetting[] | undefined,\n connection: { active?: boolean; settings?: Record<string, unknown> } | null | undefined,\n): SettingsReadiness {\n if (!connection?.active) return { needsSetup: false }\n const missing = missingRequiredSettings(settings, connection.settings)\n return missing.length > 0 ? { needsSetup: true, missingSettings: missing } : { needsSetup: false }\n}\n\n/** `status_detail` for a connection waiting on configuration. Keys only. */\nexport function setupStatusDetail(missing: string[]): string {\n return `setup: ${missing.join(', ')}`\n}\n","import { getSupabaseClientOptional } from '../data/supabase'\nimport { getActiveTenantId } from '../lib/tenant'\nimport type { ConnectionConfig, ConnectorField, ConnectorStatus, Cursor, SyncRun } from './index'\nimport {\n missingRequiredSettings,\n setupStatusDetail,\n type ConnectorSetting,\n type ConnectorSettingValue,\n} from './settings'\n\n/**\n * The one data layer every connector shares. A connector declares a\n * ConnectorDefinition and writes no SQL: `plg_connections` and `plg_sync_runs`\n * (migration 029) are read and written from here.\n *\n * `recordRun` is deliberately absent. A run is a server-side write — the table\n * carries no INSERT grant for `authenticated`, because a history the\n * application can write is not a history.\n *\n * Opt-in, not mandatory: a connector whose truth lives entirely at the provider\n * (Stripe Connect) stores nothing here rather than keeping a second source of\n * truth that derives from the first.\n */\n\nexport const CONNECTIONS_TABLE = 'plg_connections'\nexport const SYNC_RUNS_TABLE = 'plg_sync_runs'\n\n/** A settings key that is not declared, or is a credential. */\nexport class ConnectionSettingsError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ConnectionSettingsError'\n }\n}\n\nexport interface ConnectionStoreOptions {\n /** The connector's declared fields — the allow-list `save()` checks against. */\n fields?: ConnectorField[]\n /**\n * The connector's declared operational settings. Their keys are allowed, and\n * the required-to-operate ones decide whether a saved connection reads as\n * `connected` or as `pending` — see {@link createConnectionStore}.\n */\n settings?: ConnectorSetting[]\n /** Non-credential keys the connector writes itself (a chosen calendar, an import mode). */\n settingsKeys?: string[]\n /** Which account at the provider. `''` (default) is the single-account case. */\n instanceKey?: string\n /** Tenant override; defaults to the active tenant. */\n tenantId?: string\n /** Supabase client override; defaults to the globally registered one. */\n client?: unknown\n}\n\n/** The mutable half of a connection. `status` is absent on purpose: it is observed server-side. */\nexport interface ConnectionSaveInput {\n settings?: Record<string, unknown>\n displayName?: string | null\n active?: boolean\n providerAccountKey?: string | null\n}\n\nexport interface ConnectionStore {\n readonly connectorId: string\n readonly instanceKey: string\n get(): Promise<ConnectionConfig | null>\n save(input?: ConnectionSaveInput): Promise<ConnectionConfig>\n disconnect(): Promise<void>\n listRuns(options?: { limit?: number }): Promise<SyncRun[]>\n}\n\n/**\n * The keys a connector is allowed to put in `settings`: its declared\n * non-credential fields, plus anything it named in `settingsKeys`.\n *\n * Rejecting is the point. Without it, \"settings never holds a credential\" is a\n * comment in a migration — three connectors already broke that comment. With\n * it, a `type: 'password'` field arriving as a settings key is an error with a\n * name, and the doctor has a rule it can run.\n */\nexport function assertSettingsAllowed(\n settings: Record<string, unknown>,\n options: Pick<ConnectionStoreOptions, 'fields' | 'settings' | 'settingsKeys'>,\n connectorId = 'connector',\n): void {\n const secret = new Set((options.fields ?? []).filter((f) => f.type === 'password').map((f) => f.key))\n const allowed = new Set<string>([\n ...(options.fields ?? []).filter((f) => f.type !== 'password').map((f) => f.key),\n // A declared setting IS its own allow-list entry. Requiring it in\n // `settingsKeys` as well is two places to add a key and one place to forget.\n ...(options.settings ?? []).map((s) => s.key),\n ...(options.settingsKeys ?? []),\n ])\n for (const key of Object.keys(settings)) {\n if (secret.has(key)) {\n throw new ConnectionSettingsError(\n `[${connectorId}] \"${key}\" is a credential field — credentials never reach plg_connections.settings.`,\n )\n }\n if (!allowed.has(key)) {\n throw new ConnectionSettingsError(\n `[${connectorId}] unknown settings key \"${key}\". Declare it in the connector's fields or settingsKeys.`,\n )\n }\n }\n}\n\n// ── Row mapping ─────────────────────────────────────────────────────────────\n// Written out rather than run through the generic snake↔camel mapper: these two\n// tables are a contract, and a column silently renamed by a heuristic is the\n// kind of thing that only shows up in a pool.\n\ntype Row = Record<string, unknown>\n\nfunction toConnection(row: Row): ConnectionConfig {\n return {\n id: row.id as string,\n tenantId: row.tenant_id as string,\n connectorId: row.connector_id as string,\n instanceKey: (row.instance_key as string) ?? '',\n displayName: (row.display_name as string | null) ?? null,\n active: row.active as boolean,\n status: row.status as ConnectionConfig['status'],\n statusDetail: (row.status_detail as string | null) ?? null,\n settings: (row.settings as Record<string, unknown>) ?? {},\n providerAccountKey: (row.provider_account_key as string | null) ?? null,\n cursors: (row.cursors as Record<string, Cursor>) ?? {},\n lastSyncAt: (row.last_sync_at as string | null) ?? null,\n createdAt: row.created_at as string,\n updatedAt: row.updated_at as string,\n }\n}\n\nfunction toRun(row: Row): SyncRun {\n const stats = (row.stats as Record<string, unknown>) ?? {}\n return {\n id: row.id as string,\n tenantId: row.tenant_id as string,\n connectionId: row.connection_id as string,\n connectorId: row.connector_id as string,\n direction: row.direction as SyncRun['direction'],\n triggerKind: row.trigger_kind as SyncRun['triggerKind'],\n status: row.status as SyncRun['status'],\n stream: (row.stream as string | null) ?? null,\n fetched: (row.fetched as number) ?? 0,\n written: (row.written as number) ?? 0,\n stats,\n cursor: (row.cursor as string | null) ?? null,\n correlationId: (row.correlation_id as string | null) ?? null,\n // `stats.message` is the pre-031 home; read it so a pool that has not\n // applied 031 yet still shows the sentence rather than a blank row.\n message: (row.message as string | null) ?? (stats.message as string | undefined) ?? null,\n error: (row.error as string | null) ?? null,\n startedAt: row.started_at as string,\n finishedAt: (row.finished_at as string | null) ?? null,\n }\n}\n\n// ── The narrow slice of supabase-js this needs ──────────────────────────────\n\ninterface Answer<T> {\n data: T\n error: { message: string } | null\n}\n\ninterface Filterable extends PromiseLike<Answer<Row[] | null>> {\n eq: (column: string, value: unknown) => Filterable\n in: (column: string, values: readonly unknown[]) => Filterable\n order: (column: string, opts: { ascending: boolean }) => Filterable\n limit: (n: number) => Filterable\n select: (columns?: string) => Filterable\n single: () => Promise<Answer<Row | null>>\n maybeSingle: () => Promise<Answer<Row | null>>\n}\n\ninterface Table {\n select: (columns?: string) => Filterable\n upsert: (values: Row, opts?: { onConflict?: string }) => Filterable\n update: (values: Row) => Filterable\n}\n\ninterface Client {\n from: (table: string) => Table\n}\n\nfunction unwrap<T>(answer: Answer<T>, what: string): T {\n if (answer.error) throw new Error(`[@fayz-ai/core] ${what}: ${answer.error.message}`)\n return answer.data\n}\n\n/**\n * The connection store for one connector, on one account.\n *\n * @param connectorId Stable connector id, e.g. 'google-calendar'.\n */\nexport function createConnectionStore(connectorId: string, options: ConnectionStoreOptions = {}): ConnectionStore {\n const instanceKey = options.instanceKey ?? ''\n\n function client(): Client {\n const c = (options.client ?? getSupabaseClientOptional()) as Client | null\n if (!c) throw new Error('[@fayz-ai/core] Supabase client not available. Call createFayzApp with a provider first.')\n return c\n }\n\n function tenantId(): string {\n const id = options.tenantId ?? getActiveTenantId()\n if (!id) throw new Error(`[@fayz-ai/core] createConnectionStore(${connectorId}): no active tenant.`)\n return id\n }\n\n function scoped(q: Filterable): Filterable {\n return q.eq('tenant_id', tenantId()).eq('connector_id', connectorId).eq('instance_key', instanceKey)\n }\n\n const store: ConnectionStore = {\n connectorId,\n instanceKey,\n\n async get() {\n const row = unwrap(\n await scoped(client().from(CONNECTIONS_TABLE).select('*')).maybeSingle(),\n `read ${CONNECTIONS_TABLE}`,\n )\n return row ? toConnection(row) : null\n },\n\n async save(input: ConnectionSaveInput = {}) {\n const patch = input.settings ?? {}\n assertSettingsAllowed(patch, options, connectorId)\n\n // MERGE BY KEY, never replace. Every bespoke saveConnection today upserts\n // the whole jsonb, so a panel and an edge function writing different keys\n // erase each other in silence. Read-modify-write is the cheap half of the\n // fix; the atomic half is a `settings || patch` RPC, still owed.\n const current = await store.get()\n const settings = { ...(current?.settings ?? {}), ...patch }\n\n const row: Row = {\n tenant_id: tenantId(),\n connector_id: connectorId,\n instance_key: instanceKey,\n settings,\n updated_at: new Date().toISOString(),\n }\n if (input.displayName !== undefined) row.display_name = input.displayName\n if (input.active !== undefined) row.active = input.active\n if (input.providerAccountKey !== undefined) row.provider_account_key = input.providerAccountKey\n if (current?.id) row.id = current.id\n\n // The ONE dimension of `status` the app owns: whether the tenant has\n // chosen the settings the connector cannot operate without. Provider\n // health ('error', 'revoked') is observed server-side and is left exactly\n // as found — a connection the provider revoked must not read as connected\n // again because someone picked a payment method.\n //\n // A connector that declares NO settings has nothing to be pending ON, and\n // it used to fall through this block entirely — so the row kept the\n // table's `pending` default forever. Bling authorized at the provider,\n // came back, and still read as not connected, which sent the merchant\n // round the consent screen again. \"Nothing to fill in\" is ready, not\n // waiting.\n const missing = options.settings?.length\n ? missingRequiredSettings(options.settings, settings)\n : []\n // Turning a connection ON again is the one case that may clear `revoked`:\n // the tenant just re-authorized. A settings save must not, which is why\n // this reads `input.active` rather than the row's.\n const reactivating = input.active === true\n if (missing.length > 0) {\n row.status = 'pending'\n row.status_detail = setupStatusDetail(missing)\n } else if (!current || current.status === 'pending' || (reactivating && current.status === 'revoked')) {\n row.status = 'connected'\n row.status_detail = null\n }\n\n const saved = unwrap(\n await client()\n .from(CONNECTIONS_TABLE)\n .upsert(row, { onConflict: 'tenant_id,connector_id,instance_key' })\n .select('*')\n .single(),\n `write ${CONNECTIONS_TABLE}`,\n )\n if (!saved) throw new Error(`[@fayz-ai/core] write ${CONNECTIONS_TABLE}: no row returned.`)\n return toConnection(saved)\n },\n\n async disconnect() {\n // Soft: the run history outlives the connection, and `active` is the\n // tenant's switch. Settings and cursors are cleared so a reconnect starts\n // from nothing rather than resuming a cursor the provider no longer honours.\n const answer = await scoped(\n client().from(CONNECTIONS_TABLE).update({\n active: false,\n status: 'revoked',\n settings: {},\n cursors: {},\n updated_at: new Date().toISOString(),\n }),\n )\n unwrap(answer, `disconnect ${CONNECTIONS_TABLE}`)\n },\n\n async listRuns(opts = {}) {\n const connection = await store.get()\n if (!connection?.id) return []\n const answer = await client()\n .from(SYNC_RUNS_TABLE)\n .select('*')\n .eq('connection_id', connection.id)\n .order('started_at', { ascending: false })\n .limit(opts.limit ?? 20)\n const rows = unwrap(answer, `read ${SYNC_RUNS_TABLE}`)\n return (rows ?? []).map(toRun)\n },\n }\n\n return store\n}\n\n// ── Reading many connections at once ────────────────────────────────────────\n\n/** Map key for {@link listConnections}. A connection is (connector, account). */\nexport function connectionKey(connectorId: string, instanceKey = ''): string {\n return `${connectorId}\u0000${instanceKey}`\n}\n\nexport interface ListConnectionsOptions {\n /** Tenant override; defaults to the active tenant. */\n tenantId?: string\n /** Supabase client override; defaults to the globally registered one. */\n client?: unknown\n}\n\n/**\n * Every named connector's row in ONE read.\n *\n * The connectors screen used to cost one `plg_connections` GET per connector,\n * because each connector asked for its own row through its own store — N round\n * trips to fill one list. They all share the table, so `connector_id=in.(…)`\n * answers all of them at once.\n *\n * The tenant is part of the QUERY, never of a cache key alone: a caller that\n * holds this map across a tenant switch is holding the wrong tenant's rows, so\n * the map is deliberately returned, not stored.\n */\nexport async function listConnections(\n connectorIds: readonly string[],\n options: ListConnectionsOptions = {},\n): Promise<Map<string, ConnectionConfig>> {\n const found = new Map<string, ConnectionConfig>()\n const ids = [...new Set(connectorIds)].filter(Boolean)\n if (ids.length === 0) return found\n\n const c = (options.client ?? getSupabaseClientOptional()) as Client | null\n if (!c) throw new Error('[@fayz-ai/core] Supabase client not available. Call createFayzApp with a provider first.')\n const tenantId = options.tenantId ?? getActiveTenantId()\n if (!tenantId) throw new Error('[@fayz-ai/core] listConnections: no active tenant.')\n\n const rows = unwrap(\n await c.from(CONNECTIONS_TABLE).select('*').eq('tenant_id', tenantId).in('connector_id', ids),\n `read ${CONNECTIONS_TABLE}`,\n )\n for (const row of rows ?? []) {\n const connection = toConnection(row)\n found.set(connectionKey(connection.connectorId, connection.instanceKey), connection)\n }\n return found\n}\n\n/** What {@link connectionStatus} contributes to a ConnectorDefinition. */\nexport interface ConnectionBackedStatus {\n instanceKey: string\n statusFromConnection: (connection: ConnectionConfig | null) => ConnectorStatus\n getStatus: () => Promise<ConnectorStatus>\n}\n\n/**\n * Wire a connector's status badge to its `plg_connections` row.\n *\n * One `derive` answers both doors: `getStatus()` for a screen showing this\n * connector alone, and `statusFromConnection` for a screen showing a list — the\n * list hands it a row it already read in a batch, so N connectors cost one\n * request instead of N. Spread the result into the definition.\n *\n * A connector whose truth lives at the provider (Stripe Connect) writes its own\n * `getStatus` and declares no `statusFromConnection`; the list then reads it\n * one-by-one, which is correct because there is no shared row to batch.\n */\n/** What {@link connectionSettings} contributes to a ConnectorDefinition. */\nexport interface ConnectionSettingsIO {\n getSettings: () => Promise<Record<string, unknown>>\n saveSettings: (values: Record<string, ConnectorSettingValue>) => Promise<void>\n}\n\n/**\n * Wire a connector's settings form to its `plg_connections.settings` jsonb.\n *\n * Spread into the definition, the same way {@link connectionStatus} is. Every\n * store-backed connector would otherwise write the same four lines, and the one\n * that wrote them slightly differently would be the one that replaced the jsonb\n * instead of merging into it.\n */\nexport function connectionSettings(store: ConnectionStore): ConnectionSettingsIO {\n return {\n async getSettings() {\n return (await store.get())?.settings ?? {}\n },\n async saveSettings(values) {\n await store.save({ settings: values })\n },\n }\n}\n\n/** What {@link connectionRuns} contributes to a ConnectorDefinition. */\nexport interface ConnectionRunsIO {\n listRuns: (options?: { limit?: number }) => Promise<SyncRun[]>\n}\n\n/**\n * Wire a connector's history to its `plg_sync_runs` rows.\n *\n * Spread into the definition, like {@link connectionStatus} and\n * {@link connectionSettings}. Swallowing is the point: a history is never the\n * reason a connector's screen fails to render, and \"no rows\" and \"unreadable\"\n * are the same answer to somebody asking what has happened.\n */\nexport function connectionRuns(store: ConnectionStore | (() => ConnectionStore)): ConnectionRunsIO {\n return {\n async listRuns(options) {\n try {\n // Either shape, because both are already in use: a module-level store\n // (Melhor Envio) and a factory called per read (Bling). A factory is the\n // safer default — nothing is resolved until somebody asks.\n return await (typeof store === 'function' ? store() : store).listRuns(options)\n } catch {\n return []\n }\n },\n }\n}\n\nexport function connectionStatus(\n connectorId: string,\n derive: (connection: ConnectionConfig | null) => ConnectorStatus,\n options: { instanceKey?: string; store?: () => ConnectionStore } = {},\n): ConnectionBackedStatus {\n const instanceKey = options.instanceKey ?? ''\n return {\n instanceKey,\n statusFromConnection: derive,\n async getStatus() {\n try {\n const store = options.store?.() ?? createConnectionStore(connectorId, { instanceKey })\n return derive(await store.get())\n } catch {\n // No client, no tenant, or an unreadable row — \"not connected\" is the\n // honest answer for a badge, and never a broken list.\n return { connected: false }\n }\n },\n }\n}\n","// ---------------------------------------------------------------------------\n// The request plane — the connector the buyer is waiting on\n// ---------------------------------------------------------------------------\n// gcal, PlugBank and RankLayer are asynchronous: nobody is waiting, a failed run\n// is retried later, and the audit trail is the product. Checkout inverts all\n// three. The shopper is on the page, there is a budget, and a failure has to be\n// answered NOW — with a worse answer, or with a refusal, but never with a\n// spinner that never ends.\n//\n// So the request plane needs four things the sync plane never asked for, and\n// they live here rather than inside AppMax or Melhor Envio because both need\n// all four:\n//\n// 1. a LATENCY BUDGET, declared by the connector, enforced by the caller;\n// 2. FAILURE SEMANTICS as a field, because the two connectors want opposite\n// ones — freight that fails must not stop the sale, payment that fails must\n// stop it — and \"which one\" is a property of the connector, not a decision\n// re-taken in every screen that happens to call it;\n// 3. an IDEMPOTENCY story keyed by the BUYER's intent, so a double-clicked\n// \"pagar\" is one charge;\n// 4. the line between a QUOTE and an EFFECT. A quote is not a run: see\n// {@link runEffect} and packages/db/migrations/029+030.\n//\n// What the plane deliberately does NOT get is a row per invocation. See the\n// header of 029_connections.sql.\nimport type { ConnectorDefinition, ConnectorDirection, SyncTrigger } from './index'\n\n/**\n * What the connector does when the provider does not answer in time.\n *\n * `degrade` — serve a worse answer and let the buyer continue (shipping falls\n * back to the configured zone; the sale is never blocked by a carrier's API).\n * `block` — refuse the step and tell the buyer why (a payment that did not\n * confirm must not read as a confirmed order).\n */\nexport type RequestFailureMode = 'degrade' | 'block'\n\n/** Why the provider's answer was not used. Codes, not copy — the UI writes the pt-BR. */\nexport type DegradeReason =\n /** The latency budget was spent before the provider answered. */\n | 'timeout'\n /** The provider answered with an error, or the call threw. */\n | 'provider-error'\n /** There is no live connection for this connector — nothing was called. */\n | 'not-connected'\n\n/** The answer, plus where it came from. Provenance is not optional: a fallback price shown as a provider price is how a store quotes one number and charges another. */\nexport interface RequestOutcome<T> {\n value: T\n source: 'provider' | 'fallback'\n /** Wall time spent on the provider attempt. Reported even when it timed out. */\n elapsedMs: number\n /** Present exactly when `source` is 'fallback'. */\n degraded?: { reason: DegradeReason; detail?: string }\n}\n\n/**\n * A `block` connector refused the step. Carries a reason code the checkout maps\n * to copy — it is thrown AT the buyer's request, so it must say something.\n */\nexport class RequestBlockedError extends Error {\n readonly connectorId: string\n readonly reason: DegradeReason\n readonly elapsedMs: number\n constructor(connectorId: string, reason: DegradeReason, elapsedMs: number, detail?: string) {\n super(`[${connectorId}] request plane blocked: ${reason}${detail ? ` — ${detail}` : ''}`)\n this.name = 'RequestBlockedError'\n this.connectorId = connectorId\n this.reason = reason\n this.elapsedMs = elapsedMs\n }\n}\n\n/**\n * The connector's declaration is wrong. Never reaches a buyer: it fires the\n * first time the connector is exercised, which is a test or a dev boot.\n */\nexport class RequestPlaneError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'RequestPlaneError'\n }\n}\n\n/** A connector's request-plane declaration, after validation. */\nexport interface ResolvedRequestPlane {\n latencyBudgetMs: number\n onFailure: RequestFailureMode\n}\n\ntype RequestPlaneDecl = Pick<ConnectorDefinition, 'id' | 'planes' | 'latencyBudgetMs' | 'onFailure'>\n\n/**\n * Read a connector's request-plane declaration, or say why it has none.\n *\n * There is no default budget on purpose. A default is a number nobody chose,\n * and this one decides how long a stranger stares at a spinner; \"3000 because\n * that is what the helper does\" is exactly the decision the contract exists to\n * force someone to make.\n */\nexport function requestPlaneSpec(def: RequestPlaneDecl): ResolvedRequestPlane {\n const planes = def.planes ?? ['sync']\n if (!planes.includes('request')) {\n throw new RequestPlaneError(`[${def.id}] is not on the request plane — declare planes: ['request'].`)\n }\n if (typeof def.latencyBudgetMs !== 'number' || !Number.isFinite(def.latencyBudgetMs) || def.latencyBudgetMs <= 0) {\n throw new RequestPlaneError(\n `[${def.id}] request-plane connector must declare latencyBudgetMs — how long the buyer may wait.`,\n )\n }\n if (def.onFailure !== 'degrade' && def.onFailure !== 'block') {\n throw new RequestPlaneError(\n `[${def.id}] request-plane connector must declare onFailure: 'degrade' | 'block'. ` +\n `Shipping degrades (the sale continues); payment blocks (the order does not confirm).`,\n )\n }\n return { latencyBudgetMs: def.latencyBudgetMs, onFailure: def.onFailure }\n}\n\n/** True when the connector declares a usable request plane. Never throws — for a UI badge. */\nexport function hasRequestPlane(def: RequestPlaneDecl): boolean {\n try {\n requestPlaneSpec(def)\n return true\n } catch {\n return false\n }\n}\n\nexport interface RequestAttempt<T> {\n /**\n * The provider call. The signal aborts when the budget is spent — honour it\n * so the socket closes, but the budget is enforced regardless of whether you do.\n */\n call(signal: AbortSignal): Promise<T>\n /**\n * The worse answer, for `degrade` connectors. Must be LOCAL (a database row, a\n * configured zone) — a fallback that itself calls a network is a second budget\n * nobody declared. Required when `onFailure` is 'degrade'.\n */\n fallback?(reason: DegradeReason, detail?: string): T | Promise<T>\n /** Skip the provider entirely — no live connection, connector switched off. */\n skip?: boolean\n /** Injectable clock, for tests that assert elapsed time without sleeping. */\n now?(): number\n}\n\n/**\n * Run one request-plane invocation under the connector's declared budget and\n * failure semantics.\n *\n * Writes nothing. A quote is not a run: it has no fetched, no written and no\n * cursor, it is issued for an `anon` shopper with no tenant-scoped write path,\n * and one row per quote would make plg_sync_runs the largest table in the pool\n * within weeks. Effects go through {@link runEffect}, which does file a row.\n */\nexport async function runRequest<T>(def: RequestPlaneDecl, attempt: RequestAttempt<T>): Promise<RequestOutcome<T>> {\n const spec = requestPlaneSpec(def)\n const now = attempt.now ?? (() => Date.now())\n const started = now()\n\n const degradeOrBlock = async (reason: DegradeReason, detail?: string): Promise<RequestOutcome<T>> => {\n const elapsedMs = now() - started\n if (spec.onFailure === 'block') throw new RequestBlockedError(def.id, reason, elapsedMs, detail)\n if (!attempt.fallback) {\n // Degrading with nothing to degrade TO is blocking with worse manners: the\n // buyer gets an exception from a connector that promised never to throw.\n throw new RequestPlaneError(\n `[${def.id}] declares onFailure: 'degrade' but the call supplied no fallback. ` +\n `Degrading requires an answer to degrade to.`,\n )\n }\n return {\n value: await attempt.fallback(reason, detail),\n source: 'fallback',\n elapsedMs,\n degraded: { reason, detail },\n }\n }\n\n if (attempt.skip) return degradeOrBlock('not-connected')\n\n const controller = new AbortController()\n let timer: ReturnType<typeof setTimeout> | undefined\n // Raced rather than merely signalled: a provider client that ignores the\n // AbortSignal would otherwise hold the page for as long as it likes, and the\n // budget would be documentation.\n const budget = new Promise<'timeout'>((resolve) => {\n timer = setTimeout(() => resolve('timeout'), spec.latencyBudgetMs)\n })\n\n try {\n const raced = await Promise.race([\n attempt.call(controller.signal).then((value) => ({ ok: true as const, value })),\n budget,\n ])\n if (raced === 'timeout') {\n controller.abort()\n return await degradeOrBlock('timeout', `budget of ${spec.latencyBudgetMs}ms spent`)\n }\n return { value: raced.value, source: 'provider', elapsedMs: now() - started }\n } catch (error) {\n if (error instanceof RequestBlockedError || error instanceof RequestPlaneError) throw error\n return await degradeOrBlock('provider-error', error instanceof Error ? error.message : String(error))\n } finally {\n if (timer) clearTimeout(timer)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Effects — the half of the request plane that IS a run\n// ---------------------------------------------------------------------------\n// Capturing a payment and buying a label are not quotes. They move money and\n// they are worth one row each: they have a status, an error, a duration and a\n// stats bag, which is exactly plg_sync_runs. What they additionally need — and\n// the sync plane never did, because nobody double-clicks a cron — is a claim\n// that survives a retry.\n\nexport type EffectStatus = 'success' | 'partial' | 'error'\n\nexport interface EffectClaimInput {\n /** Which connection is acting. The tenant is resolved FROM it, never passed in. */\n connectionId: string\n /** Buyer-derived. See {@link buyerIdempotencyKey}. */\n idempotencyKey: string\n direction: ConnectorDirection\n triggerKind: SyncTrigger\n stream?: string\n}\n\nexport interface EffectClaim {\n /** The plg_sync_runs row this effect owns — the same id on every retry of the key. */\n runId: string\n /** `false` = the key already ran. Do not call the provider. */\n claimed: boolean\n}\n\n/**\n * The durable claim. The one implementation that matters is\n * `plg_claim_effect` / `plg_settle_effect` (packages/db 030): the run row IS the\n * claim, so \"file the run\" and \"win the race\" are one statement and cannot\n * disagree. Both are service_role only — the shopper never reaches them.\n */\nexport interface EffectLedger {\n claim(input: EffectClaimInput): Promise<EffectClaim>\n settle(input: { runId: string; status: EffectStatus; stats?: Record<string, unknown>; error?: string }): Promise<void>\n}\n\nexport interface EffectOutcome<T> {\n runId: string\n /** `true` when THIS call reached the provider. `false` = the key had already run. */\n performed: boolean\n value?: T\n}\n\n/**\n * Perform an effect at most once per idempotency key.\n *\n * The claim comes first and the provider call second, in that order and never\n * the reverse: a claim written after a successful capture leaves a window in\n * which the retry captures again. A claim that then fails is settled as an\n * error and stays claimed — the retry does not re-charge, an operator decides.\n */\nexport async function runEffect<T>(\n ledger: EffectLedger,\n input: EffectClaimInput,\n perform: (runId: string) => Promise<T>,\n): Promise<EffectOutcome<T>> {\n if (!input.idempotencyKey) {\n throw new RequestPlaneError('runEffect requires an idempotencyKey — an effect nobody can name twice is an effect that runs twice.')\n }\n const claim = await ledger.claim(input)\n if (!claim.claimed) return { runId: claim.runId, performed: false }\n\n try {\n const value = await perform(claim.runId)\n await ledger.settle({ runId: claim.runId, status: 'success' })\n return { runId: claim.runId, performed: true, value }\n } catch (error) {\n await ledger.settle({\n runId: claim.runId,\n status: 'error',\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n}\n\n/** The slice of supabase-js the ledger calls. Two RPCs, no table access. */\ninterface RpcClient {\n rpc(fn: string, args: Record<string, unknown>): PromiseLike<{ data: unknown; error: { message: string } | null }>\n}\n\n/**\n * The shipped {@link EffectLedger}: `plg_claim_effect` / `plg_settle_effect`\n * (packages/db 030). Both are service_role only, so this is constructed inside\n * the data plane — an edge function — and never in a page the shopper loads.\n */\nexport function createRpcEffectLedger(client: RpcClient): EffectLedger {\n const call = async (fn: string, args: Record<string, unknown>): Promise<unknown> => {\n const { data, error } = await client.rpc(fn, args)\n if (error) throw new Error(`[@fayz-ai/core] ${fn}: ${error.message}`)\n return data\n }\n\n return {\n async claim(input) {\n // The function RETURNS TABLE, so PostgREST answers with a one-row array.\n const rows = (await call('plg_claim_effect', {\n p_connection_id: input.connectionId,\n p_idempotency_key: input.idempotencyKey,\n p_direction: input.direction,\n p_trigger_kind: input.triggerKind,\n p_stream: input.stream ?? null,\n })) as Array<{ run_id: string; claimed: boolean }> | { run_id: string; claimed: boolean } | null\n const row = Array.isArray(rows) ? rows[0] : rows\n if (!row?.run_id) throw new Error('[@fayz-ai/core] plg_claim_effect returned no run')\n return { runId: row.run_id, claimed: !!row.claimed }\n },\n async settle(input) {\n await call('plg_settle_effect', {\n p_run_id: input.runId,\n p_status: input.status,\n p_stats: input.stats ?? {},\n p_error: input.error ?? null,\n })\n },\n }\n}\n\n/**\n * The key the buyer's intent produces — never the provider's id.\n *\n * The provider's id only exists AFTER the call that must not happen twice, so a\n * key derived from it cannot prevent the second one. `pagar` clicked twice is the\n * same order for the same amount, and that is what has to hash to one key.\n *\n * The amount is part of it deliberately: a re-tried capture for a DIFFERENT\n * amount is a different intent and must be allowed through, not silently\n * swallowed as a duplicate.\n */\nexport function buyerIdempotencyKey(parts: { effect: string; subject: string; amountCents?: number }): string {\n const { effect, subject, amountCents } = parts\n if (!effect || !subject) {\n throw new RequestPlaneError('buyerIdempotencyKey needs both an effect and a subject (the order, the shipment).')\n }\n // Readable on purpose: this string shows up in a support conversation about a\n // charge, and an opaque hash there costs an hour.\n return amountCents === undefined ? `${effect}:${subject}` : `${effect}:${subject}:${amountCents}`\n}\n","// ---------------------------------------------------------------------------\n// Integration Connector spine\n// ---------------------------------------------------------------------------\n// An integration is a connector that keeps canonical Fayz data in agreement\n// with an external provider (Google Calendar, open banking, Shopify, …). This\n// module is the thin shared contract both native (SDK) and client-built\n// connectors implement. The heavy lifting (auth, fetch/push, idempotent\n// upserts) runs in the data plane — typically a Supabase Edge Function — while\n// the control plane (a settings tab + this contract) lives in the app/plugin.\n//\n// Design notes live in docs/integrations/bling-integration-brief.md. Proven precedents:\n// the Fayz runtime OAuth broker (packages/core/src/runtime/oauth.ts) and the\n// bank-statement edge functions in the predecessor app.\nimport type * as React from 'react'\nimport type { ConnectorPermission } from './permissions'\nimport type { RequestFailureMode } from './request'\nimport type { Completeness, Cursor, RateLimitBudget } from './runtime'\nimport type { ConnectorSetting, ConnectorSettingValue } from './settings'\n\n// What a connector NEEDS ACCESS TO, declared apart from what it does with it.\n// See ./permissions.ts for the grammar and for what does and does not enforce it.\nexport {\n permissionActions,\n isDataPermission,\n isEventPermission,\n grants,\n connectorPermissions,\n connectorEntities,\n connectorSubscribesTo,\n connectorSubscribes,\n permissionsWrite,\n hasSensitivePermission,\n sortedPermissions,\n groupedPermissions,\n connectorGrantScopes,\n} from './permissions'\nexport type {\n ConnectorPermission,\n ConnectorPermissionAction,\n ConnectorResourceKind,\n PermissionBearing,\n} from './permissions'\n\nexport { eventKeyMatches } from './events'\n\n// Where a PULL connector gets the token its own edge function has to forward.\n// See ./runtime-token.ts for why this is a port and not a helper.\nexport {\n CONNECTOR_RUNTIME_TOKEN_HEADER,\n ConnectorRuntimeTokenUnavailableError,\n connectorRuntimeToken,\n getConnectorRuntimeTokenSource,\n setConnectorRuntimeTokenSource,\n} from './runtime-token'\nexport type { ConnectorRuntimeTokenRequest, ConnectorRuntimeTokenSource } from './runtime-token'\n\nexport {\n createConnectionStore,\n listConnections,\n connectionKey,\n connectionStatus,\n connectionSettings,\n connectionRuns,\n assertSettingsAllowed,\n ConnectionSettingsError,\n CONNECTIONS_TABLE,\n SYNC_RUNS_TABLE,\n} from './store'\nexport type {\n ConnectionStore,\n ConnectionStoreOptions,\n ConnectionSaveInput,\n ConnectionBackedStatus,\n ConnectionSettingsIO,\n ConnectionRunsIO,\n ListConnectionsOptions,\n} from './store'\n\n// Operational configuration — what a connector needs to WORK, declared apart\n// from what it needs to be AUTHORIZED. See ./settings.ts for why they split.\nexport {\n connectorSettings,\n isSettingSet,\n missingRequiredSettings,\n settingsStatus,\n setupStatusDetail,\n} from './settings'\nexport type {\n ConnectorSetting,\n ConnectorSettingType,\n ConnectorSettingOption,\n ConnectorSettingValue,\n SettingsReadiness,\n} from './settings'\n\nexport {\n runRequest,\n runEffect,\n requestPlaneSpec,\n hasRequestPlane,\n buyerIdempotencyKey,\n createRpcEffectLedger,\n RequestBlockedError,\n RequestPlaneError,\n} from './request'\nexport type {\n RequestFailureMode,\n DegradeReason,\n RequestOutcome,\n RequestAttempt,\n ResolvedRequestPlane,\n EffectLedger,\n EffectClaim,\n EffectClaimInput,\n EffectOutcome,\n EffectStatus,\n} from './request'\n// The data-plane mechanics. They live in ./runtime because that module has no\n// runtime imports and is built to its own entry (`@fayz-ai/core/connector-runtime`),\n// so a Deno edge function can load it without pulling supabase-js or React in.\nexport {\n ConnectorHttpError,\n RateLimitExceededError,\n parseRetryAfter,\n backoffDelay,\n classify,\n statusNeedsBody,\n fetchWithRetry,\n isExpiring,\n paginate,\n createRateLimiter,\n sliceWindow,\n advanceWindow,\n serializeCursor,\n reconcileMirror,\n cursorCompleteness,\n} from './runtime'\nexport type {\n Cursor,\n Completeness,\n Verdict,\n AttemptOutcome,\n ClassifyOptions,\n BackoffOptions,\n FetchWithRetryOptions,\n MinimalResponse,\n PageResult,\n PaginateOptions,\n PaginateResult,\n RateLimitBudget,\n RateLimiter,\n RateLimiterOptions,\n MirrorRecord,\n ReconcileInput,\n ReconcileResult,\n} from './runtime'\n\n/** How a connector authenticates to its provider. */\nexport type IntegrationAuthKind = 'oauth' | 'api-key' | 'mtls'\n\n// ---------------------------------------------------------------------------\n// Categories — the shelf a connector is filed under\n// ---------------------------------------------------------------------------\n// The vocabulary is the platform catalogue's, mirrored here because three\n// things have to agree on it and only one of them lives in that repo: the\n// connector that declares a category, the badge that renders it, and the\n// catalogue row it joins to by slug. A free-form string agreed with none of\n// them — `bling` shipped as `'commerce'`, a word the catalogue has never used,\n// and the badge silently rendered nothing for a year's worth of screens.\n//\n// The rule for a new connector, in one line: **take the category from the\n// catalogue row with the same slug; if there is no such row yet, pick the shelf\n// a shopkeeper would look on, and add the row.** The list below is closed on\n// purpose — widening it is a decision, and a decision needs the seed changed\n// too, which is exactly the review this is meant to force.\n//\n// Source of truth: fayz/packages/db/prisma/seeds/connectors.seed.ts.\nexport const CONNECTOR_CATEGORIES = [\n /** The provider IS a database or backend the app is built on. */\n 'database',\n /** Money in: gateways, acquirers, Pix. */\n 'payments',\n /** A bank account read (open banking, statements) — not a gateway. */\n 'banking',\n /** Stock, invoicing, back office. */\n 'erp',\n /** Freight quotes, labels, tracking. */\n 'logistics',\n /** Someone else's storefront the business also sells on (iFood, Shopee). */\n 'marketplace',\n /** The business's OWN online store. */\n 'ecommerce',\n /** Contacts, deals, pipeline. */\n 'crm',\n /** Courses sold by a third party (Hotmart, Kiwify). */\n 'courses',\n /** Bookings and calendars. */\n 'scheduling',\n /** Conversations: WhatsApp, SMS, email campaigns. */\n 'messaging',\n /** Measurement, pixels, SEO. */\n 'analytics',\n /** Presence on a map or a directory (Google Meu Negócio). */\n 'local',\n /** Models and agent frameworks. */\n 'ai',\n /** Wiring between other tools (Zapier, n8n). */\n 'automation',\n] as const\n\n/** A shelf in the connector catalogue. See {@link CONNECTOR_CATEGORIES}. */\nexport type ConnectorCategory = (typeof CONNECTOR_CATEGORIES)[number]\n\nconst CATEGORY_SET: ReadonlySet<string> = new Set<string>(CONNECTOR_CATEGORIES)\n\n/** Whether a string is a category the catalogue knows. */\nexport function isConnectorCategory(value: unknown): value is ConnectorCategory {\n return typeof value === 'string' && CATEGORY_SET.has(value)\n}\n\n// ---------------------------------------------------------------------------\n// Planes — the two ways a connector gets honoured\n// ---------------------------------------------------------------------------\n// \"Integração\" and \"conector\" are the same noun. What differs is the plane it\n// runs on:\n//\n// - 'agentic' — the provider's tools are handed to the assistant. Nothing is\n// copied: the agent calls the provider at the moment it needs the answer,\n// so there is no mirror to drift and no de-para to maintain. Preferred\n// whenever the provider offers it.\n// - 'sync' — the old-school pipeline: authorize, map, run, keep an audit\n// trail. Required when the data must exist *inside* Fayz — to be listed,\n// filtered, reported on, or read while the provider is unreachable.\n// - 'request' — the provider is asked, in line, for an answer that is used\n// once and never stored: a shipping quote, a checkout session. It has a\n// connection like any other connector, but it has no runs. Recording one\n// row per quote would make plg_sync_runs the largest table in the pool\n// within weeks, and the caller is an anonymous buyer with no tenant-scoped\n// write path anyway. The *effects* a quote leads to (capture the payment,\n// buy the label) are ordinary sync runs.\n//\n// A connector may support both; `preferredPlane` encodes the house rule.\nexport type ConnectorPlane = 'agentic' | 'sync' | 'request'\n\n/** Which side reaches for the other, from this app's point of view. */\nexport type ConnectorDirection = 'inbound' | 'outbound'\n\n/** A tool the assistant gains once a connector is resolved on the agentic plane. */\nexport interface ConnectorAgentTool {\n name: string\n description?: string\n}\n\n/** Which way data flows for a given capability. */\nexport type SyncDirection = 'inbound' | 'outbound' | 'bidirectional'\n\n/** What causes a sync to run. */\nexport type SyncTrigger = 'on-write' | 'scheduled' | 'manual' | 'webhook'\n\n/** One thing a connector can sync (an entity + its direction + triggers). */\nexport interface ConnectorCapability {\n /** Canonical entity synced, e.g. 'booking', 'movement'. */\n entity: string\n direction: SyncDirection\n triggers: SyncTrigger[]\n}\n\n// `Cursor`, `Completeness` and `cursorCompleteness` are declared in ./runtime and\n// re-exported above — the data plane needs them and cannot import this module.\n\n/**\n * One row of `public.plg_connections` (migration 029) — a tenant's connection to\n * ONE account at one provider. Two accounts are two rows, separated by\n * `instanceKey`; two resources inside one account are two streams of one row.\n *\n * There is no credential field because the table has no credential column.\n */\nexport interface ConnectionConfig {\n id?: string\n tenantId?: string\n /** Connector id, e.g. 'google-calendar', 'plugbank'. */\n connectorId: string\n /** Which account at the provider. `''` for the connectors that only ever have one. */\n instanceKey: string\n displayName?: string | null\n /** The tenant's switch. */\n active: boolean\n /** Health, observed server-side — not a mirror of `active`. */\n status: ConnectionStatusValue\n statusDetail?: string | null\n /** Provider-specific config, restricted to the connector's declared field keys. Never secrets. */\n settings: Record<string, unknown>\n /** The provider's own id for the account — how an inbound webhook finds the tenant. */\n providerAccountKey?: string | null\n /** Resume state keyed BY STREAM: Google keeps a syncToken per calendar, not per connection. */\n cursors: Record<string, Cursor>\n lastSyncAt?: string | null\n createdAt?: string\n updatedAt?: string\n}\n\n/** Server-observed health of a connection (`plg_connections.status`). */\nexport type ConnectionStatusValue = 'pending' | 'connected' | 'error' | 'revoked'\n\n/** One row of `public.plg_sync_runs` (migration 029) — one execution of the sync plane. */\nexport interface SyncRun {\n id?: string\n tenantId?: string\n /** Which connection ran. Without it two bank accounts share one history. */\n connectionId: string\n connectorId: string\n direction: ConnectorDirection\n /** `trigger` is a reserved word in Postgres; the column is `trigger_kind`. */\n triggerKind: SyncTrigger\n status: 'running' | 'success' | 'partial' | 'error'\n /** Which resource inside the account this run touched. */\n stream?: string | null\n fetched?: number\n written?: number\n /** Counters that are the connector's own: duplicates, discovered, period_from/to. */\n stats?: Record<string, unknown>\n /** The cursor this run advanced to, serialised. */\n cursor?: string | null\n /** Ties an outbound push to the inbound echo it will provoke. */\n correlationId?: string | null\n /**\n * What the run has to SAY, on any status (migration 031). `error` is what went\n * WRONG; a successful run with something to report used to smuggle it through\n * `stats.message`, which is the ad-hoc convention the generic table exists to\n * prevent.\n */\n message?: string | null\n error?: string | null\n startedAt?: string\n finishedAt?: string | null\n}\n\n/**\n * What a connector's sync returns. Distinct from {@link SyncRun}: `completeness`\n * is not a column, it is the verdict the engine needs BEFORE it decides whether\n * records missing from this result may be cancelled locally.\n */\nexport interface SyncResult {\n status: 'success' | 'partial' | 'error'\n completeness: Completeness\n fetched?: number\n written?: number\n /** Advanced cursor, to be written back under its stream key. */\n cursor?: Cursor\n stats?: Record<string, unknown>\n error?: string\n}\n\nexport interface TestConnectionResult {\n ok: boolean\n message?: string\n}\n\n/**\n * A connector's control-plane descriptor. The data-plane verbs (testConnection,\n * sync) are usually thin clients that invoke a Supabase Edge Function — the\n * function holds credentials and does the real work.\n */\nexport interface Connector {\n /** Stable connector id, e.g. 'google-calendar', 'plugbank'. */\n id: string\n /** Provider key matching ConnectionConfig.provider. */\n provider: string\n /** Plugin this connector extends, e.g. 'agenda', 'financial'. */\n pluginId: string\n authKind: IntegrationAuthKind\n capabilities: ConnectorCapability[]\n /** Validate the stored credentials/config without syncing. */\n testConnection?(config: ConnectionConfig): Promise<TestConnectionResult>\n /** Run a sync for the given direction; the caller files the run server-side. */\n sync?(input: { config: ConnectionConfig; direction: SyncDirection; trigger: SyncTrigger }): Promise<SyncResult>\n}\n\n// ---------------------------------------------------------------------------\n// Connector UI contract — how an addon plugin EXTENDS a host plugin's settings\n// ---------------------------------------------------------------------------\n// An addon plugin declares one or more ConnectorDefinitions on its manifest\n// (`connectors: [...]`). The runtime groups them by `hostPluginId`, and the host\n// plugin's settings panel renders them in a unified \"Integrations\" tab — the\n// same connect/credentials experience for every connector. The connector-\n// specific bits arrive through four named seams and not one catch-all panel:\n// `ConnectorStatus.issues` (what is wrong), `listRuns` (what has happened),\n// `RunActions` (make something happen) and `ExtraPanel` (configuration).\n\n/**\n * An input the connect step renders — **what authorizes the connection**, and\n * nothing else.\n *\n * The rule, in one line: if the connection cannot be established without it, it\n * is a field; if it changes how a live connection behaves, it is a\n * {@link ConnectorSetting}. An API key is a field. The account identifier the\n * key is scoped to is a field. Which payment methods the store accepts, or which\n * postcode it ships from, is not — see ./settings.ts.\n *\n * `type: 'password'` is the marker the credential seam reads: a password field\n * never reaches connector-author code and never reaches\n * `plg_connections.settings`.\n */\nexport interface ConnectorField {\n key: string\n label: string\n type: 'text' | 'password'\n placeholder?: string\n /**\n * Route this to the credential sink even though it is not masked.\n *\n * For the half of a credential PAIR that is not itself confidential — AppMax\n * issues `client_id` alongside `client_secret`, and the id is useless to\n * anyone without the secret. Masking it would only stop the merchant checking\n * they pasted the right one; letting it fall through to the connector's own\n * `saveConnection` would split one credential across two stores, which is\n * how half of it ends up in a pool table.\n */\n secret?: boolean\n}\n\n/**\n * A door the merchant goes through AT THE PROVIDER before the connect step can\n * be finished — and the reason the hub does not have to know which provider.\n *\n * Not every partner hands back a code on a redirect. AppMax issues the\n * `client_id`/`client_secret` pair when the merchant INSTALLS our app inside\n * their own AppMax admin (\"chaves emitidas na instalação do app\"), and only\n * then shows them something to copy. An OAuth button there would be a button\n * that lies: nothing comes back, and pressing it could never connect anything.\n * What is true is a two-step gesture — go install it there, come back and paste\n * what it showed you — so the gesture is declared and the panel renders it\n * above {@link ConnectorDefinition.fields}.\n *\n * Declared and not hardcoded in the UI because the address is a fact about\n * THIS app's registration at that provider, which the hub cannot know and a\n * second connector with the same gesture will spell differently.\n *\n * An OAuth connector declares none: consent is the install.\n */\nexport interface ConnectorProviderInstall {\n /** Where the merchant installs this app at the provider. Opened in a new tab. */\n url: string\n}\n\n/**\n * What the hub knows about who is connecting, handed to\n * {@link ConnectorDefinition.startOAuth}.\n *\n * `tenantId` is a SELECTOR and never an assertion: the platform proves\n * membership from the token it was called with and refuses anything outside it,\n * so naming an organization here narrows which of the caller's own orgs the\n * consent is for and can never widen it. Without it a merchant who belongs to\n * two organizations cannot be told apart from one who belongs to neither.\n */\nexport interface ConnectorConnectContext {\n tenantId?: string\n}\n\n/**\n * An automation the connector owns rather than the tenant.\n *\n * \"New sale → send it to Bling\" is not a preference someone chose; it is what\n * the integration IS. So it appears in the automations screen only while the\n * connection is live, and the screen must not offer to delete it — a deleted\n * row would leave the integration connected and silently half-wired, which\n * reads as \"Bling stopped working\" weeks later. Disconnecting is the way out.\n */\nexport interface ConnectorManagedAutomation {\n /** Domain event that fires it. Must be covered by `subscribesTo`. */\n eventKey: string\n /** What the tenant is told it does (\"Send the sale to Bling\"). */\n label: string\n /** Whether the tenant may switch it off and stay connected. Default false. */\n optional?: boolean\n}\n\n// ---------------------------------------------------------------------------\n// \"Acionado em quais momentos\" — the call sites a connector participates in\n// ---------------------------------------------------------------------------\n// Three of the four answers already had a vocabulary. `subscribesTo` says which\n// facts it listens to, `managedAutomations` says which reactions it owns, and\n// `trigger_kind` on a run says what fired a sync. The gap was the REQUEST plane:\n// a connector called synchronously has runs to show for none of it, so a reader\n// asking \"quando o Melhor Envio é acionado?\" found nothing — the two moments\n// that matter (the buyer asking for freight, the order buying a label) were\n// facts about `packages/shop`, written down nowhere the connector's own page\n// could read.\n//\n// So this is the fourth answer and deliberately not a fourth vocabulary: same\n// shape as a managed automation (a stable key, the sentence a tenant reads),\n// and where a moment is a sync it names its `SyncTrigger` rather than inventing\n// a second word for \"webhook\".\n\n/** One call site that invokes a connector, and what happens there. */\nexport interface ConnectorInvocation {\n /**\n * Stable call-site key, `<plugin>.<surface>.<verb>` —\n * `shop.checkout.shipping_quote`. Not an event key: nothing publishes it, it\n * names a place in the code, and it is what a support conversation and a trace\n * will call the same call.\n */\n key: string\n /** What the tenant is told happens there (\"O cliente pede as opções de frete\"). */\n label: string\n /**\n * Which plane carries the call. Default `'request'` — the buyer is waiting.\n * `'sync'` for the effects a request leads to (capture the payment, buy the\n * label), which DO file a run.\n */\n plane?: Extract<ConnectorPlane, 'request' | 'sync'>\n /** Sync moments only: what fires it, in `plg_sync_runs.trigger_kind`'s words. */\n trigger?: SyncTrigger\n /**\n * Which declared resources this call reaches — `permissions[].resource` names.\n *\n * The half of \"quando ele age\" that was missing: the section said *when* a\n * connector is called and never *what it gets at*. Naming the resource rather\n * than restating the access is what keeps the two from disagreeing — a moment\n * cannot reach something the connector did not ask for, and the contract check\n * enforces exactly that.\n */\n touches?: string[]\n}\n\n/** The plane a moment runs on when it does not say. */\nexport function invocationPlane(moment: ConnectorInvocation): Extract<ConnectorPlane, 'request' | 'sync'> {\n return moment.plane ?? 'request'\n}\n\n/**\n * The two entries a first load has when the provider's catalogue is big enough\n * that pulling it in line is not an option.\n *\n * Keeping them apart is forced by the budget, not by taste: at 3 req/s a\n * ten-thousand-product catalogue is nearly an hour, and a connect screen that\n * waits for it is a connect screen nobody finishes.\n */\nexport interface ConnectorFirstLoad {\n /** How many records the fast phase pulls before answering. */\n sampleSize: number\n /** Pages the fast phase may spend. A sample that pages forever is a backfill. */\n samplePages?: number\n /** Which stream the phases walk (`'products'`, `'orders'`). */\n stream: string\n}\n\nexport interface ConnectorStatus {\n connected: boolean\n detail?: string\n /**\n * What is wrong with a live connection, in sentences a merchant can act on.\n *\n * `detail` is one line and is what a LIST row has room for; a connection can\n * be unwell in more than one way at once (the watch expired AND the timezone\n * drifted), and a connector that had more to say used to say it in its own\n * panel — which put status on the settings tab and left `detail` repeating the\n * first item. Declaring both is what lets the surface render the list once and\n * fall back to `detail` when there is nothing to enumerate.\n */\n issues?: string[]\n /** Which plane the live connection is running on (when connected). */\n plane?: ConnectorPlane\n /**\n * Connected, and unable to do its job until a required-to-operate setting is\n * chosen — `plg_connections.status = 'pending'`.\n *\n * Not a third kind of \"connected\": the connection is real, the authorization\n * happened, and nothing about it needs redoing. What is missing is\n * configuration, which is why it is reported here rather than by pretending\n * the connect step failed. See {@link settingsStatus}.\n */\n needsSetup?: boolean\n /** Which setting keys are missing. Keys only — never what the tenant typed. */\n missingSettings?: string[]\n}\n\n/**\n * UI-facing connector descriptor. Built on the data-plane `Connector` concept\n * (`pluginId` → `hostPluginId`), plus the control-plane hooks the unified\n * Integrations hub calls. Lives in core so `PluginManifest.connectors` can type\n * it; the rendering hub lives in `@fayz-ai/admin`.\n */\nexport interface ConnectorDefinition {\n /** Stable connector id, e.g. 'google-calendar', 'plugbank'. */\n id: string\n /**\n * The platform catalogue slug this connector IS, when it differs from `id`.\n *\n * `id` names the implementation and `slug` names the provider, and they are\n * only usually the same word: `plugbank` is the catalogue's `tecnospeed`.\n * The tie matters twice — it is what lends\n * an installed connector the catalogue's localized copy and brand mark, and\n * what tells a slug a module declared in {@link PluginManifest.integrations}\n * apart from one still to be built.\n */\n catalogSlug?: string\n /** The plugin this connector extends, e.g. 'financial', 'agenda'. */\n hostPluginId: string\n name: string\n description?: string\n /** Lucide icon name. */\n icon?: string\n /**\n * The connector's own brand mark — a URL or an inline data URI. Preferred\n * over the catalogue's icon and over `icon`, so a connector the Fayz\n * directory doesn't carry still shows up as itself.\n */\n logoUrl?: string\n authKind: IntegrationAuthKind\n /** Planes this connector can be honoured on. Default: `['sync']`. */\n planes?: ConnectorPlane[]\n /**\n * Request plane only, and required there: how long the buyer may wait before\n * `onFailure` applies. No default — see {@link requestPlaneSpec}.\n */\n latencyBudgetMs?: number\n /**\n * Request plane only, and required there. `'degrade'` serves a worse answer\n * and the sale continues; `'block'` refuses the step and the buyer is told\n * why. A field, not a decision re-taken in every screen that calls it.\n */\n onFailure?: RequestFailureMode\n /** Default `'outbound'` — this app reaching a provider. */\n direction?: ConnectorDirection\n /** What the assistant gains on the agentic plane — shown before connecting. */\n agentTools?: ConnectorAgentTool[]\n /**\n * **What this connector needs access to, and why** — the one declaration the\n * consent view, \"quando ele age\" and (eventually) the minted credential all\n * read. See ./permissions.ts.\n *\n * It SUBSUMES {@link entities} and {@link subscribesTo}: declare permissions\n * and both are derived ({@link connectorEntities}, {@link connectorSubscribesTo}).\n * Declaring a permission and a contradicting legacy field fails the contract\n * check rather than being merged — a connector that says it writes `booking`\n * in one field and never mentions `booking` in the other has a bug, and\n * picking a winner would hide it.\n */\n permissions?: ConnectorPermission[]\n /**\n * Canonical entities this connector touches ('booking', 'movement').\n *\n * Superseded by {@link permissions}, which says read or write rather than only\n * the name. Still read for connectors built against an older core; when both\n * are present they must name the same set. Read it through\n * {@link connectorEntities}, never off the field.\n */\n entities?: string[]\n /**\n * The catalogue shelf, from the closed vocabulary in\n * {@link CONNECTOR_CATEGORIES}. Typed rather than free-form because the badge\n * that renders it is keyed by this exact string: an unlisted one renders no\n * badge at all, which is invisible in review and invisible in the screenshot.\n */\n category?: ConnectorCategory\n /**\n * The provider's call budget for ONE account, declared rather than discovered.\n *\n * The scheduler owns the clock ({@link createRateLimiter}); a `sleep` inside a\n * connector's fetch helper cannot express a daily ceiling and cannot be shared\n * between two streams pulling at the same time. Declaring it is also what\n * makes \"never one request per product\" a checkable statement instead of a\n * habit — see {@link firstLoad}.\n */\n rateLimit?: RateLimitBudget\n /**\n * How the first load enters, when the catalogue is too large to fetch in line.\n *\n * Two phases, because they answer different questions: `sample` returns in\n * seconds and is what a briefing or a generated storefront is designed\n * against; `backfill` runs in the background against the budget and is what\n * makes the mirror complete. Absent = the first load is just a sync.\n */\n firstLoad?: ConnectorFirstLoad\n /** Provider documentation, linked from the connector's detail. */\n docsUrl?: string\n /**\n * What AUTHORIZES the connection — the connect step renders exactly these and\n * nothing more (api-key / mtls). An OAuth connector declares none: consent is\n * the whole form.\n *\n * A connector whose credential lives in the Fayz platform declares none\n * either, and the connect step says so rather than drawing an empty grid.\n */\n fields?: ConnectorField[]\n /**\n * The provider-side install the merchant must do first, when there is one.\n * Rendered above `fields`. See {@link ConnectorProviderInstall}.\n */\n providerInstall?: ConnectorProviderInstall\n /**\n * How the live connection BEHAVES — asked for only after it exists.\n *\n * The split is the point. Everything here changes with the season and none of\n * it belongs in front of someone who has not connected yet; see ./settings.ts.\n * Declaring a setting also allow-lists its key for\n * `plg_connections.settings`, so a connector needs it in one place, not two.\n */\n settings?: ConnectorSetting[]\n /** Current values for the settings form. Required whenever `settings` is declared. */\n getSettings?(): Promise<Record<string, unknown>>\n /** Persist a settings patch — merged by key, never replacing the jsonb. */\n saveSettings?(values: Record<string, ConnectorSettingValue>): Promise<void>\n /**\n * The moments this connector is CALLED at — the request plane's answer to\n * \"acionado quando?\". See {@link ConnectorInvocation}.\n */\n invokedAt?: ConnectorInvocation[]\n /**\n * Domain-event keys this connector reacts to — exact keys or `*`-suffixed\n * prefixes (`agenda.booking_created`, `blog.post.*`). The ingress reads it to\n * decide which facts are worth waking the connector for; without it every\n * connector would have to be handed every event and filter it itself.\n *\n * Superseded by a `kind: 'event'` {@link permissions} entry carrying `listen`,\n * which says the same thing plus why. Same agreement rule as {@link entities}.\n * Read it through {@link connectorSubscribesTo}, never off the field.\n */\n subscribesTo?: string[]\n /** Automations this connector owns. See {@link ConnectorManagedAutomation}. */\n managedAutomations?: ConnectorManagedAutomation[]\n /** Current connection state for the status badge. */\n getStatus(): Promise<ConnectorStatus>\n /**\n * The same answer as {@link getStatus}, derived from a `plg_connections` row a\n * caller already holds.\n *\n * Declaring it is what lets a list of N connectors resolve in ONE batched read\n * (`listConnections`) instead of N `getStatus()` round trips — the connectors\n * screen used to issue one request per row. Pure by contract: it is handed a\n * row, it must not fetch.\n *\n * Absent means \"my truth is not in that table\" (Stripe Connect derives from\n * the provider), and the list falls back to calling `getStatus()`. Use\n * {@link connectionStatus} to write both from one function.\n */\n statusFromConnection?(connection: ConnectionConfig | null): ConnectorStatus\n /** Which account at the provider `statusFromConnection` reads. Default `''`. */\n instanceKey?: string\n /** Validate credentials without persisting (api-key / mtls). */\n testConnection?(values: Record<string, string>): Promise<TestConnectionResult>\n /** Persist the connection (api-key / mtls). */\n saveConnection?(values: Record<string, string>): Promise<void>\n /**\n * Begin an OAuth connect flow — returns the consent URL to redirect to.\n *\n * `context` is optional so a connector written against an older core keeps\n * compiling; the hub always passes it. See {@link ConnectorConnectContext}.\n */\n startOAuth?(redirectTo?: string, context?: ConnectorConnectContext): Promise<string>\n /** Tear down the connection. */\n disconnect?(): Promise<void>\n /**\n * What unplugging costs, when the answer is not obvious.\n *\n * A mirror that freezes is not a catalogue that is deleted, and a merchant\n * who cannot tell the two apart never presses the button. Rendered beside\n * Desconectar, which is the only place the question is ever asked.\n */\n disconnectNote?: string\n /**\n * When this connector syncs, in the merchant's words.\n *\n * The first question anyone has after connecting, and one the screen could\n * not answer: the cadence lives in `plg_connector_schedules`, the on-write\n * wake in a database trigger, the manual run in a button — three places, none\n * of them a sentence. Rendered on Visão geral.\n */\n howItSyncs?: string[]\n /** Move an existing connection between planes (only when `planes` has both). */\n setPlane?(plane: ConnectorPlane): Promise<void>\n /**\n * What this connection has DONE — newest first.\n *\n * The surface renders one history for every connector, so a connector\n * declares where its runs are and nothing about how they look. Store-backed\n * connectors get it from {@link connectionRuns}; a connector whose runs live\n * in its own table maps them onto {@link SyncRun} here, which is the only\n * shape the view knows.\n *\n * Absent means \"I keep no history\", and the surface offers no history tab —\n * never an empty one, which would read as \"nothing ever ran\".\n */\n listRuns?(options?: { limit?: number }): Promise<SyncRun[]>\n /**\n * The connector's own actions that PRODUCE a run — sync now, import a\n * statement, pull events from a date.\n *\n * Deliberately separate from {@link ExtraPanel}: an import is something\n * somebody does once, and it was rendered beside a settings form, which is\n * where the two got confused. Rendered above the history, because the history\n * is where its effect shows up.\n *\n * `onRan` reloads that history — call it after the action lands.\n */\n RunActions?: React.ComponentType<{ onRan?: () => void }>\n /**\n * The same thing as {@link RunActions}, DECLARED instead of drawn.\n *\n * What differs between two connectors is the sentence on the button and the\n * call behind it. Spinner, toast, reloading the history, confirming a write at\n * the provider — the surface owns all of it, or two integrations end up\n * feeling like two products.\n *\n * Both seams render, so a connector can migrate one action at a time.\n */\n syncActions?: ConnectorSyncAction[]\n /**\n * Record by record: what reached the provider, what is queued, what was\n * refused. The seam the automations screen reads — a managed automation could\n * only show that the fact FIRED, never that anything arrived.\n */\n listDeliveries?(options?: { eventKey?: string; limit?: number }): Promise<ConnectorDelivery[]>\n /**\n * The connector's own CONFIGURATION UI, rendered on the Settings tab.\n *\n * Configuration only: which Google calendar maps to which professional, which\n * warehouse a stream belongs to. Status belongs in {@link ConnectorStatus},\n * history in {@link listRuns}, and a one-off action in {@link RunActions} —\n * this panel used to hold all four at once.\n */\n ExtraPanel?: React.ComponentType\n}\n\n/**\n * One RECORD's journey to the provider — \"cadastrei aqui, foi?\".\n *\n * A {@link SyncRun} says \"12 of 20 filed\", which is the number that does not\n * help the person holding order 1042 in their hand.\n */\nexport interface ConnectorDelivery {\n /** The record, as the merchant would name it: \"Pedido 1042\", \"Costela defumada\". */\n subject: string\n /** This app's id for it, when a screen wants to link back to the record. */\n subjectId?: string\n /** `pending` is a real answer: queued, not yet sent — what the merchant sees\n * in the fifteen minutes between a sale and the clock. */\n status: 'delivered' | 'pending' | 'failed'\n /** Why it is pending or failed, in the merchant's language. */\n detail?: string\n /** The id or number it got at the provider. The one thing checkable on both screens. */\n externalId?: string\n /** When it was delivered, or when the record was created if it was not. */\n at?: string\n}\n\n/** What a run actually did. `partial` and `error` are toasted as such. */\nexport interface ConnectorSyncOutcome {\n message: string\n status?: 'success' | 'partial' | 'error'\n}\n\n/** One thing a merchant can make a connection DO. Declared rather than drawn —\n * see {@link ConnectorDefinition.syncActions}. */\nexport interface ConnectorSyncAction {\n /** Stable, for React keys and for telling two actions apart in a test. */\n key: string\n /** The button. A verb, in the merchant's language: \"Trazer catálogo do Bling\". */\n label: string\n /** Which way the data moves. Outbound is a write the merchant cannot undo\n * from this screen, which is what `confirm` is for. */\n direction: 'inbound' | 'outbound'\n /** One line under the label, when the label alone cannot carry it. */\n description?: string\n /**\n * The action somebody came here to press — the one that is right on an\n * ordinary day. At most one. The rest fold under \"Outras ações\": five equal\n * buttons is a menu the reader has to grade themselves.\n */\n primary?: boolean\n /** Ask first. Only for what cannot be taken back. */\n confirm?: { title: string; body: string; cta: string }\n /**\n * Do it. What it returns becomes the toast — use the run's own sentence, so\n * the merchant reads the same words here and in the history below.\n *\n * Return a {@link ConnectorSyncOutcome} when the run can partly fail: a push\n * that filed 0 of 9 answers 200 with a sentence, and a surface that reads only\n * \"it did not throw\" celebrates it. The verdict is already computed where the\n * work happened; this is how it reaches the screen.\n */\n run(): Promise<string | ConnectorSyncOutcome | void>\n /**\n * How many records are still waiting for this action.\n *\n * `0` means there is nothing left to send, and the surface says so — a check\n * and a spent button, not a live control that would file nothing. A push whose\n * queue is an absence can always answer this; a pull cannot know what changed\n * at the provider, so it declares nothing and stays enabled.\n */\n pending?(): Promise<number | null> | number | null\n /** Whether to offer it at all. Hidden, not disabled: a greyed button reads as\n * something the reader failed to do. Absent means always. */\n available?(): Promise<boolean> | boolean\n /** A screen of its own, for an action that needs choices first. Replaces the\n * row while open; call `onRan` when something actually happened. */\n Component?: React.ComponentType<{ onClose(): void; onRan?(): void }>\n}\n\n/** Planes a connector supports — the contract's default is the sync pipeline. */\nexport function connectorPlanes(def: Pick<ConnectorDefinition, 'planes'>): ConnectorPlane[] {\n return def.planes?.length ? def.planes : ['sync']\n}\n\n/**\n * The plane to offer first. Agentic wins whenever the connector supports it:\n * handing the assistant a tool costs nothing to keep in agreement, while a sync\n * pipeline is a copy that has to be maintained for as long as it exists.\n */\nexport function preferredPlane(def: Pick<ConnectorDefinition, 'planes'>): ConnectorPlane {\n const planes = connectorPlanes(def)\n // Not `: 'sync'` — a request-only connector has no sync plane to fall back to.\n return planes.includes('agentic') ? 'agentic' : planes[0]\n}\n\n/** Direction a connector moves data in — outbound unless it says otherwise. */\nexport function connectorDirection(def: Pick<ConnectorDefinition, 'direction'>): ConnectorDirection {\n return def.direction ?? 'outbound'\n}\n\n/**\n * Wrap an object's async methods so a handler fires AFTER selected methods\n * resolve — the non-invasive hook for outbound, event-driven sync when there's\n * no app-level event bus. Example: wrap an AgendaDataProvider so that after\n * createBooking/updateBooking/deleteBooking succeed, an external calendar is\n * updated. The handler runs fire-and-forget; its failures never break the call.\n */\nexport function withAfterHooks<T extends object>(\n target: T,\n methods: Partial<Record<keyof T, (args: unknown[], result: unknown) => void | Promise<void>>>,\n): T {\n return new Proxy(target, {\n get(obj, prop, receiver) {\n const orig = Reflect.get(obj, prop, receiver)\n const hook = (methods as Record<string | symbol, ((args: unknown[], result: unknown) => void | Promise<void>) | undefined>)[prop]\n if (typeof orig !== 'function' || !hook) return orig\n return (...args: unknown[]) => {\n const result = (orig as (...a: unknown[]) => unknown).apply(obj, args)\n if (result instanceof Promise) {\n return result.then((value) => {\n try { void Promise.resolve(hook(args, value)).catch(() => {}) } catch { /* never break the call */ }\n return value\n })\n }\n try { void Promise.resolve(hook(args, result)).catch(() => {}) } catch { /* noop */ }\n return result\n }\n },\n })\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/i18n/shell-translations.pt-br.ts"],"names":[],"mappings":"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","file":"shell-translations.pt-br-ZSSVWG6H.js","sourcesContent":["// Shared shell/CRUD/framework translations — pt-BR locale.\n// Split per-locale so only the active locale ships in the bundle: 'en' is the\n// eager fallback; other locales load via dynamic import in i18n/index.ts.\nexport const shellTranslationsPtBr: Record<string, string> = {\n \"common.save\": \"Salvar\",\n \"common.saveChanges\": \"Salvar Alterações\",\n \"common.saving\": \"Salvando...\",\n \"common.cancel\": \"Cancelar\",\n \"common.delete\": \"Excluir\",\n \"common.edit\": \"Editar\",\n \"common.you\": \"Você\",\n \"common.close\": \"Fechar\",\n \"common.confirm\": \"Confirmar\",\n \"common.back\": \"Voltar\",\n \"common.add\": \"Adicionar\",\n \"common.loading\": \"Carregando...\",\n \"common.error\": \"Algo deu errado\",\n \"common.noResults\": \"Nenhum resultado encontrado.\",\n \"common.search\": \"Buscar\",\n \"common.new\": \"Novo\",\n \"common.settings\": \"Configurações\",\n \"common.actionsMenu\": \"Mais ações\",\n \"common.actions\": \"Ações\",\n \"common.continue\": \"Continuar\",\n \"common.done\": \"Pronto\",\n \"common.yes\": \"Sim\",\n \"common.no\": \"Não\",\n \"common.active\": \"Ativo\",\n \"common.inactive\": \"Inativo\",\n \"common.overview\": \"Visão Geral\",\n \"common.notFound\": \"Não Encontrado\",\n \"common.untitled\": \"Sem título\",\n \"common.noContentYet\": \"Nenhum conteúdo ainda\",\n \"common.selectDate\": \"Selecionar data\",\n \"common.plugins\": \"Plugins\",\n \"auth.login.title\": \"Entrar\",\n \"auth.login.titleCentered\": \"Bem-vindo de Volta\",\n \"auth.login.subtitle\": \"Insira suas credenciais para acessar sua conta\",\n \"auth.login.emailLabel\": \"E-mail\",\n \"auth.login.emailPlaceholder\": \"voce@exemplo.com\",\n \"auth.login.passwordLabel\": \"Senha\",\n \"auth.login.passwordPlaceholder\": \"Digite sua senha\",\n \"auth.login.forgotPassword\": \"Esqueceu a senha?\",\n \"auth.login.submit\": \"Entrar\",\n \"auth.login.submitting\": \"Entrando...\",\n \"auth.login.error\": \"Falha ao entrar. Tente novamente.\",\n \"auth.login.oauthDivider\": \"ou continue com\",\n \"auth.login.noAccount\": \"Não tem uma conta?\",\n \"auth.login.noAccountCentered\": \"Ainda não tem uma conta?\",\n \"auth.login.signUpLink\": \"Cadastre-se\",\n \"auth.login.socialProof\": \"Junte-se a milhares de empresas que já usam {{appName}}\",\n \"auth.signup.title\": \"Criar conta\",\n \"auth.signup.titleCentered\": \"Criar Conta\",\n \"auth.signup.subtitle\": \"Comece com sua nova conta\",\n \"auth.signup.nameLabel\": \"Nome completo\",\n \"auth.signup.namePlaceholder\": \"João Silva\",\n \"auth.signup.emailLabel\": \"E-mail\",\n \"auth.signup.emailPlaceholder\": \"voce@exemplo.com\",\n \"auth.signup.passwordLabel\": \"Senha\",\n \"auth.signup.passwordPlaceholder\": \"Pelo menos 8 caracteres\",\n \"auth.signup.confirmPasswordLabel\": \"Confirmar senha\",\n \"auth.signup.confirmPasswordPlaceholder\": \"Repita sua senha\",\n \"auth.signup.termsPrefix\": \"Ao criar uma conta, você concorda com nossos\",\n \"auth.signup.termsOfService\": \"Termos de Serviço\",\n \"auth.signup.privacyPolicy\": \"Política de Privacidade\",\n \"auth.signup.submit\": \"Criar conta\",\n \"auth.signup.submitting\": \"Criando conta...\",\n \"auth.signup.error\": \"Falha ao criar conta. Tente novamente.\",\n \"auth.signup.passwordMismatch\": \"As senhas não conferem.\",\n \"auth.signup.passwordTooShort\": \"A senha deve ter pelo menos 8 caracteres.\",\n \"auth.signup.success\": \"Conta criada para {{email}}. Verifique sua caixa de entrada para confirmar seu e-mail.\",\n \"auth.signup.hasAccount\": \"Já tem uma conta?\",\n \"auth.signup.signInLink\": \"Entrar\",\n \"auth.recovery.title\": \"Redefinir senha\",\n \"auth.recovery.titleCentered\": \"Redefinir Senha\",\n \"auth.recovery.instruction\": \"Insira seu e-mail e enviaremos um link para redefinir sua senha.\",\n \"auth.recovery.subtitle\": \"Enviaremos um link de redefinição\",\n \"auth.recovery.emailLabel\": \"E-mail\",\n \"auth.recovery.emailPlaceholder\": \"voce@exemplo.com\",\n \"auth.recovery.submit\": \"Enviar link\",\n \"auth.recovery.submitting\": \"Enviando...\",\n \"auth.recovery.error\": \"Falha ao enviar e-mail. Tente novamente.\",\n \"auth.recovery.successHeading\": \"Verifique seu e-mail\",\n \"auth.recovery.successMessage\": \"Enviamos um link de redefinição para {{email}}. Verifique sua caixa de entrada e siga as instruções.\",\n \"auth.recovery.backToLogin\": \"Voltar ao login\",\n \"auth.oauth.continueWith\": \"Continuar com {{provider}}\",\n \"auth.signIn\": \"Entrar\",\n \"auth.signUp\": \"Cadastrar\",\n \"auth.signOut\": \"Sair\",\n \"auth.email\": \"E-mail\",\n \"auth.password\": \"Senha\",\n \"auth.forgotPassword\": \"Esqueceu a Senha?\",\n \"crud.list.emptyGeneric\": \"Nenhum registro ainda\",\n \"crud.list.empty\": \"Nenhum(a) {{entities}} ainda\",\n \"crud.list.addFirst\": \"Adicione seu(sua) primeiro(a) {{entity}}\",\n \"crud.list.totalCount\": \"{{count}} {{entities}} no total\",\n \"crud.list.searchPlaceholder\": \"Buscar {{entities}}...\",\n \"crud.list.allFacet\": \"Todos\",\n \"crud.list.addButton\": \"+ Adicionar {{entity}}\",\n \"crud.list.rangeCount\": \"{{from}}–{{to}} de {{total}} {{entities}}\",\n \"crud.list.pageOf\": \"{{page}} / {{pages}}\",\n \"crud.list.prevPage\": \"Página anterior\",\n \"crud.list.nextPage\": \"Próxima página\",\n \"crud.list.emptyFilteredGeneric\": \"Nenhum resultado para esta busca\",\n \"crud.list.emptyFiltered\": \"Nenhum resultado em {{entities}} para esta busca\",\n \"crud.list.emptyHintGeneric\": \"O que você cadastrar aparece aqui.\",\n \"crud.list.emptyHint\": \"Os seus {{entities}} aparecem aqui depois de cadastrados.\",\n \"crud.list.loadFailedGeneric\": \"Não foi possível carregar\",\n \"crud.list.loadFailed\": \"Não foi possível carregar os {{entities}}\",\n \"crud.list.refresh\": \"Atualizar\",\n \"crud.list.refreshCached\": \"Dados locais (cache) — clique para atualizar da rede\",\n \"crud.list.sort\": \"Ordenar\",\n \"crud.list.sortBy\": \"Ordenar por\",\n \"crud.list.sortAsc\": \"Crescente\",\n \"crud.list.sortDesc\": \"Decrescente\",\n \"crud.list.sortCreatedAt\": \"Criado em\",\n \"crud.list.sortUpdatedAt\": \"Última edição\",\n \"crud.list.selectRow\": \"Selecionar linha\",\n \"crud.list.selectAllRows\": \"Selecionar todas as linhas\",\n \"crud.list.selectedOne\": \"1 selecionado\",\n \"crud.list.selectedMany\": \"{{count}} selecionados\",\n \"crud.list.selectAllCount\": \"Selecionar todos os {{total}}\",\n \"crud.list.deselectAll\": \"Limpar seleção\",\n \"crud.list.bulkActions\": \"Ações para a seleção\",\n \"crud.list.moreActions\": \"Mais ações\",\n \"crud.list.bulkDelete\": \"Excluir\",\n \"crud.list.bulkDeleteTitle\": \"Excluir {{count}} {{entities}}?\",\n \"crud.list.bulkDeleteConfirm\": \"Os {{count}} registros selecionados serão excluídos. Esta ação não pode ser desfeita.\",\n \"crud.list.bulkDeleteDone\": \"{{count}} excluídos\",\n \"crud.list.bulkDeleteFailed\": \"{{count}} não puderam ser excluídos\",\n \"crud.detail.notFound\": \"{{entity}} não encontrado(a).\",\n \"crud.detail.backTo\": \"Voltar para {{entities}}\",\n \"crud.detail.createdAt\": \"Criado em {{date}}\",\n \"crud.detail.createdBy\": \"por {{user}}\",\n \"crud.detail.updatedAt\": \"Última edição {{date}}\",\n \"crud.form.addTitle\": \"Adicionar {{entity}}\",\n \"crud.form.requiredField\": \"Preencha {{field}}\",\n \"crud.form.requiredFields\": \"Preencha: {{fields}}\",\n \"crud.form.editTitle\": \"Editar {{entity}}\",\n \"crud.form.createSubtitle\": \"Criar um(a) novo(a) {{entity}}.\",\n \"crud.form.editSubtitle\": \"Atualizar detalhes de {{entity}}.\",\n \"crud.form.newBreadcrumb\": \"Novo(a) {{entity}}\",\n \"crud.form.selectPlaceholder\": \"Selecione {{label}}...\",\n \"crud.form.saveError\": \"Falha ao salvar {{entity}}\",\n \"crud.form.saving\": \"Salvando...\",\n \"crud.form.changeImage\": \"Trocar imagem\",\n \"crud.form.imageAfterSave\": \"Foto depois de salvar\",\n \"crud.delete.title\": \"Excluir {{entity}}?\",\n \"crud.delete.confirmNamed\": \"Tem certeza que deseja excluir \\\"{{displayValue}}\\\"? Esta ação não pode ser desfeita.\",\n \"crud.delete.confirmGeneric\": \"Tem certeza que deseja excluir este(a) {{entity}}? Esta ação não pode ser desfeita.\",\n \"crud.delete.cancel\": \"Cancelar\",\n \"crud.delete.delete\": \"Excluir\",\n \"crud.tabs.access\": \"Acesso\",\n \"crud.tabs.schedule\": \"Agenda\",\n \"crud.tabs.documents\": \"Documentos\",\n \"crud.tabs.financial\": \"Extrato\",\n \"crud.tabs.activity\": \"Atividade\",\n \"crud.tabs.inventory\": \"Estoque\",\n \"crud.tabs.suppliers\": \"Fornecedores\",\n \"crud.tabs.pricing\": \"Preços\",\n \"crud.tabs.members\": \"Equipe\",\n \"crud.tabs.stats\": \"Estatísticas\",\n \"crud.tabs.availability\": \"Disponibilidade\",\n \"crud.tabs.orders\": \"Pedidos\",\n \"crud.orders.all\": \"Todos\",\n \"crud.orders.columnDate\": \"Data\",\n \"crud.orders.columnStage\": \"Etapa\",\n \"crud.orders.columnDescription\": \"Descrição\",\n \"crud.orders.columnAmount\": \"Valor\",\n \"crud.orders.searchPlaceholder\": \"Buscar pedidos...\",\n \"crud.orders.noDocuments\": \"Nenhum pedido ainda\",\n \"crud.orders.stage.draft\": \"Rascunho\",\n \"crud.orders.stage.quoted\": \"Orçado\",\n \"crud.orders.stage.booked\": \"Agendado\",\n \"crud.orders.stage.invoiced\": \"Faturado\",\n \"crud.orders.stage.paid\": \"Pago\",\n \"crud.orders.stage.partial\": \"Parcial\",\n \"crud.orders.stage.overdue\": \"Vencido\",\n \"crud.orders.stage.cancelled\": \"Cancelado\",\n \"crud.orders.stage.no_show\": \"Não Compareceu\",\n \"crud.orders.stage.completed\": \"Concluído\",\n \"layout.userMenu.profile\": \"Perfil\",\n \"layout.userMenu.settings\": \"Configurações\",\n \"layout.userMenu.billing\": \"Faturamento\",\n \"layout.userMenu.help\": \"Ajuda\",\n \"layout.userMenu.lightMode\": \"Modo claro\",\n \"layout.userMenu.darkMode\": \"Modo escuro\",\n \"layout.userMenu.systemMode\": \"Sistema\",\n \"layout.userMenu.language\": \"Idioma\",\n \"layout.userMenu.selectLocation\": \"Selecionar local\",\n \"layout.switchingLocation\": \"Trocando de local…\",\n \"layout.userMenu.signOut\": \"Sair\",\n \"layout.topbar.searchPlaceholder\": \"Buscar...\",\n \"layout.sidebar.collapse\": \"Recolher barra lateral\",\n \"layout.sidebar.expand\": \"Expandir barra lateral\",\n \"layout.commandPalette.placeholder\": \"Buscar páginas, pessoas, produtos, serviços...\",\n \"layout.commandPalette.resultsCount\": \"{{count}} resultado{{plural}}\",\n \"layout.commandPalette.noResults\": \"Nenhum resultado encontrado.\",\n \"layout.commandPalette.searching\": \"Buscando…\",\n \"layout.commandPalette.refreshCached\": \"Resultados do cache — buscar de novo\",\n \"layout.commandPalette.refresh\": \"Atualizar resultados\",\n \"billing.title\": \"Faturamento\",\n \"billing.subtitle\": \"Gerencie sua assinatura e faturamento.\",\n \"billing.currentPlan\": \"Plano Atual\",\n \"billing.subscription.title\": \"Assinatura\",\n \"billing.subscription.subtitle\": \"Gerencie seu plano e desbloqueie mais recursos.\",\n \"billing.changeToPlan\": \"Mudar para este plano\",\n \"billing.featureMatrix\": \"Comparativo de recursos\",\n \"billing.changePlanConfirmTitle\": \"Mudar de plano?\",\n \"billing.changePlanConfirmBody\": \"Você está mudando para o plano {{plan}}.\",\n \"billing.changePlanConfirm\": \"Mudar de plano\",\n \"billing.planChanged\": \"Agora você está no plano {{plan}}.\",\n \"billing.planChangeFailed\": \"Não foi possível mudar seu plano. Tente novamente.\",\n \"billing.noPlans\": \"Nenhum plano configurado.\",\n \"billing.pro\": \"Pro\",\n \"billing.upgrade\": \"Fazer Upgrade\",\n \"billing.downgrade\": \"Fazer Downgrade\",\n \"billing.monthly\": \"Mensal\",\n \"billing.yearly\": \"Anual\",\n \"billing.yearlySave\": \"Economize 20%\",\n \"billing.free\": \"Gratuito\",\n \"billing.cancelSubscription\": \"Cancelar Assinatura\",\n \"billing.canceling\": \"Cancelando...\",\n \"billing.resumeSubscription\": \"Retomar Assinatura\",\n \"billing.resuming\": \"Retomando...\",\n \"billing.features\": \"Recursos\",\n \"billing.perMonth\": \"/mês\",\n \"billing.perYear\": \"/ano\",\n \"billing.getStarted\": \"Começar\",\n \"billing.processing\": \"Processando...\",\n \"billing.mostPopular\": \"Mais Popular\",\n \"billing.nextBilling\": \"Próxima cobrança: {{date}}\",\n \"billing.cancelsOn\": \"Cancela em {{date}}\",\n \"billing.trialEnds\": \"Período de teste termina em {{date}}\",\n \"billing.pastDueWarning\": \"Seu pagamento está atrasado. Atualize seu método de pagamento para evitar interrupção do serviço.\",\n \"billing.status.active\": \"Ativo\",\n \"billing.status.trialing\": \"Período de Teste\",\n \"billing.status.pastDue\": \"Atrasado\",\n \"billing.status.canceled\": \"Cancelado\",\n \"billing.status.paused\": \"Pausado\",\n \"organization.invite\": \"Convidar\",\n \"organization.members\": \"Membros\",\n \"organization.memberCount\": \"{{count}} membro{{plural}} nesta organização.\",\n \"organization.role\": \"Função\",\n \"organization.emailPlaceholder\": \"equipe@exemplo.com\",\n \"organization.sendInvites\": \"Enviar Convites\",\n \"organization.sending\": \"Enviando...\",\n \"organization.pending\": \"Convites Pendentes\",\n \"organization.remove\": \"Remover membro\",\n \"organization.resend\": \"Reenviar\",\n \"organization.revoke\": \"Revogar\",\n \"organization.inviteTitle\": \"Convidar Membros da Equipe\",\n \"organization.inviteDescription\": \"Envie convites para entrar na sua organização.\",\n \"organization.inviteSent\": \"Convites enviados\",\n \"organization.inviteSentDescription\": \"Seus membros receberão um e-mail com instruções para entrar.\",\n \"organization.emailAddresses\": \"Endereços de e-mail\",\n \"organization.addAnother\": \"Adicionar outro\",\n \"organization.selectRole\": \"Selecione uma função\",\n \"organization.you\": \"(você)\",\n \"organization.joined\": \"Entrou\",\n \"organization.onboarding.title\": \"Configure seu espaço de trabalho\",\n \"organization.onboarding.namePrompt\": \"Como devemos chamar seu espaço de trabalho?\",\n \"organization.onboarding.preferencesPrompt\": \"Preferências regionais\",\n \"organization.onboarding.workspaceName\": \"Nome do espaço de trabalho\",\n \"organization.onboarding.workspaceNamePlaceholder\": \"Minha Empresa\",\n \"organization.onboarding.timezone\": \"Fuso horário\",\n \"organization.onboarding.currency\": \"Moeda\",\n \"organization.onboarding.creating\": \"Configurando seu espaço de trabalho\",\n \"organization.onboarding.creatingDescription\": \"Isso levará apenas um momento...\",\n \"organization.onboarding.createWorkspace\": \"Criar Espaço de Trabalho\",\n \"settings.title\": \"Configurações\",\n \"settings.subtitle\": \"Gerencie sua conta e preferências da organização.\",\n \"settings.backToHome\": \"Voltar para o início\",\n \"settings.navLinks\": \"Configurações\",\n \"settings.general\": \"Geral\",\n \"settings.properties\": \"Propriedades\",\n \"settings.profile\": \"Perfil\",\n \"settings.branding\": \"Marca\",\n \"settings.security\": \"Segurança\",\n \"settings.sites\": \"Sites\",\n \"settings.connectors\": \"Conectores\",\n \"settings.subscription\": \"Assinatura\",\n \"upgrade.title\": \"Recurso premium\",\n \"upgrade.description\": \"Este recurso está disponível em um plano superior. Faça upgrade para liberá-lo.\",\n \"upgrade.descriptionFeature\": \"O recurso {feature} está disponível em um plano superior. Faça upgrade para liberá-lo.\",\n \"contactPicker.search\": \"Buscar contato...\",\n \"contactPicker.newContact\": \"Novo contato\",\n \"contactPicker.name\": \"Nome\",\n \"contactPicker.phone\": \"Telefone\",\n \"contactPicker.emailOptional\": \"E-mail (opcional)\",\n \"contactPicker.create\": \"Cadastrar\",\n \"contactPicker.creating\": \"Cadastrando...\",\n \"contactPicker.cancel\": \"Cancelar\",\n \"contactPicker.clear\": \"Remover contato\",\n \"contactPicker.createFailed\": \"Não foi possível cadastrar o contato\",\n \"contactPicker.addField\": \"Adicionar {label}\",\n \"upgrade.includes\": \"Inclui {feature}\",\n \"upgrade.cta\": \"Ver planos\",\n \"upgrade.badgeTooltip\": \"Disponível em um plano superior\",\n \"upgrade.unlock\": \"Desbloqueie {feature}\",\n \"upgrade.currentPlan\": \"Seu plano: {plan}\",\n \"upgrade.recommended\": \"Recomendado\",\n \"upgrade.ctaUpgrade\": \"Fazer upgrade\",\n \"upgrade.ctaUpgradeTo\": \"Fazer upgrade para {plan}\",\n \"upgrade.compareAll\": \"Comparar todos os planos\",\n \"upgrade.valueGeneric\": \"Tudo o que você precisa para crescer — incluso nos planos abaixo.\",\n \"upgrade.value.marketing\": \"Campanhas, funil e conteúdo para crescer sua base de clientes.\",\n \"upgrade.value.reports\": \"Relatórios avançados e insights para decidir com mais precisão.\",\n \"upgrade.value.fin_reconciliation\": \"Concilie pagamentos e mantenha seu fluxo de caixa sob controle.\",\n \"upgrade.value.assistant\": \"Seu copiloto de operações — pergunte, analise e aja com IA.\",\n \"upgrade.feature.assistant\": \"Assistente de IA\",\n \"billing.unlimited\": \"Ilimitado\",\n \"billing.upTo\": \"Até {count}\",\n \"banner.overLimit\": \"Você excedeu o limite de {label} do seu plano — faça upgrade para continuar crescendo.\",\n \"banner.overLimit.title\": \"Você usou todos os seus {resource}\",\n \"banner.overLimit.planLabel\": \"Plano {plan}\",\n \"banner.overLimit.unlock\": \"Nada foi bloqueado. O {plan} tira esse teto do seu caminho.\",\n \"banner.overLimit.body\": \"Nada foi bloqueado — mas esse é o teto do seu plano.\",\n \"banner.overLimit.ctaPriced\": \"Assinar {plan} — {price}/mês\",\n \"banner.overLimit.compare\": \"Comparar planos\",\n \"banner.overLimit.more\": \"+{count} outro(s) limite(s) no teto.\",\n \"limit.label.clients\": \"clientes\",\n \"limit.label.users\": \"membros da equipe\",\n \"limit.label.locations\": \"locais\",\n \"limit.label.bookings_month\": \"agendamentos mensais\",\n \"limit.label.leads\": \"leads\",\n \"limit.label.quotes\": \"orçamentos\",\n \"limit.label.conversations_month\": \"conversas mensais\",\n \"limit.label.ai_credits_month\": \"créditos de IA por mês\",\n \"limit.label.recipes\": \"receitas\",\n \"limit.label.form_templates\": \"modelos de formulário\",\n \"limit.label.documents_month\": \"documentos mensais\",\n \"limit.label.content_posts_month\": \"posts de conteúdo mensais\",\n \"limit.label.blog_posts\": \"posts de blog\",\n \"limit.label.products\": \"produtos\",\n \"limit.label.students\": \"alunos\",\n \"limit.label.courses\": \"cursos\",\n \"limit.label.contacts\": \"contatos\",\n \"limit.label.deals\": \"negócios\",\n \"limit.label.menu_items\": \"itens do cardápio\",\n \"limit.label.orders_month\": \"pedidos mensais\",\n \"limit.label.connected_banks\": \"bancos conectados\",\n \"limit.label.movements_month\": \"movimentações mensais\",\n \"settings.team\": \"Equipe\",\n \"settings.permissions\": \"Permissões\",\n \"settings.locations\": \"Locais\",\n \"settings.holidays\": \"Feriados\",\n \"settings.fieldRules\": \"Regras de Campos\",\n \"settings.notifications\": \"Notificações\",\n \"settings.save\": \"Salvar Alterações\",\n \"settings.saving\": \"Salvando...\",\n \"settings.companyInfo\": \"Informações da Empresa\",\n \"settings.companyInfoDescription\": \"Atualize os dados da sua organização e preferências regionais.\",\n \"settings.companyName\": \"Nome da Empresa\",\n \"settings.companyNamePlaceholder\": \"Minha Empresa LTDA\",\n \"settings.timezone\": \"Fuso Horário\",\n \"settings.timezonePlaceholder\": \"Selecione o fuso horário\",\n \"settings.currency\": \"Moeda\",\n \"settings.currencyPlaceholder\": \"Selecione a moeda\",\n \"settings.locale\": \"Idioma\",\n \"settings.localePlaceholder\": \"Selecione o idioma\",\n \"settings.uploadLogo\": \"Enviar Logo\",\n \"settings.uiLanguage\": \"Idioma da Interface\",\n \"settings.uiLanguageDescription\": \"Escolha o idioma da interface. Aplica-se apenas à sua sessão.\",\n \"notifications.title\": \"Notificações\",\n \"notifications.markAllRead\": \"Marcar todas como lidas\",\n \"notifications.empty\": \"Sem notificações\",\n \"notifications.whatsNew\": \"Novidades\",\n \"notifications.inbox\": \"Caixa de Entrada\",\n \"app.notFound.title\": \"404\",\n \"app.notFound.heading\": \"Página não encontrada\",\n \"app.notFound.message\": \"A página que você procura não existe ou foi movida.\",\n \"app.notFound.goToDashboard\": \"Ir para o Painel\",\n \"app.accessDenied.heading\": \"Acesso Negado\",\n \"app.accessDenied.message\": \"Você não tem permissão para acessar esta página.\",\n \"shell.accessDenied.title\": \"Acesso restrito\",\n \"shell.accessDenied.message\": \"Você não tem permissão para acessar esta página.\",\n \"shell.error.title\": \"Não foi possível carregar esta tela\",\n \"shell.error.message\": \"Algo deu errado do nosso lado. O resto do sistema continua funcionando — você pode voltar e tentar de novo.\",\n \"shell.error.retry\": \"Tentar de novo\",\n \"shell.error.copy\": \"Copiar detalhes do erro\",\n \"shell.error.copied\": \"Copiado\",\n \"shell.error.reference\": \"Informe este código ao falar com o suporte\",\n \"organization.workspaces\": \"Áreas de trabalho\",\n \"organization.onlyWorkspace\": \"Esta é a sua única área de trabalho.\",\n \"crud.form.requiredIndicator\": \"*\",\n \"crud.form.createDescription\": \"Criar um(a) novo(a) {{entity}}.\",\n \"crud.form.editDescription\": \"Atualizar detalhes de {{entity}}.\",\n \"crud.form.failedToSave\": \"Falha ao salvar {{entity}}\",\n \"crud.form.saveChanges\": \"Salvar Alterações\",\n \"crud.form.showAllFields\": \"Preencher mais campos\",\n \"crud.form.showEssentialFields\": \"Mostrar só o essencial\",\n \"crud.form.select\": \"Selecione {{field}}...\",\n \"crud.list.records\": \"registros\",\n \"crud.list.addEntity\": \"Adicionar {{entity}}\",\n \"crud.list.aiHint\": \"Descreva e eu cadastro para você.\",\n \"crud.list.aiPlaceholder\": \"Descreva o que cadastrar…\",\n \"crud.list.newHint\": \"Preencher um cadastro à mão\",\n \"crud.list.searchGeneric\": \"Buscar...\",\n \"crud.list.search\": \"Buscar {{entities}}...\",\n \"crud.import.action\": \"Importar\",\n \"crud.import.hint\": \"Trazer vários de uma planilha CSV\",\n \"crud.import.title\": \"Importar {{entity}}\",\n \"crud.import.step.download\": \"Modelo\",\n \"crud.import.step.upload\": \"Upload\",\n \"crud.import.step.mapping\": \"Mapeamento\",\n \"crud.import.step.importing\": \"Importar\",\n \"crud.import.downloadTitle\": \"Baixe o modelo\",\n \"crud.import.downloadDescription\": \"Baixe um modelo CSV com todos os campos disponíveis para {{entity}}. Preencha e envie no próximo passo.\",\n \"crud.import.downloadTemplate\": \"Baixar modelo CSV\",\n \"crud.import.downloadHint\": \"{{count}} campos disponíveis\",\n \"crud.import.alreadyHaveFile\": \"Já tenho um arquivo\",\n \"crud.import.uploadTitle\": \"Arraste seu arquivo CSV aqui ou clique para buscar\",\n \"crud.import.uploadHint\": \"Apenas arquivos .csv são aceitos\",\n \"crud.import.invalidFile\": \"Envie um arquivo .csv.\",\n \"crud.import.emptyFile\": \"O arquivo parece estar vazio.\",\n \"crud.import.noRows\": \"O arquivo tem cabeçalho mas nenhuma linha de dados.\",\n \"crud.import.mappingTitle\": \"Mapeie suas colunas\",\n \"crud.import.mappingDescription\": \"{{file}} — {{columns}} colunas, {{rows}} linhas\",\n \"crud.import.mappedCount\": \"{{count}} de {{total}} mapeados\",\n \"crud.import.csvColumn\": \"Coluna CSV\",\n \"crud.import.mapsTo\": \"Mapeia para\",\n \"crud.import.preview\": \"Prévia\",\n \"crud.import.skip\": \"— Ignorar esta coluna\",\n \"crud.import.startImport\": \"Iniciar importação\",\n \"crud.import.importing\": \"Importando...\",\n \"crud.import.importingHint\": \"Processando {{count}} linhas\",\n \"crud.import.progressCount\": \"{{processed}} de {{total}} linhas processadas\",\n \"crud.import.doneSuccess\": \"Importação concluída!\",\n \"crud.import.doneWithErrors\": \"Importação concluída com erros\",\n \"crud.import.doneCount\": \"{{success}} de {{total}} linhas importadas com sucesso\",\n \"crud.import.rowNumber\": \"Linha {{row}}:\",\n \"crud.import.toastSuccess\": \"{{count}} registros importados\",\n \"crud.import.noConnection\": \"Sem conexão com o banco de dados. A importação requer uma conexão ativa.\",\n \"crud.import.limitExceeded\": \"Esta importação excede o limite do seu plano. Faça upgrade ou importe menos linhas.\",\n \"crud.export.action\": \"Exportar\",\n \"crud.export.noData\": \"Sem dados para exportar.\",\n \"crud.export.toastSuccess\": \"{{count}} registros exportados\",\n \"layout.topbar.keyboardShortcut\": \"⌘K\",\n \"layout.topbar.search\": \"Buscar...\",\n \"layout.commandPalette.commandsCount\": \"{{count}} comando{{plural}}\",\n \"layout.commandPalette.navigate\": \"navegar\",\n \"layout.commandPalette.open\": \"abrir\",\n \"layout.commandPalette.commandCount\": \"{{count}} comando{{plural}}\",\n \"layout.commandPalette.description\": \"Buscar páginas, ações, pessoas, produtos e serviços\",\n \"layout.commandPalette.resultCount\": \"{{count}} resultado{{plural}}\",\n \"layout.commandPalette.title\": \"Paleta de comandos\",\n \"layout.bottomNav.chat\": \"Chat\",\n \"layout.mobileDrawer.description\": \"Links de navegação do aplicativo\",\n \"layout.mobileDrawer.title\": \"Menu de navegação\",\n \"organization.sent\": \"Enviado {{date}}\",\n \"organization.failedInvites\": \"Falha ao enviar convites\",\n \"organization.onboarding.failedCreate\": \"Falha ao criar espaço de trabalho\",\n \"organization.createOrg\": \"Nova área de trabalho\",\n \"organization.createOrgDescription\": \"Crie um novo espaço de trabalho para sua equipe.\",\n \"organization.createOrgTitle\": \"Criar Organização\",\n \"organization.creating\": \"Criando...\",\n \"organization.orgNamePlaceholder\": \"Nome da organização\",\n \"organization.onboarding.oneMoment\": \"Isso levará apenas um momento...\",\n \"organization.onboarding.preferences\": \"Preferências regionais\",\n \"organization.onboarding.settingUp\": \"Configurando seu espaço de trabalho\",\n \"organization.onboarding.setupWorkspace\": \"Configure seu espaço de trabalho\",\n \"organization.onboarding.whatName\": \"Como devemos chamar seu espaço de trabalho?\",\n \"organization.invite.addAnother\": \"Adicionar outro\",\n \"organization.invite.description\": \"Envie convites para entrar na sua organização.\",\n \"organization.invite.emailLabel\": \"Endereços de e-mail\",\n \"organization.invite.roleLabel\": \"Função\",\n \"organization.invite.rolePlaceholder\": \"Selecione uma função\",\n \"organization.invite.sendInvites\": \"Enviar Convites\",\n \"organization.invite.sending\": \"Enviando...\",\n \"organization.invite.sent\": \"Convites enviados\",\n \"organization.invite.sentDescription\": \"Seus membros receberão um e-mail com instruções para entrar.\",\n \"organization.invite.title\": \"Convidar Membros da Equipe\",\n \"organization.permissions.createCustom\": \"Criar Perfil Personalizado\",\n \"organization.permissions.newWithAIHint\": \"Descreva quem é o perfil e eu monto a matriz.\",\n \"organization.permissions.newByHand\": \"Criar manualmente\",\n \"organization.permissions.newByHandHint\": \"Marcar as permissões uma a uma.\",\n \"organization.permissions.askPlaceholder\": \"Descreva o perfil…\",\n \"organization.permissions.askPersona\": \"Administrador de acessos\",\n \"organization.permissions.askPitch\": \"Diga quem é o perfil e o que ele faz.\",\n \"organization.permissions.askDescription\": \"Conheço todas as áreas deste app. Descreva o cargo — o que a pessoa precisa ver, o que precisa lançar e o que não pode alcançar — e eu monto a matriz. Você confirma antes de qualquer coisa ser salva.\",\n \"organization.permissions.askSuggestion.0\": \"Recepção: vê agenda e clientes, não vê financeiro\",\n \"organization.permissions.askSuggestion.1\": \"Profissional: só a própria agenda e os próprios atendimentos\",\n \"organization.permissions.askSuggestion.2\": \"Gerente: tudo menos permissões e cobrança\",\n \"organization.permissions.createProfile\": \"Criar Perfil\",\n \"organization.permissions.duplicate\": \"Duplicar\",\n \"organization.permissions.copyName\": \"{{name}} (cópia)\",\n \"organization.permissions.description\": \"Descrição\",\n \"organization.permissions.descriptionPlaceholder\": \"Descrição opcional\",\n \"organization.permissions.editProfile\": \"Editar: {{name}}\",\n \"organization.permissions.manageBilling\": \"Gerenciar Faturamento\",\n \"organization.permissions.managePermissions\": \"Gerenciar Permissões\",\n \"organization.permissions.manageSettings\": \"Gerenciar Configurações\",\n \"organization.permissions.manageTeam\": \"Gerenciar Equipe\",\n \"organization.permissions.memberCount\": \"{{count}} membro{{plural}}\",\n \"organization.permissions.previewAs\": \"Visualizar como\",\n \"organization.permissions.previewingAs\": \"Visualizando como\",\n \"organization.permissions.exitPreview\": \"Sair da Visualização\",\n \"organization.permissions.searchFeatures\": \"Buscar recursos...\",\n \"organization.permissions.profile\": \"Perfil\",\n \"organization.permissions.profileName\": \"Nome do Perfil\",\n \"organization.permissions.profileNamePlaceholder\": \"ex.: Função Personalizada\",\n \"organization.permissions.subtitle\": \"Gerencie funções e suas permissões.\",\n \"organization.permissions.system\": \"Sistema\",\n \"organization.permissions.systemPermissions\": \"Permissões do Sistema\",\n \"organization.permissions.title\": \"Perfis de Permissão\",\n \"organization.permissions.updateProfile\": \"Atualizar Perfil\",\n \"organization.team.invite\": \"Convidar\",\n \"organization.team.joined\": \"Entrou\",\n \"organization.team.member\": \"Membro\",\n \"organization.team.memberCount\": \"{{count}} membro{{plural}} nesta organização.\",\n \"organization.team.pendingInvites\": \"Convites Pendentes\",\n \"organization.team.removeMember\": \"Remover membro\",\n \"organization.team.unitAccess\": \"Acessos por unidade\",\n \"organization.team.resend\": \"Reenviar\",\n \"organization.team.revoke\": \"Revogar\",\n \"organization.team.inviteResent\": \"Convite reenviado\",\n \"organization.team.inviteRevoked\": \"Convite revogado\",\n \"organization.team.inviteActionFailed\": \"Não foi possível concluir\",\n \"organization.team.role\": \"Função\",\n \"organization.team.sent\": \"Enviado {{date}}\",\n \"organization.team.title\": \"Membros\",\n \"organization.team.you\": \"(você)\",\n \"user.profile\": \"Perfil\",\n \"user.settings\": \"Configurações\",\n \"user.help\": \"Ajuda\",\n \"user.shortcuts\": \"Atalhos de Teclado\",\n \"user.theme\": \"Tema\",\n \"user.themeLight\": \"Claro\",\n \"user.themeDark\": \"Escuro\",\n \"user.themeSystem\": \"Sistema\",\n \"notifications.noUpdates\": \"Nenhuma atualização ainda\",\n \"common.create\": \"Criar\",\n \"common.feature\": \"Recurso\",\n \"common.message\": \"Mensagem...\",\n \"common.more\": \"Mais\",\n \"common.noContent\": \"Nenhum conteúdo ainda\",\n \"chat.defaultTitle\": \"Assistente\",\n \"assistant.invite.placeholder\": \"Pergunte sobre o seu negócio...\",\n \"assistant.invite.dismiss\": \"Agora não\",\n \"assistant.invite.suggested\": \"Sugestões\",\n \"chat.tryAsking\": \"Experimente perguntar\",\n \"chat.fab.tryIt\": \"Experimente\",\n \"chat.fab.dismiss\": \"Não mostrar sugestões aqui\",\n \"chat.fab.open\": \"Abrir assistente\",\n \"chat.fab.close\": \"Fechar assistente\",\n \"chat.attachments.add\": \"Anexar arquivo\",\n \"chat.attachments.dropHere\": \"Solte para anexar\",\n \"chat.attachments.dropHint\": \"Planilhas, PDFs e imagens. Eu leio e uso na resposta.\",\n \"chat.attachments.parsing\": \"lendo…\",\n \"chat.attachments.hasWarnings\": \"com avisos\",\n \"chat.attachments.error.excelUnsupported\": \"formato de Excel não suportado — salve como .xlsx ou .csv\",\n \"chat.whatsapp.continue\": \"Continuar no WhatsApp\",\n \"chat.whatsapp.defaultMessage\": \"Oi! Vim pelo app.\",\n \"chat.messagePlaceholder\": \"Como posso ajudar?\",\n \"chat.upload.send\": \"Ler {{count}} foto(s)\",\n \"chat.upload.addMoreImages\": \"Adicionar mais uma foto\",\n \"chat.upload.addMoreFiles\": \"Adicionar mais um arquivo\",\n \"chat.upload.working\": \"Lendo...\",\n \"chat.upload.browseImage\": \"Ou escolher uma imagem deste aparelho\",\n \"chat.upload.browseFile\": \"Ou escolher um arquivo deste aparelho\",\n \"chat.send\": \"Enviar mensagem\",\n \"chat.notConfigured\": \"Assistente não configurado — defina chat.apiEndpoint para habilitar conversas.\",\n \"chat.unavailable\": \"Assistente indisponível\",\n \"chat.greeting\": \"Como posso ajudar?\",\n \"chat.greetingNamed\": \"Oi {{name}}, como posso ajudar?\",\n \"chat.greetingHint\": \"Peça com suas palavras — ou toque no microfone e fale. Eu consulto seus dados, crio e atualizo cadastros, e explico o que está acontecendo no seu negócio.\",\n \"chat.disclaimer\": \"A IA pode errar. Confira o que for importante.\",\n \"chat.staff.team\": \"Sua equipe\",\n \"chat.staff.switch\": \"Falar com outra pessoa da equipe\",\n \"chat.staff.hire\": \"Conhecer {{name}}\",\n \"chat.staff.hireNote\": \"{{name}} entra na sua equipe assim que o plano for ativado. Você pode cancelar quando quiser.\",\n \"chat.staff.priceFrom\": \"A partir de\",\n \"chat.staff.perMonth\": \"/mês\",\n \"chat.staff.onPlan\": \"no plano {{plan}}\",\n \"chat.staff.priceOnPlans\": \"Veja nos planos o que inclui cada agente.\",\n \"chat.staff.seePlans\": \"Ver planos\",\n \"chat.staff.notHired\": \"Não contratado\",\n \"chat.staff.handoffFrom\": \"{{from}} passou para {{to}}\",\n \"chat.staff.handoffTo\": \"{{to}} assumiu\",\n \"chat.opener.capabilities\": \"O que você consegue fazer aqui?\",\n \"chat.opener.today\": \"Como está o negócio hoje?\",\n \"chat.opener.findRecord\": \"Procura um cadastro pra mim\",\n \"chat.history.title\": \"Conversas\",\n \"chat.recording.pending\": \"Nada foi gravado ainda.\",\n \"chat.recording.running\": \"Gravando. Pode navegar pelo app — a gravação continua.\",\n \"chat.recording.paused\": \"Gravação pausada.\",\n \"chat.recording.finished\": \"Gravação encerrada.\",\n \"chat.status.ready\": \"Pronto\",\n \"chat.status.working\": \"Trabalhando nisso...\",\n \"chat.status.offline\": \"Sem conexão\",\n \"chat.jumpToLatest\": \"Ir para o fim\",\n \"chat.confirmAction.title\": \"Confirmar esta ação?\",\n \"chat.confirmAction.confirm\": \"Confirmar\",\n \"chat.confirmAction.cancel\": \"Cancelar\",\n \"chat.confirmAction.always\": \"Sempre permitir\",\n \"chat.confirmAction.alwaysSession\": \"Permitir nesta sessão\",\n \"chat.confirmAction.alwaysHint\": \"Parar de perguntar antes de \\\"{{label}}\\\"\",\n \"chat.confirmAction.autoApproved\": \"auto\",\n \"chat.confirmAction.autoApprovedHint\": \"Executado sem perguntar — você liberou esta ação\",\n \"chat.confirmAction.blocked\": \"Responda a confirmação acima primeiro\",\n \"chat.confirmAction.fillRequired\": \"Preencha para continuar: {{fields}}\",\n \"chat.confirmAction.showAll\": \"Preencher mais campos ({{count}})\",\n \"chat.confirmAction.showLess\": \"Mostrar menos campos\",\n \"chat.tool.createAppointment\": \"Marcar horário\",\n \"chat.tool.createRecord\": \"Criar registro\",\n \"chat.tool.updateRecord\": \"Atualizar registro\",\n \"chat.tool.deleteRecord\": \"Excluir registro\",\n \"chat.tool.createOrder\": \"Criar pedido\",\n \"chat.tool.createInvoice\": \"Emitir cobrança\",\n \"chat.tool.markPaymentReceived\": \"Marcar pagamento como recebido\",\n \"chat.tool.createCampaign\": \"Criar campanha\",\n \"chat.tool.sendMessage\": \"Enviar mensagem\",\n \"chat.tool.seatGuests\": \"Acomodar clientes\",\n \"chat.tool.toggleMenuItemAvailability\": \"Alterar disponibilidade do item\",\n \"chat.tool.createShopOrder\": \"Criar pedido da loja\",\n \"chat.tool.chargeShopOrder\": \"Gerar cobrança do pedido\",\n \"chat.tool.setShopOrderAddress\": \"Anotar endereço de entrega\",\n \"chat.autoApprovals.title\": \"Ações liberadas\",\n \"chat.autoApprovals.revoke\": \"Voltar a perguntar\",\n \"chat.autoApprovals.revokeAll\": \"Perguntar sempre\",\n \"chat.suggestions.show\": \"Mostrar sugestões\",\n \"chat.suggestions.hide\": \"Ocultar sugestões\",\n \"chat.voice.start\": \"Falar\",\n \"chat.voice.stop\": \"Parar gravação\",\n \"chat.voice.listening\": \"Ouvindo — pode falar\",\n \"chat.voice.transcribing\": \"Transcrevendo...\",\n \"chat.voice.denied\": \"Microfone bloqueado. Libere o acesso nas configurações do navegador.\",\n \"chat.voice.network\": \"Não consegui falar com o serviço de transcrição.\",\n \"chat.voice.failed\": \"Não consegui entender — tente de novo.\",\n \"chat.voice.speakOn\": \"Responder em voz alta\",\n \"chat.voice.speakOff\": \"Silenciar respostas faladas\",\n \"chat.signingIn\": \"Um instante — ainda estou confirmando sua sessão.\",\n \"chat.history\": \"Conversas anteriores\",\n \"chat.history.search\": \"Buscar conversas\",\n \"chat.history.empty\": \"Nenhuma conversa encontrada.\",\n \"chat.history.today\": \"Hoje\",\n \"chat.history.yesterday\": \"Ontem\",\n \"chat.history.week\": \"Últimos 7 dias\",\n \"chat.history.older\": \"Mais antigas\",\n \"chat.newConversation\": \"Nova conversa\",\n \"chat.untitledConversation\": \"Conversa sem título\",\n \"chat.recentConversations\": \"Recentes\",\n \"chat.backToConversations\": \"Voltar para as conversas\",\n \"chat.renameConversation\": \"Renomear\",\n \"chat.saveTitle\": \"Salvar título\",\n \"chat.toolsAvailable\": \"{{count}} ferramentas disponíveis\",\n \"chat.suggestion.dashboard.kpi-summary.0\": \"Como está meu negócio hoje?\",\n \"chat.suggestion.dashboard.kpi-summary.1\": \"Qual o faturamento de hoje?\",\n \"chat.suggestion.dashboard.kpi-summary.2\": \"Me dê um resumo do dia\",\n \"chat.suggestion.agenda.list-appointments.0\": \"O que tem na agenda hoje?\",\n \"chat.suggestion.agenda.list-appointments.1\": \"Mostre os agendamentos de amanhã\",\n \"chat.suggestion.agenda.list-appointments.2\": \"Quem tem mais atendimentos esta semana?\",\n \"chat.suggestion.agenda.create-appointment.0\": \"Agende um corte para Sarah amanhã às 10h\",\n \"chat.suggestion.agenda.check-availability.0\": \"Quando Ana está disponível amanhã?\",\n \"chat.suggestion.agenda.check-availability.1\": \"Encontre um horário de 90 minutos para Carlos esta semana\",\n \"chat.suggestion.financial.get-revenue.0\": \"Quanto faturamos hoje?\",\n \"chat.suggestion.financial.get-revenue.1\": \"Qual o faturamento deste mês?\",\n \"chat.suggestion.financial.get-revenue.2\": \"Compare o faturamento desta semana com a anterior\",\n \"chat.suggestion.financial.create-invoice.0\": \"Crie uma fatura para um novo cliente\",\n \"chat.suggestion.financial.list-payables.0\": \"Mostre as contas em atraso\",\n \"chat.suggestion.financial.list-payables.1\": \"Quais contas vencem esta semana?\",\n \"chat.suggestion.inventory.low-stock.0\": \"Quais produtos estão com estoque baixo?\",\n \"chat.suggestion.inventory.low-stock.1\": \"Mostre um resumo do estoque\",\n \"chat.suggestion.inventory.low-stock.2\": \"Quais são os produtos mais usados?\",\n \"chat.suggestion.crm.count-customers.0\": \"Quantos clientes temos?\",\n \"chat.suggestion.crm.count-customers.1\": \"Quem são meus melhores clientes?\",\n \"chat.suggestion.crm.list-leads.0\": \"Mostre os leads novos desta semana\",\n \"chat.suggestion.crm.list-leads.1\": \"Quais leads precisam de follow-up?\",\n \"chat.suggestion.crm.list-leads.2\": \"Qual nossa taxa de conversão?\",\n \"chat.suggestion.custom_forms.list-templates.0\": \"Quais formulários temos?\",\n \"chat.suggestion.custom_forms.list-templates.1\": \"Mostre os modelos de anamnese\",\n \"chat.suggestion.custom_forms.list-documents.0\": \"Mostre os documentos deste cliente\",\n \"billing.invoice.amount\": \"Valor\",\n \"billing.invoice.date\": \"Data\",\n \"billing.invoice.invoice\": \"Fatura\",\n \"billing.invoice.noInvoices\": \"Nenhuma fatura ainda\",\n \"billing.invoice.status\": \"Status\",\n \"billing.paywall.notAvailable\": \"Este recurso não está disponível no seu plano atual.\",\n \"billing.paywall.requiresPlan\": \"Este recurso requer o plano {{plan}} ou superior.\",\n \"billing.paywall.upgradeRequired\": \"Upgrade Necessário\",\n \"billing.paywall.viewPlans\": \"Ver Planos\",\n \"auth.login.enterCredentials\": \"Insira suas credenciais para acessar sua conta\",\n \"auth.login.failedDefault\": \"Falha ao entrar. Tente novamente.\",\n \"auth.login.failedWithProvider\": \"Falha ao entrar com {{provider}}.\",\n \"auth.login.orContinueWith\": \"ou continue com\",\n \"auth.login.placeholder.email\": \"voce@exemplo.com\",\n \"auth.login.placeholder.password\": \"Digite sua senha\",\n \"auth.login.signingIn\": \"Entrando...\",\n \"auth.login.welcomeBack\": \"Bem-vindo de Volta\",\n \"auth.login.welcomeTo\": \"Bem-vindo ao {{appName}}\",\n \"auth.recovery.checkEmail\": \"Verifique seu e-mail\",\n \"auth.recovery.description\": \"Insira seu e-mail e enviaremos um link para redefinir sua senha.\",\n \"auth.recovery.failedDefault\": \"Falha ao enviar e-mail. Tente novamente.\",\n \"auth.recovery.resetLinkSent\": \"Enviamos um link de redefinição para <strong>{{email}}</strong>. Verifique sua caixa de entrada e siga as instruções.\",\n \"auth.recovery.sendResetLink\": \"Enviar link de redefinição\",\n \"auth.recovery.sending\": \"Enviando...\",\n \"auth.signup.confirmPassword\": \"Confirmar senha\",\n \"auth.signup.creating\": \"Criando conta...\",\n \"auth.signup.emailVerification\": \"Conta criada para {{email}}. Verifique sua caixa de entrada para confirmar seu e-mail.\",\n \"auth.signup.failedDefault\": \"Falha ao criar conta. Tente novamente.\",\n \"auth.signup.fullName\": \"Nome completo\",\n \"auth.signup.getStarted\": \"Comece com sua nova conta\",\n \"auth.signup.passwordMinLength\": \"A senha deve ter pelo menos 8 caracteres.\",\n \"auth.signup.passwordsMismatch\": \"As senhas não conferem.\",\n \"auth.signup.placeholder.confirm\": \"Repita sua senha\",\n \"auth.signup.placeholder.name\": \"João Silva\",\n \"auth.signup.placeholder.password\": \"Pelo menos 8 caracteres\",\n \"auth.signup.termsAgreement\": \"Ao criar uma conta, você concorda com nossos\",\n \"settings.branding.accentColor\": \"Cor de Destaque\",\n \"settings.branding.chooseFile\": \"Escolher Arquivo\",\n \"settings.branding.favicon\": \"Favicon\",\n \"settings.branding.faviconHint\": \"Recomendado: 32x32px, PNG ou ICO\",\n \"settings.branding.logo\": \"Logo\",\n \"settings.branding.logoHint\": \"Recomendado: 200x50px, PNG ou SVG\",\n \"settings.branding.preview\": \"Pré-visualização\",\n \"settings.branding.primaryColor\": \"Cor Primária\",\n \"settings.branding.saveBranding\": \"Salvar Marca\",\n \"settings.branding.subtitle\": \"Personalize a aparência do seu espaço de trabalho.\",\n \"settings.branding.title\": \"Marca\",\n \"settings.company.currency\": \"Moeda\",\n \"settings.company.currencyPlaceholder\": \"Selecione a moeda\",\n \"settings.company.locale\": \"Idioma\",\n \"settings.company.localePlaceholder\": \"Selecione o idioma\",\n \"settings.company.name\": \"Nome da Empresa\",\n \"settings.company.subtitle\": \"Atualize os dados da sua organização e preferências regionais.\",\n \"settings.company.timezone\": \"Fuso Horário\",\n \"settings.company.timezonePlaceholder\": \"Selecione o fuso horário\",\n \"settings.company.title\": \"Informações da Empresa\",\n \"settings.holidays.addHoliday\": \"Adicionar Feriado\",\n \"settings.holidays.annual\": \"Anual\",\n \"settings.holidays.descriptionPlaceholder\": \"Descrição (opcional)\",\n \"settings.holidays.empty\": \"Nenhum feriado configurado ainda.\",\n \"settings.holidays.namePlaceholder\": \"Nome do feriado *\",\n \"settings.holidays.newHoliday\": \"Novo Feriado\",\n \"settings.holidays.recurringAnnually\": \"Recorrente anualmente\",\n \"settings.holidays.subtitle\": \"Dias não úteis e feriados recorrentes.\",\n \"settings.holidays.title\": \"Feriados\",\n \"settings.fieldRules.subtitle\": \"Configure quais campos são obrigatórios ou visíveis para cada tipo de cadastro.\",\n \"settings.fieldRules.required\": \"Obrigatório\",\n \"settings.fieldRules.inForm\": \"Formulário\",\n \"settings.fieldRules.inTable\": \"Tabela\",\n \"settings.fieldRules.inDetail\": \"Detalhe\",\n \"settings.fieldRules.field\": \"Campo\",\n \"settings.fieldRules.resetDefaults\": \"Restaurar Padrões\",\n \"settings.fieldRules.resetConfirm\": \"Restaurar todas as regras de campos de {{entity}} para seus padrões?\",\n \"settings.fieldRules.saved\": \"Regras de campos salvas\",\n \"settings.fieldRules.saveFailed\": \"Falha ao salvar regras de campos\",\n \"settings.fieldRules.modified\": \"{{count}} modificado(s)\",\n \"settings.fieldRules.searchPlaceholder\": \"Buscar tipos de cadastro...\",\n \"settings.fieldRules.noEntities\": \"Nenhum tipo de cadastro disponível.\",\n \"settings.fieldRules.coreRegisters\": \"Tipos de Cadastro\",\n \"settings.fieldRules.otherRegisters\": \"Outros\",\n \"settings.fieldRules.showMore\": \"{{count}} tipos de cadastro a mais...\",\n \"settings.fieldRules.showLess\": \"Mostrar menos\",\n \"settings.locations.addFirst\": \"Adicione seu primeiro local\",\n \"settings.locations.addLocation\": \"Adicionar Local\",\n \"settings.locations.adding\": \"Adicionando...\",\n \"settings.locations.addressPlaceholder\": \"Endereço\",\n \"settings.locations.cityPlaceholder\": \"Cidade\",\n \"settings.locations.countDescription\": \"{{count}} local{{plural}} cadastrado(s).\",\n \"settings.locations.countryPlaceholder\": \"País\",\n \"settings.locations.empty\": \"Nenhum local foi adicionado a esta organização ainda.\",\n \"settings.locations.headquarters\": \"Sede\",\n \"settings.locations.namePlaceholder\": \"Nome do local *\",\n \"settings.locations.newLocation\": \"Novo Local\",\n \"settings.locations.noLocations\": \"Nenhum local configurado ainda.\",\n \"settings.locations.phonePlaceholder\": \"Telefone\",\n \"settings.locations.statePlaceholder\": \"Estado\",\n \"settings.locations.title\": \"Locais\",\n \"settings.profile.email\": \"E-mail\",\n \"settings.profile.emailHelp\": \"O e-mail não pode ser alterado diretamente. Entre em contato com o suporte.\",\n \"settings.profile.fullName\": \"Nome Completo\",\n \"settings.profile.saveProfile\": \"Salvar Perfil\",\n \"settings.profile.subtitle\": \"Gerencie suas informações pessoais e configurações da conta.\",\n \"settings.profile.title\": \"Perfil\",\n \"settings.security.inviteOnly\": \"Acesso Apenas por Convite\",\n \"settings.security.inviteOnlyDescription\": \"Novos usuários só podem entrar nesta organização via convite.\",\n \"settings.security.linkSent\": \"Link Enviado\",\n \"settings.security.orgSecuritySubtitle\": \"Políticas de segurança aplicadas a todos os membros desta organização.\",\n \"settings.security.orgSecurityTitle\": \"Segurança da Organização\",\n \"settings.security.passwordSubtitle\": \"Gerencie a senha da sua conta. Um link de redefinição será enviado para seu e-mail.\",\n \"settings.security.passwordTitle\": \"Senha\",\n \"settings.security.require2FA\": \"Exigir Autenticação de Dois Fatores\",\n \"settings.security.require2FADescription\": \"Todos os membros devem ativar 2FA para acessar esta organização.\",\n \"settings.security.resetLinkDescription\": \"Enviar um link de redefinição de senha para seu e-mail.\",\n \"settings.security.resetLinkSent\": \"Link de redefinição enviado — verifique sua caixa de entrada.\",\n \"settings.security.resetPassword\": \"Redefinir Senha\",\n \"settings.security.sessionTimeout\": \"Tempo Limite da Sessão\",\n \"settings.security.sessionTimeoutDescription\": \"Desconectar automaticamente usuários inativos após este período.\",\n \"settings.plugin.agenda\": \"Agenda\",\n \"settings.plugin.financial\": \"Financeiro\",\n \"settings.plugin.inventory\": \"Estoque\",\n \"settings.plugin.crm\": \"Vendas & CRM\",\n \"crud.archetype.comingSoon\": \"Em Breve\",\n \"crud.archetype.access.title\": \"Acesso e Permissões\",\n \"crud.archetype.access.description\": \"Gerencie credenciais de login, atribua perfis de permissão e controle o que esta pessoa pode acessar no sistema.\",\n \"crud.access.accountStatus\": \"Status da Conta\",\n \"crud.access.statusLinked\": \"Ativo\",\n \"crud.access.statusPending\": \"Convite pendente\",\n \"crud.access.statusAccepted\": \"Aceito\",\n \"crud.access.statusExpired\": \"Convite expirado\",\n \"crud.access.statusRevoked\": \"Revogado\",\n \"crud.access.acceptedAt\": \"Aceito em {{date}}\",\n \"crud.access.revokedDesc\": \"O acesso foi revogado. Você pode enviar um novo convite.\",\n \"crud.access.grantAccess\": \"Conceder Acesso\",\n \"crud.access.account\": \"Conta\",\n \"crud.access.accountDesc\": \"Credenciais de login e status da conta desta pessoa.\",\n \"crud.access.resetPassword\": \"Redefinir Senha\",\n \"crud.access.passwordResetSent\": \"E-mail de redefinição de senha enviado.\",\n \"crud.access.profileUpdated\": \"Perfil de permissão atualizado.\",\n \"crud.access.inviteResent\": \"Convite reenviado.\",\n \"crud.access.inviteRevoked\": \"Convite revogado.\",\n \"crud.access.accessRemoved\": \"Acesso removido.\",\n \"crud.access.dangerZone\": \"Zona de Perigo\",\n \"crud.access.dangerZoneDesc\": \"Ações irreversíveis que afetam o acesso desta pessoa ao sistema.\",\n \"crud.access.removeAccess\": \"Remover Acesso\",\n \"crud.access.revokeInvite\": \"Revogar Convite\",\n \"crud.access.confirmRemoveTitle\": \"Tem certeza?\",\n \"crud.access.confirmRemoveDesc\": \"Esta pessoa perderá todo o acesso ao sistema imediatamente. Esta ação não pode ser desfeita.\",\n \"crud.access.accountLinked\": \"Conta vinculada\",\n \"crud.access.noAccount\": \"Nenhuma conta vinculada\",\n \"crud.access.noAccountDesc\": \"Esta pessoa não possui uma conta de acesso e não pode entrar no sistema.\",\n \"crud.access.setupDesc\": \"Configure o acesso ao sistema para esta pessoa informando o e-mail e escolhendo um perfil de permissão.\",\n \"crud.access.emailPlaceholder\": \"pessoa@exemplo.com\",\n \"crud.access.sendInvite\": \"Enviar Convite\",\n \"crud.access.invitePending\": \"Convite pendente\",\n \"crud.access.inviteSent\": \"Convite enviado em {{date}}\",\n \"crud.access.permissionProfile\": \"Perfil de Permissão\",\n \"crud.access.profileDesc\": \"Defina o que esta pessoa pode acessar e fazer no sistema.\",\n \"crud.access.systemAccess\": \"Acesso ao Sistema\",\n \"crud.access.effectivePermissions\": \"Permissões Efetivas\",\n \"crud.access.effectiveDesc\": \"O que esta pessoa pode fazer com base no perfil atribuído.\",\n \"crud.access.feature\": \"Funcionalidade\",\n \"crud.access.joined\": \"Entrou em {{date}}\",\n \"crud.access.noEmail\": \"Sem endereço de e-mail\",\n \"crud.access.noEmailDesc\": \"Adicione um endereço de e-mail a esta pessoa para vinculá-la a uma conta do sistema.\",\n \"crud.access.manageTeam\": \"Gerenciar Equipe\",\n \"crud.access.manageBilling\": \"Gerenciar Faturamento\",\n \"crud.access.manageSettings\": \"Gerenciar Configurações\",\n \"crud.access.managePermissions\": \"Gerenciar Permissões\",\n \"crud.archetype.activity.title\": \"Linha do Tempo\",\n \"crud.archetype.activity.description\": \"Veja um registro cronológico de todas as ações, alterações e eventos relacionados a esta pessoa.\",\n \"crud.archetype.documents.title\": \"Documentos\",\n \"crud.archetype.documents.description\": \"Anexe e gerencie arquivos, contratos, certificações e outros documentos desta pessoa.\",\n \"crud.archetype.addresses.title\": \"Endereços\",\n \"crud.archetype.addresses.add\": \"Adicionar endereço\",\n \"crud.archetype.addresses.addTitle\": \"Novo endereço\",\n \"crud.archetype.addresses.editTitle\": \"Editar endereço\",\n \"crud.archetype.addresses.formDescription\": \"CEP, rua e cidade são obrigatórios; o resto é opcional.\",\n \"crud.archetype.addresses.emptyTitle\": \"Nenhum endereço cadastrado\",\n \"crud.archetype.addresses.emptyDescription\": \"Cadastre onde esta pessoa recebe entregas, é coletada ou é cobrada.\",\n \"crud.archetype.addresses.fallbackLabel\": \"Endereço\",\n \"crud.archetype.addresses.labelPlaceholder\": \"Casa, Trabalho…\",\n \"crud.archetype.addresses.default\": \"Padrão\",\n \"crud.archetype.addresses.setDefault\": \"Usar como endereço padrão\",\n \"crud.archetype.addresses.kind.both\": \"Entrega e cobrança\",\n \"crud.archetype.addresses.kind.shipping\": \"Entrega\",\n \"crud.archetype.addresses.kind.billing\": \"Cobrança\",\n \"crud.archetype.addresses.field.label\": \"Identificação\",\n \"crud.archetype.addresses.field.kind\": \"Uso\",\n \"crud.archetype.addresses.cepNotFound\": \"CEP não encontrado. Preencha o endereço à mão.\",\n \"crud.archetype.addresses.cepFailed\": \"Não deu para consultar o CEP agora. Preencha à mão ou tente de novo.\",\n \"crud.archetype.addresses.field.postalCode\": \"CEP\",\n \"crud.archetype.addresses.field.street\": \"Rua\",\n \"crud.archetype.addresses.field.number\": \"Número\",\n \"crud.archetype.addresses.field.complement\": \"Complemento\",\n \"crud.archetype.addresses.field.district\": \"Bairro\",\n \"crud.archetype.addresses.field.city\": \"Cidade\",\n \"crud.archetype.addresses.field.state\": \"UF\",\n \"crud.archetype.addresses.field.recipient\": \"Quem recebe\",\n \"crud.archetype.addresses.field.phone\": \"Telefone\",\n \"crud.archetype.addresses.created\": \"Endereço adicionado\",\n \"crud.archetype.addresses.updated\": \"Endereço atualizado\",\n \"crud.archetype.addresses.deleted\": \"Endereço removido\",\n \"crud.archetype.addresses.deleteTitle\": \"Remover este endereço?\",\n \"crud.archetype.addresses.loadFailed\": \"Não foi possível carregar os endereços.\",\n \"crud.archetype.addresses.saveFailed\": \"Não foi possível salvar o endereço.\",\n \"crud.archetype.addresses.deleteFailed\": \"Não foi possível remover o endereço.\",\n \"crud.archetype.addresses.noTenant\": \"Nenhuma organização ativa — recarregue a página e tente de novo.\",\n \"crud.archetype.schedule.title\": \"Agenda\",\n \"crud.archetype.schedule.description\": \"Visualize e gerencie compromissos, turnos e disponibilidade desta pessoa.\",\n \"crud.archetype.inventory.title\": \"Estoque\",\n \"crud.archetype.inventory.description\": \"Acompanhe níveis de estoque, histórico de movimentação, alertas de reposição e gerencie o inventário entre locais.\",\n \"crud.archetype.suppliers.title\": \"Fornecedores\",\n \"crud.archetype.suppliers.description\": \"Veja e gerencie quais fornecedores oferecem este produto, compare custos e acompanhe pedidos de compra.\",\n \"crud.archetype.pricing.title\": \"Histórico de Preços\",\n \"crud.archetype.pricing.description\": \"Veja alterações de preço ao longo do tempo, gerencie preços promocionais e defina preços por local.\",\n \"crud.archetype.productActivity.title\": \"Atividade\",\n \"crud.archetype.productActivity.description\": \"Veja um registro de todas as alterações, ajustes de estoque e eventos relacionados a este produto.\",\n \"crud.archetype.availability.title\": \"Disponibilidade\",\n \"crud.archetype.availability.description\": \"Configure quando este serviço pode ser agendado, defina regras de duração e gerencie limites de capacidade.\",\n \"crud.archetype.servicePricing.title\": \"Faixas de Preço\",\n \"crud.archetype.servicePricing.description\": \"Gerencie faixas de preço, descontos para membros e preços por local para este serviço.\",\n \"crud.archetype.serviceActivity.title\": \"Atividade\",\n \"crud.archetype.serviceActivity.description\": \"Veja um registro de todos os agendamentos, alterações e eventos relacionados a este serviço.\",\n \"crud.archetype.members.title\": \"Equipe\",\n \"crud.archetype.members.description\": \"Veja e gerencie a equipe atribuída a este local, seus cargos e horários.\",\n \"crud.archetype.locationSchedule.title\": \"Horário de Funcionamento\",\n \"crud.archetype.locationSchedule.description\": \"Defina horário comercial, feriados e horários especiais para este local.\",\n \"crud.archetype.locationStats.title\": \"Estatísticas\",\n \"crud.archetype.locationStats.description\": \"Veja métricas de desempenho, faturamento e atividade deste local.\",\n \"crud.archetype.locationActivity.title\": \"Atividade\",\n \"crud.archetype.locationActivity.description\": \"Veja um registro de todos os eventos, alterações e operações neste local.\",\n \"crud.archetype.owner.noOwner\": \"Nenhum responsável atribuído\",\n \"crud.archetype.owner.assignHint\": \"Edite este registro para atribuir um responsável.\",\n \"crud.archetype.owner.name\": \"Nome\",\n \"crud.archetype.owner.phone\": \"Telefone\",\n \"crud.archetype.owner.email\": \"E-mail\",\n \"crud.archetype.owner.document\": \"Documento\",\n \"crud.archetype.owner.address\": \"Endereço\",\n \"crud.archetype.owner.active\": \"Ativo\",\n \"crud.archetype.owner.inactive\": \"Inativo\",\n \"crud.archetype.history.title\": \"Histórico\",\n \"crud.archetype.history.description\": \"Veja o histórico de visitas, relatórios anteriores, tratamentos e linha do tempo de eventos.\",\n \"crud.archetype.subjectDocuments.title\": \"Documentos\",\n \"crud.archetype.subjectDocuments.description\": \"Anexe e gerencie arquivos, resultados de exames, imagens e certificados.\",\n \"schedule.days.sun\": \"Dom\",\n \"schedule.days.mon\": \"Seg\",\n \"schedule.days.tue\": \"Ter\",\n \"schedule.days.wed\": \"Qua\",\n \"schedule.days.thu\": \"Qui\",\n \"schedule.days.fri\": \"Sex\",\n \"schedule.days.sat\": \"Sáb\",\n \"schedule.editor.weeklyTitle\": \"Horário de Trabalho Semanal\",\n \"schedule.editor.weeklyDescription\": \"Defina quando este profissional está regularmente disponível\",\n \"schedule.editor.unavailable\": \"Indisponível\",\n \"schedule.editor.newInterval\": \"Novo intervalo para {{day}}\",\n \"schedule.editor.addHoursFor\": \"Adicionar horários para {{day}}\",\n \"schedule.editor.removeInterval\": \"Remover intervalo\",\n \"schedule.editor.copyToAll\": \"Copiar para todos os dias\",\n \"schedule.editor.bufferTooltip\": \"Tempo de intervalo entre atendimentos\",\n \"schedule.editor.min\": \"min\",\n \"schedule.editor.exceptionsTitle\": \"Exceções de Data\",\n \"schedule.editor.exceptionsDescription\": \"Substituir horário de trabalho para datas específicas\",\n \"schedule.editor.addException\": \"Adicionar Exceção\",\n \"schedule.editor.noExceptions\": \"Nenhuma exceção de data configurada\",\n \"schedule.editor.startDate\": \"Data de início\",\n \"schedule.editor.endDate\": \"Data de término\",\n \"schedule.editor.type\": \"Tipo\",\n \"schedule.editor.customHours\": \"Horário personalizado\",\n \"schedule.editor.workingHours\": \"Horário de trabalho\",\n \"schedule.editor.to\": \"até\",\n \"schedule.editor.addTimeBlock\": \"Adicionar bloco de horário\",\n \"schedule.editor.notes\": \"Observações\",\n \"schedule.editor.notesPlaceholder\": \"ex. Férias, Feriado, Treinamento...\",\n \"schedule.editor.saveException\": \"Salvar Exceção\",\n \"schedule.editor.removeException\": \"Remover exceção\",\n \"schedule.editor.failedToLoad\": \"Falha ao carregar agenda\",\n \"schedule.editor.saved\": \"Horário de trabalho salvo\",\n \"schedule.editor.failedToSave\": \"Falha ao salvar\",\n \"schedule.editor.selectStartDate\": \"Selecione uma data de início\",\n \"schedule.editor.endDateAfterStart\": \"A data de término deve ser posterior à data de início\",\n \"schedule.editor.exceptionAdded\": \"Exceção adicionada\",\n \"schedule.editor.failedToSaveException\": \"Falha ao salvar exceção\",\n \"schedule.editor.exceptionRemoved\": \"Exceção removida\",\n \"schedule.editor.failedToDelete\": \"Falha ao excluir\",\n \"schedule.blockSettings.title\": \"Configurações do Bloco\",\n \"schedule.blockSettings.location\": \"Local\",\n \"schedule.blockSettings.noLocation\": \"Sem local\",\n \"schedule.blockSettings.maxConcurrent\": \"Máx. simultâneos\",\n \"schedule.blockSettings.minAdvance\": \"Antecedência mín.\",\n \"schedule.blockSettings.maxAdvance\": \"Antecedência máx.\",\n \"schedule.blockSettings.hrs\": \"hrs\",\n \"schedule.blockSettings.days\": \"dias\",\n \"schedule.blockSettings.label\": \"Rótulo\",\n \"schedule.blockSettings.labelPlaceholder\": \"ex. Manhã – Apenas cortes\",\n \"schedule.blockSettings.allowedServices\": \"Serviços permitidos\",\n \"schedule.blockSettings.allServices\": \"Todos os serviços\",\n \"schedule.blockSettings.oneService\": \"1 serviço\",\n \"schedule.blockSettings.nServices\": \"{{count}} serviços\",\n \"registry.suppliers\": \"Fornecedor\",\n \"registry.suppliers.description\": \"Gerencie seus fornecedores de produtos e materiais\",\n \"registry.product-categories\": \"Categoria de Produto\",\n \"registry.product-categories.description\": \"Categorias de produtos para organização\",\n \"registry.stock-locations\": \"Local de Estoque\",\n \"registry.stock-locations.description\": \"Locais físicos de armazenamento do estoque\",\n \"registry.measurement-units\": \"Unidade de Medida\",\n \"registry.measurement-units.description\": \"Unidades padrão de medida\",\n \"registry.payment-methods\": \"Método de Pagamento\",\n \"registry.chart-of-accounts\": \"Plano de Contas\",\n \"registry.cost-centers\": \"Centro de Custo\",\n \"registry.bank-accounts\": \"Conta Bancária\",\n \"registry.commission-rules\": \"Regra de Comissão\",\n \"registry.price-tables\": \"Tabela de Preços\",\n \"registry.price-variations\": \"Variação de Preço\",\n \"registry.payment-method-types\": \"Tipo de Pagamento\",\n \"registry.card-brands\": \"Bandeira de Cartão\",\n \"registry.lead-sources\": \"Origem de Lead\",\n \"registry.tags\": \"Tag\",\n \"registry.activity-types\": \"Tipo de Atividade\",\n \"org.connectionError.title\": \"Falha na conexão\",\n \"org.connectionError.description\": \"Não foi possível conectar ao servidor. Verifique sua conexão com a internet e tente novamente.\",\n \"org.connectionError.retry\": \"Tentar novamente\",\n \"app.mockMode.banner\": \"Você está no modo offline. Os dados exibidos podem não estar atualizados.\",\n\n // Barra de controles das Análises — período, comparação e filtros.\n \"analytics.range.today\": \"Hoje\",\n \"analytics.range.yesterday\": \"Ontem\",\n \"analytics.range.last_7_days\": \"Últimos 7 dias\",\n \"analytics.range.last_30_days\": \"Últimos 30 dias\",\n \"analytics.range.last_90_days\": \"Últimos 90 dias\",\n \"analytics.range.this_month\": \"Este mês\",\n \"analytics.range.last_month\": \"Mês passado\",\n \"analytics.range.this_quarter\": \"Este trimestre\",\n \"analytics.range.this_year\": \"Este ano\",\n \"analytics.range.custom\": \"Período personalizado\",\n \"analytics.range.label\": \"Período\",\n \"analytics.range.from\": \"De\",\n \"analytics.range.to\": \"Até\",\n \"analytics.compare.previous_period\": \"Período anterior\",\n \"analytics.compare.previous_year\": \"Ano anterior\",\n \"analytics.compare.none\": \"Sem comparação\",\n \"analytics.compare.label\": \"Comparar\",\n \"analytics.filters\": \"Filtros\",\n \"analytics.filters.search\": \"Buscar filtros\",\n \"analytics.filters.none\": \"Nenhum filtro encontrado\",\n \"analytics.filters.noOptions\": \"Nenhuma opção disponível\",\n \"analytics.filters.apply\": \"Aplicar\",\n \"analytics.filters.clear\": \"Limpar\",\n \"analytics.filters.general\": \"Geral\",\n \"analytics.filters.selected\": \"{{count}} selecionados\",\n \"analytics.filters.remove\": \"Remover filtro\",\n \"analytics.refresh\": \"Atualizar\",\n \"assistant.askAI\": \"Criar com IA\",\n // Tasks moved from plugin-tasks into the shell with 047, so the strings had\n // to come with it — an app without the plugin would otherwise show raw keys.\n // The plugin still registers its own copy; last one in wins and they match.\n \"tasks.drawer.title\": \"Tarefas\",\n \"tasks.drawer.subtitle\": \"Gerencie as tarefas da equipe\",\n \"tasks.quickAdd.placeholder\": \"Adicionar tarefa...\",\n \"tasks.filter.all\": \"Todas\",\n \"tasks.filter.todo\": \"A Fazer\",\n \"tasks.filter.inProgress\": \"Em Andamento\",\n \"tasks.filter.done\": \"Concluídas\",\n \"tasks.filter.mine\": \"Minhas\",\n \"tasks.group.onboarding\": \"Primeiros passos\",\n // The same words as the group header — the tag is that header travelling\n // with the row into the filtered views, where there is no header.\n \"tasks.source.onboarding\": \"Primeiros passos\",\n \"tasks.source.agent\": \"Assistente\",\n \"tasks.status.todo\": \"A Fazer\",\n \"tasks.status.in_progress\": \"Em Andamento\",\n \"tasks.status.done\": \"Concluída\",\n \"tasks.status.cancelled\": \"Cancelada\",\n \"tasks.priority.low\": \"Baixa\",\n \"tasks.priority.medium\": \"Média\",\n \"tasks.priority.high\": \"Alta\",\n \"tasks.priority.urgent\": \"Urgente\",\n \"tasks.detail.descriptionPlaceholder\": \"Adicionar descrição...\",\n \"tasks.detail.dueDate\": \"Data de Vencimento\",\n \"tasks.detail.subtasks\": \"Subtarefas\",\n \"tasks.detail.delete\": \"Excluir Tarefa\",\n \"tasks.detail.deleteConfirm\": \"Tem certeza que deseja excluir esta tarefa?\",\n \"tasks.detail.created\": \"Criada em\",\n \"tasks.detail.updated\": \"Atualizada em\",\n \"tasks.detail.chatWithAi\": \"Conversar com IA\",\n \"tasks.detail.chatWithAi.prompt\": \"Assuma esta tarefa e me ajude a resolver agora, usando suas ferramentas quando precisar:\",\n \"tasks.detail.addSubtask\": \"Adicionar subtarefa...\",\n \"tasks.detail.back\": \"Voltar à lista\",\n \"tasks.detail.title\": \"Tarefa\",\n \"tasks.summary.overdue\": \"atrasadas\",\n \"tasks.summary.dueToday\": \"vencem hoje\",\n \"tasks.empty\": \"Nenhuma tarefa ainda\",\n \"tasks.empty.description\": \"Adicione sua primeira tarefa usando o campo acima\",\n \"analytics.moveBar\": \"Mover a barra (arraste, ou setas do teclado; duplo clique volta ao lugar)\",\n}\n"]}
|