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:
| Schema | Table | Contents |
|---|---|---|
merchant | transactions | Main transaction records (gross, fee breakdown, status). |
merchant | transaction_daily_fees | Daily fee aggregate per merchant (rolled up from transactions). |
merchant | settlements | T+1 settlement records from the PSP. |
merchant | refunds | Refunds linked to transactions. |
merchant | transactions_monthly_agg | Monthly aggregate for the dashboard. |
merchant | merchant_financials | Running merchant balance / accumulation. Must be reset to stay aligned with the deleted transactions. |
psp | event_log | Raw event log from the PSP (transaction.created, settlement, refund). |
psp | outbound_requests | Audit 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_terminalsmerchant.payment_terminal_psp_pairingsmerchant.payment_terminal_status_logsmerchant.payment_terminal_activity_logsmerchant.payment_terminal_inventorypsp.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:
- Read
POSTGRES_DSNfromservices/dashboard_api/.env.development. - Display the target DB host.
- Ask for interactive
YESconfirmation. - Print row counts before truncate.
- Run
TRUNCATE ... RESTART IDENTITY CASCADEin a single transaction. - 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
- Restart
dashboard_apiif the in-process service caches aggregates / counters in memory — so state is fresh. - Smoke test from a device:
- Pull a QRIS transaction from a terminal.
- Check
merchant.transactions(1 new row). - Check
psp.event_log(at least 1transaction.createdevent).
- Check the merchant dashboard — the numbers in "Today's Transactions" / "Balance" should start from 0 and rise as test transactions come in.
- 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
| Symptom | Usual cause | Action |
|---|---|---|
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 reset | merchant_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 production | Guard --i-know-what-i-am-doing was not provided. | It must be explicit. Reconsider before bypassing the guard. |