Skip to content

Latest commit

 

History

History
524 lines (393 loc) · 13.5 KB

File metadata and controls

524 lines (393 loc) · 13.5 KB

Reconciliation Worker Implementation Guide

Overview

Open-Audit now includes a comprehensive Reconciliation Worker that:

  1. Detects Data Gaps — Identifies missing events due to network failures, database deadlocks, or maintenance windows
  2. Verifies Data Integrity — Compares local database events with the authoritative Stellar RPC source
  3. Auto-Repairs — Automatically reindexes missing or corrupted events (optional)
  4. Maintains Audit Trail — Records all reconciliation actions for compliance and oversight
  5. Runs Automatically — Executes on a configurable daily cron schedule or on-demand

Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│                   Open-Audit System                          │
├─────────────────────────────────────────────────────────────┤
│                                                               │
│  PostgreSQL Database                                          │
│  ├── events (persisted with reconciliation metadata)          │
│  ├── reconciliation_jobs (job history & status)              │
│  ├── audit_logs (complete audit trail)                       │
│  └── reconciliation_config (configuration)                   │
│                                                               │
│  Redis + Bull Queue                                           │
│  └── Async job processing & retry logic                      │
│                                                               │
│  Reconciliation Engine                                        │
│  ├── Comparator (DB vs RPC comparison)                       │
│  ├── Auditor (audit trail recording)                         │
│  └── Scheduler (cron-based job triggering)                   │
│                                                               │
│  API Endpoints                                                │
│  ├── /api/health (system health)                             │
│  ├── /api/reconciliation/status (job status)                 │
│  ├── /api/reconciliation/trigger (manual trigger)            │
│  ├── /api/reconciliation/config (configuration)              │
│  ├── /api/reconciliation/history (job history)               │
│  └── /api/reconciliation/report/[jobId] (detailed reports)   │
│                                                               │
└─────────────────────────────────────────────────────────────┘

Setup Instructions

1. Install Dependencies

All necessary packages are already added to package.json:

npm install

Key packages:

  • @prisma/client — ORM for database
  • bull — Redis-based job queue
  • ioredis — Redis client
  • node-cron — Cron scheduling
  • pino — Structured logging

2. Database Setup

Option A: PostgreSQL (Production)

# Update .env.local
DATABASE_URL=postgresql://user:password@localhost:5432/openaudit

# Run migrations
npm run db:migrate

Option B: SQLite (Development)

# Update .env.local
DATABASE_URL=file:./dev.db

# Run migrations
npm run db:migrate

3. Redis Setup (Required for Job Queue)

# Start Redis locally
redis-server

# Or using Docker
docker run -d -p 6379:6379 redis:latest

# Update .env.local
REDIS_URL=redis://localhost:6379

4. Seed Database

npm run db:seed

This creates the default reconciliation configuration.

5. Start the Application

# Development with hot reload
npm run dev

# Production
npm run build
npm start

Configuration

Edit reconciliation settings in the database or via the API:

# Via API (GET current config)
curl http://localhost:3000/api/reconciliation/config

# Via API (UPDATE config)
curl -X PUT http://localhost:3000/api/reconciliation/config \
  -H "Content-Type: application/json" \
  -d '{
    "cronSchedule": "0 2 * * *",
    "lookbackDays": 7,
    "autoFix": false,
    "alertThreshold": 0.1
  }'

Configuration Options

Option Default Description
cronSchedule 0 2 * * * Cron schedule for daily reconciliation (2 AM UTC)
batchSize 1000 Number of events to process per batch
lookbackDays 7 Number of days to reconcile
autoFix false Automatically reindex missing events
alertThreshold 0.1 Alert if discrepancies > 0.1%
enabled true Enable/disable reconciliation

API Usage

Check System Health

curl http://localhost:3000/api/health

Response:

{
  "status": "healthy",
  "database": {
    "connected": true,
    "totalEvents": 45230,
    "verifiedEvents": 45215,
    "pendingVerification": 15,
    "verificationRate": "99.97%"
  },
  "indexer": {
    "lastLedger": 50000000
  },
  "timestamp": "2026-06-19T14:32:00Z"
}

