---
description: "Task list for feature 002-agent-db-clients-contracts"
---

# Tasks: Agent DB — Clientes y contratos

**Input**: Design documents from `/specs/002-agent-db-clients-contracts/`

**Prerequisites**: plan.md, spec.md, research.md, data-model.md, contracts/agent-database-tools.md, quickstart.md

**Tests**: Incluidos en fase Polish (plan Phase D); no TDD estricto — spec no lo exige explícitamente.

**Organization**: Tareas agrupadas por user story para implementación y prueba incremental independiente.

## Format: `[ID] [P?] [Story] Description`

- **[P]**: Paralelizable (archivos distintos, sin dependencias entre sí)
- **[Story]**: User story de spec.md (US1–US4)
- Rutas concretas en cada descripción

## Phase 1: Setup (Shared Infrastructure)

**Purpose**: Estructura base y configuración compartida

- [x] T001 Crear directorio `app/Models/Commercial/` según plan.md
- [x] T002 Añadir clave `max_results` (default 50) en sección `agent_database` de `config/agent.php`
- [x] T003 [P] Verificar conexión `agent_db_secondary` en `config/database.php` y variables `AGENT_DB_*` documentadas en `specs/002-agent-db-clients-contracts/quickstart.md`

---

## Phase 2: Foundational (Blocking Prerequisites)

**Purpose**: Modelos Eloquent y servicio base — **bloquea todas las user stories**

**⚠️ CRITICAL**: Ninguna user story puede completarse hasta terminar esta fase

- [x] T004 [P] Portar modelo `Cliente` desde `desarrolloeneon/app/Models/Cliente.php` a `app/Models/Commercial/Cliente.php` (sin `BelongsToTenant`, `$connection = 'agent_db_secondary'`, scope `buscar`)
- [x] T005 [P] Portar modelo `Contacto` a `app/Models/Commercial/Contacto.php` con relación `detallesCliente()`
- [x] T006 [P] Portar modelo `ContactoDetalleCliente` a `app/Models/Commercial/ContactoDetalleCliente.php`
- [x] T007 [P] Portar modelo `PropuestaComercial` a `app/Models/Commercial/PropuestaComercial.php` con `hasMany(PropuestaComercialCliente)`
- [x] T008 [P] Portar modelo `PropuestaComercialCliente` a `app/Models/Commercial/PropuestaComercialCliente.php` con relaciones titular TipProCom 2/3
- [x] T009 [P] Portar modelo `PropuestaComercialCups` a `app/Models/Commercial/PropuestaComercialCups.php`
- [x] T010 [P] Portar modelo `Contrato` a `app/Models/Commercial/Contrato.php` con `belongsTo(PropuestaComercial)`
- [x] T011 Crear esqueleto `AgentCommercialQueryService` con método `execute(string $queryName, array $parameters): array` en `app/Services/Agent/AgentCommercialQueryService.php`
- [x] T012 Implementar validación de parámetros (trim, `termino` max 120 chars, IDs numéricos) en `app/Services/Agent/AgentCommercialQueryService.php`
- [x] T013 Implementar `applyMaxResults()` con flag `truncated` usando `config/agent.php` en `app/Services/Agent/AgentCommercialQueryService.php`

**Checkpoint**: Modelos y servicio base listos — pueden empezar las user stories

---

## Phase 3: User Story 1 — Buscar cliente y ver contratos (Priority: P1) 🎯 MVP

**Goal**: Operador localiza cliente o contacto y obtiene propuestas comerciales (contratos) asociadas vía chat

**Independent Test**: Preguntar "¿Qué contratos tiene [nombre/NIF]?" devuelve datos reales diferenciando TipProCom 2 y 3; término ambiguo pide concretar

### Implementation for User Story 1

