From ec09e319edd82bc9b97ad2ab580ff954140108d9 Mon Sep 17 00:00:00 2001 From: Ryan Moon Date: Mon, 30 Mar 2026 19:41:23 -0500 Subject: [PATCH] =?UTF-8?q?Update=20accounting=20planning=20doc=20v2=20?= =?UTF-8?q?=E2=80=94=20fix=20AP/safe=20accounts,=20add=20periods,=20tax=20?= =?UTF-8?q?rates,=20gift=20cards,=20consignment,=20posting=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../12_Domain_Accounting_Journal_Entries.md | 1434 ++++++----------- 1 file changed, 473 insertions(+), 961 deletions(-) diff --git a/planning/12_Domain_Accounting_Journal_Entries.md b/planning/12_Domain_Accounting_Journal_Entries.md index 37d0652..0161720 100644 --- a/planning/12_Domain_Accounting_Journal_Entries.md +++ b/planning/12_Domain_Accounting_Journal_Entries.md @@ -1,318 +1,147 @@ -Music Store Management Platform +LunarFront Platform Domain Design: Accounting & Journal Entries -Version 1.0 | Draft +Version 2.0 | Updated 2026-03-30 # 1. Overview -The Accounting domain ensures every financial event in the platform produces correct double-entry journal entries. The platform does not replace QuickBooks — it generates journal entries that the store's accountant imports into QuickBooks on a regular schedule (daily, weekly, or monthly). - - +The Accounting domain ensures every financial event in the platform produces correct double-entry journal entries following Generally Accepted Accounting Principles (GAAP). The platform does not replace QuickBooks — it generates journal entries that the business's accountant imports into QuickBooks on a regular schedule (daily, weekly, or monthly). This is the Hybrid approach: the platform owns all operational financial data and generates the accounting records. QuickBooks owns the general ledger, financial statements, and tax reporting. The accountant works in a familiar tool. No real-time API dependency on QuickBooks is required. +## 1.1 Accounting Standards +The system implements: -Responsibility +- **Double-entry bookkeeping** — every transaction produces balanced debit/credit entries. Total debits must always equal total credits. +- **GAAP revenue recognition** — revenue recorded when earned, not when cash received (accrual basis). Deferred revenue tracked as a liability until earned. +- **Matching principle** — COGS recorded at the same time as the related revenue. +- **Immutability** — journal entries are never modified or deleted. Corrections are made via reversing entries only. +- **Contra accounts** — discounts and returns tracked separately from gross revenue for full visibility. +- **Materiality** — the system tracks every transaction. Rounding differences handled via the Cash Over/Short account. -Owner +## 1.2 Accounting Basis -Operational records +The system generates entries on an **accrual basis** — revenue is recognized when earned, expenses when incurred, regardless of when cash changes hands. This is the GAAP standard. -Platform — transactions, rentals, lessons, repairs, discounts, drawer +For businesses that file taxes on a **cash basis** (most small businesses), the accountant handles the conversion in QuickBooks. The platform provides both cash-flow reports (cash basis visibility) and accrual-based journal entries. This is the standard approach for small businesses: operate on accrual internally, file on cash basis. -Journal entry generation +## 1.3 Scope -Platform — automatic on every financial event +| Responsibility | Owner | +|---------------|-------| +| Operational records | Platform — transactions, rentals, lessons, repairs, discounts, drawer | +| Journal entry generation | Platform — automatic on every financial event | +| Journal entry export | Platform — CSV export by date range, importable to QuickBooks | +| General ledger | QuickBooks — accountant imports exported entries | +| Financial statements | QuickBooks — P&L, balance sheet, tax reporting | +| Chart of accounts | Defined in platform, configurable per business to match QB setup | +| Payroll | External — ADP, Gusto, etc. Platform tracks hours/sessions for export only | -Journal entry export +## 1.4 Currency -Platform — CSV export by date range, importable to QuickBooks - -General ledger - -QuickBooks — accountant imports exported entries - -Financial statements - -QuickBooks — P&L, balance sheet, tax reporting - -Chart of accounts - -Defined in platform, configurable per store to match QB setup +The system operates in **USD only**. Single-currency assumption. Multi-currency support is out of scope — if needed in the future, it would require a separate currency layer with exchange rate tracking and foreign currency translation accounts. # 2. Chart of Accounts -The chart of accounts is defined in the platform and is store-configurable. Account codes and names should match the store's existing QuickBooks chart of accounts exactly to ensure clean imports. Default codes are provided below as a starting point. +The chart of accounts is defined in the platform and is business-configurable. Account codes and names should match the business's existing QuickBooks chart of accounts exactly to ensure clean imports. Default codes are provided below as a starting point. +Businesses can rename accounts, add custom accounts, and deactivate unused accounts. They cannot delete accounts that have journal entry references. ## 2.1 Assets -Code - -Account Name - -Notes - -1000 - -Cash - Store Drawer - -Physical cash in main register - -1010 - -Cash - Convention Drawer - -iOS mobile POS cash - -1100 - -Accounts Receivable - -Amounts owed by customers - -1200 - -Stripe Clearing - -Card payments received but not yet paid out by Stripe - -1300 - -Inventory - Sale Stock - -Instruments and accessories for sale - -1310 - -Inventory - Rental Fleet - -Instruments held for rental - -1320 - -Inventory - Parts & Supplies - -Repair parts and consumables - +| Code | Account Name | Notes | +|------|-------------|-------| +| 1000 | Cash - Register Drawer | Physical cash in main register | +| 1010 | Cash - Mobile POS | Mobile POS cash (trade shows, events) | +| 1020 | Cash - Safe | Cash moved from drawer to secure storage | +| 1100 | Accounts Receivable | Amounts owed by customers | +| 1200 | Payment Clearing | Card payments received but not yet settled by processor | +| 1300 | Inventory - Sale Stock | Products held for sale | +| 1310 | Inventory - Rental Fleet | Items held for rental (industry-specific module) | +| 1320 | Inventory - Parts & Supplies | Repair parts and consumables | ## 2.2 Liabilities -Code - -Account Name - -Notes - -2000 - -Sales Tax Payable - -Tax collected from customers, owed to state - -2100 - -Deferred Revenue - Rentals - -Rental payments received for future periods - -2110 - -Deferred Revenue - Lessons - -Lesson payments received for future periods - -2120 - -Deferred Revenue - RTO Equity - -Rent-to-own equity portion — not earned until buyout - -2200 - -Rental Deposits Held - -Security deposits — liability until returned or applied - -2300 - -Customer Credits - -Store credits, makeup lesson credits - -2400 - -Unearned Repair Revenue - -Deposits on repairs not yet completed - +| Code | Account Name | Notes | +|------|-------------|-------| +| 2000 | Sales Tax Payable | Tax collected from customers, owed to taxing authority | +| 2100 | Deferred Revenue - Rentals | Rental payments received for future periods | +| 2110 | Deferred Revenue - Lessons | Lesson payments received for future periods | +| 2120 | Deferred Revenue - RTO Equity | Rent-to-own equity portion — not earned until buyout | +| 2200 | Rental Deposits Held | Security deposits — liability until returned or applied | +| 2300 | Customer Credits | Store credits, makeup lesson credits, overpayments | +| 2350 | Gift Card Liability | Gift cards sold but not yet redeemed (module) | +| 2400 | Unearned Repair Revenue | Deposits on repairs not yet completed | +| 2500 | Accounts Payable | Amounts owed to vendors/suppliers | ## 2.3 Revenue -Code - -Account Name - -Notes - -4000 - -Sales Revenue - Instruments - - - -4010 - -Sales Revenue - Accessories - - - -4020 - -Sales Revenue - Supplies - -Strings, reeds, books, etc. - -4100 - -Rental Revenue - -Monthly rental income earned - -4200 - -Lesson Revenue - -Monthly lesson income earned - -4300 - -Repair Revenue - Labor - - - -4310 - -Repair Revenue - Parts - -Parts billed to customer - -4400 - -RTO Buyout Revenue - -Recognized on rent-to-own completion - -4500 - -Other Income - -Kept deposits, late fees, misc - +| Code | Account Name | Notes | +|------|-------------|-------| +| 4000 | Sales Revenue - Category 1 | Primary product category (configurable name) | +| 4010 | Sales Revenue - Category 2 | Secondary product category (configurable name) | +| 4020 | Sales Revenue - Category 3 | Tertiary product category (configurable name) | +| 4100 | Rental Revenue | Monthly rental income earned | +| 4200 | Lesson Revenue | Lesson income earned | +| 4300 | Repair Revenue - Labor | Repair labor charges | +| 4310 | Repair Revenue - Parts | Parts billed to customer | +| 4400 | RTO Buyout Revenue | Recognized on rent-to-own completion | +| 4500 | Other Income | Kept deposits, late fees, misc | ## 2.4 Contra Revenue -Code - -Account Name - -Notes - -4900 - -Sales Discounts - -Discounts applied at POS — keeps gross revenue clean - -4910 - -Sales Returns & Refunds - -Returned merchandise and refunded amounts - -4920 - -Proration Credits Issued - -Billing date change credits - +| Code | Account Name | Notes | +|------|-------------|-------| +| 4900 | Sales Discounts | Discounts applied at POS — keeps gross revenue clean | +| 4910 | Sales Returns & Refunds | Returned merchandise and refunded amounts | +| 4920 | Proration Credits Issued | Billing date change credits | ## 2.5 Cost of Goods Sold -Code - -Account Name - -Notes - -5000 - -COGS - Instruments - -Cost of instruments sold - -5010 - -COGS - Accessories - -Cost of accessories sold - -5020 - -COGS - Supplies - -Cost of supplies sold - -5100 - -Repair Parts Cost - -Cost of parts used in repairs - +| Code | Account Name | Notes | +|------|-------------|-------| +| 5000 | COGS - Category 1 | Cost of primary category products sold | +| 5010 | COGS - Category 2 | Cost of secondary category products sold | +| 5020 | COGS - Category 3 | Cost of tertiary category products sold | +| 5100 | Repair Parts Cost | Cost of parts used in repairs | ## 2.6 Expenses -Code +| Code | Account Name | Notes | +|------|-------------|-------| +| 6000 | Cash Over / Short | Drawer variance — over is credit, short is debit | +| 6100 | Payment Processing Fees | Card processor transaction fees | +| 6200 | Bad Debt Expense | Written-off account balances | +| 6300 | Inventory Shrinkage | Inventory adjustments and write-offs | -Account Name -Notes +## 2.7 Revenue Category Mapping -6000 +Revenue and COGS accounts (4000-4020 and 5000-5020) map to product categories defined in the inventory module. Each business configures which product categories roll up to which revenue accounts. This mapping is stored in a `category_account_mapping` table. -Cash Over / Short +For a music store, the defaults might be: +- 4000/5000 → Instruments +- 4010/5010 → Accessories +- 4020/5020 → Supplies (strings, reeds, books) -Drawer variance — over is credit, short is debit +For a bike shop: +- 4000/5000 → Bicycles +- 4010/5010 → Parts & Components +- 4020/5020 → Apparel & Accessories -6100 - -Payment Processing Fees - -Stripe transaction fees - -6200 - -Bad Debt Expense - -Written-off account balances - -6300 - -Inventory Shrinkage - -Inventory adjustments and write-offs +The account names and category mappings are fully configurable. Additional revenue/COGS account pairs can be created if a business needs more granularity. @@ -320,185 +149,151 @@ Inventory adjustments and write-offs ## 3.1 account_code -Store-configurable chart of accounts. Each store maps platform account codes to their QuickBooks account names and numbers. +Business-configurable chart of accounts. Each business maps platform account codes to their QuickBooks account names and numbers. -id, company_id, code (varchar), name (varchar),account_type (enum: asset|liability|revenue|contra_revenue|cogs|expense),quickbooks_account_name (varchar), ← must match QB exactly for importquickbooks_account_number (varchar),is_active (boolean), created_at +| Column | Type | Notes | +|--------|------|-------| +| id | uuid PK | | +| company_id | uuid FK | | +| code | varchar(10) | e.g. "1000", "4010" | +| name | varchar(255) | Display name | +| account_type | enum | asset, liability, revenue, contra_revenue, cogs, expense | +| normal_balance | enum | debit, credit — derived from account_type, enforced | +| quickbooks_account_name | varchar(255) | Must match QB exactly for import | +| quickbooks_account_number | varchar(20) | Optional — QB account number | +| is_system | boolean | System accounts cannot be deleted | +| is_active | boolean | Inactive accounts cannot receive new entries | +| created_at | timestamptz | | +| updated_at | timestamptz | | +Normal balance derivation: +- Assets, Expenses, COGS → debit +- Liabilities, Revenue, Contra Revenue → credit ## 3.2 journal_entry Header record for each accounting event. One journal entry per financial event — groups all debit and credit lines for that event. -Column - -Type - -Notes - -id - -uuid PK - - - -company_id - -uuid FK - - - -entry_number - -varchar - -Human-readable JE number e.g. JE-2024-00142 - -entry_date - -date - -Accounting date — may differ from created_at - -entry_type - -enum - -See section 4 for full list - -source_entity_type - -enum - -transaction|rental|enrollment|repair|drawer_session|batch - -source_entity_id - -uuid - -FK to the originating record - -description - -text - -Human-readable description for accountant - -total_debits - -numeric(10,2) - -Must equal total_credits - -total_credits - -numeric(10,2) - -Must equal total_debits - -export_batch_id - -uuid - -Set when entry is included in an export - -exported_at - -timestamptz - -When exported — null if not yet exported - -reconciled_at - -timestamptz - -When accountant confirmed import to QB - -is_void - -boolean - -Voided entries excluded from exports - -void_reason - -text - -Required if voided - -created_by - -uuid FK - -System or employee - -created_at - -timestamptz - - +| Column | Type | Notes | +|--------|------|-------| +| id | uuid PK | | +| company_id | uuid FK | | +| entry_number | varchar(20) | Auto-generated, e.g. JE-2026-00142 | +| entry_date | date | Accounting date — may differ from created_at | +| period_id | uuid FK | References accounting_period — null if no periods defined | +| entry_type | varchar(50) | See section 4 for full list | +| source_entity_type | varchar(50) | transaction, rental, enrollment, repair, drawer_session, batch | +| source_entity_id | uuid | FK to the originating record | +| description | text | Human-readable description for accountant | +| total_debits | numeric(12,2) | Must equal total_credits | +| total_credits | numeric(12,2) | Must equal total_debits | +| export_batch_id | uuid FK | Set when entry is included in an export | +| exported_at | timestamptz | When exported — null if not yet exported | +| reconciled_at | timestamptz | When accountant confirmed import to QB | +| is_void | boolean | Voided entries excluded from exports | +| void_reason | text | Required if voided | +| voided_by | uuid FK | User who voided | +| voided_at | timestamptz | When voided | +| reversal_of_id | uuid FK | If this is a reversing entry, references the original | +| created_by | uuid FK | System or employee | +| created_at | timestamptz | | +Precision: `numeric(12,2)` supports values up to $9,999,999,999.99 per entry. ## 3.3 journal_entry_line Individual debit and credit lines for each journal entry. Every entry must have at least one debit and one credit line and total_debits must equal total_credits. -Column - -Type - -Notes - -id - -uuid PK +| Column | Type | Notes | +|--------|------|-------| +| id | uuid PK | | +| journal_entry_id | uuid FK | | +| account_code_id | uuid FK | Which account is affected | +| line_type | enum | debit, credit | +| amount | numeric(12,2) | Always positive — line_type determines direction | +| description | text | Line-level description | +| entity_type | varchar(50) | Optional — customer, vendor, employee for sub-ledger | +| entity_id | uuid | Optional — FK to account, supplier, etc. | +| created_at | timestamptz | | +## 3.4 accounting_period -journal_entry_id +Accounting periods for month-end close. Optional — if no periods are defined, entries can be posted to any date. -uuid FK +| Column | Type | Notes | +|--------|------|-------| +| id | uuid PK | | +| company_id | uuid FK | | +| name | varchar(50) | e.g. "March 2026" | +| start_date | date | Period start (inclusive) | +| end_date | date | Period end (inclusive) | +| status | enum | open, closed, locked | +| closed_by | uuid FK | User who closed the period | +| closed_at | timestamptz | | +| created_at | timestamptz | | + +Period status: +- **open** — entries can be posted +- **closed** — no new entries without manager override (soft close for month-end review) +- **locked** — no new entries, period is final (after QB reconciliation) + +Posting to a closed period requires `accounting.admin` permission. Posting to a locked period is blocked entirely. - -account_code_id - -uuid FK - -Which account is affected - -line_type - -enum - -debit | credit - -amount - -numeric(10,2) - -Always positive — line_type determines direction - -description - -text - -Line-level description - -created_at - -timestamptz - - - - - -## 3.4 export_batch +## 3.5 export_batch Records each export operation for audit and reconciliation tracking. -id, company_id, exported_by (uuid FK), export_format (csv|iif),date_range_from, date_range_to, entry_count, total_amount,file_path (S3 URL), reconciled_at, created_at +| Column | Type | Notes | +|--------|------|-------| +| id | uuid PK | | +| company_id | uuid FK | | +| exported_by | uuid FK | User who initiated export | +| export_format | enum | csv, iif | +| date_range_from | date | | +| date_range_to | date | | +| entry_count | integer | | +| total_amount | numeric(12,2) | Sum of all debit amounts in batch | +| file_path | varchar(500) | Storage path for export file | +| reconciled_at | timestamptz | When accountant confirmed import | +| reconciled_by | uuid FK | | +| created_at | timestamptz | | + + +## 3.6 category_account_mapping + +Maps product categories to revenue and COGS accounts. + +| Column | Type | Notes | +|--------|------|-------| +| id | uuid PK | | +| company_id | uuid FK | | +| category_id | uuid FK | References product category | +| revenue_account_id | uuid FK | References account_code | +| cogs_account_id | uuid FK | References account_code | +| created_at | timestamptz | | + + +## 3.7 tax_rate + +Sales tax rates by jurisdiction. Supports multi-rate jurisdictions (state + county + city). + +| Column | Type | Notes | +|--------|------|-------| +| id | uuid PK | | +| company_id | uuid FK | | +| name | varchar(100) | e.g. "Texas State", "Travis County", "Austin City" | +| rate | numeric(6,4) | e.g. 0.0625 for 6.25% | +| jurisdiction | varchar(100) | e.g. "TX", "Travis County, TX" | +| is_active | boolean | | +| sort_order | integer | Order applied (state first, then county, then city) | +| created_at | timestamptz | | +| updated_at | timestamptz | | + +Tax rates are applied at the location level — each location has a tax profile that combines applicable rates. The combined rate is calculated at the time of sale, and the total tax is posted to Sales Tax Payable (2000) as a single line item. The tax rate breakdown is stored on the transaction record for reporting. @@ -506,555 +301,263 @@ id, company_id, exported_by (uuid FK), export_format (csv|iif),date_range_from, Every financial event generates one or more journal entries automatically. The following tables show the exact debit and credit mapping for each event type. All entries are generated by the platform — staff do not create journal entries manually. +Payment processor references below are generic — "Payment Clearing" (1200) applies to any processor (Stripe, Global Payments, or future providers). The clearing account is reconciled against processor payout reports. ## 4.1 Cash Sale -Debit - -Credit - -Notes - -1000 Cash - Store Drawer - -4000-4020 Sales Revenue - -Revenue recognized at point of sale - -1000 Cash - Store Drawer - -2000 Sales Tax Payable - -Tax collected from customer - -5000-5020 COGS - -1300 Inventory - Sale Stock - -Cost of item removed from inventory +| Debit | Credit | Notes | +|-------|--------|-------| +| 1000 Cash - Register Drawer | 4000-4020 Sales Revenue | Revenue recognized at point of sale | +| 1000 Cash - Register Drawer | 2000 Sales Tax Payable | Tax collected from customer | +| 5000-5020 COGS | 1300 Inventory - Sale Stock | Cost of item removed from inventory | +## 4.2 Card Sale -## 4.2 Card Sale (Stripe Terminal or Keyed) +| Debit | Credit | Notes | +|-------|--------|-------| +| 1200 Payment Clearing | 4000-4020 Sales Revenue | Card payment in transit to bank | +| 1200 Payment Clearing | 2000 Sales Tax Payable | Tax collected | +| 5000-5020 COGS | 1300 Inventory - Sale Stock | Cost of item sold | -Debit - -Credit - -Notes - -1200 Stripe Clearing - -4000-4020 Sales Revenue - -Card payment in transit to bank - -1200 Stripe Clearing - -2000 Sales Tax Payable - -Tax collected - -5000-5020 COGS - -1300 Inventory - Sale Stock - -Cost of item sold - - - -When Stripe pays out to bank account (triggered by Stripe payout webhook): - -Debit - -Credit - -Notes - -1000 Cash - Store Drawer - -1200 Stripe Clearing - -Funds settled from Stripe to bank - -6100 Payment Processing Fees - -1200 Stripe Clearing - -Stripe fee deducted from payout +When processor settles to bank account (triggered by payout webhook or manual reconciliation): +| Debit | Credit | Notes | +|-------|--------|-------| +| 1000 Cash (Bank) | 1200 Payment Clearing | Funds settled from processor to bank | +| 6100 Payment Processing Fees | 1200 Payment Clearing | Processor fee deducted from payout | ## 4.3 Discount Applied at POS -Debit - -Credit - -Notes - -4900 Sales Discounts - -4000-4020 Sales Revenue - -Contra revenue — keeps gross revenue clean - - +| Debit | Credit | Notes | +|-------|--------|-------| +| 4900 Sales Discounts | 4000-4020 Sales Revenue | Contra revenue — keeps gross revenue clean | Note: Gross revenue is always recorded at full price. The discount is recorded separately as a contra-revenue debit. Net revenue = Sales Revenue minus Sales Discounts. This gives the accountant visibility into both gross and net figures. - ## 4.4 Sale Refund -Debit - -Credit - -Notes - -4910 Sales Returns & Refunds - -1000/1200 Cash or Stripe Clearing - -Refund issued to customer - -1300 Inventory - Sale Stock - -5000-5020 COGS - -Item returned to inventory at cost - -2000 Sales Tax Payable - -1000/1200 Cash or Stripe Clearing - -Tax refunded - +| Debit | Credit | Notes | +|-------|--------|-------| +| 4910 Sales Returns & Refunds | 1000/1200 Cash or Payment Clearing | Refund issued to customer | +| 1300 Inventory - Sale Stock | 5000-5020 COGS | Item returned to inventory at cost | +| 2000 Sales Tax Payable | 1000/1200 Cash or Payment Clearing | Tax refunded | ## 4.5 Rental Payment Received Standard month-to-month rental — full payment is earned revenue: -Debit - -Credit - -Notes - -1200 Stripe Clearing - -4100 Rental Revenue - -Monthly rental payment — earned immediately - -1200 Stripe Clearing - -2000 Sales Tax Payable - -Tax if applicable to rentals in jurisdiction - +| Debit | Credit | Notes | +|-------|--------|-------| +| 1200 Payment Clearing | 4100 Rental Revenue | Monthly rental payment — earned immediately | +| 1200 Payment Clearing | 2000 Sales Tax Payable | Tax if applicable to rentals in jurisdiction | ## 4.6 Rent-to-Own Payment Received RTO payments split between earned rental revenue and deferred equity portion: -Debit - -Credit - -Notes - -1200 Stripe Clearing - -4100 Rental Revenue - -Rental portion — earned immediately - -1200 Stripe Clearing - -2120 Deferred Revenue - RTO Equity - -Equity portion — not earned until buyout - +| Debit | Credit | Notes | +|-------|--------|-------| +| 1200 Payment Clearing | 4100 Rental Revenue | Rental portion — earned immediately | +| 1200 Payment Clearing | 2120 Deferred Revenue - RTO Equity | Equity portion — not earned until buyout | ## 4.7 Rent-to-Own Buyout Completed When customer exercises buyout option — deferred equity is recognized as revenue: -Debit - -Credit - -Notes - -2120 Deferred Revenue - RTO Equity - -4400 RTO Buyout Revenue - -Accumulated equity recognized on buyout - -1200/1000 Stripe or Cash - -4400 RTO Buyout Revenue - -Remaining buyout balance collected - -5000 COGS - Instruments - -1310 Inventory - Rental Fleet - -Cost of instrument transferred from fleet to sold - +| Debit | Credit | Notes | +|-------|--------|-------| +| 2120 Deferred Revenue - RTO Equity | 4400 RTO Buyout Revenue | Accumulated equity recognized on buyout | +| 1200/1000 Payment Clearing or Cash | 4400 RTO Buyout Revenue | Remaining buyout balance collected | +| 5000 COGS | 1310 Inventory - Rental Fleet | Cost of item transferred from fleet to sold | ## 4.8 Rental Security Deposit Collected Deposit is a liability — not revenue until earned or applied: -Debit - -Credit - -Notes - -1000/1200 Cash or Stripe Clearing - -2200 Rental Deposits Held - -Deposit received — held as liability - +| Debit | Credit | Notes | +|-------|--------|-------| +| 1000/1200 Cash or Payment Clearing | 2200 Rental Deposits Held | Deposit received — held as liability | ## 4.9 Rental Deposit Returned -Debit - -Credit - -Notes - -2200 Rental Deposits Held - -1000/1200 Cash or Stripe Clearing - -Deposit refunded to customer on return - +| Debit | Credit | Notes | +|-------|--------|-------| +| 2200 Rental Deposits Held | 1000/1200 Cash or Payment Clearing | Deposit refunded to customer on return | ## 4.10 Rental Deposit Kept (Damage) -Debit - -Credit - -Notes - -2200 Rental Deposits Held - -4500 Other Income - -Deposit applied to damage — now earned income - +| Debit | Credit | Notes | +|-------|--------|-------| +| 2200 Rental Deposits Held | 4500 Other Income | Deposit applied to damage — now earned income | ## 4.11 Lesson Payment Received -Debit - -Credit - -Notes - -1200 Stripe Clearing - -4200 Lesson Revenue - -Monthly lesson payment — earned for current month - - - -Note: If the store policy is to recognize lesson revenue per session delivered rather than per month billed, the entry on payment would credit Deferred Revenue - Lessons (2110) and recognize revenue as each session is marked attended. Most small music stores bill monthly and recognize on billing — either approach is acceptable but must be consistent. +| Debit | Credit | Notes | +|-------|--------|-------| +| 1200 Payment Clearing | 4200 Lesson Revenue | Lesson payment — earned for current period | +**Revenue recognition note:** If the business recognizes lesson revenue per session delivered rather than per billing period, the entry on payment would credit Deferred Revenue - Lessons (2110) and recognize revenue as each session is marked attended. Most small businesses bill monthly and recognize on billing — either approach is acceptable but must be consistent within a fiscal year. The business selects their method in settings. ## 4.12 Makeup Lesson Credit Issued -Debit - -Credit - -Notes - -4200 Lesson Revenue - -2300 Customer Credits - -Revenue reversed for undelivered lesson - +| Debit | Credit | Notes | +|-------|--------|-------| +| 4200 Lesson Revenue | 2300 Customer Credits | Revenue reversed for undelivered lesson | ## 4.13 Repair Payment Collected at Pickup -Debit - -Credit - -Notes - -1000/1200 Cash or Stripe Clearing - -4300 Repair Revenue - Labor - -Labor charges collected - -1000/1200 Cash or Stripe Clearing - -4310 Repair Revenue - Parts - -Parts charges collected - -1000/1200 Cash or Stripe Clearing - -2000 Sales Tax Payable - -Tax on parts if applicable - -5100 Repair Parts Cost - -1320 Inventory - Parts & Supplies - -Cost of parts consumed in repair - +| Debit | Credit | Notes | +|-------|--------|-------| +| 1000/1200 Cash or Payment Clearing | 4300 Repair Revenue - Labor | Labor charges collected | +| 1000/1200 Cash or Payment Clearing | 4310 Repair Revenue - Parts | Parts charges collected | +| 1000/1200 Cash or Payment Clearing | 2000 Sales Tax Payable | Tax on parts if applicable | +| 5100 Repair Parts Cost | 1320 Inventory - Parts & Supplies | Cost of parts consumed in repair | ## 4.14 Repair Charged to Account -Debit - -Credit - -Notes - -1100 Accounts Receivable - -4300 Repair Revenue - Labor - -Repair billed to account — not yet paid - -1100 Accounts Receivable - -4310 Repair Revenue - Parts - -Parts billed to account - -5100 Repair Parts Cost - -1320 Inventory - Parts & Supplies - -Cost of parts consumed - +| Debit | Credit | Notes | +|-------|--------|-------| +| 1100 Accounts Receivable | 4300 Repair Revenue - Labor | Repair billed to account — not yet paid | +| 1100 Accounts Receivable | 4310 Repair Revenue - Parts | Parts billed to account | +| 5100 Repair Parts Cost | 1320 Inventory - Parts & Supplies | Cost of parts consumed | ## 4.15 Account Payment Received -Debit - -Credit - -Notes - -1000/1200 Cash or Stripe Clearing - -1100 Accounts Receivable - -Payment applied to outstanding balance - +| Debit | Credit | Notes | +|-------|--------|-------| +| 1000/1200 Cash or Payment Clearing | 1100 Accounts Receivable | Payment applied to outstanding balance | ## 4.16 Bad Debt Write-Off -Debit - -Credit - -Notes - -6200 Bad Debt Expense - -1100 Accounts Receivable - -Uncollectible balance written off — requires manager approval - +| Debit | Credit | Notes | +|-------|--------|-------| +| 6200 Bad Debt Expense | 1100 Accounts Receivable | Uncollectible balance written off — requires manager approval | ## 4.17 Billing Date Change — Proration Credit -Debit - -Credit - -Notes - -4920 Proration Credits Issued - -1100/1200 AR or Stripe Clearing - -Credit issued to customer for billing date shift - +| Debit | Credit | Notes | +|-------|--------|-------| +| 4920 Proration Credits Issued | 1100/1200 AR or Payment Clearing | Credit issued to customer for billing date shift | ## 4.18 Billing Date Change — Proration Charge -Debit - -Credit - -Notes - -1200 Stripe Clearing - -4100/4200 Rental or Lesson Revenue - -Additional charge for extended billing period - +| Debit | Credit | Notes | +|-------|--------|-------| +| 1200 Payment Clearing | 4100/4200 Rental or Lesson Revenue | Additional charge for extended billing period | ## 4.19 Inventory Purchase (Receiving PO) -Debit - -Credit - -Notes - -1300 Inventory - Sale Stock - -1100 Accounts Payable - -Merchandise received — owed to vendor - -1310 Inventory - Rental Fleet - -1100 Accounts Payable - -Rental fleet instruments received - +| Debit | Credit | Notes | +|-------|--------|-------| +| 1300 Inventory - Sale Stock | 2500 Accounts Payable | Merchandise received — owed to vendor | +| 1310 Inventory - Rental Fleet | 2500 Accounts Payable | Rental fleet items received | ## 4.20 Vendor Payment -Debit - -Credit - -Notes - -1100 Accounts Payable - -1000/1200 Cash or Bank - -Payment to vendor for purchase order +| Debit | Credit | Notes | +|-------|--------|-------| +| 2500 Accounts Payable | 1000/1200 Cash or Bank | Payment to vendor for purchase order | +## 4.21 Gift Card Sold (Module) -## 4.21 Cash Drawer — Opening Float - -Debit - -Credit - -Notes - -1000 Cash - Store Drawer - -1000 Cash - Store Drawer - -Internal transfer — float set for shift (net zero) +| Debit | Credit | Notes | +|-------|--------|-------| +| 1000/1200 Cash or Payment Clearing | 2350 Gift Card Liability | Gift card sold — liability until redeemed | +## 4.22 Gift Card Redeemed (Module) -## 4.22 Cash Drawer — Closing Variance +| Debit | Credit | Notes | +|-------|--------|-------| +| 2350 Gift Card Liability | 4000-4020 Sales Revenue | Gift card applied to purchase — liability becomes revenue | + +If gift card only partially covers the sale, the remainder is a separate payment entry (cash or card). + + +## 4.23 Consignment Sale (Module) + +| Debit | Credit | Notes | +|-------|--------|-------| +| 1000/1200 Cash or Payment Clearing | 2500 Accounts Payable | Consignor's portion — owed to the owner | +| 1000/1200 Cash or Payment Clearing | 4500 Other Income (Commission) | Store's commission on the sale | +| 1000/1200 Cash or Payment Clearing | 2000 Sales Tax Payable | Tax collected | + +Note: consignment inventory is not on the store's books (the store doesn't own it). No COGS entry. The store's revenue is only the commission. + + +## 4.24 Cash Drawer — Opening Float + +| Debit | Credit | Notes | +|-------|--------|-------| +| 1000 Cash - Register Drawer | 1020 Cash - Safe | Float transferred from safe to drawer for shift | + + +## 4.25 Cash Drawer — Closing Variance If drawer is over (more cash than expected): -Debit - -Credit - -Notes - -1000 Cash - Store Drawer - -6000 Cash Over / Short - -Overage — credit to over/short account - - +| Debit | Credit | Notes | +|-------|--------|-------| +| 1000 Cash - Register Drawer | 6000 Cash Over / Short | Overage — credit to over/short account | If drawer is short (less cash than expected): -Debit - -Credit - -Notes - -6000 Cash Over / Short - -1000 Cash - Store Drawer - -Shortage — debit to over/short account +| Debit | Credit | Notes | +|-------|--------|-------| +| 6000 Cash Over / Short | 1000 Cash - Register Drawer | Shortage — debit to over/short account | +## 4.26 Cash Drop Mid-Shift -## 4.23 Cash Drop Mid-Shift - -Debit - -Credit - -Notes - -1000 Cash - Safe / Vault - -1000 Cash - Store Drawer - -Cash moved from drawer to secure location +| Debit | Credit | Notes | +|-------|--------|-------| +| 1020 Cash - Safe | 1000 Cash - Register Drawer | Cash moved from drawer to secure location | - -## 4.24 Batch Repair Invoice — School +## 4.27 Batch Repair Invoice Batch repair invoices follow the same pattern as individual repair payments but reference the batch record: -Debit +| Debit | Credit | Notes | +|-------|--------|-------| +| 1100 Accounts Receivable | 4300 Repair Revenue - Labor | Batch labor billed to account | +| 1100 Accounts Receivable | 4310 Repair Revenue - Parts | Batch parts billed to account | +| 5100 Repair Parts Cost | 1320 Inventory - Parts & Supplies | Cost of all parts used across batch | -Credit -Notes +## 4.28 Store Credit Issued (Return without Receipt) -1100 Accounts Receivable +| Debit | Credit | Notes | +|-------|--------|-------| +| 4910 Sales Returns & Refunds | 2300 Customer Credits | Store credit issued in lieu of cash refund | -4300 Repair Revenue - Labor -Batch labor billed to school account +## 4.29 Store Credit Redeemed -1100 Accounts Receivable - -4310 Repair Revenue - Parts - -Batch parts billed to school account - -5100 Repair Parts Cost - -1320 Inventory - Parts & Supplies - -Cost of all parts used across batch +| Debit | Credit | Notes | +|-------|--------|-------| +| 2300 Customer Credits | 4000-4020 Sales Revenue | Store credit applied to purchase | @@ -1063,16 +566,15 @@ Cost of all parts used across batch Every journal entry is validated before being written to the database. Validation failures block the originating financial event and alert staff. - total_debits must equal total_credits — entries that do not balance are rejected - -- Every line must reference a valid active account_code - -- Entry date cannot be more than 30 days in the past without manager override - +- Every line must reference a valid, active account_code - Entry date cannot be in the future - +- Entry date must fall within an open accounting period (if periods are configured) +- Posting to a closed period requires `accounting.admin` permission +- Posting to a locked period is blocked entirely - Voided entries generate a reversing entry — equal and opposite lines — rather than being deleted - -- Reversing entries reference the original entry ID for traceability +- Reversing entries reference the original entry ID via `reversal_of_id` for traceability +- All amounts must be positive — the line_type (debit/credit) determines direction +- A journal entry must have at least two lines (at least one debit and one credit) @@ -1082,138 +584,148 @@ Every journal entry is validated before being written to the database. Validatio Journal entries are exported as CSV in a format compatible with QuickBooks Desktop and QuickBooks Online import. Each row represents one journal entry line. - - -CSV Column - -Source - -Date - -journal_entry.entry_date - -Journal No - -journal_entry.entry_number - -Account - -account_code.quickbooks_account_name — must match QB exactly - -Debit - -journal_entry_line.amount where line_type = debit - -Credit - -journal_entry_line.amount where line_type = credit - -Description - -journal_entry.description - -Name - -account.name where applicable — for AR/AP lines - -Class - -Optional — store name for multi-location QB setups - +| CSV Column | Source | +|-----------|--------| +| Date | journal_entry.entry_date | +| Journal No | journal_entry.entry_number | +| Account | account_code.quickbooks_account_name — must match QB exactly | +| Debit | journal_entry_line.amount where line_type = debit | +| Credit | journal_entry_line.amount where line_type = credit | +| Description | journal_entry.description | +| Name | account.name where applicable — for AR/AP lines | +| Class | Optional — location name for multi-location QB setups | ## 6.2 Export Workflow -- Staff or accountant selects date range for export - -- System returns count of unexported entries in range for confirmation - -- Export generated as CSV and stored in S3 — download link provided - -- All included entries marked with export_batch_id and exported_at timestamp - -- Entries already exported are excluded from subsequent exports by default - -- Override option available to re-export a specific batch — requires manager approval - -- Accountant imports CSV into QuickBooks — confirms successful import in platform - -- Confirmed entries marked reconciled_at — visible in reconciliation report - +1. Staff or accountant selects date range for export +2. System returns count of unexported entries in range for confirmation +3. Export generated as CSV and stored via file storage — download link provided +4. All included entries marked with export_batch_id and exported_at timestamp +5. Entries already exported are excluded from subsequent exports by default +6. Override option available to re-export a specific batch — requires manager approval +7. Accountant imports CSV into QuickBooks — confirms successful import in platform +8. Confirmed entries marked reconciled_at — visible in reconciliation report ## 6.3 Export Frequency Recommendation -Daily export is recommended for active stores to keep QuickBooks current. Weekly export is acceptable for lower-volume stores. Monthly export creates large import files and increases risk of errors going undetected. The platform supports any frequency — the accountant decides what works for their workflow. +Daily export is recommended for active businesses to keep QuickBooks current. Weekly export is acceptable for lower-volume businesses. Monthly export creates large import files and increases risk of errors going undetected. The platform supports any frequency — the accountant decides what works for their workflow. -# 7. In-Platform Accounting Reports +# 7. Accounting Periods -These reports are generated from journal entry data within the platform and do not require QuickBooks. They give the store owner operational financial visibility without waiting for the accountant's monthly close. +Accounting periods provide month-end close discipline. They are optional — small businesses that don't need formal period management can skip this entirely and all entries are posted without period validation. + +## 7.1 Period Lifecycle + +1. **Open** — default state. Entries can be posted freely. +2. **Closed** — soft close for month-end review. New entries require `accounting.admin` override. Allows corrections before finalization. +3. **Locked** — hard close after QB reconciliation. No entries can be posted. Period is final. + +## 7.2 Month-End Close Process + +1. Accountant reviews all entries for the period in the platform +2. Runs trial balance report — verifies debits equal credits across all accounts +3. Closes the period (status → closed) +4. Exports entries to QuickBooks +5. Confirms QB import is clean +6. Locks the period (status → locked) + +## 7.3 Auto-Period Generation + +Periods can be auto-generated monthly. The system creates the next period when the current one is closed. Businesses that don't use periods have no periods created — the feature is entirely opt-in. -Report +# 8. In-Platform Accounting Reports -Description +These reports are generated from journal entry data within the platform and do not require QuickBooks. They give the business owner operational financial visibility without waiting for the accountant's monthly close. -Revenue Summary - -Revenue by category (instruments, rentals, lessons, repairs) by period - -Gross vs Net Revenue - -Gross revenue vs discounts vs net — shows discount impact - -AR Aging - -Outstanding account balances by age — current, 30, 60, 90+ days - -Deferred Revenue - -RTO equity, lesson credits, deposits held — future obligations - -Cash Flow Summary - -Cash in vs out by period — drawer, Stripe, deposits - -Stripe Clearing Reconciliation - -Amounts in clearing vs expected payouts — flags missing payouts - -Export Status - -Entries exported vs pending export — reconciliation tracking - -Cash Over / Short History - -Drawer variance by shift, employee, and register - -COGS vs Revenue - -Gross margin by product category +| Report | Description | +|--------|-------------| +| Trial Balance | Debit/credit totals by account — must balance to zero | +| Revenue Summary | Revenue by category by period | +| Gross vs Net Revenue | Gross revenue, discounts, returns, net — shows discount impact | +| AR Aging | Outstanding account balances by age — current, 30, 60, 90+ days | +| AP Aging | Outstanding vendor balances by age | +| Deferred Revenue | RTO equity, lesson credits, deposits held — future obligations | +| Cash Flow Summary | Cash in vs out by period — drawer, card payments, deposits | +| Payment Clearing Reconciliation | Amounts in clearing vs expected payouts — flags missing settlements | +| Export Status | Entries exported vs pending export — reconciliation tracking | +| Cash Over / Short History | Drawer variance by shift, employee, and register | +| COGS vs Revenue | Gross margin by product category | +| Tax Collected | Sales tax collected by jurisdiction and period | +| Gift Card Liability | Outstanding gift card balances (module) | -# 8. Business Rules +# 9. Business Rules - Journal entries are generated automatically — staff never create entries manually - - Every financial event must produce a balanced journal entry before the event is committed - -- Entries are immutable — corrections made via reversing entries only - +- Entries are append-only and immutable — corrections made via reversing entries only - Voided entries generate equal and opposite reversing entries — never deleted - - Exported entries are not re-exported unless explicitly overridden with manager approval - -- Chart of accounts is configurable per store — account names must match QuickBooks exactly - -- Stripe clearing account must be reconciled against Stripe payout reports monthly - -- Deferred revenue accounts reviewed quarterly — amounts that should have been recognized flagged - +- Chart of accounts is configurable per business — account names must match QuickBooks exactly +- Payment clearing account must be reconciled against processor payout reports regularly +- Deferred revenue accounts reviewed quarterly — amounts that should have been recognized are flagged - Bad debt write-offs require manager approval and are logged in audit trail +- Revenue/COGS accounts map to product categories — configurable per business +- Tax rates are location-specific — each location has a tax profile with applicable rates +- Gift card and consignment entries only generated when those modules are active -- AIM migration historical transactions imported as journal entries with legacy_source tag — clearly separated from live entries in exports \ No newline at end of file + + +# 10. Posting Service Interface + +The posting service is the single entry point for all journal entry generation. Domain services (POS, rentals, lessons, repairs) call the posting service with a business event — they do not construct journal entries directly. + +``` +AccountingService.post(companyId, { + type: 'cash_sale', // event type — maps to journal entry template + date: '2026-03-30', // accounting date + sourceEntityType: 'transaction', + sourceEntityId: 'uuid', + description: 'Sale #1234 — 3 items', + lines: [ // optional override — normally auto-generated from event type + { accountCode: '1000', type: 'debit', amount: 107.50 }, + { accountCode: '4010', type: 'credit', amount: 99.99 }, + { accountCode: '2000', type: 'credit', amount: 7.51 }, + ], + metadata: { // domain-specific context + transactionId: 'uuid', + customerId: 'uuid', + items: [...], + }, +}) +``` + +The posting service: +1. Resolves the event type to a journal entry template (or uses provided lines) +2. Looks up the correct revenue/COGS accounts from category mappings +3. Calculates tax from the location's tax profile +4. Validates the entry balances (debits == credits) +5. Validates the entry date falls in an open period +6. Writes the journal entry and lines in a single transaction +7. Returns the journal entry ID + +If validation fails, the posting service throws and the originating event is rolled back. No financial event can be committed without a valid journal entry. + + + +# 11. Implementation Order + +1. `account_code` table + seed default chart of accounts +2. `journal_entry` + `journal_entry_line` tables +3. Posting service with validation (balance check, period check, account check) +4. `tax_rate` table + location tax profiles +5. `category_account_mapping` table +6. `accounting_period` table + open/close/lock endpoints +7. Journal entry list/detail API endpoints (read-only for staff) +8. Void + reversing entry flow +9. `export_batch` table + CSV export +10. In-platform reports (trial balance first, then others) +11. Integration hooks from POS, rentals, lessons, repairs (added as each domain goes live) +12. QuickBooks reconciliation workflow