Immutable Ledger System

DoorStax maintains an append-only financial ledger that records every monetary event with full audit trail and automatic reconciliation.

Design Principles

The ledger is the financial source of truth for every property, unit, and tenant in DoorStax. It is designed around three core principles:

Append-Only

Entries are never modified or deleted. New entries are always appended.

Locked Entries

Once written, a ledger entry is immutable. Its fields cannot be changed.

Compensating Adjustments

Corrections are made by adding new offsetting entries, not editing existing ones.

Entry Types

Every ledger entry has a type that categorizes the nature of the transaction.

TypeDirectionDescription
CHARGEDebit (+)Rent, late fees, or other charges owed by tenant
PAYMENTCredit (-)Payment received from tenant
REVERSALCredit (-)Reversal of a previous charge (compensating entry)
ADJUSTMENTEitherManual correction — debit or credit as needed

Running Balance Calculation

Each ledger entry stores a runningBalance field that is computed at write time. The balance for a lease is the sum of all entry amounts in chronological order:

Balance Formula
runningBalance = previousBalance + amount

Where:
  CHARGE     →  amount > 0  (increases balance owed)
  PAYMENT    →  amount < 0  (decreases balance owed)
  REVERSAL   →  amount < 0  (decreases balance owed)
  ADJUSTMENT →  amount ≷ 0  (either direction)

A running balance of 0 means the tenant is fully paid up. A positive balance means the tenant owes money. A negative balance means a credit exists on the account.

LedgerEntry Field Reference

FieldTypeDescription
idStringUnique identifier (cuid)
leaseIdStringAssociated lease
unitIdStringAssociated unit
tenantIdString?Associated tenant (nullable for charges)
typeEntryTypeCHARGE | PAYMENT | REVERSAL | ADJUSTMENT
amountDecimalSigned amount in cents
runningBalanceDecimalBalance after this entry
descriptionStringHuman-readable description
referenceIdString?Links to a payment or charge record
referenceTypeString?Type of referenced record (payment, charge, etc.)
metadataJson?Arbitrary metadata
createdAtDateTimeTimestamp of entry creation
createdByIdStringUser who created this entry
isLockedBooleanAlways true after creation

Example Flow

Here is a typical sequence for a monthly rent cycle:

1

Rent Charge Created

CHARGE of +$1,500.00 — running balance: $1,500.00

2

Tenant Payment Received

PAYMENT of -$1,500.00 — running balance: $0.00

3

Late Fee (if payment was late)

CHARGE of +$50.00 — running balance: $50.00

4

Late Fee Waived

REVERSAL of -$50.00 — running balance: $0.00

Ledger Entry Example
{
  "id": "led_abc123",
  "leaseId": "lea_xyz789",
  "unitId": "unt_456",
  "tenantId": "tnt_012",
  "type": "PAYMENT",
  "amount": -150000,
  "runningBalance": 0,
  "description": "Rent payment for January 2025",
  "referenceId": "pay_def456",
  "referenceType": "payment",
  "createdAt": "2025-01-05T10:30:00.000Z",
  "createdById": "usr_tnt012",
  "isLocked": true
}

Audit Trail

Every ledger entry is linked to the user who created it via createdById. When a payment triggers a ledger entry, the referenceId links back to the originating payment record, creating a complete audit chain.

Because entries are immutable, the full history of every financial event is preserved and can be audited at any time. Reversals and adjustments maintain explicit references to the entries they compensate.

Reconciliation

DoorStax runs an automated reconciliation cron job that:

  • Verifies running balances match the sum of all entries per lease
  • Cross-references ledger entries with payment processor records (Kadima)
  • Flags discrepancies for manual review
  • Generates reconciliation reports for accounting teams

Note: The reconciliation cron runs daily at 2:00 AM UTC. Discrepancies are surfaced in the admin dashboard and via email notifications to accountants.