Import & Categorization
Ledgerly’s import flow is evidence-first:
- BankEvent: immutable evidence of a statement line
- Reconciliation: matching + categorization (suggestions + confirmation)
- Transaction/Entry: canonical ledger truth
- BankEventMatch: mapping from evidence → truth
This structure is what enables transfer de-duplication across multiple bank accounts and safer rollback.
Supported statement formats
Ledgerly currently imports CSVs via bank-specific parsers plus a fallback:
| Bank / Parser | bank_id |
Format | Notes |
|---|---|---|---|
| HDFC | hdfc |
CSV | HDFC export format |
| KVB | kvb |
CSV | KVB export format (often includes a preamble) |
| Federal | federal |
CSV | Federal export format |
| Generic CSV | generic |
CSV | Fallback when no bank-specific parser matches |
Parser detection happens automatically and returns a detected bank_id with a confidence score.
Import process (UI)
- Upload a CSV and select a source bank account.
- Detect + Preview:
- Parses rows (no database writes)
- Suggests a category account per row
- Computes a stable
event_hashper row - Finds possible transfer matches across other bank accounts
- Flags duplicates
- Confirm + Execute:
- Creates an
ImportBatch - Upserts
BankEventrecords (idempotent per account viaevent_hash) - Creates or attaches
Transactionrecords - Creates
BankEventMatchmappings - History:
- Review completed batches
- Rollback (safe)
- Hard delete (destructive)
Categorization (how suggestions work)
Categorization rules
Rules suggest accounts based on patterns in the description.
Pattern types:
- Contains
- Starts With
- Ends With
- Exact
- Regex
Rules are checked by priority (higher first). First match wins.
Example:
Priority 10: Pattern "STARBUCKS" → Expenses::Food::Coffee
Priority 5: Pattern "AMAZON" → Expenses::Shopping
Priority 1: Pattern "GAS" → Expenses::Transportation
Heuristics (fallback)
If no rule matches, Ledgerly may apply basic heuristics (e.g., fallback expense buckets) to avoid “no suggestion” for common cases. Always review the preview before executing.
“Learn” behavior
When Learn is enabled for a row during import, Ledgerly creates a categorization rule based on the extracted merchant token and the selected category account so future imports are more deterministic.
Transfers and cross-account de-duplication (MVP)
When you categorize a row to another internal bank account (an Asset account), Ledgerly treats it as a transfer and will attempt to attach the opposite-side statement line imported from the other account:
- Candidate search: opposite direction, same amount, date window ±2 days, other bank accounts
- Confidence scoring: amount + direction + date proximity + lightweight reference/description overlap
- If confidence ≥ threshold, Ledgerly auto-attaches both events to the same transfer
Transaction
The preview UI surfaces this as “Possible transfer match” and lets you Accept or Ignore.
Rollback vs hard delete
Rollback (safe)
Rollback removes derived ledger truth and mappings for a batch:
- Deletes
Transaction+Entryrecords created by that batch - Deletes
BankEventMatchrows for that batch’s bank events - Keeps
BankEventevidence (they become “unmatched” again)
Hard delete (destructive)
Hard delete removes everything associated with a batch:
- Deletes the
ImportBatch - Deletes its
BankEventevidence andBankEventMatchrows - Deletes any
Transaction/Entrycreated by that batch - Deletes audit log entries for that batch
Import actions
Ledgerly provides these import actions through the UI:
- Detect: determine the best matching bank parser for an uploaded file
- Preview: parse rows and return suggestions (no database writes)
- Execute: ingest evidence and create/attach ledger transactions (creates an import batch)
- History: list batches and view batch details
- Rollback: remove derived ledger/matches for a batch, keep evidence
- Hard delete: permanently delete the batch and all associated data
Troubleshooting
“Detected: Generic CSV”
If a statement file is detected as Generic CSV, check:
- Leading blank lines before the header
- File encoding (UTF-8 recommended)
- Column headers matching the bank export format
Wrong categorization
- Add/adjust categorization rules (be specific and use priority)
- Use “Learn” on correctly categorized rows to improve future suggestions