Facturis — SaaS Business Management Platform
A multi-tenant SaaS platform for Moroccan businesses covering invoicing, sales, purchasing, stock and treasury. Built and run in production since 2022.
- Laravel 13
- Stancl Tenancy
- MySQL
- PHP 8.4
- Spatie Permission
- Spatie Model States
- Spatie Media Library
- mPDF
- Laravel Queues
- Blade
- Alpine.js
- Bootstrap
- PWA
- Linux
- Nginx
Overview
Facturis is a production SaaS platform built for Moroccan businesses. I have designed, developed, deployed and evolved it since 2022. It started as an invoicing tool and grew into a complete business management platform, with invoicing still at its core.
The problem
Small and mid-sized businesses often run sales, purchasing, stock and payments in separate tools or spreadsheets. Their documents and figures drift apart, and nothing gives them one reliable view of the business.
What Facturis does
- Sales: customers and prospects, estimates (devis), invoices, pro forma invoices, credit notes (avoirs), orders, delivery notes and payment tracking.
- Purchasing: suppliers, purchase orders, purchase invoices and expenses.
- Operations and finance: product and service catalogues, stock, treasury, VAT, aged balances, multi-currency, payment terms, recurring documents, custom fields and reporting.
- AI-assisted document capture: Facturis uses the DeepSeek API to extract data from documents (OCR), reducing manual data entry.
Connected workflows, not isolated modules
The key design decision was to connect these capabilities instead of building separate CRUD screens. An estimate becomes an order, then a delivery note, then an invoice. Payments, stock levels and customer balances update along the way. Every document takes part in a larger business workflow, so the numbers stay consistent across the platform.
Architecture
Database-per-tenant isolation
Facturis uses Stancl Tenancy with a database-per-tenant model. Each company gets its own isolated database, and a central database holds only platform and tenant information.
Central database → platform and tenant registry
Tenant A → dedicated database
Tenant B → dedicated database
Tenant C → dedicated database
Isolation means one company's financial data never shares a table with another's. It also makes the platform portable: a tenant can be moved to another database server or region without redesigning the data model. The trade-off is that everything must stay tenancy-aware, including tenant resolution, migrations, queued jobs, document processing and file storage.
A pragmatic modular monolith
I chose a modular monolith over enterprise patterns adopted for appearance. A typical request flows like this:
Form Request and authorization → Controller → Action → Service (where shared logic justifies it) → Eloquent → MySQL
Controllers stay small, and there are no repositories, CQRS layers or abstractions that don't earn their place.
Document lifecycles as state machines
Business documents move through defined states with Spatie Model States, so an estimate can only become an order, and an order a delivery note or invoice, through valid transitions. This keeps the connected workflows consistent and auditable.
My role
I own the platform end to end:
- Architecture: multi-tenant SaaS design, financial-domain modelling, database design and migrations, API architecture.
- Application: Laravel development, business workflows, authentication and authorization, queues and asynchronous processing, PDF document generation, AI/OCR integration.
- Infrastructure: production deployment on Linux, Nginx and PHP; cloud architecture and migrations; security; backups and disaster recovery; performance and reliability work.
Why it matters
Facturis is a long-running production system, not a short-lived project. Four years of real customers, real financial data and continuous evolution have shaped every part of it, from the data model to the recovery plan.