Analytics & reporting
Expense Tracking
Indicative price, not an offer: €24/mo; OCR receipt capture, expense categorization, approval workflows
Generated from docs/plan/paid/expense-tracking/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.
A paid module for merchants to capture business expenses (supplier invoices, receipts, operational costs) via OCR, categorize automatically, route for approval, and reconcile with accounting. Core provides audit logging; this pack adds receipt storage, OCR, approval workflows, and expense categorization.
The problem
Merchant receives 50 supplier invoices/month, manually enters line items into spreadsheets, cannot categorize by expense type (COGS vs. shipping vs. rent), misses deductions, and has no proof for tax audits when receipts are lost.
What it does
- Receipt upload: merchant or staff uploads receipt image (JPG/PDF), system stores securely
- OCR extraction: auto-extract vendor name, date, line items, totals from receipt image
- Expense categorization: assign receipt to category (COGS, Shipping, Rent, Marketing, Utilities, Other)
- Approval workflow: manager reviews extracted data, approves or edits line items (multi-level approval if >threshold)
- Reconciliation: link expense to supplier invoice or PO (if exists), flag mismatches
- Expense reports: group by category/month, total by category (for tax/bookkeeping)
- Audit trail: log OCR extraction, approval chain, edits (who changed line item X on date Y)
What it deliberately does NOT do
Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.
- Supplier invoice matching (PO vs invoice reconciliation)—owned by accounts payable module
- Automatic payment of supplier invoices—owned by payments module
- Mileage tracking (business travel)—separate expense type, not in scope
- Receipt image backup/archival (legal compliance)—core handles secure storage, this module doesn’t set policy
- Tax deduction optimization (which expenses are deductible)—accounting consulting, not automation
Data model
New entities: Expense (id, merchantId, receipt, vendor, date, totalAmount, currency, category, approvalStatus, approvedBy, approvalAt); ExpenseLineItem (id, expenseId, description, amount, category). Links: Expense.merchantId → Shop. Files: Receipt images stored in S3-compatible storage with encryption. Migration: none (new data).
API
- POST /api/v1/expenses — upload receipt file, initiate OCR (staff only)
- GET /api/v1/expenses/{id} — fetch expense + extracted line items + OCR confidence (staff only)
- PATCH /api/v1/expenses/{id} — approve/edit expense (manager only, audit logged)
- POST /api/v1/expenses/{id}/line-items — add/edit line items (manager only, audit logged)
- GET /api/v1/expenses/by-category — expenses grouped by category, date range (staff only)
- GET /api/v1/expenses/report — monthly expense report (total by category) (staff only, exportable)
- POST /api/v1/expenses/reconcile — match expense to supplier PO (staff only)
Every route added here must also appear in src/pages/openapi.json.ts — a test
fails the build if it does not.
Admin
Expenses page: upload receipt form (drag-drop or file picker). Pending approvals list: expenses awaiting review, sorted by date. Approval detail: OCR-extracted vendor, date, line items (editable), total. Expense reports page: date range picker, toggle by category (bar chart), table showing category, count, total. Audit trail: show who approved, when, any edits made.
The seam — why this is paid
Core owns: audit logging, secure file storage, email notifications. Paid pack owns: Expense entity, OCR extraction, approval workflow, categorization, reconciliation UI. Seam drawn here because OCR accuracy varies by receipt quality—support team trains models and validates accuracy.
Support commitment: OCR accuracy, receipt storage compliance, audit trail
Dependencies
- core:file-storage — store receipt images securely
- core:audit-log — log every approval, edit, OCR attempt
- core:email — notify manager of pending approvals, notify staff of approval/rejection
- core:roles-and-permissions — only staff can upload, manager approves
- external:OCR service — assume Tesseract or cloud OCR API is available
Acceptance checks
Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.
- A receipt image (JPG, 2MB) is uploaded; OCR extracts vendor ‘Supplier Inc’, date ‘2026-09-01’, total €450 within 30 seconds
- OCR extraction shows 5 line items with amounts; merchant edits one line item amount (€100 → €110); audit log shows ‘staff-id edited line item on 2026-09-01, changed amount from €100 to €110’
- Expense is submitted for approval; manager receives email ‘Expense #123 (€450) from Supplier Inc awaits approval’; manager clicks link, approves
- Expense with total >€200 is submitted; system routes to director (approval threshold set in admin) instead of manager
- Category filter shows ‘COGS’ category; report lists 12 expenses, total €5600 for September (CSV export is accurate)
- OCR confidence is <50% for a receipt (poor image quality); system marks it ‘manual review required’ and shows low confidence warning
- Two merchants cannot see each other’s expenses (multitenancy enforced)
- Receipt file is stored encrypted; audit log shows only file_id, not raw file (PII protection)
Risks
OCR accuracy is image-dependent—blurry/rotated receipts extract incorrectly, causing errors. Test OCR on sample receipts first. Approval workflow must not deadlock—ensure there’s always an approval path (manager → director → owner). Receipt file deletion is permanent—implement soft delete (mark as ‘archived’, not hard delete) for audit trail. Currency must match shop currency (or handle multi-currency); if expense is in EUR but shop is GBP, conversion is manual or flagged. Sensitive data in receipt (employee salary, customer info) must not appear in logs.
Commercial context
| Suggested price | €24/mo; OCR receipt capture, expense categorization, approval workflows |
| Rival anchor | Wave: free; Zoho: €12-99/mo; custom: €1500+ |
The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.
Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full
catalogue and ../../AI-GUIDE.md for how to work on this repository.