SAK3.0
WaveDirect
Sign in
Swiss Army Knife 3.0 — Internal Tools
SAK3.0
WaveDirect
AD
Admin
administrator
Dashboard
Good morning
Runs today
—
Payments processed
—
Amount today
—
Last run
—
Customise mode — drag tiles to reorder, click ✕ to remove
RBC Payment Processor
Upload, precheck, and submit RBC flat files to Sonar
1 · Upload
2 · Precheck
3 · Review
4 · Process
5 · Report
Drop an RBC flat file here
or click to browse — .txt or .dat files
About the RBC flat file format
140-byte fixed-width records. A = file header, B = batch header, G = payment detail, T = batch trailer, Z = file trailer. The parser uses the exact regex from the legacy SAK2 processor — anomalous G-records are silently skipped and reported in the precheck.
Payments found
—
Total value
—
Payments with issues
—
CCIN / File date
—
Review payments
DRY RUN (safe)
No live submissions. Uncheck to go live.
# Account Payer Amount Pay date Trace Status
0 selected · $0.00
Processing payments…
Do not navigate away
✓ 0 succeeded ✗ 0 failed ↻ 0 duplicate of 0 payments
Succeeded
0
Failed
0
Duplicate (auto-skipped)
0
Total amount processed
$0.00
# Account Payer Amount Result Detail
File Date Payments Amount Result Dry? User
Loading…
When Run Account Payer Amount Error
Loading…
—
(loading...)
Hasura integration
Endpoint
https://hasura.wavedirect.net/api/rest/submitcustomerpayment
Admin secret
stored in backend .env (not exposed)
Debug log path
backend/logs/sonar_debug.log
Safety behaviour
Submit delay
200 ms between live submissions
Duplicate file block
SHA-256 match blocks upload (admin can force)
Singleton lock
Only one run may be processing at a time
Retries
Manual only — use "Retry failed" on a completed run

RBC Payment Processor — Documentation

Upload an RBC Corporate Creditor Bill Payment flat file, review every payment, then submit them to Sonar via Hasura — with full audit trail and multiple layers of protection against duplicates and accidental double-submission.

The five-step workflow

  1. Upload — drag an RBC .txt/.dat file onto the drop zone or click to browse. The backend computes the file’s SHA-256, parses every G-record, and persists everything to the database in a ready state. If this exact file has already been successfully processed, you’ll see a red duplicate banner with details of the previous run. Only an admin can force a re-upload.
  2. Precheck — summary cards show total payments, total amount, anomaly count, and the CCIN/file date from the A-record. File-level issues (missing header/trailer) and skipped G-records (anomalies the regex rejected) are listed. Download buttons produce a human-readable review.txt and a machine-readable review.jsonl (the exact payloads that will be POSTed to Hasura).
  3. Review — the full payment table. Every row is pre-selected; uncheck anything you want to exclude. Rows with issues (missing account, zero amount, missing trace) are highlighted amber. The Dry Run toggle defaults ON (green) and must be explicitly unticked to go live (turns red). Selected count and total update live.
  4. Process — clicking "Submit selected payments" opens a confirmation modal. Live submissions require you to type RUN to enable the confirm button. Once confirmed, the backend streams Server-Sent Events as each payment is submitted: a live terminal console shows every request, running counters update, and a progress bar fills in. Dry runs use 100 ms pacing; live runs use 200 ms.
  5. Report — final summary cards, tabbed results (All / Succeeded / Failed / Duplicate / Skipped), and download buttons for the decorated audit report (audit.txt) and the full JSON export. If any payments failed, a "Retry failed" button appears — admin-only, re-streams ONLY the failed rows.

Safety rails

  • File-hash duplicate block. SHA-256 of every uploaded file is stored. Re-uploading a previously-processed file returns HTTP 409 with the prior run’s metadata. Admin can bypass with ?force=true.
  • Singleton lock. At most one run may be in running state at any time. A second accountant trying to start a run while one is in progress gets a clear 409 error.
  • Trace-level de-dupe (belt). Before each Hasura POST, the backend checks whether the payment’s trace number has already been successfully submitted in a different run. If it has, the payment is marked duplicate and skipped — no Hasura call is made.
  • Trace warnings at precheck (suspenders). Same check runs informationally at upload time so the accountant sees it before submitting.
  • Dry-run default. Every new run starts with Dry Run ON. Live submission requires an explicit tick plus typing RUN in the confirmation modal.
  • Interrupted-run recovery. If the backend crashes mid-stream, any run stuck in running state is marked interrupted at startup. It will never auto-resume — an admin must explicitly resume (re-streams only still-pending rows) or abort it.
  • No retries, no loops, no polling. No file watchers, no cron jobs, no automatic retries of failed rows. Every action requires a human click. The legacy SAK2 10-minute polling loop is gone for good.
  • Single-pass iteration. Each run invocation iterates its payment list exactly once. Retry-failed creates a new iteration with only the failed rows (never touches success rows).

Where files live

