@fayz-ai/plugin-financial 0.24.6 → 0.25.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.
@@ -134,6 +134,7 @@ export declare const MIGRATION_132_THE_STATEMENT_SOURCE_KNOWS_ITS_PROVIDER_ACCOU
134
134
  export declare const MIGRATION_133_REVERSING_A_PAYMENT_RELEASES_ITS_BANK_LINE = "-- 133: reversing a payment also releases its bank-statement evidence. A\n-- reconciled payment that was reversed left its statement line \"conciliada\",\n-- pointing at money that was undone, so the line never came back to be matched\n-- again. The rest of the function is 116's, unchanged (a reversal is never\n-- reversed; reversing twice replays the first reversal).\n\nCREATE OR REPLACE FUNCTION public.financial_reverse_movement(p_movement_id uuid, p_reason text, p_idempotency_key text DEFAULT NULL::text) RETURNS jsonb\n LANGUAGE plpgsql SECURITY DEFINER\n SET search_path TO ''\n AS $$\nDECLARE\n v_tenant uuid := public.plg_financial_require_tenant();\n v_m public.plg_financial_movements%ROWTYPE;\n v_rev uuid;\nBEGIN\n IF nullif(btrim(coalesce(p_reason, '')), '') IS NULL THEN\n RAISE EXCEPTION 'financial_reverse_movement: a reason is required' USING ERRCODE = '22023';\n END IF;\n SELECT * INTO v_m FROM public.plg_financial_movements WHERE id = p_movement_id AND tenant_id = v_tenant;\n IF NOT FOUND THEN\n RAISE EXCEPTION 'financial_reverse_movement: movement % not found', p_movement_id USING ERRCODE = 'P0002';\n END IF;\n PERFORM public.plg_financial_require_permission('financial.edit', v_m.unit_id);\n IF v_m.movement_kind NOT IN ('payment', 'transfer') OR v_m.debit_account_id IS NULL THEN\n RAISE EXCEPTION 'financial_reverse_movement: % is not a money event', p_movement_id USING ERRCODE = '55000';\n END IF;\n IF v_m.reverses_id IS NOT NULL THEN\n RAISE EXCEPTION 'Este lan\u00E7amento j\u00E1 \u00E9 um estorno e n\u00E3o pode ser estornado.' USING ERRCODE = '55000';\n END IF;\n IF v_m.reversed_by_id IS NOT NULL THEN\n RETURN jsonb_build_object('reversal_id', v_m.reversed_by_id, 'movement_id', v_m.id, 'replayed', true);\n END IF;\n IF p_idempotency_key IS NOT NULL THEN\n PERFORM public.plg_financial_claim_idempotency(v_tenant, p_idempotency_key);\n SELECT m.id INTO v_rev FROM public.plg_financial_movements m WHERE m.tenant_id = v_tenant AND m.idempotency_key = p_idempotency_key;\n IF v_rev IS NOT NULL THEN\n RETURN jsonb_build_object('reversal_id', v_rev, 'movement_id', v_m.id, 'replayed', true);\n END IF;\n END IF;\n\n INSERT INTO public.plg_financial_movements\n (tenant_id, unit_id, invoice_id, financial_invoice_id, financial_invoice_installment_id, direction, movement_kind, amount, paid_amount, status,\n due_date, payment_date, installment_number, method, cash_session_id, bank_account_id, reason, notes, metadata,\n idempotency_key, created_by, reverses_id, debit_account_id, credit_account_id)\n VALUES\n (v_m.tenant_id, v_m.unit_id, v_m.invoice_id, v_m.financial_invoice_id, v_m.financial_invoice_installment_id,\n CASE WHEN v_m.direction = 'credit' THEN 'debit' ELSE 'credit' END, v_m.movement_kind, v_m.amount, v_m.amount, 'paid',\n current_date, current_date, v_m.installment_number, v_m.method, v_m.cash_session_id, v_m.bank_account_id, btrim(p_reason),\n 'Estorno de ' || v_m.id::text,\n jsonb_build_object('source', 'financial_reverse_movement', 'reversal_of', v_m.id, 'reason', btrim(p_reason)),\n p_idempotency_key, auth.uid(), v_m.id, v_m.credit_account_id, v_m.debit_account_id)\n RETURNING id INTO v_rev;\n\n UPDATE public.plg_financial_movements SET reversed_by_id = v_rev, reason = coalesce(reason, btrim(p_reason)), updated_at = now()\n WHERE id = v_m.id;\n IF v_m.financial_invoice_installment_id IS NOT NULL THEN PERFORM public.plg_financial_sync_mirror(v_m.financial_invoice_installment_id); END IF;\n\n -- The bank line that proved this payment no longer proves anything: it goes\n -- back to the reconciliation queue instead of pointing at money that left.\n UPDATE public.plg_financial_bank_statement_lines\n SET matched_movement_id = NULL, reconciled_at = NULL\n WHERE tenant_id = v_tenant AND matched_movement_id = v_m.id;\n UPDATE public.plg_financial_movements SET reconciled_at = NULL WHERE id = v_m.id AND reconciled_at IS NOT NULL;\n\n PERFORM public.plg_financial_audit(v_tenant, 'financial.movement.reverse', 'plg_financial_movements', v_m.id::text,\n jsonb_build_object('reversal_id', v_rev, 'amount', v_m.amount, 'reason', btrim(p_reason), 'idempotency_key', p_idempotency_key));\n RETURN jsonb_build_object('reversal_id', v_rev, 'movement_id', v_m.id, 'replayed', false);\nEND $$;\n\n";
