Skip to content

Getting Started

Welcome to the Keshless Accounting System documentation. This guide will help you understand and integrate the double-entry bookkeeping system into your fintech application.

What is the Keshless Accounting System?

A complete ACID-compliant double-entry bookkeeping system built specifically for the Keshless fintech application. Every financial transaction creates balanced journal entries with immutable audit trails, ensuring regulatory compliance and accurate financial records.

Key Features

  • ACID Compliance - All operations wrapped in PostgreSQL transactions with automatic rollback on failures
  • Double-Entry Bookkeeping - Every transaction creates balanced debit/credit pairs following accounting principles
  • Immutability - Posted ledger entries cannot be modified, only reversed through proper accounting procedures
  • Tamper-Proof Audit Trail - Complete logging with SHA-256 hash chaining to detect any tampering
  • Pending/Posted Workflow - Validate transactions for 30 minutes before finalization
  • Automated Reconciliation - Daily balance verification at 2 AM to ensure wallet balances match ledger
  • Financial Reports - Trial balance, account statements, and P&L reports ready out of the box

System Components

Models (6)

  • ChartOfAccounts - Hierarchical account structure (Assets, Liabilities, Equity, Revenue, Expenses)
  • JournalEntry - Groups related ledger entries with workflow status (PENDING/POSTED/REVERSED)
  • LedgerEntry - Individual debit/credit records (immutable once posted)
  • AccountBalance - Performance cache with reconciliation tracking
  • Reconciliation - Audit reconciliation records with discrepancy detection
  • AuditLog - Tamper-proof audit trail with hash chaining

Services (7)

  • chartOfAccountsService - Manage chart of accounts
  • transactionTemplatesService - 10+ predefined double-entry patterns
  • ledgerService - ACID-compliant journal/ledger operations
  • postingService - Pending → Posted workflow management
  • balanceVerificationService - Reconciliation logic
  • trialBalanceService - Financial reporting
  • statementService - Account statements generation

Jobs (1)

  • dailyReconciliation - Automated reconciliation runs at 2 AM daily

Currency

All amounts are in E (Emalageni) - the system is locked to this currency only. No multi-currency support.

Quick Start

1. Initialize the System

Run this once on server startup to seed the chart of accounts and verify system integrity:

typescript
import { initializeAccountingSystem } from './utils/initializeAccounting';

// Run once on server startup
await initializeAccountingSystem();

This will:

  • Seed 25+ standard accounts to Chart of Accounts
  • Verify audit log integrity
  • Display system status in console

2. Your First Transaction: P2P Transfer

Here's how to create a peer-to-peer transfer between two users:

typescript
import { ledgerService, transactionTemplatesService } from './services/accounting';

// Step 1: Create transfer template
const template = transactionTemplatesService.getUserTransferTemplate(
  senderId,     // User sending money
  recipientId,  // User receiving money
  100,          // Amount (E100)
  'REF-12345'   // Optional reference
);

// Step 2: Create journal entry (ACID transaction - POSTED immediately)
const { journal, ledgerEntries } = await ledgerService.createJournalEntry(template, {
  walletTransactionId: walletTxn._id,
  actorId: senderId,
  ipAddress: req.ip,
  requestId: req.id,
  // autoPost defaults to true (industry standard - immediate posting)
  // Only set to false for flagged/high-risk transactions requiring manual review
});

console.log(`✅ Journal ${journal.journalId} created with ${ledgerEntries.length} entries`);

What happens behind the scenes:

  1. Debit: User A's wallet account (asset) decreases by E100
  2. Credit: User B's wallet account (asset) increases by E100
  3. Both entries are created atomically in a PostgreSQL transaction
  4. Entries are immediately POSTED (finalized) - industry standard
  5. User B can spend the money instantly
  6. An audit log entry is created with hash chaining

3. Example: Vendor Payment with Fee

When a user pays a vendor and Keshless charges a transaction fee:

typescript
const template = transactionTemplatesService.getUserPaymentTemplate(
  userId,      // User paying
  vendorId,    // Vendor receiving
  95,          // Payment amount (E95)
  5,           // Fee (E5)
  'PAY-789'    // Reference
);

const { journal } = await ledgerService.createJournalEntry(template, {
  walletTransactionId: walletTxn._id,
  actorId: userId,
  autoPost: false, // Exception: High-value payment requires manual review
  amlStatus: 'flagged', // Mark for compliance team review
});

// Later, manually post it after compliance review
await postingService.postEntry(journal.journalId, {
  postedBy: adminId,
  notes: 'Compliance verified - approved',
});

What happens behind the scenes:

  1. Debit: User wallet account decreases by E100 (95 + 5)
  2. Credit: Vendor wallet account increases by E95
  3. Credit: Fee revenue account increases by E5
  4. Total debits (E100) = Total credits (E95 + E5) ✅
  5. Entry is PENDING (exception) awaiting compliance review
  6. User and vendor balances are updated immediately regardless

Workflow States

Journal entries follow this lifecycle:

POSTED (default 95%+) → [REVERSED if correction needed]

PENDING (exception <5%) → POSTED or CANCELLED
  • POSTED (default): Entry finalized immediately and immutable - industry standard
  • PENDING (exception): High-risk/flagged entries awaiting manual review
  • REVERSED: Posted entry corrected with offsetting entry (original remains intact)
  • CANCELLED: Pending entry rejected before posting

Next Steps

Need Help?

Check the Troubleshooting Guide for common issues and solutions.

Internal use only - Keshless Payment Platform