WhatWhere
Application root/home/wavedirect/sak3/
Backend (FastAPI)/home/wavedirect/sak3/backend/app/
Payment routesbackend/app/routes/payments.py
Databasebackend/data/sak3.db (SQLite)
Sonar debug logbackend/logs/sonar_debug.log — tail -f-able, legacy format preserved
Frontend (single SPA)frontend/index.html — no build step
systemd servicesak3.service → uvicorn on 127.0.0.1:8000
nginx reverse proxyPort 443 with Let’s Encrypt SSL
Timestamped backupsSiblings of the original (*.bak.YYYYMMDD-HHMMSS)

Admin actions

  • Force re-upload — bypass the SHA-256 duplicate block. Available only to admins, surfaced as a button on the duplicate banner.
  • Abort a run — cancel a running or interrupted run. Currently backend-only: POST /api/payments/runs/{id}/abort.
  • Resume an interrupted run — re-streams only still-pending rows. Backend-only: POST /api/payments/runs/{id}/resume.
  • Retry failed payments — button on the Report step. Resets failed rows to pending and re-streams only those.
  • Clear debug log — button on the API Log tab. Truncates sonar_debug.log on disk.
  • Delete a run — admin-only via DELETE /api/payments/runs/{id}.

Hasura / Sonar integration

Payments are submitted as query-string parameters to Hasura’s REST endpoint: https://hasura.wavedirect.net/api/rest/submitcustomerpayment. Hasura wraps the call as a GraphQL mutation into Sonar. Authentication is via the x-hasura-admin-secret header, read from the backend .env and never exposed to the browser. Success is detected by the presence of a createPayment key in the response.

The payload sent to Hasura for each payment has four fields: account_id (10-digit zero-padded), amount (integer cents), reference (trace number from the G-record), payment_datetime (ISO timestamp at upload time).

The submitter is encapsulated in submit_to_sonar() in payments.py so it can be replaced with a direct GraphQL mutation later without touching the workflow code.

File format (RBC G-record parser)

140-byte fixed-width records. The parser uses the exact regex from the legacy SAK2 main2.py:

^G\d{9}(\S{1,30})\s+(\d{4,10})\s+(\d{13,15})\s+(\d{8})(\d{8})\d{6}(.{1,35})

Field order: G + 9-digit sequence + trace (up to 30 chars) + account number + amount + pay date + (filler) + payer name. Any G-record the regex doesn’t match is reported as a "skipped line" in the precheck — these are real anomalies the regex was hand-tuned to reject, and they must NOT be auto-fixed or included. Parity between this parser and the legacy script is verified by backend/tests/test_rbc_parser_parity.py.

Endpoints reference

MethodPathPurpose
POST/api/payments/uploadUpload + parse → ready run
GET/api/payments/runsList all runs
GET/api/payments/runs/{id}Run detail + payments
GET/api/payments/runs/{id}/review.txtHuman-readable review (pre-submit)
GET/api/payments/runs/{id}/review.jsonlExact Hasura payloads (JSON Lines)
GET/api/payments/runs/{id}/audit.txtFinal decorated audit report
GET/api/payments/runs/{id}/exportFull JSON export
POST/api/payments/runs/{id}/startBegin processing (SSE stream)
POST/api/payments/runs/{id}/abortAdmin: cancel a run
POST/api/payments/runs/{id}/resumeAdmin: resume interrupted
POST/api/payments/runs/{id}/retry-failedAdmin: re-run failures only
DELETE/api/payments/runs/{id}Admin: delete a run
GET/api/payments/errorsAll failed payments across runs
GET/api/payments/sonar-log?tail=NLast N lines of sonar_debug.log
DELETE/api/payments/sonar-logAdmin: clear the debug log

Troubleshooting

  • 502 Bad Gateway — the sak3 service crashed on startup. Check sudo journalctl -u sak3 -n 50 for the traceback, fix the code, then sudo systemctl restart sak3.
  • Upload returns 409 file_already_processed — this file’s SHA-256 matches a previously-completed run. Contact an admin to force re-upload, or (more likely) use a different file.
  • "Another run is already in progress" — the singleton lock is engaged. Check the Run History tab for a run in running state. If the backend crashed, the run will be marked interrupted at startup instead — an admin must resume or abort it.
  • Payments marked duplicate — their trace number has already been successfully submitted in a previous run. This is the safety belt preventing double-submission. If you believe it’s wrong, investigate the trace in the Run History.
  • Can’t find my old file in "Review Complete" — the new SAK3.0 system does not move files anywhere. The uploaded file content is stored directly in the database on each run row (file_content column). Use the JSON export to retrieve it.
  • Live tail of the debug log — tail -f /home/wavedirect/sak3/backend/logs/sonar_debug.log from any shell on this server. Same format as the legacy SAK2 debug log.

Version & credits

SAK3.0 — WaveDirect internal tools platform. FastAPI + SQLite backend, single-file HTML/JS/CSS frontend, JWT auth, systemd-managed uvicorn process, nginx reverse proxy with Let’s Encrypt. Replaces the SAK2 directory-watcher + regex scripts.

Read ~/sak3_context.md for the broader project overview, and ~/rbc_payment_processor_ui_summary.md for the UI spec this tool was built against.

Users
Manage access to SAK3
Name Email Role Last login Status
Loading…
Settings
API configuration and system options
Appearance
Choose a theme for this browser. Applies instantly.
Sonar integration
Saved ✓
System info
Version: SAK3.0
Backend: FastAPI + SQLite
Auth: JWT (httpOnly cookie)
Add dashboard tile