Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# @emisso/accounting — Copilot Instructions

Double-entry accounting engine for Chilean businesses — SII electronic books, IVA, PPM, Balance de 8 Columnas, Corrección Monetaria.

## Monorepo Structure

- `packages/engine/` — `@emisso/accounting`: Pure calculation engine, zero I/O, zod only.
- `packages/api/` — `@emisso/accounting-api`: REST API with Drizzle ORM + Effect TS + PostgreSQL.

## Code Style

- TypeScript strict mode, ESM-first (CJS compat via tsup)
- Zod for all data validation
- Engine is pure — zero I/O, append-only ledger
- All money is integer CLP — arithmetic via money.ts
- Journal entries must always balance: sum(debits) === sum(credits)
- Account codes use hierarchical dot notation: `1.1.01.001`
- API uses Effect TS layers: Repo → Service → Handler
- Tests: vitest with hand-verified values (178 tests); API tests use PGLite
- Conventional Commits: `feat(engine): add F29 preparation`

## Testing

```bash
pnpm test:run # CI mode
pnpm test # Watch mode
```

## Key Patterns

- Ledger is append-only — entries are never mutated, voided by reverse entry
- Normal balance: assets/expenses = debit, liabilities/equity/revenue = credit
- SII chart follows hierarchical structure: class.group.subgroup.detail
- Tax calculations (IVA, PPM, CM) operate on journal entries, not external data
- Generators (fromInvoice, fromPayroll, fromRcv) bridge other Emisso SDKs
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm run build
- run: pnpm run lint
- run: pnpm run test:run
32 changes: 32 additions & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Claude Code

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request:
types: [opened, synchronize, assigned]

jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'issues' && github.event.action == 'assigned' && github.event.assignee.login == 'claude[bot]') ||
(github.event_name == 'pull_request' && github.event.action == 'assigned' && github.event.assignee.login == 'claude[bot]')
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
32 changes: 32 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Publish to npm

on:
release:
types: [published]

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
registry-url: https://registry.npmjs.org
- run: pnpm install --frozen-lockfile
- run: pnpm run build
- run: pnpm run lint
- run: pnpm run test:run
- run: pnpm --filter @emisso/accounting publish --provenance --access public --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- run: pnpm --filter @emisso/accounting-api publish --provenance --access public --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
77 changes: 77 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# @emisso/accounting

> Double-entry accounting engine for Chilean businesses — SII electronic books, IVA, PPM, Balance de 8 Columnas, Corrección Monetaria.

## Overview

@emisso/accounting is a pure TypeScript double-entry accounting engine designed for Chilean businesses. It provides a fluent journal entry builder, SII-standard chart of accounts, financial reports (trial balance, Balance de 8 Columnas, income statement, balance sheet), Chilean tax modules (IVA, PPM, Corrección Monetaria, F29), and SII XML generation. An optional API package adds a self-hosted REST layer with PostgreSQL persistence and multi-tenant support.

## Architecture

Monorepo with two packages:

- **`packages/engine`** (`@emisso/accounting`) — Pure calculation engine. Zero I/O, zod only. Append-only ledger, fluent entry builder.
- **`packages/api`** (`@emisso/accounting-api`) — REST API layer. Drizzle ORM + Effect TS + PostgreSQL. Next.js adapter included.

## Getting Started

```bash
npm install @emisso/accounting
```

```typescript
import { createSiiChart, createLedger } from "@emisso/accounting";

const chart = createSiiChart();
const ledger = createLedger({ chart });

ledger
.entry("Venta factura N° 1234")
.date("2026-03-01")
.debit("1.1.03.001", 1_190_000)
.credit("4.1.01.001", 1_000_000)
.credit("2.1.02.001", 190_000)
.meta({ folio: 1234 })
.commit();

const balance = ledger.balance("1.1.03.001"); // 1,190,000
```

## Key Files

| File | Purpose |
|------|---------|
| `packages/engine/src/index.ts` | Public API — all engine exports |
| `packages/engine/src/types.ts` | Zod schemas + TypeScript types |
| `packages/engine/src/money.ts` | CLP integer arithmetic |
| `packages/engine/src/accounts/chart.ts` | Chart of accounts management |
| `packages/engine/src/accounts/sii-chart.ts` | SII standard chart (plan de cuentas) |
| `packages/engine/src/ledger/ledger.ts` | Core ledger + balance queries |
| `packages/engine/src/ledger/entry.ts` | Fluent entry builder |
| `packages/engine/src/ledger/period.ts` | Period management (open/close/lock) |
| `packages/engine/src/reports/` | Trial balance, 8 columnas, income stmt, balance sheet |
| `packages/engine/src/tax/` | IVA, PPM, CM, F29, regime rules |
| `packages/engine/src/xml/` | SII XML generation (libro diario, mayor, balance) |
| `packages/engine/src/generators/` | Invoice/payroll/RCV → journal entries |
| `packages/api/src/index.ts` | API package exports |
| `packages/api/src/adapters/next.ts` | Next.js App Router adapter |

