Moodus
A POS expense tracking platform where each client maps to their own set of terminals, giving them real-time transaction monitoring and financial visibility across all of them.
- Timeline
- 2023 – 2025
- Context
- Professional project · Innoart Technologies
- My role
- Full stack engineer — terminal data pipeline, reporting, dashboards
Illustrative representation of the interface — not a screenshot of client software.
The problem
Clients running several POS terminals had no single view of what was being spent where. Each terminal was its own island of transactions, so building a picture of the month meant collecting exports and reconciling them by hand.
Terminal data doesn't arrive in one clean format either, which makes naive aggregation quietly wrong.
What I worked on
Designed and built the POS expense tracking dashboard, with each client mapped to their dedicated terminals for real-time transaction monitoring and financial visibility.
Engineered the backend services that aggregate, normalise and process terminal-level transaction data so expense tracking and reconciliation are accurate rather than approximately right.
Built dynamic reporting modules with downloadable summaries and client-specific analytics.
How it worked
Django and Python own the aggregation and reconciliation services; a Node layer handles the transaction intake side; PostgreSQL holds relational and reporting data with MongoDB used for the less-structured transaction payloads.
Normalisation happens on the way in — transactions are mapped to a common shape at ingest, so reporting queries never have to know which terminal model produced a row.
Client-to-terminal mapping is a first-class relationship, which is what makes tenant-scoped dashboards and per-client analytics straightforward instead of a filter bolted onto every query.
Reporting modules are generated from the same aggregates the dashboard reads, so a downloaded summary and the on-screen number can't disagree.
Challenges
Reconciliation is unforgiving: a duplicate or dropped transaction turns a finance dashboard into something nobody trusts, so the ingest path needed to be idempotent and the reconciliation checkable.
Mixing relational and document storage is useful right up until it isn't. Drawing a clear line about which data lives where kept the reporting layer sane.
Different clients wanted different cuts of the same data, which pushed the reporting toward configurable modules rather than a growing list of one-off reports.
Outcome
Improved financial transparency and operational oversight for clients through real-time terminal-level monitoring.
Reporting became self-serve — client-specific analytics and downloadable summaries replaced manual export-and-reconcile work.