Desarrollo Laravel en Marruecos
Laravel es mi backend principal para SaaS multi-tenant, facturación, permisos, colas y dominio denso — desde Tánger, para APIs de las que se puede depender.
El trabajo no es «CRUD en un fin de semana». Es modelar el dominio, aislar tenants, mantener los jobs fiables y escribir APIs de las que otros equipos puedan depender.
Multi-tenancy suele significar scoping a nivel de consulta, no solo una columna tenant_id que un WHERE olvidado puede saltarse. Las colas corren sobre Redis para que un job lento — una exportación, un lote de emails, un reintento de webhook — no bloquee la petición que lo disparó, y los jobs fallidos quedan visibles en vez de perderse en silencio.
Facturación y permisos se modelan juntos desde el inicio: un plan define qué puede hacer un rol, y los eventos de suscripción de Stripe mantienen ese mapeo al día cuando un tenant sube, baja o cancela. AnyWare ERP y BROC ServiceOS funcionan así — Laravel debajo, PostgreSQL para los datos, Redis para los jobs que tienen que ser fiables.
Me hago cargo de codebases Laravel existentes casi tan seguido como empiezo nuevas. La mayor parte de ese trabajo es deshacer consultas que se saltan el scoping por tenant, jobs sin estrategia de reintento, o comprobaciones de permisos dispersas en controladores en vez de centralizadas — el tipo de deuda que parece bien hasta que llega un segundo cliente.
Problemas de negocio
- CRUD que no expresa tenancy, facturación ni permisos, así que cada nuevo requisito se añade como caso especial en vez de encajar en un modelo pensado para contenerlo.
- Jobs y cachés que se filtran entre clientes, porque una clave de caché o una carga de job se construyó sin pensar en el aislamiento por tenant desde el inicio.
- APIs REST de las que el frontend no puede depender, porque la forma de una respuesta cambia sin subir de versión y nadie fuera del equipo backend se entera hasta que algo se rompe.
- Una app Laravel donde cada controlador habla directamente con los modelos Eloquent sin capa de servicio, así que la misma regla de negocio se copia y pega en tres controladores y solo dos se actualizan cuando cambia.
- Feature flags y configuración fijadas por entorno en vez de gobernadas por la base de datos, así que activar algo para un tenant significa un deploy en vez de un simple interruptor.
- Consultas N+1 enviadas porque Eloquent facilita el lazy-load de una relación dentro de un bucle sin darse cuenta, hasta que una página que iba bien con diez filas hace timeout con diez mil.
- Migraciones cuyo rollback nunca se ha probado, así que un mal deploy no se puede deshacer limpiamente de verdad y el arreglo se convierte en una reparación manual de la base bajo presión.
Proceso de desarrollo
- Modelar el dominio en PHP: tenants, auth, colas, PostgreSQL, Redis — el límite de tenant aplicado en la capa de consultas, no dejado a la memoria de cada controlador.
- Entregar APIs REST versionadas, luego la UI de admin o producto que las consume, para que el contrato quede fijo antes de construir la interfaz que depende de él.
- Cubrir los fallos y reintentos de colas en el mismo paso que el caso normal, porque un job que desaparece silenciosamente en su primer fallo es peor que no tener job.
- Usar deliberadamente las colas y eventos de Laravel — jobs para todo lo lento o externo, eventos para todo aquello a lo que otra parte del sistema debe reaccionar — en vez de meterlo todo en un método de controlador.
- Escribir tests funcionales contra la capa de API, no solo tests unitarios sobre clases aisladas, para que una suite de tests en verde signifique de verdad que el producto funciona de extremo a extremo.
- Precargar relaciones deliberadamente y comprobar el número de consultas en páginas que listan algo, para que un problema N+1 se detecte en desarrollo y no al llegar datos reales.
- Probar que las migraciones revierten limpiamente, no solo que se ejecutan hacia adelante, para que un mal deploy tenga una reversión real en vez de una reparación manual.
Qué obtienes
- SaaS, ERP y apps de negocio mantenibles tras el segundo cliente, cuando los supuestos hechos para un tenant se cruzan con un segundo que hace las cosas distinto.
- Arquitectura desde Tánger que equipos europeos pueden leer y extender, porque el vocabulario del dominio en el código coincide con el que usa el negocio de verdad.
- Un backend en el que otros desarrolladores — míos o contratados por el cliente — se ponen al día en días, no semanas, porque el vocabulario del dominio en el código coincide con el negocio.
- Menos alertas a las 2 de la madrugada, porque los fallos de colas, las fugas entre tenants y los bugs de permisos se diseñaron para evitarse en vez de descubrirse en producción.
- Páginas que siguen rápidas a medida que crecen los datos, porque los patrones de consulta se comprobaron contra volúmenes realistas, no solo una base de dev vacía.
- Un camino de rollback real cuando un deploy sale mal, en vez de una reparación manual de la base hecha bajo presión.
Proyectos seleccionados
FAQ
Is Laravel suitable for SaaS?
Yes, when tenancy, queues, billing and permissions are designed from the start. I build Laravel SaaS that way by default.
Do you build REST APIs with Laravel?
Yes. Versioned REST APIs with authentication, rate limits, and documentation that frontend and mobile teams can actually use.