12 KiB
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. normalizeTimeduplicado en API y page.server.ymdUTCyaddMonthsUTCdefinidas 3 veces en rutas ICS y también en tests.sha256Hexreimplementado en múltiples tests pese a existir ensrc/utils/crypto.ts.- SimulatedResponseQueue replicado en varios tests.
- Formateo SQL-UTC con
-
Tipado/infra:
- tsc falla en apps/web por
$liby./$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).
- tsc falla en apps/web por
-
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:
git ls-files '*.ts' '*.tsx' '*.svelte' | xargs wc -l | sort -nr | head -n 30
git grep -n "toISOString().replace('T', ' ').replace('Z', '')"
git grep -n "normalizeTime(" && git grep -n "ymdUTC(" && git grep -n "addMonthsUTC(" && git grep -n "isValidYmd("
git grep -n "sha256Hex(" && git grep -n "SimulatedResponseQueue"
bunx tsc --noEmit --pretty false
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.
- Documento creado y versionado (commit
- 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:coreytypecheck:webconfigurados y verificados. Se utilizatsconfig.core.jsonpara aislar el typecheck del core con reglas laxas, mientras que la web usa su propia configuración de SvelteKit. Los shims ensrc/types/shims.d.tsresuelven conflictos de tipos entre Bun y el DOM. - Verificación exitosa:
bun run typecheck:coreybun run typecheck:webse ejecutan sin errores.
- Lote 0 completado: scripts
- 2025-11-09:
- 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. - Lote 5 completado: división de TaskItem en subcomponentes (SVGs a iconos, TaskDueBadge, TaskAssignees, TaskCompleteButton, TaskActions, TaskText, TaskMeta); sin cambios funcionales; tests verdes y typecheck web limpio.
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: Completado.
- 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.
- Scripts:
- Métricas:
bunx tsc --noEmitlimpio por paquete.- Desaparecen errores
$liby./$typestrassvelte-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.
- Crear helpers canónicos (por ejemplo,
- 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
sha256Hexpor import desdesrc/utils/crypto. - Centralizar SimulatedResponseQueue en
tests/helpers/queue.tsy reusarlo. - Unificar helpers de fechas en tests (
toIsoSql,ymdUTC,addDays) entests/helpers/dates.ts.
- Reemplazar implementaciones locales de
- Métricas:
git grep -n "async function sha256Hex"en tests → 0.git grep -n "SimulatedResponseQueue"→ 1 implementación única.
- Comprobaciones:
bun test --coverageestable o mejor.
Lote 3 — Tipos y endurecimiento suave - Completado
- Objetivo:
- Bajar ruido de TS con cambios mínimos, sin funcionalidad nueva.
- Cambios:
- Resolver
undefinedvsnullen utils como groupColor/whatsapp. - Corregir
HeadersInit/fetchen 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.
- Resolver
- Métricas:
bunx tsc --noEmitlimpio 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/addMonthsUTCal móduloapps/web/src/lib/server/ics.tsy usarlos desde aggregate/group/personal. - Mantener helpers de escape/folding/etag en el mismo módulo.
- Mover
- Métricas:
git grep -n "function ymdUTC"y"function addMonthsUTC"solo en ics.ts.
- Comprobaciones:
- Tests ICS (
tests/web/ics.*) verdes.
- Tests ICS (
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
AppShelly/app/+pagepara separar lógica de datos y presentación (stores y load).
- Dividir
- 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
resolveDbAbsolutePathentre 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).
- TS estricto por módulos de forma incremental:
-
Organización:
- Helpers compartidos (fecha/validaciones/cripto) en módulo único (o shared).
- Tests reusan helpers de
tests/helpers.
-
SvelteKit:
svelte-kit syncantes detscpara 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 --noEmitlimpio en el ámbito del lote.- Cobertura estable o en subida en módulos afectados.
Siguientes pasos prácticos
- Estabilizar typecheck (Lote 0): Completado.
- Unificar fechas/validaciones (Lote 1): Completado.
- Centralizar helpers de tests y cripto (Lote 2): Completado.
- Endurecer tipos en core (Lote 3): Completado.
- Consolidar ICS (Lote 4): Completado.
- Dividir TaskItem y revisar AppShell (Lote 5): Completado.
- DI ligera para DB (Lote 6).
- 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.