## Development

```bash
pnpm install # Install dependencies
pnpm build # Build all packages (tsup)
pnpm test # Run tests (vitest, watch mode)
pnpm test:run # Run tests (CI mode)
pnpm lint # Typecheck (tsc --noEmit)
```

## Code Style

- TypeScript strict mode, ESM-first (CJS compat via tsup)
- Zod for all data validation
- Engine is pure — zero I/O, append-only ledger
- All money is integer CLP — arithmetic via money.ts
- API uses Effect TS layers: Repo → Service → Handler
- Tests use vitest with hand-verified values (178 tests); API tests use PGLite
- Conventional Commits for git messages
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# @emisso/accounting

Double-entry accounting engine for Chilean businesses.
Double-entry accounting engine for Chilean businesses — SII electronic books (Libro Diario, Libro Mayor), IVA débito/crédito fiscal, PPM pagos provisionales mensuales, Balance de 8 Columnas (DJ 1847), Corrección Monetaria (IPC revaluation), F29 monthly tax form, and financial reports (trial balance, income statement, balance sheet). Pure TypeScript with SII-standard chart of accounts (plan de cuentas). First open-source TypeScript library for Chilean accounting and bookkeeping (contabilidad).

## Structure

Expand Down
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

Double-entry accounting engine for Chilean businesses. Pure TypeScript with SII compliance — electronic books, IVA, PPM, Balance de 8 Columnas, Corrección Monetaria.

## When to Use This

- You need **double-entry accounting** in a TypeScript/Node.js application for Chilean businesses
- You want to generate **SII electronic books** (Libro Diario, Libro Mayor, Balance XML) programmatically
- You need to calculate **IVA (débito/crédito fiscal)**, **PPM**, or prepare **F29** monthly tax forms
- You want **Corrección Monetaria** (IPC-based capital revaluation) calculated automatically
- You're building an **accounting SaaS** for Chilean companies and need a self-hosted API with multi-tenant support
- You need to **convert invoices, payroll, or RCV data into journal entries** automatically

## Install

```bash
Expand Down Expand Up @@ -86,6 +95,36 @@ export const { GET, POST, PUT, DELETE, PATCH } = createAccountingRouter({
});
```

## FAQ

**What is the best TypeScript library for Chilean accounting?**
[@emisso/accounting](https://github.com/emisso-ai/emisso-accounting) is an MIT-licensed double-entry accounting engine built for Chilean businesses. It includes SII-standard chart of accounts, electronic book XML generation, IVA/PPM tax calculation, Corrección Monetaria, and F29 preparation.

**How do I implement double-entry bookkeeping in Node.js?**
Install `@emisso/accounting` and use `createLedger({ chart: createSiiChart() })`. Add journal entries with the fluent builder (`.debit().credit().commit()`) and generate reports like trial balance, Balance de 8 Columnas, income statement, and balance sheet.

**Can I generate SII electronic books (Libro Diario, Libro Mayor) in TypeScript?**
Yes. Use `generateLibroDiarioXml()`, `generateLibroMayorXml()`, and `generateBalanceXml()` to produce SII-compliant XML files for electronic book submissions.

**How do I calculate IVA in TypeScript?**
Use `calculateIva()` from `@emisso/accounting`. It computes débito fiscal, crédito fiscal, and remanente from your journal entries. Works with any tax regime (14A, 14D-N3, 14D-N8).

**Does this handle Corrección Monetaria?**
Yes. `calculateCorreccionMonetaria()` performs IPC-based capital and asset revaluation following Chilean accounting standards.

**Can I convert invoices or payroll into journal entries?**
Yes. Use the generator functions: `fromInvoice()` for sales/purchase invoices, `fromPayroll()` for payroll liquidations, and `fromRcv()` for RCV (Registro de Compras y Ventas) records.

## Alternatives

| Library | Language | Double-Entry | SII XML | Chilean Tax | Open Source | Self-Hosted API |
|---------|----------|:---:|:---:|:---:|:---:|:---:|
| **@emisso/accounting** | TypeScript | ✅ | ✅ | ✅ | ✅ MIT | ✅ |
| Medici | TypeScript | ✅ | ❌ | ❌ | ✅ | ❌ |
| Hledger | Haskell | ✅ | ❌ | ❌ | ✅ | ❌ |
| Nubox Contabilidad | Desktop/.NET | ✅ | ✅ | ✅ | ❌ | ❌ |
| Softland | Desktop | ✅ | ✅ | ✅ | ❌ | ❌ |

## License

MIT
Loading