Skip to content
Edson Francisco
  • AgriTech & traceability
  • Multi-tenant SaaS

FAMS Mahala – free multi-tenant tier

FAMS as SaaS: self-service sign-up, per-company data isolation and plan limits.

Period
2026
Status
In production
Role
Backend developer: per-company roles, data isolation, plan limits, sign-up and deploy

Problem

Every FAMS client needed its own server and installation. For cooperatives and small companies that was too expensive, and there was no way to try the system without an implementation project.

Solution

A single shared installation, with each company isolated by company_id and a free plan with limits. Companies sign themselves up through a two-step form. When they grow, there is a path to export the company to a dedicated installation.

Technical decisions

  1. 01

    Shared schema with company_id

    Instead of one database per company, all share tables with company_id, and an Eloquent global scope (written by a colleague) filters the queries. One migration serves every tenant.

  2. 02

    Per-company Spatie roles

    Edson extended Spatie's Role model with company_id, so each company defines its own supervisors and technicians without seeing other companies' roles.

  3. 03

    Plan limits enforced on the server

    An EnforcesPlanLimits trait and a PlanLimitService block creating members, agents, fields and purchases beyond the plan, returning HTTP 422 with a translated message. The service has unit tests.

  4. 04

    Removing single-install shortcuts

    The old code assumed one company per server (Company::first()). Edson replaced those calls with the authenticated user's company in controllers, exports and providers.

Images

01 / 02 — FAMS Mahala landing page with the 'From paper to data' headline and the free plan limits

Technologies

  • Laravel
  • PHP
  • MySQL
  • GitHub Actions

Verifiable results

farmers on the free plan (up to 2 users, 0 MZN)
500
mahala.fams.co.mz (opens in a new tab)
models scoped by company_id
24

What I learned

Moving from one install per client to multi-tenant is mostly hunting hidden assumptions: every Company::first() or company config value was a place where one company's data could leak into another's.

SDGs

  • SDG 2 · Zero Hungerprimary

    The free plan brings smallholder registration and follow-up to cooperatives and small companies that could not afford their own server.

  • SDG 8 · Decent Work and Economic Growthprimary

    Companies sign up on their own within minutes and only pay when they grow, lowering the cost of digitising operations and payments.

  • SDG 9 · Industry, Innovation and Infrastructurecomplementary

    A single multi-tenant installation shares one digital infrastructure across many organisations, instead of a server per client.