🏠 TinoProp CRM
CRM inmobiliario multi-tenant: varias agencias sobre una misma instalación, cada una viendo solo sus datos
Escala del Proyecto
Descripción General
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.
Tecnologías Utilizadas
PHP 8.x
MySQL / MariaDB
PDO
JavaScript ES6+
CSS3 puro
Chart.js
i18n es / en
Apache
Los 19 Módulos del Sistema
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.
Sistema de Roles y Permisos
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 |
Arquitectura
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
Base de Datos
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 |
Características Transversales
- Buscador global en el sidebar que consulta clientes, propiedades y prospectos a la vez.
- Favoritos: cualquier sección se marca para acceso rápido.
- Internacionalización completa en español e inglés.
- Tres temas — sistema, claro y oscuro — con persistencia por usuario.
- Densidad de tablas configurable en media, cómoda o compacta.
- Filtros guardados por sección y por usuario, para no repetir la misma búsqueda cada día.
- Etiquetas con color definibles y compartidas entre módulos.
- Exportación a CSV de cualquier listado.
Flujo Completo de Negocio
- Alta del tenant: el SuperAdmin crea la inmobiliaria y su usuario Jefe, con contraseña temporal.
- Primer acceso: el usuario acepta los términos versionados y cambia obligatoriamente la contraseña.
- Captación: entra un lead como prospecto y avanza por el pipeline Kanban arrastrándolo entre etapas.
- Alta de propiedad: el prospecto captado se convierte en propiedad de la cartera con su galería.
- Demanda del comprador: se registra al cliente comprador con su presupuesto, zona y requisitos.
- Matching: el sistema cruza esa demanda con la cartera y propone los inmuebles compatibles.
- Visitas: se programan y quedan reflejadas con recordatorio y notificación al agente.
- Oferta: se registra la oferta y se resuelve como aceptada, rechazada o contraoferta.
- Cierre y documentación: el Kanban de proceso llega a documentación y la operación se cierra.
- Post-venta: el módulo de post-venta mantiene el seguimiento del cliente ya cerrado.
Seguridad Implementada
- Contraseñas hasheadas con bcrypt mediante
password_hash(). - Contraseñas temporales con cambio obligatorio en el primer inicio de sesión.
- Protección CSRF con token por formulario.
- Escape XSS en toda la salida HTML.
- Prepared statements PDO en el 100% de las consultas: nunca concatenación.
- Rate limiting contra ataques de fuerza bruta en el login.
- Cabeceras de seguridad:
X-Frame-Options,X-Content-Type-Optionsy HSTS con max-age de un año. - Redirección forzada a HTTPS y protección de directorios y ficheros de configuración.
- Aislamiento entre tenants verificado en la capa de datos, no solo en la interfaz.
- Términos y condiciones versionados con registro de aceptación por usuario.
Evolución en 41 Versiones
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.
- V0.0.01Web de presentación para vender el producto.
- V0.0.03Primer módulo real: gestión de clientes.
- V0.0.07Inmuebles, el corazón de la cartera.
- V0.0.08Dashboard con métricas y gráficos.
- V0.0.09Rediseño de la base de datos con claves ajenas e índices.
- V0.0.13Kanban con arrastrar y soltar.
- V0.0.14Inicio personalizable con widgets por usuario.
- V0.0.16Sistema de recordatorios.
- V0.0.17Galería de imágenes por propiedad.
- V0.0.19Búsqueda avanzada multicriterio.
- V0.0.21Preferencias de interfaz: tema y densidad de tablas.
- V0.0.22Internacionalización español / inglés.
- V0.0.24Autenticación reforzada.
- V0.0.26Módulo de visitas.
- V0.0.29Jerarquía definitiva de 7 niveles de usuario.
- V0.0.30Preparación para producción.
- V0.0.31Documentación del código.
- V1.0.0Primera versión en producción.
- V1.0.3Versión actual, tras tres rondas de corrección de errores.
Retos Técnicos y Decisiones de Diseño
Multi-tenant sin multiplicar bases de datos
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.
Siete roles sin convertirlo en un laberinto
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.
Por qué PHP sin frameworks
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.
Mi Rol
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.
Estado del Proyecto
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.