Client. A debt management and collections company that ran its financial operation in Excel spreadsheets: the invoice lifecycle, partial payments, debt aging and balances lived in cells, with no system to make them auditable and no single source of truth.
Approach
This case runs through two links of the method —software engineering and data engineering— with no handoff between them: the same mind that built the platform replacing Excel is the one that later moved the historical data into another system without degrading its meaning along the way. There is no team that delivers the ERP and another that migrates the data: there is a single path that understands what an invoice, a partial payment and a voucher are in this company, and preserves it end to end.
The thesis ordering the work is that of reliable data as a precondition, not an addendum. A balance engine is only useful if it is deterministic —if the same operations always produce the same balance— and a migration is only worth it if it is idempotent —if running it twice neither duplicates nor corrupts. In finance, those two properties are not implementation details: they are the difference between an auditable tool and a faster Excel.
The problem identified
The company ran its debt management in Excel. Each collector, each price list, each partial payment and each debt-aging calculation depended on spreadsheets that no one could audit and that degraded with every copy. The stated problem was “we need a system”. The real problem came earlier: there was no reliable balance engine —a client’s balance was the result of a chain of cells that no person could reconstruct or justify before an audit.
On top of that came a second, latent problem: once the operation was put in order, the historical data had to be moved into accounting software (via its API) to close the formal accounting cycle. Migrating from the legacy management system was not a table dump: it was reconstructing the meaning of each voucher in another system’s data model, with its own mandatory fields and its own rules.
Functional assessment
The assessment covered both sides of the work.
On the ERP side, the invoice lifecycle was modeled —issuance, partial payments, balance, debt aging— and the workflows that Excel resolved informally were identified: debt-aging classification, multi-stage withholding validation, complete transaction histories. Each was assessed as a real process, not as a screen to be drawn.
On the migration side, the assessment was about data. A data dictionary and the source→target mappings between the legacy management system and the accounting software were built, with the destination API’s payload requirements. The assessment included documenting what could not be obtained: the findings on the limits of the sources —for example, mandatory accounting-software fields that the analytical sources did not expose for reconstructing complete vouchers. Recording the gap is as much part of the assessment as recording the available data.
Building the technical solution
The work had two technical sides sharing one demand for auditability.
The full-stack ERP platform. A financial platform built with FastAPI, PostgreSQL and Next.js 14 / React / TypeScript, replacing Excel-based management. Its centerpiece is a deterministic balance engine: the balance is not the residue of a spreadsheet, but the reproducible result of a model of the invoice and partial-payment lifecycle. The APIs were secured with RBAC, so that who can view and operate on what is governed by role rather than by convention. The business workflows —debt-aging classification, multi-stage withholding validation, complete histories— were built as auditable flows, with production dashboards and PDF reporting (ReportLab).
The data migration into the accounting software. A migration pipeline that moves the data from the legacy management system into accounting software via its API, with parsing and normalization of the sources, generation of the payloads the destination API requires, and a push with checkpoint, progress and idempotency: the pipeline can be interrupted and resumed without duplicating or corrupting, and re-running it converges to the same state instead of accumulating errors. The execution was ordered with phase-by-phase traceability —masters → vouchers → validation → controlled production load— so that no phase advances over data the previous one did not validate. The bulk load via API covered importing clients, creating regional price lists and bulk-assigning missing client codes, each operation with its execution report.
Information and data layer
Data governance was design, not an addendum, on both sides.
- Determinism and auditability in the ERP. The balance engine is deterministic by design: a client’s balance is always reconstructable and justifiable. Complete transaction histories and auditable flows mean that every system state has a trace, not a verbal explanation.
- Idempotency and traceability in the migration. Checkpointing and idempotency make the migration repeatable without harm; phase-by-phase traceability makes the load state always readable —which masters entered, which vouchers were validated, what remained pending.
- Functional analysis as a source of truth. The data dictionary, the source→target mappings and the payload requirements were documented as versioned artifacts, so that migration decisions remain auditable rather than living in one person’s head. The findings on the limits of the sources were recorded explicitly, because what the data does not say is also governance information.
How the work was conducted
The work was executed between December 2025 and June 2026. The concrete and verifiable was disciplined engineering, not a showcase of trendy tools.
- The migration pipeline was built with the properties that matter in finance: checkpoint, idempotency, progress reporting and phase-by-phase traceability. It is not a single-use script, but an instrument that can be run, interrupted and re-run without losing integrity.
- The functional analysis was sustained with written artifacts —data dictionary, source→target mappings, payload requirements, migration plan and validation-phase log— so that the data work would be reconstructable by someone else.
- The real executions were recorded in an operational status log: what was loaded, when and with what result. The log is what distinguishes an executed and verified migration from a plan on paper.
- For the repetitive scripts —per-data-model payload generators, source normalizers— code agents were used as the engineer’s instrument, to speed up the mechanical part. The design criteria, the integrity properties and the validation of each phase were my own decision and responsibility; the tool accelerates, it does not decide.
What this case proves
- Full-stack development with financial discipline: an ERP with a deterministic balance engine, invoice lifecycle, partial payments and RBAC-secured APIs, as a real replacement for Excel-based management —not a prototype.
- Data migration as engineering, not as a dump: an idempotent pipeline, with checkpoint and phase-by-phase traceability, into accounting software via its API, with documented functional analysis and a log of real executions.
- Continuity between building and migrating: the same mind that put the operation in order is the one that moved the data into another system without degrading its meaning at the seam.