CRM inmobiliario multi-tenant: varias agencias sobre una misma instalación, cada una viendo solo sus datos
Una agencia inmobiliaria trabaja simultáneamente dos lados del negocio que casi nunca conviven en el mismo software: el del vendedor, que capta propietarios y publica inmuebles, y el del comprador, que busca vivienda y necesita que alguien le cruce su demanda con la cartera disponible. TinoProp los une en una sola aplicación y decide qué ve cada empleado según su rol.
El sistema es multi-tenant: varias inmobiliarias comparten la misma instalación y base de datos, pero cada una accede exclusivamente a sus clientes, propiedades y operaciones. Un panel de SuperAdmin gestiona las agencias como inquilinos: alta, baja, configuración y límites.
Es mi proyecto intermodular del Grado Superior en DAM y el más grande del portafolio. Está construido en PHP sin frameworks, sin Composer y sin npm: cada pieza — enrutado, sesiones, permisos, internacionalización, exportación — está escrita a mano, que era precisamente el objetivo del ejercicio.
Métricas, gráficos con Chart.js y KPIs con widgets personalizables por usuario.
Gestión separada por lado del negocio, con fichas detalladas.
Pipeline Kanban de leads con arrastrar y soltar entre etapas.
Inventario de inmuebles de venta y alquiler con galería de imágenes.
Circuito específico para propiedades en régimen de alquiler.
Kanban de operación: captación → publicada → visitas → negociación → documentación → cerrada.
Programación y seguimiento con estados y recordatorios asociados.
Ciclo de oferta con estados de pendiente, aceptada, rechazada y contraoferta.
Seguimiento posterior al cierre de la operación.
Cruce automático entre la demanda de cada comprador y la cartera disponible.
Buscador multicriterio con filtros guardables por sección y usuario.
Alertas por fecha y hora vinculadas a prospectos y visitas.
Gestión documental por entidad: subida, generación de PDF y descarga.
Carga masiva de clientes y propiedades desde ficheros CSV.
Log de auditoría de todas las acciones realizadas.
Avisos automáticos de visitas pendientes y recordatorios vencidos.
Soporte interno entre los distintos niveles de la jerarquía.
Perfil, contraseña, widgets, tema, densidad de tablas e idioma.
Términos y condiciones versionados con aceptación obligatoria.
La jerarquía tiene 7 niveles con permisos acumulativos: cada rol hereda lo del inferior y añade su alcance. Los dos roles de nivel 1 son deliberadamente asimétricos: ven el mismo número de secciones, pero de lados opuestos del negocio.
| Nivel | Rol | Alcance |
|---|---|---|
| 99 | Super Admin | Control absoluto de la plataforma: inmobiliarias, usuarios y tickets |
| 5 | Jefe | Director de inmobiliaria. Control total de su tenant |
| 4 | Supervisor | Supervisa agentes y accede a herramientas de sistema |
| 3 | Marketing | Herramientas de difusión. Ve los dos lados, vendedor y comprador |
| 2 | Agente | Agente completo. Ve los dos lados |
| 1 | Agente Vendedor | Solo las secciones del lado vendedor |
| 1 | Agente Comprador | Solo las secciones del lado comprador |
Monolito modular con un punto de entrada y secciones autocontenidas. El aislamiento multi-tenant no se resuelve con bases de datos separadas sino con un filtro de inmobiliaria aplicado en la capa de acceso a datos, de forma que ninguna consulta puede devolver registros de otro inquilino.
Tinoprop/ ├── index.php # dashboard y punto de entrada ├── login.php · logout.php ├── aceptar-terminos.php # gate de T&C versionados ├── cambiar-password.php # cambio obligatorio en 1er login ├── inc/ # núcleo: auth, permisos, helpers, i18n ├── secciones/ # los 19 módulos funcionales ├── api/ # endpoints AJAX internos ├── database/ · sql/ # esquema y migraciones ├── scripts/ # utilidades de mantenimiento ├── storage/ # documentos y galerías subidas └── css/ · js/ # frontend sin bundler
18 tablas con claves ajenas e índices, motor InnoDB para tener
transacciones y cotejamiento utf8mb4_unicode_ci para que los acentos y
emojis no rompan nada.
| Tabla | Contenido |
|---|---|
| inmobiliarias | Los tenants de la plataforma, con su configuración y límites |
| usuarios | Cuentas con rol, inmobiliaria asignada y preferencias de interfaz |
| clientes | Compradores y vendedores, separados por lado del negocio |
| propiedades | Cartera de inmuebles con superficies, extras y estado de publicación |
| prospectos | Leads de captación con su etapa dentro del pipeline Kanban |
| visitas | Visitas programadas con agente, cliente, propiedad y estado |
| ofertas | Ofertas con su ciclo de aceptación, rechazo y contraoferta |
| recordatorios | Alertas por fecha y hora asociadas a prospectos y visitas |
| documentos | Documentación adjunta por entidad |
| peticiones | Tickets de soporte interno entre niveles jerárquicos |
| actividad | Log de auditoría de todas las acciones |
| etiquetas | Etiquetas personalizadas con color, reutilizables entre módulos |
password_hash().X-Frame-Options,
X-Content-Type-Options y HSTS con max-age de un
año.El repositorio conserva cada versión como una carpeta independiente, desde el primer prototipo hasta producción. No es un historial de commits: es el proyecto entero congelado en 41 momentos, lo que permite ver exactamente qué se añadió en cada paso.
Las cifras de arriba corresponden a la versión V1.0.3, que es el producto real: 48 archivos y 23.600 líneas. Sumar las 41 carpetas daría 254.000 líneas, pero sería contar el mismo código cuarenta y una veces.
La opción fácil era una base de datos por inmobiliaria, pero eso obliga a replicar
migraciones N veces y encarece el hosting. Opté por una sola base con
inmobiliaria_id en cada tabla y el filtro aplicado en la capa de acceso
a datos, no en cada consulta suelta: así una sección nueva hereda el aislamiento sin
que haya que recordar añadirlo.
Con siete niveles, un sistema de permisos por casuística se vuelve inmantenible. La solución fue hacer los permisos acumulativos por nivel numérico: comprobar acceso es comparar enteros. Los dos roles de nivel 1 son la excepción deliberada — mismo nivel, secciones distintas — porque el negocio realmente tiene dos lados simétricos.
Era el requisito del proyecto intermodular, pero acabó siendo lo más formativo: escribir a mano el enrutado, las sesiones, la i18n y la exportación obliga a entender qué hace Laravel por debajo. El coste es evidente en volumen de código; el beneficio es que despliega en cualquier hosting compartido sin build ni dependencias.
Desarrollador full stack — autor único.
Análisis de requisitos, modelo de datos, arquitectura multi-tenant, sistema de roles, los 19 módulos, el frontend completo y el despliegue. También la documentación del repositorio: LICENSE, SECURITY.md, CONTRIBUTING.md y CODE_OF_CONDUCT.md.
En producción desde la versión V1.0.0, actualmente en V1.0.3 tras tres iteraciones de corrección. Presentado como proyecto intermodular del Grado Superior en Desarrollo de Aplicaciones Multiplataforma.