- [x] T014 [P] [US1] Implementar `buscarClientes(array $params)` con Eloquent en `app/Services/Agent/AgentCommercialQueryService.php` (FR-003)
- [x] T015 [P] [US1] Implementar `buscarContactos(array $params)` con relación `detallesCliente.cliente` en `app/Services/Agent/AgentCommercialQueryService.php` (FR-003)
- [x] T016 [US1] Implementar `listarPropuestasPorCliente(array $params)` cadena Cliente→PropuestaComercialCliente→PropuestaComercial WHERE TipProCom=2 en `app/Services/Agent/AgentCommercialQueryService.php` (FR-004, FR-005)
- [x] T017 [US1] Implementar `listarPropuestasPorContacto(array $params)` cadena Contacto→PropuestaComercialCliente→PropuestaComercial WHERE TipProCom=3 en `app/Services/Agent/AgentCommercialQueryService.php` (FR-004, FR-005)
- [x] T018 [US1] Registrar metadatos herramientas US1 (`buscar_clientes`, `buscar_contactos`, `listar_propuestas_por_cliente`, `listar_propuestas_por_contacto`) sin clave SQL en `config/agent.php` (FR-011)
- [x] T019 [US1] Refactorizar `app/Services/Agent/Handlers/AgentDatabaseQueryCapabilityHandler.php` para inyectar y delegar en `AgentCommercialQueryService` en lugar de SQL crudo (FR-002, FR-013)

**Checkpoint**: MVP funcional — búsqueda cliente/contacto + listado contratos

---

## Phase 4: User Story 2 — Detalle de contrato con contexto (Priority: P1)

**Goal**: Operador consulta una propuesta/contrato concreto y recibe titular según TipProCom

**Independent Test**: "Dame información del contrato [RefProCom o CodProCom]" devuelve PropuestaComercial + Cliente o Contacto; ID inexistente → sin resultados

### Implementation for User Story 2

- [x] T020 [US2] Implementar `detallePropuesta(array $params)` por `cod_pro_com`/`ref_pro_com`/`id_oferta` con titular TipProCom en `app/Services/Agent/AgentCommercialQueryService.php` (FR-005, FR-006)
- [x] T021 [P] [US2] Implementar `detalleFormalizacion(array $params)` vía modelo `Contrato` en `app/Services/Agent/AgentCommercialQueryService.php` (FR-005)
- [x] T022 [US2] Registrar metadatos `detalle_propuesta` y `detalle_formalizacion` en `config/agent.php` según `specs/002-agent-db-clients-contracts/contracts/agent-database-tools.md`

**Checkpoint**: US1 + US2 completas — flujos cliente→contrato y contrato→titular

---

## Phase 5: User Story 3 — Cruce de información (Priority: P2)

**Goal**: Preguntas con filtros (estado, tipo, periodo) y CUPs devuelven respuestas integradas desde datos consultados

**Independent Test**: "Lista los CUPs de la propuesta X" o filtros por EstProCom devuelven listado coherente; datos no disponibles → mensaje claro

### Implementation for User Story 3

- [x] T023 [US3] Implementar `listarCupsPropuesta(array $params)` PropuestaComercial→PropuestaComercialCliente→PropuestaComercialCups en `app/Services/Agent/AgentCommercialQueryService.php` (FR-014)
- [x] T024 [US3] Añadir filtros opcionales `est_pro_com`, `tip_pro_com`, rango fechas en métodos de listado en `app/Services/Agent/AgentCommercialQueryService.php` (FR-006)
- [x] T025 [US3] Registrar metadatos `listar_cups_propuesta` en `config/agent.php`

**Checkpoint**: Consultas cruzadas y detalle CUPs operativas

---

## Phase 6: User Story 4 — Respuestas fiables (Priority: P2)

**Goal**: Sin invención de datos; errores de BD y resultados vacíos comunicados claramente

**Independent Test**: Criterio inexistente → "no encontré registros"; BD caída → error comprensible sin datos ficticios

### Implementation for User Story 4

- [x] T026 [US4] Mapear excepciones de conexión a mensaje seguro (`agent_db_unreachable`) en `app/Services/Agent/Handlers/AgentDatabaseQueryCapabilityHandler.php` (FR-008, SC-004)
- [x] T027 [US4] Reforzar prompt turno-2 LLM: solo datos de resultados, vacío explícito, sin SQL/herramientas expuestas en `app/Services/Agent/Handlers/AgentDatabaseQueryCapabilityHandler.php` (FR-007, FR-008)
- [x] T028 [US4] Añadir alias legacy `buscar_representantes_contactos`→`buscar_contactos` y redirigir `listar_clientes` a búsqueda acotada en `app/Services/Agent/AgentCommercialQueryService.php` y `config/agent.php`

**Checkpoint**: Fidelidad al dato y compatibilidad legacy

---

## Phase 7: Polish & Cross-Cutting Concerns

**Purpose**: Tests, routing, cache y validación final

