You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
taskbot/docs/2025-11-01-plan-refactor-te...

434 lines
24 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 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 250335 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.
- 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.
- Lote 5.5-a completado: ResponseQueue extraído (EvolutionClient, limpieza modular, parseo de metadata); sin cambios funcionales; commits: 1b7420e, 2032712.
- Lote 5.5-c completado: TaskService extraído (display_code, reacción al completar, mapeadores); sin cambios funcionales; LOC actual en src/tasks/service.ts ≈ 621; commits: e3ec820, a72184f.
- Lote 5.5-b completado: GroupSyncService modularizado (api.ts, repo.ts, cache.ts, reconcile.ts) y desacople de Onboarding A3 (publishGroupCoveragePrompt); umbral aplicado; tests y typecheck limpios; commits: 1b0d2ec, 0ce3ecb, 2f24806.
- Lote 5.5-d completado: WebhookServer modularizado (/metrics, /health y bootstrap a src/http; handleMessageUpsert extraído a src/http/webhook-handler.ts); sin cambios funcionales; tests verdes; commits: 46bec52, 7189756, e430fc1.
- Lote 6.0-6.2 completados: DB Locator mínimo, conexión en bootstrap con setDb y ruta única de DB (centralización y reexport en web); sin cambios funcionales; tests y typecheck limpios; commits: 9222242, 6196dba, 2669d42.
- Lote 6.3 completado: adopción piloto con fallback en ResponseQueue y TaskService; añadido smoke test de fallback (tests/unit/locator.fallback.test.ts); tests y typecheck limpios; commit relevante: 77ad9d7.
- Lote 6.4 completado: adopción progresiva de servicios al locator (fallback parámetro → .dbInstance → getDb()) en CommandService, RemindersService, MaintenanceService, AdminService y fachada de GroupSync; tests y typecheck limpios; commits: cd83455, f786ba8.
## 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 5.5 — Refactor de servicios grandes (god classes): Completado.
- Lote 6 — DB Locator / DI ligera: En curso (PRs 6.0, 6.1, 6.2, 6.3 y 6.4 completados).
- 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 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 (Completado; ~621 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) Completado
- 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<string,string>` 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` 600700 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 `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 600700, 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:
- Simplificar inyección de DB en runtime y tests.
- Cambios:
- Crear un dbLocator (getDb/setDb/withDb) 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, con reexport en web para no romper imports).
- Métricas:
- Sin cambios de comportamiento; tests de servicios verdes.
- PRs propuestos y archivos a tocar:
PR 6.0 Locator mínimo (infraestructura, sin usos en servicios) Completado
- Nuevos archivos:
- src/db/locator.ts export { setDb, getDb, withDb }.
- tests/unit/db/locator.test.ts pruebas básicas del locator.
- Cambios en docs:
- Este documento (apartado de Lote 6).
PR 6.1 Conexión en bootstrap (setDb al arrancar) Completado
- Archivos a modificar:
- src/http/bootstrap.ts importar setDb desde src/db/locator y llamarlo en el arranque (cuando se abra la DB).
- src/server.ts si es quien abre la DB, llamar setDb(db) justo después de crearla (o delegar en bootstrap).
- Servicios: sin cambios (compatibilidad total con dbInstance estático).
PR 6.2 Ruta única de DB (centralizar resolveDbAbsolutePath) Completado
- Nuevos archivos:
- src/env/db-path.ts export function resolveDbAbsolutePath(filename = 'tasks.db'): string.
- Archivos a modificar:
- apps/web/src/lib/server/env.ts reexportar desde src/env/db-path.ts para mantener compatibilidad (sin cambios de API pública).
- src/server.ts o src/http/bootstrap.ts actualizar imports a src/env/db-path.
- Comprobaciones esperadas:
- bunx tsc -p tsconfig.core.json --noEmit
- bun test --coverage
PR 6.3 Adopción piloto con fallback (2 servicios) Completado
- Archivos a modificar:
- src/services/response-queue.ts usar (ResponseQueue as any).dbInstance ?? getDb().
- src/tasks/service.ts usar (TaskService as any).dbInstance ?? getDb().
- Tests a ajustar (si aplica):
- tests/unit/services/response-queue.test.ts asegurar setDb(memdb) en beforeAll cuando no se inyecte dbInstance.
- tests/unit/tasks/*.test.ts idem.
- Comprobaciones esperadas:
- bunx tsc -p tsconfig.core.json --noEmit
- bun test --coverage
PR 6.4 Adopción progresiva (resto de servicios principales) Completado
- Archivos a modificar (por tandas pequeñas):
- src/services/group-sync/*.ts (api.ts, repo.ts, cache.ts, reconcile.ts) fallback a getDb().
- src/services/command.ts, src/services/reminders.ts, src/services/maintenance.ts, src/services/admin.ts, src/services/contacts.ts, src/services/webhook-manager.ts fallback a getDb().
- Tests a ajustar según servicio:
- tests/unit/services/**/*.test.ts añadir setDb(memdb) donde no se use dbInstance explícita.
- Comprobaciones esperadas:
- bunx tsc -p tsconfig.core.json --noEmit
- bun test --coverage
PR 6.5 Limpieza opcional (cuando no queden usos de .dbInstance)
- Archivos a modificar:
- Eliminar propiedades estáticas dbInstance de servicios ya migrados.
- Actualizar tests que aún dependan de ellas.
- Nota: no es obligatorio para completar el lote; puede posponerse a una fase de limpieza.
### 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 (0023:0059).
- 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): **Completado**.
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.