Documentation Index
Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
Use this file to discover all available pages before exploring further.
Version: 1.0.0
Last Updated: 2025-11-26
Related Documentation: FA-01 through FA-09 specifications
Overview
This document provides a comprehensive reference for all frontend hooks, components, and utilities in the Finance & Accounting (FA) module. All FA APIs follow Constitutional guidelines for import paths, RLS enforcement, and integration patterns.
Table of Contents
- Hooks
- Components
- Utilities
- Types
- Edge Functions
Hooks
Chart of Accounts & Funds (FA-01)
useAccounts
Fetch chart of accounts with filtering and search.
import { useAccounts } from '@/cores/fa/hooks/useAccounts';
const { accounts, isLoading, error } = useAccounts({
organizationId?: string;
fundId?: string;
accountType?: 'asset' | 'liability' | 'equity' | 'revenue' | 'expense';
isActive?: boolean;
searchTerm?: string;
});
Returns:
accounts: FAAccount[] - Array of account records
isLoading: boolean - Loading state
error: Error | null - Error object if query failed
RLS: Requires has_org_access(auth.uid(), organization_id)
useAccountDetail
Fetch single account with balances (when FA-02 implemented).
import { useAccountDetail } from '@/cores/fa/hooks/useAccountDetail';
const { account, balances, isLoading } = useAccountDetail(accountId);
Returns:
account: FAAccount - Account record
balances: { debit: number; credit: number; balance: number } - Account balances
isLoading: boolean
useFunds
Fetch list of funds.
import { useFunds } from '@/cores/fa/hooks/useFunds';
const { funds, isLoading } = useFunds({
organizationId?: string;
fundType?: 'unrestricted' | 'restricted' | 'temporarily_restricted' | 'permanently_restricted';
isActive?: boolean;
});
Returns:
funds: FAFund[] - Array of fund records
isLoading: boolean
useDepartments
Fetch department hierarchy.
import { useDepartments } from '@/cores/fa/hooks/useDepartments';
const { departments, isLoading } = useDepartments({
organizationId?: string;
siteId?: string;
isClinical?: boolean;
isActive?: boolean;
});
Returns:
departments: FADepartment[] - Array of department records with parent-child relationships
isLoading: boolean
usePrograms
Fetch program list.
import { usePrograms } from '@/cores/fa/hooks/usePrograms';
const { programs, isLoading } = usePrograms({
organizationId?: string;
isActive?: boolean;
});
Returns:
programs: FAProgram[] - Array of program records
isLoading: boolean
useFiscalPeriods
Fetch fiscal periods for a year.
import { useFiscalPeriods } from '@/cores/fa/hooks/useFiscalPeriods';
const { periods, currentPeriod, isLoading } = useFiscalPeriods({
organizationId?: string;
fiscalYear?: number;
status?: 'open' | 'closed';
});
Returns:
periods: FAFiscalPeriod[] - Array of fiscal periods
currentPeriod: FAFiscalPeriod | null - Current open period
isLoading: boolean
useAccountMutation
Create, update, delete accounts.
import { useAccountMutation } from '@/cores/fa/hooks/useAccountMutation';
const { createAccount, updateAccount, deleteAccount } = useAccountMutation();
await createAccount.mutateAsync({
organization_id: orgId,
account_number: '1000',
account_name: 'Cash - Operating',
account_type: 'asset',
...
});
RLS: Requires fa_is_finance_admin(auth.uid(), organization_id)
General Ledger (FA-02)
useJournalEntries
Fetch journal entries with filtering.
import { useJournalEntries } from '@/cores/fa/hooks/useJournalEntries';
const { entries, isLoading } = useJournalEntries({
organizationId?: string;
fiscalPeriodId?: string;
status?: 'draft' | 'posted' | 'voided';
startDate?: Date;
endDate?: Date;
});
useTrialBalance
Fetch trial balance for a period.
import { useTrialBalance } from '@/cores/fa/hooks/useTrialBalance';
const { trialBalance, totals, isLoading } = useTrialBalance({
organizationId: string;
fiscalPeriodId: string;
fundId?: string;
});
Returns:
trialBalance: TrialBalanceRow[] - Array of account balances
totals: { totalDebits: number; totalCredits: number } - Trial balance totals
isLoading: boolean
useJournalEntryMutation
Create, post, void journal entries.
import { useJournalEntryMutation } from '@/cores/fa/hooks/useJournalEntryMutation';
const { createEntry, postEntry, voidEntry } = useJournalEntryMutation();
await createEntry.mutateAsync({
organization_id: orgId,
fiscal_period_id: periodId,
entry_date: new Date(),
lines: [
{ account_id: debitAccountId, debit_amount: 1000, ... },
{ account_id: creditAccountId, credit_amount: 1000, ... }
]
});
Accounts Payable (FA-04)
useVendors
Fetch vendor list.
import { useVendors } from '@/cores/fa/hooks/useVendors';
const { vendors, isLoading } = useVendors({
organizationId?: string;
isActive?: boolean;
searchTerm?: string;
});
useVendorBills
Fetch vendor bills.
import { useVendorBills } from '@/cores/fa/hooks/useVendorBills';
const { bills, isLoading } = useVendorBills({
organizationId?: string;
vendorId?: string;
status?: 'draft' | 'pending_approval' | 'approved' | 'paid' | 'voided';
dueDate?: Date;
});
usePayments
Fetch payments.
import { usePayments } from '@/cores/fa/hooks/usePayments';
const { payments, isLoading } = usePayments({
organizationId?: string;
vendorId?: string;
paymentMethod?: 'check' | 'ach' | 'wire' | 'credit_card' | 'cash';
startDate?: Date;
endDate?: Date;
});
useVendorBillMutation
Create, approve, pay vendor bills.
import { useVendorBillMutation } from '@/cores/fa/hooks/useVendorBillMutation';
const { createBill, approveBill, payBill } = useVendorBillMutation();
Accounts Receivable (FA-06)
useCustomers
Fetch customer list.
import { useCustomers } from '@/cores/fa/hooks/useCustomers';
const { customers, isLoading } = useCustomers({
organizationId?: string;
isActive?: boolean;
searchTerm?: string;
});
useInvoices
Fetch invoices.
import { useInvoices } from '@/cores/fa/hooks/useInvoices';
const { invoices, isLoading } = useInvoices({
organizationId?: string;
customerId?: string;
status?: 'draft' | 'sent' | 'partial' | 'paid' | 'voided' | 'overdue';
});
useCustomerPayments
Fetch customer payments.
import { useCustomerPayments } from '@/cores/fa/hooks/useCustomerPayments';
const { payments, isLoading } = useCustomerPayments({
organizationId?: string;
customerId?: string;
invoiceId?: string;
startDate?: Date;
endDate?: Date;
});
Financial Reporting (FA-07)
useReportDefinitions
Fetch saved report definitions.
import { useReportDefinitions } from '@/cores/fa/hooks/useReportDefinitions';
const { reports, isLoading } = useReportDefinitions({
organizationId?: string;
reportType?: 'trial_balance' | 'balance_sheet' | 'stmt_activities' | 'cash_flow' | 'grant_compliance';
});
useReportExecution
Execute financial report.
import { useReportExecution } from '@/cores/fa/hooks/useReportExecution';
const { execute, result, isExecuting } = useReportExecution();
const reportData = await execute({
reportType: 'balance_sheet',
organizationId: orgId,
fiscalPeriodId: periodId,
fundId?: fundId,
format: 'pdf'
});
useReportSchedules
Fetch scheduled reports.
import { useReportSchedules } from '@/cores/fa/hooks/useReportSchedules';
const { schedules, isLoading } = useReportSchedules({
organizationId?: string;
isActive?: boolean;
});
Budgeting (FA-08)
useBudgets
Fetch budgets.
import { useBudgets } from '@/cores/fa/hooks/useBudgets';
const { budgets, isLoading } = useBudgets({
organizationId?: string;
fiscalYear?: number;
status?: 'draft' | 'submitted' | 'approved' | 'locked';
});
useBudgetVsActual
Fetch budget vs actual comparison.
import { useBudgetVsActual } from '@/cores/fa/hooks/useBudgetVsActual';
const { data, isLoading } = useBudgetVsActual({
budgetId: string;
fiscalPeriodId?: string;
accountId?: string;
departmentId?: string;
});
Returns:
data: BudgetVsActualRow[] - Array of budget vs actual comparisons
isLoading: boolean
useBudgetAlerts
Fetch budget alerts for exceeded thresholds.
import { useBudgetAlerts } from '@/cores/fa/hooks/useBudgetAlerts';
const { alerts, isLoading } = useBudgetAlerts({
organizationId?: string;
budgetId?: string;
severity?: 'warning' | 'critical';
isAcknowledged?: boolean;
});
Multi-Entity Consolidation (FA-09)
useEntities
Fetch legal entities.
import { useEntities } from '@/cores/fa/hooks/useEntities';
const { entities, isLoading } = useEntities({
organizationId?: string;
isActive?: boolean;
});
useEntityHierarchy
Fetch entity hierarchy with ownership percentages.
import { useEntityHierarchy } from '@/cores/fa/hooks/useEntityHierarchy';
const { hierarchy, isLoading } = useEntityHierarchy({
organizationId: string;
});
Returns:
hierarchy: EntityNode[] - Tree structure of entities with children
isLoading: boolean
useIntercompanyBalances
Fetch inter-company balances for reconciliation.
import { useIntercompanyBalances } from '@/cores/fa/hooks/useIntercompanyBalances';
const { balances, isBalanced, isLoading } = useIntercompanyBalances({
organizationId: string;
fiscalPeriodId: string;
});
Returns:
balances: IntercompanyBalance[] - Array of inter-company transactions
isBalanced: boolean - True if all inter-company accounts net to zero
isLoading: boolean
useRunConsolidation
Execute consolidation process.
import { useRunConsolidation } from '@/cores/fa/hooks/useRunConsolidation';
const { execute, isExecuting, result } = useRunConsolidation();
await execute({
organizationId: string;
fiscalPeriodId: string;
});
Module Settings (FA-10)
useFAModuleSettings
Fetch and update FA module settings.
import { useFAModuleSettings } from '@/cores/fa/hooks/useFAModuleSettings';
const { settings, update, isLoading, isUpdating } = useFAModuleSettings();
await update({
default_cash_account_id: accountId,
fiscal_year_start_month: 7,
budget_warning_threshold: 85.00,
...
});
RLS: View requires org access, update requires org_admin
Components
Account Selector
Select from chart of accounts with filtering.
import { AccountSelector } from '@/cores/fa/components/AccountSelector';
<AccountSelector
value={accountId}
onChange={(accountId) => setValue('account_id', accountId)}
accountTypes={['asset', 'liability']} // Optional filter
fundId={fundId} // Optional fund filter
placeholder="Select account"
/>
Fund Selector
Select from available funds.
import { FundSelector } from '@/cores/fa/components/FundSelector';
<FundSelector
value={fundId}
onChange={(fundId) => setValue('fund_id', fundId)}
fundTypes={['unrestricted', 'restricted']}
placeholder="Select fund"
/>
Department Selector
Select from department hierarchy.
import { DepartmentSelector } from '@/cores/fa/components/DepartmentSelector';
<DepartmentSelector
value={departmentId}
onChange={(deptId) => setValue('department_id', deptId)}
siteId={siteId} // Optional site filter
isClinical={true} // Optional clinical filter
/>
Journal Entry Form
Create and edit journal entries.
import { JournalEntryForm } from '@/cores/fa/components/JournalEntryForm';
<JournalEntryForm
entryId={entryId} // Optional, for editing
onSuccess={(entryId) => navigate(`/fa/journal-entries/${entryId}`)}
onCancel={() => navigate('/fa/journal-entries')}
/>
Trial Balance Report
Display trial balance with drill-down.
import { TrialBalanceReport } from '@/cores/fa/components/TrialBalanceReport';
<TrialBalanceReport
organizationId={orgId}
fiscalPeriodId={periodId}
fundId={fundId} // Optional
onAccountClick={(accountId) => navigate(`/fa/accounts/${accountId}`)}
/>
Utilities
import { formatAccountNumber } from '@/cores/fa/lib/accountUtils';
const formatted = formatAccountNumber('1000'); // "1000" or "1-000" depending on org config
Balance Calculation
import { calculateBalance } from '@/cores/fa/lib/balanceUtils';
const balance = calculateBalance({
accountType: 'asset',
debits: 5000,
credits: 2000
}); // Returns 3000 for asset (debit balance)
Fiscal Period Helpers
import {
isCurrentPeriod,
isPeriodClosed,
canPostToPeriod
} from '@/cores/fa/lib/periodUtils';
if (!canPostToPeriod(period, moduleSettings)) {
throw new Error('Cannot post to this period');
}
Types
Core Types
// Account
interface FAAccount {
id: string;
organization_id: string;
fund_id?: string;
account_number: string;
account_name: string;
account_type: 'asset' | 'liability' | 'equity' | 'revenue' | 'expense';
account_subtype: string;
is_active: boolean;
parent_account_id?: string;
requires_department: boolean;
requires_program: boolean;
created_at: string;
updated_at: string;
}
// Fund
interface FAFund {
id: string;
organization_id: string;
fund_code: string;
fund_name: string;
fund_type: 'unrestricted' | 'restricted' | 'temporarily_restricted' | 'permanently_restricted';
is_active: boolean;
created_at: string;
}
// Journal Entry
interface FAJournalEntry {
id: string;
organization_id: string;
fiscal_period_id: string;
entry_date: string;
status: 'draft' | 'posted' | 'voided';
reference_number?: string;
description?: string;
posted_at?: string;
posted_by?: string;
created_at: string;
}
// Journal Entry Line
interface FAJournalEntryLine {
id: string;
entry_id: string;
line_number: number;
account_id: string;
fund_id?: string;
department_id?: string;
program_id?: string;
debit_amount?: number;
credit_amount?: number;
description?: string;
}
Edge Functions
execute-report
Execute financial report and return data.
Endpoint: supabase/functions/execute-report/index.ts
Request:
{
"report_type": "balance_sheet",
"organization_id": "uuid",
"fiscal_period_id": "uuid",
"fund_id": "uuid",
"format": "json" | "pdf" | "excel"
}
Response:
{
"success": true,
"report_data": { ... },
"execution_time_ms": 245
}
consolidate-entities
Run multi-entity consolidation.
Endpoint: supabase/functions/consolidate-entities/index.ts
Request:
{
"organization_id": "uuid",
"fiscal_period_id": "uuid"
}
Response:
{
"success": true,
"consolidation_run_id": "uuid",
"elimination_count": 42,
"execution_time_ms": 1250
}
check-budget-alerts
Scheduled function to check budget thresholds.
Endpoint: supabase/functions/check-budget-alerts/index.ts
Trigger: Cron (daily at 8 AM)
Behavior:
- Queries
fa_budget_vs_actual_view
- Compares variance to module settings thresholds
- Creates
fa_budget_alerts records
- Publishes
budget_exceeded events
- Sends notifications via PF-10
Error Handling
All FA hooks use consistent error handling:
const { data, error, isLoading } = useAccounts();
if (error) {
// Error is typed as Error
console.error(error.message);
}
Mutations use toast notifications for success/error:
const { createAccount } = useAccountMutation();
// Success: Shows "Account created successfully"
// Error: Shows error.message in destructive toast
await createAccount.mutateAsync({ ... });
RLS Reference
All FA tables enforce RLS with these common patterns:
View Access:
CREATE POLICY "fa_table_view"
ON fa_table FOR SELECT
USING (has_org_access(auth.uid(), organization_id));
Admin Modify:
CREATE POLICY "fa_table_admin_modify"
ON fa_table FOR ALL
USING (fa_is_finance_admin(auth.uid(), organization_id));
Helper Functions:
has_org_access(user_id, org_id) - User belongs to organization
fa_is_finance_admin(user_id, org_id) - User has org_admin or platform_admin role
Import Paths
CORRECT:
// ✅ Import from core
import { useAccounts } from '@/cores/fa/hooks/useAccounts';
import { AccountSelector } from '@/cores/fa/components/AccountSelector';
WRONG:
// ❌ Do not use relative imports across cores
import { useAccounts } from '../../fa/hooks/useAccounts';
// ❌ Do not import FA directly from other cores
// Use Platform Integration Layer or Events instead
Version History
- v1.0.0 (2025-11-26): Initial API reference for FA-01 through FA-10