const { ChartOfAccountsRepository } = require('../repositories'); const logger = require('../../../src/utils/logger'); // Define the 7 default accounts to seed for every new HOA site const DEFAULT_ACCOUNTS = [ { code: '1000', name: 'Checking Account', type: 'asset', description: 'Holds all cash; receives monthly fees, pays all bills.' }, { code: '1100', name: 'Accounts Receivable – Owners', type: 'asset', description: 'Tracks unpaid monthly service fees (who owes what).' }, { code: '2000', name: 'Accounts Payable – Vendors', type: 'liability', description: 'Tracks unpaid bills (what the HOA owes).' }, { code: '2100', name: 'Prepaid Assessments', type: 'liability', description: 'Records fees paid in advance (liability until earned).' }, { code: '3100', name: 'HOA Fund Balance', type: 'equity', description: 'Starting/ending equity; required for balance sheet.' }, { code: '4100', name: 'Monthly Service Fees', type: 'income', description: 'All regular income comes here.' }, { code: '5100', name: 'Operating Expenses', type: 'expense', description: 'All spending (utilities, repairs, insurance, etc.).' } ]; /** * Seed default financial accounts for a given site * This function is idempotent per account code per site: it skips any that already exist. * @param {string} siteId * @param {string|null} createdByUserId */ async function seedDefaultAccounts(siteId, createdByUserId = null) { const chartOfAccountsRepository = new ChartOfAccountsRepository(); const createdAccountIds = []; try { for (const acc of DEFAULT_ACCOUNTS) { // Skip if exists const exists = await chartOfAccountsRepository.findByCode(siteId, acc.code); if (exists) { continue; } const newAccount = await chartOfAccountsRepository.createAccount({ site_id: siteId, account_code: acc.code, account_name: acc.name, account_type: acc.type, description: acc.description, is_active: true, // created_by is optional in repository ...(createdByUserId ? { created_by: createdByUserId } : {}) }); if (newAccount && newAccount.id) { createdAccountIds.push(newAccount.id); } } logger.info(`Seeded default financial accounts for site ${siteId}: ${createdAccountIds.length} created`); return { success: true, created: createdAccountIds.length }; } catch (error) { // Best-effort rollback of any accounts created in this run try { for (const id of createdAccountIds) { await chartOfAccountsRepository.deleteById(id); } logger.warn(`Rolled back ${createdAccountIds.length} seeded accounts for site ${siteId} due to error.`); } catch (rollbackError) { logger.error('Failed to rollback seeded accounts:', rollbackError); } logger.error('Failed to seed default accounts:', error); throw error; } } module.exports = { seedDefaultAccounts, DEFAULT_ACCOUNTS };