Get Reconciliation Status

curl http://localhost:3000/api/reconciliation/status

Manually Trigger Reconciliation

curl -X POST http://localhost:3000/api/reconciliation/trigger \
  -H "Content-Type: application/json" \
  -d '{
    "startLedger": 49500000,
    "endLedger": 50000000,
    "autoFix": false
  }'

View Reconciliation History

curl "http://localhost:3000/api/reconciliation/history?limit=10&offset=0"

Get Detailed Report

curl "http://localhost:3000/api/reconciliation/report/[jobId]"

# Get as HTML
curl "http://localhost:3000/api/reconciliation/report/[jobId]?format=html"

How It Works

Automatic Reconciliation (Cron)

  1. Scheduled Trigger — Runs daily at 2 AM UTC (configurable)
  2. Ledger Range Calculation — Determines which ledgers to reconcile based on lookbackDays
  3. Queue Job — Adds reconciliation job to Bull queue
  4. Process Job — Bull worker processes the job with retry logic
  5. Compare Data — Compares local DB with Stellar RPC
  6. Detect Discrepancies — Identifies gaps and mismatches
  7. Record Audit Trail — Logs all findings
  8. Auto-Repair (Optional) — Reindexes missing events if enabled
  9. Report — Generates summary report

Manual Reconciliation

# Trigger a manual reconciliation for a specific ledger range
curl -X POST http://localhost:3000/api/reconciliation/trigger \
  -H "Content-Type: application/json" \
  -d '{
    "startLedger": 1000000,
    "endLedger": 1010000,
    "contractIds": ["CABC001"],
    "autoFix": true
  }'

Discrepancy Detection

The reconciliation system detects:

  1. Missing Events — Events in RPC but not in local database
  2. Extra Events — Events in database not found in RPC (possible re-org)
  3. Data Mismatches — Event data doesn't match between DB and RPC
  4. Corruption — Hash mismatches indicating data corruption

Audit Trail

Every reconciliation action is logged:

// Example audit log entry
{
  jobId: "1000-2000-1234567890",
  action: "detected",           // "detected" | "fixed" | "flagged" | "verified"
  eventId: "event-12345",
  ledger: 1500,
  details: {
    issue: "Event missing from local database",
    action: "reindex"
  },
  createdAt: "2026-06-19T14:32:00Z"
}

Acceptance Criteria Validation

✅ Criterion 1: Detect Artificially Deleted Records

The system accurately detects when database records are deleted:

# 1. Artificially delete an event
DELETE FROM events WHERE id = 'event-12345';

# 2. Trigger reconciliation
curl -X POST http://localhost:3000/api/reconciliation/trigger \
  -d '{"startLedger": 1000, "endLedger": 2000}'

# 3. Check the report
curl http://localhost:3000/api/reconciliation/report/[jobId]

# Response includes:
{
  "discrepancies": [
    {
      "eventId": "event-12345",
      "issue": "Event missing from local database",
      "action": "reindex"
    }
  ]
}

✅ Criterion 2: Clear Audit Trail

Every action is logged for administrator oversight:

# Get audit logs for a job
curl http://localhost:3000/api/reconciliation/report/[jobId]

# Response includes audit timeline:
{
  "timeline": [
    {
      "timestamp": "2026-06-19T14:30:00Z",
      "action": "detected",
      "eventId": "event-12345",
      "ledger": 1500,
      "details": {...}
    },
    {
      "timestamp": "2026-06-19T14:31:00Z",
      "action": "fixed",
      "eventId": "event-12345",
      "ledger": 1500,
      "details": {...}
    }
  ]
}

Testing

Run the comprehensive test suite:

npm test

# Watch mode
npm run test:watch

Tests cover:

  • ✓ Detecting missing events
  • ✓ Detecting data integrity mismatches
  • ✓ Recording audit trails
  • ✓ Database persistence
  • ✓ Event verification

