Ledger Service: Database, Flow, and Admin / Miniapp Integration
1. Database
- Same Postgres as rest of stack: Ledger uses
POSTGRES_HOST,POSTGRES_PORT,POSTGRES_USER,POSTGRES_PASSWORD,POSTGRES_DB(e.g.gitinext_wallet_corein swarm). - Schema: General Ledger tables live in that DB:
gl_accounts– Chart of Accounts (seeded by migration)gl_journal_entries– Journal entry headersgl_postings– Double-entry lines (debit/credit per entry)fx_rates– FX rates (filled by ledger’s FX ingestion job)gl_positions– Optional cache for balances
- Migration: Run once per DB:
services/ledger/migrations/001_create_gl_schema.sql.
If ledger starts and FX ingestion runs without DB errors, the schema is present (FX job writes tofx_rates). - Note: User balances in the app are still in
ledger_entries(gateway/wallet use that). The GL service is for accounting/reporting (P&L, trial balance, journal), not for real-time user balance display.
2. Service Logs (Working Fine)
- Ledger: Starts, HTTP on
:8080, FX ingestion runs every 5 min (“FX ingestion completed”, “success”:28). No DB or startup errors. - Gateway: Proxies
/api/v1/accounting/*(gateway handlers) and/api/v1/ledger/*(to ledger). Accounting turnover and admin auth are working (e.g./api/v1/accounting/turnover/simple200).
3. How the Flow Works
Admin / Miniapp (gitibot-admin or TMA)
│
▼
Gateway (api.nextgiti.cloud)
│
├── /api/v1/accounting/* ──► Gateway handlers (AccountingHandler)
│ • Turnover, deposits/withdrawals/vouchers summaries
│ • Uses gateway’s Postgres (deposits, withdrawals, etc.)
│
└── /api/v1/ledger/* ──► Ledger proxy ──► Ledger service (ledger:8080)
• Reports, journal, chart of accounts, FX, treasury
• Uses same Postgres, GL tables (gl_*, fx_rates)
- Auth: Both accounting and ledger routes require admin JWT and roles
superadmin,admin, oraccountant. - Proxy: Gateway does not strip path; it forwards the full path to ledger (e.g.
GET /api/v1/ledger/reports/trial-balance→http://ledger:8080/api/v1/ledger/reports/trial-balance).
4. Ledger API (via Gateway) – For Admin Panel
Base URL: /api/v1/ledger (same host as gateway, e.g. https://api.nextgiti.cloud).
All require Authorization: Bearer <admin_jwt> (and role superadmin/admin/accountant).
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/ledger/reports/pnl |
P&L report. Query: from, to (dates, optional). |
| GET | /api/v1/ledger/reports/balance-sheet |
Balance sheet. Query: at or as_of (optional). |
| GET | /api/v1/ledger/reports/trial-balance |
Trial balance. Query: at or as_of (optional). |
| GET | /api/v1/ledger/reports/reconciliation |
Chain/asset reconciliation. Query: chain, asset. |
| GET | /api/v1/ledger/journal |
Journal entries (paginated). Query: from, to, limit, offset, page. |
| GET | /api/v1/ledger/accounts |
Chart of accounts. |
| GET | /api/v1/ledger/fx-rates |
FX rates. Query: base (default USD). |
| POST | /api/v1/ledger/fx-rates/refresh |
Trigger FX rate refresh. |
| GET | /api/v1/ledger/treasury |
Treasury overview. |
| GET | /api/v1/ledger/exports/journal |
Export journal (CSV). Query: format, from, to. |
| GET | /api/v1/ledger/exports/trial-balance |
Export trial balance (CSV). Query: format, as_of. |
Date formats: YYYY-MM-DD or RFC3339 for from/to/at/as_of.
Journal pagination: Use page (e.g. page=2) and limit (default 50). Response: { "entries", "total", "limit", "offset" }.
Trial balance response: { "accounts": [ { "account_code", "account_name", "account_type", "debit", "credit", "balance" } ], "total_debits", "total_credits", "as_of" }. Use debit / credit (strings, may be "0").
5. Accounting API (Gateway, Not Ledger) – For Admin Panel
Base URL: /api/v1/accounting. Same auth as above.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/accounting/turnover/simple |
Turnover (default last 7 days). Query: from, to (YYYY-MM-DD). |
| GET | /api/v1/accounting/turnover/daily |
Same as simple (daily turnover). |
| GET | /api/v1/accounting/turnover/weekly |
Weekly aggregation. |
| GET | /api/v1/accounting/turnover/monthly |
Monthly aggregation. |
| GET | /api/v1/accounting/deposits/summary |
Deposits summary. |
| GET | /api/v1/accounting/withdrawals/summary |
Withdrawals summary. |
| GET | /api/v1/accounting/vouchers/summary |
Vouchers summary. |
| GET | /api/v1/accounting/vouchers/daily |
Vouchers daily. |
| GET | /api/v1/accounting/vouchers/weekly |
Vouchers weekly. |
| GET | /api/v1/accounting/vouchers/monthly |
Vouchers monthly. |
Use YYYY-MM-DD (or RFC3339) for dates; invalid/NaN dates return 400 with a clear message.
6. Where to Update: Admin Panel and Miniapp
Admin panel (e.g. gitibot-admin)
- General Ledger / Reports:
- Base URL: Same as gateway, e.g.
https://api.nextgiti.cloud. - Call
/api/v1/ledger/*for: trial balance, P&L, balance sheet, journal list, chart of accounts, FX rates, treasury, exports. - Send Authorization: Bearer <admin_token> (from admin login).
- Trial balance: Use response field
accounts[].debitandaccounts[].credit(strings); show"0"as zero, not “—”. - Journal: Use query params
pageandlimit; show “Next/Previous” usingtotalandlimitto compute max page.
- Base URL: Same as gateway, e.g.
- Accounting / Turnover:
- Call
/api/v1/accounting/turnover/daily(or/simple,/weekly,/monthly) with queryfrom,toin YYYY-MM-DD. - Avoid passing invalid dates (e.g. NaN); backend returns 400 with “invalid from/to date (use YYYY-MM-DD)”.
- Call
- Swap summary:
/api/v1/admin/swap/summary– ifSWAP_ADMIN_TOKENis not set, gateway returns 503 with{"error":"swap admin not configured","code":"SWAP_ADMIN_NOT_CONFIGURED"}. Handle 503 in UI (e.g. “Swap stats not configured”) instead of generic 500.
Miniapp (TMA / in-bot UI)
- Miniapp typically does not call ledger or accounting (those are admin-only).
- If you add an “admin” or “support” view inside the miniapp that needs reports, use the same gateway base URL and
/api/v1/ledger/*and/api/v1/accounting/*with an admin JWT (obtained via your admin auth flow), and apply the same date and response-field rules as above.
7. Quick Checklist
| Item | Status |
|---|---|
| Ledger DB (same Postgres, GL schema) | OK if ledger starts and FX job runs |
| Ledger logs (start + FX ingestion) | OK |
| Gateway proxy to ledger | OK (no strip; full path forwarded) |
| Admin auth for /v1/ledger and /v1/accounting | Required (JWT + roles) |
| Admin panel: use /api/v1/ledger/* for GL | Verified – General Ledger page uses correct endpoints |
| Admin panel: trial balance debit/credit | Use debit / credit; show 0 as “0” |
| Admin panel: journal pagination | Use page and limit; Next/Previous from total |
| Admin panel: turnover dates | Send YYYY-MM-DD; handle 400 on invalid date |
| Miniapp | No change unless adding admin/report views |
Live verification (admin.nextgiti.cloud/finance/ledger): Overview, P&L, Balance Sheet, Trial Balance, Journal, and Reconciliation tabs load; trial balance shows chart of accounts; journal shows empty state when no entries; export buttons (Journal CSV, Trial Balance) present.