Files
ricardo 19c6fb3153 DashboardView: columna SP + fix priority/story_points perdidos en enrichHU
- enrichHU ahora incluye status, priority y story_points en el return
- Nueva columna SP (story points) entre Título y Estado en tabla HUs
- Filtro prioridad acepta valores numéricos (1/2/3)
2026-05-29 08:41:37 -05:00

7.8 KiB
Raw Permalink Blame History

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)

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

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).