@fayz-ai/plugin-financial 0.9.0 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +3 -3
  2. package/dist/components/PersonStatementWidget.d.ts +1 -1
  3. package/dist/components/PersonStatementWidget.d.ts.map +1 -1
  4. package/dist/{FinancialContext.d.ts → context.d.ts} +4 -2
  5. package/dist/context.d.ts.map +1 -0
  6. package/dist/data/registries.d.ts.map +1 -0
  7. package/dist/index.d.ts +13 -4
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +1426 -1426
  10. package/dist/index.js.map +1 -1
  11. package/dist/integrations/stripe/connectorDef.d.ts +14 -0
  12. package/dist/integrations/stripe/connectorDef.d.ts.map +1 -0
  13. package/dist/integrations/stripe/data.d.ts +43 -0
  14. package/dist/integrations/stripe/data.d.ts.map +1 -0
  15. package/dist/lib/message-events.d.ts +12 -0
  16. package/dist/lib/message-events.d.ts.map +1 -0
  17. package/dist/{quick-add.d.ts → lib/quick-add.d.ts} +1 -1
  18. package/dist/lib/quick-add.d.ts.map +1 -0
  19. package/dist/locales/en.d.ts.map +1 -1
  20. package/dist/locales/pt-BR.d.ts.map +1 -1
  21. package/dist/{FinancialPage.d.ts → views/FinancialPage.d.ts} +3 -3
  22. package/dist/views/FinancialPage.d.ts.map +1 -0
  23. package/dist/views/InvoiceDetailView.d.ts.map +1 -1
  24. package/dist/views/InvoiceFormView.d.ts.map +1 -1
  25. package/dist/views/InvoiceListView.d.ts.map +1 -1
  26. package/dist/views/PayablesView.d.ts +1 -1
  27. package/dist/views/PayablesView.d.ts.map +1 -1
  28. package/dist/views/ReceivablesView.d.ts +1 -1
  29. package/dist/views/ReceivablesView.d.ts.map +1 -1
  30. package/dist/views/StatementsView.d.ts.map +1 -1
  31. package/dist/views/dashboardWidgets.d.ts +1 -1
  32. package/dist/views/dashboardWidgets.d.ts.map +1 -1
  33. package/package.json +12 -14
  34. package/dist/FinancialContext.d.ts.map +0 -1
  35. package/dist/FinancialPage.d.ts.map +0 -1
  36. package/dist/contract.test.d.ts +0 -2
  37. package/dist/contract.test.d.ts.map +0 -1
  38. package/dist/quick-add.d.ts.map +0 -1
  39. package/dist/registries.d.ts.map +0 -1
  40. package/src/FinancialContext.tsx +0 -59
  41. package/src/FinancialPage.tsx +0 -413
  42. package/src/README.md +0 -155
  43. package/src/components/FinancialGeneralSettings.tsx +0 -39
  44. package/src/components/FinancialOnboarding.tsx +0 -87
  45. package/src/components/FinancialSettings.tsx +0 -31
  46. package/src/components/PaymentModal.tsx +0 -369
  47. package/src/components/PersonStatementWidget.tsx +0 -133
  48. package/src/components/TransferModal.tsx +0 -150
  49. package/src/contract.test.ts +0 -58
  50. package/src/data/capability.test.ts +0 -135
  51. package/src/data/index.ts +0 -3
  52. package/src/data/mock.ts +0 -842
  53. package/src/data/supabase.ts +0 -968
  54. package/src/data/tables.ts +0 -13
  55. package/src/data/types.ts +0 -86
  56. package/src/index.ts +0 -487
  57. package/src/lib/tenant.ts +0 -3
  58. package/src/locales/en.ts +0 -493
  59. package/src/locales/index.ts +0 -7
  60. package/src/locales/pt-BR.ts +0 -493
  61. package/src/migrations/000_plg_rename.sql +0 -30
  62. package/src/migrations/001_financial_base.sql +0 -109
  63. package/src/migrations/002_chart_of_accounts.sql +0 -28
  64. package/src/migrations/003_card_brands.sql +0 -12
  65. package/src/migrations/004_order_to_cash.sql +0 -178
  66. package/src/migrations/005_seed_defaults.sql +0 -38
  67. package/src/migrations/006_rls_policies.sql +0 -37
  68. package/src/migrations/006b_extract_fee_amount.sql +0 -20
  69. package/src/migrations/007_reconciliation.sql +0 -32
  70. package/src/migrations/007b_movement_payment_method_type.sql +0 -6
  71. package/src/migrations/008_split_payment_movements.sql +0 -29
  72. package/src/migrations/009_agent_rpcs.sql +0 -165
  73. package/src/migrations/010_invoice_internal.sql +0 -133
  74. package/src/migrations/011_nfe.sql +0 -58
  75. package/src/migrations/index.ts +0 -923
  76. package/src/quick-add.ts +0 -58
  77. package/src/registries.ts +0 -308
  78. package/src/store.ts +0 -329
  79. package/src/types.ts +0 -592
  80. package/src/views/CardsView.tsx +0 -213
  81. package/src/views/CashRegistersView.tsx +0 -597
  82. package/src/views/CommissionsView.tsx +0 -18
  83. package/src/views/InvoiceDetailView.tsx +0 -616
  84. package/src/views/InvoiceFormView.tsx +0 -945
  85. package/src/views/InvoiceListView.tsx +0 -323
  86. package/src/views/NotasFiscaisView.tsx +0 -209
  87. package/src/views/PayablesView.tsx +0 -48
  88. package/src/views/QuickTransactionForm.tsx +0 -548
  89. package/src/views/ReceivablesView.tsx +0 -48
  90. package/src/views/ReconciliationView.tsx +0 -211
  91. package/src/views/StatementsView.tsx +0 -335
  92. package/src/views/SummaryView.tsx +0 -203
  93. package/src/views/dashboardWidgets.tsx +0 -437
  94. package/src/views/navReferrer.ts +0 -24
  95. /package/dist/{registries.d.ts → data/registries.d.ts} +0 -0
@@ -1,13 +0,0 @@
1
- // Central physical-table-name registry for plugin-financial. Providers import T so
2
- // the plg_financial_* strings live in one place.
3
- export const T = {
4
- movements: 'plg_financial_movements',
5
- chartOfAccounts: 'plg_financial_chart_of_accounts',
6
- bankAccounts: 'plg_financial_bank_accounts',
7
- cardBrands: 'plg_financial_card_brands',
8
- costCenters: 'plg_financial_cost_centers',
9
- cashRegisterSessions: 'plg_financial_cash_register_sessions',
10
- paymentMethods: 'plg_financial_payment_methods',
11
- paymentMethodTypes: 'plg_financial_payment_method_types',
12
- notas: 'plg_financial_nfe',
13
- } as const
package/src/data/types.ts DELETED
@@ -1,86 +0,0 @@
1
- import type {
2
- Invoice, InvoiceItem, FinancialMovement, BankAccount,
3
- CashSession, PaymentMethod, PaymentMethodType, ChartOfAccountsNode,
4
- CostCenter, CardTransaction,
5
- CreateInvoiceInput, PayMovementInput, CreateTransferInput, TransferResult,
6
- OpenCashSessionInput, CloseCashSessionInput, CreateBankAccountInput,
7
- InvoiceQuery, MovementQuery, StatementQuery,
8
- PaginatedResult, FinancialSummary, StatementResult, CashSessionSummary,
9
- DateRange,
10
- ImportBankTransactionsInput, ImportBankTransactionsResult,
11
- UnreconciledQuery, ReconciliationCandidate, ReconcileInput,
12
- NotaFiscal, CreateNotaFiscalInput, NotaFiscalQuery,
13
- } from '../types'
14
-
15
- export interface FinancialDataProvider {
16
- // --- Invoices ---
17
- getInvoices(query: InvoiceQuery): Promise<PaginatedResult<Invoice>>
18
- getInvoiceById(id: string): Promise<Invoice | null>
19
- getInvoiceItems(invoiceId: string): Promise<InvoiceItem[]>
20
- createInvoice(input: CreateInvoiceInput): Promise<Invoice>
21
- updateInvoice(id: string, data: Partial<Invoice>): Promise<Invoice>
22
- cancelInvoice(id: string): Promise<void>
23
-
24
- // --- Movements ---
25
- getMovements(query: MovementQuery): Promise<PaginatedResult<FinancialMovement>>
26
- payMovement(input: PayMovementInput): Promise<FinancialMovement>
27
- cancelMovement(id: string): Promise<void>
28
-
29
- // --- Transfers (between accounts) ---
30
- createTransfer(input: CreateTransferInput): Promise<TransferResult>
31
-
32
- // --- Bank Accounts ---
33
- getBankAccounts(): Promise<BankAccount[]>
34
- createBankAccount(data: CreateBankAccountInput): Promise<BankAccount>
35
- updateBankAccount(id: string, data: Partial<BankAccount>): Promise<BankAccount>
36
-
37
- // --- Cash Sessions ---
38
- getCashSessions(bankAccountId?: string): Promise<CashSession[]>
39
- getOpenSession(bankAccountId: string): Promise<CashSession | null>
40
- openCashSession(input: OpenCashSessionInput): Promise<CashSession>
41
- closeCashSession(input: CloseCashSessionInput): Promise<CashSession>
42
- getCashSessionSummary(sessionId: string): Promise<CashSessionSummary>
43
-
44
- // --- Payment Methods ---
45
- getPaymentMethods(): Promise<PaymentMethod[]>
46
- getPaymentMethodTypes(): Promise<PaymentMethodType[]>
47
-
48
- // --- Chart of Accounts ---
49
- getChartOfAccounts(): Promise<ChartOfAccountsNode[]>
50
- getCostCenters(): Promise<CostCenter[]>
51
-
52
- // --- Card Transactions ---
53
- getCardTransactions(dateRange?: DateRange): Promise<CardTransaction[]>
54
-
55
- // --- Statements ---
56
- getStatement(query: StatementQuery): Promise<StatementResult>
57
-
58
- // --- Summary / Dashboard ---
59
- getSummary(dateRange?: DateRange): Promise<FinancialSummary>
60
-
61
- // --- Reconciliation (conciliação) ---
62
- // Optional: implemented by providers that back the matching UI. A bank
63
- // connector imports lines; the SDK ReconciliationView reads/matches them.
64
- /** Upsert normalized bank-statement lines as movements (idempotent by external id). */
65
- importBankTransactions?(input: ImportBankTransactionsInput): Promise<ImportBankTransactionsResult>
66
- /** Imported lines not yet reconciled (externalSource set, reconciledAt null). */
67
- getUnreconciled?(query?: UnreconciledQuery): Promise<FinancialMovement[]>
68
- /** Internal-movement candidates to match a given imported line, ranked by score. */
69
- suggestReconciliation?(bankMovementId: string): Promise<ReconciliationCandidate[]>
70
- /** Reconcile: link to an internal movement, or accept the line standalone. */
71
- reconcileMovement?(input: ReconcileInput): Promise<void>
72
- /** Undo a reconciliation. */
73
- unreconcileMovement?(bankMovementId: string): Promise<void>
74
-
75
- // --- Notas fiscais (NF-e / NFC-e / NFS-e) ---
76
- // Optional: implemented by providers that back the Notas Fiscais tab. Emission
77
- // to SEFAZ is delegated — `issueNota` is the seam an external emissor plugs
78
- // into; until then it assigns a número/série locally and marks it issued.
79
- getNotas?(query: NotaFiscalQuery): Promise<PaginatedResult<NotaFiscal>>
80
- getNotaById?(id: string): Promise<NotaFiscal | null>
81
- createNota?(input: CreateNotaFiscalInput): Promise<NotaFiscal>
82
- updateNota?(id: string, data: Partial<NotaFiscal>): Promise<NotaFiscal>
83
- /** Request authorization. Decoupled from the fiscal gateway — see note above. */
84
- issueNota?(id: string): Promise<NotaFiscal>
85
- cancelNota?(id: string, reason?: string): Promise<NotaFiscal>
86
- }
package/src/index.ts DELETED
@@ -1,487 +0,0 @@
1
- import React from 'react'
2
- import type { PluginManifest, PluginRegistryDef, PluginScope, VerticalId } from '@fayz-ai/core'
3
- import type { EntityLookupMap } from '@fayz-ai/saas'
4
- import { FinancialPage } from './FinancialPage'
5
- import { createFinancialDashboardWidgets } from './views/dashboardWidgets'
6
- import type { ResolvedFinancialConfig } from './FinancialContext'
7
- import type { FinancialDataProvider } from './data/types'
8
- import { createMockFinancialProvider } from './data/mock'
9
- import { createSupabaseFinancialProvider } from './data/supabase'
10
- import { createSafeDataProvider, registerTranslations } from '@fayz-ai/core'
11
- import { createFinancialStore } from './store'
12
-
13
- /**
14
- * Public: a lazy supabase-or-mock financial provider. Apps use this to share one
15
- * provider between the plugin and a cross-plugin bridge (e.g. agenda's financial
16
- * bridge in beauty-saas). Thin wrapper over the shared createSafeDataProvider.
17
- */
18
- export function createSafeFinancialProvider(): FinancialDataProvider {
19
- return createSafeDataProvider(
20
- () => createSupabaseFinancialProvider(),
21
- () => createMockFinancialProvider(),
22
- )
23
- }
24
- import { financialRegistries } from './registries'
25
- import { financialLocales } from './locales'
26
- import { FinancialGeneralSettings } from './components/FinancialGeneralSettings'
27
- import { PersonStatementWidget } from './components/PersonStatementWidget'
28
- import { PluginSettingsPanel } from '@fayz-ai/saas'
29
-
30
- // ---------------------------------------------------------------------------
31
- // Public types
32
- // ---------------------------------------------------------------------------
33
-
34
- export interface FinancialPluginLabels {
35
- pageTitle: string
36
- pageSubtitle: string
37
- summary: string
38
- payables: string
39
- payablesNew: string
40
- payablesList: string
41
- payablesRecurring: string
42
- receivables: string
43
- receivablesNew: string
44
- receivablesList: string
45
- cashRegisters: string
46
- statements: string
47
- commissions: string
48
- commissionsOverview: string
49
- commissionsRules: string
50
- cards: string
51
- cardsOverview: string
52
- cardsReconciliation: string
53
- notasFiscais: string
54
- }
55
-
56
- export interface ItemTypeOption {
57
- value: string
58
- label: string
59
- icon?: string
60
- }
61
-
62
- export interface FinancialPluginOptions {
63
- modules?: {
64
- payables?: boolean
65
- receivables?: boolean
66
- cashRegisters?: boolean
67
- statements?: boolean
68
- commissions?: boolean
69
- cards?: boolean
70
- /** Bank reconciliation (conciliação). Defaults off — enable with a bank connector. */
71
- reconciliation?: boolean
72
- /** Notas fiscais (NF-e/NFC-e/NFS-e). Defaults off — opt-in per app. */
73
- notasFiscais?: boolean
74
- }
75
- labels?: Partial<FinancialPluginLabels>
76
- currency?: {
77
- code?: string
78
- locale?: string
79
- symbol?: string
80
- }
81
- /**
82
- * Show the plugin's own quick-add affordances (the "New transaction" + "Send
83
- * receipt" header buttons and, on mobile, the FAB). Opt-in (default: false) so
84
- * hosts that already surface a "New" menu / global center-action don't render
85
- * redundant controls. The shared quick-add sheet still opens via openQuickAdd().
86
- */
87
- quickAdd?: boolean
88
- navPosition?: number
89
- navSection?: 'main' | 'secondary'
90
- scope?: PluginScope
91
- verticalId?: VerticalId
92
-
93
- /** Data provider. Defaults to mock (in-memory) if not supplied. */
94
- dataProvider?: FinancialDataProvider
95
-
96
- /** Available item types for invoice lines. Default: product + service + other */
97
- itemTypes?: ItemTypeOption[]
98
-
99
- /** Enable service execution tracking on invoice items (default: false) */
100
- enableServiceExecution?: boolean
101
-
102
- /** Contact entity config — which person kind to use */
103
- contactEntity?: { archetypeKind: string; label?: string }
104
-
105
- /** Seed payment method types for mock provider */
106
- paymentMethodTypes?: Array<{ name: string; transactionType?: string }>
107
-
108
- /** Business units / locations. Unit selector only shows when 2+ locations are provided. */
109
- locations?: Array<{ id: string; name: string; isHQ?: boolean }>
110
-
111
- /**
112
- * Entity lookups for cross-plugin references.
113
- * Keys match `itemTypes` values (e.g., 'product', 'service').
114
- * When a lookup is provided, item forms show a search selector for that type.
115
- * When absent, users type descriptions manually.
116
- */
117
- entityLookups?: EntityLookupMap
118
-
119
- /** Contact/person lookup for "Pay to" / "Receive from" fields. Queries persons archetype. */
120
- contactLookup?: import('@fayz-ai/saas').EntityLookup
121
-
122
- /** App-owned registries shown under /settings/financial Properties. */
123
- settingsRegistries?: PluginRegistryDef[]
124
-
125
- /** Callback when user clicks a booking link on an invoice. Receives the order ID. */
126
- onBookingClick?: (orderId: string) => void
127
-
128
- /**
129
- * Which internal-nav links this APP gates, as `nav item id → feature id`.
130
- * Empty by default: the plugin ships no opinion about what is paid — packaging
131
- * is the app's decision, declared alongside its `permissions.ts` (RBAC) and
132
- * `billing.ts` (plan entitlements). An id absent from this map is never hidden
133
- * and never gated, in the nav OR in the content.
134
- *
135
- * {@link FINANCIAL_NAV_FEATURES} is an opt-in preset of the `fin_*` ids used
136
- * by the reference apps — spread the entries you actually want:
137
- *
138
- * ```ts
139
- * navFeatureMap: { reconciliation: FINANCIAL_NAV_FEATURES.reconciliation }
140
- * ```
141
- */
142
- navFeatureMap?: Record<string, string>
143
- }
144
-
145
- // ---------------------------------------------------------------------------
146
- // Defaults
147
- // ---------------------------------------------------------------------------
148
-
149
- const DEFAULT_LABELS: FinancialPluginLabels = {
150
- pageTitle: 'Financial',
151
- pageSubtitle: 'Financial overview and cash flow management',
152
- summary: 'Summary',
153
- payables: 'Accounts Payable',
154
- payablesNew: 'New',
155
- payablesList: 'List',
156
- payablesRecurring: 'Recurring Expenses',
157
- receivables: 'Accounts Receivable',
158
- receivablesNew: 'New',
159
- receivablesList: 'List',
160
- cashRegisters: 'Cash Registers',
161
- statements: 'Statements',
162
- commissions: 'Commissions',
163
- commissionsOverview: 'Overview',
164
- commissionsRules: 'Rules',
165
- cards: 'Cards',
166
- cardsOverview: 'Overview',
167
- cardsReconciliation: 'Reconciliation',
168
- notasFiscais: 'Fiscal Invoices',
169
- }
170
-
171
- const DEFAULT_CURRENCY = { code: 'BRL', locale: 'pt-BR', symbol: 'R$' }
172
-
173
- /**
174
- * OPT-IN preset of feature ids for the financial sub-modules — a naming
175
- * convention offered to apps, NOT a default. Nothing here is applied unless an
176
- * app passes the entries it wants through `options.navFeatureMap`, because what
177
- * is paid is a product decision that belongs to the app (its `permissions.ts` +
178
- * `billing.ts`), never to the plugin.
179
- */
180
- export const FINANCIAL_NAV_FEATURES = {
181
- reconciliation: 'fin_reconciliation',
182
- cards: 'fin_cards',
183
- commissions: 'fin_commissions',
184
- statements: 'fin_statements',
185
- receivables: 'fin_receivables',
186
- payables: 'fin_payables',
187
- 'cash-registers': 'fin_cash_registers',
188
- } as const satisfies Record<string, string>
189
-
190
- const DEFAULT_ITEM_TYPES: ItemTypeOption[] = [
191
- { value: 'service', label: 'Service', icon: 'Briefcase' },
192
- { value: 'product', label: 'Product', icon: 'Package' },
193
- { value: 'other', label: 'Other', icon: 'MoreHorizontal' },
194
- ]
195
-
196
- // ---------------------------------------------------------------------------
197
- // Config resolver
198
- // ---------------------------------------------------------------------------
199
-
200
- function resolveConfig(options?: FinancialPluginOptions): ResolvedFinancialConfig {
201
- return {
202
- modules: {
203
- payables: options?.modules?.payables !== false,
204
- receivables: options?.modules?.receivables !== false,
205
- cashRegisters: options?.modules?.cashRegisters !== false,
206
- statements: options?.modules?.statements !== false,
207
- commissions: options?.modules?.commissions !== false,
208
- cards: options?.modules?.cards !== false,
209
- // Opt-in: only shown when an app explicitly enables reconciliation (bank connector present).
210
- reconciliation: options?.modules?.reconciliation === true,
211
- // Opt-in: only shown when an app explicitly enables fiscal-invoice tracking.
212
- notasFiscais: options?.modules?.notasFiscais === true,
213
- },
214
- // Opt-in: only render the plugin's own quick-add buttons/FAB when the host asks.
215
- quickAdd: options?.quickAdd === true,
216
- labels: { ...DEFAULT_LABELS, ...options?.labels },
217
- currency: { ...DEFAULT_CURRENCY, ...options?.currency },
218
- itemTypes: options?.itemTypes ?? DEFAULT_ITEM_TYPES,
219
- enableServiceExecution: options?.enableServiceExecution ?? false,
220
- contactEntity: {
221
- archetypeKind: options?.contactEntity?.archetypeKind ?? 'client',
222
- label: options?.contactEntity?.label ?? 'Contact',
223
- },
224
- locations: options?.locations ?? [],
225
- entityLookups: options?.entityLookups ?? {},
226
- contactLookup: options?.contactLookup,
227
- onBookingClick: options?.onBookingClick,
228
- navFeatureMap: { ...options?.navFeatureMap },
229
- }
230
- }
231
-
232
- // ---------------------------------------------------------------------------
233
- // Factory
234
- // ---------------------------------------------------------------------------
235
-
236
- export function createFinancialPlugin(options?: FinancialPluginOptions): PluginManifest {
237
- const config = resolveConfig(options)
238
- registerTranslations(financialLocales)
239
-
240
- const provider = options?.dataProvider ?? createSafeFinancialProvider()
241
- const store = createFinancialStore(provider)
242
- const dashboardWidgets = createFinancialDashboardWidgets({ config, provider, store })
243
- const registries = [...financialRegistries, ...(options?.settingsRegistries ?? [])]
244
-
245
- // Per-person statement tab (account_central-style): bound to this plugin's provider.
246
- const PersonStatementBound: React.FC<any> = (props) =>
247
- React.createElement(PersonStatementWidget, { person: props.item, provider, config })
248
- PersonStatementBound.displayName = 'FinancialPersonStatement'
249
-
250
- const PageComponent: React.FC<any> = () =>
251
- React.createElement(FinancialPage, { config, provider, store, registries })
252
-
253
- return {
254
- id: 'financial',
255
- name: config.labels.pageTitle,
256
- icon: 'DollarSign',
257
- version: '1.0.0',
258
- scope: options?.scope ?? 'universal',
259
- verticalId: options?.verticalId,
260
- defaultEnabled: true,
261
- dependencies: [],
262
- declaredFeatures: [
263
- { id: 'financial', label: config.labels.pageTitle, group: config.labels.pageTitle },
264
- ...(config.modules.receivables ? [{ id: 'financial.receivables', label: config.labels.receivables, group: config.labels.pageTitle }] : []),
265
- ...(config.modules.payables ? [{ id: 'financial.payables', label: config.labels.payables, group: config.labels.pageTitle }] : []),
266
- ...(config.modules.commissions ? [{ id: 'financial.commissions', label: config.labels.commissions, group: config.labels.pageTitle }] : []),
267
- ],
268
- // Recurring monthly quota — counts financial movement rows created this
269
- // month (invoices write one per installment; quick transactions one, or two
270
- // for a transfer).
271
- declaredLimits: [
272
- { key: 'movements_month', label: 'Financial movements this month', table: 'plg_financial_movements', period: 'month' },
273
- ],
274
- queryEntities: [
275
- {
276
- key: 'financial:invoices',
277
- entity: {
278
- name: 'Invoice',
279
- namePlural: 'Invoices (receipts REC- / payables PAG-)',
280
- icon: 'Receipt',
281
- permission: { feature: 'financial', action: 'read' },
282
- fields: [
283
- { key: 'referenceNumber', label: 'Reference (REC-/PAG-)', type: 'text', searchable: true },
284
- { key: 'flow', label: 'Flow (receivable/payable)', type: 'text' },
285
- { key: 'amount', label: 'Amount', type: 'number' },
286
- { key: 'paid', label: 'Paid', type: 'number' },
287
- { key: 'balance', label: 'Balance', type: 'number' },
288
- { key: 'status', label: 'Status', type: 'text' },
289
- { key: 'createdAt', label: 'Created at', type: 'text' },
290
- ],
291
- data: {
292
- table: 'v_invoice_balances',
293
- tenantScoped: true,
294
- searchColumns: ['reference_number'],
295
- },
296
- },
297
- },
298
- {
299
- key: 'financial:movements',
300
- entity: {
301
- name: 'Financial movement',
302
- namePlural: 'Financial movements (installment ledger)',
303
- icon: 'Banknote',
304
- permission: { feature: 'financial', action: 'read' },
305
- fields: [
306
- { key: 'direction', label: 'Direction', type: 'text' },
307
- { key: 'movementKind', label: 'Kind (bill/payment)', type: 'text' },
308
- { key: 'amount', label: 'Amount', type: 'number' },
309
- { key: 'paidAmount', label: 'Paid amount', type: 'number' },
310
- { key: 'status', label: 'Status', type: 'text' },
311
- { key: 'dueDate', label: 'Due date', type: 'text' },
312
- { key: 'paymentDate', label: 'Payment date', type: 'text' },
313
- { key: 'installmentNumber', label: 'Installment', type: 'number' },
314
- { key: 'cardInstallments', label: 'Card installments', type: 'number' },
315
- { key: 'createdAt', label: 'Created at', type: 'text' },
316
- ],
317
- data: {
318
- table: 'plg_financial_movements',
319
- tenantScoped: true,
320
- },
321
- },
322
- },
323
- ],
324
- declaredRpcs: [
325
- {
326
- name: 'agent_financial_mark_payment_received',
327
- kind: 'write' as const,
328
- description:
329
- 'Guarded settle: invoices the order via fn_invoice_from_order (installments for credit card) and marks the receivable paid, audited with the acting user.',
330
- audits: true,
331
- },
332
- ],
333
- navigation: [
334
- {
335
- section: options?.navSection ?? 'main',
336
- position: options?.navPosition ?? 6,
337
- label: config.labels.pageTitle,
338
- route: '/financial',
339
- icon: 'DollarSign',
340
- permission: { feature: 'financial', action: 'read' as const },
341
- },
342
- ],
343
- routes: [
344
- {
345
- path: '/financial',
346
- component: PageComponent,
347
- permission: { feature: 'financial', action: 'read' as const },
348
- },
349
- ],
350
- widgets: [
351
- {
352
- id: 'financial-person-statement',
353
- zone: 'person.detail.financial',
354
- component: PersonStatementBound as unknown as React.ComponentType<unknown>,
355
- order: 0,
356
- permission: { feature: 'financial', action: 'read' as const },
357
- },
358
- ],
359
- dashboardWidgets,
360
- aiTools: [
361
- {
362
- id: 'financial.get-revenue',
363
- name: 'getRevenue',
364
- description: 'Returns revenue for the business in a given period.',
365
- icon: 'DollarSign',
366
- mode: 'read' as const,
367
- category: 'Finance',
368
- parameters: {
369
- type: 'object' as const,
370
- properties: {
371
- period: { type: 'string' as const, description: 'today, week, month, or custom date range' },
372
- },
373
- },
374
- suggestions: [
375
- { label: 'How much did we make today?' },
376
- { label: "What's this month's revenue?" },
377
- { label: "Compare this week's revenue to last week" },
378
- ],
379
- },
380
- {
381
- id: 'financial.create-invoice',
382
- name: 'createInvoice',
383
- description: 'Creates a new invoice/payable for a contact.',
384
- icon: 'FileText',
385
- mode: 'persist' as const,
386
- limitKey: 'movements_month',
387
- category: 'Finance',
388
- parameters: {
389
- type: 'object' as const,
390
- properties: {
391
- contact: { type: 'string' as const, description: 'Contact/customer name' },
392
- amount: { type: 'number' as const, description: 'Invoice amount' },
393
- description: { type: 'string' as const, description: 'Invoice description' },
394
- },
395
- required: ['contact', 'amount'],
396
- },
397
- suggestions: [
398
- { label: 'Create an invoice for a new client' },
399
- ],
400
- permission: { feature: 'financial', action: 'create' as const },
401
- },
402
- {
403
- id: 'financial.mark-payment-received',
404
- name: 'markPaymentReceived',
405
- description:
406
- 'Marks an order/appointment as paid: invoices it (with installments for credit card, e.g. "cartão 2x") and settles the receivable. Resolve the booking or order id via search tools first.',
407
- icon: 'BadgeDollarSign',
408
- mode: 'persist' as const,
409
- execution: { plane: 'server' as const, kind: 'rpc' as const, rpc: 'agent_financial_mark_payment_received' },
410
- category: 'Finance',
411
- parameters: {
412
- type: 'object' as const,
413
- properties: {
414
- booking_id: { type: 'string' as const, description: 'Appointment id (alternative to order_id)' },
415
- order_id: { type: 'string' as const, description: 'Order id' },
416
- method: {
417
- type: 'string' as const,
418
- description: 'Payment method',
419
- enum: ['cash', 'pix', 'credit_card', 'debit_card', 'transfer'],
420
- },
421
- installments: { type: 'number' as const, description: 'Credit-card installments (1-12), e.g. 2 for "cartão 2x"' },
422
- },
423
- required: ['method'],
424
- },
425
- suggestions: [
426
- { label: 'Marcar o atendimento como pago no cartão em 2x' },
427
- ],
428
- permission: { feature: 'financial.receivables', action: 'update' as const },
429
- },
430
- {
431
- id: 'financial.list-payables',
432
- name: 'listPayables',
433
- description: 'Lists outstanding payables/bills.',
434
- icon: 'FileDown',
435
- mode: 'read' as const,
436
- category: 'Finance',
437
- parameters: {
438
- type: 'object' as const,
439
- properties: {
440
- status: { type: 'string' as const, enum: ['pending', 'overdue', 'paid'] },
441
- contact: { type: 'string' as const, description: 'Filter by contact name' },
442
- },
443
- },
444
- permission: { feature: 'financial', action: 'read' as const },
445
- suggestions: [
446
- { label: 'Show me overdue bills' },
447
- { label: 'What bills are due this week?' },
448
- ],
449
- },
450
- ],
451
- registries,
452
- settings: [
453
- {
454
- id: 'financial',
455
- label: 'Financial',
456
- icon: 'DollarSign',
457
- component: (() => {
458
- const FinancialSettingsTab: React.FC = () =>
459
- React.createElement(PluginSettingsPanel, {
460
- title: 'Financial Settings',
461
- subtitle: 'Payment methods, accounts, and configurations',
462
- generalSettings: React.createElement(FinancialGeneralSettings),
463
- registries,
464
- hostPluginId: 'financial',
465
- routeBase: '/settings/financial',
466
- })
467
- FinancialSettingsTab.displayName = 'FinancialSettingsTab'
468
- return FinancialSettingsTab as unknown as React.ComponentType<unknown>
469
- })(),
470
- order: 10,
471
- permission: { feature: 'financial', action: 'read' as const },
472
- },
473
- ],
474
- locales: financialLocales,
475
- }
476
- }
477
-
478
- // Re-export types and factories for consumers
479
- export type { FinancialDataProvider } from './data/types'
480
- export type { ResolvedFinancialConfig } from './FinancialContext'
481
- // Seedable in-memory provider — apps pass a seed to render the module populated
482
- // (demo/dogfood data) instead of the empty onboarding state.
483
- export { createMockFinancialProvider } from './data/mock'
484
- export type { MockFinancialSeed, MockFinancialProviderOptions } from './data/mock'
485
- // FAY-1242: global quick-add trigger — apps wire this to a shell action (e.g.
486
- // the bottom-nav center "+") to open the transaction sheet from anywhere.
487
- export { openQuickAdd } from './quick-add'
package/src/lib/tenant.ts DELETED
@@ -1,3 +0,0 @@
1
- let t: string | undefined
2
- export function setFinancialTenantId(id: string | undefined){ t = id }
3
- export function getFinancialTenantId(): string | undefined { return t }