135
135
  export declare const MIGRATION_134_A_BILL_KNOWS_WHO_FILED_IT = "-- 134: a bill knows who filed it. `plg_financial_invoices.created_by` has been\n-- in the table since the baseline and the screens read it for the record\n-- footer (\"Criado em \u2026 por \u2026\"), but nothing ever wrote it: movements and\n-- allocations stamp their author in a trigger, invoices never got one. Every\n-- bill came out authorless. From now on the signed-in person who inserts the\n-- row is its author; an explicit value (an import, an RPC that knows better)\n-- still wins. Nothing is backfilled \u2014 who filed an old bill is not knowable.\n-- Additive and idempotent.\n\nCREATE OR REPLACE FUNCTION public.trg_plg_financial_invoices_created_by()\nRETURNS trigger\nLANGUAGE plpgsql\nSET search_path TO ''\nAS $$\nBEGIN\n NEW.created_by := coalesce(NEW.created_by, auth.uid());\n RETURN NEW;\nEND $$;\n\nDROP TRIGGER IF EXISTS plg_financial_invoices_created_by ON public.plg_financial_invoices;\nCREATE TRIGGER plg_financial_invoices_created_by\n BEFORE INSERT ON public.plg_financial_invoices\n FOR EACH ROW EXECUTE FUNCTION public.trg_plg_financial_invoices_created_by();\n";
136
136
  export declare const MIGRATION_135_A_BILL_AND_ITS_LINES_ARE_WRITTEN_TOGETHER = "-- 135: a bill's lines are written by the server, with the bill's own tenant and\n-- unit, in one statement. The client used to insert them into public.items\n-- itself, stamped with ITS idea of the active tenant; when that lagged behind\n-- the session (a workspace switch), RLS refused the lines, the error was\n-- ignored, and the bill kept its total with no lines. Replacing lines deleted\n-- the old ones first, so a refused insert lost them too. Here the delete and the\n-- insert are one transaction, under the same permission the bill itself needs.\n-- Additive and idempotent.\n\nCREATE OR REPLACE FUNCTION public.financial_set_invoice_lines(p_invoice_id uuid, p_lines jsonb, p_replace boolean DEFAULT false)\nRETURNS jsonb\nLANGUAGE plpgsql SECURITY DEFINER\nSET search_path TO ''\nAS $$\nDECLARE\n v_tenant uuid := public.plg_financial_require_tenant();\n v_invoice public.plg_financial_invoices%ROWTYPE;\n v_out jsonb;\nBEGIN\n SELECT * INTO v_invoice FROM public.plg_financial_invoices WHERE id = p_invoice_id AND tenant_id = v_tenant;\n IF NOT FOUND THEN\n RAISE EXCEPTION 'financial_set_invoice_lines: invoice % not found in this tenant', p_invoice_id USING ERRCODE = 'P0002';\n END IF;\n PERFORM public.plg_financial_require_permission(CASE WHEN p_replace THEN 'financial.edit' ELSE 'financial.create' END, v_invoice.unit_id);\n IF jsonb_typeof(coalesce(p_lines, '[]'::jsonb)) <> 'array' THEN\n RAISE EXCEPTION 'financial_set_invoice_lines: lines must be an array' USING ERRCODE = '22023';\n END IF;\n\n -- Cancelled lines are history: they are never replaced.\n IF p_replace THEN\n DELETE FROM public.items WHERE invoice_id = p_invoice_id AND tenant_id = v_tenant AND cancelled_at IS NULL;\n END IF;\n\n WITH ins AS (\n INSERT INTO public.items (tenant_id, unit_id, invoice_id, name, quantity, unit_price, discount, total, sort_order, metadata)\n SELECT v_tenant, v_invoice.unit_id, p_invoice_id,\n nullif(l ->> 'name', ''),\n coalesce((l ->> 'quantity')::numeric, 1),\n coalesce((l ->> 'unit_price')::numeric, 0),\n coalesce((l ->> 'discount')::numeric, 0),\n coalesce((l ->> 'total')::numeric, 0),\n coalesce((l ->> 'sort_order')::int, (o - 1)::int),\n coalesce(l -> 'metadata', '{}'::jsonb)\n FROM jsonb_array_elements(coalesce(p_lines, '[]'::jsonb)) WITH ORDINALITY AS t(l, o)\n RETURNING id, sort_order\n )\n SELECT coalesce(jsonb_agg(jsonb_build_object('id', id, 'sort_order', sort_order) ORDER BY sort_order), '[]'::jsonb) INTO v_out FROM ins;\n RETURN v_out;\nEND $$;\nREVOKE ALL ON FUNCTION public.financial_set_invoice_lines(uuid, jsonb, boolean) FROM PUBLIC, anon;\nGRANT EXECUTE ON FUNCTION public.financial_set_invoice_lines(uuid, jsonb, boolean) TO authenticated, service_role;\n";
