From a25fd4ee3b6bcff4517a0024d185c3277a2cf7f5 Mon Sep 17 00:00:00 2001 From: brobert Date: Mon, 10 Nov 2025 13:03:53 +0100 Subject: [PATCH] =?UTF-8?q?docs:=20a=C3=B1ade=20Lote=205.5=20al=20plan=20d?= =?UTF-8?q?e=20refactor=20t=C3=A9cnico?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: aider (openrouter/openai/gpt-5) --- docs/2025-11-01-plan-refactor-tecnico.md | 112 +++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/docs/2025-11-01-plan-refactor-tecnico.md b/docs/2025-11-01-plan-refactor-tecnico.md index 0821412..1340903 100644 --- a/docs/2025-11-01-plan-refactor-tecnico.md +++ b/docs/2025-11-01-plan-refactor-tecnico.md @@ -98,6 +98,7 @@ Resultados esperados después del refactor: disminución drástica de duplicados - Lote 3 — Tipos y endurecimiento suave: Completado. - Lote 4 — ICS central y rutas homogéneas: Completado. - Lote 5 — Svelte: dividir componentes grandes: Completado. + - Lote 5.5 — Refactor de servicios grandes (god classes): Pendiente. - Lote 6 — DB Locator / DI ligera: Pendiente. - Lote 7 — Cobertura en módulos flojos: Pendiente. @@ -186,6 +187,117 @@ Cada lote incluye objetivo, cambios, métricas y comprobaciones. Mantener tests - Comprobaciones: - Pruebas E2E web verdes. +### Lote 5.5 — Refactor de servicios grandes (god classes) + +- Objetivo general: + - Reducir acoplamiento y responsabilidades múltiples en servicios grandes para mejorar testabilidad, DX y preparar Lote 6 (locator/DI) sin cambios funcionales. + - Mantener APIs públicas y rutas de import estables, delegando a nuevos módulos internos. + +- Alcance y orden de PRs: + 1) PR 5.5-a — ResponseQueue (673 LOC) + - Motivos: mezcla de repositorio (SQLite), backoff, envío HTTP (texto/reacciones), idempotencia, limpieza/retención, métricas y lógica de onboarding. + - Cambios clave: + - Extraer cliente Evolution (HTTP): + - Nuevo módulo: `src/clients/evolution.ts` con `buildHeaders()`, `sendText(payload)`, `sendReaction(payload)` y manejo de errores/logging. + - Tipar metadata y parsers: + - Tipo `QueueMetadata = { kind: 'onboarding' | 'reaction'; ... }`, helpers `parseQueueMetadata()`, `isReactionJob()`. + - Aislar limpieza/retención: + - Nuevo módulo: `src/services/queue/cleanup.ts` con `runCleanupOnce()`, `startCleanupScheduler()`, `stopCleanupScheduler()`. + - ResponseQueue queda como orquestador (claim → enviar → marcar), delegando a EvolutionClient y Cleanup. + - Archivos a consultar: + - `src/services/response-queue.ts` (origen), `src/utils/datetime.ts`, `src/services/metrics.ts`, `src/services/identity.ts`, `src/utils/whatsapp.ts`, `src/db/migrations/index.ts` (esquema `response_queue`), tests `tests/unit/services/response-queue.test.ts`. + - Métricas de aceptación: + - `src/services/response-queue.ts` < 350 LOC. + - No variación en defaults (`MAX_ATTEMPTS`, `REACTIONS_MAX_ATTEMPTS`, backoff). + - Idempotencia de reacciones (24h) intacta. + - Comprobaciones y comandos: + ```bash + bunx tsc -p tsconfig.core.json --noEmit --pretty false + bun test --coverage + git grep -n "sendReaction\\|sendText" src + ``` + + 2) PR 5.5-c — TaskService (708 LOC) + - Motivos: mezcla de creación (códigos display), queries de listado/contadores, reglas de negocio (claim/unassign), y reacción al completar. + - Cambios clave: + - Extraer generación de display_code: + - Nuevo: `src/tasks/display-code.ts` con `pickNextDisplayCode(db)`. + - Extraer reacción al completar: + - Nuevo: `src/tasks/complete-reaction.ts` con `enqueueCompletionReactionIfEligible(db, taskId)`. + - Extraer mapeos a DTO: + - Nuevo: `src/tasks/mappers.ts` con `mapRowToTask()`, `mapRowsToListItem()`. + - `TaskService.createTask/completeTask/list*` delegan en estos helpers. + - Archivos a consultar: + - `src/tasks/service.ts` (origen), `src/services/allowed-groups.ts`, `src/services/response-queue.ts` (reacción), `src/utils/whatsapp.ts`, `src/db/migrations/index.ts`, tests `tests/unit/tasks/*.test.ts`, `tests/unit/services/command.*.test.ts`. + - Métricas de aceptación: + - `src/tasks/service.ts` < 500 LOC. + - TTL y gating de reacciones sin cambios de comportamiento. + - Comprobaciones y comandos: + ```bash + bunx tsc -p tsconfig.core.json --noEmit --pretty false + bun test --coverage + git grep -n "display_code" src + ``` + + 3) PR 5.5-b — GroupSyncService (1310 LOC) + - Motivos: agrupa API (Evolution), parseos, upsert/caché, scheduling, reconciliación de miembros, allowed-groups y publicación de onboarding. + - Cambios clave: + - Extraer acceso Evolution API: + - Nuevo: `src/services/group-sync/api.ts` con `fetchGroups()`, `fetchMembers(groupId)` y parseos robustos. + - Extraer repositorio/caché: + - Nuevo: `src/services/group-sync/repo.ts` con `upsertGroups()`, `ensureGroupExists()`, `getActiveCount()`, `cacheActiveGroups()`, `listActiveMemberIds()`, getters/setters `onboarding_prompted_at`. + - Nuevo: `src/services/group-sync/cache.ts` para la `Map` y helpers. + - Extraer reconciliación: + - Nuevo: `src/services/group-sync/reconcile.ts` con `reconcileGroupMembers(db, groupId, snapshot, nowIso?)`. + - Mover publicación de mensajes de cobertura de alias a OnboardingService: + - Añadir método en `src/services/onboarding.ts`: `publishGroupCoveragePrompt(db, groupId, ratio, options)`. + - `GroupSyncService` queda como fachada (APIs públicas y schedulers), delegando internamente. + - Archivos a consultar: + - `src/services/group-sync.ts` (origen), `src/services/allowed-groups.ts`, `src/services/identity.ts`, `src/services/metrics.ts`, `src/utils/datetime.ts`, `src/db/migrations/index.ts`, tests `tests/unit/services/group-sync.*.test.ts`. + - Métricas de aceptación: + - `src/services/group-sync.ts` ≈ 600–700 LOC (fase 1), sin cambios funcionales. + - Caché y métricas sin variaciones de semántica. + - Comprobaciones y comandos: + ```bash + bunx tsc -p tsconfig.core.json --noEmit --pretty false + bun test --coverage + git grep -n "fetchAllGroups\\|participants" src/services/group-sync* + ``` + + 4) PR 5.5-d — WebhookServer (665 LOC) + - Motivos: `src/server.ts` mezcla handlers HTTP (/metrics, /health), bootstrap y manejo del webhook (message upsert). + - Cambios clave: + - Controladores HTTP dedicados: + - Nuevo: `src/http/metrics.ts` (render y headers). + - Nuevo: `src/http/health.ts` (cálculo payload; usa `GroupSyncService.getSecondsUntilNextGroupSync()`). + - Nuevo: `src/http/webhook-handler.ts` con `handleWebhookRequest(req)` y `handleMessageUpsert(data)`. + - Nuevo: `src/http/bootstrap.ts` con `startServices()` (webhook-manager, schedulers, queues, maintenance). + - `src/server.ts` queda como wire-up (validateEnv → migrate → Bun.serve) y reexporta fachada `WebhookServer` para no romper tests. + - Archivos a consultar: + - `src/server.ts` (origen), `src/services/webhook-manager.ts`, `src/services/response-queue.ts`, `src/services/maintenance.ts`, `src/services/reminders.ts`, `src/services/group-sync.ts`, `src/services/admin.ts`, `src/services/allowed-groups.ts`, `src/services/contacts.ts`, `src/services/command.ts`. + - Métricas de aceptación: + - `src/server.ts` < 350 LOC. + - Rutas/contratos HTTP y logs sin cambios de comportamiento. + - Comprobaciones y comandos: + ```bash + bunx tsc -p tsconfig.core.json --noEmit --pretty false + bun test --coverage + git grep -n "handleRequest(\\|handleMessageUpsert" src + ``` + +- Métricas de aceptación (global Lote 5.5): + - Tests verdes y sin cambios funcionales observables. + - Reducción de LOC por fichero objetivo: + - response-queue.ts < 350, tasks/service.ts < 500, group-sync.ts ≈ 600–700, server.ts < 350. + - `bunx tsc --noEmit` limpio en core. + - Cobertura igual o superior en piezas extraídas (api/reconcile/cleanup/complete-reaction). + +- Riesgos y mitigación: + - Dividir módulos puede introducir imports cíclicos: + - Mitigación: módulos nuevos sin importar servicios de alto nivel; inyectar `db` como parámetro; reexportar desde fachada. + - Cambios en logging o tiempos: + - Mitigación: mantener mensajes/claves existentes; conservar defaults; validar en tests de integración. + ### Lote 6 — DB Locator / DI ligera - Objetivo: