Skip to content

Audit Trail & Controls

PinkApple maintains a complete, immutable audit trail of every financial action in the system. This page explains how the system tracks changes, prevents unauthorised modifications, and supports external audit requirements.

Activity Log

Every action that creates, modifies, or deletes financial data is recorded in the activity_log table. This log is:

  • Append-only — Records cannot be edited or deleted by any user
  • Automatic — Logged by stored procedures, not application code (cannot be bypassed)
  • Timestamped — Server-side created_at using database clock (not client time)

What Is Logged

FieldContent
ActionOperation type (CREATE, UPDATE, DELETE, APPROVE, REJECT, POST, VOID, REVERSE, FX_REVALUATION, IC_ELIMINATION, etc.)
Table NameThe database table affected
Record IDPrimary key of the affected record
Old ValueJSON snapshot of the record before the change (for updates)
New ValueJSON snapshot of the record after the change
Changed ByUser ID of the person who performed the action
Business UnitWhich BU the action was performed in
IP AddressClient IP address at the time of action
User AgentBrowser/device identifier
Batch NumberGroups related actions together (e.g., all lines in a journal entry share a batch)
StatusFINAL, PENDING, REVERSED, etc.

Querying the Audit Trail

Authorised users can view the activity log filtered by:

  • Date range
  • User
  • Action type
  • Entity (GL_JOURNAL_ENTRY, FISCAL_PERIOD, BUDGET, etc.)
  • Business unit

Immutability Guarantees

Posted Journal Entries Cannot Be Deleted

Once a journal entry has posted_flag = 1:

  • It cannot be physically deleted from the database
  • It cannot have its amounts or accounts changed
  • The only way to undo it is via a reversal journal — a new entry with equal and opposite amounts that references the original

Reversal Mechanism

When an entry needs to be corrected:

  1. A new journal entry is created with inverted debits/credits
  2. The original entry gets reversed_flag = 1 and reversed_entry_id pointing to the correction
  3. Both entries remain visible in the ledger permanently
  4. The activity log records who reversed it and why

Void Flag

Entries that were created in error (before posting) can be voided:

  • voided_flag = 1 marks the entry as void
  • Voided entries remain in the database but are excluded from all balance calculations
  • The void action is logged in the activity log

Source Type Classification

Every journal entry carries a source_type that identifies how it was created:

Source TypeOrigin
BACKOFFICEManual journal entry by an accountant
LOANLoan disbursement, repayment, or fee
DEPOSITDeposit account transaction
DRIVINGDriving school payment
SHARESShare capital transaction
FX_REVALUATIONAutomated FX revaluation at period end
IC_ELIMINATIONIntercompany elimination entry
RECURRING_TEMPLATEScheduled recurring journal
PLATFORM_CASH_COMMISSIONPlatform commission posting
REVERSALReversal of a prior entry

This allows auditors to immediately identify system-generated vs. manual entries.

Period Controls

Period State Machine

Fiscal periods follow a strict lifecycle that prevents back-posting:

NOT_OPENED → OPEN → SOFT_CLOSED → HARD_CLOSED → LOCKED
StateWho Can PostAuditor Implication
NOT_OPENEDNobodyFuture period, no transactions possible
OPENAuthorised usersNormal operations
SOFT_CLOSEDControllers only (designated users)Month-end adjustments window
HARD_CLOSEDNobodyPeriod finalised, no changes allowed
LOCKEDNobody, everRegulatory retention, completely immutable

Backdating Controls

The system enforces:

  • Maximum posting lag — Configurable number of days a transaction can be backdated
  • Future posting restriction — Can be disabled entirely via GL_ALLOW_FUTURE_POSTING
  • Adjustment periods — Period 13/14/15/16 exist specifically for post-close audit adjustments, accessible only with elevated permissions

Period Close Audit Trail

Every period state change (open, close, reopen) is recorded in:

  • bu_period_audit — Who changed the state, when, from what state to what state, with notes
  • activity_log — Standard audit entry

Data Retention

Balance Integrity

  • Daily balances are captured at 10 levels (COA, header, major, foundation, sub-ledger × daily/monthly)
  • Period-end snapshots are captured in fiscal_period_balance_snapshot at the time of close
  • These snapshots are immutable and serve as the point-in-time reference for financial statements

No Physical Deletion

The system does not physically delete financial records. All "deletions" in the GL domain are soft:

  • Journal entries: voided, never deleted
  • Sub-ledgers: deactivated (is_active = 0), never dropped
  • COA accounts: deactivated, never removed from the hierarchy
  • Budget records: versioned, never overwritten

Segregation of Duties

The permission system enforces separation between:

ActionRequired PermissionCannot Overlap With
Create journal entryCREATE_GL_JOURNAL_ENTRYApprove journal entry
Approve journal entryAPPROVE_GL_JOURNAL_ENTRYCreate journal entry
Post journal entryPOST_GL_JOURNAL_ENTRY
Close fiscal periodCLOSE_FISCAL_PERIODReopen fiscal period
Run FX revaluationRUN_FX_REVALUATION
Modify budgetsCREATE_BUDGET / UPDATE_BUDGETApprove budgets

Authority Limits

GL posting approval policies can enforce monetary thresholds:

  • Entries below a threshold: auto-approved
  • Entries above a threshold: routed through multi-step approval chain
  • Each step in the chain requires a different user (same user cannot approve their own entry)

System Integrity Checks

Sub-Ledger ↔ Control Account Reconciliation

At every period close, the system automatically verifies:

SUM(all sub-ledger balances for a COA) = COA control account balance

If this check fails, the period cannot be closed until the discrepancy is resolved.

Balanced Entry Enforcement

The GL posting engine validates at the point of posting:

  • Total debits must equal total credits (to the cent)
  • Unbalanced entries are rejected with an error — they never reach the ledger
  • This is enforced in the database layer (stored procedure), not the application layer

Cash Balance Enforcement

Accounts tagged as CASH_FAMILY have additional controls:

  • The system checks the current balance before posting a credit
  • If the credit would make the balance negative, the posting is blocked
  • This prevents overdrafts on cash accounts

Next Steps

PinkApple ERP by Stat Solutions Network