Boxi
Modernising the ERP of a fast-growing self-storage company

The need
Boxi is the ERP of Atout-Box, a self-storage company: quotes, contracts, invoicing, payments, site access control. The company is growing fast — more sites, more customers, more users. Yet Boxi is a PHP monolith of several hundred thousand lines, mostly untested, with an interface that no longer fits how people work.
The assessment
- Measure before deciding. A quantified inventory: over 1,000 files and over 300,000 lines of legacy code, several databases, an untyped frontend.
- No big-bang rewrite. A full rewrite would freeze the product for months and end in a high-risk switch-over. Not an option for a company that must keep selling and invoicing.
- Keep the ideas, not the code. An earlier rewrite attempt had drifted too far to be merged: its good concepts are kept, not its implementation.
The strategy: strangler fig
Like the strangler fig that grows around its host tree, the new foundation grows around the old one until it replaces it:
- Both systems coexist. The new foundation runs alongside the monolith; a routing layer sends each feature to one or the other.
- One switch-over per module. As soon as a domain is ready, its traffic moves to the new code. Everything else keeps running on the old one, with no interruption for users.
- Bounded risk. Each switch-over only touches a limited scope; as long as the old path exists, we can fall back to it.
- Legacy code goes away. Once the module is stable, the matching legacy code is deleted. The monolith shrinks at every step until it is gone.
Redesign, don’t port
Copying the legacy into a new framework would only move the debt. Every module follows the same cycle:
- Inventory of what exists: screens, rules, data, scheduled jobs.
- Tests that pin down what the business expects: amounts, states, permissions.
- Design document: domain model, invariants, permissions, volumes, journeys reviewed with users.
- Review by the lead developer and a business referent. No code before that.
- Implementation by AI, in small reviewed steps.
- Data migration, switch-over, then removal of the legacy code.
A low-risk pilot module validates the whole chain before the sensitive domains.
Architecture choices
- One module per business domain — customers, catalogue, sales, invoicing, payments, access control… Modules only talk through public contracts and events, and those boundaries are checked automatically.
- Built for growth. Every record belongs to a company and a site; long-running work goes through queues; reporting relies on aggregates; concurrency and replays are handled explicitly (unit allocation, invoice numbering, payment notifications).
AI within a frame
Code is produced by AI agents, whatever the tool: rules, procedures and guardrails live in the repository, in standard formats. Any rule that can become a test does — a test holds for every model, text does not. Every change is reviewed by another model and then by a human, and every change stays traceable, from ticket to released version.