# Plan de Refactor Técnico — 2025-11-01 Este documento describe un plan de refactor seguro, incremental y medible para estabilizar tipado, reducir duplicación, mejorar estructura y preparar la base para evolución a largo plazo. Se prioriza no añadir dependencias externas y mantener el comportamiento actual cubierto por tests. ## Objetivos - Reducir duplicación (fechas/horas, validaciones, helpers de tests, cripto). - Endurecer tipado y contratos en TypeScript (mientras mantenemos compatibilidad). - Clarificar capas (utils compartidos, servicios, API web, UI SvelteKit, tests). - Estabilizar convenciones (UTC, formato SQLite, alias/imports, nombres). - Mantener comportamiento: cambios sin funcionalidad nueva, validados por tests. ## Hallazgos clave (del diagnóstico inicial) - Archivos grandes: - apps/web/src/lib/ui/data/TaskItem.svelte ~911 LOC (punto caliente claro). - Varias páginas Svelte de 250–335 LOC (AppShell, /app, /app/groups, etc.). - Duplicación evidente: - Formateo SQL-UTC con `toISOString().replace('T',' ').replace('Z','')` aparece 35+ veces en app y tests. - `normalizeTime` duplicado en API y page.server. - `ymdUTC` y `addMonthsUTC` definidas 3 veces en rutas ICS y también en tests. - `sha256Hex` reimplementado en múltiples tests pese a existir en `src/utils/crypto.ts`. - SimulatedResponseQueue replicado en varios tests. - Tipado/infra: - tsc falla en apps/web por `$lib` y `./$types` (faltan tipos generados SvelteKit) y por DOM (navigator/document) y Bun types (HeadersInit/fetch). - apps/web/vite.config.ts incompatibilidad de tipos (UserConfig). - Errores “unknown” por resultados de SQLite (faltan tipos/casts). - Inconsistencias null vs undefined (p. ej., groupColor, whatsapp utils). - Cobertura mejorable: - webhook-manager (~32%), maintenance (~17%), contacts (~26%), onboarding (~30%), response-queue (~50%). - Organización: - Inyección de DB mediante propiedades estáticas dispersas; funcional pero frágil. Falta un “locator” central. ## Fase 1 — Diagnóstico asistido (Completada) Comandos ejecutados con éxito el 2025-11-01; a continuación se conservan para referencia y repetibilidad: ```bash git ls-files '*.ts' '*.tsx' '*.svelte' | xargs wc -l | sort -nr | head -n 30 ``` ```bash git grep -n "toISOString().replace('T', ' ').replace('Z', '')" ``` ```bash git grep -n "normalizeTime(" && git grep -n "ymdUTC(" && git grep -n "addMonthsUTC(" && git grep -n "isValidYmd(" ``` ```bash git grep -n "sha256Hex(" && git grep -n "SimulatedResponseQueue" ``` ```bash bunx tsc --noEmit --pretty false ``` ```bash bun test --coverage ``` Resultados esperados después del refactor: disminución drástica de duplicados, tsc limpio por paquete, y cobertura estable o al alza. ## Progreso - 2025-11-01: - Documento creado y versionado (commit a104b69). - Diagnóstico ejecutado (wc -l, git grep, tsc, coverage) y hallazgos consolidados en este documento. - Pendiente iniciar Lote 0 (Infra de typecheck): a la espera de revisar tsconfig raíz, apps/web/tsconfig y apps/web/vite.config. - 2025-11-02: - Lote 1 completado: util canónica de fechas/UTC creada (src/utils/datetime.ts) y wrapper web (apps/web/src/lib/server/datetime.ts); migración de rutas ICS y reemplazos en producción (hooks, login, complete/uncomplete, calendar tokens, dev-seed, response-queue, maintenance, group-sync, migrator). - Commits relevantes: f4f7d95, 882f5c9, c1f12ff, df27161, a0f35b8. - Tests verdes. Cobertura actual: 85.91% funciones / 82.12% líneas. - 2025-11-07: - Lote 0 completado: scripts `typecheck:core` y `typecheck:web` configurados y verificados. Se utiliza `tsconfig.core.json` para aislar el typecheck del core con reglas laxas, mientras que la web usa su propia configuración de SvelteKit. Los shims en `src/types/shims.d.ts` resuelven conflictos de tipos entre Bun y el DOM. - Verificación exitosa: `bun run typecheck:core` y `bun run typecheck:web` se ejecutan sin errores. - 2025-11-09: - Lote 2 completado: centralización de helpers de tests (sha256Hex, toIsoSql), unificación de SimulatedResponseQueue y helpers ICS (ymdUTC, addDays) en tests. - Commits relevantes: 77e318e, 1ad36ee, y este commit. - 2025-11-10: - Lote 3 completado: endurecimiento de tipos (noImplicitAny, exactOptionalPropertyTypes, strictNullChecks), centralización de normalizeTime y tipado ligero de SQLite en servicios; inclusión de servicios en typecheck; limpieza de as any en puntos clave. - Verificación: typecheck core/web limpios y tests verdes. - Lote 4 completado: ICS central y rutas homogéneas; rate limiting por token; títulos “Wtask.org Tareas – Personal/Grupo/Agregado” y PRODID “-/Wtask.org//ICS 1.0//ES”; eventos de día completo; ETag/304 y Cache-Control; actualización de last_used_at solo en 200. - Commit relevante: 234053c. ## Estado actual (2025-11-10) - Fase 1 — Diagnóstico asistido: Completada. - Fase 2 — Plan de refactor por lotes: En curso. - Lote 0 — Infra de typecheck: Completado. - Lote 1 — Utilidades de fecha/hora y validaciones: Completado. - Lote 2 — Helpers de test y cripto: Completado. - Lote 3 — Tipos y endurecimiento suave: Completado. - Lote 4 — ICS central y rutas homogéneas: Completado. - Lote 5 — Svelte: dividir componentes grandes: Pendiente. - Lote 6 — DB Locator / DI ligera: Pendiente. - Lote 7 — Cobertura en módulos flojos: Pendiente. ## Fase 2 — Plan de refactor por lotes (PRs pequeñas y seguras) Cada lote incluye objetivo, cambios, métricas y comprobaciones. Mantener tests verdes en cada paso. ### Lote 0 — Infra de typecheck (preparación) - Completado - Objetivo: - Separar el chequeo de tipos por paquete (core vs web) para aislar errores de SvelteKit/Bun/DOM. - Cambios: - Scripts: `typecheck:core` (tsc -p tsconfig.core.json), `typecheck:web` (apps/web: svelte-kit sync + tsc). - En raíz, excluir apps/web del typecheck general si hace falta hasta que esté sincronizado. - Ajustar lib/types: en core, definir tipos mínimos para HeadersInit/fetch si no se quiere añadir bun-types; en web, asegurar DOM y tipos SvelteKit (via `svelte-kit sync`). - Revisar apps/web/vite.config.ts para que encaje con tipos `UserConfig`. - Métricas: - `bunx tsc --noEmit` limpio por paquete. - Desaparecen errores `$lib` y `./$types` tras `svelte-kit sync`. - Comprobaciones: - `cd apps/web && bunx svelte-kit sync && bunx tsc --noEmit`. ### Lote 1 — Utilidades de fecha/hora y validaciones - Completado - Objetivo: - Centralizar y unificar: SQL-UTC, validadores YMD y HH:mm, utilidades ICS (ymdUTC, addMonthsUTC). - Cambios: - Crear helpers canónicos (por ejemplo, `toIsoSqlUTC`, `isValidYmd`, `normalizeTime`, `ymdUTC`, `addMonthsUTC`) en un módulo compartido (core o shared) y exportarlos también para web si aplica. - Reemplazar todas las ocurrencias del patrón `toISOString().replace(...)`. - Unificar las 3 rutas ICS para usar las mismas utilidades. - Métricas: - `git grep "toISOString().replace('T', ' ').replace('Z', '')"` → 1 referencia (en el helper) o 0 si se encapsula internamente. - `git grep "ymdUTC("` y `"addMonthsUTC("` solo en helpers + imports. - Comprobaciones: - Tests ICS y API siguen verdes. ### Lote 2 — Helpers de test y cripto - Completado - Objetivo: - Eliminar duplicación en tests. - Cambios: - Reemplazar implementaciones locales de `sha256Hex` por import desde `src/utils/crypto`. - Centralizar SimulatedResponseQueue en `tests/helpers/queue.ts` y reusarlo. - Unificar helpers de fechas en tests (`toIsoSql`, `ymdUTC`, `addDays`) en `tests/helpers/dates.ts`. - Métricas: - `git grep -n "async function sha256Hex"` en tests → 0. - `git grep -n "SimulatedResponseQueue"` → 1 implementación única. - Comprobaciones: - `bun test --coverage` estable o mejor. ### Lote 3 — Tipos y endurecimiento suave - Completado - Objetivo: - Bajar ruido de TS con cambios mínimos, sin funcionalidad nueva. - Cambios: - Resolver `undefined` vs `null` en utils como groupColor/whatsapp. - Corregir `HeadersInit`/`fetch` en servicios (group-sync, webhook-manager, contacts) para encajar con tipos. - Añadir refinamientos y cheques donde TS marca “posiblemente undefined”. - Tipar resultados de SQLite `.get()`/`.all()` en tests y servicios. - Métricas: - `bunx tsc --noEmit` limpio en core. - Comprobaciones: - Tests verdes. ### Lote 4 — ICS central y rutas homogéneas - Completado - Objetivo: - Consolidar construcción de ICS (escape, folding, etag) en un módulo central. - Cambios: - Mover `ymdUTC`/`addMonthsUTC` al módulo `apps/web/src/lib/server/ics.ts` y usarlos desde aggregate/group/personal. - Mantener helpers de escape/folding/etag en el mismo módulo. - Métricas: - `git grep -n "function ymdUTC"` y `"function addMonthsUTC"` solo en ics.ts. - Comprobaciones: - Tests ICS (`tests/web/ics.*`) verdes. ### Lote 5 — Svelte: dividir componentes grandes - Objetivo: - Reducir complejidad de UI; mejorar mantenibilidad. - Cambios: - Dividir `TaskItem.svelte` (~911 LOC) en subcomponentes: Header/Status, Assignees, DueBadge, Actions, Metadata, etc. - Revisar `AppShell` y `/app/+page` para separar lógica de datos y presentación (stores y load). - Métricas: - `TaskItem.svelte` < 300 LOC. - Comprobaciones: - Pruebas E2E web verdes. ### Lote 6 — DB Locator / DI ligera - Objetivo: - Simplificar inyección de DB en runtime y tests. - Cambios: - Crear un “dbLocator” (getDb/setDb) central y migrar servicios a usarlo progresivamente, manteniendo compatibilidad con propiedades estáticas mientras dura la transición. - Unificar `resolveDbAbsolutePath` entre core y web (una sola fuente). - Métricas: - Sin cambios de comportamiento; tests de servicios verdes. ### Lote 7 — Cobertura en módulos flojos - Objetivo: - Aumentar cobertura en módulos con lógica y baja cobertura (webhook-manager, maintenance, contacts, onboarding, response-queue). - Cambios: - Añadir pruebas de ramas de error y caminos menos transitados. - Métricas: - Cobertura de líneas > 80% en esos módulos. ## Convenciones acordadas - Fechas/horas: - Persistir en UTC en SQLite con formato ISO-SQL “YYYY-MM-DD HH:MM:SS[.SSS]”. - Un solo helper para serializar/deserializar timestamps. - Validadores canónicos: YMD (YYYY-MM-DD), HH:mm (00–23:00–59). - Tipado: - TS estricto por módulos de forma incremental: `strict`, `noImplicitAny`, `noUncheckedIndexedAccess`, `exactOptionalPropertyTypes` (activación progresiva). - Resultados SQLite tipados (interfaces pequeñas y casts controlados). - Organización: - Helpers compartidos (fecha/validaciones/cripto) en módulo único (o shared). - Tests reusan helpers de `tests/helpers`. - SvelteKit: - `svelte-kit sync` antes de `tsc` para generar tipos. - Rutas ICS homogéneas con helpers de `lib/server/ics`. ## Riesgos y mitigación - Fechas/UTC: posibles regresiones en límites y recordatorios. - Mitigación: snapshots/fixtures antes/después de serializaciones, comparar salidas ICS. - DI de DB: transición puede generar inconsistencias si se mezcla estático/locator. - Mitigación: migración gradual y adaptador de compatibilidad temporal. - Tipado estricto: ruido inicial. - Mitigación: endurecer flags por paquete/módulo en varias PRs pequeñas. ## Métricas de aceptación por lote - Tests verdes y sin cambios funcionales. - Reducción de duplicados medible (git grep antes/después). - `bunx tsc --noEmit` limpio en el ámbito del lote. - Cobertura estable o en subida en módulos afectados. ## Siguientes pasos prácticos 1) Estabilizar typecheck (Lote 0): **Completado**. 2) Unificar fechas/validaciones (Lote 1): **Completado**. 3) Centralizar helpers de tests y cripto (Lote 2): **Completado**. 4) Endurecer tipos en core (Lote 3): **Completado**. 5) Consolidar ICS (Lote 4): **Completado**. 6) Dividir TaskItem y revisar AppShell (Lote 5): **Siguiente**. 7) DI ligera para DB (Lote 6). 8) Aumentar cobertura en módulos flojos (Lote 7). ## Información adicional a recopilar (para Lote 0) - tsconfig.json (raíz) - apps/web/tsconfig.json - apps/web/vite.config.ts Con estos 3 archivos podremos definir cambios mínimos para tener un typecheck limpio por paquetes sin introducir dependencias externas.