Ir al contenido

Calendario y horas

El calendario del workspace combina dos vistas:

  1. Equipo (mensual) — un grid mensual con las tareas programadas del equipo (fechas de inicio y vencimiento), las horas imputadas por día y las métricas de desviación de estimación.
  2. Mi tiempo (personal) — una vista semanal donde cada usuario imputa las horas invertidas en tareas y revisa sus totales diarios/semanales y el resumen de sus tareas.
Cambio Descripción
Task.estimatedHours Float? Estimación en horas de la tarea (una cifra compartida por el equipo)
TimeEntry Cada imputación de horas: hours, date, note, taskId, userId
model TimeEntry {
id String @id @default(cuid())
hours Float
date DateTime @default(now())
note String?
taskId String
userId String
task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId, date])
@@index([taskId])
}

Con la estimación (estimatedHours) y las horas imputadas se calcula, por tarea:

  • invertido = suma de las horas de todos los TimeEntry de la tarea.
  • desviación = invertido − estimación (positivo → se invirtió más de lo estimado).
  • % invertido = invertido / estimación × 100.

La lógica vive en computeTaskMetrics() dentro de server/time-entry/service/time-entry-service.ts (función pura, fácil de testear).

Backend (Clean Architecture: Action → Service → Repository)

Sección titulada «Backend (Clean Architecture: Action → Service → Repository)»
Capa Archivo
Action server/time-entry/actions/time-entry-actions.ts
Service server/time-entry/service/time-entry-service.ts
Repository server/time-entry/repository/time-entry-repository.ts
Action Descripción
getTeamCalendarAction(workspaceId) Tareas con fechas + horas del workspace para el grid mensual
getMyTimeAction(workspaceId) Horas del usuario + resumen de sus tareas con métricas
listLoggableTasksAction(workspaceId) Tareas del workspace para el selector de imputación
logTimeAction(workspaceId, { taskId, hours, date, note }) Imputa horas (valida membresía y que la tarea pertenezca al workspace)
deleteTimeEntryAction(entryId) Elimina una imputación (solo el propietario)

Además, el createTaskAction y updateTaskAction aceptan ahora dueDate, startDate y estimatedHours, visibles en el TaskFormDialog.

Componente Propósito
components/calendar/CalendarGrid.tsx Grid mensual con heatmap de prioridad, chips de tareas y horas por día
components/calendar/DayDetail.tsx Detalle del día: tareas programadas + horas imputadas + métricas
components/calendar/MyTimeView.tsx Vista personal: formulario de imputación, semana y resumen
app/[locale]/workspaces/[workspaceId]/calendar/page.tsx Página con tabs Equipo / Mi tiempo
  • Estimación en horas, una cifra por tarea compartida por el equipo.
  • Imputación manual (formulario), sin timer.
  • Se puede imputar a cualquier tarea del workspace del que eres miembro.
  • Los “eventos” del panel mensual son tareas con dueDate/startDate (no hay un modelo Event aparte).
  • Las fechas se serializan como "YYYY-MM-DD" (componentes UTC) para evitar saltos de día por zona horaria (lib/dates.ts).
Ventana de terminal
cd syncro/apps/web
npx prisma migrate deploy
npx prisma db seed

El seeder asigna fechas/estimaciones a varias tareas de Proyecto Alpha y crea imputaciones demo (solo si no hay ninguna todavía).