Database Maintenance

View Events

-- Check total events
SELECT COUNT(*) as total_events FROM events;

-- Check verified events
SELECT COUNT(*) as verified_events FROM events WHERE rpc_verified = true;

-- Check events with discrepancies
SELECT * FROM events WHERE discrepancies IS NOT NULL;

Cleanup Old Data

# Archived old events (before a date)
# This is handled via the API in production

Database Migrations

# Create new migration
npm run db:migrate

# Reset database (DEV ONLY)
npx prisma migrate reset

Troubleshooting

Redis Connection Failed

# Check if Redis is running
redis-cli ping

# Should return: PONG

# If not running, start it
redis-server

Database Connection Failed

# Verify DATABASE_URL in .env.local
# Check database server is running
# Verify credentials

# Test connection
npx prisma db execute --stdin << 'EOF'
SELECT 1;
EOF

Queue Not Processing

# Check queue status
curl http://localhost:3000/api/reconciliation/status

# Verify Bull worker is running
# Check logs for worker errors

Reconciliation Job Stuck

# Get job status
curl http://localhost:3000/api/reconciliation/status

# Manual trigger new job
curl -X POST http://localhost:3000/api/reconciliation/trigger \
  -d '{"startLedger": ..., "endLedger": ...}'

Performance Considerations

  • Batch Size — Process events in chunks of 1000 (configurable)
  • Concurrency — Queue processes 5 jobs concurrently (configurable)
  • Lookback Days — Reconcile 7 days of history by default
  • Retry Logic — Automatic exponential backoff for failures

For large event volumes:

  1. Increase QUEUE_CONCURRENCY (default: 5)
  2. Decrease lookbackDays or schedule more frequent reconciliations
  3. Use database indexing on (ledger, contractId)

File Structure

lib/
├── db/
│   ├── client.ts              # Prisma client setup
│   └── utils.ts               # Database utilities
├── jobs/
│   └── queue.ts               # Bull queue configuration
├── reconciliation/
│   ├── engine.ts              # Main reconciliation logic
│   ├── comparator.ts          # DB vs RPC comparison
│   ├── auditor.ts             # Audit trail logging
│   ├── scheduler.ts           # Cron scheduler
│   └── reconciliation.test.ts # Comprehensive tests
├── translator/
│   └── persistence.ts         # Event translation & persistence
└── stellar/
    └── indexer-persistent.ts  # Persistent indexer wrapper

app/api/
├── health/route.ts            # System health endpoint
└── reconciliation/
    ├── status/route.ts        # Job status
    ├── trigger/route.ts       # Manual trigger
    ├── config/route.ts        # Configuration
    ├── history/route.ts       # Job history
    └── report/[jobId]/route.ts  # Detailed reports

prisma/
├── schema.prisma              # Database schema
└── seed.ts                    # Database seeding

Next Steps

  1. Deploy Database — Set up PostgreSQL in your environment
  2. Configure Redis — Start Redis for job queue
  3. Run Migrationsnpm run db:migrate
  4. Start Applicationnpm run dev or npm start
  5. Verify Healthcurl http://localhost:3000/api/health
  6. Monitor Reconciliation — Check reconciliation status regularly

Support

For issues or questions:

  1. Check logs: tail -f logs/reconciliation.log
  2. Review database state: Use prisma studio
  3. Test manually: Use provided curl examples
  4. Review tests: lib/reconciliation/reconciliation.test.ts

Summary of Implementation

This reconciliation worker provides:

100% Data Completeness — Guarantees no events are lost ✅ Automated Detection — Identifies gaps without manual intervention ✅ Self-Healing — Auto-repairs missing events (optional) ✅ Complete Audit Trail — Compliance-ready logging ✅ Easy Monitoring — Clear status endpoints and reports ✅ Production-Ready — Retry logic, error handling, scalability

Your Open-Audit instance now acts as a trusted auditing authority for the Stellar/Soroban ecosystem!