Fix: mapeo employee_id→user_id + status_name de KAPPA + filtro asignado solo desarrolladores asignados

- KappaUserStory: status_name, status/priority aceptan number
- parseAssignedUser: separa employee_id (asignado_a) de user_id (assigned_to)
  employee_id se guarda negativo en Turso para distinguirlo
- enrichHU: usa status_name de KAPPA directo, fallback a resolveStatusName
- DashboardView: resolveEmployeeToUser() busca employee→user via employees store
- assignedName: muestra nombre real desde employee→user, fallback asignado_a_names
- Filtros: placeholder Estado/Prioridad/Asignado en vez de Todos
- assignedUsers: filtro solo muestra desarrolladores asignados a HUs del proyecto
This commit is contained in:
2026-05-29 03:15:33 -05:00
parent dc210ebd36
commit c8228b315d
4 changed files with 97 additions and 45 deletions
+25 -14
View File
@@ -18,6 +18,7 @@ export interface EnrichedUserStory extends KappaUserStory {
_assignedUserId: number | null
_assignedName: string
_statusName: string
_assignedEmployeeId: number | null
}
export interface EnrichedEpic extends KappaEpicDevelopment {
@@ -63,29 +64,36 @@ export const useWorkItemsStore = defineStore('workitems', () => {
}
}
function parseAssignedUser(hu: any): { id: number | null; name: string } {
// Intenta múltiples formatos que KAPPA puede devolver
if (hu.assigned_to != null && hu.assigned_to !== '') {
const id = Number(hu.assigned_to)
if (!isNaN(id)) return { id, name: hu.assigned_name || '' }
}
function parseAssignedUser(hu: any): { id: number | null; name: string; employeeId: number | null } {
// 1. asignado_a → EMPLOYEE IDs (ej: [1135]). NO son user_ids.
if (hu.asignado_a != null) {
if (Array.isArray(hu.asignado_a)) {
const first = hu.asignado_a[0]
if (first != null) {
const id = typeof first === 'object' ? Number(first.id) : Number(first)
if (!isNaN(id)) return { id, name: typeof first === 'object' ? first.name || first.full_name || '' : '' }
const employeeId = typeof first === 'object' ? Number(first.id) : Number(first)
if (!isNaN(employeeId)) {
const name = Array.isArray(hu.asignado_a_names) ? (hu.asignado_a_names[0] ?? '') : (hu.asignado_a_names ?? '')
return { id: null, name, employeeId }
}
}
}
}
return { id: null, name: '' }
// 2. assigned_to con valor negativo → employee_id (convención Turso)
if (hu.assigned_to != null && hu.assigned_to !== '') {
const raw = Number(hu.assigned_to)
if (!isNaN(raw)) {
if (raw < 0) return { id: null, name: '', employeeId: Math.abs(raw) }
return { id: raw, name: hu.assigned_name || '', employeeId: null }
}
}
return { id: null, name: '', employeeId: null }
}
function enrichHU(hu: { title?: string; id?: number; status?: string | null; acceptance_criteria?: string | null; criterios_aceptacion?: string | null; assigned_to?: number | null; asignado_a?: number[] | string[] | null; assigned_name?: string }, initiativeId: number): EnrichedUserStory {
function enrichHU(hu: { title?: string; id?: number; status?: string | number | null; status_name?: string | null; acceptance_criteria?: string | null; criterios_aceptacion?: string | null; assigned_to?: number | null; asignado_a?: number[] | string[] | null; asignado_a_names?: string[] | string | null; assigned_name?: string }, initiativeId: number): EnrichedUserStory {
const h = parseHierarchy(hu.title || '')
const rawCriteria = hu.acceptance_criteria || hu.criterios_aceptacion || ''
const criteriaList = rawCriteria ? parseQuillList(rawCriteria) : []
const { id: assignedUserId, name: assignedName } = parseAssignedUser(hu)
const { id: assignedUserId, name: assignedName, employeeId } = parseAssignedUser(hu)
return {
id: hu.id ?? 0,
title: hu.title || '',
@@ -99,7 +107,8 @@ export const useWorkItemsStore = defineStore('workitems', () => {
has_impairment: false,
_assignedUserId: assignedUserId,
_assignedName: assignedName,
_statusName: resolveStatusName(hu.status),
_statusName: hu.status_name || resolveStatusName(hu.status),
_assignedEmployeeId: employeeId,
}
}
@@ -210,7 +219,9 @@ export const useWorkItemsStore = defineStore('workitems', () => {
hasImpairment = impairments.some(p => !p.status)
} catch {}
const { id: assignedUserId } = parseAssignedUser(hu)
const { id: assignedUserId, employeeId } = parseAssignedUser(hu)
// Convención: employee_id se guarda como negativo para distinguirlo de user_id
const assignedTo = employeeId != null ? -employeeId : assignedUserId
await tauriDb.saveUserStory({
id: huId,
@@ -225,7 +236,7 @@ export const useWorkItemsStore = defineStore('workitems', () => {
story_points: hu.story_points ?? null,
estimated_hours: null,
actual_hours: null,
assigned_to: assignedUserId,
assigned_to: assignedTo,
sprint: safeStr(hu.sprint),
has_impairment: hasImpairment,
item_type: null,