diff --git a/docs/learnings_para_rumbo.md b/docs/learnings_para_rumbo.md new file mode 100644 index 0000000..4d2be71 --- /dev/null +++ b/docs/learnings_para_rumbo.md @@ -0,0 +1,258 @@ +# Alpha → RUMBO — Decisiones y Aprendizajes + +> Documento vivo. Cada patrón, utilidad y decisión de Alpha que se reutilizará en RUMBO. +> K-20: Documentar learnings → feed a RUMBO. + +**Actualizado**: 2026-05-26 + +--- + +## 1. Utilidades TypeScript + +### 1.1 Limpieza de HTML (`clean-html.ts`) + +**Problema**: KAPPA devuelve descripciones con HTML inline (`

`, ``, ``). RUMBO recibirá contenido similar de múltiples fuentes (actas .docx, correos, web). + +**Solución**: +```typescript +// src/services/clean-html.ts +export function stripHtml(html: string): string { + return html + .replace(/<[^>]*>/g, '') // eliminar tags + .replace(/ /g, ' ') // entidades HTML + .replace(/&/g, '&') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/"/g, '"') + .replace(/'/g, "'") + .replace(/\s+/g, ' ') // normalizar espacios + .trim() +} +``` + +**Dónde usarlo en RUMBO**: +- Pipeline de ingesta: después de parsear .docx, .html, o APIs que devuelvan HTML +- Antes de enviar texto a la IA (DeepSeek) para ahorrar tokens +- Antes de guardar en SQLite/Turso + +**Alternativas evaluadas**: DOMParser (requiere DOM, no disponible en Node/SSR), cheerio (dependencia extra). Regex simple es suficiente para el 95% de los casos. + +--- + +### 1.2 Puente Tauri ↔ Frontend (`tauri-db.ts`) + +**Problema**: `invoke()` de Tauri es tipado como `Promise`. Sin tipos, cada llamada requiere casting manual. + +**Solución**: Un archivo de servicio que envuelve todos los comandos Tauri con tipos explícitos: + +```typescript +export const tauriDb = { + getUsers(): Promise { + return invoke('get_users') + }, + saveUser(user: AlphaUserRecord): Promise { + return invoke('save_user', { user }) + }, + // ... todos los comandos tipados +} +``` + +**Por qué sirve para RUMBO**: +- Mismo patrón con los comandos de transcripción, documentos, etc. +- Un solo archivo = una sola fuente de verdad de la API Rust↔TS +- Facilita el autocompletado en el IDE + +--- + +### 1.3 Store Pattern (Pinia + sync bidireccional) + +**Problema**: Datos vienen de KAPPA (remoto) pero se extienden localmente (Turso). Hay que mergear ambas fuentes. + +**Solución en `users.ts`**: +```typescript +async function fetchAll() { + const [rawUsers, page1, localUsers, localCells] = await Promise.all([ + kappa.getUsers(), // remoto + kappa.getEmployees(1), // remoto + tauriDb.getUsers(), // local (Turso) + tauriDb.getCells(), // local (Turso) + ]) + + const localMap = new Map(localUsers.map(u => [u.id, u])) + users.value = buildUsers(rawUsers, employees.value, localMap) + + syncUsersToTurso(users.value) // persistir merge +} +``` + +**Patrón**: Fetch remoto + fetch local → merge (local pisa remoto para campos extendidos) → sync inverso. + +**Para RUMBO**: Mismo patrón con: +- KAPPA API (remoto) + SQLite (local) para HUs +- OpenRouter (remoto) + caché local para respuestas IA +- Archivos locales + metadatos en SQLite + +--- + +### 1.4 AG Grid + Tema Shadcn + +**Problema**: Necesitábamos una tabla potente (filtros, ordenamiento, paginación) pero con el estilo visual de shadcn-vue. + +**Solución**: AG Grid Community + archivo CSS que mapea variables shadcn: + +```css +/* src/assets/ag-grid-alpha.css */ +.ag-theme-alpha-shadcn { + --ag-background-color: var(--card); + --ag-header-background-color: var(--muted); + --ag-border-color: var(--border); + --ag-row-hover-color: var(--accent); + --ag-font-family: var(--font-sans); + /* ... */ +} +``` + +**Importante**: En Vite, importar AG Grid CSS directamente en `main.ts` (no con `@import` en CSS), porque Vite procesa mejor los imports JS: + +```typescript +// main.ts +import 'ag-grid-community/styles/ag-grid.css' +import './assets/ag-grid-alpha.css' +``` + +**Para RUMBO**: Usar AG Grid para tablas de HUs, Work Items, métricas. El tema se reutiliza cambiando solo el nombre de clase. + +--- + +### 1.5 SVG Logo Inline vs `` + +**Problema**: El SVG del logo de Alpha se veía negro en tema oscuro. `` no permite `currentColor`. + +**Intentos**: +1. `` — no funcionó en todos los casos +2. Componente Vue inline con `fill="currentColor"` — funcionó pero era complejo +3. Al final, `` fue suficiente una vez corregido el path + +**Lección**: Para SVGs simples, `` con `dark:invert` basta. Para SVGs que necesitan heredar color del tema, crear componente Vue con el SVG inline usando `fill="currentColor"`. + +--- + +## 2. Decisiones de Arquitectura + +### 2.1 SQLite local-first con sync a remoto + +| Fuente | Dirección | Frecuencia | +|--------|-----------|------------| +| KAPPA → Turso | Pull | On-demand (al abrir vista) | +| KAPPA ← Turso | Push | Solo campos locales (rol, célula) | +| Turso ↔ UI | Bidireccional | En tiempo real (reactivo) | + +**Para RUMBO**: Mismo modelo. La fuente de verdad es el archivo local. KAPPA es solo un espejo para compartir datos entre máquinas. + +### 2.2 Limpieza de datos en el frontend + +**Decisión**: Limpiar HTML en TypeScript (no en Rust). + +**Razón**: +- Las APIs externas (KAPPA) se consumen desde TS vía `fetch()` +- La limpieza es transformación de presentación, no de negocio +- Rust solo recibe datos ya limpios para persistir + +**Para RUMBO**: Limpiar en el pipeline de ingesta (TypeScript), antes de pasar a Rust para transcripción o a OpenRouter para análisis. + +### 2.3 Tablas separadas vs JSON embebido + +**Decisión**: Usar tablas relacionales para usuarios, células, proyectos. No JSON embebido. + +**Razón**: +- SQLite soporta JOINs eficientes +- Los datos deben ser consultables desde DBeaver/externos +- Facilita reportes y métricas (SQL directo) + +**Para RUMBO**: Mantener schema relacional. No caer en "guardar todo como JSON" por comodidad. + +--- + +## 3. Patrones de UI + +### 3.1 Card con degradado sutil + +```html + +``` + +Degradado en modo claro, color sólido en oscuro. Tomado del bloque `dashboard-01` de shadcn. + +### 3.2 Layout de vista: Stats → Cards → Tabla + +``` +┌─ Header (título + badge) ──────────┐ +├─ Stats (tarjetas por categoría) ───┤ +├─ Cards (vista principal) ──────────┤ +└─ AG Grid (tabla completa) ─────────┘ +``` + +Aplicado en UsersView. Reutilizable para HUs, proyectos, documentos. + +### 3.3 Badges de rol por color + +```typescript +const badgeColors: Record = { + BA: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400', + DEV: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400', + PM: 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400', + // ... +} +``` + +**Para RUMBO**: Mismo patrón para estados de HU (backlog, in progress, done), prioridades, tipos de work item. + +--- + +## 4. Lecciones aprendidas + +### 4.1 Rust warnings no son errores + +Los warnings de Rust (variables no usadas, structs sin construir) no impiden que la app compile y ejecute. Solo indican código que puede limpiarse. + +### 4.2 DBeaver + SQLite con espacios en path + +macOS con home en volumen externo produce paths con espacios. DBeaver requiere path sin espacios. Solución: symlink a `/tmp/`. + +### 4.3 AG Grid en Vite + +El CSS de AG Grid debe importarse en `main.ts` (JS import), no con `@import` en CSS. La razón es que Vite resuelve mejor los módulos JS que los `@import` de node_modules. + +### 4.4 iCloud sync no es git + +Los archivos en iCloud se sincronizan automáticamente, pero `node_modules/` y `src-tauri/target/` deben estar en `.gitignore`. Cada máquina necesita `bun install` y `cargo build` propios. + +--- + +## 5. Lo que NO funcionó + +| Intento | Resultado | Alternativa | +|---------|-----------|-------------| +| DOMParser para limpiar HTML | Requiere DOM, error en SSR | Regex simple (`stripHtml`) | +| `@import` de AG Grid en CSS | Vite no lo resolvió | `import` en `main.ts` | +| `sharp` con Bun | Error de binario nativo | Python PIL (ya instalado) | +| Pasar SVG como componente | Complejo, muchos paths | `` con `dark:invert` | +| Driver LibSQL en DBeaver | Pide token (es para Cloud) | Driver SQLite clásico | + +--- + +## 6. Checklist para RUMBO + +Cosas que ya están resueltas en Alpha y RUMBO debe heredar: + +- [ ] Utilidad `stripHtml()` (`clean-html.ts`) +- [ ] Patrón `tauri-db.ts` (puente tipado Rust↔TS) +- [ ] Tema AG Grid + shadcn (`ag-grid-alpha.css` → `ag-grid-rumbo.css`) +- [ ] Store pattern con merge remoto + local +- [ ] Schema SQLite relacional (no JSON) +- [ ] Card con degradado sutil +- [ ] Badges de estado/rol por color +- [ ] Layout Stats → Cards → Tabla +- [ ] Import AG Grid CSS en `main.ts` +- [ ] SVG logo con `dark:invert` +- [ ] Documentación de métricas PMI (`metricas_pmi.md`)