Transactions

The ledger view — every income, expense, and transfer.

The Transactions tab is where every ledger entry for a client lives, no matter how it got there. Hand-entered, OCR'd from a receipt, imported from CSV — they all surface in one list.

Open it from any client → Transactions.

The list

Each row shows:

  • Date — sortable
  • Vendor or payer as the primary label; an amber dot appears next to the name if the AI flagged the entry as non-deductible or partially deductible
  • Account badge — the CoA code this row is booked to (e.g. 500-200)
  • Reviewed ✓ — green check if a teammate signed off (see Month-end close)
  • Amount on the right — green for income, neutral for expense, grey for transfer; sortable

The list is sorted newest first by date by default. Click any header to re-sort. Up to 1,000 rows per filter window — if the truncation banner appears, narrow the date range with the filter bar.

[Screenshot pending] Transactions list with filter chips above and rows showing vendor names, account badges, and amounts

Filtering and searching

Above the list, two controls let you narrow the data:

  • Search box — free-text across vendor, description, and account (case-insensitive). Results update as you type.
  • Multi-filter chips — add one or more structured rules via + Add filter. Each chip shows the active condition; click it to edit or remove it.

Using the multi-filter

Click + Add filter to open the filter editor:

  1. Column — pick what to filter on: Date, Vendor, Account, or Amount
  2. Operation — changes based on the column type:
    • Text: contains / does not contain / is / is not
    • Number: equals / not equals / greater than / less than / between
    • Date: equals / not equals / after / before / between
  3. Value — type a value or pick a date from the calendar. For between, set both start and end.
  4. Apply — commits the rule and closes the editor.

Applied rules are shown as chips below the search box. Click any chip to reopen its editor and tweak the rule. Hit × on a chip to remove that rule.

Multiple rules work as AND — all active rules must match for a row to appear.

The filter chip state is local to the page — it isn't persisted in the URL. If you need to share a specific filtered view with a teammate, do so via the search box (which is URL-driven) or describe the filter rules verbally.

Adding a transaction manually

Hidden from Viewers; available to everyone else. Click Add transaction above the list. The form asks for:

FieldNotes
DateRequired
TypeRequired — Income / Expense / Transfer
SubtotalRequired, positive, tax-exclusive
SSTOptional. Auto-filled if you pick a tax code with a default rate. Hidden for transfers — a bank-to-bank move carries no SST
TotalRead-only — subtotal + SST, shown so you can sanity-check
CurrencyRequired. MYR / USD / SGD today
Vendor or payerFree text
AccountSearchable dropdown of the client's chart of accounts. Limited to active codes. For a Transfer, this is the account the money comes from.
To accountTransfer only — the destination account the money goes to. A transfer needs both a from and a to account, and the two must differ.
DescriptionFree text — what the entry is about. Useful at month-end.
Payment method(More section) Free text — e.g. Maybank transfer, Cash
Tax code(More section) SST / LHDN tax code if applicable

Save creates a source = 'manual' transaction. Behind the scenes it also posts a balanced journal entry to the ledger — for a transfer, that's the money debited to the to account and credited from the from account — so the entry shows up in the trial balance and reports (see How Kiravy's general ledger works). A background AI deductibility check runs automatically and tags it for tax review.

The amount is always positive. Direction is carried by Type (income = money in, expense = money out, transfer = same-client movement). This matches mainstream accounting-software convention and keeps reports straightforward.

Editing and deleting

Open any transaction → all fields except workspace, client, and created by are editable. Those three are write-once to protect the audit trail.

To delete: Delete button at the bottom → confirm. This is a soft delete — the row is hidden from every list, filter, and search, but it isn't physically removed from the database. Recovery requires support.

Hard delete from the UI doesn't exist by design. Deleting tax-relevant data has 7-year retention implications in Malaysia.

Transactions migrated from SQL Account show a note on the detail page telling you where the row originally came from. That's just provenance — Kiravy is now the ledger of record. SQL Account is a one-time migration source, not a live system Kiravy syncs back to, so editing a migrated transaction simply updates it in Kiravy. There's no push-back to any source system; the change lives here.

The "Reviewed" workflow

When a senior accountant signs off on a row, they set reviewed_at on it. The list shows a green checkmark, and by default unreviewed entries float to the top of your view (because Unreviewed is the default filter).

Where does the review actually happen? Not on this tab directly — instead through the Month-end close Review queue, which is the bulk-review UI. Open an engagement, batch-tick a hundred rows at a time.

This is intentional: reviewing one row at a time on the Transactions tab would be tedious; the engagement workflow is built for closing a period systematically.

Sources, explained

Each transaction has an internal source tag (not displayed in the list, but visible on the detail page):

SourceWhat it means
ManualYou typed it in via Add transaction
ReceiptCame from an OCR'd receipt. The receipt detail page links back to the original photo.
IntegrationSynced from an accounting integration. The original external_id lets us de-dup on re-sync.
BankImported from a bank statement / feed
CSVBulk-imported via the import wizard

CSV import

For when you've got transactions in a spreadsheet that aren't worth re-typing. Import CSV button (next to Add transaction) opens a 4-step wizard at /clients/[clientId]/transactions/import:

  1. Upload — drag-drop the file. CSV or Excel. Kiravy AI suggests a column mapping based on header names.
  2. Mapping — confirm or adjust the mapping. You pick how amounts are encoded:
    • Typed: separate Amount + Type columns
    • Signed: one Amount column where positive = income, negative = expense
    • Debit/Credit: separate Debit and Credit columns
  3. Preview — Kiravy shows you the parsed rows, with any errors highlighted, before anything is saved
  4. Done — confirmation with a count and a back-link to the list

Every imported row gets source = 'csv' and an internal import batch id so you can find them again if something goes wrong.

Date + amount fields are required (which amount columns depends on the mode you picked). Vendor, account code, description, and payment method are all optional.

Bulk edit

There isn't one — yet. Edit transactions one at a time on the detail page. The CSV import wizard lets you bulk create but not bulk update. A bulk-edit affordance is on the roadmap.

What each role sees

RolePermissions
Viewer (assigned)Read-only list. Add transaction / Import CSV / Delete are hidden. Editing a transaction's form fields is disabled.
Staff (assigned)Full read/write on assigned clients
ManagerFull read/write across every client in the firm
PartnerSame as Manager, plus firm-level admin

Cross-firm access doesn't exist — RLS at the database level enforces tenant isolation.

What's next