Skip to main content

Runbook — Transaction Reset (Development)

Scope: db_kesles_merchant in the Development environment. Goal: Clean out all end-to-end transaction data so we can re-test sending transactions from terminal devices (or from the PSP simulator) without being polluted by old data.

Tooling:

  • scripts/db_reset_transactions.sh — TRUNCATE all transaction tables + verify.

1. Tables that get cleared​

TRUNCATE ... RESTART IDENTITY CASCADE is run on the following tables within a single transaction:

SchemaTableContents
merchanttransactionsMain transaction records (gross, fee breakdown, status).
merchanttransaction_daily_feesDaily fee aggregate per merchant (rolled up from transactions).
merchantsettlementsT+1 settlement records from the PSP.
merchantrefundsRefunds linked to transactions.
merchanttransactions_monthly_aggMonthly aggregate for the dashboard.
merchantmerchant_financialsRunning merchant balance / accumulation. Must be reset to stay aligned with the deleted transactions.
pspevent_logRaw event log from the PSP (transaction.created, settlement, refund).
pspoutbound_requestsAudit of outbound HTTP requests to the PSP.

2. Tables that are NOT touched​

The script intentionally does not touch the tables below so that device configuration and master data stay intact — if these were also deleted, terminals would have to re-pair and merchants would have to re-onboard.

  • merchant.payment_terminals
  • merchant.payment_terminal_psp_pairings
  • merchant.payment_terminal_status_logs
  • merchant.payment_terminal_activity_logs
  • merchant.payment_terminal_inventory
  • psp.api_keys
  • Master data: merchants, merchant_users, vendors, system_settings, payment_device_models, etc.

If you also need to reset device or master data, do not mix it into this script — create a separate runbook so the blast radius is explicit.

3. How to run​

3.1 Default (development)​

scripts/db_reset_transactions.sh

The script will:

  1. Read POSTGRES_DSN from services/dashboard_api/.env.development.
  2. Display the target DB host.
  3. Ask for interactive YES confirmation.
  4. Print row counts before truncate.
  5. Run TRUNCATE ... RESTART IDENTITY CASCADE in a single transaction.
  6. Print row counts after (all must be 0).

3.2 Skip confirmation (for CI / scripting)​

FORCE=1 scripts/db_reset_transactions.sh

3.3 Production​

Deliberately given an extra guard. Calling without the flag will be rejected:

scripts/db_reset_transactions.sh production --i-know-what-i-am-doing

⚠️ Never run this in production unless there is an explicit instruction from the product owner. Resetting transactions in production = real merchant data is lost.

4. After the reset​

  1. Restart dashboard_api if the in-process service caches aggregates / counters in memory — so state is fresh.
  2. Smoke test from a device:
    • Pull a QRIS transaction from a terminal.
    • Check merchant.transactions (1 new row).
    • Check psp.event_log (at least 1 transaction.created event).
  3. Check the merchant dashboard — the numbers in "Today's Transactions" / "Balance" should start from 0 and rise as test transactions come in.
  4. If there is a cache in dashboard_api (e.g. Redis), invalidate it per the service's convention.

5. Sample interaction​

Target env : development
Env file : /…/services/dashboard_api/.env.development
DSN host : 10.8.0.1:5432

Lanjut TRUNCATE semua tabel transaksi? ketik 'YES' untuk konfirmasi: YES
→ Menghitung baris sebelum truncate...
tbl | count
-------------------------------+-------
merchant.transactions | 36
…
→ Menjalankan TRUNCATE...
BEGIN
TRUNCATE TABLE
COMMIT
→ Verifikasi (semua harus 0)...
tbl | count
-------------------------------+-------
merchant.transactions | 0
…
Selesai.

6. Troubleshooting​

SymptomUsual causeAction
psql: error: connection to server at ...VPN to 10.8.0.1 is not active or DB host is on a different path.Activate VPN; see the network topology memo in memory/project_db_network.md.
ERROR: cannot truncate ... referenced by ...A new FK from another table references a transaction table.Add the child table to the TRUNCATE list (or change the FK to ON DELETE).
Dashboard balance still > 0 after resetmerchant_financials is cached or recomputed via a view.Make sure the service is restarted; also check whether a materialized view needs refresh.
Script exit code 2 in productionGuard --i-know-what-i-am-doing was not provided.It must be explicit. Reconsider before bypassing the guard.