saas-accounting-system
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseRequired Plugins
所需插件
Superpowers plugin: MUST be active for all work using this skill. Use throughout the entire build pipeline — design decisions, code generation, debugging, quality checks, and any task where it offers enhanced capabilities. If superpowers provides a better way to accomplish something, prefer it over the default approach.
Superpowers插件: 在使用本技能开展所有工作时必须激活。在整个构建流程中使用——包括设计决策、代码生成、调试、质量检查,以及任何它能提供增强能力的任务。如果Superpowers提供了更优的实现方式,请优先使用它而非默认方法。
SaaS Accounting System
SaaS会计系统
Overview
概述
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.
本技能可在业务应用中实现一个隐藏式会计引擎。终端用户无需查看借方、贷方或日记账分录——他们只需录入销售、记录付款、转移库存即可。在后台,每一笔交易都会自动生成平衡的日记账分录,会计师和审计人员可随时查询。
设计理念: 用户以业务视角操作,系统以复式记账逻辑运行。
Core Architecture
核心架构
┌─────────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────────┘┌─────────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────────┘The Golden Rule
黄金法则
Every transaction MUST produce balanced journal entries. No exceptions.
SUM(debits) = SUM(credits) — ALWAYSThis is enforced at the database level via stored procedure or trigger. If entries don't balance, the entire transaction rolls back.
每一笔交易必须生成平衡的日记账分录,无例外。
SUM(debits) = SUM(credits) — 始终成立这一规则通过数据库存储过程或触发器强制执行。如果分录不平衡,整个交易将回滚。
Chart of Accounts (COA)
会计科目表(COA)
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:
- Tenant gets a default COA on creation (seeded from template)
- Accounts are tenant-scoped ()
franchise_id - Accounts cannot be deleted if they have posted entries
- Sub-accounts supported (e.g., 1100 Cash → 1101 Petty Cash, 1102 Main Bank)
See:
references/chart-of-accounts.md会计科目表(COA)是系统的核心支柱。每个科目都有对应的类型,决定了它的正常余额方向。
| 类型 | 代码范围 | 正常余额方向 | 示例 |
|---|---|---|---|
| 资产 | 1000-1999 | 借方 | 现金、银行存款、应收账款、库存、设备 |
| 负债 | 2000-2999 | 贷方 | 应付账款、贷款、应交税费、预收收入 |
| 所有者权益 | 3000-3999 | 贷方 | 所有者权益、留存收益 |
| 收入 | 4000-4999 | 贷方 | 销售收入、服务收入、利息收入 |
| 销货成本(COGS) | 5000-5999 | 借方 | 销货成本、直接材料 |
| 费用 | 6000-6999 | 借方 | 租金、工资、水电费、营销费用 |
设置规则:
- 租户创建时会获取默认的COA(从模板导入)
- 科目按租户隔离(通过区分)
franchise_id - 已过账的科目无法删除
- 支持子科目(例如:1100 现金 → 1101 备用金、1102 主银行账户)
参考:
references/chart-of-accounts.mdAuto-Posting Rules
自动过账规则
Users never create journal entries manually. Every business transaction has a posting rule.
用户无需手动创建日记账分录。每一项业务交易都对应一套过账规则。
Transaction → Journal Entry Map
交易→日记账分录映射
| 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| 用户操作 | 借方科目 | 贷方科目 |
|---|---|---|
| 记录销售(发票) | 应收账款 | 销售收入 |
| 记录含税销售 | 应收账款+应收税费 | 销售收入+应交税费 |
| 收到付款(现金) | 现金/银行存款 | 应收账款 |
| 记录采购 | 库存/费用 | 应付账款 |
| 支付供应商货款 | 应付账款 | 现金/银行存款 |
| 记录费用 | 费用科目 | 现金/银行存款或应付账款 |
| 库存销售(结转销货成本) | 销货成本 | 库存 |
| 库存调整(+) | 库存 | 库存调整(收入类) |
| 库存调整(-) | 库存调整(费用类) | 库存 |
| 支付工资 | 工资费用 | 现金/银行存款 |
| 收到贷款 | 现金/银行存款 | 应付贷款 |
| 偿还贷款 | 应付贷款+利息费用 | 现金/银行存款 |
| 计提折旧 | 折旧费用 | 累计折旧 |
| 客户退款 | 销售退回 | 现金/银行存款或应收账款 |
多行分录: 一笔含税费和折扣的销售会生成3条以上的日记账分录行,且全部包含在同一笔分录中,该分录必须保持平衡。
参考:
references/journal-posting-rules.mdVoid & Reversal Mechanics
冲销与反转机制
Rule: Never delete a posted journal entry. Always create a reversing entry.
规则: 切勿删除已过账的日记账分录,始终创建反转分录。
Void Process
冲销流程
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 automatically1. 用户点击某笔交易的“冲销”按钮(例如:销售发票#1042)
2. 系统将原交易标记为已冲销(状态变更)
3. 系统自动生成一笔**反转日记账分录**:
- 使用相同科目,方向相反
- 备注:“REVERSAL of JE-{original_id}”
- 日期与原分录相同或使用当前日期(可配置)
4. 原分录与反转分录的净额为零
5. 所有子分类账余额自动更新Reversal Entry Example
反转分录示例
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原分录(销售发票#1042):
DR 应收账款 500.00
CR 销售收入 500.00
反转分录(冲销#1042):
DR 销售收入 500.00
CR 应收账款 500.00
净额影响:零Partial Void Rules
部分冲销规则
- Partially paid invoices: Void remaining balance only
- Payment already received: Must void payment first, then invoice
- Inventory already delivered: Must reverse stock movement first
- Cascade protection: System warns if dependent transactions exist
See:
references/void-reversal-patterns.md- 已部分付款的发票:仅冲销剩余余额
- 已收到付款的交易:必须先冲销付款,再冲销发票
- 已发货的库存交易:必须先反转库存变动
- 级联保护:若存在关联交易,系统将发出警告
参考:
references/void-reversal-patterns.mdDatabase Schema (Core Tables)
数据库架构(核心表)
sql
-- 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:
- and
journal_entry_lines.debit_amountare DECIMAL(15,2)credit_amount - CHECK constraint: Each line has debit OR credit, never both, never both zero
- Stored procedure validates SUM(debit) = SUM(credit) per entry
- on every table (multi-tenant isolation)
franchise_id - enum: DRAFT, POSTED, VOIDED
status
See:
references/schema-design.mdsql
-- 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)完整性约束:
- 和
journal_entry_lines.debit_amount为DECIMAL(15,2)类型credit_amount - CHECK约束:每一行分录只能有借方或贷方金额,不能同时存在,也不能均为零
- 通过存储过程验证每笔分录的借方总额等于贷方总额
- 所有表均包含(多租户隔离)
franchise_id - 枚举值:DRAFT(草稿)、POSTED(已过账)、VOIDED(已冲销)
status
参考:
references/schema-design.mdDual Reporting System
双轨制报告系统
User-Friendly Reports (Non-Accountant)
用户友好型报告(面向非会计人员)
| 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 |
| 报告 | 用户可见内容 | 数据源 |
|---|---|---|
| 销售汇总报告 | 按期间、客户、产品统计的销售总额 | 销售交易数据 |
| 未结清发票报告 | 欠款方及欠款账龄 | 应收账款子分类账 |
| 费用报告 | 按类别统计的支出情况 | 费用交易数据 |
| 简易利润表 | 收入减去费用 | 收入/费用科目 |
| 现金头寸报告 | 银行/现金账户余额 | 现金/银行科目 |
| 库存价值报告 | 现有库存及成本 | 库存子分类账 |
Accountant/Auditor Reports (Technical)
会计/审计人员报告(专业型)
| 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| 报告 | 展示内容 | 数据源 |
|---|---|---|
| 试算平衡表 | 所有科目的余额(借方/贷方列) | 总分类账 |
| 资产负债表 | 资产=负债+所有者权益 | 总分类账(类型1-3) |
| 利润表 | 收入-销货成本-费用=净利润 | 总分类账(类型4-6) |
| 现金流量表 | 经营活动+投资活动+筹资活动现金流 | 现金账户分录 |
| 总分类账明细 | 每个科目的所有分录 | 日记账分录 |
| 日记账登记簿 | 所有日记账分录的 chronological 记录 | 日记账分录 |
| 应收账款账龄报告 | 应收账款账龄(30/60/90/120天) | 应收账款子分类账 |
| 应付账款账龄报告 | 应付账款账龄 | 应付账款子分类账 |
| 审计追踪报告 | 过账人、过账时间及操作内容 | 日记账分录+审计日志 |
参考:
references/financial-statements.mdImplementation Checklist
实施 checklist
Phase 1: Foundation (Must Complete First)
阶段1:基础搭建(必须优先完成)
- Create table with COA seed data
accounts - Create and
journal_entriestablesjournal_entry_lines - Create table
fiscal_periods - Build balance validation stored procedure
- Build service function
postJournalEntry() - Write tests: balanced entry passes, unbalanced rejects
- 创建表并导入COA种子数据
accounts - 创建和
journal_entries表journal_entry_lines - 创建表
fiscal_periods - 构建余额验证存储过程
- 开发服务函数
postJournalEntry() - 编写测试:平衡分录通过验证,不平衡分录被拒绝
Phase 2: Auto-Posting Integration
阶段2:自动过账集成
- Wire sales invoice → auto-post AR/Revenue entry
- Wire payment received → auto-post Cash/AR entry
- Wire purchase → auto-post Inventory or Expense/AP entry
- Wire supplier payment → auto-post AP/Cash entry
- Wire inventory movement → auto-post COGS/Inventory entry
- Write tests: each transaction type posts correct entries
- 对接销售发票→自动过账应收账款/销售收入分录
- 对接收款→自动过账现金/应收账款分录
- 对接采购→自动过账库存或费用/应付账款分录
- 对接供应商付款→自动过账应付账款/现金分录
- 对接库存变动→自动过账销货成本/库存分录
- 编写测试:每种交易类型均生成正确的分录
Phase 3: Void & Reversal
阶段3:冲销与反转
- Build void transaction service (creates reversing entry)
- Handle partial void scenarios
- Handle cascade dependencies (warn before void)
- Write tests: void produces net-zero, balances correct
- 开发交易冲销服务(生成反转分录)
- 处理部分冲销场景
- 处理关联依赖(冲销前发出警告)
- 编写测试:冲销后净额为零,余额正确
Phase 4: Reporting
阶段4:报告系统
- Build Trial Balance report (all accounts, DR/CR totals)
- Build Balance Sheet (Assets = Liabilities + Equity)
- Build Income Statement (Revenue - Expenses)
- Build user-friendly summary reports
- Build audit trail report
- Write tests: reports match expected values from test data
- 构建试算平衡表报告(所有科目,借方/贷方总额)
- 构建资产负债表(资产=负债+所有者权益)
- 构建利润表(收入-费用)
- 构建用户友好型汇总报告
- 构建审计追踪报告
- 编写测试:报告数据与测试数据的预期值一致
Phase 5: Period Management
阶段5:期间管理
- Build period open/close functionality
- Prevent posting to closed periods
- Build year-end closing entry (Revenue/Expense → Retained Earnings)
- Write tests: closed period rejects entries
- 构建会计期间开闭功能
- 禁止向已关闭期间过账
- 构建年末结账分录(收入/费用→留存收益)
- 编写测试:已关闭期间拒绝接收分录
Cross-Skill Integration
跨技能集成
| Area | Skill | How It Applies |
|---|---|---|
| Database schema | | DECIMAL(15,2), indexes, FK constraints |
| API endpoints | | Consistent error responses for failed postings |
| Multi-tenancy | | franchise_id on all tables |
| UI reports | | DataTables for ledger, charts for P&L |
| Mobile reports | | Report screens with tables |
| PDF export | | Financial statement PDFs |
| Security | | Protect financial data, audit trail |
| Auth | | Permission: who can post/void/view reports |
| Inventory link | | COGS posting on stock movements |
| Testing | | Test every posting rule, every reversal |
| Implementation | | Execute accounting phases with TDD |
| Audit | | Verify accounting system completeness |
| 领域 | 技能 | 应用方式 |
|---|---|---|
| 数据库架构 | | 使用DECIMAL(15,2)、索引、外键约束 |
| API端点 | | 为过账失败场景提供一致的错误响应 |
| 多租户 | | 所有表均包含 |
| UI报告 | | 用DataTables展示分类账,用图表展示利润表 |
| 移动端报告 | | 开发带表格的报告界面 |
| PDF导出 | | 生成财务报表PDF |
| 安全 | | 保护财务数据,生成审计追踪 |
| 权限认证 | | 控制谁可以过账/冲销/查看报告 |
| 库存对接 | | 库存变动时自动过账销货成本 |
| 测试 | | 测试每一条过账规则和反转逻辑 |
| 实施规划 | | 用TDD方式执行会计系统各阶段开发 |
| 审计 | | 验证会计系统的完整性 |
Anti-Patterns
反模式
| 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.) |
| 禁止操作 | 正确做法 |
|---|---|
| 允许用户直接录入日记账分录 | 从业务交易自动过账 |
| 使用FLOAT类型存储金额 | 始终使用DECIMAL(15,2) |
| 删除日记账分录 | 创建反转分录(冲销) |
| 跳过余额验证 | 在存储过程中强制借方=贷方 |
| 仅存储计算后的余额 | 存储单个分录,按需计算余额 |
| 将会计逻辑与业务逻辑混合 | 将会计引擎作为独立服务层分离 |
| 硬编码科目代码 | 使用可配置的COA,支持租户自定义科目 |
| 跳过审计追踪 | 记录每一笔过账的用户、时间戳、IP地址 |
| 允许向已关闭期间过账 | 过账前检查会计期间状态 |
| 向终端用户展示借方/贷方 | 使用友好标签(如收入、付款等) |
Accuracy Guarantee
准确性保障
Every implementation MUST pass these tests:
- Balance test: = 0.00
SELECT SUM(debit) - SUM(credit) FROM journal_entry_lines - Entry test: Every journal entry has SUM(debit) = SUM(credit)
- Trial Balance test: Total debits = Total credits
- Balance Sheet test: Assets = Liabilities + Equity
- Reversal test: Voided transaction + reversal nets to zero
- Period test: No entries in closed periods
- Tenant test: No cross-tenant data leakage in any query
每一次实施必须通过以下测试:
- 余额测试: = 0.00
SELECT SUM(debit) - SUM(credit) FROM journal_entry_lines - 分录测试: 每笔日记账分录的借方总额等于贷方总额
- 试算平衡表测试: 借方总额=贷方总额
- 资产负债表测试: 资产=负债+所有者权益
- 反转测试: 已冲销交易+反转分录的净额为零
- 期间测试: 已关闭期间无任何分录
- 租户测试: 任何查询均不会出现跨租户数据泄露
See Also
—
- — COA templates and setup
references/chart-of-accounts.md - — Complete posting rules per transaction
references/journal-posting-rules.md - — Void mechanics and edge cases
references/void-reversal-patterns.md - — Report SQL queries and formats
references/financial-statements.md - — Complete database schema with constraints
references/schema-design.md
—