feat: Documentation and orchestration updates
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
1ddb20e282
commit
f570727617
240
AGENTS.md
Normal file
240
AGENTS.md
Normal file
@ -0,0 +1,240 @@
|
||||
---
|
||||
id: "AGENTS-IA"
|
||||
title: "Guia para Agentes IA - Inmobiliaria Analytics"
|
||||
type: "Agent Guide"
|
||||
project: "inmobiliaria-analytics"
|
||||
version: "1.0.0"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# AGENTS.md - Inmobiliaria Analytics
|
||||
|
||||
Guia completa para que agentes de IA trabajen con el proyecto Inmobiliaria Analytics.
|
||||
|
||||
---
|
||||
|
||||
## Informacion del Proyecto
|
||||
|
||||
| Campo | Valor |
|
||||
|-------|-------|
|
||||
| **Nombre** | Inmobiliaria Analytics |
|
||||
| **Prefijo** | IA |
|
||||
| **Repositorio** | inmobiliaria-analytics |
|
||||
| **Estado** | Planificado |
|
||||
| **Stack** | NestJS, React, PostgreSQL, TypeORM |
|
||||
|
||||
---
|
||||
|
||||
## Estructura del Proyecto
|
||||
|
||||
```
|
||||
inmobiliaria-analytics/
|
||||
├── apps/
|
||||
│ ├── backend/ # API NestJS (puerto 3101)
|
||||
│ ├── frontend/ # UI React (puerto 3100)
|
||||
│ └── database/ # Schemas PostgreSQL
|
||||
├── docs/ # Documentacion GAMILIT
|
||||
├── orchestration/ # Directivas y contexto
|
||||
├── AGENTS.md # Este archivo
|
||||
├── INVENTARIO.yml # Inventario del proyecto
|
||||
└── .env.ports # Puertos asignados
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Puertos Asignados
|
||||
|
||||
| Servicio | Puerto | Protocolo |
|
||||
|----------|--------|-----------|
|
||||
| Frontend | 3100 | HTTP |
|
||||
| Backend API | 3101 | HTTP |
|
||||
| WebSocket | 3102 | WS |
|
||||
| PostgreSQL | 5439 | TCP |
|
||||
| Redis | 6386 | TCP |
|
||||
|
||||
---
|
||||
|
||||
## Nomenclatura
|
||||
|
||||
### Prefijos por Tipo de Documento
|
||||
|
||||
| Tipo | Prefijo | Ejemplo |
|
||||
|------|---------|---------|
|
||||
| EPIC | IA-NNN | IA-001-fundamentos |
|
||||
| Requerimiento | RF-IA-NNN | RF-IA-001 |
|
||||
| Especificacion | ET-IA-NNN | ET-IA-001 |
|
||||
| Historia Usuario | US-IA-NNN | US-IA-001 |
|
||||
| Tarea | TASK-NNN | TASK-001 |
|
||||
| Bug | BUG-NNN | BUG-001 |
|
||||
| ADR | ADR-NNN | ADR-001 |
|
||||
|
||||
### Categorias de US
|
||||
|
||||
| Prefijo | EPIC | Descripcion |
|
||||
|---------|------|-------------|
|
||||
| FUND | IA-001 | Fundamentos |
|
||||
| PROP | IA-002 | Propiedades |
|
||||
| ANA | IA-003 | Analytics |
|
||||
| REP | IA-004 | Reportes |
|
||||
|
||||
---
|
||||
|
||||
## Como Trabajar con el Proyecto
|
||||
|
||||
### Tomar una Tarea
|
||||
|
||||
1. Revisar `docs/planning/Board.md` - columna "Por Hacer"
|
||||
2. Leer archivo `TASK-XXX.md` correspondiente
|
||||
3. Editar YAML front-matter:
|
||||
```yaml
|
||||
status: "In Progress"
|
||||
assignee: "@NombreAgente"
|
||||
```
|
||||
4. Commit: `Start TASK-XXX: [descripcion]`
|
||||
|
||||
### Completar una Tarea
|
||||
|
||||
1. Verificar criterios de aceptacion cumplidos
|
||||
2. Editar YAML front-matter:
|
||||
```yaml
|
||||
status: "Done"
|
||||
completed_date: "YYYY-MM-DD"
|
||||
```
|
||||
3. Actualizar `Board.md` - mover a "Hecho"
|
||||
4. Commit: `Complete TASK-XXX: [descripcion]`
|
||||
|
||||
### Reportar un Bug
|
||||
|
||||
1. Crear archivo `docs/planning/bugs/BUG-XXX.md`
|
||||
2. Incluir YAML front-matter obligatorio:
|
||||
```yaml
|
||||
---
|
||||
id: "BUG-XXX"
|
||||
title: "Descripcion del bug"
|
||||
type: "Bug"
|
||||
status: "Open"
|
||||
severity: "P1"
|
||||
priority: "Alta"
|
||||
affected_module: "Backend"
|
||||
steps_to_reproduce:
|
||||
- "Paso 1"
|
||||
- "Paso 2"
|
||||
expected_behavior: "..."
|
||||
actual_behavior: "..."
|
||||
created_date: "YYYY-MM-DD"
|
||||
---
|
||||
```
|
||||
3. Agregar a `Board.md` en columna "Bugs"
|
||||
|
||||
---
|
||||
|
||||
## Archivos Importantes
|
||||
|
||||
| Archivo | Proposito |
|
||||
|---------|-----------|
|
||||
| `docs/planning/Board.md` | Tablero Kanban activo |
|
||||
| `docs/planning/config.yml` | Configuracion SCRUM |
|
||||
| `docs/04-fase-backlog/DEFINITION-OF-READY.md` | Criterios para iniciar |
|
||||
| `docs/04-fase-backlog/DEFINITION-OF-DONE.md` | Criterios para completar |
|
||||
| `docs/_MAP.md` | Mapa de navegacion |
|
||||
| `INVENTARIO.yml` | Inventario del proyecto |
|
||||
|
||||
---
|
||||
|
||||
## Estados Validos
|
||||
|
||||
### User Story
|
||||
|
||||
- `Backlog`: No planificada
|
||||
- `To Do`: Planificada para sprint
|
||||
- `In Progress`: En desarrollo
|
||||
- `In Review`: En revision
|
||||
- `Done`: Completada
|
||||
|
||||
### Task
|
||||
|
||||
- `To Do`: Pendiente
|
||||
- `In Progress`: En desarrollo
|
||||
- `Blocked`: Bloqueada
|
||||
- `Done`: Completada
|
||||
|
||||
### Bug
|
||||
|
||||
- `Open`: Reportado
|
||||
- `In Progress`: En investigacion
|
||||
- `Fixed`: Corregido, pendiente validacion
|
||||
- `Done`: Validado y cerrado
|
||||
- `Won't Fix`: No se corregira
|
||||
|
||||
---
|
||||
|
||||
## Convenciones de Commits
|
||||
|
||||
```
|
||||
<tipo>(<alcance>): <descripcion>
|
||||
|
||||
Tipos:
|
||||
- feat: Nueva funcionalidad
|
||||
- fix: Correccion de bug
|
||||
- docs: Documentacion
|
||||
- refactor: Refactorizacion
|
||||
- test: Tests
|
||||
- chore: Tareas de mantenimiento
|
||||
|
||||
Ejemplos:
|
||||
- feat(auth): Implementar login con JWT
|
||||
- fix(api): Corregir validacion de propiedades
|
||||
- docs(readme): Actualizar instrucciones de setup
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Flujo de Trabajo Recomendado
|
||||
|
||||
```
|
||||
1. CONTEXTO
|
||||
- Leer AGENTS.md (este archivo)
|
||||
- Revisar Board.md para estado actual
|
||||
- Identificar tarea a trabajar
|
||||
|
||||
2. ANALISIS
|
||||
- Leer documentacion relacionada (RF, ET, US)
|
||||
- Revisar codigo existente
|
||||
- Identificar dependencias
|
||||
|
||||
3. PLANEACION
|
||||
- Desglosar en subtareas si es necesario
|
||||
- Estimar esfuerzo
|
||||
- Actualizar status a "In Progress"
|
||||
|
||||
4. VALIDACION
|
||||
- Verificar entendimiento con DoR
|
||||
- Confirmar que no hay bloqueantes
|
||||
|
||||
5. EJECUCION
|
||||
- Implementar solucion
|
||||
- Escribir tests
|
||||
- Documentar cambios
|
||||
|
||||
6. DOCUMENTACION
|
||||
- Actualizar _MAP.md si aplica
|
||||
- Marcar tarea como "Done"
|
||||
- Commit con mensaje descriptivo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Contacto y Escalamiento
|
||||
|
||||
| Rol | Responsabilidad |
|
||||
|-----|-----------------|
|
||||
| @Backend-Agent | APIs, servicios, base de datos |
|
||||
| @Frontend-Agent | UI, componentes, estado |
|
||||
| @DevOps-Agent | CI/CD, infraestructura |
|
||||
| @Tech-Lead | Decisiones arquitectonicas |
|
||||
|
||||
---
|
||||
|
||||
**Generado:** 2026-01-04
|
||||
**Sistema:** NEXUS v3.4 + SIMCO + GAMILIT Standard
|
||||
254
docs/00-vision-general/ARQUITECTURA-GENERAL.md
Normal file
254
docs/00-vision-general/ARQUITECTURA-GENERAL.md
Normal file
@ -0,0 +1,254 @@
|
||||
---
|
||||
id: "ARCH-IA"
|
||||
title: "Arquitectura General - Inmobiliaria Analytics"
|
||||
type: "Architecture Document"
|
||||
version: "1.0.0"
|
||||
status: "Draft"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# Arquitectura General - Inmobiliaria Analytics
|
||||
|
||||
---
|
||||
|
||||
## Vision Arquitectonica
|
||||
|
||||
Arquitectura basada en microservicios con separacion clara entre frontend, backend y datos, optimizada para analytics de alto rendimiento.
|
||||
|
||||
---
|
||||
|
||||
## Diagrama de Alto Nivel
|
||||
|
||||
```
|
||||
+------------------+
|
||||
| Load Balancer |
|
||||
| (Traefik) |
|
||||
+--------+---------+
|
||||
|
|
||||
+-----------------+-----------------+
|
||||
| |
|
||||
+----------v----------+ +-----------v-----------+
|
||||
| Frontend | | Backend |
|
||||
| React + Vite | | NestJS |
|
||||
| Puerto: 3100 | | Puerto: 3101 |
|
||||
+----------+----------+ +-----------+-----------+
|
||||
| |
|
||||
| +--------------+--------------+
|
||||
| | | |
|
||||
| +--------v----+ +------v------+ +----v-----+
|
||||
| | Auth | | Properties | | Analytics|
|
||||
| | Module | | Module | | Module |
|
||||
| +--------+----+ +------+------+ +----+-----+
|
||||
| | | |
|
||||
| +--------------+--------------+
|
||||
| |
|
||||
| +--------------v--------------+
|
||||
| | PostgreSQL |
|
||||
+--------------------+ Puerto: 5439 |
|
||||
| Schemas: public, |
|
||||
| properties, analytics |
|
||||
+-----------------------------+
|
||||
|
|
||||
+-------------v-------------+
|
||||
| Redis |
|
||||
| Puerto: 6386 |
|
||||
| Cache + Sessions |
|
||||
+---------------------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Capas de la Arquitectura
|
||||
|
||||
### 1. Capa de Presentacion (Frontend)
|
||||
|
||||
| Componente | Tecnologia | Proposito |
|
||||
|------------|------------|-----------|
|
||||
| SPA | React 18.x | Interfaz de usuario |
|
||||
| Build | Vite | Bundling y desarrollo |
|
||||
| Estado | Zustand | Manejo de estado global |
|
||||
| UI Kit | Tailwind CSS | Estilos |
|
||||
| Charts | Recharts | Visualizaciones |
|
||||
|
||||
### 2. Capa de Aplicacion (Backend)
|
||||
|
||||
| Componente | Tecnologia | Proposito |
|
||||
|------------|------------|-----------|
|
||||
| API Server | NestJS 10.x | Framework HTTP |
|
||||
| ORM | TypeORM 0.3.x | Acceso a datos |
|
||||
| Auth | Passport + JWT | Autenticacion |
|
||||
| Validation | class-validator | Validacion de DTOs |
|
||||
| Docs | Swagger/OpenAPI | Documentacion API |
|
||||
|
||||
### 3. Capa de Datos
|
||||
|
||||
| Componente | Tecnologia | Proposito |
|
||||
|------------|------------|-----------|
|
||||
| RDBMS | PostgreSQL 16 | Datos principales |
|
||||
| Cache | Redis 7 | Caching y sesiones |
|
||||
| Search | (Futuro) Elasticsearch | Busqueda avanzada |
|
||||
|
||||
---
|
||||
|
||||
## Modulos del Sistema
|
||||
|
||||
### IA-001: Fundamentos
|
||||
|
||||
```
|
||||
src/modules/
|
||||
├── auth/ # Autenticacion y autorizacion
|
||||
│ ├── auth.module.ts
|
||||
│ ├── auth.service.ts
|
||||
│ ├── auth.controller.ts
|
||||
│ ├── strategies/
|
||||
│ │ ├── jwt.strategy.ts
|
||||
│ │ └── local.strategy.ts
|
||||
│ └── guards/
|
||||
│ └── jwt-auth.guard.ts
|
||||
└── users/ # Gestion de usuarios
|
||||
├── users.module.ts
|
||||
├── users.service.ts
|
||||
└── entities/
|
||||
└── user.entity.ts
|
||||
```
|
||||
|
||||
### IA-002: Propiedades (Planificado)
|
||||
|
||||
```
|
||||
src/modules/
|
||||
├── properties/ # CRUD de propiedades
|
||||
├── locations/ # Ubicaciones geograficas
|
||||
└── valuations/ # Valuaciones
|
||||
```
|
||||
|
||||
### IA-003: Analytics (Planificado)
|
||||
|
||||
```
|
||||
src/modules/
|
||||
├── analytics/ # Motor de analytics
|
||||
├── reports/ # Generacion de reportes
|
||||
└── dashboards/ # Configuracion de dashboards
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Esquemas de Base de Datos
|
||||
|
||||
### Schema: public
|
||||
|
||||
Tablas de sistema y usuarios:
|
||||
- `users` - Usuarios del sistema
|
||||
- `roles` - Roles y permisos
|
||||
- `sessions` - Sesiones activas
|
||||
|
||||
### Schema: properties
|
||||
|
||||
Datos inmobiliarios:
|
||||
- `properties` - Catalogo de propiedades
|
||||
- `property_types` - Tipos (casa, depto, etc)
|
||||
- `locations` - Ubicaciones geograficas
|
||||
- `valuations` - Historial de valuaciones
|
||||
|
||||
### Schema: analytics
|
||||
|
||||
Datos analiticos:
|
||||
- `market_trends` - Tendencias de mercado
|
||||
- `price_indices` - Indices de precios
|
||||
- `reports` - Reportes generados
|
||||
|
||||
---
|
||||
|
||||
## Flujos Principales
|
||||
|
||||
### Autenticacion
|
||||
|
||||
```
|
||||
1. Usuario envia credenciales
|
||||
2. Backend valida con LocalStrategy
|
||||
3. Si valido, genera JWT
|
||||
4. Frontend almacena token
|
||||
5. Requests subsecuentes incluyen Bearer token
|
||||
6. JwtAuthGuard valida en cada request protegido
|
||||
```
|
||||
|
||||
### Consulta de Analytics
|
||||
|
||||
```
|
||||
1. Frontend solicita datos del dashboard
|
||||
2. Backend verifica cache en Redis
|
||||
3. Si cache hit, retorna datos
|
||||
4. Si cache miss:
|
||||
a. Consulta PostgreSQL
|
||||
b. Procesa/agrega datos
|
||||
c. Almacena en cache
|
||||
d. Retorna al frontend
|
||||
5. Frontend renderiza visualizaciones
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Decisiones Arquitectonicas
|
||||
|
||||
| ID | Titulo | Estado |
|
||||
|----|--------|--------|
|
||||
| [ADR-001](../97-adr/ADR-001-stack-tecnologico.md) | Stack Tecnologico | Aceptado |
|
||||
|
||||
---
|
||||
|
||||
## Seguridad
|
||||
|
||||
### Autenticacion
|
||||
- JWT con expiracion configurable
|
||||
- Refresh tokens para renovacion
|
||||
- Bcrypt para hash de passwords
|
||||
|
||||
### Autorizacion
|
||||
- RBAC (Role-Based Access Control)
|
||||
- Guards en endpoints protegidos
|
||||
- Validacion de permisos por recurso
|
||||
|
||||
### Comunicacion
|
||||
- HTTPS obligatorio en produccion
|
||||
- CORS configurado por ambiente
|
||||
- Rate limiting en endpoints publicos
|
||||
|
||||
---
|
||||
|
||||
## Escalabilidad
|
||||
|
||||
### Horizontal
|
||||
- Stateless backend (JWT)
|
||||
- Sessions en Redis
|
||||
- Load balancing con Traefik
|
||||
|
||||
### Vertical
|
||||
- Indices optimizados en PostgreSQL
|
||||
- Query optimization
|
||||
- Connection pooling
|
||||
|
||||
---
|
||||
|
||||
## Monitoreo
|
||||
|
||||
| Aspecto | Herramienta |
|
||||
|---------|-------------|
|
||||
| Logs | stdout + Docker logs |
|
||||
| Metricas | Prometheus (futuro) |
|
||||
| Alertas | Alertmanager (futuro) |
|
||||
| APM | OpenTelemetry (futuro) |
|
||||
|
||||
---
|
||||
|
||||
## Referencias
|
||||
|
||||
- [STACK-TECNOLOGICO.md](./STACK-TECNOLOGICO.md)
|
||||
- [ADR-001-stack-tecnologico.md](../97-adr/ADR-001-stack-tecnologico.md)
|
||||
- [service.descriptor.yml](../../apps/backend/service.descriptor.yml)
|
||||
|
||||
---
|
||||
|
||||
**Documento:** Arquitectura General
|
||||
**Version:** 1.0.0
|
||||
**Estado:** Draft
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
249
docs/00-vision-general/STACK-TECNOLOGICO.md
Normal file
249
docs/00-vision-general/STACK-TECNOLOGICO.md
Normal file
@ -0,0 +1,249 @@
|
||||
---
|
||||
id: "STACK-IA"
|
||||
title: "Stack Tecnologico - Inmobiliaria Analytics"
|
||||
type: "Technical Document"
|
||||
version: "1.0.0"
|
||||
status: "Active"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# Stack Tecnologico - Inmobiliaria Analytics
|
||||
|
||||
---
|
||||
|
||||
## Resumen
|
||||
|
||||
Documentacion detallada del stack tecnologico seleccionado para el proyecto Inmobiliaria Analytics.
|
||||
|
||||
---
|
||||
|
||||
## Stack Principal
|
||||
|
||||
### Backend
|
||||
|
||||
| Componente | Tecnologia | Version | Justificacion |
|
||||
|------------|------------|---------|---------------|
|
||||
| Runtime | Node.js | 20.x LTS | Estabilidad y soporte largo plazo |
|
||||
| Framework | NestJS | 10.3.x | Arquitectura modular, TypeScript nativo |
|
||||
| ORM | TypeORM | 0.3.x | Integracion con NestJS, migraciones |
|
||||
| Validacion | class-validator | 0.14.x | Decoradores para DTOs |
|
||||
| Transformacion | class-transformer | 0.5.x | Serializacion de objetos |
|
||||
|
||||
### Autenticacion
|
||||
|
||||
| Componente | Tecnologia | Version | Justificacion |
|
||||
|------------|------------|---------|---------------|
|
||||
| Framework | Passport | 0.7.x | Estrategias flexibles |
|
||||
| Token | JWT | 10.x | Stateless, escalable |
|
||||
| Local | passport-local | 1.0.x | Login con usuario/password |
|
||||
| Hashing | bcrypt | 5.1.x | Seguridad para passwords |
|
||||
|
||||
### Frontend
|
||||
|
||||
| Componente | Tecnologia | Version | Justificacion |
|
||||
|------------|------------|---------|---------------|
|
||||
| Framework | React | 18.x | Ecosistema maduro |
|
||||
| Lenguaje | TypeScript | 5.3.x | Type safety |
|
||||
| Build | Vite | 5.x | Desarrollo rapido |
|
||||
| Estado | Zustand | 4.x | Simple y performante |
|
||||
| Estilos | Tailwind CSS | 3.x | Utility-first |
|
||||
| Charts | Recharts | 2.x | React-native charts |
|
||||
|
||||
### Base de Datos
|
||||
|
||||
| Componente | Tecnologia | Version | Justificacion |
|
||||
|------------|------------|---------|---------------|
|
||||
| RDBMS | PostgreSQL | 16.x | ACID, extensiones geograficas |
|
||||
| Cache | Redis | 7.x | Alto rendimiento |
|
||||
| Driver | pg | 8.11.x | Driver PostgreSQL para Node |
|
||||
|
||||
### Infraestructura
|
||||
|
||||
| Componente | Tecnologia | Version | Justificacion |
|
||||
|------------|------------|---------|---------------|
|
||||
| Contenedores | Docker | 24.x | Portabilidad |
|
||||
| Orquestacion | Docker Compose | 2.x | Desarrollo local |
|
||||
| Proxy/LB | Traefik | 3.x | Routing dinamico |
|
||||
|
||||
---
|
||||
|
||||
## Dependencias del Backend
|
||||
|
||||
### Produccion
|
||||
|
||||
```json
|
||||
{
|
||||
"@nestjs/common": "^10.3.0",
|
||||
"@nestjs/config": "^3.1.1",
|
||||
"@nestjs/core": "^10.3.0",
|
||||
"@nestjs/jwt": "^10.2.0",
|
||||
"@nestjs/passport": "^10.0.3",
|
||||
"@nestjs/platform-express": "^10.3.0",
|
||||
"@nestjs/typeorm": "^10.0.1",
|
||||
"bcrypt": "^5.1.1",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.1",
|
||||
"passport": "^0.7.0",
|
||||
"passport-jwt": "^4.0.1",
|
||||
"passport-local": "^1.0.0",
|
||||
"pg": "^8.11.3",
|
||||
"reflect-metadata": "^0.2.1",
|
||||
"rxjs": "^7.8.1",
|
||||
"typeorm": "^0.3.19",
|
||||
"stripe": "^14.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
### Desarrollo
|
||||
|
||||
```json
|
||||
{
|
||||
"@nestjs/cli": "^10.3.0",
|
||||
"@nestjs/schematics": "^10.1.0",
|
||||
"@nestjs/testing": "^10.3.0",
|
||||
"@types/bcrypt": "^5.0.2",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/jest": "^29.5.11",
|
||||
"@types/node": "^20.10.6",
|
||||
"@types/passport-jwt": "^4.0.0",
|
||||
"@types/passport-local": "^1.0.38",
|
||||
"@typescript-eslint/eslint-plugin": "^6.18.0",
|
||||
"@typescript-eslint/parser": "^6.18.0",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-prettier": "^5.1.2",
|
||||
"jest": "^29.7.0",
|
||||
"prettier": "^3.1.1",
|
||||
"supertest": "^6.3.4",
|
||||
"ts-jest": "^29.1.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuracion de Puertos
|
||||
|
||||
| Servicio | Puerto | Ambiente |
|
||||
|----------|--------|----------|
|
||||
| Frontend | 3100 | Todos |
|
||||
| Backend API | 3101 | Todos |
|
||||
| WebSocket | 3102 | Todos |
|
||||
| PostgreSQL | 5439 | Local |
|
||||
| Redis | 6386 | Local |
|
||||
|
||||
---
|
||||
|
||||
## Variables de Entorno
|
||||
|
||||
### Aplicacion
|
||||
|
||||
```env
|
||||
# App
|
||||
APP_NAME=inmobiliaria-analytics
|
||||
APP_PORT=3101
|
||||
APP_ENV=development
|
||||
API_PREFIX=api
|
||||
|
||||
# CORS
|
||||
CORS_ORIGIN=http://localhost:3100
|
||||
```
|
||||
|
||||
### Base de Datos
|
||||
|
||||
```env
|
||||
# PostgreSQL
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5439
|
||||
DB_USERNAME=postgres
|
||||
DB_PASSWORD=postgres
|
||||
DB_DATABASE=inmobiliaria_analytics
|
||||
DB_SYNCHRONIZE=true
|
||||
DB_LOGGING=true
|
||||
|
||||
# Redis
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6386
|
||||
```
|
||||
|
||||
### Seguridad
|
||||
|
||||
```env
|
||||
# JWT
|
||||
JWT_SECRET=your-secret-key
|
||||
JWT_EXPIRES_IN=1d
|
||||
JWT_REFRESH_EXPIRES_IN=7d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Scripts de Desarrollo
|
||||
|
||||
### Backend
|
||||
|
||||
```bash
|
||||
# Desarrollo
|
||||
npm run start:dev
|
||||
|
||||
# Build
|
||||
npm run build
|
||||
|
||||
# Tests
|
||||
npm run test
|
||||
npm run test:cov
|
||||
npm run test:e2e
|
||||
|
||||
# Linting
|
||||
npm run lint
|
||||
npm run format
|
||||
```
|
||||
|
||||
### Base de Datos
|
||||
|
||||
```bash
|
||||
# Migraciones (futuro)
|
||||
npm run migration:generate -- -n MigrationName
|
||||
npm run migration:run
|
||||
npm run migration:revert
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Herramientas de Desarrollo
|
||||
|
||||
| Herramienta | Proposito |
|
||||
|-------------|-----------|
|
||||
| ESLint | Linting de codigo |
|
||||
| Prettier | Formateo de codigo |
|
||||
| Jest | Testing unitario y e2e |
|
||||
| Swagger | Documentacion API |
|
||||
| Docker Compose | Ambiente local |
|
||||
|
||||
---
|
||||
|
||||
## Extensiones Futuras
|
||||
|
||||
| Componente | Tecnologia | Proposito |
|
||||
|------------|------------|-----------|
|
||||
| Search | Elasticsearch | Busqueda avanzada |
|
||||
| ML | Python/FastAPI | Predicciones |
|
||||
| Queue | BullMQ | Jobs asinconos |
|
||||
| Metrics | Prometheus | Monitoreo |
|
||||
| Logs | ELK Stack | Centralizacion |
|
||||
|
||||
---
|
||||
|
||||
## Referencias
|
||||
|
||||
- [ADR-001-stack-tecnologico.md](../97-adr/ADR-001-stack-tecnologico.md)
|
||||
- [ARQUITECTURA-GENERAL.md](./ARQUITECTURA-GENERAL.md)
|
||||
- [package.json](../../apps/backend/package.json)
|
||||
|
||||
---
|
||||
|
||||
**Documento:** Stack Tecnologico
|
||||
**Version:** 1.0.0
|
||||
**Estado:** Active
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
321
docs/00-vision-general/VISION-PRODUCTO.md
Normal file
321
docs/00-vision-general/VISION-PRODUCTO.md
Normal file
@ -0,0 +1,321 @@
|
||||
---
|
||||
id: "VISION-IA"
|
||||
title: "Vision del Producto - Inmobiliaria Analytics"
|
||||
type: "Vision Document"
|
||||
version: "1.0.0"
|
||||
status: "Draft"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# Vision del Producto - Inmobiliaria Analytics
|
||||
|
||||
---
|
||||
|
||||
## Resumen Ejecutivo
|
||||
|
||||
**Inmobiliaria Analytics** es una plataforma de analisis de datos para el sector inmobiliario que proporciona herramientas avanzadas para la visualizacion, seguimiento y prediccion de tendencias del mercado inmobiliario.
|
||||
|
||||
---
|
||||
|
||||
## Vision
|
||||
|
||||
Ser la plataforma lider en analytics inmobiliario, proporcionando insights accionables que permitan a agentes, inversores y desarrolladores tomar decisiones informadas basadas en datos.
|
||||
|
||||
---
|
||||
|
||||
## Mision
|
||||
|
||||
Democratizar el acceso a la inteligencia de mercado inmobiliario mediante herramientas intuitivas y analisis avanzados que transformen datos en valor.
|
||||
|
||||
---
|
||||
|
||||
## Objetivos Estrategicos
|
||||
|
||||
### Corto Plazo (Q1 2026)
|
||||
- [ ] Establecer fundamentos tecnicos del proyecto
|
||||
- [ ] Implementar modulo de autenticacion y usuarios
|
||||
- [ ] Crear modelo de datos para propiedades
|
||||
- [ ] Desarrollar dashboard basico de visualizacion
|
||||
|
||||
### Mediano Plazo (Q2-Q3 2026)
|
||||
- [ ] Integrar fuentes de datos inmobiliarios
|
||||
- [ ] Implementar analytics avanzados
|
||||
- [ ] Desarrollar sistema de reportes
|
||||
- [ ] Lanzar version beta
|
||||
|
||||
### Largo Plazo (Q4 2026+)
|
||||
- [ ] Machine Learning para prediccion de precios
|
||||
- [ ] Expansion a multiples mercados
|
||||
- [ ] API publica para integraciones
|
||||
- [ ] App movil
|
||||
|
||||
---
|
||||
|
||||
## Propuesta de Valor
|
||||
|
||||
### Para Agentes Inmobiliarios
|
||||
- Analisis de mercado en tiempo real
|
||||
- Comparativas de propiedades
|
||||
- Tendencias de precios por zona
|
||||
- Herramientas de valoracion
|
||||
|
||||
### Para Inversores
|
||||
- Dashboard de portafolio
|
||||
- Analisis de ROI
|
||||
- Identificacion de oportunidades
|
||||
- Alertas de mercado
|
||||
|
||||
### Para Desarrolladores
|
||||
- Estudios de factibilidad
|
||||
- Analisis de demanda
|
||||
- Proyecciones financieras
|
||||
- Benchmarking de proyectos
|
||||
|
||||
---
|
||||
|
||||
## Diferenciadores Clave
|
||||
|
||||
| Caracteristica | Competencia | Inmobiliaria Analytics |
|
||||
|----------------|-------------|------------------------|
|
||||
| Actualizacion de datos | Semanal | Tiempo real |
|
||||
| Granularidad | Ciudad | Manzana/Colonia |
|
||||
| Predicciones ML | Basicas | Avanzadas |
|
||||
| Integraciones | Limitadas | API abierta |
|
||||
| Personalizacion | Minima | Completa |
|
||||
|
||||
---
|
||||
|
||||
## Mercado Objetivo
|
||||
|
||||
### Segmento Primario
|
||||
- Agencias inmobiliarias medianas y grandes
|
||||
- Inversores institucionales
|
||||
- Desarrolladores inmobiliarios
|
||||
|
||||
### Segmento Secundario
|
||||
- Agentes independientes
|
||||
- Inversores individuales
|
||||
- Instituciones financieras
|
||||
|
||||
### Geografia Inicial
|
||||
- Mexico (principales ciudades)
|
||||
- Expansion posterior a LATAM
|
||||
|
||||
---
|
||||
|
||||
## Metricas de Exito
|
||||
|
||||
| KPI | Meta Q1 | Meta Q4 |
|
||||
|-----|---------|---------|
|
||||
| Usuarios registrados | 100 | 5,000 |
|
||||
| Propiedades indexadas | 10,000 | 500,000 |
|
||||
| Consultas diarias | 500 | 50,000 |
|
||||
| NPS | 40 | 60 |
|
||||
| Uptime | 99% | 99.9% |
|
||||
|
||||
---
|
||||
|
||||
## Riesgos y Mitigaciones
|
||||
|
||||
| Riesgo | Probabilidad | Impacto | Mitigacion |
|
||||
|--------|--------------|---------|------------|
|
||||
| Calidad de datos | Alta | Alto | Multiples fuentes, validacion |
|
||||
| Adopcion lenta | Media | Alto | MVP rapido, feedback continuo |
|
||||
| Competencia | Media | Medio | Diferenciacion tecnologica |
|
||||
| Escalabilidad | Baja | Alto | Arquitectura cloud-native |
|
||||
|
||||
---
|
||||
|
||||
## Stakeholders
|
||||
|
||||
| Rol | Responsabilidad |
|
||||
|-----|-----------------|
|
||||
| Product Owner | Vision y prioridades |
|
||||
| Tech Lead | Arquitectura y decisiones tecnicas |
|
||||
| Backend Team | APIs y logica de negocio |
|
||||
| Frontend Team | UI/UX y experiencia |
|
||||
| Data Team | ETL y analytics |
|
||||
|
||||
---
|
||||
|
||||
## Modelo SaaS
|
||||
|
||||
### Arquitectura Multi-tenant
|
||||
|
||||
Inmobiliaria Analytics opera como plataforma SaaS con aislamiento de datos por tenant mediante Row-Level Security (RLS) en PostgreSQL.
|
||||
|
||||
```yaml
|
||||
Tipo: Single Database, Shared Schema
|
||||
Aislamiento: RLS por tenant_id
|
||||
Branding: Configurable por tenant
|
||||
```
|
||||
|
||||
### Planes de Suscripcion
|
||||
|
||||
| Plan | Precio | Propiedades | Reportes/mes | Alertas | Usuarios | Soporte |
|
||||
|------|--------|-------------|--------------|---------|----------|---------|
|
||||
| Free | $0 | 100 | 5 | 3 | 1 | Comunidad |
|
||||
| Pro | $49/mes | 5,000 | 50 | 25 | 5 | Email |
|
||||
| Enterprise | $199/mes | Ilimitado | Ilimitado | Ilimitado | Ilimitado | Dedicado |
|
||||
|
||||
### Integracion Stripe
|
||||
|
||||
```yaml
|
||||
Productos Stripe:
|
||||
ia_pro_monthly:
|
||||
precio: $49/mes
|
||||
type: subscription
|
||||
|
||||
ia_enterprise_monthly:
|
||||
precio: $199/mes
|
||||
type: subscription
|
||||
|
||||
ia_properties_500:
|
||||
precio: $19
|
||||
type: one_time
|
||||
descripcion: "500 propiedades adicionales"
|
||||
|
||||
Webhooks:
|
||||
- customer.subscription.created
|
||||
- customer.subscription.updated
|
||||
- customer.subscription.deleted
|
||||
- invoice.payment_succeeded
|
||||
- invoice.payment_failed
|
||||
- checkout.session.completed
|
||||
```
|
||||
|
||||
### Estructura de Portales
|
||||
|
||||
```yaml
|
||||
Portal 1 - Usuario (Analyst):
|
||||
URL: app.{tenant}.inmobiliaria-analytics.com
|
||||
Funciones:
|
||||
- Dashboard de propiedades
|
||||
- Analytics de mercado
|
||||
- Alertas configuradas
|
||||
- Perfil y configuracion
|
||||
|
||||
Portal 2 - Admin Cliente (Tenant Admin):
|
||||
URL: admin.{tenant}.inmobiliaria-analytics.com
|
||||
Funciones:
|
||||
- Gestion de usuarios
|
||||
- Configuracion del tenant
|
||||
- Facturacion y suscripcion
|
||||
- Reportes de uso
|
||||
|
||||
Portal 3 - Admin SaaS (Super Admin):
|
||||
URL: admin.inmobiliaria-analytics.com
|
||||
Funciones:
|
||||
- Gestion de todos los tenants
|
||||
- Configuracion de planes
|
||||
- Monitoreo del sistema
|
||||
- Analytics globales
|
||||
```
|
||||
|
||||
### Modulos SaaS
|
||||
|
||||
| ID | Modulo | Descripcion | Documento |
|
||||
|----|--------|-------------|-----------|
|
||||
| IA-004 | Tenants | Multi-tenancy con RLS | [IA-004-TENANTS](../02-definicion-modulos/IA-004-TENANTS.md) |
|
||||
| IA-005 | Payments | Integracion Stripe | [IA-005-PAYMENTS](../02-definicion-modulos/IA-005-PAYMENTS.md) |
|
||||
| IA-006 | Portals | 3 portales diferenciados | [IA-006-PORTALS](../02-definicion-modulos/IA-006-PORTALS.md) |
|
||||
|
||||
### Modulos de Datos e Inteligencia
|
||||
|
||||
| ID | Modulo | Descripcion | Documento |
|
||||
|----|--------|-------------|-----------|
|
||||
| IA-007 | Webscraper | ETL y recoleccion de datos | [IA-007-WEBSCRAPER](../02-definicion-modulos/IA-007-WEBSCRAPER.md) |
|
||||
| IA-008 | ML Analytics | Machine Learning y analytics avanzado | [IA-008-ML-ANALYTICS](../02-definicion-modulos/IA-008-ML-ANALYTICS.md) |
|
||||
|
||||
---
|
||||
|
||||
## Servicios de Machine Learning
|
||||
|
||||
La plataforma ofrece capacidades avanzadas de ML para analisis inmobiliario:
|
||||
|
||||
### Modelos Predictivos
|
||||
|
||||
| Servicio | Descripcion | Metrica Objetivo |
|
||||
|----------|-------------|------------------|
|
||||
| **AVM (Valuacion Automatica)** | Valuacion de propiedades basada en caracteristicas y mercado | MAPE < 10% |
|
||||
| **Prediccion Tiempo de Venta** | Estima dias en mercado segun precio y condiciones | MAPE < 25% |
|
||||
| **Prediccion Demanda** | Pronostico de demanda por zona geografica | Dir. Accuracy >= 70% |
|
||||
|
||||
### Analisis de Oportunidades
|
||||
|
||||
| Servicio | Descripcion |
|
||||
|----------|-------------|
|
||||
| **Detector de Subvaluadas** | Identifica propiedades con precio 10-20% bajo mercado |
|
||||
| **Zonas Emergentes** | Detecta zonas con potencial de apreciacion |
|
||||
| **Analisis ROI** | Calcula retornos proyectados para inversores |
|
||||
|
||||
### Indices de Mercado
|
||||
|
||||
| Indice | Descripcion |
|
||||
|--------|-------------|
|
||||
| **IPV** | Indice de Precios de Vivienda (Case-Shiller) |
|
||||
| **IAV** | Indice de Accesibilidad a Vivienda |
|
||||
| **Absorcion** | Meses de inventario (oferta vs demanda) |
|
||||
| **IAM** | Indice de Actividad de Mercado |
|
||||
|
||||
### Reportes Profesionales
|
||||
|
||||
**Para Agentes:**
|
||||
- CMA (Comparative Market Analysis)
|
||||
- Market Snapshot semanal
|
||||
- Listing Performance
|
||||
|
||||
**Para Inversores:**
|
||||
- Investment Analysis Report
|
||||
- Portfolio Performance
|
||||
- Alertas de oportunidades
|
||||
|
||||
**Para Desarrolladores:**
|
||||
- Feasibility Study
|
||||
- Demand Analysis
|
||||
- Project Tracking
|
||||
|
||||
---
|
||||
|
||||
## Sistema de Recoleccion de Datos (Webscraper)
|
||||
|
||||
La plataforma recolecta datos de multiples fuentes inmobiliarias:
|
||||
|
||||
### Fuentes de Datos
|
||||
|
||||
| Fuente | Tipo | Proteccion |
|
||||
|--------|------|------------|
|
||||
| Inmuebles24 | Portal inmobiliario | Cloudflare |
|
||||
| Vivanuncios | Portal inmobiliario | Cloudflare |
|
||||
| Segundamano | Portal inmobiliario | Basica |
|
||||
| INEGI | Datos demograficos | API publica |
|
||||
|
||||
### Estrategias Anti-Bloqueo
|
||||
|
||||
- Browser automation con Playwright (stealth mode)
|
||||
- Rotacion de proxies residenciales
|
||||
- Rate limiting inteligente
|
||||
- Simulacion de comportamiento humano
|
||||
|
||||
### Pipeline ETL
|
||||
|
||||
```
|
||||
Scraping -> Raw Storage -> Normalizacion -> Geocoding -> PostgreSQL
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Referencias
|
||||
|
||||
- [ARQUITECTURA-GENERAL.md](./ARQUITECTURA-GENERAL.md)
|
||||
- [STACK-TECNOLOGICO.md](./STACK-TECNOLOGICO.md)
|
||||
- [Modulos SaaS](../02-definicion-modulos/)
|
||||
- [ADR-001-stack-tecnologico.md](../97-adr/ADR-001-stack-tecnologico.md)
|
||||
|
||||
---
|
||||
|
||||
**Documento:** Vision del Producto
|
||||
**Version:** 1.0.0
|
||||
**Estado:** Draft
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
78
docs/00-vision-general/Webscraper_Politics.md
Normal file
78
docs/00-vision-general/Webscraper_Politics.md
Normal file
@ -0,0 +1,78 @@
|
||||
Web scraping efectivo sin ser bloqueado por Cloudflare
|
||||
Desafíos de hacer scraping en sitios con Cloudflare
|
||||
Realizar web scraping en páginas protegidas por Cloudflare (como FlashScore o Inmuebles24) es complicado debido a las robustas medidas anti-bot que implementa este servicio. Cloudflare cuenta con un sistema de Bot Management que puntúa cada solicitud HTTP con modelos de machine learning para decidir si es un humano o un scraper automatizado
|
||||
hardwarepremium.com
|
||||
. Estas medidas se han vuelto estratégicas en la “guerra contra los scrapers de IA”, al punto que Cloudflare ha experimentado con esquemas de “pay per crawl” (pago por rastreo) para permitir el acceso a ciertos bots legítimos bajo acuerdo comercial
|
||||
hardwarepremium.com
|
||||
. En la práctica, esto significa que un scraper tradicional puede ser identificado y bloqueado rápidamente si no toma precauciones. Cloudflare utiliza múltiples técnicas para detectar bots. Analiza enormes volúmenes de tráfico (decenas de millones de solicitudes por segundo) aplicando huellas digitales de la petición (cabeceras, TLS, patrón de HTTP), señales de comportamiento (p. ej. movimientos de mouse, tiempos entre acciones) y estadísticas globales de su red
|
||||
blog.cloudflare.com
|
||||
scrapfly.io
|
||||
. Por ejemplo, si un navegador automatizado tiene características obvias (como la propiedad JavaScript navigator.webdriver activada, o usar un motor HTTP sin navegador real), Cloudflare puede responder con un Error 1010 (Access Denied) indicando que la huella digital fue marcada como automatizada
|
||||
scrapfly.io
|
||||
. Asimismo, Cloudflare monitorea la velocidad y volumen de peticiones: si un solo IP realiza muchas solicitudes en poco tiempo, puede gatillar un Error 1015 (rate limited) por exceder el umbral permitido
|
||||
scrapfly.io
|
||||
. Otros códigos comunes incluyen el Error 1020 (Access Denied) cuando alguna regla de firewall bloquea el acceso, o desafíos como la página de "Attention Required!" con CAPTCHA Turnstile si sospecha tráfico no humano. Además de Cloudflare, hay que considerar las políticas de los sitios web en sí. Sitios como FlashScore o Inmuebles24 suelen establecer en sus términos de uso que no se permite la extracción automatizada de datos sin autorización. Muchas páginas también indican en su archivo robots.txt qué está permitido para bots: por ejemplo, la política de robots de Inmuebles24 prohíbe indexar más allá de la página 5 de listados (disallow de URLs con pagina-*.html excepto las primeras páginas)
|
||||
inmuebles24.com
|
||||
. Esto implica que una exploración profunda de todas las propiedades excedería lo que un bot de buscador normal debería hacer, y cualquier scraper que ignore estas reglas podría ser detectado o considerado como conducta no deseada. Ignorar las normativas de un sitio (términos de uso y robots.txt) no solo aumenta la probabilidad de bloqueo, sino que podría acarrear consecuencias legales o el bloqueo permanente de sus direcciones IP si el propietario del sitio toma medidas activas. En resumen, el principal desafío es parecer un usuario legítimo ante Cloudflare y el sitio destino. Para lograrlo, el scraper debe lidiar con desafíos de JavaScript, CAPTCHAs invisibles (Turnstile), detección de patrones inusuales, restricciones de velocidad, y a la vez respetar en la medida de lo posible las condiciones del sitio para evitar conflictos legales.
|
||||
Estrategias para evitar bloqueos de Cloudflare
|
||||
Superar las defensas de Cloudflare requiere adoptar varias técnicas de sigilo y buenas prácticas en la implementación de tu web scraper. A continuación, se presentan estrategias efectivas, respaldadas por guías especializadas, para minimizar la detección:
|
||||
Emular un navegador real: Es fundamental que las peticiones de tu scraper se asemejen a las de un navegador humano. Esto implica incluir headers HTTP típicos (agente de usuario moderno, encabezados de idioma, encoding, etc.), soportar conexiones TLS modernas y usar HTTP/2 si es posible
|
||||
scrapfly.io
|
||||
. Un scraper que simplemente use requests de Python con su agente de usuario por defecto será fácilmente marcado. En cambio, utilizar un navegador automatizado (Chrome/Firefox controlado por código) permite ejecutar el JavaScript de desafío de Cloudflare y obtener las cookies de sesión válidas. Herramientas actuales recomiendan incluso evitar usar modos headless puros sin camuflaje; en 2025 existen navegadores modificados para automatización (anti-detect browsers) que eliminan huellas del modo headless. Por ejemplo, Nodriver (sucesor de undetected-chromedriver) se diseñó para comunicarse con Chrome mediante el protocolo DevTools sin dejar rastro de WebDriver
|
||||
scrapfly.io
|
||||
. De igual forma, proyectos como SeleniumBase (modo UC) o Camoufox aplican parches al navegador (Chrome o Firefox respectivamente) para que los scripts anti-bot no detecten propiedades típicas de Selenium
|
||||
scrapfly.io
|
||||
. La recomendación es usar estas soluciones stealth activamente mantenidas, en lugar de librerías obsoletas; por ejemplo, el plugin puppeteer-stealth para Node fue descontinuado en 2025 en favor de alternativas más avanzadas
|
||||
scrapfly.io
|
||||
.
|
||||
Rotación y calidad de IPs: Otro pilar es la gestión inteligente de las direcciones IP desde las cuales haces las peticiones. Cloudflare verifica la reputación de IP y puede bloquear rangos asociados a centros de datos o VPNs. Por ello, es aconsejable utilizar proxies residenciales o IPs de red móvil, que se confunden mejor entre el tráfico normal
|
||||
scrapfly.io
|
||||
. Si tu scraper va a extraer grandes volúmenes de datos (por ejemplo, cargar todo el historial de 10 años de partidos), distribuye las solicitudes en múltiples IP para no saturar una sola y evitar límites de tasa
|
||||
scrapfly.io
|
||||
. Muchos servicios ofrecen rotating proxies (IPs rotativas) donde cada petición puede salir por una IP distinta de un pool residencial. Esto previene bloqueos por exceso de peticiones desde un mismo origen y sortea bloqueos geográficos (por ejemplo, Cloudflare Error 1009 si la página prohíbe cierto país) cambiando la región de salida. La inversión en proxies de calidad puede ser necesaria dentro de tu presupuesto, pero existen opciones relativamente económicas (algunos proveedores ofrecen millones de IP rotativas por montos dentro de $50-$100 mensuales, dependiendo del uso). Alternativamente, si operas tu scraper en la nube, elegir proveedores menos populares o distribuir entre varios podría ayudar, aunque Cloudflare entrena sus modelos incluso para detectar tráfico de nubes públicas de forma más agresiva
|
||||
blog.cloudflare.com
|
||||
.
|
||||
Controlar la velocidad y patrón de rastreo: Un raspador eficaz imita el comportamiento humano no solo en la configuración técnica sino en cómo navega. Implementa retrasos aleatorios entre peticiones, evita hacer clics o visitas a múltiples páginas por segundo, y programa el scraping pesado en horarios de menor tráfico para el sitio. Introducir cierta aleatoriedad en los tiempos y secuencias dificulta que un modelo de Cloudflare descubra patrones repetitivos exactos
|
||||
scrapfly.io
|
||||
. Por ejemplo, en lugar de scrapear 1000 páginas en un solo minuto desde la misma sesión, un enfoque más sigiloso sería procesar en lotes pequeños con pausas, cambiar de identidad (cookies/IP) periódicamente, y simular incluso alguna interacción intermedia (como cargar recursos asociados, desplazarse por la página, etc., acciones que un humano haría). Esto último puede lograrse con navegadores automatizados controlando eventos de scroll, movimientos del ratón ficticios o pausas al renderizar antes de extraer datos. El objetivo es presentar flujos de navegación naturales en vez de un bombardeo de peticiones uniformes
|
||||
scrapfly.io
|
||||
.
|
||||
Manejo de CAPTCHA y desafíos: En algunos casos, pese a nuestras medidas, nos toparemos con desafíos de Cloudflare como el Turnstile CAPTCHA. Este sistema, introducido en 2022, es más discreto que los CAPTCHAs tradicionales: a veces es invisible o se resuelve en segundo plano analizando el navegador, y solo muestra un desafío interactivo si la puntuación de confianza es baja
|
||||
scrapfly.io
|
||||
scrapfly.io
|
||||
. Para superarlo, hay dos enfoques: resolverlo o prevenirlo. La prevención consiste en aplicar todo lo anterior para no disparar alarmas (lo ideal es que el desafío ni aparezca porque el tráfico pareció legítimo). Si aun así aparece un CAPTCHA, necesitarás integrar un servicio de resolución (por ejemplo, 2Captcha, Anti-Captcha, etc.), donde un trabajador humano o un modelo ML aparte resuelve el desafío y devuelve el token
|
||||
scrapfly.io
|
||||
scrapfly.io
|
||||
. Algunos frameworks de navegación headless traen ayudas para esto – por ejemplo, SeleniumBase UC tiene métodos integrados para reconocer y resolver CAPTCHAs comunes
|
||||
scrapfly.io
|
||||
. Ten en cuenta que cada solicitud de CAPTCHA resuelto puede costar unos centavos y añadir retraso. En la medida de lo posible, refina tus técnicas de sigilo para evitar los CAPTCHA proactivamente, ya que Cloudflare misma indica que “la mejor manera de sortear un CAPTCHA es impedir que ocurra en primer lugar”
|
||||
scrapfly.io
|
||||
.
|
||||
Uso de herramientas y servicios especializados: Dada la complejidad técnica de evadir Cloudflare, vale la pena considerar herramientas ya existentes o servicios de terceros dentro de tu presupuesto. Por el lado de código abierto, ya mencionamos bibliotecas como undetected-chromedriver (y su sucesor Nodriver) para Python, o Playwright con plugins de stealth para Node.js. Por ejemplo, existe un proyecto de código abierto que usa Playwright para extraer resultados de FlashScore de forma estructurada
|
||||
github.com
|
||||
github.com
|
||||
, lo que confirma que es viable scrapear estos datos combinando un navegador real con algo de desarrollo. Si prefieres no reinventar la rueda, hay servicios en la nube que ofrecen scraping anti-bot como servicio: Apify, ScrapingBee, Zyte (Scrapinghub) entre otros. Algunos cuentan con APIs o actors ya preparados para sitios populares. En el caso de FlashScore, Apify tiene un actor público que provee una “API alternativa” para datos en vivo, cobrando alrededor de $1 por cada 1000 resultados extraídos
|
||||
apify.com
|
||||
. Igualmente, hay un actor para Inmuebles24 en Apify Store
|
||||
apify.com
|
||||
. Estos servicios manejan por ti las cuestiones de proxies, rotación de IP, y resolución de desafíos, lo que puede ahorrar tiempo de desarrollo. Incluso Apify ofrece la opción de integrar agentes de IA (como ChatGPT) con su MCP – un servidor que permite a modelos de lenguaje orquestar scrapers automáticamente
|
||||
apify.com
|
||||
. Esto podría ser útil si buscas que un agente de IA navegue páginas complejas simulando decisiones humanas; por ejemplo, un agente podría decidir qué enlaces de inmuebles seguir para recopilar cierta información detallada, usando las herramientas de scraping subyacentes para ejecutar las acciones. No obstante, estas soluciones deben evaluarse en costo: con un presupuesto inicial de $100-$200, podrías ejecutar scrapers propios en uno o dos servidores con proxies básicos, mientras que servicios SaaS de scraping cobrarán recurrentemente (aunque para volúmenes moderados pueden encajar en ese rango). Es importante equilibrar el ahorro de tiempo/desarrollo que brindan con el costo por volumen de datos que requerirás.
|
||||
Consideraciones legales y de cumplimiento
|
||||
Al diseñar tu web scraper es imprescindible no solo pensar en lo técnico, sino también en cumplir las normativas legales y de uso de los sitios objetivo:
|
||||
Revisa los Términos de Servicio: Tanto FlashScore como Inmuebles24 probablemente prohíban explícitamente el uso de bots o la extracción masiva de contenido sin permiso. Aunque la aplicación de estas cláusulas varía, incumplirlas podría llevar a que te bloqueen el acceso permanentemente, te envíen notificaciones legales, e incluso potenciales demandas si el scraping causa perjuicios. Si planeas ofrecer un servicio comercial basado en los datos, es aún más crítico asegurarte de que no estás violando derechos de propiedad de los datos o base de datos del sitio. En casos ideales, buscar vías oficiales: por ejemplo, ¿existe una API pública o de pago? (FlashScore no ofrece API pública
|
||||
github.com
|
||||
, de ahí que prolifere el scraping, pero conviene verificar). En el ámbito inmobiliario, quizás puedas obtener datos mediante acuerdos con agencias o usando fuentes públicas complementarias para ciertos datos (catastros, etc.) reduciendo la dependencia en scraping intensivo de un solo sitio.
|
||||
Respeta límites mediante robots.txt: Aunque el archivo robots.txt no es legalmente vinculante por sí mismo, es una guía de lo que el propietario del sitio espera de los robots. Cumplirlo muestra buena fe. En el caso de Inmuebles24 vimos que impone límites a la profundidad de listados indexables
|
||||
inmuebles24.com
|
||||
; tal restricción sugiere que un scraper que ignore ese límite (para obtener todas las propiedades) estaría actuando fuera de las expectativas del sitio. Si decides exceder lo estipulado, hazlo con mucha cautela (por ejemplo, limitando la frecuencia significativamente) para no parecer un ataque. En todo caso, no intentes evadir medidas activas de seguridad (como el propio Cloudflare) más allá de lo razonable, pues eso sí podría considerarse hacking. La clave está en acceder a la información pública de manera responsable y ética, sin afectar negativamente al servicio.
|
||||
Buena ciudadanía web: Mantén un perfil bajo. Identifícate adecuadamente cuando sea posible. Por ejemplo, algunas API o sitios pueden permitir acceso si el bot se identifica honestamente (muchos no, pero vale la pena ver si FlashScore/Inmuebles24 tienen algún programa de bot access para investigadores, etc.). Si no, al menos en tus registros y documentación interna lleva cuenta de las páginas consultadas, respeta si un usuario necesita estar autenticado (no scrapees datos privados o detrás de login si eso viola términos), y nunca publiques o revendas datos de forma que infrinja derechos de terceros (fotos, descripciones con copyright, etc., podrían estar protegidos). Un caso práctico: Inmuebles24 probablemente tiene fotografías de propiedades con derechos; extraerlas para tu propio sitio sería ilegal sin permiso expreso. En cambio, datos estadísticos agregados (precios promedio, tendencias) son menos problemáticos siempre que la fuente original no sea identificable directamente.
|
||||
En conclusión, sí es posible construir un web scraper eficaz para los proyectos que mencionas – de hecho, numerosos desarrolladores lo hacen para propósitos similares (análisis inmobiliario, modelos de apuestas deportivas). La clave del éxito estará en combinar las tácticas técnicas (navegador automatizado, proxies residenciales, rotación, stealth anti-detección) con un enfoque respetuoso: racionando el consumo de datos, acatando en lo posible las reglas de cada sitio, y manteniéndote dentro de un marco legal. Siguiendo las recomendaciones anteriores, tu scraper podrá realizar cargas iniciales de datos muy grandes (como todo el histórico de inmuebles o 10 años de estadísticas deportivas) sin ser bloqueado inmediatamente, y luego continuar con actualizaciones periódicas de forma sostenible. Recuerda siempre monitorear el comportamiento de tu scraper; si notas captchas frecuentes, bloqueos HTTP 429/1020, o respuestas anómalas, ajusta la estrategia rápidamente – la evasión de detección es un juego dinámico donde tanto Cloudflare como los scrapers evolucionan constantemente
|
||||
scrapfly.io
|
||||
. Con una inversión moderada (dentro de tu presupuesto indicado) en las herramientas adecuadas y quizás algún servicio de apoyo, podrás obtener los datos necesarios minimizando riesgos de interrupción y conflictos legales. Fuentes Consultadas: Guías técnicas de ScrapFly sobre Cloudflare
|
||||
scrapfly.io
|
||||
scrapfly.io
|
||||
, publicaciones oficiales de Cloudflare sobre Bot Management
|
||||
hardwarepremium.com
|
||||
hardwarepremium.com
|
||||
, documentación de proyectos de scraping de FlashScore e Inmuebles24, y experiencias compartidas en la comunidad de web scraping. Estas referencias respaldan las buenas prácticas aquí descritas y reflejan el estado del arte hasta 2025 en este campo.
|
||||
53
docs/00-vision-general/_MAP.md
Normal file
53
docs/00-vision-general/_MAP.md
Normal file
@ -0,0 +1,53 @@
|
||||
---
|
||||
id: "MAP-00-VISION"
|
||||
title: "Mapa de Navegacion - Vision General"
|
||||
type: "Navigation Map"
|
||||
section: "00-vision-general"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: 00-vision-general
|
||||
|
||||
**Seccion:** Vision General
|
||||
**Proyecto:** Inmobiliaria Analytics
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
|
||||
---
|
||||
|
||||
## Proposito
|
||||
|
||||
Documentos que definen la vision, arquitectura y stack tecnologico del proyecto Inmobiliaria Analytics.
|
||||
|
||||
---
|
||||
|
||||
## Contenido
|
||||
|
||||
| Archivo | Titulo | Estado |
|
||||
|---------|--------|--------|
|
||||
| [VISION-PRODUCTO.md](./VISION-PRODUCTO.md) | Vision del Producto | Draft |
|
||||
| [ARQUITECTURA-GENERAL.md](./ARQUITECTURA-GENERAL.md) | Arquitectura General | Draft |
|
||||
| [STACK-TECNOLOGICO.md](./STACK-TECNOLOGICO.md) | Stack Tecnologico | Active |
|
||||
| [Webscraper_Politics.md](./Webscraper_Politics.md) | Politicas de Web Scraping | Reference |
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [docs/](../_MAP.md)
|
||||
- **Siguiente:** [01-fase-alcance-inicial/](../01-fase-alcance-inicial/_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
## Estadisticas
|
||||
|
||||
| Metrica | Valor |
|
||||
|---------|-------|
|
||||
| Total documentos | 4 |
|
||||
| Documentos activos | 1 |
|
||||
| Documentos draft | 2 |
|
||||
| Documentos referencia | 1 |
|
||||
|
||||
---
|
||||
|
||||
**Generado:** 2026-01-04
|
||||
167
docs/01-fase-alcance-inicial/IAI-001-fundamentos/README.md
Normal file
167
docs/01-fase-alcance-inicial/IAI-001-fundamentos/README.md
Normal file
@ -0,0 +1,167 @@
|
||||
---
|
||||
id: "IA-001"
|
||||
title: "EPIC IA-001: Fundamentos"
|
||||
type: "Epic"
|
||||
status: "Planned"
|
||||
priority: "Alta"
|
||||
phase: "01 - Alcance Inicial"
|
||||
story_points: 40
|
||||
budget: "$15,000 MXN"
|
||||
sprint: "Sprint 1-3"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# IA-001: Fundamentos
|
||||
|
||||
**Epica:** IA-001
|
||||
**Nombre:** Fundamentos del Sistema
|
||||
**Fase:** 01 - Alcance Inicial
|
||||
**Story Points:** 40 SP (estimado)
|
||||
**Presupuesto:** $15,000 MXN (estimado)
|
||||
**Estado:** Planned
|
||||
**Sprint:** Sprint 1-3
|
||||
|
||||
---
|
||||
|
||||
## Proposito
|
||||
|
||||
Establecer los fundamentos tecnicos del sistema Inmobiliaria Analytics, incluyendo autenticacion, gestion de usuarios, y configuracion base de la aplicacion.
|
||||
|
||||
---
|
||||
|
||||
## Alcance
|
||||
|
||||
### Incluye
|
||||
|
||||
1. **Autenticacion y Autorizacion**
|
||||
- Login/logout de usuarios
|
||||
- JWT tokens
|
||||
- Roles y permisos basicos
|
||||
- Refresh tokens
|
||||
|
||||
2. **Gestion de Usuarios**
|
||||
- CRUD de usuarios
|
||||
- Perfiles de usuario
|
||||
- Preferencias
|
||||
|
||||
3. **Configuracion de Aplicacion**
|
||||
- Variables de entorno
|
||||
- Configuracion de base de datos
|
||||
- CORS y seguridad basica
|
||||
|
||||
4. **Health Check y Monitoreo Basico**
|
||||
- Endpoint /health
|
||||
- Logs estructurados
|
||||
- Metricas basicas
|
||||
|
||||
### No Incluye
|
||||
|
||||
- Modulos de propiedades (IA-002)
|
||||
- Modulos de analytics (IA-003)
|
||||
- Integraciones externas (IA-005)
|
||||
- Frontend completo (solo login/registro)
|
||||
|
||||
---
|
||||
|
||||
## Objetivos
|
||||
|
||||
1. Usuario puede registrarse e iniciar sesion
|
||||
2. Sistema valida tokens JWT correctamente
|
||||
3. Roles Admin/User funcionan
|
||||
4. API responde en <200ms promedio
|
||||
5. 90% test coverage en modulos core
|
||||
|
||||
---
|
||||
|
||||
## Estado Actual
|
||||
|
||||
El backend tiene un scaffold basico con:
|
||||
- NestJS configurado
|
||||
- AuthModule placeholder (sin implementacion)
|
||||
- Configuracion de TypeORM lista
|
||||
- Estructura de carpetas definida
|
||||
|
||||
---
|
||||
|
||||
## Trabajo Pendiente
|
||||
|
||||
### Autenticacion (Auth Module)
|
||||
|
||||
- [ ] Implementar AuthService
|
||||
- [ ] Implementar LocalStrategy (login)
|
||||
- [ ] Implementar JwtStrategy (validacion)
|
||||
- [ ] Implementar AuthController
|
||||
- [ ] Crear AuthGuard
|
||||
|
||||
### Usuarios (Users Module)
|
||||
|
||||
- [ ] Crear User entity
|
||||
- [ ] Implementar UsersService
|
||||
- [ ] Implementar UsersController
|
||||
- [ ] Crear DTOs (CreateUser, UpdateUser)
|
||||
- [ ] Validaciones de usuario
|
||||
|
||||
### Base de Datos
|
||||
|
||||
- [ ] Crear migration inicial
|
||||
- [ ] Schema de usuarios
|
||||
- [ ] Schema de roles
|
||||
- [ ] Seeds de datos basicos
|
||||
|
||||
### Testing
|
||||
|
||||
- [ ] Tests unitarios AuthService
|
||||
- [ ] Tests unitarios UsersService
|
||||
- [ ] Tests e2e de flujo auth
|
||||
- [ ] Tests de guards
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
### Antes (Bloqueantes)
|
||||
|
||||
- [x] Setup de proyecto NestJS
|
||||
- [x] Configuracion de Docker
|
||||
- [x] Definicion de stack tecnologico (ADR-001)
|
||||
|
||||
### Despues (Dependientes)
|
||||
|
||||
- [ ] IA-002: Propiedades (requiere auth)
|
||||
- [ ] IA-003: Analytics (requiere users)
|
||||
|
||||
---
|
||||
|
||||
## Riesgos
|
||||
|
||||
| Riesgo | Probabilidad | Impacto | Mitigacion |
|
||||
|--------|--------------|---------|------------|
|
||||
| Cambios en requerimientos auth | Media | Alto | Diseno flexible con strategies |
|
||||
| Performance de JWT validation | Baja | Medio | Caching de tokens |
|
||||
| Complejidad de roles | Media | Medio | RBAC simple inicial |
|
||||
|
||||
---
|
||||
|
||||
## Metricas
|
||||
|
||||
| Metrica | Objetivo | Actual |
|
||||
|---------|----------|--------|
|
||||
| Story Points estimados | 40 SP | - |
|
||||
| RF documentados | 5 | 0 |
|
||||
| US documentadas | 8 | 0 |
|
||||
| Tests coverage | 90% | 0% |
|
||||
|
||||
---
|
||||
|
||||
## Referencias
|
||||
|
||||
- [STACK-TECNOLOGICO.md](../../00-vision-general/STACK-TECNOLOGICO.md)
|
||||
- [ADR-001-stack-tecnologico.md](../../97-adr/ADR-001-stack-tecnologico.md)
|
||||
- [_MAP.md](./_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Creado:** 2026-01-04
|
||||
**Actualizado:** 2026-01-04
|
||||
**Responsable:** @Backend-Agent
|
||||
101
docs/01-fase-alcance-inicial/IAI-001-fundamentos/_MAP.md
Normal file
101
docs/01-fase-alcance-inicial/IAI-001-fundamentos/_MAP.md
Normal file
@ -0,0 +1,101 @@
|
||||
---
|
||||
id: "MAP-IA-001"
|
||||
title: "Mapa de Navegacion - EPIC IA-001 Fundamentos"
|
||||
type: "Navigation Map"
|
||||
epic: "IA-001"
|
||||
phase: "01-fase-alcance-inicial"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: IA-001 - Fundamentos
|
||||
|
||||
**Epica:** IA-001
|
||||
**Nombre:** Fundamentos del Sistema
|
||||
**Fase:** 01 - Alcance Inicial
|
||||
**Story Points:** 40 SP
|
||||
**Estado:** Planned
|
||||
**Sprint:** Sprint 1-3
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
|
||||
---
|
||||
|
||||
## Proposito
|
||||
|
||||
EPIC que establece los fundamentos tecnicos del sistema incluyendo autenticacion, gestion de usuarios, y configuracion base.
|
||||
|
||||
---
|
||||
|
||||
## Contenido
|
||||
|
||||
### Documentacion Base
|
||||
|
||||
| Archivo | Titulo | Estado |
|
||||
|---------|--------|--------|
|
||||
| [README.md](./README.md) | Descripcion de la EPIC | Active |
|
||||
|
||||
### Requerimientos Funcionales (0)
|
||||
|
||||
| ID | Archivo | Titulo | Estado |
|
||||
|----|---------|--------|--------|
|
||||
| - | Pendiente | - | - |
|
||||
|
||||
### Especificaciones Tecnicas (0)
|
||||
|
||||
| ID | Archivo | Titulo | RF | Estado |
|
||||
|----|---------|--------|-----|--------|
|
||||
| - | Pendiente | - | - | - |
|
||||
|
||||
### Historias de Usuario (0)
|
||||
|
||||
| ID | Archivo | Titulo | SP | Estado |
|
||||
|----|---------|--------|----|--------|
|
||||
| - | Pendiente | - | - | - |
|
||||
|
||||
**Total Story Points:** 0 SP (documentados)
|
||||
|
||||
### Implementacion
|
||||
|
||||
| Archivo | Proposito |
|
||||
|---------|-----------|
|
||||
| Pendiente | TRACEABILITY.yml |
|
||||
| Pendiente | DATABASE.yml |
|
||||
| Pendiente | BACKEND.yml |
|
||||
|
||||
---
|
||||
|
||||
## Metricas
|
||||
|
||||
| Metrica | Valor |
|
||||
|---------|-------|
|
||||
| **Presupuesto estimado** | $15,000 MXN |
|
||||
| **Story Points estimados** | 40 SP |
|
||||
| **RF documentados** | 0 |
|
||||
| **US documentadas** | 0 |
|
||||
| **ET documentadas** | 0 |
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [01-fase-alcance-inicial/](../_MAP.md)
|
||||
- **Fase:** [docs/](../../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
## Estructura de Carpetas
|
||||
|
||||
```
|
||||
IA-001-fundamentos/
|
||||
├── README.md # Este archivo de descripcion
|
||||
├── _MAP.md # Mapa de navegacion
|
||||
├── requerimientos/ # RFs (pendiente)
|
||||
├── especificaciones/ # ETs (pendiente)
|
||||
├── historias-usuario/ # US (pendiente)
|
||||
└── implementacion/ # Trazabilidad (pendiente)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Generado:** 2026-01-04
|
||||
**Mantenedores:** @Backend-Agent
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-001-ESPE"
|
||||
title: "Mapa Especificaciones IAI-001"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-001"
|
||||
section: "especificaciones"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Especificaciones - IAI-001 Fundamentos
|
||||
|
||||
**EPIC:** IAI-001
|
||||
**Seccion:** Especificaciones
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-001-fundamentos/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-001-HIST"
|
||||
title: "Mapa Historias-usuario IAI-001"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-001"
|
||||
section: "historias-usuario"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Historias-usuario - IAI-001 Fundamentos
|
||||
|
||||
**EPIC:** IAI-001
|
||||
**Seccion:** Historias-usuario
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-001-fundamentos/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-001-IMPL"
|
||||
title: "Mapa Implementacion IAI-001"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-001"
|
||||
section: "implementacion"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Implementacion - IAI-001 Fundamentos
|
||||
|
||||
**EPIC:** IAI-001
|
||||
**Seccion:** Implementacion
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-001-fundamentos/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-001-REQU"
|
||||
title: "Mapa Requerimientos IAI-001"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-001"
|
||||
section: "requerimientos"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Requerimientos - IAI-001 Fundamentos
|
||||
|
||||
**EPIC:** IAI-001
|
||||
**Seccion:** Requerimientos
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-001-fundamentos/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-001-TARE"
|
||||
title: "Mapa Tareas IAI-001"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-001"
|
||||
section: "tareas"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Tareas - IAI-001 Fundamentos
|
||||
|
||||
**EPIC:** IAI-001
|
||||
**Seccion:** Tareas
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-001-fundamentos/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
73
docs/01-fase-alcance-inicial/IAI-002-propiedades/README.md
Normal file
73
docs/01-fase-alcance-inicial/IAI-002-propiedades/README.md
Normal file
@ -0,0 +1,73 @@
|
||||
---
|
||||
id: "EPIC-IAI-002"
|
||||
title: "EPIC IAI-002 - Propiedades"
|
||||
type: "Epic Document"
|
||||
epic: "IAI-002"
|
||||
status: "Planned"
|
||||
story_points: 34
|
||||
priority: "Alta"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# EPIC IAI-002: Gestion de Propiedades
|
||||
|
||||
## Vision
|
||||
|
||||
Sistema CRUD completo para gestion de propiedades inmobiliarias, incluyendo listado, busqueda avanzada, filtros y detalle de propiedades.
|
||||
|
||||
---
|
||||
|
||||
## Alcance
|
||||
|
||||
### Incluye
|
||||
|
||||
- CRUD completo de propiedades
|
||||
- Busqueda y filtrado avanzado
|
||||
- Geolocalizacion y mapas
|
||||
- Galeria de imagenes
|
||||
- Favoritos de usuarios
|
||||
- Comparador de propiedades
|
||||
|
||||
### No Incluye
|
||||
|
||||
- Valuacion automatica (ver IAI-008)
|
||||
- Web scraping (ver IAI-007)
|
||||
- Pagos (ver IAI-005)
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
### Depende de
|
||||
|
||||
- IAI-001: Fundamentos (autenticacion, usuarios base)
|
||||
|
||||
### Bloquea a
|
||||
|
||||
- IAI-007: Web Scraping (necesita modelo de propiedades)
|
||||
- IAI-008: ML Analytics (necesita datos de propiedades)
|
||||
|
||||
---
|
||||
|
||||
## Story Points Estimados
|
||||
|
||||
| Tipo | Cantidad | SP |
|
||||
|------|----------|-----|
|
||||
| User Stories | 5 | 34 |
|
||||
| Total | - | 34 |
|
||||
|
||||
---
|
||||
|
||||
## Riesgos
|
||||
|
||||
| Riesgo | Probabilidad | Impacto | Mitigacion |
|
||||
|--------|--------------|---------|------------|
|
||||
| Modelo de datos complejo | Media | Medio | Disenar incrementalmente |
|
||||
| Performance en busquedas | Media | Alto | Indices, caching, Elasticsearch |
|
||||
|
||||
---
|
||||
|
||||
**Estado:** Planned
|
||||
**Sprint:** -
|
||||
68
docs/01-fase-alcance-inicial/IAI-002-propiedades/_MAP.md
Normal file
68
docs/01-fase-alcance-inicial/IAI-002-propiedades/_MAP.md
Normal file
@ -0,0 +1,68 @@
|
||||
---
|
||||
id: "MAP-IAI-002"
|
||||
title: "Mapa de EPIC IAI-002 Propiedades"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-002"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: EPIC IAI-002 - Gestion de Propiedades
|
||||
|
||||
**EPIC:** IAI-002
|
||||
**Nombre:** Gestion de Propiedades
|
||||
**Estado:** Planned
|
||||
**Story Points:** 34 (estimado)
|
||||
|
||||
---
|
||||
|
||||
## Estructura del EPIC
|
||||
|
||||
```
|
||||
IAI-002-propiedades/
|
||||
├── _MAP.md # Este archivo
|
||||
├── README.md # Vision general del EPIC
|
||||
│
|
||||
├── requerimientos/
|
||||
│ ├── _MAP.md
|
||||
│ ├── RF-PROP-001.md # Modelo de datos
|
||||
│ ├── RF-PROP-002.md # CRUD API
|
||||
│ └── RF-PROP-003.md # Busqueda avanzada
|
||||
│
|
||||
├── especificaciones/
|
||||
│ ├── _MAP.md
|
||||
│ └── ET-PROP-001-*.md
|
||||
│
|
||||
├── historias-usuario/
|
||||
│ ├── _MAP.md
|
||||
│ ├── US-PROP-001.md # Listado propiedades
|
||||
│ ├── US-PROP-002.md # Detalle propiedad
|
||||
│ ├── US-PROP-003.md # Busqueda y filtros
|
||||
│ ├── US-PROP-004.md # Favoritos
|
||||
│ └── US-PROP-005.md # Comparador
|
||||
│
|
||||
├── tareas/
|
||||
│ └── _MAP.md
|
||||
│
|
||||
└── implementacion/
|
||||
└── _MAP.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario (Planificadas)
|
||||
|
||||
| ID | Titulo | SP | Prioridad | Sprint |
|
||||
|----|--------|----|-----------| -------|
|
||||
| US-PROP-001 | Listado de propiedades | 8 | Alta | - |
|
||||
| US-PROP-002 | Detalle de propiedad | 5 | Alta | - |
|
||||
| US-PROP-003 | Busqueda y filtros avanzados | 8 | Alta | - |
|
||||
| US-PROP-004 | Favoritos de usuario | 5 | Media | - |
|
||||
| US-PROP-005 | Comparador de propiedades | 8 | Media | - |
|
||||
|
||||
**Total Story Points:** 34
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-002-ESPE"
|
||||
title: "Mapa Especificaciones IAI-002"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-002"
|
||||
section: "especificaciones"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Especificaciones - IAI-002 Propiedades
|
||||
|
||||
**EPIC:** IAI-002
|
||||
**Seccion:** Especificaciones
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-002-propiedades/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-002-HIST"
|
||||
title: "Mapa Historias-usuario IAI-002"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-002"
|
||||
section: "historias-usuario"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Historias-usuario - IAI-002 Propiedades
|
||||
|
||||
**EPIC:** IAI-002
|
||||
**Seccion:** Historias-usuario
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-002-propiedades/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-002-IMPL"
|
||||
title: "Mapa Implementacion IAI-002"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-002"
|
||||
section: "implementacion"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Implementacion - IAI-002 Propiedades
|
||||
|
||||
**EPIC:** IAI-002
|
||||
**Seccion:** Implementacion
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-002-propiedades/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-002-REQU"
|
||||
title: "Mapa Requerimientos IAI-002"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-002"
|
||||
section: "requerimientos"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Requerimientos - IAI-002 Propiedades
|
||||
|
||||
**EPIC:** IAI-002
|
||||
**Seccion:** Requerimientos
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-002-propiedades/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-002-TARE"
|
||||
title: "Mapa Tareas IAI-002"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-002"
|
||||
section: "tareas"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Tareas - IAI-002 Propiedades
|
||||
|
||||
**EPIC:** IAI-002
|
||||
**Seccion:** Tareas
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-002-propiedades/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
74
docs/01-fase-alcance-inicial/IAI-003-usuarios/README.md
Normal file
74
docs/01-fase-alcance-inicial/IAI-003-usuarios/README.md
Normal file
@ -0,0 +1,74 @@
|
||||
---
|
||||
id: "EPIC-IAI-003"
|
||||
title: "EPIC IAI-003 - Usuarios y Perfiles"
|
||||
type: "Epic Document"
|
||||
epic: "IAI-003"
|
||||
status: "Planned"
|
||||
story_points: 26
|
||||
priority: "Alta"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# EPIC IAI-003: Usuarios y Perfiles
|
||||
|
||||
## Vision
|
||||
|
||||
Sistema de gestion de usuarios, perfiles, preferencias y suscripciones para la plataforma SaaS inmobiliaria.
|
||||
|
||||
---
|
||||
|
||||
## Alcance
|
||||
|
||||
### Incluye
|
||||
|
||||
- Registro y autenticacion (extension de IAI-001)
|
||||
- Perfiles de usuario (inversor, agente, propietario)
|
||||
- Preferencias y notificaciones
|
||||
- Historial de actividad
|
||||
- Gestion de suscripcion (UI)
|
||||
|
||||
### No Incluye
|
||||
|
||||
- Procesamiento de pagos (ver IAI-005)
|
||||
- Multi-tenancy admin (ver IAI-004)
|
||||
|
||||
---
|
||||
|
||||
## Roles de Usuario
|
||||
|
||||
| Rol | Descripcion | Permisos |
|
||||
|-----|-------------|----------|
|
||||
| guest | Usuario anonimo | Ver propiedades publicas |
|
||||
| free_user | Usuario registrado gratuito | Buscar, favoritos limitados |
|
||||
| premium_user | Usuario con suscripcion | Todas las features |
|
||||
| agent | Agente inmobiliario | Publicar, CMA, analytics |
|
||||
| admin | Administrador | Gestion completa |
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
### Depende de
|
||||
|
||||
- IAI-001: Fundamentos (auth base)
|
||||
|
||||
### Bloquea a
|
||||
|
||||
- IAI-005: Pagos (necesita modelo de usuario)
|
||||
- IAI-008: ML Analytics (alertas personalizadas)
|
||||
|
||||
---
|
||||
|
||||
## Story Points Estimados
|
||||
|
||||
| Tipo | Cantidad | SP |
|
||||
|------|----------|-----|
|
||||
| User Stories | 4 | 26 |
|
||||
| Total | - | 26 |
|
||||
|
||||
---
|
||||
|
||||
**Estado:** Planned
|
||||
**Sprint:** -
|
||||
65
docs/01-fase-alcance-inicial/IAI-003-usuarios/_MAP.md
Normal file
65
docs/01-fase-alcance-inicial/IAI-003-usuarios/_MAP.md
Normal file
@ -0,0 +1,65 @@
|
||||
---
|
||||
id: "MAP-IAI-003"
|
||||
title: "Mapa de EPIC IAI-003 Usuarios"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-003"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: EPIC IAI-003 - Usuarios y Perfiles
|
||||
|
||||
**EPIC:** IAI-003
|
||||
**Nombre:** Usuarios y Perfiles
|
||||
**Estado:** Planned
|
||||
**Story Points:** 26 (estimado)
|
||||
|
||||
---
|
||||
|
||||
## Estructura del EPIC
|
||||
|
||||
```
|
||||
IAI-003-usuarios/
|
||||
├── _MAP.md # Este archivo
|
||||
├── README.md # Vision general del EPIC
|
||||
│
|
||||
├── requerimientos/
|
||||
│ ├── _MAP.md
|
||||
│ ├── RF-USER-001.md # Modelo de perfiles
|
||||
│ └── RF-USER-002.md # Preferencias
|
||||
│
|
||||
├── especificaciones/
|
||||
│ ├── _MAP.md
|
||||
│ └── ET-USER-001-*.md
|
||||
│
|
||||
├── historias-usuario/
|
||||
│ ├── _MAP.md
|
||||
│ ├── US-USER-001.md # Registro y perfil
|
||||
│ ├── US-USER-002.md # Preferencias
|
||||
│ ├── US-USER-003.md # Historial actividad
|
||||
│ └── US-USER-004.md # Gestion suscripcion
|
||||
│
|
||||
├── tareas/
|
||||
│ └── _MAP.md
|
||||
│
|
||||
└── implementacion/
|
||||
└── _MAP.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario (Planificadas)
|
||||
|
||||
| ID | Titulo | SP | Prioridad | Sprint |
|
||||
|----|--------|----|-----------| -------|
|
||||
| US-USER-001 | Registro y perfil de usuario | 8 | Alta | - |
|
||||
| US-USER-002 | Preferencias y notificaciones | 5 | Media | - |
|
||||
| US-USER-003 | Historial de actividad | 5 | Baja | - |
|
||||
| US-USER-004 | Gestion de suscripcion | 8 | Alta | - |
|
||||
|
||||
**Total Story Points:** 26
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-003-ESPE"
|
||||
title: "Mapa Especificaciones IAI-003"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-003"
|
||||
section: "especificaciones"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Especificaciones - IAI-003 Usuarios
|
||||
|
||||
**EPIC:** IAI-003
|
||||
**Seccion:** Especificaciones
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-003-usuarios/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-003-HIST"
|
||||
title: "Mapa Historias-usuario IAI-003"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-003"
|
||||
section: "historias-usuario"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Historias-usuario - IAI-003 Usuarios
|
||||
|
||||
**EPIC:** IAI-003
|
||||
**Seccion:** Historias-usuario
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-003-usuarios/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-003-IMPL"
|
||||
title: "Mapa Implementacion IAI-003"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-003"
|
||||
section: "implementacion"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Implementacion - IAI-003 Usuarios
|
||||
|
||||
**EPIC:** IAI-003
|
||||
**Seccion:** Implementacion
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-003-usuarios/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-003-REQU"
|
||||
title: "Mapa Requerimientos IAI-003"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-003"
|
||||
section: "requerimientos"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Requerimientos - IAI-003 Usuarios
|
||||
|
||||
**EPIC:** IAI-003
|
||||
**Seccion:** Requerimientos
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-003-usuarios/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
31
docs/01-fase-alcance-inicial/IAI-003-usuarios/tareas/_MAP.md
Normal file
31
docs/01-fase-alcance-inicial/IAI-003-usuarios/tareas/_MAP.md
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-003-TARE"
|
||||
title: "Mapa Tareas IAI-003"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-003"
|
||||
section: "tareas"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Tareas - IAI-003 Usuarios
|
||||
|
||||
**EPIC:** IAI-003
|
||||
**Seccion:** Tareas
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-003-usuarios/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
95
docs/01-fase-alcance-inicial/IAI-004-tenants/README.md
Normal file
95
docs/01-fase-alcance-inicial/IAI-004-tenants/README.md
Normal file
@ -0,0 +1,95 @@
|
||||
---
|
||||
id: "EPIC-IAI-004"
|
||||
title: "EPIC IAI-004 - Multi-Tenancy"
|
||||
type: "Epic Document"
|
||||
epic: "IAI-004"
|
||||
status: "Planned"
|
||||
story_points: 40
|
||||
priority: "Alta"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# EPIC IAI-004: Sistema Multi-Tenant
|
||||
|
||||
## Vision
|
||||
|
||||
Arquitectura multi-tenant para soportar multiples organizaciones (agencias inmobiliarias) en una sola instancia de la aplicacion, con aislamiento de datos mediante Row-Level Security (RLS).
|
||||
|
||||
---
|
||||
|
||||
## Alcance
|
||||
|
||||
### Incluye
|
||||
|
||||
- Modelo de tenant/organizacion
|
||||
- Row-Level Security (RLS) en PostgreSQL
|
||||
- Onboarding de nuevos tenants
|
||||
- Administracion de tenant
|
||||
- Branding por tenant (white-label basico)
|
||||
|
||||
### No Incluye
|
||||
|
||||
- Facturacion por tenant (ver IAI-005)
|
||||
- Despliegue multi-region
|
||||
|
||||
---
|
||||
|
||||
## Arquitectura
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ APLICACION (Single Instance) │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
||||
│ │ Tenant A│ │ Tenant B│ │ Tenant C│ │
|
||||
│ │ (RLS) │ │ (RLS) │ │ (RLS) │ │
|
||||
│ └────┬────┘ └────┬────┘ └────┬────┘ │
|
||||
│ │ │ │ │
|
||||
│ └─────────────┼─────────────┘ │
|
||||
│ │ │
|
||||
│ ┌───────▼───────┐ │
|
||||
│ │ PostgreSQL │ │
|
||||
│ │ (RLS) │ │
|
||||
│ └───────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
### Depende de
|
||||
|
||||
- IAI-001: Fundamentos (auth, usuarios)
|
||||
- IAI-003: Usuarios (modelo base)
|
||||
|
||||
### Bloquea a
|
||||
|
||||
- IAI-005: Pagos (facturacion por tenant)
|
||||
- IAI-006: Portales (portales por tenant)
|
||||
|
||||
---
|
||||
|
||||
## Story Points Estimados
|
||||
|
||||
| Tipo | Cantidad | SP |
|
||||
|------|----------|-----|
|
||||
| User Stories | 5 | 40 |
|
||||
| Total | - | 40 |
|
||||
|
||||
---
|
||||
|
||||
## Riesgos
|
||||
|
||||
| Riesgo | Probabilidad | Impacto | Mitigacion |
|
||||
|--------|--------------|---------|------------|
|
||||
| Data leakage entre tenants | Baja | Critico | RLS exhaustivo, testing |
|
||||
| Performance con muchos tenants | Media | Alto | Indices, particionamiento |
|
||||
|
||||
---
|
||||
|
||||
**Estado:** Planned
|
||||
**Sprint:** -
|
||||
69
docs/01-fase-alcance-inicial/IAI-004-tenants/_MAP.md
Normal file
69
docs/01-fase-alcance-inicial/IAI-004-tenants/_MAP.md
Normal file
@ -0,0 +1,69 @@
|
||||
---
|
||||
id: "MAP-IAI-004"
|
||||
title: "Mapa de EPIC IAI-004 Tenants"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-004"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: EPIC IAI-004 - Multi-Tenancy
|
||||
|
||||
**EPIC:** IAI-004
|
||||
**Nombre:** Sistema Multi-Tenant
|
||||
**Estado:** Planned
|
||||
**Story Points:** 40 (estimado)
|
||||
|
||||
---
|
||||
|
||||
## Estructura del EPIC
|
||||
|
||||
```
|
||||
IAI-004-tenants/
|
||||
├── _MAP.md # Este archivo
|
||||
├── README.md # Vision general del EPIC
|
||||
│
|
||||
├── requerimientos/
|
||||
│ ├── _MAP.md
|
||||
│ ├── RF-TENT-001.md # Modelo de tenant
|
||||
│ ├── RF-TENT-002.md # RLS policies
|
||||
│ └── RF-TENT-003.md # Admin tenant
|
||||
│
|
||||
├── especificaciones/
|
||||
│ ├── _MAP.md
|
||||
│ ├── ET-TENT-001-rls.md # Implementacion RLS
|
||||
│ └── ET-TENT-002-onboard.md # Flujo onboarding
|
||||
│
|
||||
├── historias-usuario/
|
||||
│ ├── _MAP.md
|
||||
│ ├── US-TENT-001.md # Registro organizacion
|
||||
│ ├── US-TENT-002.md # Onboarding wizard
|
||||
│ ├── US-TENT-003.md # Admin de tenant
|
||||
│ ├── US-TENT-004.md # Branding basico
|
||||
│ └── US-TENT-005.md # Miembros de org
|
||||
│
|
||||
├── tareas/
|
||||
│ └── _MAP.md
|
||||
│
|
||||
└── implementacion/
|
||||
└── _MAP.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario (Planificadas)
|
||||
|
||||
| ID | Titulo | SP | Prioridad | Sprint |
|
||||
|----|--------|----|-----------| -------|
|
||||
| US-TENT-001 | Registro de organizacion | 8 | Alta | - |
|
||||
| US-TENT-002 | Onboarding wizard | 8 | Alta | - |
|
||||
| US-TENT-003 | Panel de admin tenant | 8 | Alta | - |
|
||||
| US-TENT-004 | Configuracion de branding | 8 | Media | - |
|
||||
| US-TENT-005 | Gestion de miembros | 8 | Media | - |
|
||||
|
||||
**Total Story Points:** 40
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-004-ESPE"
|
||||
title: "Mapa Especificaciones IAI-004"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-004"
|
||||
section: "especificaciones"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Especificaciones - IAI-004 Tenants
|
||||
|
||||
**EPIC:** IAI-004
|
||||
**Seccion:** Especificaciones
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-004-tenants/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-004-HIST"
|
||||
title: "Mapa Historias-usuario IAI-004"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-004"
|
||||
section: "historias-usuario"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Historias-usuario - IAI-004 Tenants
|
||||
|
||||
**EPIC:** IAI-004
|
||||
**Seccion:** Historias-usuario
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-004-tenants/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-004-IMPL"
|
||||
title: "Mapa Implementacion IAI-004"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-004"
|
||||
section: "implementacion"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Implementacion - IAI-004 Tenants
|
||||
|
||||
**EPIC:** IAI-004
|
||||
**Seccion:** Implementacion
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-004-tenants/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-004-REQU"
|
||||
title: "Mapa Requerimientos IAI-004"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-004"
|
||||
section: "requerimientos"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Requerimientos - IAI-004 Tenants
|
||||
|
||||
**EPIC:** IAI-004
|
||||
**Seccion:** Requerimientos
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-004-tenants/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
31
docs/01-fase-alcance-inicial/IAI-004-tenants/tareas/_MAP.md
Normal file
31
docs/01-fase-alcance-inicial/IAI-004-tenants/tareas/_MAP.md
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-004-TARE"
|
||||
title: "Mapa Tareas IAI-004"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-004"
|
||||
section: "tareas"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Tareas - IAI-004 Tenants
|
||||
|
||||
**EPIC:** IAI-004
|
||||
**Seccion:** Tareas
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-004-tenants/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
84
docs/01-fase-alcance-inicial/IAI-005-pagos/README.md
Normal file
84
docs/01-fase-alcance-inicial/IAI-005-pagos/README.md
Normal file
@ -0,0 +1,84 @@
|
||||
---
|
||||
id: "EPIC-IAI-005"
|
||||
title: "EPIC IAI-005 - Sistema de Pagos"
|
||||
type: "Epic Document"
|
||||
epic: "IAI-005"
|
||||
status: "Planned"
|
||||
story_points: 34
|
||||
priority: "Alta"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# EPIC IAI-005: Sistema de Pagos con Stripe
|
||||
|
||||
## Vision
|
||||
|
||||
Integracion completa con Stripe para procesamiento de suscripciones mensuales, pagos unicos y facturacion automatizada.
|
||||
|
||||
---
|
||||
|
||||
## Alcance
|
||||
|
||||
### Incluye
|
||||
|
||||
- Integracion Stripe Checkout
|
||||
- Suscripciones recurrentes
|
||||
- Portal de cliente Stripe
|
||||
- Webhooks de eventos
|
||||
- Facturacion automatica
|
||||
- Proration y cambios de plan
|
||||
|
||||
### No Incluye
|
||||
|
||||
- Otros procesadores de pago
|
||||
- Pagos en efectivo/transferencia
|
||||
|
||||
---
|
||||
|
||||
## Planes de Suscripcion
|
||||
|
||||
| Plan | Precio/mes | Features |
|
||||
|------|-----------|----------|
|
||||
| Free | $0 | Busqueda basica, 5 favoritos |
|
||||
| Basic | $299 MXN | Busqueda ilimitada, alertas basicas |
|
||||
| Pro | $599 MXN | Analytics, CMA, alertas avanzadas |
|
||||
| Enterprise | $1,499 MXN | Multi-usuario, API, white-label |
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
### Depende de
|
||||
|
||||
- IAI-001: Fundamentos (auth)
|
||||
- IAI-003: Usuarios (modelo de suscripcion)
|
||||
- IAI-004: Tenants (facturacion por org)
|
||||
|
||||
### Bloquea a
|
||||
|
||||
- Todas las features premium
|
||||
|
||||
---
|
||||
|
||||
## Story Points Estimados
|
||||
|
||||
| Tipo | Cantidad | SP |
|
||||
|------|----------|-----|
|
||||
| User Stories | 5 | 34 |
|
||||
| Total | - | 34 |
|
||||
|
||||
---
|
||||
|
||||
## Riesgos
|
||||
|
||||
| Riesgo | Probabilidad | Impacto | Mitigacion |
|
||||
|--------|--------------|---------|------------|
|
||||
| Fallo en webhooks | Media | Alto | Idempotencia, reintentos |
|
||||
| Fraude | Baja | Alto | Stripe Radar, validaciones |
|
||||
|
||||
---
|
||||
|
||||
**Estado:** Planned
|
||||
**Sprint:** -
|
||||
69
docs/01-fase-alcance-inicial/IAI-005-pagos/_MAP.md
Normal file
69
docs/01-fase-alcance-inicial/IAI-005-pagos/_MAP.md
Normal file
@ -0,0 +1,69 @@
|
||||
---
|
||||
id: "MAP-IAI-005"
|
||||
title: "Mapa de EPIC IAI-005 Pagos"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-005"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: EPIC IAI-005 - Sistema de Pagos
|
||||
|
||||
**EPIC:** IAI-005
|
||||
**Nombre:** Sistema de Pagos con Stripe
|
||||
**Estado:** Planned
|
||||
**Story Points:** 34 (estimado)
|
||||
|
||||
---
|
||||
|
||||
## Estructura del EPIC
|
||||
|
||||
```
|
||||
IAI-005-pagos/
|
||||
├── _MAP.md # Este archivo
|
||||
├── README.md # Vision general del EPIC
|
||||
│
|
||||
├── requerimientos/
|
||||
│ ├── _MAP.md
|
||||
│ ├── RF-PAY-001.md # Integracion Stripe
|
||||
│ ├── RF-PAY-002.md # Suscripciones
|
||||
│ └── RF-PAY-003.md # Facturacion
|
||||
│
|
||||
├── especificaciones/
|
||||
│ ├── _MAP.md
|
||||
│ ├── ET-PAY-001-stripe.md # Arquitectura Stripe
|
||||
│ └── ET-PAY-002-webhooks.md # Manejo de webhooks
|
||||
│
|
||||
├── historias-usuario/
|
||||
│ ├── _MAP.md
|
||||
│ ├── US-PAY-001.md # Checkout suscripcion
|
||||
│ ├── US-PAY-002.md # Portal de cliente
|
||||
│ ├── US-PAY-003.md # Cambio de plan
|
||||
│ ├── US-PAY-004.md # Cancelacion
|
||||
│ └── US-PAY-005.md # Facturas
|
||||
│
|
||||
├── tareas/
|
||||
│ └── _MAP.md
|
||||
│
|
||||
└── implementacion/
|
||||
└── _MAP.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario (Planificadas)
|
||||
|
||||
| ID | Titulo | SP | Prioridad | Sprint |
|
||||
|----|--------|----|-----------| -------|
|
||||
| US-PAY-001 | Checkout de suscripcion | 8 | Alta | - |
|
||||
| US-PAY-002 | Portal de cliente Stripe | 5 | Alta | - |
|
||||
| US-PAY-003 | Cambio/upgrade de plan | 8 | Media | - |
|
||||
| US-PAY-004 | Cancelacion de suscripcion | 5 | Media | - |
|
||||
| US-PAY-005 | Historial de facturas | 8 | Media | - |
|
||||
|
||||
**Total Story Points:** 34
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-005-ESPE"
|
||||
title: "Mapa Especificaciones IAI-005"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-005"
|
||||
section: "especificaciones"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Especificaciones - IAI-005 Pagos
|
||||
|
||||
**EPIC:** IAI-005
|
||||
**Seccion:** Especificaciones
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-005-pagos/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-005-HIST"
|
||||
title: "Mapa Historias-usuario IAI-005"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-005"
|
||||
section: "historias-usuario"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Historias-usuario - IAI-005 Pagos
|
||||
|
||||
**EPIC:** IAI-005
|
||||
**Seccion:** Historias-usuario
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-005-pagos/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-005-IMPL"
|
||||
title: "Mapa Implementacion IAI-005"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-005"
|
||||
section: "implementacion"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Implementacion - IAI-005 Pagos
|
||||
|
||||
**EPIC:** IAI-005
|
||||
**Seccion:** Implementacion
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-005-pagos/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-005-REQU"
|
||||
title: "Mapa Requerimientos IAI-005"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-005"
|
||||
section: "requerimientos"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Requerimientos - IAI-005 Pagos
|
||||
|
||||
**EPIC:** IAI-005
|
||||
**Seccion:** Requerimientos
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-005-pagos/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
31
docs/01-fase-alcance-inicial/IAI-005-pagos/tareas/_MAP.md
Normal file
31
docs/01-fase-alcance-inicial/IAI-005-pagos/tareas/_MAP.md
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-005-TARE"
|
||||
title: "Mapa Tareas IAI-005"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-005"
|
||||
section: "tareas"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Tareas - IAI-005 Pagos
|
||||
|
||||
**EPIC:** IAI-005
|
||||
**Seccion:** Tareas
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-005-pagos/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
73
docs/01-fase-alcance-inicial/IAI-006-portales/README.md
Normal file
73
docs/01-fase-alcance-inicial/IAI-006-portales/README.md
Normal file
@ -0,0 +1,73 @@
|
||||
---
|
||||
id: "EPIC-IAI-006"
|
||||
title: "EPIC IAI-006 - Portales"
|
||||
type: "Epic Document"
|
||||
epic: "IAI-006"
|
||||
status: "Planned"
|
||||
story_points: 26
|
||||
priority: "Media"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# EPIC IAI-006: Portales Web
|
||||
|
||||
## Vision
|
||||
|
||||
Sistema de portales diferenciados para cada tipo de usuario: portal publico, portal de agente/inversor, y portal administrativo.
|
||||
|
||||
---
|
||||
|
||||
## Alcance
|
||||
|
||||
### Incluye
|
||||
|
||||
- Portal publico (landing, busqueda basica)
|
||||
- Portal de usuario autenticado (dashboard)
|
||||
- Portal de agente (herramientas profesionales)
|
||||
- Portal de administrador (gestion del sistema)
|
||||
|
||||
### No Incluye
|
||||
|
||||
- Portal de tenant/white-label avanzado (fase 2)
|
||||
- App movil nativa
|
||||
|
||||
---
|
||||
|
||||
## Portales
|
||||
|
||||
| Portal | URL | Audiencia |
|
||||
|--------|-----|-----------|
|
||||
| Publico | / | Todos |
|
||||
| Dashboard | /app | Usuarios autenticados |
|
||||
| Agente | /app/pro | Agentes premium |
|
||||
| Admin | /admin | Administradores |
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
### Depende de
|
||||
|
||||
- IAI-001: Fundamentos (auth, routing)
|
||||
- IAI-002: Propiedades (contenido)
|
||||
- IAI-003: Usuarios (roles)
|
||||
|
||||
### Bloquea a
|
||||
|
||||
- Ninguno (es la capa de presentacion)
|
||||
|
||||
---
|
||||
|
||||
## Story Points Estimados
|
||||
|
||||
| Tipo | Cantidad | SP |
|
||||
|------|----------|-----|
|
||||
| User Stories | 4 | 26 |
|
||||
| Total | - | 26 |
|
||||
|
||||
---
|
||||
|
||||
**Estado:** Planned
|
||||
**Sprint:** -
|
||||
66
docs/01-fase-alcance-inicial/IAI-006-portales/_MAP.md
Normal file
66
docs/01-fase-alcance-inicial/IAI-006-portales/_MAP.md
Normal file
@ -0,0 +1,66 @@
|
||||
---
|
||||
id: "MAP-IAI-006"
|
||||
title: "Mapa de EPIC IAI-006 Portales"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-006"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: EPIC IAI-006 - Portales Web
|
||||
|
||||
**EPIC:** IAI-006
|
||||
**Nombre:** Portales Web
|
||||
**Estado:** Planned
|
||||
**Story Points:** 26 (estimado)
|
||||
|
||||
---
|
||||
|
||||
## Estructura del EPIC
|
||||
|
||||
```
|
||||
IAI-006-portales/
|
||||
├── _MAP.md # Este archivo
|
||||
├── README.md # Vision general del EPIC
|
||||
│
|
||||
├── requerimientos/
|
||||
│ ├── _MAP.md
|
||||
│ ├── RF-PORT-001.md # Portal publico
|
||||
│ ├── RF-PORT-002.md # Dashboard usuario
|
||||
│ └── RF-PORT-003.md # Portal admin
|
||||
│
|
||||
├── especificaciones/
|
||||
│ ├── _MAP.md
|
||||
│ └── ET-PORT-001-routing.md
|
||||
│
|
||||
├── historias-usuario/
|
||||
│ ├── _MAP.md
|
||||
│ ├── US-PORT-001.md # Landing page
|
||||
│ ├── US-PORT-002.md # Dashboard usuario
|
||||
│ ├── US-PORT-003.md # Portal agente
|
||||
│ └── US-PORT-004.md # Portal admin
|
||||
│
|
||||
├── tareas/
|
||||
│ └── _MAP.md
|
||||
│
|
||||
└── implementacion/
|
||||
└── _MAP.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario (Planificadas)
|
||||
|
||||
| ID | Titulo | SP | Prioridad | Sprint |
|
||||
|----|--------|----|-----------| -------|
|
||||
| US-PORT-001 | Landing page publica | 8 | Alta | - |
|
||||
| US-PORT-002 | Dashboard de usuario | 8 | Alta | - |
|
||||
| US-PORT-003 | Portal de agente/pro | 5 | Media | - |
|
||||
| US-PORT-004 | Portal administrativo | 5 | Alta | - |
|
||||
|
||||
**Total Story Points:** 26
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-006-ESPE"
|
||||
title: "Mapa Especificaciones IAI-006"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-006"
|
||||
section: "especificaciones"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Especificaciones - IAI-006 Portales
|
||||
|
||||
**EPIC:** IAI-006
|
||||
**Seccion:** Especificaciones
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-006-portales/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-006-HIST"
|
||||
title: "Mapa Historias-usuario IAI-006"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-006"
|
||||
section: "historias-usuario"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Historias-usuario - IAI-006 Portales
|
||||
|
||||
**EPIC:** IAI-006
|
||||
**Seccion:** Historias-usuario
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-006-portales/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-006-IMPL"
|
||||
title: "Mapa Implementacion IAI-006"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-006"
|
||||
section: "implementacion"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Implementacion - IAI-006 Portales
|
||||
|
||||
**EPIC:** IAI-006
|
||||
**Seccion:** Implementacion
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-006-portales/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-006-REQU"
|
||||
title: "Mapa Requerimientos IAI-006"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-006"
|
||||
section: "requerimientos"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Requerimientos - IAI-006 Portales
|
||||
|
||||
**EPIC:** IAI-006
|
||||
**Seccion:** Requerimientos
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-006-portales/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
31
docs/01-fase-alcance-inicial/IAI-006-portales/tareas/_MAP.md
Normal file
31
docs/01-fase-alcance-inicial/IAI-006-portales/tareas/_MAP.md
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-006-TARE"
|
||||
title: "Mapa Tareas IAI-006"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-006"
|
||||
section: "tareas"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Tareas - IAI-006 Portales
|
||||
|
||||
**EPIC:** IAI-006
|
||||
**Seccion:** Tareas
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Pendiente de documentacion.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-006-portales/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
196
docs/01-fase-alcance-inicial/IAI-007-webscraper/README.md
Normal file
196
docs/01-fase-alcance-inicial/IAI-007-webscraper/README.md
Normal file
@ -0,0 +1,196 @@
|
||||
---
|
||||
id: "EPIC-IAI-007"
|
||||
title: "EPIC IAI-007: Sistema de Web Scraping y ETL"
|
||||
type: "EPIC"
|
||||
epic: "IAI-007"
|
||||
status: "Draft"
|
||||
project: "inmobiliaria-analytics"
|
||||
version: "1.0.0"
|
||||
story_points: 55
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# EPIC IAI-007: Sistema de Web Scraping y ETL
|
||||
|
||||
---
|
||||
|
||||
## Resumen Ejecutivo
|
||||
|
||||
Este EPIC implementa el sistema de recoleccion automatizada de datos inmobiliarios desde multiples portales (Inmuebles24, Vivanuncios, etc.), incluyendo estrategias anti-deteccion, normalizacion de datos y pipeline ETL para alimentar la plataforma de analytics.
|
||||
|
||||
---
|
||||
|
||||
## Objetivo
|
||||
|
||||
Construir un sistema robusto de web scraping capaz de:
|
||||
1. Extraer datos de propiedades de portales inmobiliarios protegidos
|
||||
2. Evitar bloqueos mediante tecnicas anti-detection
|
||||
3. Normalizar y validar datos de multiples fuentes
|
||||
4. Mantener actualizaciones incrementales eficientes
|
||||
|
||||
---
|
||||
|
||||
## Alcance
|
||||
|
||||
### Incluido
|
||||
|
||||
- Motor de scraping con Playwright/Puppeteer
|
||||
- Gestion de proxies residenciales
|
||||
- Bypass de Cloudflare y rate limiting
|
||||
- Pipeline ETL para normalizacion
|
||||
- Scheduling con Bull Queue
|
||||
- Monitoreo y metricas
|
||||
|
||||
### Excluido
|
||||
|
||||
- App mobile de administracion
|
||||
- Scraping de imagenes (fase 2)
|
||||
- APIs de terceros (Apify, etc.)
|
||||
- ML para extraccion (fase futura)
|
||||
|
||||
---
|
||||
|
||||
## Fuentes de Datos Objetivo
|
||||
|
||||
| Fuente | Prioridad | Proteccion | Estado |
|
||||
|--------|-----------|------------|--------|
|
||||
| Inmuebles24 | P1 | Cloudflare | Target |
|
||||
| Vivanuncios | P1 | Cloudflare | Target |
|
||||
| Segundamano | P2 | Basica | Backlog |
|
||||
| Metros Cubicos | P2 | Cloudflare | Backlog |
|
||||
|
||||
---
|
||||
|
||||
## Stack Tecnico
|
||||
|
||||
```yaml
|
||||
Scraping:
|
||||
browser: Playwright
|
||||
stealth: playwright-extra-stealth
|
||||
fallback: Puppeteer + undetected-chrome
|
||||
|
||||
Proxies:
|
||||
type: Residencial
|
||||
rotation: Por sesion
|
||||
provider: Bright Data / IPRoyal
|
||||
|
||||
ETL:
|
||||
queue: Bull (Redis)
|
||||
parser: Cheerio
|
||||
geocoding: Google Maps API
|
||||
|
||||
Storage:
|
||||
raw: S3/MinIO (JSON)
|
||||
normalized: PostgreSQL
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Arquitectura de Alto Nivel
|
||||
|
||||
```
|
||||
+----------------+
|
||||
| Scheduler |
|
||||
| (Bull Queue) |
|
||||
+-------+--------+
|
||||
|
|
||||
+-------------+-------------+
|
||||
| |
|
||||
+-------v-------+ +---------v---------+
|
||||
| Scraper Pool | | ETL Pipeline |
|
||||
| (Playwright) | | (Normalization) |
|
||||
+-------+-------+ +---------+---------+
|
||||
| |
|
||||
| +---------------+ |
|
||||
+-->| Proxy Pool |<------+
|
||||
+---------------+
|
||||
|
|
||||
+-----------+-----------+
|
||||
| |
|
||||
+-------v-------+ +-------v-------+
|
||||
| Raw Storage | | PostgreSQL |
|
||||
| (S3/JSON) | | (properties) |
|
||||
+---------------+ +---------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Desglose de Trabajo
|
||||
|
||||
### Fase 1: MVP Scraper (2-3 sprints)
|
||||
|
||||
| Tarea | SP | Prioridad |
|
||||
|-------|----|-----------|
|
||||
| Setup Playwright + stealth | 3 | Alta |
|
||||
| Scraper Inmuebles24 basico | 8 | Alta |
|
||||
| Integracion proxy pool | 5 | Alta |
|
||||
| Normalizacion basica | 5 | Alta |
|
||||
| Job scheduling simple | 3 | Media |
|
||||
|
||||
### Fase 2: Multi-source (1-2 sprints)
|
||||
|
||||
| Tarea | SP | Prioridad |
|
||||
|-------|----|-----------|
|
||||
| Scraper Vivanuncios | 5 | Alta |
|
||||
| Scraper Segundamano | 3 | Media |
|
||||
| Deduplicacion cross-source | 5 | Media |
|
||||
| Geocoding integration | 3 | Media |
|
||||
|
||||
### Fase 3: Produccion (1 sprint)
|
||||
|
||||
| Tarea | SP | Prioridad |
|
||||
|-------|----|-----------|
|
||||
| Monitoreo y alertas | 5 | Media |
|
||||
| Retry logic + error handling | 3 | Media |
|
||||
| Dashboard de admin | 5 | Baja |
|
||||
| Documentacion | 2 | Baja |
|
||||
|
||||
---
|
||||
|
||||
## Estimacion de Costos
|
||||
|
||||
```yaml
|
||||
Infraestructura_mensual:
|
||||
proxies_residenciales: $50-100 USD
|
||||
captcha_solving: $10-20 USD
|
||||
geocoding_api: $0-50 USD
|
||||
cloud_compute: $50-100 USD
|
||||
|
||||
Total: $100-300 USD/mes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Riesgos y Mitigaciones
|
||||
|
||||
| Riesgo | Prob | Impacto | Mitigacion |
|
||||
|--------|------|---------|------------|
|
||||
| Bloqueo Cloudflare | Alta | Alto | Stealth browser, proxies, rate limit |
|
||||
| Cambios HTML | Media | Medio | Selectores robustos, alertas |
|
||||
| Legal | Baja | Alto | Cumplir ToS, agregar valor |
|
||||
| Costos escalan | Media | Bajo | Optimizar, limitar scope |
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion del EPIC
|
||||
|
||||
- [ ] Scraper extrae 10,000+ propiedades de Inmuebles24
|
||||
- [ ] Tasa de exito >= 85%
|
||||
- [ ] Datos normalizados correctamente
|
||||
- [ ] Cero bloqueos permanentes de IP
|
||||
- [ ] Pipeline ejecuta incrementales diarios
|
||||
- [ ] Metricas disponibles en dashboard
|
||||
|
||||
---
|
||||
|
||||
## Documentacion Relacionada
|
||||
|
||||
- [IA-007-WEBSCRAPER.md](../../02-definicion-modulos/IA-007-WEBSCRAPER.md) - Definicion del modulo
|
||||
- [Webscraper_Politics.md](../../00-vision-general/Webscraper_Politics.md) - Politicas anti-bloqueo
|
||||
|
||||
---
|
||||
|
||||
**EPIC Owner:** Tech Lead
|
||||
**Fecha creacion:** 2026-01-04
|
||||
**Estado:** Draft
|
||||
128
docs/01-fase-alcance-inicial/IAI-007-webscraper/_MAP.md
Normal file
128
docs/01-fase-alcance-inicial/IAI-007-webscraper/_MAP.md
Normal file
@ -0,0 +1,128 @@
|
||||
---
|
||||
id: "MAP-IAI-007"
|
||||
title: "Mapa de EPIC IAI-007 Webscraper"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-007"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: EPIC IAI-007 - Web Scraping y ETL
|
||||
|
||||
**EPIC:** IAI-007
|
||||
**Nombre:** Sistema de Web Scraping y ETL
|
||||
**Estado:** Draft
|
||||
**Story Points:** 55 (estimado)
|
||||
|
||||
---
|
||||
|
||||
## Estructura del EPIC
|
||||
|
||||
```
|
||||
IAI-007-webscraper/
|
||||
├── _MAP.md # Este archivo
|
||||
├── README.md # Vision general del EPIC
|
||||
│
|
||||
├── requerimientos/
|
||||
│ ├── _MAP.md
|
||||
│ ├── RF-SCR-001.md # Motor de scraping
|
||||
│ ├── RF-SCR-002.md # Gestion de proxies
|
||||
│ ├── RF-SCR-003.md # Pipeline ETL
|
||||
│ ├── RF-SCR-004.md # Scheduling y jobs
|
||||
│ └── RF-SCR-005.md # Monitoreo
|
||||
│
|
||||
├── especificaciones/
|
||||
│ ├── _MAP.md
|
||||
│ ├── ET-SCR-001-scraper.md # Motor de scraping Playwright
|
||||
│ ├── ET-SCR-002-etl.md # Pipeline ETL y normalizacion
|
||||
│ └── ET-SCR-003-proxies.md # Gestion pool de proxies
|
||||
│
|
||||
├── historias-usuario/
|
||||
│ ├── _MAP.md
|
||||
│ ├── US-SCR-001.md # Scraping Inmuebles24
|
||||
│ ├── US-SCR-002.md # Scraping Vivanuncios
|
||||
│ ├── US-SCR-003.md # Normalizacion de datos
|
||||
│ ├── US-SCR-004.md # Programacion de jobs
|
||||
│ └── US-SCR-005.md # Dashboard de monitoreo
|
||||
│
|
||||
├── tareas/
|
||||
│ └── _MAP.md
|
||||
│
|
||||
└── implementacion/
|
||||
├── _MAP.md
|
||||
├── CHANGELOG.md # Historial de cambios
|
||||
└── TRACEABILITY.yml # Trazabilidad
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Requerimientos Funcionales
|
||||
|
||||
| ID | Nombre | Prioridad | Estado |
|
||||
|----|--------|-----------|--------|
|
||||
| RF-SCR-001 | Motor de scraping con anti-detection | Alta | Pendiente |
|
||||
| RF-SCR-002 | Gestion de pool de proxies | Alta | Pendiente |
|
||||
| RF-SCR-003 | Pipeline ETL y normalizacion | Alta | Pendiente |
|
||||
| RF-SCR-004 | Scheduling y job management | Media | Pendiente |
|
||||
| RF-SCR-005 | Monitoreo y alertas | Media | Pendiente |
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario
|
||||
|
||||
| ID | Titulo | SP | Prioridad | Sprint |
|
||||
|----|--------|----|-----------| -------|
|
||||
| US-SCR-001 | Scrapear propiedades de Inmuebles24 | 13 | Alta | - |
|
||||
| US-SCR-002 | Scrapear propiedades de Vivanuncios | 8 | Alta | - |
|
||||
| US-SCR-003 | Normalizar datos de multiples fuentes | 8 | Alta | - |
|
||||
| US-SCR-004 | Programar jobs de actualizacion | 5 | Media | - |
|
||||
| US-SCR-005 | Monitorear estado del scraping | 5 | Media | - |
|
||||
|
||||
**Total Story Points:** 39
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
### Depende de:
|
||||
- IAI-001: Fundamentos (autenticacion para API interna)
|
||||
- Infraestructura: Redis, PostgreSQL
|
||||
|
||||
### Bloquea a:
|
||||
- IAI-002: Propiedades (necesita datos)
|
||||
- IAI-008: ML/Analytics (necesita datos)
|
||||
|
||||
---
|
||||
|
||||
## Riesgos
|
||||
|
||||
| Riesgo | Probabilidad | Impacto | Mitigacion |
|
||||
|--------|--------------|---------|------------|
|
||||
| Bloqueo por Cloudflare | Alta | Alto | Anti-detection, proxies residenciales |
|
||||
| Cambios en estructura HTML | Media | Medio | Selectores flexibles, alertas |
|
||||
| Costos de proxies | Media | Bajo | Proveedores economicos, optimizacion |
|
||||
| Aspectos legales | Baja | Alto | Cumplir robots.txt, agregar datos |
|
||||
|
||||
---
|
||||
|
||||
## Metricas de Exito
|
||||
|
||||
- [ ] 10,000 propiedades scrapeadas en primera semana
|
||||
- [ ] Tasa de exito > 85%
|
||||
- [ ] Tiempo de normalizacion < 1s/propiedad
|
||||
- [ ] Cero bloqueos permanentes
|
||||
|
||||
---
|
||||
|
||||
## Especificaciones Tecnicas
|
||||
|
||||
| ID | Titulo | Estado | Contenido Principal |
|
||||
|----|--------|--------|---------------------|
|
||||
| ET-SCR-001 | Motor de Scraping | Creado | Playwright, stealth mode, BrowserManager |
|
||||
| ET-SCR-002 | Pipeline ETL | Creado | Extractors, normalizacion, geocoding, dedup |
|
||||
| ET-SCR-003 | Gestion de Proxies | Creado | Pool manager, rotacion, health checks |
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,965 @@
|
||||
---
|
||||
id: "ET-SCR-001"
|
||||
title: "Especificacion Tecnica: Motor de Scraping"
|
||||
type: "Technical Specification"
|
||||
epic: "IAI-007"
|
||||
status: "Draft"
|
||||
project: "inmobiliaria-analytics"
|
||||
version: "1.0.0"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# ET-SCR-001: Especificacion Tecnica del Motor de Scraping
|
||||
|
||||
---
|
||||
|
||||
## Resumen
|
||||
|
||||
Esta especificacion define la arquitectura e implementacion del motor de web scraping con capacidades anti-detection para extraer datos de portales inmobiliarios protegidos por Cloudflare.
|
||||
|
||||
---
|
||||
|
||||
## Stack Tecnologico
|
||||
|
||||
```yaml
|
||||
runtime: Node.js 20 LTS
|
||||
language: TypeScript 5.x
|
||||
|
||||
dependencias:
|
||||
scraping:
|
||||
- playwright: "^1.40.0"
|
||||
- playwright-extra: "^4.3.0"
|
||||
- puppeteer-extra-plugin-stealth: "^2.11.0"
|
||||
- cheerio: "^1.0.0"
|
||||
|
||||
queue:
|
||||
- bullmq: "^5.0.0"
|
||||
- ioredis: "^5.3.0"
|
||||
|
||||
http:
|
||||
- axios: "^1.6.0"
|
||||
- https-proxy-agent: "^7.0.0"
|
||||
|
||||
utils:
|
||||
- pino: "^8.0.0"
|
||||
- zod: "^3.22.0"
|
||||
- date-fns: "^3.0.0"
|
||||
|
||||
testing:
|
||||
- vitest: "^1.0.0"
|
||||
- msw: "^2.0.0"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Arquitectura de Componentes
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ SCRAPER SERVICE │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ Scheduler │───▶│ Job Queue │───▶│ Workers │ │
|
||||
│ │ (Cron/API) │ │ (BullMQ) │ │ (N=2-4) │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────┬───────┘ │
|
||||
│ │ │
|
||||
│ ┌──────────────────────┼──────────┐ │
|
||||
│ │ ▼ │ │
|
||||
│ ┌──────────────┐ ┌────┴─────────┐ ┌──────────────┐ │ │
|
||||
│ │ Proxy │◀───│ Browser │───▶│ Parser │ │ │
|
||||
│ │ Manager │ │ Engine │ │ (Cheerio) │ │ │
|
||||
│ └──────────────┘ │ (Playwright) │ └──────┬───────┘ │ │
|
||||
│ └──────────────┘ │ │ │
|
||||
│ ▼ │ │
|
||||
│ ┌──────────────┐ │ │
|
||||
│ │ Normalizer │ │ │
|
||||
│ └──────┬───────┘ │ │
|
||||
│ │ │ │
|
||||
│ Scraper Core │ │ │
|
||||
│ └────────────────────┼────────────┘ │
|
||||
│ ▼ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ Metrics │◀───│ Storage │───▶│ PostgreSQL │ │
|
||||
│ │ (Prometheus) │ │ (S3/Local) │ │ │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Estructura de Codigo
|
||||
|
||||
```
|
||||
apps/scraper/
|
||||
├── src/
|
||||
│ ├── index.ts # Entry point
|
||||
│ ├── config/
|
||||
│ │ ├── index.ts
|
||||
│ │ ├── sources.config.ts # Configuracion por fuente
|
||||
│ │ └── schedules.config.ts
|
||||
│ │
|
||||
│ ├── core/
|
||||
│ │ ├── browser/
|
||||
│ │ │ ├── browser-manager.ts
|
||||
│ │ │ ├── stealth-config.ts
|
||||
│ │ │ └── page-utils.ts
|
||||
│ │ │
|
||||
│ │ ├── proxy/
|
||||
│ │ │ ├── proxy-pool.ts
|
||||
│ │ │ ├── proxy-rotator.ts
|
||||
│ │ │ └── proxy-health.ts
|
||||
│ │ │
|
||||
│ │ ├── queue/
|
||||
│ │ │ ├── job-queue.ts
|
||||
│ │ │ ├── job-processor.ts
|
||||
│ │ │ └── job-types.ts
|
||||
│ │ │
|
||||
│ │ └── rate-limiter/
|
||||
│ │ └── adaptive-limiter.ts
|
||||
│ │
|
||||
│ ├── scrapers/
|
||||
│ │ ├── base-scraper.ts # Clase base abstracta
|
||||
│ │ ├── inmuebles24/
|
||||
│ │ │ ├── scraper.ts
|
||||
│ │ │ ├── selectors.ts
|
||||
│ │ │ └── mappings.ts
|
||||
│ │ ├── vivanuncios/
|
||||
│ │ │ ├── scraper.ts
|
||||
│ │ │ ├── selectors.ts
|
||||
│ │ │ └── mappings.ts
|
||||
│ │ └── segundamano/
|
||||
│ │ └── ...
|
||||
│ │
|
||||
│ ├── etl/
|
||||
│ │ ├── extractor.ts
|
||||
│ │ ├── transformer.ts
|
||||
│ │ ├── normalizer.ts
|
||||
│ │ ├── geocoder.ts
|
||||
│ │ └── deduplicator.ts
|
||||
│ │
|
||||
│ ├── storage/
|
||||
│ │ ├── raw-storage.ts # S3/MinIO
|
||||
│ │ └── property-repository.ts
|
||||
│ │
|
||||
│ ├── monitoring/
|
||||
│ │ ├── metrics.ts
|
||||
│ │ ├── alerts.ts
|
||||
│ │ └── health-check.ts
|
||||
│ │
|
||||
│ ├── api/
|
||||
│ │ ├── routes/
|
||||
│ │ │ ├── jobs.routes.ts
|
||||
│ │ │ ├── stats.routes.ts
|
||||
│ │ │ └── proxies.routes.ts
|
||||
│ │ └── server.ts
|
||||
│ │
|
||||
│ └── types/
|
||||
│ ├── job.types.ts
|
||||
│ ├── property.types.ts
|
||||
│ └── proxy.types.ts
|
||||
│
|
||||
├── tests/
|
||||
│ ├── unit/
|
||||
│ ├── integration/
|
||||
│ └── e2e/
|
||||
│
|
||||
├── Dockerfile
|
||||
├── docker-compose.yml
|
||||
├── package.json
|
||||
└── tsconfig.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementacion del Browser Engine
|
||||
|
||||
### Browser Manager
|
||||
|
||||
```typescript
|
||||
// src/core/browser/browser-manager.ts
|
||||
import { chromium, Browser, BrowserContext, Page } from 'playwright';
|
||||
import { addExtra } from 'playwright-extra';
|
||||
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
|
||||
|
||||
export class BrowserManager {
|
||||
private browser: Browser | null = null;
|
||||
private contexts: Map<string, BrowserContext> = new Map();
|
||||
|
||||
async initialize(): Promise<void> {
|
||||
const chromiumExtra = addExtra(chromium);
|
||||
chromiumExtra.use(StealthPlugin());
|
||||
|
||||
this.browser = await chromiumExtra.launch({
|
||||
headless: true,
|
||||
args: [
|
||||
'--no-sandbox',
|
||||
'--disable-setuid-sandbox',
|
||||
'--disable-dev-shm-usage',
|
||||
'--disable-accelerated-2d-canvas',
|
||||
'--disable-gpu',
|
||||
'--window-size=1920,1080',
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
async createContext(
|
||||
sessionId: string,
|
||||
proxy?: ProxyConfig
|
||||
): Promise<BrowserContext> {
|
||||
if (!this.browser) throw new Error('Browser not initialized');
|
||||
|
||||
const context = await this.browser.newContext({
|
||||
viewport: { width: 1920, height: 1080 },
|
||||
userAgent: this.getRandomUserAgent(),
|
||||
locale: 'es-MX',
|
||||
timezoneId: 'America/Mexico_City',
|
||||
proxy: proxy ? {
|
||||
server: `${proxy.address}:${proxy.port}`,
|
||||
username: proxy.username,
|
||||
password: proxy.password,
|
||||
} : undefined,
|
||||
});
|
||||
|
||||
// Anti-detection patches
|
||||
await this.applyStealthPatches(context);
|
||||
|
||||
this.contexts.set(sessionId, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
private async applyStealthPatches(context: BrowserContext): Promise<void> {
|
||||
await context.addInitScript(() => {
|
||||
// Hide webdriver
|
||||
Object.defineProperty(navigator, 'webdriver', {
|
||||
get: () => undefined,
|
||||
});
|
||||
|
||||
// Mock plugins
|
||||
Object.defineProperty(navigator, 'plugins', {
|
||||
get: () => [1, 2, 3, 4, 5],
|
||||
});
|
||||
|
||||
// Mock languages
|
||||
Object.defineProperty(navigator, 'languages', {
|
||||
get: () => ['es-MX', 'es', 'en-US', 'en'],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private getRandomUserAgent(): string {
|
||||
const userAgents = [
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
|
||||
// ... more user agents
|
||||
];
|
||||
return userAgents[Math.floor(Math.random() * userAgents.length)];
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
for (const context of this.contexts.values()) {
|
||||
await context.close();
|
||||
}
|
||||
if (this.browser) {
|
||||
await this.browser.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Human-like Behavior
|
||||
|
||||
```typescript
|
||||
// src/core/browser/page-utils.ts
|
||||
import { Page } from 'playwright';
|
||||
|
||||
export class PageUtils {
|
||||
static async humanScroll(page: Page): Promise<void> {
|
||||
const scrollHeight = await page.evaluate(() => document.body.scrollHeight);
|
||||
let currentPosition = 0;
|
||||
|
||||
while (currentPosition < scrollHeight) {
|
||||
const scrollAmount = Math.random() * 300 + 100;
|
||||
currentPosition += scrollAmount;
|
||||
|
||||
await page.evaluate((y) => window.scrollTo(0, y), currentPosition);
|
||||
await this.randomDelay(100, 300);
|
||||
}
|
||||
}
|
||||
|
||||
static async humanClick(page: Page, selector: string): Promise<void> {
|
||||
const element = await page.$(selector);
|
||||
if (!element) throw new Error(`Element not found: ${selector}`);
|
||||
|
||||
const box = await element.boundingBox();
|
||||
if (!box) throw new Error(`Element not visible: ${selector}`);
|
||||
|
||||
// Move to element with slight randomness
|
||||
const x = box.x + box.width / 2 + (Math.random() * 10 - 5);
|
||||
const y = box.y + box.height / 2 + (Math.random() * 10 - 5);
|
||||
|
||||
await page.mouse.move(x, y, { steps: 10 });
|
||||
await this.randomDelay(50, 150);
|
||||
await page.mouse.click(x, y);
|
||||
}
|
||||
|
||||
static async randomDelay(min: number, max: number): Promise<void> {
|
||||
const delay = Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
await new Promise(resolve => setTimeout(resolve, delay));
|
||||
}
|
||||
|
||||
static async waitForCloudflare(page: Page): Promise<void> {
|
||||
// Wait for Cloudflare challenge to complete
|
||||
try {
|
||||
await page.waitForSelector('#challenge-running', {
|
||||
state: 'hidden',
|
||||
timeout: 30000,
|
||||
});
|
||||
} catch {
|
||||
// No challenge present, continue
|
||||
}
|
||||
|
||||
// Additional wait for JS to fully load
|
||||
await page.waitForLoadState('networkidle');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Base Scraper Implementation
|
||||
|
||||
```typescript
|
||||
// src/scrapers/base-scraper.ts
|
||||
import { Page, BrowserContext } from 'playwright';
|
||||
import { BrowserManager } from '../core/browser/browser-manager';
|
||||
import { ProxyPool } from '../core/proxy/proxy-pool';
|
||||
import { PageUtils } from '../core/browser/page-utils';
|
||||
import { Logger } from 'pino';
|
||||
|
||||
export interface ScrapingResult {
|
||||
success: boolean;
|
||||
properties: RawProperty[];
|
||||
errors: ScrapingError[];
|
||||
stats: ScrapingStats;
|
||||
}
|
||||
|
||||
export abstract class BaseScraper {
|
||||
protected browserManager: BrowserManager;
|
||||
protected proxyPool: ProxyPool;
|
||||
protected logger: Logger;
|
||||
protected context: BrowserContext | null = null;
|
||||
protected page: Page | null = null;
|
||||
|
||||
abstract readonly source: string;
|
||||
abstract readonly baseUrl: string;
|
||||
|
||||
constructor(
|
||||
browserManager: BrowserManager,
|
||||
proxyPool: ProxyPool,
|
||||
logger: Logger
|
||||
) {
|
||||
this.browserManager = browserManager;
|
||||
this.proxyPool = proxyPool;
|
||||
this.logger = logger.child({ source: this.source });
|
||||
}
|
||||
|
||||
async scrape(config: ScrapingConfig): Promise<ScrapingResult> {
|
||||
const stats: ScrapingStats = {
|
||||
pagesScraped: 0,
|
||||
propertiesFound: 0,
|
||||
errors: 0,
|
||||
startedAt: new Date(),
|
||||
};
|
||||
|
||||
const properties: RawProperty[] = [];
|
||||
const errors: ScrapingError[] = [];
|
||||
|
||||
try {
|
||||
await this.initSession();
|
||||
|
||||
for (const city of config.targetCities) {
|
||||
for (const type of config.propertyTypes) {
|
||||
const result = await this.scrapeListings(city, type, config);
|
||||
properties.push(...result.properties);
|
||||
errors.push(...result.errors);
|
||||
stats.pagesScraped += result.pagesScraped;
|
||||
}
|
||||
}
|
||||
|
||||
stats.propertiesFound = properties.length;
|
||||
stats.errors = errors.length;
|
||||
stats.completedAt = new Date();
|
||||
|
||||
return { success: true, properties, errors, stats };
|
||||
|
||||
} catch (error) {
|
||||
this.logger.error({ error }, 'Scraping failed');
|
||||
return {
|
||||
success: false,
|
||||
properties,
|
||||
errors: [...errors, { type: 'fatal', message: String(error) }],
|
||||
stats,
|
||||
};
|
||||
} finally {
|
||||
await this.closeSession();
|
||||
}
|
||||
}
|
||||
|
||||
protected async initSession(): Promise<void> {
|
||||
const proxy = await this.proxyPool.getProxy();
|
||||
const sessionId = `${this.source}-${Date.now()}`;
|
||||
|
||||
this.context = await this.browserManager.createContext(sessionId, proxy);
|
||||
this.page = await this.context.newPage();
|
||||
|
||||
// Set default timeout
|
||||
this.page.setDefaultTimeout(30000);
|
||||
}
|
||||
|
||||
protected async closeSession(): Promise<void> {
|
||||
if (this.page) await this.page.close();
|
||||
if (this.context) await this.context.close();
|
||||
}
|
||||
|
||||
protected async navigateWithRetry(
|
||||
url: string,
|
||||
maxRetries: number = 3
|
||||
): Promise<void> {
|
||||
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
||||
try {
|
||||
await this.page!.goto(url, { waitUntil: 'domcontentloaded' });
|
||||
await PageUtils.waitForCloudflare(this.page!);
|
||||
return;
|
||||
} catch (error) {
|
||||
this.logger.warn({ url, attempt, error }, 'Navigation failed, retrying');
|
||||
|
||||
if (attempt === maxRetries) throw error;
|
||||
|
||||
// Rotate proxy on failure
|
||||
await this.rotateProxy();
|
||||
await PageUtils.randomDelay(2000, 5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected async rotateProxy(): Promise<void> {
|
||||
const newProxy = await this.proxyPool.getProxy();
|
||||
await this.closeSession();
|
||||
|
||||
const sessionId = `${this.source}-${Date.now()}`;
|
||||
this.context = await this.browserManager.createContext(sessionId, newProxy);
|
||||
this.page = await this.context.newPage();
|
||||
}
|
||||
|
||||
// Abstract methods to be implemented by each source
|
||||
protected abstract scrapeListings(
|
||||
city: string,
|
||||
propertyType: string,
|
||||
config: ScrapingConfig
|
||||
): Promise<ListingResult>;
|
||||
|
||||
protected abstract parsePropertyDetail(
|
||||
page: Page
|
||||
): Promise<RawProperty>;
|
||||
|
||||
protected abstract getListingUrl(
|
||||
city: string,
|
||||
propertyType: string,
|
||||
page: number
|
||||
): string;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Proxy Pool Implementation
|
||||
|
||||
```typescript
|
||||
// src/core/proxy/proxy-pool.ts
|
||||
import { Redis } from 'ioredis';
|
||||
|
||||
export interface ProxyConfig {
|
||||
id: string;
|
||||
address: string;
|
||||
port: number;
|
||||
username?: string;
|
||||
password?: string;
|
||||
type: 'residential' | 'datacenter' | 'mobile';
|
||||
country: string;
|
||||
status: 'active' | 'cooling' | 'banned';
|
||||
successRate: number;
|
||||
lastUsedAt?: Date;
|
||||
coolingUntil?: Date;
|
||||
}
|
||||
|
||||
export class ProxyPool {
|
||||
private redis: Redis;
|
||||
private readonly POOL_KEY = 'proxy:pool';
|
||||
private readonly COOLING_KEY = 'proxy:cooling';
|
||||
|
||||
constructor(redis: Redis) {
|
||||
this.redis = redis;
|
||||
}
|
||||
|
||||
async getProxy(): Promise<ProxyConfig> {
|
||||
// Get all active proxies
|
||||
const proxies = await this.getActiveProxies();
|
||||
|
||||
if (proxies.length === 0) {
|
||||
throw new Error('No active proxies available');
|
||||
}
|
||||
|
||||
// Weighted selection based on success rate
|
||||
const selected = this.weightedSelection(proxies);
|
||||
|
||||
// Mark as used
|
||||
await this.markUsed(selected.id);
|
||||
|
||||
return selected;
|
||||
}
|
||||
|
||||
private async getActiveProxies(): Promise<ProxyConfig[]> {
|
||||
const all = await this.redis.hgetall(this.POOL_KEY);
|
||||
const now = Date.now();
|
||||
|
||||
return Object.values(all)
|
||||
.map(p => JSON.parse(p) as ProxyConfig)
|
||||
.filter(p => {
|
||||
if (p.status === 'banned') return false;
|
||||
if (p.status === 'cooling' && p.coolingUntil) {
|
||||
return new Date(p.coolingUntil).getTime() < now;
|
||||
}
|
||||
return p.status === 'active';
|
||||
});
|
||||
}
|
||||
|
||||
private weightedSelection(proxies: ProxyConfig[]): ProxyConfig {
|
||||
// Higher success rate = higher weight
|
||||
const totalWeight = proxies.reduce((sum, p) => sum + p.successRate, 0);
|
||||
let random = Math.random() * totalWeight;
|
||||
|
||||
for (const proxy of proxies) {
|
||||
random -= proxy.successRate;
|
||||
if (random <= 0) return proxy;
|
||||
}
|
||||
|
||||
return proxies[0];
|
||||
}
|
||||
|
||||
async markUsed(proxyId: string): Promise<void> {
|
||||
const proxy = await this.getProxy(proxyId);
|
||||
if (proxy) {
|
||||
proxy.lastUsedAt = new Date();
|
||||
await this.redis.hset(this.POOL_KEY, proxyId, JSON.stringify(proxy));
|
||||
}
|
||||
}
|
||||
|
||||
async markSuccess(proxyId: string): Promise<void> {
|
||||
const proxy = await this.getProxyById(proxyId);
|
||||
if (proxy) {
|
||||
// Update success rate with exponential moving average
|
||||
proxy.successRate = proxy.successRate * 0.9 + 1 * 0.1;
|
||||
await this.redis.hset(this.POOL_KEY, proxyId, JSON.stringify(proxy));
|
||||
}
|
||||
}
|
||||
|
||||
async markFailure(proxyId: string, errorType: string): Promise<void> {
|
||||
const proxy = await this.getProxyById(proxyId);
|
||||
if (!proxy) return;
|
||||
|
||||
// Update success rate
|
||||
proxy.successRate = proxy.successRate * 0.9 + 0 * 0.1;
|
||||
|
||||
if (errorType === 'rate_limit') {
|
||||
// Put in cooling for 1 hour
|
||||
proxy.status = 'cooling';
|
||||
proxy.coolingUntil = new Date(Date.now() + 3600000);
|
||||
} else if (errorType === 'banned') {
|
||||
proxy.status = 'banned';
|
||||
}
|
||||
|
||||
await this.redis.hset(this.POOL_KEY, proxyId, JSON.stringify(proxy));
|
||||
}
|
||||
|
||||
async getStats(): Promise<ProxyPoolStats> {
|
||||
const all = await this.redis.hgetall(this.POOL_KEY);
|
||||
const proxies = Object.values(all).map(p => JSON.parse(p) as ProxyConfig);
|
||||
|
||||
return {
|
||||
total: proxies.length,
|
||||
active: proxies.filter(p => p.status === 'active').length,
|
||||
cooling: proxies.filter(p => p.status === 'cooling').length,
|
||||
banned: proxies.filter(p => p.status === 'banned').length,
|
||||
avgSuccessRate: proxies.reduce((sum, p) => sum + p.successRate, 0) / proxies.length,
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Job Queue Implementation
|
||||
|
||||
```typescript
|
||||
// src/core/queue/job-queue.ts
|
||||
import { Queue, Worker, Job } from 'bullmq';
|
||||
import { Redis } from 'ioredis';
|
||||
|
||||
export interface ScrapingJobData {
|
||||
id: string;
|
||||
type: 'full_scan' | 'incremental' | 'targeted' | 'refresh';
|
||||
source: string;
|
||||
config: ScrapingConfig;
|
||||
createdBy?: string;
|
||||
}
|
||||
|
||||
export class JobQueue {
|
||||
private queue: Queue<ScrapingJobData>;
|
||||
private worker: Worker<ScrapingJobData>;
|
||||
private redis: Redis;
|
||||
|
||||
constructor(redis: Redis, processor: JobProcessor) {
|
||||
this.redis = redis;
|
||||
|
||||
this.queue = new Queue('scraping', {
|
||||
connection: redis,
|
||||
defaultJobOptions: {
|
||||
attempts: 3,
|
||||
backoff: {
|
||||
type: 'exponential',
|
||||
delay: 5000,
|
||||
},
|
||||
removeOnComplete: 100,
|
||||
removeOnFail: 50,
|
||||
},
|
||||
});
|
||||
|
||||
this.worker = new Worker(
|
||||
'scraping',
|
||||
async (job: Job<ScrapingJobData>) => {
|
||||
return processor.process(job);
|
||||
},
|
||||
{
|
||||
connection: redis,
|
||||
concurrency: 2,
|
||||
}
|
||||
);
|
||||
|
||||
this.setupEventHandlers();
|
||||
}
|
||||
|
||||
private setupEventHandlers(): void {
|
||||
this.worker.on('completed', (job, result) => {
|
||||
console.log(`Job ${job.id} completed`, result);
|
||||
});
|
||||
|
||||
this.worker.on('failed', (job, error) => {
|
||||
console.error(`Job ${job?.id} failed`, error);
|
||||
});
|
||||
|
||||
this.worker.on('progress', (job, progress) => {
|
||||
console.log(`Job ${job.id} progress: ${progress}%`);
|
||||
});
|
||||
}
|
||||
|
||||
async addJob(data: ScrapingJobData): Promise<Job<ScrapingJobData>> {
|
||||
return this.queue.add(data.type, data, {
|
||||
jobId: data.id,
|
||||
});
|
||||
}
|
||||
|
||||
async scheduleJob(
|
||||
data: ScrapingJobData,
|
||||
cron: string
|
||||
): Promise<void> {
|
||||
await this.queue.add(data.type, data, {
|
||||
repeat: { pattern: cron },
|
||||
jobId: `${data.id}-scheduled`,
|
||||
});
|
||||
}
|
||||
|
||||
async pauseJob(jobId: string): Promise<void> {
|
||||
const job = await this.queue.getJob(jobId);
|
||||
if (job) {
|
||||
await job.updateProgress({ status: 'paused' });
|
||||
}
|
||||
}
|
||||
|
||||
async getJobStatus(jobId: string): Promise<JobStatus | null> {
|
||||
const job = await this.queue.getJob(jobId);
|
||||
if (!job) return null;
|
||||
|
||||
const state = await job.getState();
|
||||
return {
|
||||
id: job.id!,
|
||||
state,
|
||||
progress: job.progress,
|
||||
data: job.data,
|
||||
attemptsMade: job.attemptsMade,
|
||||
failedReason: job.failedReason,
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints
|
||||
|
||||
```typescript
|
||||
// src/api/routes/jobs.routes.ts
|
||||
import { Router } from 'express';
|
||||
import { z } from 'zod';
|
||||
|
||||
const CreateJobSchema = z.object({
|
||||
type: z.enum(['full_scan', 'incremental', 'targeted', 'refresh']),
|
||||
source: z.string(),
|
||||
config: z.object({
|
||||
targetCities: z.array(z.string()).optional(),
|
||||
propertyTypes: z.array(z.string()).optional(),
|
||||
maxPages: z.number().optional(),
|
||||
delayMs: z.object({
|
||||
min: z.number(),
|
||||
max: z.number(),
|
||||
}).optional(),
|
||||
}),
|
||||
});
|
||||
|
||||
export function createJobsRouter(jobQueue: JobQueue): Router {
|
||||
const router = Router();
|
||||
|
||||
// Create new job
|
||||
router.post('/', async (req, res) => {
|
||||
const parsed = CreateJobSchema.safeParse(req.body);
|
||||
if (!parsed.success) {
|
||||
return res.status(400).json({ error: parsed.error });
|
||||
}
|
||||
|
||||
const jobId = `job-${Date.now()}`;
|
||||
const job = await jobQueue.addJob({
|
||||
id: jobId,
|
||||
...parsed.data,
|
||||
});
|
||||
|
||||
res.status(201).json({
|
||||
id: job.id,
|
||||
status: 'queued',
|
||||
});
|
||||
});
|
||||
|
||||
// List jobs
|
||||
router.get('/', async (req, res) => {
|
||||
const jobs = await jobQueue.getJobs(req.query);
|
||||
res.json({ jobs });
|
||||
});
|
||||
|
||||
// Get job status
|
||||
router.get('/:id', async (req, res) => {
|
||||
const status = await jobQueue.getJobStatus(req.params.id);
|
||||
if (!status) {
|
||||
return res.status(404).json({ error: 'Job not found' });
|
||||
}
|
||||
res.json(status);
|
||||
});
|
||||
|
||||
// Pause job
|
||||
router.post('/:id/pause', async (req, res) => {
|
||||
await jobQueue.pauseJob(req.params.id);
|
||||
res.json({ status: 'paused' });
|
||||
});
|
||||
|
||||
// Resume job
|
||||
router.post('/:id/resume', async (req, res) => {
|
||||
await jobQueue.resumeJob(req.params.id);
|
||||
res.json({ status: 'resumed' });
|
||||
});
|
||||
|
||||
// Cancel job
|
||||
router.delete('/:id', async (req, res) => {
|
||||
await jobQueue.cancelJob(req.params.id);
|
||||
res.status(204).send();
|
||||
});
|
||||
|
||||
return router;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Docker Configuration
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
scraper:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- REDIS_URL=redis://redis:6379
|
||||
- DATABASE_URL=postgresql://user:pass@postgres:5432/inmobiliaria
|
||||
- S3_ENDPOINT=http://minio:9000
|
||||
- S3_BUCKET=raw-data
|
||||
depends_on:
|
||||
- redis
|
||||
- postgres
|
||||
- minio
|
||||
deploy:
|
||||
replicas: 2
|
||||
resources:
|
||||
limits:
|
||||
memory: 2G
|
||||
cpus: '1'
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
POSTGRES_DB: inmobiliaria
|
||||
POSTGRES_USER: user
|
||||
POSTGRES_PASSWORD: pass
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
|
||||
minio:
|
||||
image: minio/minio
|
||||
command: server /data --console-address ":9001"
|
||||
environment:
|
||||
MINIO_ROOT_USER: minioadmin
|
||||
MINIO_ROOT_PASSWORD: minioadmin
|
||||
volumes:
|
||||
- minio-data:/data
|
||||
|
||||
volumes:
|
||||
redis-data:
|
||||
postgres-data:
|
||||
minio-data:
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Metricas Prometheus
|
||||
|
||||
```typescript
|
||||
// src/monitoring/metrics.ts
|
||||
import { Registry, Counter, Histogram, Gauge } from 'prom-client';
|
||||
|
||||
export const register = new Registry();
|
||||
|
||||
export const metrics = {
|
||||
propertiesScraped: new Counter({
|
||||
name: 'scraper_properties_total',
|
||||
help: 'Total properties scraped',
|
||||
labelNames: ['source', 'status'],
|
||||
registers: [register],
|
||||
}),
|
||||
|
||||
requestDuration: new Histogram({
|
||||
name: 'scraper_request_duration_seconds',
|
||||
help: 'Duration of scraping requests',
|
||||
labelNames: ['source'],
|
||||
buckets: [0.1, 0.5, 1, 2, 5, 10, 30],
|
||||
registers: [register],
|
||||
}),
|
||||
|
||||
activeJobs: new Gauge({
|
||||
name: 'scraper_active_jobs',
|
||||
help: 'Number of active scraping jobs',
|
||||
labelNames: ['source'],
|
||||
registers: [register],
|
||||
}),
|
||||
|
||||
proxyPoolSize: new Gauge({
|
||||
name: 'scraper_proxy_pool_size',
|
||||
help: 'Size of proxy pool by status',
|
||||
labelNames: ['status'],
|
||||
registers: [register],
|
||||
}),
|
||||
|
||||
errorsTotal: new Counter({
|
||||
name: 'scraper_errors_total',
|
||||
help: 'Total scraping errors',
|
||||
labelNames: ['source', 'error_type'],
|
||||
registers: [register],
|
||||
}),
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
```typescript
|
||||
// tests/integration/inmuebles24.test.ts
|
||||
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
||||
import { BrowserManager } from '../../src/core/browser/browser-manager';
|
||||
import { Inmuebles24Scraper } from '../../src/scrapers/inmuebles24/scraper';
|
||||
|
||||
describe('Inmuebles24 Scraper', () => {
|
||||
let browserManager: BrowserManager;
|
||||
let scraper: Inmuebles24Scraper;
|
||||
|
||||
beforeAll(async () => {
|
||||
browserManager = new BrowserManager();
|
||||
await browserManager.initialize();
|
||||
scraper = new Inmuebles24Scraper(browserManager, mockProxyPool, mockLogger);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await browserManager.close();
|
||||
});
|
||||
|
||||
it('should extract property listings from search page', async () => {
|
||||
const result = await scraper.scrape({
|
||||
targetCities: ['guadalajara'],
|
||||
propertyTypes: ['casas'],
|
||||
maxPages: 1,
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.properties.length).toBeGreaterThan(0);
|
||||
expect(result.properties[0]).toHaveProperty('source_id');
|
||||
expect(result.properties[0]).toHaveProperty('price');
|
||||
});
|
||||
|
||||
it('should handle Cloudflare challenge', async () => {
|
||||
// Test with mock that returns challenge page
|
||||
// Verify scraper waits and retries
|
||||
});
|
||||
|
||||
it('should rotate proxy on failure', async () => {
|
||||
// Test proxy rotation logic
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion Tecnicos
|
||||
|
||||
- [ ] Bot detection tests pass (bot.sannysoft.com)
|
||||
- [ ] Scraper extracts 500+ properties without block
|
||||
- [ ] Request latency p95 < 10s
|
||||
- [ ] Memory usage < 500MB per worker
|
||||
- [ ] CPU usage < 50% average
|
||||
- [ ] Error rate < 5%
|
||||
- [ ] All unit tests pass
|
||||
- [ ] Integration tests pass
|
||||
|
||||
---
|
||||
|
||||
**Documento:** Especificacion Tecnica Motor Scraping
|
||||
**Version:** 1.0.0
|
||||
**Autor:** Tech Lead
|
||||
**Fecha:** 2026-01-04
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,35 @@
|
||||
---
|
||||
id: "MAP-IAI-007-ET"
|
||||
title: "Mapa Especificaciones IAI-007"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-007"
|
||||
section: "especificaciones"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Especificaciones Tecnicas - IAI-007 Webscraper
|
||||
|
||||
**EPIC:** IAI-007
|
||||
**Seccion:** Especificaciones Tecnicas
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
| ID | Archivo | Titulo | Estado |
|
||||
|----|---------|--------|--------|
|
||||
| ET-SCR-001 | [ET-SCR-001-scraper.md](./ET-SCR-001-scraper.md) | Motor de Scraping Playwright | Creado |
|
||||
| ET-SCR-002 | [ET-SCR-002-etl.md](./ET-SCR-002-etl.md) | Pipeline ETL y Normalizacion | Creado |
|
||||
| ET-SCR-003 | [ET-SCR-003-proxies.md](./ET-SCR-003-proxies.md) | Gestion Pool de Proxies | Creado |
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-007-webscraper/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,179 @@
|
||||
---
|
||||
id: "US-SCR-001"
|
||||
title: "Scraping de propiedades desde Inmuebles24"
|
||||
type: "User Story"
|
||||
epic: "IAI-007"
|
||||
status: "Draft"
|
||||
story_points: 13
|
||||
priority: "Alta"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# US-SCR-001: Scraping de propiedades desde Inmuebles24
|
||||
|
||||
---
|
||||
|
||||
## User Story
|
||||
|
||||
**Como** administrador del sistema
|
||||
**Quiero** que el sistema extraiga automaticamente propiedades de Inmuebles24
|
||||
**Para** tener datos actualizados del mercado inmobiliario mexicano
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
Implementar un scraper robusto que extraiga listados de propiedades del portal Inmuebles24, manejando la proteccion de Cloudflare y respetando las politicas de rate limiting para evitar bloqueos.
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
### Funcionales
|
||||
|
||||
- [ ] El scraper puede navegar y extraer listados de propiedades
|
||||
- [ ] Extrae todos los campos requeridos (precio, ubicacion, caracteristicas)
|
||||
- [ ] Maneja paginacion hasta el limite configurado
|
||||
- [ ] Almacena datos raw en formato JSON
|
||||
|
||||
### Tecnicos
|
||||
|
||||
- [ ] Usa Playwright con stealth mode
|
||||
- [ ] Rotacion de proxies residenciales
|
||||
- [ ] Delay configurable entre requests (2-5s base)
|
||||
- [ ] Manejo de reintentos con backoff exponencial
|
||||
|
||||
### Anti-detection
|
||||
|
||||
- [ ] Simula comportamiento humano (scroll, delays)
|
||||
- [ ] User-Agent rotativo y realista
|
||||
- [ ] Maneja desafios de Cloudflare Turnstile
|
||||
- [ ] Respeta robots.txt (paginas 1-5 inicialmente)
|
||||
|
||||
---
|
||||
|
||||
## Campos a Extraer
|
||||
|
||||
```yaml
|
||||
Requeridos:
|
||||
- source_id: ID interno de Inmuebles24
|
||||
- source_url: URL de la propiedad
|
||||
- title: Titulo del anuncio
|
||||
- price: Precio (numerico)
|
||||
- currency: MXN/USD
|
||||
- property_type: casa/departamento/terreno/etc
|
||||
- transaction_type: venta/renta
|
||||
- bedrooms: Recamaras
|
||||
- bathrooms: Banos
|
||||
- construction_m2: Metros construidos
|
||||
- land_m2: Metros de terreno
|
||||
- address: Direccion
|
||||
- neighborhood: Colonia
|
||||
- city: Ciudad
|
||||
- state: Estado
|
||||
- description: Descripcion completa
|
||||
|
||||
Opcionales:
|
||||
- parking_spaces: Estacionamientos
|
||||
- age_years: Antiguedad
|
||||
- amenities: Lista de amenidades
|
||||
- images: URLs de imagenes
|
||||
- latitude: Coordenada
|
||||
- longitude: Coordenada
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tareas Tecnicas
|
||||
|
||||
| # | Tarea | Estimacion |
|
||||
|---|-------|------------|
|
||||
| 1 | Setup Playwright + stealth plugins | 2h |
|
||||
| 2 | Implementar navegacion de listados | 4h |
|
||||
| 3 | Parser de detalle de propiedad | 4h |
|
||||
| 4 | Integracion con proxy pool | 3h |
|
||||
| 5 | Rate limiting y delays | 2h |
|
||||
| 6 | Manejo de errores y reintentos | 3h |
|
||||
| 7 | Storage de raw data (S3/local) | 2h |
|
||||
| 8 | Tests unitarios y de integracion | 4h |
|
||||
|
||||
**Total estimado:** 24h (~3 dias)
|
||||
|
||||
---
|
||||
|
||||
## Configuracion
|
||||
|
||||
```yaml
|
||||
scraper_config:
|
||||
source: inmuebles24
|
||||
base_url: https://www.inmuebles24.com
|
||||
|
||||
targets:
|
||||
cities:
|
||||
- guadalajara
|
||||
- monterrey
|
||||
- ciudad-de-mexico
|
||||
property_types:
|
||||
- casas
|
||||
- departamentos
|
||||
|
||||
limits:
|
||||
max_pages_per_city: 5
|
||||
max_properties_per_run: 500
|
||||
delay_ms:
|
||||
min: 2000
|
||||
max: 5000
|
||||
|
||||
proxy:
|
||||
type: residential
|
||||
rotate_every: session
|
||||
|
||||
retry:
|
||||
max_attempts: 3
|
||||
backoff_multiplier: 2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notas de Implementacion
|
||||
|
||||
1. **Selectores**: Usar selectores CSS robustos, evitar XPath fragiles
|
||||
2. **Cloudflare**: Esperar carga completa antes de extraer
|
||||
3. **CAPTCHA**: Si aparece frecuentemente, activar solver externo
|
||||
4. **Logs**: Logging detallado para debugging
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] Codigo implementado y revisado
|
||||
- [ ] Tests pasan (unit + integracion)
|
||||
- [ ] Scraper extrae 500+ propiedades sin bloqueos
|
||||
- [ ] Documentacion actualizada
|
||||
- [ ] Metricas de exito > 80%
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
- Proxy pool configurado (US-SCR-000)
|
||||
- Redis para Bull Queue
|
||||
- Storage S3/local para raw data
|
||||
|
||||
---
|
||||
|
||||
## Riesgos
|
||||
|
||||
| Riesgo | Mitigacion |
|
||||
|--------|------------|
|
||||
| Cambios en HTML | Alertas + selectores flexibles |
|
||||
| Rate limit | Delay adaptativo |
|
||||
| IP ban | Pool de proxies amplio |
|
||||
|
||||
---
|
||||
|
||||
**Asignado a:** -
|
||||
**Sprint:** -
|
||||
**Fecha limite:** -
|
||||
@ -0,0 +1,98 @@
|
||||
---
|
||||
id: "US-SCR-002"
|
||||
title: "Scraping de propiedades desde Vivanuncios"
|
||||
type: "User Story"
|
||||
epic: "IAI-007"
|
||||
status: "Draft"
|
||||
story_points: 8
|
||||
priority: "Alta"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# US-SCR-002: Scraping de propiedades desde Vivanuncios
|
||||
|
||||
---
|
||||
|
||||
## User Story
|
||||
|
||||
**Como** administrador del sistema
|
||||
**Quiero** que el sistema extraiga automaticamente propiedades de Vivanuncios
|
||||
**Para** complementar datos de Inmuebles24 y tener mayor cobertura del mercado
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
Implementar un scraper para el portal Vivanuncios que reutilice la infraestructura base del scraper de Inmuebles24, adaptando los selectores y mappings especificos del sitio.
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
### Funcionales
|
||||
|
||||
- [ ] El scraper navega y extrae listados de Vivanuncios
|
||||
- [ ] Extrae todos los campos del schema normalizado
|
||||
- [ ] Maneja paginacion del sitio
|
||||
- [ ] Datos se almacenan en formato unificado
|
||||
|
||||
### Tecnicos
|
||||
|
||||
- [ ] Reutiliza motor de scraping base
|
||||
- [ ] Selectores especificos para Vivanuncios
|
||||
- [ ] Mappings de campos documentados
|
||||
- [ ] Tests de integracion especificos
|
||||
|
||||
---
|
||||
|
||||
## Campos a Extraer
|
||||
|
||||
```yaml
|
||||
Mappings_Vivanuncios:
|
||||
property_type:
|
||||
"Casa en Venta": house
|
||||
"Departamento en Venta": apartment
|
||||
"Terreno en Venta": land
|
||||
|
||||
precio:
|
||||
selector: "[data-testid='price']"
|
||||
transform: "parse_mexican_currency"
|
||||
|
||||
ubicacion:
|
||||
selector: "[data-testid='location']"
|
||||
transform: "split_city_state"
|
||||
|
||||
caracteristicas:
|
||||
selector: "[data-testid='features'] li"
|
||||
parse: "extract_key_value"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tareas Tecnicas
|
||||
|
||||
| # | Tarea | Estimacion |
|
||||
|---|-------|------------|
|
||||
| 1 | Analizar estructura HTML Vivanuncios | 2h |
|
||||
| 2 | Crear selectores especificos | 2h |
|
||||
| 3 | Implementar mappings de campos | 2h |
|
||||
| 4 | Adaptar navegacion de listados | 2h |
|
||||
| 5 | Tests de integracion | 2h |
|
||||
|
||||
**Total estimado:** 10h (~1.5 dias)
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] Scraper extrae 500+ propiedades sin bloqueos
|
||||
- [ ] Datos se normalizan correctamente
|
||||
- [ ] Tests pasan
|
||||
- [ ] Documentacion actualizada
|
||||
|
||||
---
|
||||
|
||||
**Asignado a:** -
|
||||
**Sprint:** -
|
||||
@ -0,0 +1,135 @@
|
||||
---
|
||||
id: "US-SCR-003"
|
||||
title: "Normalizacion de datos de multiples fuentes"
|
||||
type: "User Story"
|
||||
epic: "IAI-007"
|
||||
status: "Draft"
|
||||
story_points: 8
|
||||
priority: "Alta"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# US-SCR-003: Normalizacion de datos de multiples fuentes
|
||||
|
||||
---
|
||||
|
||||
## User Story
|
||||
|
||||
**Como** sistema de analytics
|
||||
**Quiero** que los datos de diferentes portales se normalicen a un schema unificado
|
||||
**Para** poder realizar analisis consistentes independientemente de la fuente
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
Implementar el pipeline ETL que transforma datos raw de cada portal al schema normalizado, incluyendo limpieza de datos, geocoding, calculo de metricas derivadas y deteccion de duplicados.
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
### Funcionales
|
||||
|
||||
- [ ] Tipos de propiedad se mapean a enum unificado
|
||||
- [ ] Precios se convierten a formato numerico estandar
|
||||
- [ ] Direcciones se geocodifican a lat/lon
|
||||
- [ ] Duplicados cross-source se detectan y fusionan
|
||||
- [ ] Precio por m2 se calcula automaticamente
|
||||
|
||||
### Calidad de Datos
|
||||
|
||||
- [ ] 95%+ de registros tienen geocoding exitoso
|
||||
- [ ] 0% de precios con formato incorrecto
|
||||
- [ ] Duplicados detectados con precision > 98%
|
||||
|
||||
---
|
||||
|
||||
## Transformaciones
|
||||
|
||||
```yaml
|
||||
transformaciones:
|
||||
precio:
|
||||
input: "$3,500,000 MXN" | "3.5 millones"
|
||||
output: 3500000.00
|
||||
pasos:
|
||||
- remove_currency_symbols
|
||||
- expand_abbreviations
|
||||
- to_decimal
|
||||
|
||||
tipo_propiedad:
|
||||
input: "Casa en Venta" | "Casa" | "Residencia"
|
||||
output: "house"
|
||||
pasos:
|
||||
- lowercase
|
||||
- normalize_synonyms
|
||||
- map_to_enum
|
||||
|
||||
ubicacion:
|
||||
input: "Col. Providencia, Guadalajara, Jal."
|
||||
output:
|
||||
neighborhood: "Providencia"
|
||||
city: "Guadalajara"
|
||||
state: "Jalisco"
|
||||
pasos:
|
||||
- parse_address_components
|
||||
- normalize_state_names
|
||||
- geocode_to_coordinates
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Reglas de Deduplicacion
|
||||
|
||||
```yaml
|
||||
deduplicacion:
|
||||
estrategia_primaria:
|
||||
match: source_id + source
|
||||
accion: update
|
||||
|
||||
estrategia_fallback:
|
||||
match:
|
||||
- address_normalized
|
||||
- price +/- 5%
|
||||
- type
|
||||
- size +/- 10%
|
||||
accion: merge
|
||||
|
||||
merge_policy:
|
||||
precio: most_recent
|
||||
descripcion: longest
|
||||
fotos: union
|
||||
first_seen: oldest
|
||||
last_seen: newest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tareas Tecnicas
|
||||
|
||||
| # | Tarea | Estimacion |
|
||||
|---|-------|------------|
|
||||
| 1 | Parser de precios robusto | 3h |
|
||||
| 2 | Normalizador de tipos | 2h |
|
||||
| 3 | Integracion geocoding API | 4h |
|
||||
| 4 | Algoritmo de deduplicacion | 6h |
|
||||
| 5 | Calculo de metricas derivadas | 2h |
|
||||
| 6 | Tests unitarios | 4h |
|
||||
|
||||
**Total estimado:** 21h (~3 dias)
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] Pipeline procesa 1000 propiedades/hora
|
||||
- [ ] Metricas de calidad cumplen objetivos
|
||||
- [ ] Tests de transformacion pasan
|
||||
- [ ] Documentacion de mappings completa
|
||||
|
||||
---
|
||||
|
||||
**Asignado a:** -
|
||||
**Sprint:** -
|
||||
@ -0,0 +1,101 @@
|
||||
---
|
||||
id: "US-SCR-004"
|
||||
title: "Programacion de jobs de actualizacion"
|
||||
type: "User Story"
|
||||
epic: "IAI-007"
|
||||
status: "Draft"
|
||||
story_points: 5
|
||||
priority: "Media"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# US-SCR-004: Programacion de jobs de actualizacion
|
||||
|
||||
---
|
||||
|
||||
## User Story
|
||||
|
||||
**Como** administrador del sistema
|
||||
**Quiero** programar jobs de scraping automaticos
|
||||
**Para** mantener los datos actualizados sin intervencion manual
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
Implementar sistema de scheduling que permita programar full scans semanales, actualizaciones incrementales diarias, y verificacion de propiedades activas periodicamente.
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Jobs se programan con expresiones cron
|
||||
- [ ] Full scan ejecuta semanalmente (domingos 2am)
|
||||
- [ ] Incremental ejecuta diariamente (4am)
|
||||
- [ ] Jobs se pueden ejecutar bajo demanda via API
|
||||
- [ ] Jobs fallidos se reintentan con backoff
|
||||
- [ ] Progreso visible en dashboard
|
||||
|
||||
---
|
||||
|
||||
## Schedules Predefinidos
|
||||
|
||||
```yaml
|
||||
schedules:
|
||||
full_scan_inmuebles24:
|
||||
cron: "0 2 * * 0"
|
||||
tipo: full_scan
|
||||
config:
|
||||
source: inmuebles24
|
||||
max_pages: 100
|
||||
|
||||
full_scan_vivanuncios:
|
||||
cron: "0 3 * * 0"
|
||||
tipo: full_scan
|
||||
config:
|
||||
source: vivanuncios
|
||||
max_pages: 100
|
||||
|
||||
incremental_all:
|
||||
cron: "0 4 * * *"
|
||||
tipo: incremental
|
||||
config:
|
||||
sources: [inmuebles24, vivanuncios]
|
||||
max_pages: 20
|
||||
|
||||
refresh_active:
|
||||
cron: "0 */6 * * *"
|
||||
tipo: refresh
|
||||
config:
|
||||
mark_inactive_after_days: 7
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tareas Tecnicas
|
||||
|
||||
| # | Tarea | Estimacion |
|
||||
|---|-------|------------|
|
||||
| 1 | Configurar Bull Queue | 2h |
|
||||
| 2 | Implementar job types | 4h |
|
||||
| 3 | Scheduler con cron | 3h |
|
||||
| 4 | Retry logic con backoff | 2h |
|
||||
| 5 | API endpoints | 3h |
|
||||
|
||||
**Total estimado:** 14h (~2 dias)
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] Jobs se ejecutan segun schedule
|
||||
- [ ] Reintentos funcionan correctamente
|
||||
- [ ] API permite trigger manual
|
||||
- [ ] Logs detallados disponibles
|
||||
|
||||
---
|
||||
|
||||
**Asignado a:** -
|
||||
**Sprint:** -
|
||||
@ -0,0 +1,110 @@
|
||||
---
|
||||
id: "US-SCR-005"
|
||||
title: "Dashboard de monitoreo de scraping"
|
||||
type: "User Story"
|
||||
epic: "IAI-007"
|
||||
status: "Draft"
|
||||
story_points: 5
|
||||
priority: "Media"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# US-SCR-005: Dashboard de monitoreo de scraping
|
||||
|
||||
---
|
||||
|
||||
## User Story
|
||||
|
||||
**Como** administrador del sistema
|
||||
**Quiero** un dashboard para monitorear el estado del scraping
|
||||
**Para** detectar problemas rapidamente y asegurar calidad de datos
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
Implementar dashboard de monitoreo que muestre metricas en tiempo real, estado de jobs, salud del pool de proxies, y alertas activas.
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Dashboard muestra propiedades scrapeadas hoy/semana
|
||||
- [ ] Muestra success rate por fuente
|
||||
- [ ] Muestra estado de jobs activos
|
||||
- [ ] Muestra salud del pool de proxies
|
||||
- [ ] Alertas visibles cuando hay problemas
|
||||
- [ ] Graficas de tendencia temporal
|
||||
|
||||
---
|
||||
|
||||
## Widgets del Dashboard
|
||||
|
||||
```yaml
|
||||
row_1:
|
||||
- tipo: stat_card
|
||||
titulo: "Propiedades Hoy"
|
||||
valor: count_today
|
||||
|
||||
- tipo: stat_card
|
||||
titulo: "Success Rate"
|
||||
valor: success_rate_24h
|
||||
formato: percentage
|
||||
|
||||
- tipo: stat_card
|
||||
titulo: "Jobs Activos"
|
||||
valor: active_jobs_count
|
||||
|
||||
- tipo: stat_card
|
||||
titulo: "Proxies Activos"
|
||||
valor: active_proxies_count
|
||||
alerta: < 20
|
||||
|
||||
row_2:
|
||||
- tipo: line_chart
|
||||
titulo: "Propiedades por Hora"
|
||||
datos: properties_hourly_7d
|
||||
group_by: source
|
||||
|
||||
- tipo: line_chart
|
||||
titulo: "Success Rate"
|
||||
datos: success_rate_hourly_7d
|
||||
|
||||
row_3:
|
||||
- tipo: table
|
||||
titulo: "Jobs Recientes"
|
||||
columnas: [id, source, status, progress, duration]
|
||||
|
||||
- tipo: pie_chart
|
||||
titulo: "Errores por Tipo"
|
||||
datos: errors_by_type_24h
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tareas Tecnicas
|
||||
|
||||
| # | Tarea | Estimacion |
|
||||
|---|-------|------------|
|
||||
| 1 | Definir metricas Prometheus | 3h |
|
||||
| 2 | Crear dashboard Grafana | 4h |
|
||||
| 3 | Configurar alertas | 2h |
|
||||
| 4 | Integrar en admin panel | 3h |
|
||||
|
||||
**Total estimado:** 12h (~1.5 dias)
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] Dashboard accesible desde admin panel
|
||||
- [ ] Datos se actualizan en tiempo real
|
||||
- [ ] Alertas configuradas y funcionando
|
||||
- [ ] Documentacion de metricas
|
||||
|
||||
---
|
||||
|
||||
**Asignado a:** -
|
||||
**Sprint:** -
|
||||
@ -0,0 +1,39 @@
|
||||
---
|
||||
id: "MAP-IAI-007-US"
|
||||
title: "Mapa Historias Usuario IAI-007"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-007"
|
||||
section: "historias-usuario"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Historias de Usuario - IAI-007 Webscraper
|
||||
|
||||
**EPIC:** IAI-007
|
||||
**Seccion:** Historias de Usuario
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
| ID | Archivo | Titulo | SP | Prioridad | Sprint |
|
||||
|----|---------|--------|----|-----------|--------|
|
||||
| US-SCR-001 | [US-SCR-001.md](./US-SCR-001.md) | Scrapear Inmuebles24 | 13 | Alta | - |
|
||||
| US-SCR-002 | [US-SCR-002.md](./US-SCR-002.md) | Scrapear Vivanuncios | 8 | Alta | - |
|
||||
| US-SCR-003 | [US-SCR-003.md](./US-SCR-003.md) | Normalizar datos | 8 | Alta | - |
|
||||
| US-SCR-004 | [US-SCR-004.md](./US-SCR-004.md) | Programar jobs | 5 | Media | - |
|
||||
| US-SCR-005 | [US-SCR-005.md](./US-SCR-005.md) | Dashboard monitoreo | 5 | Media | - |
|
||||
|
||||
**Total Story Points:** 39
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-007-webscraper/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,34 @@
|
||||
---
|
||||
id: "MAP-IAI-007-IMPL"
|
||||
title: "Mapa Implementacion IAI-007"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-007"
|
||||
section: "implementacion"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Implementacion - IAI-007 Webscraper
|
||||
|
||||
**EPIC:** IAI-007
|
||||
**Seccion:** Implementacion y Trazabilidad
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
| Archivo | Proposito | Estado |
|
||||
|---------|-----------|--------|
|
||||
| CHANGELOG.md | Historial de cambios | Pendiente |
|
||||
| TRACEABILITY.yml | Trazabilidad RF-US-ET | Pendiente |
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-007-webscraper/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,105 @@
|
||||
---
|
||||
id: "RF-SCR-001"
|
||||
title: "Motor de Scraping con Anti-Detection"
|
||||
type: "Functional Requirement"
|
||||
epic: "IAI-007"
|
||||
priority: "Alta"
|
||||
status: "Draft"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# RF-IA-007-001: Motor de Scraping con Anti-Detection
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
El sistema debe proporcionar un motor de web scraping capaz de extraer datos de portales inmobiliarios protegidos por Cloudflare y otros sistemas anti-bot, emulando comportamiento de usuario real para evitar bloqueos.
|
||||
|
||||
---
|
||||
|
||||
## Justificacion
|
||||
|
||||
Los portales inmobiliarios como Inmuebles24 y Vivanuncios implementan protecciones robustas contra scraping automatizado. Sin un motor especializado con capacidades anti-detection, el sistema no podra obtener datos actualizados del mercado.
|
||||
|
||||
---
|
||||
|
||||
## Requisitos Funcionales
|
||||
|
||||
### RF-001.1: Browser Automation
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-001.1.1 | El sistema debe usar Playwright como motor de automatizacion principal | Alta |
|
||||
| RF-001.1.2 | El sistema debe soportar modo headless con stealth patches | Alta |
|
||||
| RF-001.1.3 | El sistema debe ocultar propiedades de WebDriver (navigator.webdriver) | Alta |
|
||||
| RF-001.1.4 | El sistema debe emular User-Agents reales y rotarlos | Alta |
|
||||
| RF-001.1.5 | El sistema debe soportar HTTP/2 y TLS moderno | Media |
|
||||
|
||||
### RF-001.2: Anti-Detection
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-001.2.1 | El sistema debe simular movimientos de mouse antes de clicks | Alta |
|
||||
| RF-001.2.2 | El sistema debe implementar scroll gradual (no instantaneo) | Alta |
|
||||
| RF-001.2.3 | El sistema debe agregar delays aleatorios entre acciones | Alta |
|
||||
| RF-001.2.4 | El sistema debe esperar carga completa de JavaScript antes de extraer | Alta |
|
||||
| RF-001.2.5 | El sistema debe detectar y manejar desafios Cloudflare Turnstile | Media |
|
||||
|
||||
### RF-001.3: Session Management
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-001.3.1 | El sistema debe persistir cookies entre sesiones | Alta |
|
||||
| RF-001.3.2 | El sistema debe rotar sesiones periodicamente | Media |
|
||||
| RF-001.3.3 | El sistema debe implementar "warming up" de sesiones nuevas | Media |
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Playwright se inicializa con stealth mode habilitado
|
||||
- [ ] navigator.webdriver retorna undefined en el browser automatizado
|
||||
- [ ] User-Agent rota entre 10+ agentes reales diferentes
|
||||
- [ ] Delays entre acciones varian entre 1-5 segundos aleatoriamente
|
||||
- [ ] Scroll simula comportamiento humano (velocidad variable)
|
||||
- [ ] Sesiones se persisten y reusan correctamente
|
||||
- [ ] El scraper pasa pruebas de bot detection (bot.sannysoft.com)
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
- Playwright NPM package
|
||||
- playwright-extra con stealth plugin
|
||||
- Redis para session storage
|
||||
|
||||
---
|
||||
|
||||
## Riesgos
|
||||
|
||||
| Riesgo | Probabilidad | Impacto | Mitigacion |
|
||||
|--------|--------------|---------|------------|
|
||||
| Stealth patches obsoletos | Media | Alto | Monitorear actualizaciones, tener fallbacks |
|
||||
| Nuevas tecnicas de deteccion | Alta | Alto | Monitoreo continuo, ajustes rapidos |
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario Relacionadas
|
||||
|
||||
- US-SCR-001: Scraping de Inmuebles24
|
||||
|
||||
---
|
||||
|
||||
## Referencias Tecnicas
|
||||
|
||||
- [playwright-extra-stealth](https://github.com/nickarsenault/playwright-extra-stealth)
|
||||
- [Nodriver](https://github.com/nickarsenault/nodriver)
|
||||
- [ScrapFly Cloudflare Guide](https://scrapfly.io/blog/how-to-bypass-cloudflare-protection/)
|
||||
|
||||
---
|
||||
|
||||
**Autor:** Tech Lead
|
||||
**Fecha:** 2026-01-04
|
||||
@ -0,0 +1,158 @@
|
||||
---
|
||||
id: "RF-SCR-002"
|
||||
title: "Gestion de Pool de Proxies"
|
||||
type: "Functional Requirement"
|
||||
epic: "IAI-007"
|
||||
priority: "Alta"
|
||||
status: "Draft"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# RF-IA-007-002: Gestion de Pool de Proxies
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
El sistema debe gestionar un pool de proxies residenciales para distribuir las solicitudes y evitar bloqueos por IP, incluyendo rotacion automatica, health checks y cooling periods.
|
||||
|
||||
---
|
||||
|
||||
## Justificacion
|
||||
|
||||
Cloudflare y los portales inmobiliarios rastrean IPs y bloquean aquellas con comportamiento sospechoso. Un pool de proxies residenciales permite distribuir la carga y simular trafico desde multiples ubicaciones geograficas legitimas.
|
||||
|
||||
---
|
||||
|
||||
## Requisitos Funcionales
|
||||
|
||||
### RF-002.1: Gestion de Pool
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-002.1.1 | El sistema debe mantener un pool de proxies residenciales | Alta |
|
||||
| RF-002.1.2 | El sistema debe almacenar metadata de cada proxy (tipo, pais, status) | Alta |
|
||||
| RF-002.1.3 | El sistema debe soportar multiples proveedores de proxy | Media |
|
||||
| RF-002.1.4 | El sistema debe permitir agregar/remover proxies dinamicamente | Media |
|
||||
|
||||
### RF-002.2: Rotacion
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-002.2.1 | El sistema debe rotar proxies por sesion o por request | Alta |
|
||||
| RF-002.2.2 | El sistema debe seleccionar proxies con mejor success rate | Alta |
|
||||
| RF-002.2.3 | El sistema debe evitar proxies en cooling period | Alta |
|
||||
| RF-002.2.4 | El sistema debe balancear carga entre proxies disponibles | Media |
|
||||
|
||||
### RF-002.3: Health Checks
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-002.3.1 | El sistema debe verificar conectividad de proxies periodicamente | Alta |
|
||||
| RF-002.3.2 | El sistema debe marcar proxies como "banned" cuando detecte bloqueo | Alta |
|
||||
| RF-002.3.3 | El sistema debe calcular y actualizar success rate por proxy | Alta |
|
||||
| RF-002.3.4 | El sistema debe alertar cuando el pool este bajo umbral minimo | Media |
|
||||
|
||||
### RF-002.4: Cooling Periods
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-002.4.1 | El sistema debe poner proxies en cooling despues de rate limit | Alta |
|
||||
| RF-002.4.2 | El sistema debe configurar duracion de cooling por tipo de error | Media |
|
||||
| RF-002.4.3 | El sistema debe reactivar proxies automaticamente post-cooling | Alta |
|
||||
|
||||
---
|
||||
|
||||
## Modelo de Datos
|
||||
|
||||
```yaml
|
||||
ProxyPool:
|
||||
id: UUID
|
||||
address: string
|
||||
port: number
|
||||
type: enum [residential, datacenter, mobile]
|
||||
provider: string
|
||||
country: string
|
||||
city: string (opcional)
|
||||
username: string (encrypted)
|
||||
password: string (encrypted)
|
||||
status: enum [active, cooling, banned, inactive]
|
||||
success_rate: decimal (0-1)
|
||||
total_requests: integer
|
||||
successful_requests: integer
|
||||
last_used_at: timestamp
|
||||
last_success_at: timestamp
|
||||
cooling_until: timestamp (nullable)
|
||||
banned_at: timestamp (nullable)
|
||||
created_at: timestamp
|
||||
updated_at: timestamp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Pool almacena y gestiona 50+ proxies residenciales
|
||||
- [ ] Rotacion selecciona proxies con mejor success rate
|
||||
- [ ] Proxies con rate limit entran en cooling automaticamente
|
||||
- [ ] Health check detecta proxies caidos en < 5 minutos
|
||||
- [ ] Alertas se disparan cuando pool < 20 proxies activos
|
||||
- [ ] Success rate se calcula correctamente por proxy
|
||||
- [ ] Proxies banned no se seleccionan para nuevos requests
|
||||
|
||||
---
|
||||
|
||||
## Configuracion
|
||||
|
||||
```yaml
|
||||
proxy_pool:
|
||||
min_active_proxies: 20
|
||||
health_check_interval_ms: 300000 # 5 minutos
|
||||
|
||||
rotation:
|
||||
strategy: "weighted_random" # best_success, round_robin, weighted_random
|
||||
change_every: "session" # request, session, n_requests
|
||||
|
||||
cooling:
|
||||
rate_limit_duration_ms: 3600000 # 1 hora
|
||||
error_duration_ms: 1800000 # 30 minutos
|
||||
max_consecutive_failures: 3
|
||||
|
||||
providers:
|
||||
- name: "brightdata"
|
||||
priority: 1
|
||||
- name: "iproyal"
|
||||
priority: 2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
- Proveedor de proxies residenciales (Bright Data, IPRoyal, etc.)
|
||||
- PostgreSQL para persistencia
|
||||
- Redis para cache de status
|
||||
|
||||
---
|
||||
|
||||
## Costos Estimados
|
||||
|
||||
| Proveedor | Plan | Proxies | Costo/mes |
|
||||
|-----------|------|---------|-----------|
|
||||
| Bright Data | Residential | 5GB | $75 USD |
|
||||
| IPRoyal | Residential | 5GB | $52 USD |
|
||||
| Smartproxy | Residential | 5GB | $65 USD |
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario Relacionadas
|
||||
|
||||
- US-SCR-001: Scraping de Inmuebles24
|
||||
- US-SCR-002: Scraping de Vivanuncios
|
||||
|
||||
---
|
||||
|
||||
**Autor:** Tech Lead
|
||||
**Fecha:** 2026-01-04
|
||||
@ -0,0 +1,214 @@
|
||||
---
|
||||
id: "RF-SCR-003"
|
||||
title: "Pipeline ETL y Normalizacion"
|
||||
type: "Functional Requirement"
|
||||
epic: "IAI-007"
|
||||
priority: "Alta"
|
||||
status: "Draft"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# RF-IA-007-003: Pipeline ETL y Normalizacion
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
El sistema debe procesar los datos raw extraidos de multiples fuentes, normalizarlos a un schema unificado, enriquecerlos con geocoding y cargarlos en la base de datos de propiedades.
|
||||
|
||||
---
|
||||
|
||||
## Justificacion
|
||||
|
||||
Cada portal inmobiliario tiene su propia estructura de datos y nomenclatura. Para poder realizar analytics consistentes, los datos deben normalizarse a un schema comun con campos estandarizados.
|
||||
|
||||
---
|
||||
|
||||
## Requisitos Funcionales
|
||||
|
||||
### RF-003.1: Extraccion
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-003.1.1 | El sistema debe parsear HTML a JSON estructurado | Alta |
|
||||
| RF-003.1.2 | El sistema debe extraer todos los campos definidos en el schema | Alta |
|
||||
| RF-003.1.3 | El sistema debe manejar variaciones en estructura HTML | Alta |
|
||||
| RF-003.1.4 | El sistema debe almacenar raw data en storage persistente | Media |
|
||||
|
||||
### RF-003.2: Transformacion
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-003.2.1 | El sistema debe normalizar tipos de propiedad a enum unificado | Alta |
|
||||
| RF-003.2.2 | El sistema debe convertir precios a formato numerico estandar | Alta |
|
||||
| RF-003.2.3 | El sistema debe normalizar unidades de superficie (m2) | Alta |
|
||||
| RF-003.2.4 | El sistema debe extraer caracteristicas de texto libre | Media |
|
||||
| RF-003.2.5 | El sistema debe limpiar y estandarizar direcciones | Alta |
|
||||
|
||||
### RF-003.3: Enriquecimiento
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-003.3.1 | El sistema debe geocodificar direcciones a lat/lon | Alta |
|
||||
| RF-003.3.2 | El sistema debe calcular precio por m2 | Alta |
|
||||
| RF-003.3.3 | El sistema debe asignar zona/colonia normalizada | Alta |
|
||||
| RF-003.3.4 | El sistema debe detectar duplicados cross-source | Media |
|
||||
|
||||
### RF-003.4: Carga
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-003.4.1 | El sistema debe hacer upsert en tabla de propiedades | Alta |
|
||||
| RF-003.4.2 | El sistema debe mantener historial de cambios de precio | Alta |
|
||||
| RF-003.4.3 | El sistema debe marcar propiedades inactivas | Alta |
|
||||
| RF-003.4.4 | El sistema debe emitir eventos de nuevas propiedades | Media |
|
||||
|
||||
---
|
||||
|
||||
## Schema Normalizado
|
||||
|
||||
```yaml
|
||||
Property:
|
||||
# Identificacion
|
||||
id: UUID
|
||||
source: string # inmuebles24, vivanuncios, etc
|
||||
source_id: string # ID original del portal
|
||||
source_url: string
|
||||
|
||||
# Tipo
|
||||
property_type: enum
|
||||
- house
|
||||
- apartment
|
||||
- land
|
||||
- commercial
|
||||
- office
|
||||
- warehouse
|
||||
transaction_type: enum [sale, rent]
|
||||
|
||||
# Ubicacion
|
||||
address: string
|
||||
neighborhood: string
|
||||
city: string
|
||||
state: string
|
||||
postal_code: string
|
||||
latitude: decimal
|
||||
longitude: decimal
|
||||
zone_id: UUID (FK)
|
||||
|
||||
# Caracteristicas
|
||||
bedrooms: integer
|
||||
bathrooms: decimal
|
||||
parking_spaces: integer
|
||||
construction_m2: decimal
|
||||
land_m2: decimal
|
||||
age_years: integer
|
||||
floors: integer
|
||||
|
||||
# Precio
|
||||
price: decimal
|
||||
currency: string # MXN, USD
|
||||
price_per_m2: decimal (calculado)
|
||||
|
||||
# Descripcion
|
||||
title: string
|
||||
description: text
|
||||
amenities: string[]
|
||||
images: string[]
|
||||
|
||||
# Metadata
|
||||
is_active: boolean
|
||||
first_seen_at: timestamp
|
||||
last_seen_at: timestamp
|
||||
price_history: JSONB
|
||||
created_at: timestamp
|
||||
updated_at: timestamp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mappings por Fuente
|
||||
|
||||
### Inmuebles24
|
||||
|
||||
```yaml
|
||||
mappings:
|
||||
property_type:
|
||||
"Casa": house
|
||||
"Departamento": apartment
|
||||
"Terreno": land
|
||||
"Local comercial": commercial
|
||||
"Oficina": office
|
||||
"Bodega": warehouse
|
||||
|
||||
transaction_type:
|
||||
"Venta": sale
|
||||
"Renta": rent
|
||||
"Venta o Renta": sale # priorizar venta
|
||||
|
||||
precio:
|
||||
selector: ".price-value"
|
||||
transform: "remove_currency_symbols | to_number"
|
||||
|
||||
superficie:
|
||||
selector: ".surface-value"
|
||||
transform: "extract_number | assume_m2"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Reglas de Validacion
|
||||
|
||||
```yaml
|
||||
validations:
|
||||
precio:
|
||||
min: 10000 # MXN
|
||||
max: 500000000
|
||||
required: true
|
||||
|
||||
superficie:
|
||||
min: 10 # m2
|
||||
max: 100000
|
||||
required: false
|
||||
|
||||
coordenadas:
|
||||
latitude_range: [14.5, 32.7] # Mexico
|
||||
longitude_range: [-118.5, -86.7]
|
||||
|
||||
deduplicacion:
|
||||
strategy: "source_id + source"
|
||||
fallback: "address_normalized + price + type"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Pipeline procesa 1000 propiedades/hora minimo
|
||||
- [ ] Todos los campos requeridos se mapean correctamente
|
||||
- [ ] Precios se convierten a formato numerico sin errores
|
||||
- [ ] Geocoding tiene 95%+ success rate
|
||||
- [ ] Duplicados se detectan con 98%+ precision
|
||||
- [ ] Historial de precios se mantiene correctamente
|
||||
- [ ] Raw data se almacena para debugging
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
- Cheerio o similar para parsing HTML
|
||||
- Google Maps API para geocoding
|
||||
- PostgreSQL para persistencia
|
||||
- S3/MinIO para raw data storage
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario Relacionadas
|
||||
|
||||
- US-SCR-003: Normalizacion de datos
|
||||
|
||||
---
|
||||
|
||||
**Autor:** Tech Lead
|
||||
**Fecha:** 2026-01-04
|
||||
@ -0,0 +1,220 @@
|
||||
---
|
||||
id: "RF-SCR-004"
|
||||
title: "Scheduling y Job Management"
|
||||
type: "Functional Requirement"
|
||||
epic: "IAI-007"
|
||||
priority: "Media"
|
||||
status: "Draft"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# RF-IA-007-004: Scheduling y Job Management
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
El sistema debe programar y gestionar trabajos de scraping, permitiendo ejecuciones programadas, incrementales y bajo demanda, con capacidad de pausar, reanudar y monitorear el progreso.
|
||||
|
||||
---
|
||||
|
||||
## Justificacion
|
||||
|
||||
La recoleccion de datos debe ser automatizada y eficiente. Los trabajos programados permiten mantener datos actualizados, mientras que las sincronizaciones incrementales optimizan recursos al procesar solo cambios.
|
||||
|
||||
---
|
||||
|
||||
## Requisitos Funcionales
|
||||
|
||||
### RF-004.1: Tipos de Jobs
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-004.1.1 | El sistema debe soportar jobs de tipo "full_scan" | Alta |
|
||||
| RF-004.1.2 | El sistema debe soportar jobs de tipo "incremental" | Alta |
|
||||
| RF-004.1.3 | El sistema debe soportar jobs de tipo "targeted" (URLs especificas) | Media |
|
||||
| RF-004.1.4 | El sistema debe soportar jobs de tipo "refresh" (verificar activas) | Media |
|
||||
|
||||
### RF-004.2: Scheduling
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-004.2.1 | El sistema debe permitir programar jobs con expresiones cron | Alta |
|
||||
| RF-004.2.2 | El sistema debe ejecutar jobs bajo demanda via API | Alta |
|
||||
| RF-004.2.3 | El sistema debe respetar horarios de baja demanda | Media |
|
||||
| RF-004.2.4 | El sistema debe distribuir carga entre workers | Media |
|
||||
|
||||
### RF-004.3: Job Lifecycle
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-004.3.1 | El sistema debe permitir pausar jobs en ejecucion | Alta |
|
||||
| RF-004.3.2 | El sistema debe permitir reanudar jobs pausados | Alta |
|
||||
| RF-004.3.3 | El sistema debe cancelar jobs con cleanup apropiado | Alta |
|
||||
| RF-004.3.4 | El sistema debe reintentar jobs fallidos con backoff | Alta |
|
||||
|
||||
### RF-004.4: Monitoreo
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-004.4.1 | El sistema debe reportar progreso en tiempo real | Alta |
|
||||
| RF-004.4.2 | El sistema debe registrar estadisticas por job | Alta |
|
||||
| RF-004.4.3 | El sistema debe alertar en caso de fallas | Alta |
|
||||
| RF-004.4.4 | El sistema debe mantener historial de ejecuciones | Media |
|
||||
|
||||
---
|
||||
|
||||
## Modelo de Datos
|
||||
|
||||
```yaml
|
||||
ScrapingJob:
|
||||
id: UUID
|
||||
type: enum [full_scan, incremental, targeted, refresh]
|
||||
source: string # inmuebles24, vivanuncios, all
|
||||
status: enum [pending, queued, running, paused, completed, failed, cancelled]
|
||||
|
||||
config:
|
||||
target_cities: string[]
|
||||
property_types: string[]
|
||||
max_pages: integer
|
||||
max_properties: integer
|
||||
delay_ms:
|
||||
min: integer
|
||||
max: integer
|
||||
|
||||
schedule:
|
||||
cron_expression: string (nullable)
|
||||
next_run_at: timestamp (nullable)
|
||||
timezone: string
|
||||
|
||||
progress:
|
||||
pages_scraped: integer
|
||||
properties_found: integer
|
||||
properties_processed: integer
|
||||
errors: integer
|
||||
current_page: string
|
||||
|
||||
stats:
|
||||
started_at: timestamp
|
||||
completed_at: timestamp
|
||||
duration_ms: integer
|
||||
success_rate: decimal
|
||||
|
||||
retry:
|
||||
attempts: integer
|
||||
max_attempts: integer
|
||||
last_error: string
|
||||
|
||||
created_at: timestamp
|
||||
updated_at: timestamp
|
||||
created_by: UUID
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuracion de Schedules
|
||||
|
||||
```yaml
|
||||
schedules:
|
||||
full_scan:
|
||||
inmuebles24:
|
||||
cron: "0 2 * * 0" # Domingos 2am
|
||||
config:
|
||||
max_pages: 100
|
||||
cities: [guadalajara, monterrey, cdmx]
|
||||
|
||||
vivanuncios:
|
||||
cron: "0 3 * * 0" # Domingos 3am
|
||||
config:
|
||||
max_pages: 100
|
||||
|
||||
incremental:
|
||||
all_sources:
|
||||
cron: "0 4 * * *" # Diario 4am
|
||||
config:
|
||||
max_pages: 20
|
||||
only_new: true
|
||||
|
||||
refresh:
|
||||
active_properties:
|
||||
cron: "0 */6 * * *" # Cada 6 horas
|
||||
config:
|
||||
check_active: true
|
||||
mark_inactive_after_days: 7
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints
|
||||
|
||||
```yaml
|
||||
POST /api/v1/scraper/jobs:
|
||||
description: Crear nuevo job
|
||||
body:
|
||||
type: string
|
||||
source: string
|
||||
config: object
|
||||
response: 201 Created
|
||||
|
||||
GET /api/v1/scraper/jobs:
|
||||
description: Listar jobs
|
||||
query:
|
||||
status: string
|
||||
source: string
|
||||
limit: integer
|
||||
offset: integer
|
||||
response: 200 OK (paginado)
|
||||
|
||||
GET /api/v1/scraper/jobs/:id:
|
||||
description: Obtener job con progreso
|
||||
response: 200 OK
|
||||
|
||||
POST /api/v1/scraper/jobs/:id/pause:
|
||||
description: Pausar job
|
||||
response: 200 OK
|
||||
|
||||
POST /api/v1/scraper/jobs/:id/resume:
|
||||
description: Reanudar job
|
||||
response: 200 OK
|
||||
|
||||
DELETE /api/v1/scraper/jobs/:id:
|
||||
description: Cancelar job
|
||||
response: 204 No Content
|
||||
|
||||
GET /api/v1/scraper/stats:
|
||||
description: Estadisticas globales
|
||||
response: 200 OK
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Jobs se programan correctamente con cron expressions
|
||||
- [ ] Jobs se pueden ejecutar bajo demanda via API
|
||||
- [ ] Pausar/reanudar funciona sin perder progreso
|
||||
- [ ] Reintentos usan exponential backoff
|
||||
- [ ] Progreso se actualiza en tiempo real
|
||||
- [ ] Estadisticas se calculan correctamente
|
||||
- [ ] Alertas se envian en caso de fallas
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
- Bull Queue (Redis)
|
||||
- node-cron o similar
|
||||
- Redis para estado de jobs
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario Relacionadas
|
||||
|
||||
- US-SCR-004: Programacion de jobs
|
||||
|
||||
---
|
||||
|
||||
**Autor:** Tech Lead
|
||||
**Fecha:** 2026-01-04
|
||||
@ -0,0 +1,227 @@
|
||||
---
|
||||
id: "RF-SCR-005"
|
||||
title: "Monitoreo y Alertas"
|
||||
type: "Functional Requirement"
|
||||
epic: "IAI-007"
|
||||
priority: "Media"
|
||||
status: "Draft"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# RF-IA-007-005: Monitoreo y Alertas
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
El sistema debe proporcionar monitoreo en tiempo real del estado del scraping, metricas de rendimiento, deteccion de anomalias y alertas automaticas cuando se detecten problemas.
|
||||
|
||||
---
|
||||
|
||||
## Justificacion
|
||||
|
||||
El scraping es un proceso fragil que puede fallar por multiples razones (cambios en HTML, bloqueos, errores de red). El monitoreo proactivo permite detectar y resolver problemas rapidamente antes de que afecten la calidad de datos.
|
||||
|
||||
---
|
||||
|
||||
## Requisitos Funcionales
|
||||
|
||||
### RF-005.1: Metricas
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-005.1.1 | El sistema debe registrar propiedades scrapeadas por fuente/hora | Alta |
|
||||
| RF-005.1.2 | El sistema debe calcular success rate por fuente/proxy | Alta |
|
||||
| RF-005.1.3 | El sistema debe medir latencia promedio por request | Alta |
|
||||
| RF-005.1.4 | El sistema debe contar errores por tipo y fuente | Alta |
|
||||
| RF-005.1.5 | El sistema debe trackear estado del pool de proxies | Alta |
|
||||
|
||||
### RF-005.2: Dashboard
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-005.2.1 | El sistema debe mostrar estado actual de jobs | Alta |
|
||||
| RF-005.2.2 | El sistema debe visualizar metricas en tiempo real | Alta |
|
||||
| RF-005.2.3 | El sistema debe mostrar historial de ejecuciones | Media |
|
||||
| RF-005.2.4 | El sistema debe permitir drill-down por fuente/job | Media |
|
||||
|
||||
### RF-005.3: Alertas
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-005.3.1 | El sistema debe alertar cuando success rate < 80% | Alta |
|
||||
| RF-005.3.2 | El sistema debe alertar cuando un job falla | Alta |
|
||||
| RF-005.3.3 | El sistema debe alertar cuando pool de proxies < umbral | Alta |
|
||||
| RF-005.3.4 | El sistema debe alertar cuando detecte cambio en estructura HTML | Media |
|
||||
| RF-005.3.5 | El sistema debe soportar canales: email, Slack, webhook | Media |
|
||||
|
||||
### RF-005.4: Logs
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-005.4.1 | El sistema debe registrar logs estructurados (JSON) | Alta |
|
||||
| RF-005.4.2 | El sistema debe incluir correlation IDs por job | Alta |
|
||||
| RF-005.4.3 | El sistema debe permitir ajustar nivel de log | Media |
|
||||
| RF-005.4.4 | El sistema debe retener logs por 30 dias minimo | Media |
|
||||
|
||||
---
|
||||
|
||||
## Metricas Definidas
|
||||
|
||||
```yaml
|
||||
metricas:
|
||||
counters:
|
||||
- scraper_properties_total:
|
||||
labels: [source, type, status]
|
||||
description: "Total propiedades procesadas"
|
||||
|
||||
- scraper_requests_total:
|
||||
labels: [source, status_code]
|
||||
description: "Total requests HTTP"
|
||||
|
||||
- scraper_errors_total:
|
||||
labels: [source, error_type]
|
||||
description: "Total errores por tipo"
|
||||
|
||||
gauges:
|
||||
- scraper_active_jobs:
|
||||
labels: [source]
|
||||
description: "Jobs activos actualmente"
|
||||
|
||||
- scraper_proxy_pool_size:
|
||||
labels: [status]
|
||||
description: "Proxies por estado"
|
||||
|
||||
- scraper_queue_size:
|
||||
description: "Tareas pendientes en cola"
|
||||
|
||||
histograms:
|
||||
- scraper_request_duration_seconds:
|
||||
labels: [source]
|
||||
buckets: [0.1, 0.5, 1, 2, 5, 10]
|
||||
description: "Duracion de requests"
|
||||
|
||||
- scraper_job_duration_seconds:
|
||||
labels: [source, type]
|
||||
description: "Duracion total de jobs"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuracion de Alertas
|
||||
|
||||
```yaml
|
||||
alerts:
|
||||
success_rate_low:
|
||||
condition: "scraper_success_rate < 0.8"
|
||||
duration: "5m"
|
||||
severity: warning
|
||||
channels: [slack, email]
|
||||
message: "Success rate bajo en {source}: {value}%"
|
||||
|
||||
job_failed:
|
||||
condition: "scraper_job_status == 'failed'"
|
||||
severity: critical
|
||||
channels: [slack, email, pagerduty]
|
||||
message: "Job fallido: {job_id} en {source}"
|
||||
|
||||
proxy_pool_low:
|
||||
condition: "scraper_proxy_pool_size{status='active'} < 20"
|
||||
duration: "10m"
|
||||
severity: warning
|
||||
channels: [slack]
|
||||
message: "Pool de proxies bajo: {value} activos"
|
||||
|
||||
no_data:
|
||||
condition: "scraper_properties_total == 0"
|
||||
duration: "1h"
|
||||
severity: critical
|
||||
channels: [slack, email]
|
||||
message: "Sin propiedades scrapeadas en la ultima hora"
|
||||
|
||||
html_change_detected:
|
||||
condition: "scraper_selector_failures > 10"
|
||||
duration: "15m"
|
||||
severity: warning
|
||||
channels: [slack]
|
||||
message: "Posible cambio en estructura HTML de {source}"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dashboard Widgets
|
||||
|
||||
```yaml
|
||||
dashboard:
|
||||
row_1:
|
||||
- widget: "stat"
|
||||
title: "Propiedades Hoy"
|
||||
metric: "sum(scraper_properties_total{status='success'})"
|
||||
|
||||
- widget: "stat"
|
||||
title: "Success Rate"
|
||||
metric: "scraper_success_rate * 100"
|
||||
format: "percent"
|
||||
|
||||
- widget: "stat"
|
||||
title: "Jobs Activos"
|
||||
metric: "scraper_active_jobs"
|
||||
|
||||
- widget: "stat"
|
||||
title: "Proxies Activos"
|
||||
metric: "scraper_proxy_pool_size{status='active'}"
|
||||
|
||||
row_2:
|
||||
- widget: "timeseries"
|
||||
title: "Propiedades por Hora"
|
||||
metric: "rate(scraper_properties_total[1h])"
|
||||
group_by: source
|
||||
|
||||
- widget: "timeseries"
|
||||
title: "Success Rate"
|
||||
metric: "scraper_success_rate"
|
||||
group_by: source
|
||||
|
||||
row_3:
|
||||
- widget: "table"
|
||||
title: "Jobs Recientes"
|
||||
query: "SELECT * FROM scraping_jobs ORDER BY created_at DESC LIMIT 10"
|
||||
|
||||
- widget: "piechart"
|
||||
title: "Errores por Tipo"
|
||||
metric: "scraper_errors_total"
|
||||
group_by: error_type
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Metricas se registran correctamente en Prometheus/similar
|
||||
- [ ] Dashboard muestra datos en tiempo real
|
||||
- [ ] Alertas se disparan dentro de la duracion configurada
|
||||
- [ ] Notificaciones llegan a los canales configurados
|
||||
- [ ] Logs son estructurados y contienen correlation IDs
|
||||
- [ ] Historial de metricas disponible por 30+ dias
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
- Prometheus o similar para metricas
|
||||
- Grafana o similar para dashboard
|
||||
- AlertManager o similar para alertas
|
||||
- ELK Stack o similar para logs
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario Relacionadas
|
||||
|
||||
- US-SCR-005: Dashboard de monitoreo
|
||||
|
||||
---
|
||||
|
||||
**Autor:** Tech Lead
|
||||
**Fecha:** 2026-01-04
|
||||
@ -0,0 +1,37 @@
|
||||
---
|
||||
id: "MAP-IAI-007-RF"
|
||||
title: "Mapa Requerimientos IAI-007"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-007"
|
||||
section: "requerimientos"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Requerimientos - IAI-007 Webscraper
|
||||
|
||||
**EPIC:** IAI-007
|
||||
**Seccion:** Requerimientos Funcionales
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
| ID | Archivo | Titulo | Prioridad | Estado |
|
||||
|----|---------|--------|-----------|--------|
|
||||
| RF-SCR-001 | [RF-SCR-001.md](./RF-SCR-001.md) | Motor de scraping con anti-detection | Alta | Draft |
|
||||
| RF-SCR-002 | [RF-SCR-002.md](./RF-SCR-002.md) | Gestion de pool de proxies | Alta | Draft |
|
||||
| RF-SCR-003 | [RF-SCR-003.md](./RF-SCR-003.md) | Pipeline ETL y normalizacion | Alta | Draft |
|
||||
| RF-SCR-004 | [RF-SCR-004.md](./RF-SCR-004.md) | Scheduling y job management | Media | Draft |
|
||||
| RF-SCR-005 | [RF-SCR-005.md](./RF-SCR-005.md) | Monitoreo y alertas | Media | Draft |
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-007-webscraper/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-007-TASK"
|
||||
title: "Mapa Tareas IAI-007"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-007"
|
||||
section: "tareas"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Tareas Tecnicas - IAI-007 Webscraper
|
||||
|
||||
**EPIC:** IAI-007
|
||||
**Seccion:** Tareas Tecnicas
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Sin tareas tecnicas definidas todavia.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-007-webscraper/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
245
docs/01-fase-alcance-inicial/IAI-008-ml-analytics/README.md
Normal file
245
docs/01-fase-alcance-inicial/IAI-008-ml-analytics/README.md
Normal file
@ -0,0 +1,245 @@
|
||||
---
|
||||
id: "EPIC-IAI-008"
|
||||
title: "EPIC IA-008: Machine Learning y Analytics Avanzado"
|
||||
type: "EPIC"
|
||||
status: "Draft"
|
||||
project: "inmobiliaria-analytics"
|
||||
version: "1.0.0"
|
||||
story_points: 89
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# EPIC IAI-008: Machine Learning y Analytics Avanzado
|
||||
|
||||
---
|
||||
|
||||
## Resumen Ejecutivo
|
||||
|
||||
Este EPIC implementa el nucleo de inteligencia artificial de la plataforma: modelos de valuacion automatica (AVM), prediccion de tendencias de mercado, deteccion de oportunidades de inversion, indices de mercado y generacion de reportes profesionales con insights accionables.
|
||||
|
||||
---
|
||||
|
||||
## Objetivo
|
||||
|
||||
Proporcionar capacidades de ML que transformen datos inmobiliarios en inteligencia de mercado accionable:
|
||||
|
||||
1. **Valuacion Automatica (AVM)** - Estimar valor de propiedades con MAPE < 10%
|
||||
2. **Predicciones** - Tiempo de venta, demanda por zona, tendencias
|
||||
3. **Oportunidades** - Detectar propiedades subvaluadas y zonas emergentes
|
||||
4. **Analisis ROI** - Calcular retornos proyectados para inversores
|
||||
5. **Reportes** - Generar reportes profesionales personalizados
|
||||
|
||||
---
|
||||
|
||||
## Propuesta de Valor por Segmento
|
||||
|
||||
### Para Agentes Inmobiliarios
|
||||
|
||||
- Valuaciones instantaneas para clientes
|
||||
- Reportes CMA profesionales automatizados
|
||||
- Prediccion de tiempo de venta
|
||||
- Market snapshots semanales
|
||||
|
||||
### Para Inversores
|
||||
|
||||
- Deteccion de propiedades subvaluadas
|
||||
- Analisis ROI con escenarios
|
||||
- Identificacion de zonas emergentes
|
||||
- Alertas de oportunidades
|
||||
|
||||
### Para Desarrolladores
|
||||
|
||||
- Estudios de factibilidad automatizados
|
||||
- Analisis de demanda por zona
|
||||
- Benchmarking de costos
|
||||
- Proyecciones de absorcion
|
||||
|
||||
---
|
||||
|
||||
## Modelos ML Core
|
||||
|
||||
```
|
||||
+-------------------+ +-------------------+ +-------------------+
|
||||
| AVM-Core | | DOM-Predictor | | Demand-Forecaster |
|
||||
| (Valuacion) | | (Tiempo Venta) | | (Demanda Zona) |
|
||||
+-------------------+ +-------------------+ +-------------------+
|
||||
| | |
|
||||
v v v
|
||||
+---------------------------------------------------------------+
|
||||
| Feature Engineering |
|
||||
| (Geo, Mercado, Propiedad, Temporales, NLP Embeddings) |
|
||||
+---------------------------------------------------------------+
|
||||
| | |
|
||||
v v v
|
||||
+-------------------+ +-------------------+ +-------------------+
|
||||
| Deal-Finder | | Zone-Spotter | | ROI-Analyzer |
|
||||
| (Subvaluadas) | |(Zonas Emergentes) | | (Inversion) |
|
||||
+-------------------+ +-------------------+ +-------------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Stack Tecnologico
|
||||
|
||||
| Capa | Tecnologia | Uso |
|
||||
|------|------------|-----|
|
||||
| ML Framework | XGBoost, LightGBM, Prophet | Modelos predictivos |
|
||||
| Data | pandas, polars, geopandas | Procesamiento |
|
||||
| NLP | spaCy, sentence-transformers | Analisis texto |
|
||||
| API | FastAPI, Pydantic | Serving |
|
||||
| MLOps | MLflow, DVC | Versionamiento |
|
||||
| Cache | Redis | Predicciones frecuentes |
|
||||
| Vectors | pgvector | Embeddings |
|
||||
|
||||
---
|
||||
|
||||
## Arquitectura de Alto Nivel
|
||||
|
||||
```
|
||||
+------------------+
|
||||
| API Gateway |
|
||||
+--------+---------+
|
||||
|
|
||||
+-----------------+-----------------+
|
||||
| |
|
||||
+----------v----------+ +-----------v-----------+
|
||||
| ML API Service | | Report Generator |
|
||||
| (FastAPI) | | (PDF/HTML) |
|
||||
+----------+----------+ +-----------+-----------+
|
||||
| |
|
||||
| +---------------+ |
|
||||
+------>| ML Models |<---------+
|
||||
| (MLflow) |
|
||||
+-------+-------+
|
||||
|
|
||||
+-------v-------+
|
||||
| Feature Store|
|
||||
| (Redis) |
|
||||
+-------+-------+
|
||||
|
|
||||
+---------------+---------------+
|
||||
| |
|
||||
+----------v----------+ +----------v----------+
|
||||
| PostgreSQL | | pgvector |
|
||||
| (Datos Mercado) | | (Embeddings) |
|
||||
+---------------------+ +---------------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Desglose por Fase
|
||||
|
||||
### Fase 1: MVP (4-6 semanas)
|
||||
|
||||
| Tarea | SP | Entregable |
|
||||
|-------|----|------------|
|
||||
| Setup MLflow + FastAPI | 3 | Infraestructura base |
|
||||
| Feature engineering pipeline | 5 | Pipeline de features |
|
||||
| Modelo AVM (XGBoost) | 8 | Valuacion basica |
|
||||
| API `/valuation/predict` | 3 | Endpoint de prediccion |
|
||||
| Dashboard tendencias | 5 | Visualizacion basica |
|
||||
| Reporte CMA basico | 5 | PDF generado |
|
||||
|
||||
**Total:** 29 SP
|
||||
|
||||
### Fase 2: Predicciones (4-6 semanas)
|
||||
|
||||
| Tarea | SP | Entregable |
|
||||
|-------|----|------------|
|
||||
| TimeToSell model | 8 | Prediccion dias |
|
||||
| Demand forecaster | 5 | Prediccion demanda |
|
||||
| Detector subvaluadas | 5 | Deal-Finder |
|
||||
| Sistema de alertas | 5 | Email + push |
|
||||
|
||||
**Total:** 23 SP
|
||||
|
||||
### Fase 3: Analisis Avanzado (4-6 semanas)
|
||||
|
||||
| Tarea | SP | Entregable |
|
||||
|-------|----|------------|
|
||||
| Indices de mercado | 5 | IPV, IAV, IAM, IRI |
|
||||
| Zonas emergentes | 8 | Zone-Spotter |
|
||||
| Analisis ROI | 8 | Investment-Analyzer |
|
||||
| Reportes inversores | 5 | PDF completo |
|
||||
|
||||
**Total:** 26 SP
|
||||
|
||||
### Fase 4: NLP + Enterprise (4-6 semanas)
|
||||
|
||||
| Tarea | SP | Entregable |
|
||||
|-------|----|------------|
|
||||
| NLP pipeline | 5 | Extraccion amenidades |
|
||||
| Quality scoring | 3 | Score de listings |
|
||||
| Multi-tenant models | 5 | Aislamiento |
|
||||
| White-label reports | 5 | Branding custom |
|
||||
|
||||
**Total:** 18 SP
|
||||
|
||||
---
|
||||
|
||||
## Metricas de Exito
|
||||
|
||||
### Modelo
|
||||
|
||||
| Metrica | Objetivo | Medicion |
|
||||
|---------|----------|----------|
|
||||
| AVM MAPE | < 10% | vs precio venta real |
|
||||
| AVM R2 | >= 0.85 | Cross-validation |
|
||||
| Time-to-sell MAPE | < 25% | vs dias reales |
|
||||
| Demand accuracy | >= 70% | Directional |
|
||||
|
||||
### Negocio
|
||||
|
||||
| Metrica | Objetivo |
|
||||
|---------|----------|
|
||||
| Adopcion ML features | 70% MAU |
|
||||
| Reportes generados | > 100/mes (enterprise) |
|
||||
| Conversion oportunidades | 30% investigadas |
|
||||
| NPS ML features | >= 40 |
|
||||
|
||||
### Tecnico
|
||||
|
||||
| Metrica | Objetivo |
|
||||
|---------|----------|
|
||||
| Latencia prediccion | p95 < 500ms |
|
||||
| Uptime | 99.5% |
|
||||
| Model freshness | Re-train mensual |
|
||||
|
||||
---
|
||||
|
||||
## Riesgos y Mitigaciones
|
||||
|
||||
| Riesgo | Prob | Impacto | Mitigacion |
|
||||
|--------|------|---------|------------|
|
||||
| Datos insuficientes | Alta | Alto | Scraping agresivo, datos sinteticos |
|
||||
| Accuracy baja inicial | Media | Alto | Feature engineering, ensemble |
|
||||
| Latencia alta | Media | Medio | Caching agresivo, batch |
|
||||
| Model drift | Alta | Medio | Monitoreo continuo |
|
||||
| Costos compute | Media | Bajo | Optimizacion, spot instances |
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] AVM predice con MAPE < 10% en test set
|
||||
- [ ] API responde < 500ms p95
|
||||
- [ ] Reportes se generan correctamente
|
||||
- [ ] Alertas se envian en tiempo real
|
||||
- [ ] Dashboard muestra tendencias actualizadas
|
||||
- [ ] Modelos versionados en MLflow
|
||||
- [ ] Tests de integracion pasan
|
||||
|
||||
---
|
||||
|
||||
## Documentacion Relacionada
|
||||
|
||||
- [IA-008-ML-ANALYTICS.md](../../02-definicion-modulos/IA-008-ML-ANALYTICS.md) - Definicion del modulo
|
||||
- [ML-SERVICES-SPEC.yml](/shared/knowledge-base/projects/inmobiliaria-analytics/ML-SERVICES-SPEC.yml) - Especificacion completa
|
||||
- [PERFIL-ML-SPECIALIST.md](/orchestration/agents/perfiles/PERFIL-ML-SPECIALIST.md) - Perfil de agente
|
||||
|
||||
---
|
||||
|
||||
**EPIC Owner:** Tech Lead / ML Lead
|
||||
**Fecha creacion:** 2026-01-04
|
||||
**Estado:** Draft
|
||||
155
docs/01-fase-alcance-inicial/IAI-008-ml-analytics/_MAP.md
Normal file
155
docs/01-fase-alcance-inicial/IAI-008-ml-analytics/_MAP.md
Normal file
@ -0,0 +1,155 @@
|
||||
---
|
||||
id: "MAP-IAI-008"
|
||||
title: "Mapa de EPIC IAI-008 ML Analytics"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-008"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: EPIC IAI-008 - Machine Learning y Analytics Avanzado
|
||||
|
||||
**EPIC:** IAI-008
|
||||
**Nombre:** Sistema de ML y Analytics Avanzado
|
||||
**Estado:** Draft
|
||||
**Story Points:** 60 (estimado)
|
||||
|
||||
---
|
||||
|
||||
## Estructura del EPIC
|
||||
|
||||
```
|
||||
IAI-008-ml-analytics/
|
||||
├── _MAP.md # Este archivo
|
||||
├── README.md # Vision general del EPIC
|
||||
│
|
||||
├── requerimientos/
|
||||
│ ├── _MAP.md
|
||||
│ ├── RF-ML-001.md # AVM - Valuacion automatica
|
||||
│ ├── RF-ML-002.md # Prediccion tiempo de venta
|
||||
│ ├── RF-ML-003.md # Deteccion oportunidades
|
||||
│ └── RF-ML-004.md # Zonas emergentes
|
||||
│
|
||||
├── especificaciones/
|
||||
│ ├── _MAP.md
|
||||
│ ├── ET-ML-001-avm.md # Modelo AVM (XGBoost ensemble)
|
||||
│ └── ET-ML-002-opportunities.md # Deteccion de oportunidades
|
||||
│
|
||||
├── historias-usuario/
|
||||
│ ├── _MAP.md
|
||||
│ ├── US-ML-001.md # Valuacion automatica basica
|
||||
│ ├── US-ML-002.md # Explicabilidad de valuacion
|
||||
│ ├── US-ML-003.md # Prediccion dias en mercado
|
||||
│ ├── US-ML-004.md # Dashboard tendencias
|
||||
│ ├── US-ML-005.md # Alertas oportunidades
|
||||
│ ├── US-ML-006.md # Reporte CMA
|
||||
│ ├── US-ML-007.md # Analisis ROI inversion
|
||||
│ └── US-ML-008.md # Zonas emergentes
|
||||
│
|
||||
├── tareas/
|
||||
│ └── _MAP.md
|
||||
│
|
||||
└── implementacion/
|
||||
├── _MAP.md
|
||||
├── MODEL-CARDS/ # Documentacion de modelos
|
||||
└── CHANGELOG.md # Historial de cambios
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Requerimientos Funcionales
|
||||
|
||||
| ID | Nombre | Prioridad | Estado |
|
||||
|----|--------|-----------|--------|
|
||||
| [RF-ML-001](./requerimientos/RF-ML-001.md) | AVM - Valuacion automatica | Alta | Draft |
|
||||
| [RF-ML-002](./requerimientos/RF-ML-002.md) | Prediccion tiempo de venta | Alta | Draft |
|
||||
| [RF-ML-003](./requerimientos/RF-ML-003.md) | Deteccion oportunidades | Alta | Draft |
|
||||
| [RF-ML-004](./requerimientos/RF-ML-004.md) | Zonas emergentes | Media | Draft |
|
||||
|
||||
---
|
||||
|
||||
## Especificaciones Tecnicas
|
||||
|
||||
| ID | Titulo | Estado | Contenido Principal |
|
||||
|----|--------|--------|---------------------|
|
||||
| [ET-ML-001](./especificaciones/ET-ML-001-avm.md) | Modelo AVM | Creado | XGBoost/LightGBM ensemble, SHAP, features |
|
||||
| [ET-ML-002](./especificaciones/ET-ML-002-opportunities.md) | Deteccion Oportunidades | Creado | Undervalued detector, emerging zones, alerts |
|
||||
|
||||
---
|
||||
|
||||
## Servicios ML
|
||||
|
||||
| ID | Servicio | Tipo | Algoritmo | Prioridad |
|
||||
|----|----------|------|-----------|-----------|
|
||||
| AVM-Core | PropertyPricePredictor | Regression | XGBoost ensemble | Alta |
|
||||
| DOM-Predictor | TimeToSellPredictor | Survival | Cox PH / RSF | Alta |
|
||||
| Demand-Forecaster | ZoneDemandPredictor | Time Series | Prophet | Media |
|
||||
| Deal-Finder | UndervaluedDetector | Anomaly | AVM + z-score | Alta |
|
||||
| Zone-Spotter | EmergingZoneIdentifier | Clustering | K-Means + trends | Media |
|
||||
| Investment-Analyzer | ROIAnalyzer | Financial | Multi-model | Media |
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario
|
||||
|
||||
| ID | Titulo | SP | Prioridad | Fase |
|
||||
|----|--------|----|-----------|------|
|
||||
| [US-ML-001](./historias-usuario/US-ML-001.md) | Valuacion automatica de propiedad | 13 | Alta | MVP |
|
||||
| [US-ML-002](./historias-usuario/US-ML-002.md) | Explicabilidad SHAP de valuacion | 5 | Media | MVP |
|
||||
| [US-ML-003](./historias-usuario/US-ML-003.md) | Prediccion de dias en mercado | 8 | Alta | F2 |
|
||||
| [US-ML-004](./historias-usuario/US-ML-004.md) | Dashboard de tendencias por zona | 8 | Alta | MVP |
|
||||
| [US-ML-005](./historias-usuario/US-ML-005.md) | Alertas de oportunidades | 5 | Alta | F2 |
|
||||
| [US-ML-006](./historias-usuario/US-ML-006.md) | Generacion reporte CMA | 8 | Alta | F2 |
|
||||
| [US-ML-007](./historias-usuario/US-ML-007.md) | Calculadora ROI para inversores | 5 | Media | F3 |
|
||||
| [US-ML-008](./historias-usuario/US-ML-008.md) | Mapa de zonas emergentes | 8 | Media | F3 |
|
||||
|
||||
**Total Story Points:** 60
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
### Depende de:
|
||||
- IAI-007 (Webscraper): Datos de propiedades
|
||||
- IAI-002 (Propiedades): Modelo normalizado
|
||||
- IAI-001 (Auth): API authentication
|
||||
|
||||
### Bloquea a:
|
||||
- Portal de Inversores (features avanzadas)
|
||||
- Reportes white-label
|
||||
|
||||
---
|
||||
|
||||
## Metricas de Exito
|
||||
|
||||
| Modelo | Metrica | Objetivo |
|
||||
|--------|---------|----------|
|
||||
| AVM | MAPE | < 10% |
|
||||
| AVM | R2 | >= 0.85 |
|
||||
| Time-to-sell | MAPE | < 25% |
|
||||
| Demand forecast | Dir. Accuracy | >= 70% |
|
||||
|
||||
---
|
||||
|
||||
## Riesgos
|
||||
|
||||
| Riesgo | Probabilidad | Impacto | Mitigacion |
|
||||
|--------|--------------|---------|------------|
|
||||
| Datos insuficientes | Alta | Alto | Scraping agresivo inicial |
|
||||
| Accuracy baja | Media | Alto | Feature engineering, mas datos |
|
||||
| Latencia alta | Media | Medio | Caching, batch predictions |
|
||||
| Drift de modelos | Alta | Medio | Monitoreo, re-entrenamiento |
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [01-fase-alcance-inicial/](../_MAP.md)
|
||||
- **Anterior:** [IAI-007-webscraper/](../IAI-007-webscraper/_MAP.md)
|
||||
- **Siguiente:** -
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,34 @@
|
||||
---
|
||||
id: "MAP-IAI-008-ET"
|
||||
title: "Mapa Especificaciones IAI-008"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-008"
|
||||
section: "especificaciones"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Especificaciones Tecnicas - IAI-008 ML Analytics
|
||||
|
||||
**EPIC:** IAI-008
|
||||
**Seccion:** Especificaciones Tecnicas
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
| ID | Archivo | Titulo | Estado |
|
||||
|----|---------|--------|--------|
|
||||
| ET-ML-001 | [ET-ML-001-avm.md](./ET-ML-001-avm.md) | Modelo AVM (Valuacion Automatica) | Creado |
|
||||
| ET-ML-002 | [ET-ML-002-opportunities.md](./ET-ML-002-opportunities.md) | Deteccion de Oportunidades | Creado |
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-008-ml-analytics/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,183 @@
|
||||
---
|
||||
id: "US-ML-001"
|
||||
title: "Valuacion automatica de propiedad"
|
||||
type: "User Story"
|
||||
epic: "IAI-008"
|
||||
status: "Draft"
|
||||
story_points: 13
|
||||
priority: "Alta"
|
||||
sprint: "-"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# US-ML-001: Valuacion automatica de propiedad
|
||||
|
||||
---
|
||||
|
||||
## User Story
|
||||
|
||||
**Como** agente inmobiliario
|
||||
**Quiero** obtener una valuacion automatica de una propiedad
|
||||
**Para** proporcionar a mis clientes una estimacion de precio basada en datos
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
Implementar el modelo AVM (Automated Valuation Model) que estime el valor de mercado de propiedades basandose en caracteristicas, ubicacion y condiciones de mercado. El modelo debe ser preciso (MAPE < 10%) y proporcionar explicaciones de los factores que influyen en la valuacion.
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
### Funcionales
|
||||
|
||||
- [ ] Usuario ingresa caracteristicas de propiedad
|
||||
- [ ] Sistema retorna valor estimado con rango
|
||||
- [ ] Sistema muestra score de confianza
|
||||
- [ ] Sistema muestra precio por m2
|
||||
- [ ] Sistema lista propiedades comparables
|
||||
|
||||
### Tecnicos
|
||||
|
||||
- [ ] MAPE < 10% en test set
|
||||
- [ ] Latencia < 500ms
|
||||
- [ ] Modelo versionado en MLflow
|
||||
- [ ] API disponible en `/api/v1/ml/valuation/predict`
|
||||
|
||||
---
|
||||
|
||||
## Mockup de Interfaz
|
||||
|
||||
```
|
||||
+------------------------------------------+
|
||||
| VALUACION AUTOMATICA |
|
||||
+------------------------------------------+
|
||||
| |
|
||||
| Tipo: [Casa v] Transaccion: [Venta v] |
|
||||
| |
|
||||
| Recamaras: [3] Banos: [2.5] |
|
||||
| Superficie construida: [180] m2 |
|
||||
| Superficie terreno: [250] m2 |
|
||||
| Antiguedad: [5] anos |
|
||||
| |
|
||||
| Direccion: [Av. Americas 1234_______] |
|
||||
| Colonia: [Providencia] |
|
||||
| Ciudad: [Guadalajara] |
|
||||
| |
|
||||
| [ CALCULAR VALUACION ] |
|
||||
| |
|
||||
+------------------------------------------+
|
||||
| RESULTADO |
|
||||
+------------------------------------------+
|
||||
| |
|
||||
| Valor Estimado: $4,850,000 MXN |
|
||||
| Rango: $4,600,000 - $5,100,000 |
|
||||
| Precio/m2: $26,944 |
|
||||
| Confianza: 87% |
|
||||
| |
|
||||
| Factores principales: |
|
||||
| + Ubicacion premium (+12%) |
|
||||
| + Superficie generosa (+8%) |
|
||||
| - Antiguedad moderada (-3%) |
|
||||
| |
|
||||
| Comparables cercanos: |
|
||||
| | Direccion | Precio | m2 | $/m2 | |
|
||||
| |-----------|--------|-----|------| |
|
||||
| | Americas | 4.9M | 190 | 25.8K| |
|
||||
| | Lopez M. | 4.7M | 175 | 26.9K| |
|
||||
| |
|
||||
+------------------------------------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tareas Tecnicas
|
||||
|
||||
| # | Tarea | Estimacion |
|
||||
|---|-------|------------|
|
||||
| 1 | Feature engineering pipeline | 8h |
|
||||
| 2 | Entrenar modelo XGBoost | 4h |
|
||||
| 3 | Entrenar modelo LightGBM | 4h |
|
||||
| 4 | Implementar ensemble | 4h |
|
||||
| 5 | API endpoint FastAPI | 4h |
|
||||
| 6 | Integracion frontend | 8h |
|
||||
| 7 | Tests unitarios y de integracion | 6h |
|
||||
| 8 | Documentacion y model card | 4h |
|
||||
|
||||
**Total estimado:** 42h (~5 dias)
|
||||
|
||||
---
|
||||
|
||||
## Datos de Entrada
|
||||
|
||||
```yaml
|
||||
input:
|
||||
required:
|
||||
- property_type: string
|
||||
- transaction_type: string
|
||||
- construction_m2: number
|
||||
- latitude: number
|
||||
- longitude: number
|
||||
|
||||
optional:
|
||||
- land_m2: number
|
||||
- bedrooms: integer
|
||||
- bathrooms: number
|
||||
- parking_spaces: integer
|
||||
- age_years: integer
|
||||
- postal_code: string
|
||||
- amenities: string[]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Datos de Salida
|
||||
|
||||
```yaml
|
||||
output:
|
||||
estimated_price: number
|
||||
price_range:
|
||||
min: number
|
||||
max: number
|
||||
price_per_m2: number
|
||||
confidence_score: number # 0-1
|
||||
factors:
|
||||
- name: string
|
||||
impact: string # "positive" | "negative"
|
||||
magnitude: number # %
|
||||
comparables:
|
||||
- id: string
|
||||
address: string
|
||||
price: number
|
||||
surface_m2: number
|
||||
price_per_m2: number
|
||||
similarity_score: number
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] MAPE < 10% validado
|
||||
- [ ] API responde en < 500ms
|
||||
- [ ] UI implementada y funcional
|
||||
- [ ] Comparables se muestran correctamente
|
||||
- [ ] Tests pasan (unit + integration)
|
||||
- [ ] Model card documentado
|
||||
- [ ] Deployed a staging
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
- IA-007 completado (datos de propiedades)
|
||||
- Modelo de datos de propiedades
|
||||
- Infraestructura ML (FastAPI, MLflow)
|
||||
|
||||
---
|
||||
|
||||
**Asignado a:** -
|
||||
**Sprint:** -
|
||||
@ -0,0 +1,86 @@
|
||||
---
|
||||
id: "US-ML-002"
|
||||
title: "Explicabilidad de valuacion con SHAP"
|
||||
type: "User Story"
|
||||
epic: "IAI-008"
|
||||
status: "Draft"
|
||||
story_points: 5
|
||||
priority: "Media"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# US-ML-002: Explicabilidad de valuacion con SHAP
|
||||
|
||||
---
|
||||
|
||||
## User Story
|
||||
|
||||
**Como** agente inmobiliario
|
||||
**Quiero** entender por que el modelo estimo cierto valor
|
||||
**Para** poder explicar la valuacion a mis clientes con confianza
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
Implementar explicabilidad del modelo AVM usando SHAP (SHapley Additive exPlanations) que muestre el impacto de cada feature en la prediccion de forma visual e interpretable.
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Se calculan SHAP values para cada prediccion
|
||||
- [ ] Se genera visualizacion waterfall
|
||||
- [ ] Se identifican top 5 factores de impacto
|
||||
- [ ] Explicaciones en lenguaje natural
|
||||
- [ ] Latencia total < 1 segundo
|
||||
|
||||
---
|
||||
|
||||
## Visualizacion SHAP
|
||||
|
||||
```
|
||||
Impacto en el precio estimado ($4,850,000)
|
||||
------------------------------------------
|
||||
|
||||
Ubicacion (Providencia) ████████████ +$520,000
|
||||
Superficie (180 m2) ████████ +$380,000
|
||||
Recamaras (3) ███ +$120,000
|
||||
Precio zona promedio ██████ +$280,000
|
||||
Banos (2.5) ██ +$80,000
|
||||
Antiguedad (5 anos) ▓▓ -$95,000
|
||||
Estacionamientos (2) █ +$65,000
|
||||
---------------------
|
||||
Valor base: $3,500,000
|
||||
Valor final: $4,850,000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tareas Tecnicas
|
||||
|
||||
| # | Tarea | Estimacion |
|
||||
|---|-------|------------|
|
||||
| 1 | Integrar SHAP library | 2h |
|
||||
| 2 | Calcular SHAP values en inference | 4h |
|
||||
| 3 | Generar explicaciones naturales | 4h |
|
||||
| 4 | Visualizacion frontend | 6h |
|
||||
| 5 | Caching de SHAP values | 2h |
|
||||
|
||||
**Total estimado:** 18h (~2.5 dias)
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] SHAP values se calculan correctamente
|
||||
- [ ] Visualizacion clara e interpretable
|
||||
- [ ] Explicaciones en espanol natural
|
||||
- [ ] Performance aceptable (< 1s total)
|
||||
|
||||
---
|
||||
|
||||
**Asignado a:** -
|
||||
**Sprint:** -
|
||||
@ -0,0 +1,103 @@
|
||||
---
|
||||
id: "US-ML-003"
|
||||
title: "Prediccion de dias en mercado"
|
||||
type: "User Story"
|
||||
epic: "IAI-008"
|
||||
status: "Draft"
|
||||
story_points: 8
|
||||
priority: "Alta"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# US-ML-003: Prediccion de dias en mercado
|
||||
|
||||
---
|
||||
|
||||
## User Story
|
||||
|
||||
**Como** agente inmobiliario
|
||||
**Quiero** saber cuanto tiempo tardara una propiedad en venderse
|
||||
**Para** establecer expectativas realistas con mis clientes
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
Implementar modelo de survival analysis que prediga el tiempo estimado de venta (Days on Market) basandose en caracteristicas de la propiedad, precio de lista vs mercado, y condiciones actuales.
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Sistema predice dias estimados en mercado
|
||||
- [ ] Muestra probabilidades a 30/60/90 dias
|
||||
- [ ] Identifica factores que aceleran/retrasan venta
|
||||
- [ ] Proporciona recomendaciones para acelerar
|
||||
- [ ] C-index >= 0.75 en validacion
|
||||
|
||||
---
|
||||
|
||||
## Mockup de Resultado
|
||||
|
||||
```
|
||||
+------------------------------------------+
|
||||
| TIEMPO ESTIMADO DE VENTA |
|
||||
+------------------------------------------+
|
||||
| |
|
||||
| Dias estimados: 45 dias |
|
||||
| Rango probable: 30 - 65 dias |
|
||||
| |
|
||||
| Probabilidad de venta: |
|
||||
| En 30 dias: 35% [==== ] |
|
||||
| En 60 dias: 72% [======== ] |
|
||||
| En 90 dias: 91% [========= ] |
|
||||
| |
|
||||
| Factores que ACELERAN: |
|
||||
| + Precio competitivo (-15 dias) |
|
||||
| + Buenas fotos (-8 dias) |
|
||||
| |
|
||||
| Factores que RETRASAN: |
|
||||
| - Alto inventario en zona (+12 dias) |
|
||||
| - Temporada baja (+5 dias) |
|
||||
| |
|
||||
| RECOMENDACIONES: |
|
||||
| - Reducir precio 5% podria acelerar |
|
||||
| la venta en ~10 dias |
|
||||
| - Agregar tour virtual podria |
|
||||
| reducir tiempo en ~5 dias |
|
||||
| |
|
||||
+------------------------------------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tareas Tecnicas
|
||||
|
||||
| # | Tarea | Estimacion |
|
||||
|---|-------|------------|
|
||||
| 1 | Preparar dataset con censoring | 4h |
|
||||
| 2 | Entrenar Cox PH model | 4h |
|
||||
| 3 | Entrenar Random Survival Forest | 4h |
|
||||
| 4 | Generar probabilidades y recomendaciones | 4h |
|
||||
| 5 | API endpoint | 3h |
|
||||
| 6 | UI frontend | 6h |
|
||||
| 7 | Tests | 3h |
|
||||
|
||||
**Total estimado:** 28h (~3.5 dias)
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] C-index >= 0.75
|
||||
- [ ] Probabilidades calibradas
|
||||
- [ ] Recomendaciones generadas
|
||||
- [ ] UI implementada
|
||||
- [ ] Tests pasan
|
||||
|
||||
---
|
||||
|
||||
**Asignado a:** -
|
||||
**Sprint:** -
|
||||
@ -0,0 +1,112 @@
|
||||
---
|
||||
id: "US-ML-004"
|
||||
title: "Dashboard de tendencias de mercado"
|
||||
type: "User Story"
|
||||
epic: "IAI-008"
|
||||
status: "Draft"
|
||||
story_points: 8
|
||||
priority: "Alta"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# US-ML-004: Dashboard de tendencias de mercado
|
||||
|
||||
---
|
||||
|
||||
## User Story
|
||||
|
||||
**Como** usuario de la plataforma
|
||||
**Quiero** ver tendencias de precios y mercado por zona
|
||||
**Para** entender la dinamica del mercado inmobiliario
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
Implementar dashboard interactivo que muestre tendencias de precios, inventario, absorcion y otros indicadores clave por zona geografica, con visualizaciones de series temporales y mapas de calor.
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Dashboard muestra precio promedio por zona
|
||||
- [ ] Grafica de tendencia temporal (12 meses)
|
||||
- [ ] Mapa de calor de precios por m2
|
||||
- [ ] Indicadores de mercado (inventario, absorcion)
|
||||
- [ ] Filtros por zona, tipo, rango de precio
|
||||
- [ ] Datos actualizados diariamente
|
||||
|
||||
---
|
||||
|
||||
## Widgets del Dashboard
|
||||
|
||||
```yaml
|
||||
widgets:
|
||||
header:
|
||||
- stat: "Precio Promedio/m2"
|
||||
valor: "$28,500"
|
||||
cambio: "+3.2%"
|
||||
|
||||
- stat: "Inventario Activo"
|
||||
valor: "1,234"
|
||||
cambio: "-5%"
|
||||
|
||||
- stat: "Dias Promedio"
|
||||
valor: "62"
|
||||
cambio: "-8%"
|
||||
|
||||
- stat: "Indice de Mercado"
|
||||
valor: "72/100"
|
||||
cambio: "+2"
|
||||
|
||||
row_1:
|
||||
- tipo: line_chart
|
||||
titulo: "Evolucion de Precios"
|
||||
datos: precio_m2_mensual
|
||||
period: 12_meses
|
||||
|
||||
- tipo: heatmap_geo
|
||||
titulo: "Precio por m2 por Zona"
|
||||
datos: precio_m2_por_zona
|
||||
|
||||
row_2:
|
||||
- tipo: bar_chart
|
||||
titulo: "Top 10 Colonias por Precio"
|
||||
datos: top_colonias
|
||||
|
||||
- tipo: line_chart
|
||||
titulo: "Inventario vs Absorcion"
|
||||
datos: [inventario, ventas]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tareas Tecnicas
|
||||
|
||||
| # | Tarea | Estimacion |
|
||||
|---|-------|------------|
|
||||
| 1 | Agregaciones de datos por zona | 6h |
|
||||
| 2 | API de tendencias | 4h |
|
||||
| 3 | Componente de graficas (Recharts) | 8h |
|
||||
| 4 | Mapa de calor (Mapbox/Leaflet) | 8h |
|
||||
| 5 | Filtros interactivos | 4h |
|
||||
| 6 | Caching de agregaciones | 3h |
|
||||
|
||||
**Total estimado:** 33h (~4 dias)
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] Dashboard renderiza correctamente
|
||||
- [ ] Datos actualizados diariamente
|
||||
- [ ] Performance aceptable (< 2s carga)
|
||||
- [ ] Filtros funcionan correctamente
|
||||
- [ ] Mobile responsive
|
||||
|
||||
---
|
||||
|
||||
**Asignado a:** -
|
||||
**Sprint:** -
|
||||
@ -0,0 +1,113 @@
|
||||
---
|
||||
id: "US-ML-005"
|
||||
title: "Alertas de oportunidades de inversion"
|
||||
type: "User Story"
|
||||
epic: "IAI-008"
|
||||
status: "Draft"
|
||||
story_points: 5
|
||||
priority: "Alta"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# US-ML-005: Alertas de oportunidades de inversion
|
||||
|
||||
---
|
||||
|
||||
## User Story
|
||||
|
||||
**Como** inversor inmobiliario
|
||||
**Quiero** recibir alertas cuando aparezcan propiedades subvaluadas
|
||||
**Para** actuar rapidamente antes que otros inversores
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
Implementar sistema de alertas que notifique a usuarios cuando se detecten propiedades con precio significativamente menor al valor de mercado estimado, permitiendo configurar criterios personalizados.
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Usuario configura criterios de alerta
|
||||
- [ ] Sistema detecta propiedades subvaluadas automaticamente
|
||||
- [ ] Alertas se envian via email y push
|
||||
- [ ] Alerta incluye analisis rapido de oportunidad
|
||||
- [ ] Tiempo entre publicacion y alerta < 1 hora
|
||||
|
||||
---
|
||||
|
||||
## Configuracion de Alerta
|
||||
|
||||
```yaml
|
||||
alerta_config:
|
||||
nombre: "Oportunidades Providencia"
|
||||
criterios:
|
||||
descuento_minimo: 15%
|
||||
zonas: [providencia, americana, lafayette]
|
||||
tipos: [casa, departamento]
|
||||
precio_max: 8000000
|
||||
confianza_min: 0.75
|
||||
|
||||
notificaciones:
|
||||
email: true
|
||||
push: true
|
||||
frecuencia: "inmediata"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Template de Alerta
|
||||
|
||||
```
|
||||
+------------------------------------------+
|
||||
| NUEVA OPORTUNIDAD DETECTADA |
|
||||
+------------------------------------------+
|
||||
| |
|
||||
| Casa en Providencia |
|
||||
| Publicada hace 45 minutos |
|
||||
| |
|
||||
| Precio Lista: $4,200,000 |
|
||||
| Valor Estimado: $5,100,000 |
|
||||
| DESCUENTO: 18% |
|
||||
| |
|
||||
| - 3 recamaras, 2.5 banos |
|
||||
| - 180 m2 construidos |
|
||||
| - Excelente ubicacion |
|
||||
| |
|
||||
| Confianza de estimacion: 82% |
|
||||
| |
|
||||
| [VER PROPIEDAD] [ANALISIS COMPLETO] |
|
||||
| |
|
||||
+------------------------------------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tareas Tecnicas
|
||||
|
||||
| # | Tarea | Estimacion |
|
||||
|---|-------|------------|
|
||||
| 1 | Modelo de configuracion de alertas | 3h |
|
||||
| 2 | Job de deteccion continua | 4h |
|
||||
| 3 | Sistema de notificaciones (email/push) | 6h |
|
||||
| 4 | UI de configuracion | 4h |
|
||||
| 5 | Tests | 2h |
|
||||
|
||||
**Total estimado:** 19h (~2.5 dias)
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] Alertas se configuran correctamente
|
||||
- [ ] Deteccion funciona en tiempo real
|
||||
- [ ] Notificaciones llegan en < 1 hora
|
||||
- [ ] Falsos positivos < 20%
|
||||
|
||||
---
|
||||
|
||||
**Asignado a:** -
|
||||
**Sprint:** -
|
||||
@ -0,0 +1,151 @@
|
||||
---
|
||||
id: "US-ML-006"
|
||||
title: "Reporte CMA automatizado"
|
||||
type: "User Story"
|
||||
epic: "IAI-008"
|
||||
status: "Draft"
|
||||
story_points: 8
|
||||
priority: "Alta"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# US-ML-006: Reporte CMA automatizado
|
||||
|
||||
---
|
||||
|
||||
## User Story
|
||||
|
||||
**Como** agente inmobiliario
|
||||
**Quiero** generar reportes CMA (Comparative Market Analysis) automaticamente
|
||||
**Para** presentar valuaciones profesionales a mis clientes sin trabajo manual
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
Implementar sistema de generacion automatica de reportes CMA profesionales que incluyan comparables, analisis de mercado, valuacion AVM y recomendaciones, exportables a PDF con branding personalizable.
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Sistema genera CMA completo en < 30 segundos
|
||||
- [ ] Incluye minimo 5 comparables relevantes
|
||||
- [ ] Muestra graficas de tendencias de mercado
|
||||
- [ ] Incluye valuacion AVM con explicacion
|
||||
- [ ] PDF profesional con branding del agente
|
||||
- [ ] Exportable en multiples formatos (PDF, DOCX)
|
||||
|
||||
---
|
||||
|
||||
## Estructura del Reporte
|
||||
|
||||
```yaml
|
||||
cma_sections:
|
||||
portada:
|
||||
- logo_agencia
|
||||
- titulo: "Analisis Comparativo de Mercado"
|
||||
- direccion_propiedad
|
||||
- fecha_reporte
|
||||
- datos_agente
|
||||
|
||||
resumen_ejecutivo:
|
||||
- valor_estimado: "$4,850,000"
|
||||
- rango_sugerido: "$4,600,000 - $5,100,000"
|
||||
- precio_recomendado: "$4,750,000"
|
||||
- confianza: "85%"
|
||||
- dias_estimados_mercado: "45-60"
|
||||
|
||||
propiedad_sujeto:
|
||||
- fotos_principales
|
||||
- caracteristicas_clave
|
||||
- ubicacion_mapa
|
||||
- descripcion
|
||||
|
||||
comparables:
|
||||
- lista_5_propiedades
|
||||
- tabla_comparativa
|
||||
- ajustes_aplicados
|
||||
- mapa_ubicaciones
|
||||
|
||||
analisis_mercado:
|
||||
- tendencias_precios_zona
|
||||
- inventario_absorcion
|
||||
- dias_promedio_mercado
|
||||
- predicciones
|
||||
|
||||
valuacion:
|
||||
- metodologia
|
||||
- factores_principales_shap
|
||||
- conclusion
|
||||
- disclaimer
|
||||
|
||||
anexos:
|
||||
- detalle_comparables
|
||||
- fuentes_datos
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mockup de Portada
|
||||
|
||||
```
|
||||
+--------------------------------------------------+
|
||||
| |
|
||||
| [LOGO AGENCIA] |
|
||||
| |
|
||||
| ═══════════════════════════════════════════════ |
|
||||
| |
|
||||
| ANALISIS COMPARATIVO DE MERCADO |
|
||||
| (CMA Report) |
|
||||
| |
|
||||
| ─────────────────────────────────────────────── |
|
||||
| |
|
||||
| Propiedad: |
|
||||
| Av. Providencia 1234, Col. Providencia |
|
||||
| Guadalajara, Jalisco |
|
||||
| |
|
||||
| ─────────────────────────────────────────────── |
|
||||
| |
|
||||
| Preparado por: |
|
||||
| Juan Perez | RE/MAX Premium |
|
||||
| Tel: 33 1234 5678 |
|
||||
| Email: juan@remax.mx |
|
||||
| |
|
||||
| Fecha: 4 de Enero, 2026 |
|
||||
| |
|
||||
+--------------------------------------------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tareas Tecnicas
|
||||
|
||||
| # | Tarea | Estimacion |
|
||||
|---|-------|------------|
|
||||
| 1 | Definir esquema JSON del CMA | 2h |
|
||||
| 2 | Selector de comparables automatico | 6h |
|
||||
| 3 | Generador de graficas (Recharts/D3) | 6h |
|
||||
| 4 | Template PDF con react-pdf | 8h |
|
||||
| 5 | API de generacion | 4h |
|
||||
| 6 | Sistema de branding personalizable | 4h |
|
||||
| 7 | Tests | 3h |
|
||||
|
||||
**Total estimado:** 33h (~4 dias)
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] CMA se genera en < 30 segundos
|
||||
- [ ] PDF renderiza correctamente
|
||||
- [ ] Comparables son relevantes (similarity > 0.7)
|
||||
- [ ] Branding es configurable
|
||||
- [ ] Tests de generacion pasan
|
||||
|
||||
---
|
||||
|
||||
**Asignado a:** -
|
||||
**Sprint:** -
|
||||
@ -0,0 +1,190 @@
|
||||
---
|
||||
id: "US-ML-007"
|
||||
title: "Calculadora de ROI para inversiones"
|
||||
type: "User Story"
|
||||
epic: "IAI-008"
|
||||
status: "Draft"
|
||||
story_points: 5
|
||||
priority: "Media"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# US-ML-007: Calculadora de ROI para inversiones
|
||||
|
||||
---
|
||||
|
||||
## User Story
|
||||
|
||||
**Como** inversor inmobiliario
|
||||
**Quiero** calcular el retorno de inversion proyectado de una propiedad
|
||||
**Para** tomar decisiones informadas de compra
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
Implementar calculadora de ROI que considere precio de compra, costos de cierre, potencial de renta, apreciacion proyectada, gastos de mantenimiento e impuestos para generar proyecciones de retorno a 1, 5 y 10 anos.
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Calcula Cap Rate y Cash-on-Cash return
|
||||
- [ ] Proyecta apreciacion basada en ML
|
||||
- [ ] Considera todos los costos (cierre, mantenimiento, impuestos)
|
||||
- [ ] Muestra comparacion con otras inversiones
|
||||
- [ ] Genera grafica de flujo de efectivo
|
||||
- [ ] Permite ajustar parametros interactivamente
|
||||
|
||||
---
|
||||
|
||||
## Parametros de Entrada
|
||||
|
||||
```yaml
|
||||
purchase:
|
||||
price: 4500000
|
||||
down_payment_pct: 30
|
||||
closing_costs_pct: 5
|
||||
renovation_budget: 200000
|
||||
|
||||
financing:
|
||||
loan_amount: 3150000 # calculado
|
||||
interest_rate: 12.5
|
||||
term_years: 20
|
||||
|
||||
income:
|
||||
monthly_rent: 28000
|
||||
occupancy_rate: 95 # %
|
||||
annual_rent_increase: 4 # %
|
||||
|
||||
expenses:
|
||||
property_tax_annual: 15000
|
||||
insurance_annual: 8000
|
||||
maintenance_pct: 1 # % del valor anual
|
||||
hoa_monthly: 2500
|
||||
management_fee_pct: 8 # % de renta
|
||||
|
||||
appreciation:
|
||||
use_ml_forecast: true
|
||||
manual_rate: null # si no usa ML
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mockup de Resultados
|
||||
|
||||
```
|
||||
+--------------------------------------------------+
|
||||
| ANALISIS DE INVERSION |
|
||||
+--------------------------------------------------+
|
||||
| |
|
||||
| METRICAS CLAVE |
|
||||
| ┌────────────────────────────────────────────┐ |
|
||||
| │ Cap Rate │ 6.8% │ |
|
||||
| │ Cash-on-Cash │ 9.2% │ |
|
||||
| │ ROI Total (5 anos)│ 78% │ |
|
||||
| │ TIR │ 14.3% │ |
|
||||
| └────────────────────────────────────────────┘ |
|
||||
| |
|
||||
| FLUJO DE EFECTIVO MENSUAL |
|
||||
| ┌────────────────────────────────────────────┐ |
|
||||
| │ + Renta bruta │ $28,000 │ |
|
||||
| │ - Vacancia (5%) │ -$1,400 │ |
|
||||
| │ - Hipoteca │ -$35,500 │ |
|
||||
| │ - HOA │ -$2,500 │ |
|
||||
| │ - Mantenimiento │ -$3,750 │ |
|
||||
| │ - Administracion │ -$2,240 │ |
|
||||
| │ ═══════════════════════════════════════ │ |
|
||||
| │ = Flujo neto │ -$17,390 (*) │ |
|
||||
| └────────────────────────────────────────────┘ |
|
||||
| (*) Flujo negativo compensado por apreciacion |
|
||||
| |
|
||||
| PROYECCION A 5 ANOS |
|
||||
| ┌────────────────────────────────────────────┐ |
|
||||
| │ Inversion inicial │ $1,575,000 │ |
|
||||
| │ Valor estimado │ $6,200,000 │ |
|
||||
| │ Equity acumulado │ $2,800,000 │ |
|
||||
| │ Renta acumulada │ $1,512,000 │ |
|
||||
| │ Gastos acumulados │ -$780,000 │ |
|
||||
| │ Ganancia neta │ $1,232,000 │ |
|
||||
| │ ROI │ 78% │ |
|
||||
| └────────────────────────────────────────────┘ |
|
||||
| |
|
||||
+--------------------------------------------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Grafica de Proyeccion
|
||||
|
||||
```
|
||||
Valor de la Inversion (MXN)
|
||||
│
|
||||
7M │ ╭───
|
||||
│ ╭────╯
|
||||
6M │ ╭────╯
|
||||
│ ╭────╯
|
||||
5M │ ╭────╯
|
||||
│ ╭────╯
|
||||
4M │ ╭────╯
|
||||
│ ╭────╯
|
||||
3M │─╯
|
||||
│
|
||||
└────────────────────────────────────────
|
||||
Ano 1 Ano 2 Ano 3 Ano 4 Ano 5
|
||||
|
||||
─── Valor Propiedad ─── Equity ─── Deuda
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tareas Tecnicas
|
||||
|
||||
| # | Tarea | Estimacion |
|
||||
|---|-------|------------|
|
||||
| 1 | Modelo de calculo financiero | 4h |
|
||||
| 2 | Integracion con ML de apreciacion | 3h |
|
||||
| 3 | Componente de entrada interactivo | 4h |
|
||||
| 4 | Visualizaciones de proyeccion | 4h |
|
||||
| 5 | Exportar a PDF | 2h |
|
||||
| 6 | Tests | 2h |
|
||||
|
||||
**Total estimado:** 19h (~2.5 dias)
|
||||
|
||||
---
|
||||
|
||||
## Formulas Clave
|
||||
|
||||
```python
|
||||
# Cap Rate
|
||||
cap_rate = (net_operating_income / property_value) * 100
|
||||
|
||||
# Cash-on-Cash Return
|
||||
cash_on_cash = (annual_cash_flow / total_cash_invested) * 100
|
||||
|
||||
# NOI (Net Operating Income)
|
||||
noi = gross_rent - vacancy - operating_expenses
|
||||
|
||||
# ROI Total
|
||||
roi = (equity_gain + cash_flow_cumulative) / initial_investment * 100
|
||||
|
||||
# TIR (IRR)
|
||||
irr = npf.irr(cash_flows_array)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] Calculos financieros correctos
|
||||
- [ ] ML de apreciacion integrado
|
||||
- [ ] UI interactiva funcional
|
||||
- [ ] Graficas renderizan correctamente
|
||||
- [ ] Tests pasan
|
||||
|
||||
---
|
||||
|
||||
**Asignado a:** -
|
||||
**Sprint:** -
|
||||
@ -0,0 +1,213 @@
|
||||
---
|
||||
id: "US-ML-008"
|
||||
title: "Mapa de zonas emergentes"
|
||||
type: "User Story"
|
||||
epic: "IAI-008"
|
||||
status: "Draft"
|
||||
story_points: 8
|
||||
priority: "Media"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# US-ML-008: Mapa de zonas emergentes
|
||||
|
||||
---
|
||||
|
||||
## User Story
|
||||
|
||||
**Como** inversor inmobiliario
|
||||
**Quiero** visualizar zonas con potencial de apreciacion en un mapa interactivo
|
||||
**Para** identificar donde invertir antes de que suban los precios
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
Implementar mapa interactivo que muestre zonas clasificadas por potencial de apreciacion, con colores indicando oportunidad (verde=alta, amarillo=media, rojo=baja), incluyendo metricas clave y tendencias historicas por zona.
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Mapa interactivo con polygonos de zonas
|
||||
- [ ] Color-coding por potencial de apreciacion
|
||||
- [ ] Click en zona muestra metricas detalladas
|
||||
- [ ] Filtros por tipo de propiedad y rango de precio
|
||||
- [ ] Historico de 12 meses en graficas
|
||||
- [ ] Carga rapida (< 2 segundos)
|
||||
|
||||
---
|
||||
|
||||
## Mockup del Mapa
|
||||
|
||||
```
|
||||
+----------------------------------------------------------+
|
||||
| MAPA DE OPORTUNIDADES DE INVERSION |
|
||||
+----------------------------------------------------------+
|
||||
| Filtros: [Casas ▼] [< $5M ▼] [Ultimos 12 meses ▼] |
|
||||
+----------------------------------------------------------+
|
||||
| |
|
||||
| ┌─────────────────────────────────────────────┐ |
|
||||
| │ ZAPOPAN │ |
|
||||
| │ ┌────────┐ │ |
|
||||
| │ │ Country│ ▓▓▓ │ |
|
||||
| │ │ Club │ │ |
|
||||
| │ └────────┘ ┌──────────┐ │ |
|
||||
| │ │Providencia│ ███ │ |
|
||||
| │ ┌──────┐ │ (+18%) │ │ |
|
||||
| │ │Chapal│ └──────────┘ │ |
|
||||
| │ │ita │ ▓▓▓ │ |
|
||||
| │ └──────┘ │ |
|
||||
| │ GUADALAJARA │ |
|
||||
| │ ┌─────────┐ │ |
|
||||
| │ │Lafayette│ ███ │ |
|
||||
| │ │ (+22%) │ │ |
|
||||
| │ └─────────┘ ┌────────┐ │ |
|
||||
| │ │Americana│ ▓▓▓ │ |
|
||||
| │ │ (+15%) │ │ |
|
||||
| │ └────────┘ │ |
|
||||
| │ │ |
|
||||
| │ ███ Alta (>15%) ▓▓▓ Media (8-15%) │ |
|
||||
| │ ░░░ Baja (<8%) ─── Sin datos │ |
|
||||
| └─────────────────────────────────────────────┘ |
|
||||
| |
|
||||
+----------------------------------------------------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Panel de Detalle de Zona
|
||||
|
||||
```
|
||||
+------------------------------------------+
|
||||
| LAFAYETTE - Zapopan |
|
||||
+------------------------------------------+
|
||||
| |
|
||||
| Score de Inversion: 87/100 ████ |
|
||||
| Riesgo: Bajo |
|
||||
| |
|
||||
| METRICAS |
|
||||
| ┌─────────────────────────────────────┐ |
|
||||
| │ Apreciacion 12m │ +22.3% │ |
|
||||
| │ Precio promedio/m2 │ $35,400 │ |
|
||||
| │ vs. promedio ciudad │ +18% │ |
|
||||
| │ Tendencia │ Acelerando │ |
|
||||
| │ Inventario activo │ 45 props │ |
|
||||
| │ Dias en mercado │ 38 dias │ |
|
||||
| └─────────────────────────────────────┘ |
|
||||
| |
|
||||
| TENDENCIA DE PRECIOS |
|
||||
| $40K │ ╭────── |
|
||||
| $35K │ ╭───╯ |
|
||||
| $30K │╭───╯ |
|
||||
| $25K │ |
|
||||
| └──────────────────── |
|
||||
| E F M A M J J A S O N D |
|
||||
| |
|
||||
| DRIVERS DE CRECIMIENTO |
|
||||
| - Nuevo desarrollo comercial |
|
||||
| - Derrame de zona Andares |
|
||||
| - Alta demanda, bajo inventario |
|
||||
| |
|
||||
| PROPIEDADES EN ZONA |
|
||||
| [Ver 45 propiedades activas] |
|
||||
| |
|
||||
+------------------------------------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tareas Tecnicas
|
||||
|
||||
| # | Tarea | Estimacion |
|
||||
|---|-------|------------|
|
||||
| 1 | Obtener/crear GeoJSON de colonias | 4h |
|
||||
| 2 | Implementar mapa con Mapbox/Leaflet | 6h |
|
||||
| 3 | Calcular scores por zona (backend) | 4h |
|
||||
| 4 | Panel de detalle interactivo | 4h |
|
||||
| 5 | Graficas de tendencia por zona | 4h |
|
||||
| 6 | Filtros y busqueda | 3h |
|
||||
| 7 | Optimizacion de carga | 2h |
|
||||
| 8 | Tests | 2h |
|
||||
|
||||
**Total estimado:** 29h (~3.5 dias)
|
||||
|
||||
---
|
||||
|
||||
## Datos por Zona
|
||||
|
||||
```yaml
|
||||
zone_data:
|
||||
lafayette:
|
||||
polygon: "geojson..."
|
||||
municipality: "Zapopan"
|
||||
|
||||
metrics:
|
||||
appreciation_12m: 22.3
|
||||
avg_price_m2: 35400
|
||||
vs_city_avg: 1.18
|
||||
trend: "accelerating"
|
||||
inventory: 45
|
||||
avg_dom: 38
|
||||
|
||||
investment_score: 87
|
||||
risk_level: "low"
|
||||
|
||||
drivers:
|
||||
- "Nuevo desarrollo comercial cercano"
|
||||
- "Derrame de zona Andares"
|
||||
- "Alta demanda vs inventario bajo"
|
||||
|
||||
forecast:
|
||||
next_12m: 15.5 # % estimado
|
||||
confidence: 0.78
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints
|
||||
|
||||
```yaml
|
||||
endpoints:
|
||||
GET /api/zones/emerging:
|
||||
description: "Lista de zonas emergentes"
|
||||
response:
|
||||
- zone_id
|
||||
- name
|
||||
- polygon_geojson
|
||||
- score
|
||||
- appreciation_12m
|
||||
- color_code
|
||||
|
||||
GET /api/zones/{zone_id}/details:
|
||||
description: "Detalle de una zona"
|
||||
response:
|
||||
- full_metrics
|
||||
- price_history_monthly
|
||||
- drivers
|
||||
- forecast
|
||||
- sample_properties
|
||||
|
||||
GET /api/zones/heatmap:
|
||||
description: "Datos para heatmap de precios"
|
||||
response:
|
||||
- grid_cells_with_values
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] Mapa renderiza correctamente
|
||||
- [ ] Polygonos de zonas cargados
|
||||
- [ ] Colores reflejan scoring correcto
|
||||
- [ ] Panel de detalle funcional
|
||||
- [ ] Performance < 2s carga inicial
|
||||
- [ ] Mobile responsive
|
||||
|
||||
---
|
||||
|
||||
**Asignado a:** -
|
||||
**Sprint:** -
|
||||
@ -0,0 +1,42 @@
|
||||
---
|
||||
id: "MAP-IAI-008-US"
|
||||
title: "Mapa Historias Usuario IAI-008"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-008"
|
||||
section: "historias-usuario"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Historias de Usuario - IAI-008 ML Analytics
|
||||
|
||||
**EPIC:** IAI-008
|
||||
**Seccion:** Historias de Usuario
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
| ID | Archivo | Titulo | SP | Prioridad | Fase |
|
||||
|----|---------|--------|----|-----------|------|
|
||||
| US-ML-001 | [US-ML-001.md](./US-ML-001.md) | Valuacion automatica propiedad | 13 | Alta | MVP |
|
||||
| US-ML-002 | [US-ML-002.md](./US-ML-002.md) | Explicabilidad SHAP | 5 | Media | MVP |
|
||||
| US-ML-003 | [US-ML-003.md](./US-ML-003.md) | Prediccion dias en mercado | 8 | Alta | F2 |
|
||||
| US-ML-004 | [US-ML-004.md](./US-ML-004.md) | Dashboard tendencias | 8 | Alta | MVP |
|
||||
| US-ML-005 | [US-ML-005.md](./US-ML-005.md) | Alertas oportunidades | 5 | Alta | F2 |
|
||||
| US-ML-006 | [US-ML-006.md](./US-ML-006.md) | Reporte CMA | 8 | Alta | F2 |
|
||||
| US-ML-007 | [US-ML-007.md](./US-ML-007.md) | Calculadora ROI | 5 | Media | F3 |
|
||||
| US-ML-008 | [US-ML-008.md](./US-ML-008.md) | Zonas emergentes | 8 | Media | F3 |
|
||||
|
||||
**Total Story Points:** 60
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-008-ml-analytics/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,34 @@
|
||||
---
|
||||
id: "MAP-IAI-008-IMPL"
|
||||
title: "Mapa Implementacion IAI-008"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-008"
|
||||
section: "implementacion"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Implementacion - IAI-008 ML Analytics
|
||||
|
||||
**EPIC:** IAI-008
|
||||
**Seccion:** Implementacion y Trazabilidad
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
| Archivo | Proposito | Estado |
|
||||
|---------|-----------|--------|
|
||||
| MODEL-CARDS/ | Documentacion de modelos ML | Pendiente |
|
||||
| CHANGELOG.md | Historial de cambios | Pendiente |
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-008-ml-analytics/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,245 @@
|
||||
---
|
||||
id: "RF-ML-001"
|
||||
title: "AVM - Valuacion Automatica de Propiedades"
|
||||
type: "Functional Requirement"
|
||||
epic: "IAI-008"
|
||||
priority: "Alta"
|
||||
status: "Draft"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# RF-IA-008-001: AVM - Valuacion Automatica de Propiedades
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
El sistema debe proporcionar un modelo de valuacion automatica (Automated Valuation Model - AVM) que estime el valor de mercado de propiedades inmobiliarias basandose en caracteristicas fisicas, ubicacion y condiciones de mercado.
|
||||
|
||||
---
|
||||
|
||||
## Justificacion
|
||||
|
||||
La valuacion automatica es el servicio core de la plataforma. Permite a agentes generar valuaciones instantaneas, a inversores evaluar oportunidades, y es la base para otros servicios como deteccion de propiedades subvaluadas.
|
||||
|
||||
---
|
||||
|
||||
## Requisitos Funcionales
|
||||
|
||||
### RF-001.1: Prediccion de Precio
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-001.1.1 | El sistema debe predecir precio de venta de propiedades | Alta |
|
||||
| RF-001.1.2 | El sistema debe predecir precio de renta de propiedades | Alta |
|
||||
| RF-001.1.3 | El sistema debe proporcionar intervalo de confianza | Alta |
|
||||
| RF-001.1.4 | El sistema debe retornar score de confianza (0-1) | Alta |
|
||||
| RF-001.1.5 | El sistema debe calcular precio por m2 | Alta |
|
||||
|
||||
### RF-001.2: Features del Modelo
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-001.2.1 | El modelo debe usar caracteristicas intrinsecas (m2, recamaras, etc) | Alta |
|
||||
| RF-001.2.2 | El modelo debe usar caracteristicas de ubicacion (lat/lon, zona) | Alta |
|
||||
| RF-001.2.3 | El modelo debe usar indicadores de mercado (precio promedio zona) | Alta |
|
||||
| RF-001.2.4 | El modelo debe usar features derivadas (precio m2 comparables) | Media |
|
||||
| RF-001.2.5 | El modelo debe manejar features faltantes gracefully | Alta |
|
||||
|
||||
### RF-001.3: Explicabilidad
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-001.3.1 | El sistema debe explicar factores que influyen en la valuacion | Alta |
|
||||
| RF-001.3.2 | El sistema debe usar SHAP values para explicaciones | Media |
|
||||
| RF-001.3.3 | El sistema debe mostrar comparables usados en la estimacion | Alta |
|
||||
| RF-001.3.4 | El sistema debe indicar features con mayor impacto | Media |
|
||||
|
||||
### RF-001.4: Comparables
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-001.4.1 | El sistema debe encontrar propiedades comparables | Alta |
|
||||
| RF-001.4.2 | El sistema debe calcular similitud entre propiedades | Alta |
|
||||
| RF-001.4.3 | El sistema debe ponderar comparables por fecha de venta | Media |
|
||||
| RF-001.4.4 | El sistema debe filtrar comparables por radio geografico | Alta |
|
||||
|
||||
---
|
||||
|
||||
## Features del Modelo
|
||||
|
||||
### Intrinsecas
|
||||
|
||||
| Feature | Tipo | Importancia |
|
||||
|---------|------|-------------|
|
||||
| superficie_construida_m2 | float | Alta |
|
||||
| superficie_terreno_m2 | float | Alta |
|
||||
| num_recamaras | int | Media |
|
||||
| num_banos | float | Media |
|
||||
| num_estacionamientos | int | Media |
|
||||
| antiguedad_anos | int | Alta |
|
||||
| tipo_propiedad | categorical | Alta |
|
||||
| estado_conservacion | ordinal | Media |
|
||||
| amenidades_count | int | Media |
|
||||
|
||||
### Ubicacion
|
||||
|
||||
| Feature | Tipo | Importancia |
|
||||
|---------|------|-------------|
|
||||
| latitud | float | Alta |
|
||||
| longitud | float | Alta |
|
||||
| codigo_postal | categorical | Alta |
|
||||
| distancia_centro_m | float | Media |
|
||||
| distancia_metro_m | float | Media |
|
||||
| indice_seguridad_zona | float | Alta |
|
||||
| nivel_socioeconomico | ordinal | Alta |
|
||||
|
||||
### Mercado
|
||||
|
||||
| Feature | Tipo | Importancia |
|
||||
|---------|------|-------------|
|
||||
| precio_promedio_m2_zona | float | Alta |
|
||||
| tendencia_precios_12m | float | Alta |
|
||||
| oferta_activa_zona | int | Media |
|
||||
| absorcion_promedio_zona | float | Alta |
|
||||
|
||||
---
|
||||
|
||||
## Arquitectura del Modelo
|
||||
|
||||
```yaml
|
||||
modelo:
|
||||
tipo: Ensemble
|
||||
componentes:
|
||||
- modelo: XGBoost
|
||||
peso: 0.5
|
||||
hiperparametros:
|
||||
n_estimators: 500
|
||||
max_depth: 7
|
||||
learning_rate: 0.05
|
||||
|
||||
- modelo: LightGBM
|
||||
peso: 0.3
|
||||
hiperparametros:
|
||||
num_leaves: 50
|
||||
learning_rate: 0.05
|
||||
|
||||
- modelo: ElasticNet
|
||||
peso: 0.2
|
||||
hiperparametros:
|
||||
alpha: 0.5
|
||||
l1_ratio: 0.5
|
||||
|
||||
preprocessing:
|
||||
- log_transform: [precio]
|
||||
- standard_scaler: [superficie_*, distancia_*]
|
||||
- one_hot: [tipo_propiedad]
|
||||
- target_encoding: [codigo_postal]
|
||||
|
||||
target: log(precio)
|
||||
inverse_transform: exp(prediction)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints
|
||||
|
||||
```yaml
|
||||
POST /api/v1/ml/valuation/predict:
|
||||
description: Valuacion de propiedad individual
|
||||
request:
|
||||
property:
|
||||
type: string
|
||||
transaction_type: string
|
||||
bedrooms: integer
|
||||
bathrooms: number
|
||||
construction_m2: number
|
||||
land_m2: number
|
||||
age_years: integer
|
||||
latitude: number
|
||||
longitude: number
|
||||
postal_code: string
|
||||
amenities: string[]
|
||||
response:
|
||||
estimated_price: number
|
||||
price_range:
|
||||
min: number
|
||||
max: number
|
||||
confidence_score: number
|
||||
price_per_m2: number
|
||||
comparables: array
|
||||
explanation:
|
||||
top_factors: array
|
||||
shap_values: object
|
||||
|
||||
POST /api/v1/ml/valuation/batch:
|
||||
description: Valuacion de multiples propiedades
|
||||
request:
|
||||
properties: array
|
||||
response:
|
||||
results: array
|
||||
|
||||
POST /api/v1/ml/valuation/explain:
|
||||
description: Valuacion con explicacion detallada
|
||||
response:
|
||||
# Incluye SHAP waterfall plot data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Metricas de Calidad
|
||||
|
||||
```yaml
|
||||
metricas:
|
||||
objetivo:
|
||||
MAPE: "< 10%"
|
||||
R2: ">= 0.85"
|
||||
RMSE: "< 15% del precio medio"
|
||||
|
||||
monitoreo:
|
||||
- mape_por_tipo_propiedad
|
||||
- mape_por_rango_precio
|
||||
- mape_por_zona
|
||||
- drift_score
|
||||
|
||||
reentrenamiento:
|
||||
trigger: "MAPE > 12% en ultimos 7 dias"
|
||||
frecuencia_minima: "mensual"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] MAPE < 10% en test set holdout
|
||||
- [ ] R2 >= 0.85 en cross-validation
|
||||
- [ ] Latencia < 200ms para prediccion individual
|
||||
- [ ] Latencia < 2s para batch de 100 propiedades
|
||||
- [ ] Explicaciones SHAP disponibles para cada prediccion
|
||||
- [ ] Comparables relevantes incluidos en respuesta
|
||||
- [ ] Modelo versionado en MLflow
|
||||
- [ ] Tests de regresion pasan
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
- IA-007 (Webscraper): Datos de propiedades
|
||||
- IA-002 (Propiedades): Modelo de datos normalizado
|
||||
- XGBoost, LightGBM, scikit-learn
|
||||
- SHAP para explicabilidad
|
||||
- MLflow para versionamiento
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario Relacionadas
|
||||
|
||||
- US-ML-001: Valuacion automatica basica
|
||||
- US-ML-002: Explicabilidad de valuacion
|
||||
|
||||
---
|
||||
|
||||
**Autor:** ML Lead
|
||||
**Fecha:** 2026-01-04
|
||||
@ -0,0 +1,191 @@
|
||||
---
|
||||
id: "RF-ML-002"
|
||||
title: "Prediccion de Tiempo de Venta"
|
||||
type: "Functional Requirement"
|
||||
epic: "IAI-008"
|
||||
priority: "Alta"
|
||||
status: "Draft"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# RF-IA-008-002: Prediccion de Tiempo de Venta
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
El sistema debe predecir cuantos dias tardara una propiedad en venderse (Days on Market - DOM) basandose en caracteristicas de la propiedad, precio de lista y condiciones de mercado.
|
||||
|
||||
---
|
||||
|
||||
## Justificacion
|
||||
|
||||
Conocer el tiempo estimado de venta permite a agentes establecer expectativas realistas con clientes, ajustar estrategias de pricing, y a inversores evaluar liquidez de inversiones.
|
||||
|
||||
---
|
||||
|
||||
## Requisitos Funcionales
|
||||
|
||||
### RF-002.1: Prediccion DOM
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-002.1.1 | El sistema debe predecir dias estimados en mercado | Alta |
|
||||
| RF-002.1.2 | El sistema debe proporcionar intervalo de confianza | Alta |
|
||||
| RF-002.1.3 | El sistema debe calcular probabilidades de venta a 30/60/90 dias | Alta |
|
||||
| RF-002.1.4 | El sistema debe considerar estacionalidad | Media |
|
||||
|
||||
### RF-002.2: Features Criticas
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-002.2.1 | El modelo debe usar ratio precio/mercado como feature principal | Alta |
|
||||
| RF-002.2.2 | El modelo debe considerar inventario activo en zona | Alta |
|
||||
| RF-002.2.3 | El modelo debe considerar absorcion historica | Alta |
|
||||
| RF-002.2.4 | El modelo debe evaluar calidad del listing (fotos, descripcion) | Media |
|
||||
|
||||
### RF-002.3: Actualizacion
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-002.3.1 | El sistema debe recalcular prediccion si cambia precio | Alta |
|
||||
| RF-002.3.2 | El sistema debe ajustar prediccion con dias transcurridos | Media |
|
||||
| RF-002.3.3 | El sistema debe aprender de ventas reales | Alta |
|
||||
|
||||
---
|
||||
|
||||
## Features del Modelo
|
||||
|
||||
### Propiedad
|
||||
|
||||
| Feature | Tipo | Importancia |
|
||||
|---------|------|-------------|
|
||||
| precio_lista | float | Alta |
|
||||
| precio_vs_mercado_ratio | float | Critica |
|
||||
| tipo_propiedad | categorical | Alta |
|
||||
| superficie_m2 | float | Media |
|
||||
| antiguedad_anos | int | Media |
|
||||
| calidad_fotos_score | float | Alta |
|
||||
| descripcion_quality_score | float | Media |
|
||||
| tiene_tour_virtual | boolean | Media |
|
||||
|
||||
### Mercado
|
||||
|
||||
| Feature | Tipo | Importancia |
|
||||
|---------|------|-------------|
|
||||
| inventario_activo_zona | int | Alta |
|
||||
| absorcion_mensual_zona | float | Alta |
|
||||
| tendencia_demanda_zona | float | Alta |
|
||||
| competencia_precio_similar | int | Alta |
|
||||
| estacionalidad_mes | int | Media |
|
||||
|
||||
---
|
||||
|
||||
## Arquitectura del Modelo
|
||||
|
||||
```yaml
|
||||
modelo:
|
||||
tipo: Survival Analysis
|
||||
componentes:
|
||||
- modelo: CoxProportionalHazards
|
||||
uso: "Baseline, interpretable"
|
||||
|
||||
- modelo: RandomSurvivalForest
|
||||
uso: "Captura no-linealidades"
|
||||
hiperparametros:
|
||||
n_estimators: 200
|
||||
max_depth: 10
|
||||
|
||||
target: dias_en_mercado
|
||||
censoring: propiedades_aun_activas
|
||||
|
||||
output:
|
||||
dias_estimados: median_survival_time
|
||||
probabilidades:
|
||||
- p_venta_30d: survival_function(30)
|
||||
- p_venta_60d: survival_function(60)
|
||||
- p_venta_90d: survival_function(90)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints
|
||||
|
||||
```yaml
|
||||
POST /api/v1/ml/predictions/time-to-sell:
|
||||
description: Prediccion de tiempo de venta
|
||||
request:
|
||||
property:
|
||||
type: string
|
||||
price: number
|
||||
construction_m2: number
|
||||
latitude: number
|
||||
longitude: number
|
||||
listing_quality:
|
||||
photos_count: integer
|
||||
has_virtual_tour: boolean
|
||||
response:
|
||||
estimated_days: integer
|
||||
confidence_interval:
|
||||
min: integer
|
||||
max: integer
|
||||
probabilities:
|
||||
sell_30_days: number
|
||||
sell_60_days: number
|
||||
sell_90_days: number
|
||||
factors:
|
||||
- factor: string
|
||||
impact: string # "accelerates" | "delays"
|
||||
magnitude: number
|
||||
recommendations:
|
||||
- recommendation: string
|
||||
potential_improvement_days: integer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Metricas de Calidad
|
||||
|
||||
```yaml
|
||||
metricas:
|
||||
objetivo:
|
||||
C_index: ">= 0.75"
|
||||
MAPE: "< 25%"
|
||||
|
||||
segmentacion:
|
||||
- accuracy_por_rango_precio
|
||||
- accuracy_por_tipo_propiedad
|
||||
- accuracy_por_zona
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] C-index >= 0.75 en test set
|
||||
- [ ] MAPE < 25% en propiedades vendidas
|
||||
- [ ] Probabilidades calibradas correctamente
|
||||
- [ ] Latencia < 100ms por prediccion
|
||||
- [ ] Recomendaciones generadas automaticamente
|
||||
- [ ] Modelo se actualiza con ventas reales
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
- IA-008-001 (AVM): Para ratio precio/mercado
|
||||
- IA-007 (Webscraper): Datos de listings
|
||||
- lifelines o scikit-survival
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario Relacionadas
|
||||
|
||||
- US-ML-003: Prediccion dias en mercado
|
||||
|
||||
---
|
||||
|
||||
**Autor:** ML Lead
|
||||
**Fecha:** 2026-01-04
|
||||
@ -0,0 +1,260 @@
|
||||
---
|
||||
id: "RF-ML-003"
|
||||
title: "Deteccion de Oportunidades de Inversion"
|
||||
type: "Functional Requirement"
|
||||
epic: "IAI-008"
|
||||
priority: "Alta"
|
||||
status: "Draft"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# RF-IA-008-003: Deteccion de Oportunidades de Inversion
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
El sistema debe identificar automaticamente propiedades subvaluadas, zonas emergentes con potencial de apreciacion, y oportunidades de inversion basandose en analisis de mercado y modelos predictivos.
|
||||
|
||||
---
|
||||
|
||||
## Justificacion
|
||||
|
||||
Los inversores buscan oportunidades que el mercado aun no ha identificado. Un sistema automatizado puede analizar miles de propiedades y detectar anomalias de precio o tendencias emergentes que serian imposibles de identificar manualmente.
|
||||
|
||||
---
|
||||
|
||||
## Requisitos Funcionales
|
||||
|
||||
### RF-003.1: Propiedades Subvaluadas
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-003.1.1 | El sistema debe comparar precio lista vs valor AVM | Alta |
|
||||
| RF-003.1.2 | El sistema debe clasificar nivel de oportunidad | Alta |
|
||||
| RF-003.1.3 | El sistema debe filtrar falsos positivos (distressed, defectos) | Alta |
|
||||
| RF-003.1.4 | El sistema debe validar con comparables recientes | Alta |
|
||||
|
||||
### RF-003.2: Zonas Emergentes
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-003.2.1 | El sistema debe detectar zonas con incremento de demanda | Alta |
|
||||
| RF-003.2.2 | El sistema debe identificar senales de desarrollo | Alta |
|
||||
| RF-003.2.3 | El sistema debe proyectar apreciacion potencial | Media |
|
||||
| RF-003.2.4 | El sistema debe clasificar etapa de emergencia | Media |
|
||||
|
||||
### RF-003.3: Alertas
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-003.3.1 | El sistema debe notificar nuevas oportunidades | Alta |
|
||||
| RF-003.3.2 | El sistema debe permitir configurar criterios de alerta | Alta |
|
||||
| RF-003.3.3 | El sistema debe priorizar oportunidades por score | Media |
|
||||
|
||||
---
|
||||
|
||||
## Deteccion de Subvaluadas
|
||||
|
||||
### Metodologia
|
||||
|
||||
```yaml
|
||||
pasos:
|
||||
1_valuacion:
|
||||
accion: "Calcular valor mercado con AVM"
|
||||
output: valor_mercado, confianza
|
||||
|
||||
2_comparacion:
|
||||
accion: "Calcular descuento = (valor_mercado - precio_lista) / valor_mercado"
|
||||
output: descuento_pct
|
||||
|
||||
3_validacion:
|
||||
accion: "Verificar con comparables recientes"
|
||||
filtros:
|
||||
- confianza_avm > 0.75
|
||||
- antiguedad_listing < 30 dias
|
||||
- no_es_foreclosure
|
||||
- no_tiene_defectos_obvios
|
||||
|
||||
4_clasificacion:
|
||||
umbrales:
|
||||
oportunidad_moderada: ">= 10%"
|
||||
oportunidad_alta: ">= 15%"
|
||||
oportunidad_excepcional: ">= 20%"
|
||||
```
|
||||
|
||||
### Filtros Anti-Falso Positivo
|
||||
|
||||
```yaml
|
||||
filtros:
|
||||
excluir:
|
||||
- precio_muy_bajo: "< percentil_5 de zona"
|
||||
- descripcion_contiene: ["rematar", "urgente", "embargo"]
|
||||
- sin_fotos: true
|
||||
- antiguedad_extrema: "> 50 anos sin remodelacion"
|
||||
|
||||
flags_revisar:
|
||||
- precio_baja_reciente: "> 20% en 30 dias"
|
||||
- tiempo_en_mercado_largo: "> 180 dias"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deteccion de Zonas Emergentes
|
||||
|
||||
### Senales
|
||||
|
||||
```yaml
|
||||
senales:
|
||||
infraestructura:
|
||||
peso: 0.25
|
||||
indicadores:
|
||||
- nuevas_lineas_transporte
|
||||
- nuevos_centros_comerciales
|
||||
- mejoras_viales
|
||||
fuente: "noticias, permisos municipales"
|
||||
|
||||
desarrollo:
|
||||
peso: 0.20
|
||||
indicadores:
|
||||
- permisos_construccion_nuevos
|
||||
- proyectos_anunciados
|
||||
- inversion_inmobiliaria
|
||||
fuente: "registros publicos, noticias"
|
||||
|
||||
demanda:
|
||||
peso: 0.30
|
||||
indicadores:
|
||||
- incremento_busquedas_yoy: "> 20%"
|
||||
- reduccion_dias_mercado_yoy: "> 15%"
|
||||
- incremento_precio_m2_yoy: "> 10%"
|
||||
fuente: "datos propios"
|
||||
|
||||
demograficos:
|
||||
peso: 0.15
|
||||
indicadores:
|
||||
- crecimiento_poblacional
|
||||
- mejora_nivel_socioeconomico
|
||||
- reduccion_criminalidad
|
||||
fuente: "INEGI, estadisticas publicas"
|
||||
|
||||
sociales:
|
||||
peso: 0.10
|
||||
indicadores:
|
||||
- nuevos_restaurantes_cafes
|
||||
- apertura_coworkings
|
||||
- eventos_culturales
|
||||
fuente: "Google Places, Yelp"
|
||||
```
|
||||
|
||||
### Clasificacion
|
||||
|
||||
```yaml
|
||||
clasificacion:
|
||||
early_stage:
|
||||
score: "60-70"
|
||||
caracteristicas: "Senales iniciales, pocos inversionistas"
|
||||
riesgo: "Alto"
|
||||
potencial: "Muy alto"
|
||||
|
||||
growing:
|
||||
score: "70-80"
|
||||
caracteristicas: "Tendencia confirmada, precios subiendo"
|
||||
riesgo: "Medio"
|
||||
potencial: "Alto"
|
||||
|
||||
maturing:
|
||||
score: "80-90"
|
||||
caracteristicas: "Establecida, desacelerando"
|
||||
riesgo: "Bajo"
|
||||
potencial: "Medio"
|
||||
|
||||
saturated:
|
||||
score: "> 90"
|
||||
caracteristicas: "Precios altos, poco upside"
|
||||
riesgo: "Bajo"
|
||||
potencial: "Bajo"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints
|
||||
|
||||
```yaml
|
||||
GET /api/v1/ml/opportunities/undervalued:
|
||||
description: Listar propiedades subvaluadas
|
||||
query:
|
||||
min_discount: number # default 10
|
||||
max_price: number
|
||||
property_type: string
|
||||
zone_id: string
|
||||
limit: integer
|
||||
response:
|
||||
opportunities:
|
||||
- property_id: string
|
||||
price: number
|
||||
estimated_value: number
|
||||
discount_pct: number
|
||||
opportunity_level: string
|
||||
confidence: number
|
||||
comparables: array
|
||||
|
||||
GET /api/v1/ml/opportunities/emerging-zones:
|
||||
description: Listar zonas emergentes
|
||||
query:
|
||||
min_score: number
|
||||
stage: string
|
||||
response:
|
||||
zones:
|
||||
- zone_id: string
|
||||
name: string
|
||||
score: number
|
||||
stage: string
|
||||
appreciation_12m: number
|
||||
signals: array
|
||||
heatmap: geojson
|
||||
|
||||
POST /api/v1/ml/opportunities/alerts:
|
||||
description: Configurar alertas de oportunidad
|
||||
request:
|
||||
criteria:
|
||||
min_discount: number
|
||||
property_types: array
|
||||
zones: array
|
||||
max_price: number
|
||||
channels: array # email, push, webhook
|
||||
response: 201 Created
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Propiedades subvaluadas detectadas con precision > 80%
|
||||
- [ ] Falsos positivos < 20%
|
||||
- [ ] Zonas emergentes correlacionan con apreciacion real
|
||||
- [ ] Alertas se envian en < 1 hora de nueva oportunidad
|
||||
- [ ] Dashboard muestra mapa de calor de oportunidades
|
||||
- [ ] Usuarios pueden configurar criterios de alerta
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
- IA-008-001 (AVM): Valuacion de propiedades
|
||||
- IA-007 (Webscraper): Datos de listings
|
||||
- Fuentes externas (INEGI, noticias)
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario Relacionadas
|
||||
|
||||
- US-ML-005: Alertas de oportunidades
|
||||
- US-ML-008: Zonas emergentes
|
||||
|
||||
---
|
||||
|
||||
**Autor:** ML Lead
|
||||
**Fecha:** 2026-01-04
|
||||
@ -0,0 +1,282 @@
|
||||
---
|
||||
id: "RF-ML-004"
|
||||
title: "Reportes Profesionales Automatizados"
|
||||
type: "Functional Requirement"
|
||||
epic: "IAI-008"
|
||||
priority: "Media"
|
||||
status: "Draft"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# RF-IA-008-004: Reportes Profesionales Automatizados
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
El sistema debe generar reportes profesionales automatizados para distintos segmentos de usuarios (agentes, inversores, desarrolladores), integrando datos de mercado, predicciones ML y visualizaciones.
|
||||
|
||||
---
|
||||
|
||||
## Justificacion
|
||||
|
||||
Los reportes profesionales son un diferenciador clave y fuente de valor para clientes. Automatizar su generacion permite escalar el servicio y ofrecer insights consistentes basados en datos.
|
||||
|
||||
---
|
||||
|
||||
## Requisitos Funcionales
|
||||
|
||||
### RF-004.1: Tipos de Reportes
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-004.1.1 | El sistema debe generar reportes CMA para agentes | Alta |
|
||||
| RF-004.1.2 | El sistema debe generar reportes de inversion | Alta |
|
||||
| RF-004.1.3 | El sistema debe generar market snapshots | Media |
|
||||
| RF-004.1.4 | El sistema debe generar estudios de factibilidad | Media |
|
||||
|
||||
### RF-004.2: Formatos
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-004.2.1 | El sistema debe exportar a PDF | Alta |
|
||||
| RF-004.2.2 | El sistema debe exportar a HTML interactivo | Media |
|
||||
| RF-004.2.3 | El sistema debe exportar a PowerPoint | Baja |
|
||||
| RF-004.2.4 | El sistema debe soportar branding personalizado | Alta |
|
||||
|
||||
### RF-004.3: Contenido
|
||||
|
||||
| ID | Requisito | Prioridad |
|
||||
|----|-----------|-----------|
|
||||
| RF-004.3.1 | Los reportes deben incluir datos de mercado actualizados | Alta |
|
||||
| RF-004.3.2 | Los reportes deben incluir predicciones ML | Alta |
|
||||
| RF-004.3.3 | Los reportes deben incluir visualizaciones (graficas, mapas) | Alta |
|
||||
| RF-004.3.4 | Los reportes deben incluir comparables relevantes | Alta |
|
||||
|
||||
---
|
||||
|
||||
## Tipos de Reportes
|
||||
|
||||
### CMA (Comparative Market Analysis)
|
||||
|
||||
```yaml
|
||||
reporte: CMA
|
||||
audiencia: Agentes (para clientes vendedores)
|
||||
secciones:
|
||||
1_resumen_ejecutivo:
|
||||
- valor_estimado
|
||||
- rango_precio
|
||||
- tiempo_estimado_venta
|
||||
- recomendacion_precio
|
||||
|
||||
2_informacion_propiedad:
|
||||
- datos_basicos
|
||||
- fotos
|
||||
- caracteristicas
|
||||
|
||||
3_analisis_comparables:
|
||||
- tabla_comparables
|
||||
- mapa_ubicacion
|
||||
- ajustes_precio
|
||||
|
||||
4_condiciones_mercado:
|
||||
- tendencia_precios_zona
|
||||
- inventario_activo
|
||||
- absorcion
|
||||
|
||||
5_estrategia_venta:
|
||||
- precio_recomendado
|
||||
- timeline_sugerido
|
||||
- tips_preparacion
|
||||
|
||||
formato: PDF (8-12 paginas)
|
||||
branding: logo_inmobiliaria, datos_agente
|
||||
```
|
||||
|
||||
### Investment Analysis
|
||||
|
||||
```yaml
|
||||
reporte: Investment_Analysis
|
||||
audiencia: Inversores
|
||||
secciones:
|
||||
1_resumen_ejecutivo:
|
||||
- roi_proyectado
|
||||
- cash_flow_mensual
|
||||
- recomendacion
|
||||
|
||||
2_descripcion_propiedad:
|
||||
- datos_basicos
|
||||
- ubicacion
|
||||
- estado_actual
|
||||
|
||||
3_analisis_mercado:
|
||||
- tendencias_zona
|
||||
- comparables
|
||||
- proyeccion_apreciacion
|
||||
|
||||
4_proyecciones_financieras:
|
||||
- flujo_caja_5_anos
|
||||
- escenarios_sensibilidad
|
||||
- metricas:
|
||||
- cap_rate
|
||||
- cash_on_cash
|
||||
- irr
|
||||
- payback
|
||||
|
||||
5_analisis_riesgo:
|
||||
- factores_riesgo
|
||||
- mitigaciones
|
||||
- score_riesgo
|
||||
|
||||
6_recomendacion:
|
||||
- go_no_go
|
||||
- proximos_pasos
|
||||
|
||||
formato: PDF (15-20 paginas)
|
||||
```
|
||||
|
||||
### Market Snapshot
|
||||
|
||||
```yaml
|
||||
reporte: Market_Snapshot
|
||||
audiencia: Agentes (semanal)
|
||||
secciones:
|
||||
1_indicadores_clave:
|
||||
- precio_promedio_m2
|
||||
- variacion_semanal
|
||||
- inventario
|
||||
- absorcion
|
||||
|
||||
2_tendencias:
|
||||
- grafica_precios_30d
|
||||
- top_zonas_movimiento
|
||||
|
||||
3_oportunidades:
|
||||
- propiedades_destacadas
|
||||
- zonas_emergentes
|
||||
|
||||
4_prediccion:
|
||||
- outlook_corto_plazo
|
||||
|
||||
formato: PDF (4-6 paginas) o Email
|
||||
frecuencia: Semanal
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Personalizacion (White-Label)
|
||||
|
||||
```yaml
|
||||
branding:
|
||||
logo:
|
||||
posicion: header_right
|
||||
tamano_max: 200x80px
|
||||
formatos: [png, svg]
|
||||
|
||||
colores:
|
||||
primario: hex_color
|
||||
secundario: hex_color
|
||||
acento: hex_color
|
||||
|
||||
tipografia:
|
||||
headings: font_family
|
||||
body: font_family
|
||||
|
||||
footer:
|
||||
texto: string
|
||||
contacto: string
|
||||
disclaimer: string
|
||||
|
||||
cover_page:
|
||||
background_image: url
|
||||
titulo_custom: string
|
||||
|
||||
por_tenant: true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints
|
||||
|
||||
```yaml
|
||||
POST /api/v1/ml/reports/cma:
|
||||
description: Generar reporte CMA
|
||||
request:
|
||||
property_id: string
|
||||
branding:
|
||||
logo_url: string
|
||||
agent_name: string
|
||||
agent_phone: string
|
||||
format: "pdf" | "html"
|
||||
response:
|
||||
report_id: string
|
||||
download_url: string
|
||||
expires_at: timestamp
|
||||
|
||||
POST /api/v1/ml/reports/investment-analysis:
|
||||
description: Generar reporte de inversion
|
||||
request:
|
||||
property_id: string
|
||||
financing:
|
||||
down_payment_pct: number
|
||||
interest_rate: number
|
||||
term_years: number
|
||||
assumptions:
|
||||
vacancy_rate: number
|
||||
appreciation_rate: number
|
||||
response:
|
||||
report_id: string
|
||||
download_url: string
|
||||
|
||||
POST /api/v1/ml/reports/market-snapshot:
|
||||
description: Generar market snapshot
|
||||
request:
|
||||
zone_id: string
|
||||
period: "weekly" | "monthly"
|
||||
response:
|
||||
report_id: string
|
||||
download_url: string
|
||||
|
||||
GET /api/v1/ml/reports/:id:
|
||||
description: Obtener estado/URL de reporte
|
||||
response:
|
||||
status: "processing" | "ready" | "failed"
|
||||
download_url: string
|
||||
expires_at: timestamp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] CMA se genera en < 30 segundos
|
||||
- [ ] PDFs tienen calidad profesional
|
||||
- [ ] Branding se aplica correctamente
|
||||
- [ ] Datos de mercado son actuales (< 24 horas)
|
||||
- [ ] Predicciones ML se incluyen con confianza
|
||||
- [ ] Graficas se renderizan correctamente
|
||||
- [ ] Links de descarga expiran en 24 horas
|
||||
|
||||
---
|
||||
|
||||
## Dependencias
|
||||
|
||||
- IA-008-001 (AVM): Valuaciones
|
||||
- IA-008-002 (Time-to-Sell): Predicciones
|
||||
- Puppeteer/Playwright para PDF rendering
|
||||
- Chart.js o similar para visualizaciones
|
||||
- S3 para storage de reportes
|
||||
|
||||
---
|
||||
|
||||
## Historias de Usuario Relacionadas
|
||||
|
||||
- US-ML-006: Generacion reporte CMA
|
||||
- US-ML-007: Analisis ROI para inversores
|
||||
|
||||
---
|
||||
|
||||
**Autor:** Product Lead
|
||||
**Fecha:** 2026-01-04
|
||||
@ -0,0 +1,36 @@
|
||||
---
|
||||
id: "MAP-IAI-008-RF"
|
||||
title: "Mapa Requerimientos IAI-008"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-008"
|
||||
section: "requerimientos"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Requerimientos - IAI-008 ML Analytics
|
||||
|
||||
**EPIC:** IAI-008
|
||||
**Seccion:** Requerimientos Funcionales
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
| ID | Archivo | Titulo | Prioridad | Estado |
|
||||
|----|---------|--------|-----------|--------|
|
||||
| RF-ML-001 | [RF-ML-001.md](./RF-ML-001.md) | AVM - Valuacion automatica | Alta | Draft |
|
||||
| RF-ML-002 | [RF-ML-002.md](./RF-ML-002.md) | Prediccion tiempo de venta | Alta | Draft |
|
||||
| RF-ML-003 | [RF-ML-003.md](./RF-ML-003.md) | Deteccion oportunidades | Alta | Draft |
|
||||
| RF-ML-004 | [RF-ML-004.md](./RF-ML-004.md) | Zonas emergentes | Media | Draft |
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-008-ml-analytics/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
@ -0,0 +1,31 @@
|
||||
---
|
||||
id: "MAP-IAI-008-TASK"
|
||||
title: "Mapa Tareas IAI-008"
|
||||
type: "Navigation Map"
|
||||
epic: "IAI-008"
|
||||
section: "tareas"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Tareas Tecnicas - IAI-008 ML Analytics
|
||||
|
||||
**EPIC:** IAI-008
|
||||
**Seccion:** Tareas Tecnicas
|
||||
|
||||
---
|
||||
|
||||
## Documentos
|
||||
|
||||
*Sin tareas tecnicas definidas todavia.*
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [IAI-008-ml-analytics/](../_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
127
docs/01-fase-alcance-inicial/_MAP.md
Normal file
127
docs/01-fase-alcance-inicial/_MAP.md
Normal file
@ -0,0 +1,127 @@
|
||||
---
|
||||
id: "MAP-01-FASE"
|
||||
title: "Mapa de Navegacion - Fase Alcance Inicial"
|
||||
type: "Navigation Map"
|
||||
phase: "01"
|
||||
project: "inmobiliaria-analytics"
|
||||
standard: "GAMILIT"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Fase 1 - Alcance Inicial (MVP)
|
||||
|
||||
**Fase:** 01 - Alcance Inicial
|
||||
**Proyecto:** Inmobiliaria Analytics
|
||||
**Total Story Points:** 315 SP
|
||||
**Estado:** En Desarrollo
|
||||
|
||||
---
|
||||
|
||||
## EPICs de la Fase
|
||||
|
||||
| EPIC ID | Carpeta | Titulo | SP | RF | US | ET | Estado |
|
||||
|---------|---------|--------|----|----|----|----|--------|
|
||||
| IAI-001 | [IAI-001-fundamentos/](.//IAI-001-fundamentos/_MAP.md) | Fundamentos del Sistema | 40 | - | - | - | Planned |
|
||||
| IAI-002 | [IAI-002-propiedades/](./IAI-002-propiedades/_MAP.md) | Propiedades CRUD | 34 | - | 5 | - | Planned |
|
||||
| IAI-003 | [IAI-003-usuarios/](./IAI-003-usuarios/_MAP.md) | Usuarios y Perfiles | 26 | - | 4 | - | Planned |
|
||||
| IAI-004 | [IAI-004-tenants/](./IAI-004-tenants/_MAP.md) | Multi-Tenancy | 40 | - | 5 | - | Planned |
|
||||
| IAI-005 | [IAI-005-pagos/](./IAI-005-pagos/_MAP.md) | Pagos (Stripe) | 34 | - | 5 | - | Planned |
|
||||
| IAI-006 | [IAI-006-portales/](./IAI-006-portales/_MAP.md) | Portales Web | 26 | - | 4 | - | Planned |
|
||||
| IAI-007 | [IAI-007-webscraper/](./IAI-007-webscraper/_MAP.md) | Web Scraping y ETL | 55 | 5 | 5 | 3 | Draft |
|
||||
| IAI-008 | [IAI-008-ml-analytics/](./IAI-008-ml-analytics/_MAP.md) | ML y Analytics Avanzado | 60 | 4 | 8 | 2 | Draft |
|
||||
|
||||
---
|
||||
|
||||
## Resumen de la Fase
|
||||
|
||||
| Metrica | Valor |
|
||||
|---------|-------|
|
||||
| Total EPICs | 8 |
|
||||
| Total Story Points | 315 SP |
|
||||
| Requerimientos (RF) | 9 |
|
||||
| User Stories (US) | 36+ |
|
||||
| Especificaciones (ET) | 5 |
|
||||
| EPICs Completadas | 0 |
|
||||
| EPICs En Progreso | 0 |
|
||||
| EPICs Draft/Planned | 8 |
|
||||
|
||||
---
|
||||
|
||||
## Dependencias entre EPICs
|
||||
|
||||
```
|
||||
IAI-001 (Fundamentos)
|
||||
│
|
||||
├──▶ IAI-002 (Propiedades)
|
||||
│ │
|
||||
│ └──▶ IAI-007 (Webscraper) ──▶ IAI-008 (ML Analytics)
|
||||
│
|
||||
├──▶ IAI-003 (Usuarios)
|
||||
│ │
|
||||
│ ├──▶ IAI-004 (Tenants)
|
||||
│ │ │
|
||||
│ │ └──▶ IAI-005 (Pagos)
|
||||
│ │
|
||||
│ └──▶ IAI-006 (Portales)
|
||||
│
|
||||
└──▶ IAI-008 (ML Analytics) ◀── IAI-007 (Webscraper)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Estructura por EPIC
|
||||
|
||||
### IAI-001: Fundamentos
|
||||
- Infraestructura base
|
||||
- Autenticacion JWT
|
||||
- Configuracion NestJS + PostgreSQL
|
||||
|
||||
### IAI-002: Propiedades
|
||||
- CRUD de propiedades
|
||||
- Busqueda y filtros
|
||||
- Galeria de imagenes
|
||||
|
||||
### IAI-003: Usuarios
|
||||
- Gestion de usuarios
|
||||
- Perfiles y roles
|
||||
- Permisos RBAC
|
||||
|
||||
### IAI-004: Multi-Tenancy
|
||||
- Aislamiento por tenant
|
||||
- RLS PostgreSQL
|
||||
- Configuracion por tenant
|
||||
|
||||
### IAI-005: Pagos
|
||||
- Integracion Stripe
|
||||
- Suscripciones
|
||||
- Facturacion
|
||||
|
||||
### IAI-006: Portales
|
||||
- Portal publico
|
||||
- Portal agentes
|
||||
- Portal admin
|
||||
|
||||
### IAI-007: Web Scraping
|
||||
- Scrapers por portal
|
||||
- Pipeline ETL
|
||||
- Pool de proxies
|
||||
|
||||
### IAI-008: ML Analytics
|
||||
- Modelo AVM (valuacion)
|
||||
- Deteccion oportunidades
|
||||
- Zonas emergentes
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [docs/](../_MAP.md)
|
||||
- **Anterior:** [00-vision-general/](../00-vision-general/_MAP.md)
|
||||
- **Siguiente:** [02-fase-robustecimiento/](../02-fase-robustecimiento/_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Generado:** 2026-01-04
|
||||
**Sistema:** NEXUS v3.4 + SIMCO + GAMILIT
|
||||
|
||||
45
docs/02-fase-robustecimiento/_MAP.md
Normal file
45
docs/02-fase-robustecimiento/_MAP.md
Normal file
@ -0,0 +1,45 @@
|
||||
---
|
||||
id: "MAP-02-FASE"
|
||||
title: "Mapa de Fase 2 - Robustecimiento"
|
||||
type: "Navigation Map"
|
||||
phase: "02"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Fase 2 - Robustecimiento
|
||||
|
||||
**Fase:** 02 - Robustecimiento
|
||||
**Estado:** Backlog
|
||||
**Dependencia:** Fase 1 completada
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
Esta fase se enfocara en optimizaciones, mejoras de rendimiento y robustecimiento de las funcionalidades core implementadas en Fase 1.
|
||||
|
||||
---
|
||||
|
||||
## EPICs Planificadas
|
||||
|
||||
| EPIC | Nombre | Descripcion | Estado |
|
||||
|------|--------|-------------|--------|
|
||||
| IAR-001 | Optimizacion DB | Indices, queries, particionamiento | Backlog |
|
||||
| IAR-002 | Caching | Redis, CDN, estrategias | Backlog |
|
||||
| IAR-003 | Monitoring | Observabilidad, alertas | Backlog |
|
||||
| IAR-004 | Testing | E2E, load testing | Backlog |
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Entrada
|
||||
|
||||
- [ ] Fase 1 completada al 100%
|
||||
- [ ] MVP en produccion
|
||||
- [ ] Feedback de usuarios iniciales
|
||||
- [ ] Metricas de baseline establecidas
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
45
docs/03-fase-extensiones/_MAP.md
Normal file
45
docs/03-fase-extensiones/_MAP.md
Normal file
@ -0,0 +1,45 @@
|
||||
---
|
||||
id: "MAP-03-FASE"
|
||||
title: "Mapa de Fase 3 - Extensiones"
|
||||
type: "Navigation Map"
|
||||
phase: "03"
|
||||
project: "inmobiliaria-analytics"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: Fase 3 - Extensiones
|
||||
|
||||
**Fase:** 03 - Extensiones
|
||||
**Estado:** Backlog
|
||||
**Dependencia:** Fase 2 completada
|
||||
|
||||
---
|
||||
|
||||
## Descripcion
|
||||
|
||||
Esta fase agregara funcionalidades extendidas y nuevos modulos basados en feedback del mercado.
|
||||
|
||||
---
|
||||
|
||||
## EPICs Planificadas
|
||||
|
||||
| EPIC | Nombre | Descripcion | Estado |
|
||||
|------|--------|-------------|--------|
|
||||
| IAE-001 | App Mobile | React Native app | Backlog |
|
||||
| IAE-002 | White Label | Branding completo por tenant | Backlog |
|
||||
| IAE-003 | API Publica | API para integraciones | Backlog |
|
||||
| IAE-004 | Notificaciones | Push, email, SMS | Backlog |
|
||||
| IAE-005 | Reportes Avanzados | PDF, Excel exports | Backlog |
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Entrada
|
||||
|
||||
- [ ] Fase 2 completada
|
||||
- [ ] Product-Market Fit validado
|
||||
- [ ] Roadmap priorizado con usuarios
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
226
docs/04-fase-backlog/DEFINITION-OF-DONE.md
Normal file
226
docs/04-fase-backlog/DEFINITION-OF-DONE.md
Normal file
@ -0,0 +1,226 @@
|
||||
---
|
||||
id: "DOD-IA"
|
||||
title: "Definition of Done - Inmobiliaria Analytics"
|
||||
type: "Process Document"
|
||||
version: "1.0.0"
|
||||
status: "Active"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# Definition of Done (DoD)
|
||||
|
||||
## Inmobiliaria Analytics
|
||||
|
||||
---
|
||||
|
||||
## Proposito
|
||||
|
||||
Define los criterios que debe cumplir un item (User Story, Task, Bug) para ser considerado "terminado" y listo para produccion.
|
||||
|
||||
---
|
||||
|
||||
## Checklist General
|
||||
|
||||
Un item esta **Done** cuando cumple TODOS los siguientes criterios:
|
||||
|
||||
### Codigo
|
||||
|
||||
- [ ] **Codigo implementado**
|
||||
- Funcionalidad completa segun especificacion
|
||||
- Sin codigo comentado o debug
|
||||
- Sin console.log innecesarios
|
||||
|
||||
- [ ] **Code review aprobado**
|
||||
- Al menos 1 revisor aprobo
|
||||
- Comentarios de review atendidos
|
||||
- Sin conflictos de merge
|
||||
|
||||
- [ ] **Sin warnings de linter**
|
||||
- ESLint pasa sin errores
|
||||
- Prettier aplicado
|
||||
- TypeScript sin errores de tipo
|
||||
|
||||
- [ ] **Commits limpios**
|
||||
- Mensajes descriptivos
|
||||
- Formato convencional (feat/fix/docs...)
|
||||
- Sin commits de WIP
|
||||
|
||||
### Testing
|
||||
|
||||
- [ ] **Tests unitarios**
|
||||
- Coverage minimo 80% del codigo nuevo
|
||||
- Todos los tests pasan
|
||||
- Casos edge cubiertos
|
||||
|
||||
- [ ] **Tests de integracion**
|
||||
- Endpoints probados
|
||||
- Flujos criticos cubiertos
|
||||
|
||||
- [ ] **Tests E2E (si aplica)**
|
||||
- Flujos de usuario probados
|
||||
- Sin regresiones
|
||||
|
||||
- [ ] **Probado en ambiente de desarrollo**
|
||||
- Funciona en ambiente local
|
||||
- Validado con datos de prueba
|
||||
|
||||
### Documentacion
|
||||
|
||||
- [ ] **API documentada (si aplica)**
|
||||
- Swagger/OpenAPI actualizado
|
||||
- Ejemplos de request/response
|
||||
- Codigos de error documentados
|
||||
|
||||
- [ ] **YAML front-matter actualizado**
|
||||
- status: "Done"
|
||||
- completed_date: "YYYY-MM-DD"
|
||||
|
||||
- [ ] **Notas de implementacion**
|
||||
- Decisiones tecnicas documentadas
|
||||
- Cambios de diseno registrados
|
||||
|
||||
- [ ] **_MAP.md actualizado (si aplica)**
|
||||
- Nuevos archivos agregados
|
||||
- Estados actualizados
|
||||
|
||||
### Deploy
|
||||
|
||||
- [ ] **Build exitoso**
|
||||
- npm run build sin errores
|
||||
- Sin warnings criticos
|
||||
|
||||
- [ ] **Deploy a staging (si aplica)**
|
||||
- Despliegue automatico funciona
|
||||
- Configuracion correcta
|
||||
|
||||
- [ ] **Smoke tests pasados**
|
||||
- Funcionalidad basica verificada
|
||||
- Sin errores 500
|
||||
|
||||
---
|
||||
|
||||
## Checklist por Tipo
|
||||
|
||||
### User Story
|
||||
|
||||
```markdown
|
||||
Codigo:
|
||||
- [ ] Implementacion completa de todos los criterios de aceptacion
|
||||
- [ ] Code review aprobado
|
||||
- [ ] Sin deuda tecnica nueva (o documentada)
|
||||
|
||||
Testing:
|
||||
- [ ] Tests unitarios (>80% coverage nuevo codigo)
|
||||
- [ ] Tests de integracion para endpoints
|
||||
- [ ] Casos de error manejados
|
||||
|
||||
Documentacion:
|
||||
- [ ] API documentada en Swagger
|
||||
- [ ] US marcada como "Done" con fecha
|
||||
- [ ] Notas de implementacion agregadas
|
||||
|
||||
Validacion:
|
||||
- [ ] Demo al PO (si requerido)
|
||||
- [ ] Todos los CA verificados
|
||||
```
|
||||
|
||||
### Task
|
||||
|
||||
```markdown
|
||||
- [ ] Tarea completada segun descripcion
|
||||
- [ ] Sin efectos secundarios no documentados
|
||||
- [ ] Tests relevantes actualizados
|
||||
- [ ] TASK marcada como "Done"
|
||||
- [ ] Horas reales registradas
|
||||
```
|
||||
|
||||
### Bug
|
||||
|
||||
```markdown
|
||||
- [ ] Bug corregido y verificado
|
||||
- [ ] No reproduce con pasos originales
|
||||
- [ ] Test de regresion agregado
|
||||
- [ ] Sin efectos secundarios
|
||||
- [ ] Root cause documentado
|
||||
- [ ] BUG marcado como "Done"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Proceso de Validacion
|
||||
|
||||
```
|
||||
1. Desarrollador completa implementacion
|
||||
2. Desarrollador verifica checklist DoD
|
||||
3. Crea Pull Request
|
||||
4. Revisor valida codigo y tests
|
||||
5. Si cumple DoD:
|
||||
a. Merge a branch principal
|
||||
b. Actualizar status a "Done"
|
||||
c. Mover en Board.md a "Hecho"
|
||||
6. Si NO cumple:
|
||||
a. Comentarios en PR
|
||||
b. Desarrollador corrige
|
||||
c. Volver a paso 3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Excepciones
|
||||
|
||||
Se permiten excepciones documentadas para:
|
||||
|
||||
1. **Hotfixes P0**: Pueden diferir tests a siguiente Sprint
|
||||
2. **Prototipos/POC**: Menor coverage requerido
|
||||
3. **Refactors masivos**: Review por Tech Lead
|
||||
|
||||
En estos casos:
|
||||
- Documentar excepcion en el item
|
||||
- Crear TASK de seguimiento para completar
|
||||
- Registrar en deuda tecnica
|
||||
|
||||
---
|
||||
|
||||
## Metricas
|
||||
|
||||
| Metrica | Objetivo |
|
||||
|---------|----------|
|
||||
| Items que cumplen DoD | 100% |
|
||||
| Coverage promedio | >80% |
|
||||
| PRs rechazados por DoD | <5% |
|
||||
| Bugs post-deploy | <2 por sprint |
|
||||
|
||||
---
|
||||
|
||||
## Niveles de Done
|
||||
|
||||
### Done-Done (Desarrollo)
|
||||
- Codigo completo y revisado
|
||||
- Tests pasando
|
||||
- Documentacion actualizada
|
||||
|
||||
### Done-Done-Done (Staging)
|
||||
- Desplegado en staging
|
||||
- Smoke tests pasados
|
||||
- QA validado
|
||||
|
||||
### Done-Done-Done-Done (Produccion)
|
||||
- Desplegado en produccion
|
||||
- Monitoreado por 24h
|
||||
- Sin incidentes
|
||||
|
||||
---
|
||||
|
||||
## Referencias
|
||||
|
||||
- [DEFINITION-OF-READY.md](./DEFINITION-OF-READY.md)
|
||||
- [Board.md](../planning/Board.md)
|
||||
- [config.yml](../planning/config.yml)
|
||||
|
||||
---
|
||||
|
||||
**Documento:** Definition of Done
|
||||
**Version:** 1.0.0
|
||||
**Estado:** Active
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
165
docs/04-fase-backlog/DEFINITION-OF-READY.md
Normal file
165
docs/04-fase-backlog/DEFINITION-OF-READY.md
Normal file
@ -0,0 +1,165 @@
|
||||
---
|
||||
id: "DOR-IA"
|
||||
title: "Definition of Ready - Inmobiliaria Analytics"
|
||||
type: "Process Document"
|
||||
version: "1.0.0"
|
||||
status: "Active"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# Definition of Ready (DoR)
|
||||
|
||||
## Inmobiliaria Analytics
|
||||
|
||||
---
|
||||
|
||||
## Proposito
|
||||
|
||||
Define los criterios que debe cumplir un item (User Story, Task, Bug) para ser considerado "listo" para trabajar en un Sprint.
|
||||
|
||||
---
|
||||
|
||||
## Checklist General
|
||||
|
||||
Un item esta **Ready** cuando cumple TODOS los siguientes criterios:
|
||||
|
||||
### Claridad
|
||||
|
||||
- [ ] **Titulo claro y descriptivo**
|
||||
- El titulo describe la funcionalidad o tarea en pocas palabras
|
||||
- Cualquier miembro del equipo entiende de que se trata
|
||||
|
||||
- [ ] **Descripcion completa**
|
||||
- Problema o necesidad documentada
|
||||
- Contexto de negocio explicado
|
||||
- Sin ambiguedades en el lenguaje
|
||||
|
||||
- [ ] **Criterios de aceptacion definidos**
|
||||
- Minimo 3 criterios verificables
|
||||
- Escritos en formato "Dado/Cuando/Entonces" o lista clara
|
||||
- Cada criterio es medible y testeable
|
||||
|
||||
### Alcance
|
||||
|
||||
- [ ] **Scope delimitado**
|
||||
- Limites claros de lo que incluye y NO incluye
|
||||
- Tamano adecuado para completar en un Sprint
|
||||
- No mas de 13 Story Points
|
||||
|
||||
- [ ] **Dependencias identificadas**
|
||||
- Lista de items que deben completarse antes
|
||||
- APIs o servicios externos requeridos
|
||||
- Datos o recursos necesarios
|
||||
|
||||
- [ ] **Bloqueantes resueltos**
|
||||
- No hay impedimentos conocidos
|
||||
- Accesos y permisos disponibles
|
||||
- Ambientes listos
|
||||
|
||||
### Estimacion
|
||||
|
||||
- [ ] **Story Points asignados**
|
||||
- Estimacion del equipo (Planning Poker si aplica)
|
||||
- Consenso del equipo
|
||||
|
||||
- [ ] **Complejidad evaluada**
|
||||
- Riesgos tecnicos identificados
|
||||
- Incertidumbre documentada
|
||||
|
||||
### Documentacion
|
||||
|
||||
- [ ] **YAML front-matter completo**
|
||||
- id, title, status, epic, story_points (para US)
|
||||
- priority, assignee (si aplica)
|
||||
- created_date
|
||||
|
||||
- [ ] **Referencias vinculadas**
|
||||
- RF asociado existe (para US)
|
||||
- ET existe si aplica (para implementacion tecnica)
|
||||
- Mockups/wireframes disponibles (si hay UI)
|
||||
|
||||
---
|
||||
|
||||
## Checklist por Tipo
|
||||
|
||||
### User Story
|
||||
|
||||
```markdown
|
||||
- [ ] Formato "Como [rol], quiero [funcionalidad], para [beneficio]"
|
||||
- [ ] EPIC asignada
|
||||
- [ ] Criterios de aceptacion (minimo 3)
|
||||
- [ ] Story Points estimados
|
||||
- [ ] Dependencias identificadas
|
||||
- [ ] RF asociado
|
||||
```
|
||||
|
||||
### Task
|
||||
|
||||
```markdown
|
||||
- [ ] Descripcion tecnica clara
|
||||
- [ ] Horas estimadas
|
||||
- [ ] Prioridad asignada (P0-P3)
|
||||
- [ ] US padre identificada (si aplica)
|
||||
- [ ] Subtareas desglosadas (si >4 horas)
|
||||
```
|
||||
|
||||
### Bug
|
||||
|
||||
```markdown
|
||||
- [ ] Pasos para reproducir (minimo 3 pasos)
|
||||
- [ ] Comportamiento esperado
|
||||
- [ ] Comportamiento actual
|
||||
- [ ] Severidad asignada (P0-P3)
|
||||
- [ ] Modulo afectado identificado
|
||||
- [ ] Screenshots/logs adjuntos
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Proceso de Validacion
|
||||
|
||||
```
|
||||
1. Autor crea el item con todos los campos
|
||||
2. Autor completa checklist de DoR
|
||||
3. PO/Tech Lead revisa el item
|
||||
4. Si cumple DoR → Puede entrar al Sprint
|
||||
5. Si NO cumple → Regresa a Backlog con feedback
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Excepciones
|
||||
|
||||
Solo se permiten excepciones para:
|
||||
|
||||
1. **Hotfixes P0**: Items criticos que afectan produccion
|
||||
2. **Spikes**: Investigaciones tecnicas time-boxed
|
||||
3. **Deuda tecnica critica**: Aprobada por Tech Lead
|
||||
|
||||
En estos casos, documentar razon de excepcion en el item.
|
||||
|
||||
---
|
||||
|
||||
## Metricas
|
||||
|
||||
| Metrica | Objetivo |
|
||||
|---------|----------|
|
||||
| Items que cumplen DoR | >90% |
|
||||
| Items rechazados por DoR | <10% |
|
||||
| Tiempo promedio para cumplir DoR | <2 dias |
|
||||
|
||||
---
|
||||
|
||||
## Referencias
|
||||
|
||||
- [DEFINITION-OF-DONE.md](./DEFINITION-OF-DONE.md)
|
||||
- [Board.md](../planning/Board.md)
|
||||
- [config.yml](../planning/config.yml)
|
||||
|
||||
---
|
||||
|
||||
**Documento:** Definition of Ready
|
||||
**Version:** 1.0.0
|
||||
**Estado:** Active
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
50
docs/04-fase-backlog/_MAP.md
Normal file
50
docs/04-fase-backlog/_MAP.md
Normal file
@ -0,0 +1,50 @@
|
||||
---
|
||||
id: "MAP-04-BACKLOG"
|
||||
title: "Mapa de Navegacion - Fase Backlog"
|
||||
type: "Navigation Map"
|
||||
section: "04-fase-backlog"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: 04-fase-backlog
|
||||
|
||||
**Seccion:** Fase Backlog
|
||||
**Proyecto:** Inmobiliaria Analytics
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
|
||||
---
|
||||
|
||||
## Proposito
|
||||
|
||||
Documentos de proceso y definiciones para el manejo del backlog, incluyendo Definition of Ready (DoR) y Definition of Done (DoD).
|
||||
|
||||
---
|
||||
|
||||
## Contenido
|
||||
|
||||
| Archivo | Titulo | Estado |
|
||||
|---------|--------|--------|
|
||||
| [DEFINITION-OF-READY.md](./DEFINITION-OF-READY.md) | Definition of Ready | Active |
|
||||
| [DEFINITION-OF-DONE.md](./DEFINITION-OF-DONE.md) | Definition of Done | Active |
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [docs/](../_MAP.md)
|
||||
- **Anterior:** [01-fase-alcance-inicial/](../01-fase-alcance-inicial/_MAP.md)
|
||||
- **Siguiente:** [90-transversal/](../90-transversal/_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
## Estadisticas
|
||||
|
||||
| Metrica | Valor |
|
||||
|---------|-------|
|
||||
| Total documentos | 2 |
|
||||
| Documentos activos | 2 |
|
||||
|
||||
---
|
||||
|
||||
**Generado:** 2026-01-04
|
||||
62
docs/90-transversal/_MAP.md
Normal file
62
docs/90-transversal/_MAP.md
Normal file
@ -0,0 +1,62 @@
|
||||
---
|
||||
id: "MAP-90-TRANSVERSAL"
|
||||
title: "Mapa de Navegacion - Transversal"
|
||||
type: "Navigation Map"
|
||||
section: "90-transversal"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: 90-transversal
|
||||
|
||||
**Seccion:** Documentacion Transversal
|
||||
**Proyecto:** Inmobiliaria Analytics
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
|
||||
---
|
||||
|
||||
## Proposito
|
||||
|
||||
Documentacion transversal que aplica a todo el proyecto: arquitectura, inventarios, roadmap, deuda tecnica.
|
||||
|
||||
---
|
||||
|
||||
## Estructura
|
||||
|
||||
```
|
||||
90-transversal/
|
||||
├── _MAP.md # Este archivo
|
||||
├── arquitectura/ # Diagramas y decisiones
|
||||
└── inventarios/ # Inventarios de componentes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Contenido
|
||||
|
||||
### Arquitectura
|
||||
|
||||
| Archivo | Titulo | Estado |
|
||||
|---------|--------|--------|
|
||||
| Pendiente | Diagramas C4 | - |
|
||||
| Pendiente | Diagrama de secuencia | - |
|
||||
|
||||
### Inventarios
|
||||
|
||||
| Archivo | Titulo | Estado |
|
||||
|---------|--------|--------|
|
||||
| Pendiente | DATABASE_INVENTORY.yml | - |
|
||||
| Pendiente | BACKEND_INVENTORY.yml | - |
|
||||
| Pendiente | FRONTEND_INVENTORY.yml | - |
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [docs/](../_MAP.md)
|
||||
- **Anterior:** [04-fase-backlog/](../04-fase-backlog/_MAP.md)
|
||||
- **Siguiente:** [95-guias-desarrollo/](../95-guias-desarrollo/_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Generado:** 2026-01-04
|
||||
55
docs/95-guias-desarrollo/_MAP.md
Normal file
55
docs/95-guias-desarrollo/_MAP.md
Normal file
@ -0,0 +1,55 @@
|
||||
---
|
||||
id: "MAP-95-GUIAS"
|
||||
title: "Mapa de Navegacion - Guias de Desarrollo"
|
||||
type: "Navigation Map"
|
||||
section: "95-guias-desarrollo"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: 95-guias-desarrollo
|
||||
|
||||
**Seccion:** Guias de Desarrollo
|
||||
**Proyecto:** Inmobiliaria Analytics
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
|
||||
---
|
||||
|
||||
## Proposito
|
||||
|
||||
Guias tecnicas para desarrolladores del proyecto.
|
||||
|
||||
---
|
||||
|
||||
## Estructura
|
||||
|
||||
```
|
||||
95-guias-desarrollo/
|
||||
├── _MAP.md # Este archivo
|
||||
├── backend/ # Guias backend NestJS
|
||||
├── frontend/ # Guias frontend React
|
||||
└── testing/ # Guias de testing
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Contenido
|
||||
|
||||
| Archivo | Titulo | Estado |
|
||||
|---------|--------|--------|
|
||||
| Pendiente | SETUP-DESARROLLO.md | - |
|
||||
| Pendiente | BACKEND-GUIDE.md | - |
|
||||
| Pendiente | FRONTEND-GUIDE.md | - |
|
||||
| Pendiente | TESTING-GUIDE.md | - |
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [docs/](../_MAP.md)
|
||||
- **Anterior:** [90-transversal/](../90-transversal/_MAP.md)
|
||||
- **Siguiente:** [96-quick-reference/](../96-quick-reference/_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Generado:** 2026-01-04
|
||||
42
docs/96-quick-reference/_MAP.md
Normal file
42
docs/96-quick-reference/_MAP.md
Normal file
@ -0,0 +1,42 @@
|
||||
---
|
||||
id: "MAP-96-QUICKREF"
|
||||
title: "Mapa de Navegacion - Quick Reference"
|
||||
type: "Navigation Map"
|
||||
section: "96-quick-reference"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# _MAP: 96-quick-reference
|
||||
|
||||
**Seccion:** Quick Reference / Cheatsheets
|
||||
**Proyecto:** Inmobiliaria Analytics
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
|
||||
---
|
||||
|
||||
## Proposito
|
||||
|
||||
Cheatsheets y referencias rapidas para consulta de desarrolladores.
|
||||
|
||||
---
|
||||
|
||||
## Contenido
|
||||
|
||||
| Archivo | Titulo | Estado |
|
||||
|---------|--------|--------|
|
||||
| Pendiente | API-CHEATSHEET.md | - |
|
||||
| Pendiente | DB-CHEATSHEET.md | - |
|
||||
| Pendiente | GIT-CHEATSHEET.md | - |
|
||||
|
||||
---
|
||||
|
||||
## Navegacion
|
||||
|
||||
- **Arriba:** [docs/](../_MAP.md)
|
||||
- **Anterior:** [95-guias-desarrollo/](../95-guias-desarrollo/_MAP.md)
|
||||
- **Siguiente:** [97-adr/](../97-adr/_MAP.md)
|
||||
|
||||
---
|
||||
|
||||
**Generado:** 2026-01-04
|
||||
208
docs/97-adr/ADR-001-stack-tecnologico.md
Normal file
208
docs/97-adr/ADR-001-stack-tecnologico.md
Normal file
@ -0,0 +1,208 @@
|
||||
---
|
||||
id: "ADR-001"
|
||||
title: "Seleccion de Stack Tecnologico"
|
||||
type: "Architecture Decision Record"
|
||||
status: "Accepted"
|
||||
date: "2026-01-04"
|
||||
deciders: ["Tech Lead", "Backend Team", "Frontend Team"]
|
||||
tags: ["stack", "nestjs", "react", "postgresql"]
|
||||
---
|
||||
|
||||
# ADR-001: Seleccion de Stack Tecnologico
|
||||
|
||||
**Status:** Accepted
|
||||
**Date:** 2026-01-04
|
||||
**Deciders:** Tech Lead, Backend Team, Frontend Team
|
||||
**Tags:** stack, nestjs, react, postgresql
|
||||
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
El proyecto Inmobiliaria Analytics requiere un stack tecnologico que soporte:
|
||||
|
||||
1. **Alto rendimiento en analytics**: Procesamiento eficiente de grandes volumenes de datos inmobiliarios
|
||||
2. **Escalabilidad horizontal**: Crecimiento de usuarios y datos sin rediseno
|
||||
3. **Time-to-market rapido**: MVP en Q1 2026
|
||||
4. **Mantenibilidad a largo plazo**: Codigo limpio y documentado
|
||||
5. **Ecosistema maduro**: Librerias y comunidad activa
|
||||
|
||||
### Restricciones
|
||||
|
||||
- Equipo con experiencia en TypeScript/JavaScript
|
||||
- Infraestructura existente basada en Docker
|
||||
- Base de datos relacional requerida para transacciones
|
||||
- Compatibilidad con sistema NEXUS existente
|
||||
|
||||
---
|
||||
|
||||
## Decision
|
||||
|
||||
Seleccionamos el siguiente stack tecnologico:
|
||||
|
||||
### Backend: NestJS 10.x + TypeORM
|
||||
|
||||
**Razon:** Framework TypeScript-first con arquitectura modular que facilita el desarrollo de APIs escalables. TypeORM proporciona un ORM robusto con soporte para migraciones.
|
||||
|
||||
### Frontend: React 18.x + TypeScript + Vite
|
||||
|
||||
**Razon:** Ecosistema maduro con excelente soporte para aplicaciones de datos. Vite proporciona DX rapida. TypeScript asegura type-safety end-to-end.
|
||||
|
||||
### Base de Datos: PostgreSQL 16 + Redis 7
|
||||
|
||||
**Razon:** PostgreSQL ofrece:
|
||||
- Extensiones geograficas (PostGIS) para datos inmobiliarios
|
||||
- JSONB para datos semi-estructurados
|
||||
- Excelente rendimiento en queries analiticas
|
||||
- ACID compliance
|
||||
|
||||
Redis para:
|
||||
- Caching de queries frecuentes
|
||||
- Sesiones de usuario
|
||||
- Rate limiting
|
||||
|
||||
### Autenticacion: Passport + JWT
|
||||
|
||||
**Razon:** Estrategia stateless que facilita escalabilidad horizontal. JWT permite validacion sin consulta a BD.
|
||||
|
||||
---
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
### Alternative 1: Python + FastAPI + SQLAlchemy
|
||||
|
||||
**Pros:**
|
||||
- Excelente para ML/Analytics
|
||||
- Librerias de data science maduras
|
||||
- FastAPI es muy rapido
|
||||
|
||||
**Cons:**
|
||||
- Equipo tiene menos experiencia
|
||||
- Dos stacks de lenguaje (Python + JS/TS para frontend)
|
||||
- Menor integracion con ecosistema existente
|
||||
|
||||
**Decision:** Rechazada - curva de aprendizaje y fragmentacion de stack
|
||||
|
||||
### Alternative 2: Next.js Full-Stack
|
||||
|
||||
**Pros:**
|
||||
- Un solo framework
|
||||
- SSR built-in
|
||||
- Vercel deployment simple
|
||||
|
||||
**Cons:**
|
||||
- Menos flexible para APIs complejas
|
||||
- Acoplamiento frontend-backend
|
||||
- Escalabilidad de API limitada
|
||||
|
||||
**Decision:** Rechazada - requerimos separacion clara para escalabilidad independiente
|
||||
|
||||
### Alternative 3: Go + Fiber + React
|
||||
|
||||
**Pros:**
|
||||
- Alto rendimiento
|
||||
- Compilacion a binarios
|
||||
- Excelente para microservicios
|
||||
|
||||
**Cons:**
|
||||
- Cambio significativo de paradigma
|
||||
- Menos ecosistema para web apps
|
||||
- Curva de aprendizaje alta
|
||||
|
||||
**Decision:** Rechazada - time-to-market afectado significativamente
|
||||
|
||||
### Alternative 4: MongoDB en lugar de PostgreSQL
|
||||
|
||||
**Pros:**
|
||||
- Flexibilidad de schema
|
||||
- JSON nativo
|
||||
- Facil escalabilidad horizontal
|
||||
|
||||
**Cons:**
|
||||
- Sin transacciones ACID robustas (hasta recientemente)
|
||||
- Datos inmobiliarios son relacionales por naturaleza
|
||||
- PostGIS superior para geo-datos
|
||||
|
||||
**Decision:** Rechazada - PostgreSQL mejor para dominio inmobiliario
|
||||
|
||||
---
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positivas
|
||||
|
||||
1. **Consistencia de lenguaje**: TypeScript end-to-end
|
||||
2. **Reutilizacion**: DTOs y tipos compartidos
|
||||
3. **Productividad**: Equipo productivo desde dia 1
|
||||
4. **Escalabilidad**: Cada componente escala independientemente
|
||||
5. **Comunidad**: Amplio soporte y recursos
|
||||
|
||||
### Negativas
|
||||
|
||||
1. **Node.js single-threaded**: Puede ser limitante para CPU-intensive
|
||||
- Mitigacion: Worker threads o microservicio Python para ML
|
||||
2. **ORM overhead**: TypeORM puede ser lento para queries complejas
|
||||
- Mitigacion: Raw queries para analytics criticos
|
||||
3. **Bundle size React**: Apps grandes pueden ser pesadas
|
||||
- Mitigacion: Code splitting, lazy loading
|
||||
|
||||
### Neutrales
|
||||
|
||||
1. Requiere setup inicial de TypeORM migrations
|
||||
2. Configuracion de Swagger para documentacion API
|
||||
3. Setup de testing con Jest
|
||||
|
||||
---
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### Dependencias Clave
|
||||
|
||||
```json
|
||||
{
|
||||
"backend": {
|
||||
"@nestjs/core": "^10.3.0",
|
||||
"@nestjs/typeorm": "^10.0.1",
|
||||
"typeorm": "^0.3.19",
|
||||
"pg": "^8.11.3"
|
||||
},
|
||||
"frontend": {
|
||||
"react": "^18.x",
|
||||
"typescript": "^5.3.x",
|
||||
"vite": "^5.x"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Configuracion Inicial
|
||||
|
||||
1. Monorepo con apps separadas
|
||||
2. Docker Compose para desarrollo local
|
||||
3. GitHub Actions para CI/CD
|
||||
4. PostgreSQL con schemas por dominio
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [NestJS Documentation](https://docs.nestjs.com/)
|
||||
- [TypeORM Documentation](https://typeorm.io/)
|
||||
- [React Documentation](https://react.dev/)
|
||||
- [PostgreSQL Documentation](https://www.postgresql.org/docs/)
|
||||
- [STACK-TECNOLOGICO.md](../00-vision-general/STACK-TECNOLOGICO.md)
|
||||
|
||||
---
|
||||
|
||||
## Status History
|
||||
|
||||
| Date | Status | Notes |
|
||||
|------|--------|-------|
|
||||
| 2026-01-04 | Proposed | ADR creado |
|
||||
| 2026-01-04 | Accepted | Aprobado por equipo tecnico |
|
||||
|
||||
---
|
||||
|
||||
**Document:** ADR-001
|
||||
**Status:** Accepted
|
||||
**Date Created:** 2026-01-04
|
||||
**Supersedes:** N/A
|
||||
91
docs/97-adr/README.md
Normal file
91
docs/97-adr/README.md
Normal file
@ -0,0 +1,91 @@
|
||||
---
|
||||
id: "ADR-INDEX"
|
||||
title: "Indice de ADRs - Inmobiliaria Analytics"
|
||||
type: "Index Document"
|
||||
created_date: "2026-01-04"
|
||||
updated_date: "2026-01-04"
|
||||
---
|
||||
|
||||
# Architecture Decision Records (ADR)
|
||||
|
||||
## Inmobiliaria Analytics
|
||||
|
||||
---
|
||||
|
||||
## Proposito
|
||||
|
||||
Este directorio contiene las decisiones arquitectonicas importantes tomadas para el proyecto Inmobiliaria Analytics. Cada ADR documenta el contexto, la decision tomada, las alternativas consideradas y las consecuencias.
|
||||
|
||||
---
|
||||
|
||||
## Indice de ADRs
|
||||
|
||||
| ID | Titulo | Estado | Fecha |
|
||||
|----|--------|--------|-------|
|
||||
| [ADR-001](./ADR-001-stack-tecnologico.md) | Seleccion de Stack Tecnologico | Accepted | 2026-01-04 |
|
||||
|
||||
---
|
||||
|
||||
## Estados de ADR
|
||||
|
||||
| Estado | Descripcion |
|
||||
|--------|-------------|
|
||||
| **Proposed** | En discusion |
|
||||
| **Accepted** | Aprobado e implementado |
|
||||
| **Deprecated** | Ya no aplica pero historico |
|
||||
| **Superseded** | Reemplazado por otro ADR |
|
||||
|
||||
---
|
||||
|
||||
## Como Crear un ADR
|
||||
|
||||
1. Copiar plantilla de ADR existente
|
||||
2. Asignar siguiente numero secuencial (ADR-XXX)
|
||||
3. Completar todas las secciones
|
||||
4. Discutir con stakeholders
|
||||
5. Actualizar status a Accepted cuando aprobado
|
||||
6. Agregar a este indice
|
||||
|
||||
### Plantilla Basica
|
||||
|
||||
```markdown
|
||||
---
|
||||
id: "ADR-XXX"
|
||||
title: "Titulo de la Decision"
|
||||
type: "Architecture Decision Record"
|
||||
status: "Proposed"
|
||||
date: "YYYY-MM-DD"
|
||||
deciders: ["Stakeholder 1", "Stakeholder 2"]
|
||||
tags: ["tag1", "tag2"]
|
||||
---
|
||||
|
||||
# ADR-XXX: Titulo
|
||||
|
||||
## Context
|
||||
{Contexto y problema}
|
||||
|
||||
## Decision
|
||||
{La decision tomada}
|
||||
|
||||
## Alternatives Considered
|
||||
{Alternativas evaluadas}
|
||||
|
||||
## Consequences
|
||||
{Consecuencias positivas y negativas}
|
||||
|
||||
## References
|
||||
{Referencias relevantes}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Referencias
|
||||
|
||||
- [Arquitectura General](../00-vision-general/ARQUITECTURA-GENERAL.md)
|
||||
- [Stack Tecnologico](../00-vision-general/STACK-TECNOLOGICO.md)
|
||||
- [Michael Nygard - Documenting Architecture Decisions](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions)
|
||||
|
||||
---
|
||||
|
||||
**Ultima actualizacion:** 2026-01-04
|
||||
**Total ADRs:** 1
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user