137
+ export declare const MIGRATION_136_A_BANK_STATEMENT_ARRIVES_FROM_THE_SERVICE = "-- ============================================================================\n-- 136 \u2014 a bank statement arrives from the integration service\n--\n-- The V2 sink of the banking module (ADR 0003): the doors through which the\n-- integration service hands this product the lines of a store's bank or\n-- credit-card statement, withdraws the ones the bank took back, reports the\n-- connection's state, and reads which lines are already here. The provider\n-- calls, the schedule and the waiting are the service's; what a line IS here\n-- is decided here.\n--\n-- A line is keyed as before: (tenant, external_source, external_id), where\n-- external_source is the statement source's provider ('openbanking:pagbank')\n-- and external_id the provider's transaction id. Lines already brought in by\n-- the V1 migration match the ones the service brings, so nothing doubles.\n--\n-- Providers revise statements for days: an Open Finance bank can drop a\n-- transaction and bring it back under a new id. A withdrawn line is marked\n-- (provider_deleted), never deleted, and comes back if the provider brings\n-- the same id again. A line already reconciled keeps its money and its date:\n-- a revision of either is recorded beside it, for a person to look at.\n--\n-- No person is behind these calls; the actor is the service, acting for the\n-- tenant it names. The functions are closed to every signed-in user and\n-- opened only to the service's role, `fayz_integration`, when it exists.\n-- ============================================================================\n\nCREATE OR REPLACE FUNCTION public.financial_statement_source_get(p_tenant uuid, p_source uuid)\nRETURNS jsonb\nLANGUAGE sql STABLE SECURITY DEFINER\nSET search_path TO ''\nAS $$\n SELECT jsonb_build_object(\n 'id', s.id, 'tenantId', s.tenant_id, 'unitId', s.unit_id, 'accountId', s.account_id,\n 'provider', s.provider, 'kind', s.statement_kind, 'cardLast4', s.card_last4,\n 'accountRef', s.provider_account_hash, 'active', s.is_active,\n 'lastSyncedAt', s.last_synced_at, 'lastSyncStatus', s.last_sync_status\n )\n FROM public.plg_financial_account_statement_sources s\n WHERE s.id = p_source AND s.tenant_id = p_tenant\n$$;\n\n-- Every source tied to a provider account, across tenants: how the service\n-- finds the connections the V1 migration left, to adopt them.\nCREATE OR REPLACE FUNCTION public.financial_statement_sources_linked(p_provider_prefix text)\nRETURNS SETOF jsonb\nLANGUAGE sql STABLE SECURITY DEFINER\nSET search_path TO ''\nAS $$\n SELECT jsonb_build_object(\n 'id', s.id, 'tenantId', s.tenant_id, 'unitId', s.unit_id, 'accountId', s.account_id,\n 'provider', s.provider, 'kind', s.statement_kind, 'cardLast4', s.card_last4,\n 'accountRef', s.provider_account_hash, 'active', s.is_active\n )\n FROM public.plg_financial_account_statement_sources s\n WHERE s.provider LIKE p_provider_prefix || '%' AND s.provider_account_hash IS NOT NULL\n ORDER BY s.tenant_id, s.created_at\n$$;\n\n-- Ties a source to the provider's account, once the store has authorized it.\nCREATE OR REPLACE FUNCTION public.financial_statement_source_link(p_tenant uuid, p_source uuid, p_account_ref text)\nRETURNS void\nLANGUAGE plpgsql SECURITY DEFINER\nSET search_path TO ''\nAS $$\nBEGIN\n IF p_account_ref IS NULL OR btrim(p_account_ref) = '' THEN\n RAISE EXCEPTION 'financial_statement_source_link: account ref is required' USING ERRCODE = '22023';\n END IF;\n UPDATE public.plg_financial_account_statement_sources\n SET provider_account_hash = btrim(p_account_ref), updated_at = now()\n WHERE id = p_source AND tenant_id = p_tenant;\n IF NOT FOUND THEN\n RAISE EXCEPTION 'financial_statement_source_link: source % is not of tenant %', p_source, p_tenant USING ERRCODE = 'P0002';\n END IF;\nEND\n$$;\n\nCREATE OR REPLACE FUNCTION public.financial_statement_lines_ingest(p_tenant uuid, p_source uuid, p_lines jsonb)\nRETURNS jsonb\nLANGUAGE plpgsql SECURITY DEFINER\nSET search_path TO ''\nAS $$\nDECLARE\n v_source public.plg_financial_account_statement_sources%ROWTYPE;\n v_line jsonb;\n v_amount numeric;\n v_day date;\n v_method text;\n v_meta jsonb;\n v_existing public.plg_financial_bank_statement_lines%ROWTYPE;\n v_inserted integer := 0;\n v_updated integer := 0;\nBEGIN\n SELECT * INTO v_source FROM public.plg_financial_account_statement_sources\n WHERE id = p_source AND tenant_id = p_tenant;\n IF NOT FOUND THEN\n RAISE EXCEPTION 'financial_statement_lines_ingest: source % is not of tenant %', p_source, p_tenant USING ERRCODE = 'P0002';\n END IF;\n IF jsonb_typeof(p_lines) <> 'array' THEN\n RAISE EXCEPTION 'financial_statement_lines_ingest: lines must be an array' USING ERRCODE = '22023';\n END IF;\n\n FOR v_line IN SELECT value FROM jsonb_array_elements(p_lines) LOOP\n IF coalesce(v_line ->> 'externalId', '') = '' OR (v_line ->> 'direction') NOT IN ('credit', 'debit') THEN\n RAISE EXCEPTION 'financial_statement_lines_ingest: a line needs externalId and direction' USING ERRCODE = '22023';\n END IF;\n v_amount := round((v_line ->> 'amountCents')::numeric / 100, 2);\n v_day := (v_line ->> 'postedOn')::date;\n IF v_amount IS NULL OR v_amount < 0 OR v_day IS NULL THEN\n RAISE EXCEPTION 'financial_statement_lines_ingest: line % needs a positive amount and a day', v_line ->> 'externalId' USING ERRCODE = '22023';\n END IF;\n v_method := nullif(v_line ->> 'paymentMethod', '');\n v_meta := jsonb_strip_nulls(jsonb_build_object(\n 'statement', jsonb_build_object('ref', v_line ->> 'statementRef', 'via', 'integration-service'),\n 'paymentMethod', v_method,\n 'currency', coalesce(v_line ->> 'currency', 'BRL'),\n 'boleto', v_line -> 'boleto',\n 'card', v_line -> 'card'\n ));\n\n SELECT * INTO v_existing FROM public.plg_financial_bank_statement_lines\n WHERE tenant_id = p_tenant AND external_source = v_source.provider AND external_id = v_line ->> 'externalId';\n\n IF NOT FOUND THEN\n INSERT INTO public.plg_financial_bank_statement_lines (\n tenant_id, unit_id, bank_account_id, external_source, external_id, posted_on, direction, amount,\n description, counterparty_name, counterparty_document, document, code, category, transaction_type,\n provider_deleted, raw_payload, metadata\n ) VALUES (\n p_tenant, v_source.unit_id, v_source.account_id, v_source.provider, v_line ->> 'externalId', v_day,\n v_line ->> 'direction', v_amount,\n nullif(v_line ->> 'description', ''), nullif(v_line #>> '{counterparty,name}', ''),\n nullif(v_line #>> '{counterparty,document}', ''), nullif(v_line ->> 'reference', ''),\n nullif(v_line ->> 'code', ''), nullif(v_line ->> 'category', ''),\n coalesce(v_method, upper(v_line ->> 'direction')),\n false, coalesce(v_line -> 'raw', '{}'::jsonb), v_meta\n );\n v_inserted := v_inserted + 1;\n ELSE\n UPDATE public.plg_financial_bank_statement_lines l SET\n -- Money, day and direction move only while nobody has reconciled the line.\n posted_on = CASE WHEN l.reconciled_at IS NULL THEN v_day ELSE l.posted_on END,\n amount = CASE WHEN l.reconciled_at IS NULL THEN v_amount ELSE l.amount END,\n direction = CASE WHEN l.reconciled_at IS NULL THEN v_line ->> 'direction' ELSE l.direction END,\n description = coalesce(nullif(v_line ->> 'description', ''), l.description),\n counterparty_name = coalesce(nullif(v_line #>> '{counterparty,name}', ''), l.counterparty_name),\n counterparty_document = coalesce(nullif(v_line #>> '{counterparty,document}', ''), l.counterparty_document),\n document = coalesce(nullif(v_line ->> 'reference', ''), l.document),\n code = coalesce(nullif(v_line ->> 'code', ''), l.code),\n category = coalesce(nullif(v_line ->> 'category', ''), l.category),\n transaction_type = coalesce(v_method, l.transaction_type),\n provider_deleted = false,\n raw_payload = coalesce(v_line -> 'raw', l.raw_payload),\n metadata = (l.metadata - 'withdrawn') || v_meta\n || CASE WHEN l.reconciled_at IS NOT NULL AND (l.amount <> v_amount OR l.posted_on <> v_day OR l.direction <> v_line ->> 'direction')\n THEN jsonb_build_object('revisedAfterReconciliation', jsonb_build_object(\n 'amount', v_amount, 'postedOn', v_day, 'direction', v_line ->> 'direction', 'at', now()))\n ELSE '{}'::jsonb END,\n updated_at = now()\n WHERE l.id = v_existing.id;\n v_updated := v_updated + 1;\n END IF;\n END LOOP;\n\n RETURN jsonb_build_object('inserted', v_inserted, 'updated', v_updated);\nEND\n$$;\n\nCREATE OR REPLACE FUNCTION public.financial_statement_lines_withdraw(p_tenant uuid, p_source uuid, p_external_ids text[], p_reason text)\nRETURNS integer\nLANGUAGE plpgsql SECURITY DEFINER\nSET search_path TO ''\nAS $$\nDECLARE\n v_source public.plg_financial_account_statement_sources%ROWTYPE;\n v_count integer;\nBEGIN\n SELECT * INTO v_source FROM public.plg_financial_account_statement_sources\n WHERE id = p_source AND tenant_id = p_tenant;\n IF NOT FOUND THEN\n RAISE EXCEPTION 'financial_statement_lines_withdraw: source % is not of tenant %', p_source, p_tenant USING ERRCODE = 'P0002';\n END IF;\n UPDATE public.plg_financial_bank_statement_lines l\n SET provider_deleted = true,\n metadata = l.metadata || jsonb_build_object('withdrawn', jsonb_build_object('reason', p_reason, 'at', now())),\n updated_at = now()\n WHERE l.tenant_id = p_tenant AND l.external_source = v_source.provider\n AND l.bank_account_id = v_source.account_id\n AND l.external_id = ANY (p_external_ids) AND NOT l.provider_deleted;\n GET DIAGNOSTICS v_count = ROW_COUNT;\n RETURN v_count;\nEND\n$$;\n\n-- The lines here for a source in a window, withdrawn ones left out: what the\n-- service compares with the provider to find the ones the bank took back.\nCREATE OR REPLACE FUNCTION public.financial_statement_lines_known(p_tenant uuid, p_source uuid, p_from date, p_to date)\nRETURNS SETOF text\nLANGUAGE sql STABLE SECURITY DEFINER\nSET search_path TO ''\nAS $$\n SELECT l.external_id\n FROM public.plg_financial_bank_statement_lines l\n JOIN public.plg_financial_account_statement_sources s\n ON s.id = p_source AND s.tenant_id = p_tenant\n WHERE l.tenant_id = p_tenant AND l.external_source = s.provider AND l.bank_account_id = s.account_id\n AND l.posted_on BETWEEN p_from AND p_to AND NOT l.provider_deleted\n$$;\n\nCREATE OR REPLACE FUNCTION public.financial_statement_source_report(\n p_tenant uuid, p_source uuid, p_status text, p_error text, p_details jsonb\n) RETURNS void\nLANGUAGE plpgsql SECURITY DEFINER\nSET search_path TO ''\nAS $$\nBEGIN\n IF p_status NOT IN ('ok', 'error', 'pending', 'revoked') THEN\n RAISE EXCEPTION 'financial_statement_source_report: unknown status %', p_status USING ERRCODE = '22023';\n END IF;\n UPDATE public.plg_financial_account_statement_sources s\n SET last_sync_status = p_status,\n last_sync_error = CASE WHEN p_status = 'error' THEN left(p_error, 500) ELSE NULL END,\n last_synced_at = CASE WHEN p_status = 'ok' THEN now() ELSE s.last_synced_at END,\n metadata = s.metadata || jsonb_build_object('connection', coalesce(p_details, '{}'::jsonb)),\n updated_at = now()\n WHERE s.id = p_source AND s.tenant_id = p_tenant;\n IF NOT FOUND THEN\n RAISE EXCEPTION 'financial_statement_source_report: source % is not of tenant %', p_source, p_tenant USING ERRCODE = 'P0002';\n END IF;\nEND\n$$;\n\nREVOKE ALL ON FUNCTION public.financial_statement_source_get(uuid, uuid) FROM PUBLIC, anon, authenticated;\nREVOKE ALL ON FUNCTION public.financial_statement_sources_linked(text) FROM PUBLIC, anon, authenticated;\nREVOKE ALL ON FUNCTION public.financial_statement_source_link(uuid, uuid, text) FROM PUBLIC, anon, authenticated;\nREVOKE ALL ON FUNCTION public.financial_statement_lines_ingest(uuid, uuid, jsonb) FROM PUBLIC, anon, authenticated;\nREVOKE ALL ON FUNCTION public.financial_statement_lines_withdraw(uuid, uuid, text[], text) FROM PUBLIC, anon, authenticated;\nREVOKE ALL ON FUNCTION public.financial_statement_lines_known(uuid, uuid, date, date) FROM PUBLIC, anon, authenticated;\nREVOKE ALL ON FUNCTION public.financial_statement_source_report(uuid, uuid, text, text, jsonb) FROM PUBLIC, anon, authenticated;\n\nDO $$\nBEGIN\n IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'fayz_integration') THEN\n GRANT USAGE ON SCHEMA public TO fayz_integration;\n GRANT EXECUTE ON FUNCTION public.financial_statement_source_get(uuid, uuid) TO fayz_integration;\n GRANT EXECUTE ON FUNCTION public.financial_statement_sources_linked(text) TO fayz_integration;\n GRANT EXECUTE ON FUNCTION public.financial_statement_source_link(uuid, uuid, text) TO fayz_integration;\n GRANT EXECUTE ON FUNCTION public.financial_statement_lines_ingest(uuid, uuid, jsonb) TO fayz_integration;\n GRANT EXECUTE ON FUNCTION public.financial_statement_lines_withdraw(uuid, uuid, text[], text) TO fayz_integration;\n GRANT EXECUTE ON FUNCTION public.financial_statement_lines_known(uuid, uuid, date, date) TO fayz_integration;\n GRANT EXECUTE ON FUNCTION public.financial_statement_source_report(uuid, uuid, text, text, jsonb) TO fayz_integration;\n END IF;\nEND\n$$;\n";
137
138
  export declare const MIGRATIONS: Array<{
138
139
  id: string;
139
140
  sql: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { StatementSink } from '@fayz-ai/contracts';
2
+ /**
3
+ * The plugin's server-side code, and all of it: the statement sink the
4
+ * integration service calls to hand this product a store's bank lines
5
+ * (ADR 0003, migration 136). One SQL function per method, the tenant
6
+ * explicit, no rule here. Never imports React; the service is its only
7
+ * consumer.
8
+ */
9
+ /** The slice of a Postgres client this needs; `pg.Pool` satisfies it. */
10
+ export interface SqlClient {
11
+ query<Row = Record<string, unknown>>(text: string, params?: unknown[]): Promise<{
12
+ rows: Row[];
13
+ }>;
14
+ }
15
+ /** A statement source as the product keeps it. */
16
+ export interface V2StatementSource {
17
+ id: string;
18
+ tenantId: string;
19
+ unitId: string | null;
20
+ accountId: string;
21
+ /** 'openbanking:pagbank'…: the lines' external_source. */
22
+ provider: string;
23
+ kind: 'bank' | 'credit_card';
24
+ cardLast4: string | null;
25
+ /** The provider's account id (PlugBank: accountHash); null until linked. */
26
+ accountRef: string | null;
27
+ active: boolean;
28
+ }
29
+ export declare function createV2StatementSink(db: SqlClient): StatementSink & {
30
+ source(tenantId: string, sourceId: string): Promise<V2StatementSource | null>;
31
+ linked(providerPrefix: string): Promise<V2StatementSource[]>;
32
+ link(tenantId: string, sourceId: string, accountRef: string): Promise<void>;
33
+ };
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsC,aAAa,EAAwB,MAAM,oBAAoB,CAAA;AAEjH;;;;;;GAMG;AAEH,yEAAyE;AACzE,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC,CAAA;CACjG;AAED,kDAAkD;AAClD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,GAAG,aAAa,CAAA;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,4EAA4E;IAC5E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,SAAS,GAAG,aAAa,GAAG;IACpE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAA;IAC7E,MAAM,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAA;IAC5D,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5E,CAsDA"}
@@ -0,0 +1,58 @@
1
+ // src/server/index.ts
2
+ function createV2StatementSink(db) {
3
+ return {
4
+ async ingest(lines, c) {
5
+ if (!lines.length) return { inserted: 0, updated: 0 };
6
+ const { rows } = await db.query(
7
+ "SELECT public.financial_statement_lines_ingest($1, $2, $3::jsonb) AS r",
8
+ [c.tenantId, c.sourceId, JSON.stringify(lines)]
9
+ );
10
+ return rows[0]?.r ?? { inserted: 0, updated: 0 };
11
+ },
12
+ async withdraw(externalIds, c, reason) {
13
+ if (!externalIds.length) return { withdrawn: 0 };
14
+ const { rows } = await db.query(
15
+ "SELECT public.financial_statement_lines_withdraw($1, $2, $3::text[], $4) AS n",
16
+ [c.tenantId, c.sourceId, externalIds, reason]
17
+ );
18
+ return { withdrawn: Number(rows[0]?.n ?? 0) };
19
+ },
20
+ async report(state, c) {
21
+ await db.query("SELECT public.financial_statement_source_report($1, $2, $3, $4, $5::jsonb)", [
22
+ c.tenantId,
23
+ c.sourceId,
24
+ state.status,
25
+ state.error ?? null,
26
+ JSON.stringify(state.details ?? {})
27
+ ]);
28
+ },
29
+ async known(c, from, to) {
30
+ const { rows } = await db.query(
31
+ "SELECT public.financial_statement_lines_known($1, $2, $3::date, $4::date) AS id",
32
+ [c.tenantId, c.sourceId, from, to]
33
+ );
34
+ return rows.map((r) => r.id);
35
+ },
36
+ async source(tenantId, sourceId) {
37
+ const { rows } = await db.query(
38
+ "SELECT public.financial_statement_source_get($1, $2) AS s",
39
+ [tenantId, sourceId]
40
+ );
41
+ return rows[0]?.s ?? null;
42
+ },
43
+ async linked(providerPrefix) {
44
+ const { rows } = await db.query(
45
+ "SELECT s FROM public.financial_statement_sources_linked($1) AS s",
46
+ [providerPrefix]
47
+ );
48
+ return rows.map((r) => r.s);
49
+ },
50
+ async link(tenantId, sourceId, accountRef) {
51
+ await db.query("SELECT public.financial_statement_source_link($1, $2, $3)", [tenantId, sourceId, accountRef]);
52
+ }
53
+ };
54
+ }
55
+
56
+ export { createV2StatementSink };
57
+ //# sourceMappingURL=index.js.map
58
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/index.ts"],"names":[],"mappings":";AA8BO,SAAS,sBAAsB,EAAA,EAIpC;AACA,EAAA,OAAO;AAAA,IACL,MAAM,MAAA,CAAO,KAAA,EAAwB,CAAA,EAAwB;AAC3D,MAAA,IAAI,CAAC,MAAM,MAAA,EAAQ,OAAO,EAAE,QAAA,EAAU,CAAA,EAAG,SAAS,CAAA,EAAE;AACpD,MAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,EAAA,CAAG,KAAA;AAAA,QACxB,wEAAA;AAAA,QACA,CAAC,EAAE,QAAA,EAAU,CAAA,CAAE,UAAU,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC;AAAA,OAChD;AACA,MAAA,OAAO,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,IAAK,EAAE,QAAA,EAAU,CAAA,EAAG,SAAS,CAAA,EAAE;AAAA,IACjD,CAAA;AAAA,IAEA,MAAM,QAAA,CAAS,WAAA,EAAuB,CAAA,EAAwB,MAAA,EAAgB;AAC5E,MAAA,IAAI,CAAC,WAAA,CAAY,MAAA,EAAQ,OAAO,EAAE,WAAW,CAAA,EAAE;AAC/C,MAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,EAAA,CAAG,KAAA;AAAA,QACxB,+EAAA;AAAA,QACA,CAAC,CAAA,CAAE,QAAA,EAAU,CAAA,CAAE,QAAA,EAAU,aAAa,MAAM;AAAA,OAC9C;AACA,MAAA,OAAO,EAAE,WAAW,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,IAAK,CAAC,CAAA,EAAE;AAAA,IAC9C,CAAA;AAAA,IAEA,MAAM,MAAA,CAAO,KAAA,EAA6B,CAAA,EAAwB;AAChE,MAAA,MAAM,EAAA,CAAG,MAAM,4EAAA,EAA8E;AAAA,QAC3F,CAAA,CAAE,QAAA;AAAA,QAAU,CAAA,CAAE,QAAA;AAAA,QAAU,KAAA,CAAM,MAAA;AAAA,QAAQ,MAAM,KAAA,IAAS,IAAA;AAAA,QAAM,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,OAAA,IAAW,EAAE;AAAA,OAC9F,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,MAAM,KAAA,CAAM,CAAA,EAAwB,IAAA,EAAc,EAAA,EAAY;AAC5D,MAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,EAAA,CAAG,KAAA;AAAA,QACxB,iFAAA;AAAA,QACA,CAAC,CAAA,CAAE,QAAA,EAAU,CAAA,CAAE,QAAA,EAAU,MAAM,EAAE;AAAA,OACnC;AACA,MAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AAAA,IAC7B,CAAA;AAAA,IAEA,MAAM,MAAA,CAAO,QAAA,EAAkB,QAAA,EAAkB;AAC/C,MAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,EAAA,CAAG,KAAA;AAAA,QACxB,2DAAA;AAAA,QACA,CAAC,UAAU,QAAQ;AAAA,OACrB;AACA,MAAA,OAAO,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,IAAK,IAAA;AAAA,IACvB,CAAA;AAAA,IAEA,MAAM,OAAO,cAAA,EAAwB;AACnC,MAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,EAAA,CAAG,KAAA;AAAA,QACxB,kEAAA;AAAA,QACA,CAAC,cAAc;AAAA,OACjB;AACA,MAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,CAAC,CAAA;AAAA,IAC5B,CAAA;AAAA,IAEA,MAAM,IAAA,CAAK,QAAA,EAAkB,QAAA,EAAkB,UAAA,EAAoB;AACjE,MAAA,MAAM,GAAG,KAAA,CAAM,2DAAA,EAA6D,CAAC,QAAA,EAAU,QAAA,EAAU,UAAU,CAAC,CAAA;AAAA,IAC9G;AAAA,GACF;AACF","file":"index.js","sourcesContent":["import type { StatementConnection, StatementLine, StatementSink, StatementSourceState } from '@fayz-ai/contracts'\n\n/**\n * The plugin's server-side code, and all of it: the statement sink the\n * integration service calls to hand this product a store's bank lines\n * (ADR 0003, migration 136). One SQL function per method, the tenant\n * explicit, no rule here. Never imports React; the service is its only\n * consumer.\n */\n\n/** The slice of a Postgres client this needs; `pg.Pool` satisfies it. */\nexport interface SqlClient {\n query<Row = Record<string, unknown>>(text: string, params?: unknown[]): Promise<{ rows: Row[] }>\n}\n\n/** A statement source as the product keeps it. */\nexport interface V2StatementSource {\n id: string\n tenantId: string\n unitId: string | null\n accountId: string\n /** 'openbanking:pagbank'…: the lines' external_source. */\n provider: string\n kind: 'bank' | 'credit_card'\n cardLast4: string | null\n /** The provider's account id (PlugBank: accountHash); null until linked. */\n accountRef: string | null\n active: boolean\n}\n\nexport function createV2StatementSink(db: SqlClient): StatementSink & {\n source(tenantId: string, sourceId: string): Promise<V2StatementSource | null>\n linked(providerPrefix: string): Promise<V2StatementSource[]>\n link(tenantId: string, sourceId: string, accountRef: string): Promise<void>\n} {\n return {\n async ingest(lines: StatementLine[], c: StatementConnection) {\n if (!lines.length) return { inserted: 0, updated: 0 }\n const { rows } = await db.query<{ r: { inserted: number; updated: number } }>(\n 'SELECT public.financial_statement_lines_ingest($1, $2, $3::jsonb) AS r',\n [c.tenantId, c.sourceId, JSON.stringify(lines)],\n )\n return rows[0]?.r ?? { inserted: 0, updated: 0 }\n },\n\n async withdraw(externalIds: string[], c: StatementConnection, reason: string) {\n if (!externalIds.length) return { withdrawn: 0 }\n const { rows } = await db.query<{ n: number }>(\n 'SELECT public.financial_statement_lines_withdraw($1, $2, $3::text[], $4) AS n',\n [c.tenantId, c.sourceId, externalIds, reason],\n )\n return { withdrawn: Number(rows[0]?.n ?? 0) }\n },\n\n async report(state: StatementSourceState, c: StatementConnection) {\n await db.query('SELECT public.financial_statement_source_report($1, $2, $3, $4, $5::jsonb)', [\n c.tenantId, c.sourceId, state.status, state.error ?? null, JSON.stringify(state.details ?? {}),\n ])\n },\n\n async known(c: StatementConnection, from: string, to: string) {\n const { rows } = await db.query<{ id: string }>(\n 'SELECT public.financial_statement_lines_known($1, $2, $3::date, $4::date) AS id',\n [c.tenantId, c.sourceId, from, to],\n )\n return rows.map((r) => r.id)\n },\n\n async source(tenantId: string, sourceId: string) {\n const { rows } = await db.query<{ s: V2StatementSource | null }>(\n 'SELECT public.financial_statement_source_get($1, $2) AS s',\n [tenantId, sourceId],\n )\n return rows[0]?.s ?? null\n },\n\n async linked(providerPrefix: string) {\n const { rows } = await db.query<{ s: V2StatementSource }>(\n 'SELECT s FROM public.financial_statement_sources_linked($1) AS s',\n [providerPrefix],\n )\n return rows.map((r) => r.s)\n },\n\n async link(tenantId: string, sourceId: string, accountRef: string) {\n await db.query('SELECT public.financial_statement_source_link($1, $2, $3)', [tenantId, sourceId, accountRef])\n },\n }\n}\n"]}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "status": "beta",
5
5
  "dependencies": []
6
6
  },
7
- "version": "0.24.6",
7
+ "version": "0.25.1",
8
8
  "description": "Fayz SDK — plugin-financial plugin",
9
9
  "type": "module",
10
10
  "sideEffects": false,
@@ -15,6 +15,10 @@
15
15
  ".": {
16
16
  "types": "./dist/index.d.ts",
17
17
  "import": "./dist/index.js"
18
+ },
19
+ "./server": {
20
+ "types": "./dist/server/index.d.ts",
21
+ "import": "./dist/server/index.js"
18
22
  }
19
23
  },
20
24
  "files": [
@@ -28,8 +32,9 @@
28
32
  },
29
33
  "dependencies": {
30
34
  "@tanstack/react-table": "^8.20.0",
31
- "@fayz-ai/admin": "^0.54.0",
32
- "@fayz-ai/core": "^0.53.0",
35
+ "@fayz-ai/admin": "^0.55.0",
36
+ "@fayz-ai/contracts": "^0.4.0",
37
+ "@fayz-ai/core": "^0.54.3",
33
38
  "@fayz-ai/financial": "^0.1.4",
34
39
  "@fayz-ai/ui": "^0.53.0"
35
40
  },