saas-accounting-system/SKILL.md
Implement a complete double-entry accounting system inside any SaaS app. Users enter transactions naturally (sales, expenses, inventory) while the system auto-posts journal entries under the hood. Produces both user-friendly reports and technical...
npx skillsauth add peterbamuhigire/skills-web-dev saas-accounting-systemInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
saas-accounting-system or would be better handled by a more specific companion skill.references only as needed.SKILL.md first, then load only the referenced deep-dive files that are necessary for the task.references/ directory for deep detail after reading the core workflow below.This skill implements a hidden accounting engine inside business applications. End users never see debits, credits, or journal entries — they enter sales, record payments, move inventory. Under the hood, every transaction auto-posts balanced journal entries that accountants and auditors can query at any time.
Philosophy: Users think in business terms. The system thinks in double-entry.
┌─────────────────────────────────────────────────┐
│ USER LAYER (Friendly) │
│ Sales, Purchases, Payments, Inventory, Expenses│
│ → User sees: "Sale #1042 to Customer X: $500" │
└──────────────────────┬──────────────────────────┘
│ auto-posts
┌──────────────────────▼──────────────────────────┐
│ ACCOUNTING ENGINE (Hidden) │
│ Journal Entries, Ledger Postings, Trial Balance│
│ → Engine posts: DR Accounts Receivable $500 │
│ CR Sales Revenue $500 │
└──────────────────────┬──────────────────────────┘
│ aggregates
┌──────────────────────▼──────────────────────────┐
│ REPORTING LAYER (Dual) │
│ User Reports: Sales Summary, Aging, P&L Simple │
│ Accountant Reports: Trial Balance, BS, IS, CF │
└─────────────────────────────────────────────────┘
Every transaction MUST produce balanced journal entries. No exceptions.
SUM(debits) = SUM(credits) — ALWAYS
This is enforced at the database level via stored procedure or trigger. If entries don't balance, the entire transaction rolls back.
The COA is the backbone. Every account has a type that determines its normal balance.
| Type | Code Range | Normal Balance | Examples | |------|-----------|----------------|----------| | Asset | 1000-1999 | Debit | Cash, Bank, AR, Inventory, Equipment | | Liability | 2000-2999 | Credit | AP, Loans, Tax Payable, Unearned Revenue | | Equity | 3000-3999 | Credit | Owner's Equity, Retained Earnings | | Revenue | 4000-4999 | Credit | Sales, Service Income, Interest Income | | COGS | 5000-5999 | Debit | Cost of Goods Sold, Direct Materials | | Expense | 6000-6999 | Debit | Rent, Salaries, Utilities, Marketing |
Setup rules:
franchise_id)See: references/chart-of-accounts.md
Users never create journal entries manually. Every business transaction has a posting rule.
| User Action | Debit Account | Credit Account | |------------|---------------|----------------| | Record Sale (Invoice) | Accounts Receivable | Sales Revenue | | Record Sale + Tax | AR + Tax Receivable | Sales Revenue + Tax Payable | | Receive Payment (Cash) | Cash/Bank | Accounts Receivable | | Record Purchase | Inventory/Expense | Accounts Payable | | Pay Supplier | Accounts Payable | Cash/Bank | | Record Expense | Expense Account | Cash/Bank or AP | | Inventory Sale (COGS) | Cost of Goods Sold | Inventory | | Stock Adjustment (+) | Inventory | Inventory Adjustment (Income) | | Stock Adjustment (-) | Inventory Adjustment (Expense) | Inventory | | Salary Payment | Salary Expense | Cash/Bank | | Loan Received | Cash/Bank | Loan Payable | | Loan Repayment | Loan Payable + Interest Exp | Cash/Bank | | Depreciation | Depreciation Expense | Accumulated Depreciation | | Customer Refund | Sales Returns | Cash/Bank or AR |
Multi-line entries: A single sale with tax and discount creates 3+ journal lines, all in one entry. The entry MUST balance.
See: references/journal-posting-rules.md
Rule: Never delete a posted journal entry. Always create a reversing entry.
1. User clicks "Void" on a transaction (e.g., Sale Invoice #1042)
2. System marks the original transaction as VOIDED (status change)
3. System auto-creates a REVERSING journal entry:
- Same accounts, opposite directions
- Reference: "REVERSAL of JE-{original_id}"
- Same date OR current date (configurable)
4. Original entry + reversal entry net to ZERO
5. All sub-ledger balances update automatically
Original (Sale Invoice #1042):
DR Accounts Receivable 500.00
CR Sales Revenue 500.00
Reversal (Void of #1042):
DR Sales Revenue 500.00
CR Accounts Receivable 500.00
Net effect: ZERO
See: references/void-reversal-patterns.md
-- Chart of Accounts
accounts (id, franchise_id, code, name, type, parent_id,
is_active, normal_balance, created_at)
-- Journal Entries (Header)
journal_entries (id, franchise_id, entry_date, reference_type,
reference_id, narration, is_reversal, reversed_entry_id,
posted_by, status, created_at)
-- Journal Entry Lines (Detail)
journal_entry_lines (id, journal_entry_id, account_id,
debit_amount, credit_amount, narration,
franchise_id, created_at)
-- Fiscal Periods
fiscal_periods (id, franchise_id, period_name, start_date,
end_date, status, closed_by, closed_at)
-- Account Balances (Materialized for performance)
account_balances (id, franchise_id, account_id, period_id,
opening_balance, debit_total, credit_total,
closing_balance, updated_at)
Integrity constraints:
journal_entry_lines.debit_amount and credit_amount are DECIMAL(15,2)franchise_id on every table (multi-tenant isolation)status enum: DRAFT, POSTED, VOIDEDSee: references/schema-design.md
| Report | What User Sees | Data Source | |--------|---------------|-------------| | Sales Summary | Total sales by period, customer, product | Sales transactions | | Outstanding Invoices | Who owes what, how old | AR sub-ledger | | Expense Report | Spending by category | Expense transactions | | Profit & Loss (Simple) | Revenue minus expenses | Income/expense accounts | | Cash Position | Money in bank/cash | Cash/bank accounts | | Inventory Value | Stock on hand with cost | Inventory sub-ledger |
| Report | What It Shows | Source | |--------|-------------|--------| | Trial Balance | All account balances (DR/CR columns) | General Ledger | | Balance Sheet | Assets = Liabilities + Equity | GL (type 1-3) | | Income Statement | Revenue - COGS - Expenses = Net Income | GL (type 4-6) | | Cash Flow Statement | Operating + Investing + Financing | Cash account entries | | General Ledger Detail | Every entry per account | Journal entries | | Journal Register | All journal entries chronologically | Journal entries | | Aged Receivables | AR aging (30/60/90/120 days) | AR sub-ledger | | Aged Payables | AP aging | AP sub-ledger | | Audit Trail | Who posted what, when | Journal entries + audit log |
See: references/financial-statements.md
accounts table with COA seed datajournal_entries and journal_entry_lines tablesfiscal_periods tablepostJournalEntry() service function| Area | Skill | How It Applies |
|------|-------|---------------|
| Database schema | mysql-best-practices | DECIMAL(15,2), indexes, FK constraints |
| API endpoints | api-error-handling | Consistent error responses for failed postings |
| Multi-tenancy | multi-tenant-saas-architecture | franchise_id on all tables |
| UI reports | webapp-gui-design | DataTables for ledger, charts for P&L |
| Mobile reports | jetpack-compose-ui | Report screens with tables |
| PDF export | android-pdf-export, report-print-pdf | Financial statement PDFs |
| Security | vibe-security-skill | Protect financial data, audit trail |
| Auth | dual-auth-rbac | Permission: who can post/void/view reports |
| Inventory link | inventory-management | COGS posting on stock movements |
| Testing | sdlc-testing | Test every posting rule, every reversal |
| Implementation | plan-implementation | Execute accounting phases with TDD |
| Audit | implementation-status-auditor | Verify accounting system completeness |
| Don't | Do Instead | |-------|-----------| | Let users enter journal entries directly | Auto-post from business transactions | | Use FLOAT for money | Use DECIMAL(15,2) always | | Delete journal entries | Create reversing entries (void) | | Skip balance validation | Enforce DR=CR in stored procedure | | Store calculated balances only | Store individual entries, calculate on demand | | Mix accounting with business logic | Separate accounting engine as its own service layer | | Hard-code account codes | Use configurable COA with tenant-specific accounts | | Skip audit trail | Log every posting with user, timestamp, IP | | Allow posting to closed periods | Enforce period status check before posting | | Show debits/credits to end users | Show friendly labels (Income, Payment, etc.) |
Every implementation MUST pass these tests:
SELECT SUM(debit) - SUM(credit) FROM journal_entry_lines = 0.00references/chart-of-accounts.md — COA templates and setupreferences/journal-posting-rules.md — Complete posting rules per transactionreferences/void-reversal-patterns.md — Void mechanics and edge casesreferences/financial-statements.md — Report SQL queries and formatsreferences/schema-design.md — Complete database schema with constraintsdata-ai
Use when adding AI-powered analytics to a SaaS platform — semantic search over business data, natural language queries, trend detection, anomaly alerts, and AI-generated insights for dashboards. Covers embeddings, NL2SQL, and per-tenant analytics...
data-ai
Design AI-powered analytics dashboards — what metrics to show, how to display AI predictions and confidence, drill-down patterns, KPI cards, trend visualisation, AI Insights panels, export design, and role-based dashboard variants. Invoke when...
development
Use when designing, building, reviewing, or upgrading production software systems that must be secure, performant, maintainable, scalable, and user-centered. Apply before writing specs, code, architecture, APIs, databases, mobile apps, SaaS platforms, or ERP systems.
development
Professional web app UI using commercial templates (Tabler/Bootstrap 5) with strong frontend design direction when needed. Use for CRUD interfaces, dashboards, admin panels with SweetAlert2, DataTables, Flatpickr. Clone seeder-page.php, use...