Architecture, stack, key decisions and the quality gates DEV3 Balayo passed before release.
The engineering behind Balayo: appointments as chains of stages that hold different stations, deadlines enforced on read, tenant isolation by team id and a till that settles several tenders on one sale.
The problem it solves
A salon day is a scheduling problem with gaps in it. A colour client develops for forty minutes while the stylist is free, but the chair or basin is still held. Two desks can reach for the same gap, a patch test can be too recent, a deposit hold can expire mid-checkout, and one install serves many salons whose data must never meet. Money arrives as deposits, gift cards, cash, card and tips on a single sale.
Architecture and approach
Balayo is a Laravel 12 application with a Filament 4 super-admin at /admin, a salon back office at /business, a public website with tenant pages and a client account, and a REST API used by two Flutter apps.
Stage chains
A service is a chain of stages (apply, process, rinse). Each stage holds a stylist, a chair or a basin for its own minutes, so a processing stage frees the stylist but keeps the chair. A time is offered only if the whole chain fits, and the server refuses a stage whose basin, station or stylist is taken.
Deadlines on read
Deposit holds, waitlist offers and memberships carry deadlines that are applied under a lock whenever a record is read or acted on, so nothing depends on the scheduler. A tick command only catches records nobody is looking at and retries refunds.
Tenancy
Every tenant table carries a team id, and a request for another salon's record is a 404. Plan features and limits are enforced on the server, and a suspended salon stays readable but refuses writes.
The till
One sale can take a deposit, a gift card, cash, card and a tip together. Services are untaxed, retail takes a sales tax, tips are split between the stylists who worked and a closed till shows the over or short figure.
Apps
The client and staff apps share one API contract with the server, run Dart ports of the server's cancel-fee and chain maths against shared vectors, and start in a demo mode that needs no server.
Quality gates and results
Balayo 1.0.0 ran 393 Pest tests with 4,478 assertions and a headless-browser pass over 36 pages and 45 race checks, both shortly before a few small final edits. The installer test and the secret scan passed on the final zip. The full release-gate run was not repeated on the final code. The client and staff apps passed analysis and 317 and 297 tests before a last text change.
Limits are listed on the item page: the operator is merchant of record, card terminals are recorded and not integrated, there is no card-on-file no-show fee, auto-renew on a real gateway needs buyer work, Stripe refunds have no idempotency key yet and the apps were tested on simulators only.
Tech stack
| Area |
Technologies |
| Application |
Laravel 12, Filament 4, Blade, REST API |
| Salon |
Stage chains and stations, Floor calendar and Floor Plan, Patch tests and consent, Gram-level formulas |
| Money |
Split-tender till, Gift cards and packages, Memberships with grace, Commission and pay statements |
| Apps |
Flutter client app, Flutter staff app, Shared dev3 Flutter package, Demo mode |
| Quality |
Pest, Static analysis, Headless browser smoke, Shared test vectors |
Inside the build
Hero — A professional photo of a bright salon floor sits in an arch beside the headline, the trial button and the trust points on a warm cream page.
The gap — A stylist is free while a colour develops: a flat day lane shows the free stretch filled by a fringe trim.