- [x] T029 [P] Crear `tests/Feature/Agent/AgentCommercialQueryServiceTest.php` (TipProCom 2/3, sin resultados, params inválidos, límite filas)
- [x] T030 [P] Verificar/ampliar keywords comerciales en `app/Services/Agent/IntentClassifierService.php` para enrutar a `AgentCapability::AgentDatabase` (FR-010, SC-005)
- [x] T031 Documentar invalidación cache `agent_database_queries_catalog` tras cambios en `config/agent.php` en `app/Services/Agent/DatabaseSchemaService.php` o comentario en config
- [x] T032 Ejecutar checklist manual de `specs/002-agent-db-clients-contracts/quickstart.md`
- [x] T033 Ejecutar `php artisan test` y `vendor/bin/pint --dirty`

---

## Dependencies & Execution Order

### Phase Dependencies

- **Setup (Phase 1)**: Sin dependencias — inicio inmediato
- **Foundational (Phase 2)**: Depende de Phase 1 — **BLOQUEA** US1–US4
- **US1 (Phase 3)**: Depende de Phase 2 — MVP
- **US2 (Phase 4)**: Depende de Phase 2; recomendado tras US1 (reutiliza modelos y handler refactor T019)
- **US3 (Phase 5)**: Depende de Phase 2; recomendado tras US2 (detalle propuesta)
- **US4 (Phase 6)**: Depende de T019 (handler refactor); puede solaparse con US2/US3
- **Polish (Phase 7)**: Depende de US deseadas completadas

### User Story Dependencies

| Story | Depende de | Independiente para probar |
|-------|------------|---------------------------|
| US1 | Phase 2 | ✅ Chat: buscar + listar contratos |
| US2 | Phase 2 (+ T019 handler) | ✅ Chat: detalle propuesta |
| US3 | Phase 2 (+ US2 modelos) | ✅ Chat: CUPs y filtros |
| US4 | T019, T026–T027 | ✅ Errores/vacíos en cualquier herramienta |

### Within Each User Story

- Modelos (Phase 2) antes que métodos de servicio
- Métodos servicio antes que registro en `config/agent.php`
- Handler refactor (T019) antes de pruebas end-to-end US1+

### Parallel Opportunities

- **Phase 2**: T004–T010 (7 modelos) en paralelo
- **Phase 3**: T014 y T015 en paralelo; T016/T017 secuenciales tras T014/T015 si comparten helpers
- **Phase 4**: T021 en paralelo con T020 tras servicio base
- **Phase 7**: T029 y T030 en paralelo

---

## Parallel Example: Phase 2 (modelos)

```bash
# Portar modelos en paralelo (archivos distintos):
T004: app/Models/Commercial/Cliente.php
T005: app/Models/Commercial/Contacto.php
T006: app/Models/Commercial/ContactoDetalleCliente.php
T007: app/Models/Commercial/PropuestaComercial.php
T008: app/Models/Commercial/PropuestaComercialCliente.php
T009: app/Models/Commercial/PropuestaComercialCups.php
T010: app/Models/Commercial/Contrato.php
```

## Parallel Example: User Story 1

```bash
# Tras Phase 2:
T014: buscarClientes en AgentCommercialQueryService.php
T015: buscarContactos en AgentCommercialQueryService.php
# Luego secuencial:
T016 → T017 → T018 → T019
```

---

## Implementation Strategy

### MVP First (User Story 1)

1. Phase 1: Setup (T001–T003)
2. Phase 2: Foundational (T004–T013) — **crítico**
3. Phase 3: User Story 1 (T014–T019)
4. **STOP y VALIDAR** con quickstart: "¿Qué contratos tiene [cliente]?"
5. Demo si listo

### Incremental Delivery

1. Setup + Foundational → base lista
2. US1 → MVP en chat
3. US2 → detalle contrato
4. US3 → CUPs y filtros
5. US4 → fiabilidad y legacy
6. Polish → tests + SC-001/SC-005

### Parallel Team Strategy

1. Equipo completa Phase 1–2 junto
2. Tras Phase 2:
   - Dev A: US1 (T014–T019)
   - Dev B: US2 (T020–T022) tras T019
   - Dev C: US3 (T023–T025) tras T020
3. US4 + Polish al final

---

## Notes

- Fuente modelos: `D:\Projectos\Codigo\SomosTuWebMaster\desarrolloeneon\app\Models\`
- Sin cambios en `ChatFront/` (feature backend-only)
- Solo lectura FR-009: servicio MUST NOT usar `insert`/`update`/`delete`
- Referencia contrato herramientas: `specs/002-agent-db-clients-contracts/contracts/agent-database-tools.md`
