Laroo — Laravel ERP project

Laravel ERP covering inventory, billing and CRM for growing teams.

Laroo — Laravel ERP project
Role
Founder, full stack developer
Stack
Laravel 12 · Livewire 4
Architecture
24 installable modules
Status
Live

Context

Odoo set a model for ERPs: modules you install as you need them, record-level access rules and several companies in one instance. But it ties you to Python and its own framework. Laroo asks the question: can that modular logic live in the Laravel ecosystem?

Business challenge

Deliver lightweight ERP modules (stock, billing, CRM) on Laravel.

Solution

A Laravel 12 monolith split into 24 Odoo-style modules, each with its module.json manifest, dependencies and service provider. A manager installs modules in dependency order. Business logic lives in about a hundred services connected by events, and multi-company works through the /app/{company}/… URL and global Eloquent scopes.

Outcome

An ERP online with a back office, customer portal and REST API: CRM, sales and purchasing, valued inventory, accounting, HR, manufacturing and quality, marketing, and a Studio to add fields and views without code. Differences from Odoo are documented module by module.

My role

Lead developer

Architecture

Users

  • Back office /app/{company}
  • Customer portal
  • REST API v1 (Sanctum)
  • Inbound webhooks

Application

  • Laravel 12 · Livewire 4
  • ModuleManager: 24 modules
  • 102 services · 120 policies
  • Company scopes and access rules
  • Events and listeners
  • Database queue · 11 jobs · scheduler

External services

  • MySQL 8
  • Twilio · Vonage (SMS)
  • Resend (e-mail)
  • Sentry · PostHog
  • nginx · PHP-FPM (Docker)

The flow, step by step

  1. Company

    The /app/{company}/… request checks the user has access to it, then sets the current company.

  2. Order

    Confirming a sales order fires the SaleOrderConfirmed event.

  3. Confirmation

    A listener queues the confirmation e-mail to the customer.

  4. Inventory

    Validating the stock move computes the cost (FIFO or average) and updates quantities, in a single transaction.

  5. Reactions

    Listeners create the valuation entries and, when needed, quality checks.

  6. Accounting

    Posting checks that debit and credit balance to the cent, then marks the entry as posted.

Data model

The main entities, their key fields and their relations.

Company

  • name · slug
  • email
  • timezone
  • 1—n User
  • 1—n SaleOrder
  • 1—n AccountMove

Product

  • default_code · type
  • list_price · standard_price
  • qty_available
  • FIFO or average costing
  • 1—n StockMove
  • 1—n StockQuant

SaleOrder

  • partner_id
  • order_ref
  • state
  • amount_total
  • 1—n SaleOrderLine
  • 1—n AccountMove

StockMove

  • product_id
  • location_from_id · location_dest_id
  • quantity · state
  • n—1 Location
  • 1—n StockValuationLayer

StockQuant

  • product_id · location_id
  • quantity
  • reserved_quantity
  • n—1 Product
  • n—1 Location

AccountMove

  • journal_id · ref · date
  • state · move_type
  • 1—n AccountMoveLine (debit, credit)
  • n—1 AccountJournal

RecordRule

  • model
  • role_id
  • domain_expression
  • company_id
  • n—1 Role

Module

  • technical name
  • dependencies
  • install state

Full technical sheet

Languages
PHP 8.4, JavaScript
Framework
Laravel 12
Front end
Blade (742 views), Livewire 4, Tailwind 4, Vite 7, Chart.js
Admin
In-house Odoo-style back office, platform admin area
Database
MySQL 8, in-memory SQLite for tests
Queues and scheduler
Database queue, Docker worker, 11 jobs; scheduled tasks: automated actions, recurring entries, revenue recognition, payment reminders
Authentication and roles
Session and Sanctum, roles and permissions, 120 policies, record-level access rules
Multi-company
Global CompanyScope, records shareable across companies
Integrations
Twilio and Vonage SMS, Resend e-mail, verified inbound webhooks, HMAC-SHA256-signed outbound webhooks
Hosting
Multi-stage Docker (nginx, PHP-FPM 8.4), Supervisor
CI/CD
GitHub Actions: PHPUnit and PHPStan on PHP 8.4, pre-push hook
Tests
PHPUnit 11 (274 test files), Playwright
Quality
PHPStan level 6, Pint, Conventional Commits
Observability
Sentry, PostHog, activity log, audit log
Languages (UI)
French and English complete, Spanish and Dutch partial

Key features

  • CRM

    Kanban pipeline, lead scoring and assignment rules.

  • Sales and purchasing

    Orders, receipts, blanket orders and price lists.

  • Inventory

    Moves, lots, replenishment, FIFO or average costing.

  • Accounting

    Journal entries, bank reconciliation, credit notes, recurring entries, reminders.

  • HR and manufacturing

    Leave, attendance, payroll; bills of materials, manufacturing orders, quality checks.

  • Studio

    Custom fields, views and automated actions without code.

Problems solved

  1. Isolation between companies

    ProblemEvery query must only see the current company’s data, except what is explicitly shared.

    FixA global scope that also accepts records shared through a dedicated table.

  2. Concurrent numbering

    ProblemTwo invoices created at the same moment could get the same number.

    FixRow lock (lockForUpdate) on the sequence.

  3. Consistent stock and value

    ProblemA half-validated move left quantities and valuation out of sync.

    FixCost layers consumed and quantities updated in a single transaction.

  4. Per-company URLs

    ProblemThe current company only lived in the session, which made links ambiguous.

    FixRouting redesign: the company is in the URL and in the route defaults.

  5. Hardening

    ProblemSome sensitive controllers didn’t always check permissions.

    FixSystematic authorisation, Form Requests and webhook signature checks.

Technical choices

Choice Why
Odoo-style modules A manifest with dependencies: install only what you need, in the right order.
Domain-based access rules An expression parser inspired by Odoo domains filters records by role.
Livewire rather than an SPA Hundreds of management screens rendered server-side, without an API to maintain for each.
Switch-off observability Without a DSN, Sentry is off with no network call.

Timeline

  1. March 2026 First commit of the current repository, ERP schema
  2. March 2026 Services, policies, API and Studio
  3. May 2026 Accounting, sales, inventory, manufacturing and quality
  4. June 2026 SMS marketing and security audit
  5. August 2026 Sentry, PostHog and Resend
  6. August 2026 Per-company routing

In numbers

24
modules
253
models
306
migrations
1,256
routes

Taken from the project’s source code and Git history on 8 October 2026. No usage or revenue figures are published.

Related projects

SaaS
Oct 2024 — present
Vetzy — Laravel SaaS project
SaaS veterinary booking platform for clinics and pet owners with scheduling, notifications and client portal.
PHP, Laravel, Livewire, TailwindCSS, SaaS
View project
SaaS
Jan 2024 — present
StreamCrea — Creator dashboard
Twitch, YouTube and Kick sync, multi-network publishing and a subscriber blog.
PHP, Laravel, Livewire, Stripe
View project
SaaS
Jan 2022 — Dec 2022
MissionsCMS — Web App project
Mission management system with tracking dashboards and workflow tools.
Laravel, Livewire, Alpine.js, TailwindCSS
View project
SaaS
Sep 2025 — present
Lodate — Web App project
Appointment scheduling system with reminders and clean interface navigation.
Laravel, Livewire, Alpine.js, TailwindCSS
View project

Available for PHP / Laravel / WordPress / Silverstripe missions in Belgium and remote EU.