# KAPPA Hub > Asistente multi-proyecto para KAPPA. Semilla de RUMBO. > POC → validación diaria → lo que funciona migra a RUMBO. ## Stack | Capa | Tecnología | Versión | |------|-----------|---------| | Desktop shell | Tauri v2 | 2.11 | | Frontend | Vue 3 + TypeScript + Vite | 3.4 / 5.x | | Runtime JS | Bun | 1.3+ | | Estado | Pinia | 2.1 | | BD local | Turso (libSQL) | Embedded | | HTTP | fetch() directo a KAPPA (proxy Vite en dev) | | Auth | Bearer token (POST /api/users/login/) | | UI | shadcn-vue (New York) + Tailwind CSS v4 | 2.7 | | Tablas | AG Grid Community + tanstack/vue-table | 35.3 | | i18n | vue-i18n (es.json + en.json) — **PROHIBIDO hardcodear texto** | 11.4 | ## Reglas de código 1. **PROHIBIDO hardcodear texto visible al usuario.** Todo texto debe usar `t('clave')` de vue-i18n. Si no existe la clave, agregarla a `es.json` y `en.json`. 2. **KAPPA retorna tipos mixtos**: strings, números y booleanos para el mismo campo (ej: `status` puede ser `"active"`, `true`, o `3`). Siempre usar `String(valor)` o `safeStr()` antes de operar. 3. **No usar `.catch(() => {})`** sin loguear el error. Siempre `console.error()`. 4. **Los nombres de funciones y archivos van en español** cuando son semánticos del dominio (ej: `syncHUsToTurso` → OK, pero labels visibles van en i18n). 5. **Toda función debe tener observabilidad**: loguear entrada con `[Alpha]` + acción + datos clave, loguear errores con `[Alpha]` + descripción + error completo. Sin logs no se puede diagnosticar. 6. **IDs jerárquicos obligatorios en componentes**: todo elemento raíz de sección debe tener `id="{view}-{section}-{element}"` en kebab-case. Ej: `dashboard-stats-epics`, `login-card`, `users-table`. Permite ubicar cualquier componente por su ID sin ambigüedad. ## Sincronización entre máquinas (Mac Mini ↔ MacBook Air) El proyecto vive en iCloud Drive: `com~apple~CloudDocs/AI/Teloprax/02_productos/kappa-hub/`. - **Código**: se sincroniza automáticamente vía iCloud. Solo `bun install` una vez por máquina. - **Datos de KAPPA**: viven en el servidor (kappa.lambdaanalytics.co). El Hub es solo un cliente. - **Token**: localStorage del navegador. Loguearse una vez por máquina. - **Datos locales futuros** (borradores, caché): se guardarán como archivos en `data/` dentro del proyecto, sincronizados vía iCloud. Ver `../rumbo/sincronizacion.md`. ## Calendarios externos (K-21) | Servicio | Auth | Capacidad | |----------|------|-----------| | Google Calendar | OAuth2 | Leer eventos, escribir eventos | | Microsoft Graph (Outlook/Teams) | OAuth2 | Leer eventos, escribir eventos | | iCal (.ics) | Archivo | Importar/exportar | ### Flujo post-reunión (K-22) ``` 1. RUMBO lee calendario (Google/Outlook) 2. Detecta: "Reunión con Cliente X, 8-9am" 3. Después de la reunión (+15/30 min): → 🔔 "Terminó tu reunión con Cliente X" → "¿Ya capturaste las notas?" → "¿Hay transcripción?" → "¿Se extrajeron las tareas?" 4. Si no → RUMBO guía a completar ``` **Analogía**: RUMBO como Apple Watch — te alerta cuando llevas mucho tiempo sentado (reuniones sin seguimiento = deuda de contexto). ### API de recordatorios (futuro) ```typescript interface Reminder { id: string trigger_at: string // ISO datetime title: string body: string action_url?: string // deep link a la vista correspondiente dismissed: boolean source: 'calendar' | 'scheduler' | 'hu_deadline' } ``` ## APIs KAPPA integradas | Endpoint | Método | Uso en el hub | |----------|--------|--------------| | `/users/login/` | POST | Auth | | `/initiatives-all/` | GET | Listar proyectos | | `/users/all/` | GET | Listar usuarios | | `/userstorys/create/` | POST | Crear HU desde transcripción | | `/logbooks_master/create/` | POST | Crear bitácora | | `/logbooks/create/` | POST | Entrada de bitácora | | `/plannings_master/create/` | POST | Crear planeación | | `/plannings/create/` | POST | Entrada de planeación | | `/business-rules/create/` | POST | Reglas de negocio | | `/functionalrequirements/create/` | POST | Requisitos funcionales/no funcionales | ## Estructura ``` kappa-hub/ ├── src/ │ ├── types/kappa.ts # Tipos TypeScript │ ├── services/kappa-api.ts # Cliente HTTP KAPPA │ ├── stores/ # Pinia │ │ ├── auth.ts │ │ ├── projects.ts │ │ └── workitems.ts │ ├── views/ │ │ ├── LoginView.vue │ │ └── DashboardView.vue │ ├── components/layout/ │ │ └── AppShell.vue │ ├── App.vue │ └── main.ts ├── package.json └── vite.config.ts ``` ## Cómo ejecutar ```bash cd "02_productos/kappa-hub" bun install # una vez por máquina bun dev # http://localhost:5173 ``` Abre http://localhost:5173. El proxy de Vite redirige `/api/*` a `https://kappa.lambdaanalytics.co`. ## Pipeline de transcripciones (K-10) ✅ Nueva vista **Transcripciones** en la barra lateral (icono upload). **Flujo:** 1. Configurar API key de OpenRouter (DeepSeek) — se guarda en localStorage 2. Seleccionar proyecto destino desde el dropdown 3. Arrastrar o seleccionar archivo (.docx, .vtt, .txt, .md) 4. El archivo se parsea localmente (mammoth.js para docx, parseo manual para VTT) 5. Click "Analizar con IA" → se envía a OpenRouter DeepSeek 6. La IA devuelve HUs estructuradas (título, descripción, criterios de aceptación, prioridad, tipo) 7. Revisar, seleccionar/deseleccionar, eliminar HUs 8. Click "Crear en KAPPA" → se crean vía API 9. Las HUs creadas se marcan en verde y se refresca el store de workitems **Archivos nuevos:** - `src/services/ai.ts` — Cliente OpenRouter DeepSeek - `src/services/parse-transcription.ts` — Parseo de .docx/.vtt/.txt/.md - `src/stores/transcriptions.ts` — Pinia store del pipeline - `src/views/TranscriptionsView.vue` — Vista completa con upload, preview, análisis, resultados **Modelo usado:** `deepseek/deepseek-chat-v3-0324:free` (free tier de OpenRouter) ## Próximos pasos 1. ~~Agregar Dexie.js para cache offline~~ (K-15) 2. ~~Pipeline de transcripciones~~ (K-10) 3. ⬜ **Dashboard multi-proyecto** (K-11) 4. ⬜ **Priorizador diario** (K-12) 5. ⬜ **Generador de reportes** (K-13) 6. ⬜ **Integración calendario Google/Outlook** (K-21) 7. ⬜ **Alertas post-reunión** (K-22) --- ## Changelog — Decisiones técnicas ### 2026-05-29: Asignación HU + Status desde KAPPA **Asignado (employee_id vs user_id)** - KAPPA devuelve `asignado_a: [1135]` donde 1135 es **employee_id**, no user_id. - Employee 1135 → user 1115 (Felipe Crespo). El mapeo está en `usersStore.employees`. - `parseAssignedUser()` en `stores/workitems.ts` separa: - `asignado_a` → `_assignedEmployeeId` (employee_id) - `assigned_to` → `_assignedUserId` (user_id directo) - `DashboardView.resolveEmployeeToUser()` busca en `usersStore.employees.find(e.id === employeeId)?.user` - Para persistencia en Turso (un solo campo `assigned_to`): employee_id se guarda como **negativo** (`-1135`). `parseAssignedUser()` detecta negativos y los trata como employee_id. **Status** - KAPPA devuelve `status: 6` (número) + `status_name: "QA-Client"`. - `enrichHU()` usa `hu.status_name` primero; fallback a `resolveStatusName(hu.status)`. - `STATUS_MAP` en `services/statuses-db.ts` ahora mapea valores numéricos (`'1'`–`'7'`) y nombres KAPPA. **Prioridad** - KAPPA devuelve `priority: "3"` (string numérico). `PRIORITY_MAP` mapea `"1"`/`"2"`/`"3"` y texto. **UI - Tabla HUs** - Columna Asignado: texto plano (no Select). Muestra nombre real o `asignado_a_names` de KAPPA. - Columna Estado: muestra `status_name` de KAPPA (ej: QA-Client) con badge de color. - Filtros con placeholder "Estado"/"Prioridad"/"Asignado". Filtro Asignado solo lista desarrolladores con HUs. **Dexie (browser)** - Schema v8: nueva tabla `user_stories` con `&id, initiative_id`. - Fallback en `tauri-db.ts` para get/save user_stories (antes solo Tauri).