erp-construccion/docs/02-definicion-modulos/MAI-002-proyectos-estructura/historias-usuario/US-PROJ-002-transiciones-estado.md

591 lines
23 KiB
Markdown

# US-PROJ-002: Transiciones de Estado de Proyectos
**Épica:** MAI-002 - Proyectos y Estructura de Obra
**Sprint:** Sprint 3
**Story Points:** 5 SP
**Prioridad:** P0 (Crítica)
**Estimación:** 2-3 días
**Versión:** 1.0
**Fecha:** 2025-11-17
---
## Historia de Usuario
**Como** Director de Proyectos
**Quiero** cambiar el estado de un proyecto siguiendo un flujo controlado y validado
**Para** reflejar el avance del ciclo de vida del proyecto y asegurar que solo se realicen transiciones válidas con las condiciones cumplidas
---
## Contexto de Negocio
Los proyectos de construcción pasan por un ciclo de vida bien definido:
```
Licitación → Adjudicado → Ejecución → Entregado → Cerrado
```
Cada transición de estado debe:
- Validarse contra reglas de negocio
- Actualizar fechas automáticamente
- Verificar condiciones previas (checklist)
- Emitir notificaciones a equipo relevante
- Quedar registrada en auditoría (quién, cuándo, por qué)
No se permiten saltos de estado ni regresiones (excepto casos especiales con aprobación).
---
## Criterios de Aceptación
### ✅ AC1: Visualización de Estado Actual y Permitidos
**Dado** que estoy viendo el detalle de un proyecto
**Entonces** debo ver:
- **Badge visual del estado actual** con color distintivo:
- 🟰 Licitación: Gris (#6B7280)
- 🔵 Adjudicado: Azul (#3B82F6)
- 🟢 Ejecución: Verde (#10B981)
- 🟣 Entregado: Púrpura (#8B5CF6)
- ⚫ Cerrado: Gris Oscuro (#374151)
- **Botón "Cambiar Estado"** (solo visible para Director/Admin)
- **Historial de cambios de estado** (timeline):
```
📅 15/11/2025 10:30 - Juan Pérez cambió estado a "Ejecución"
Nota: "Licencias obtenidas, inicia construcción"
📅 10/10/2025 09:15 - María López cambió estado a "Adjudicado"
Nota: "Contrato firmado con INFONAVIT"
```
---
### ✅ AC2: Flujo de Cambio de Estado
**Dado** que soy Director o Admin
**Y** el proyecto está en estado "Adjudicado"
**Cuando** hago clic en "Cambiar Estado"
**Entonces** debo ver un modal con:
```
┌───────────────────────────────────────────────────────────┐
│ Cambiar Estado del Proyecto │
│ PROJ-2025-001 - Fraccionamiento Los Pinos │
├───────────────────────────────────────────────────────────┤
│ │
│ Estado actual: 🔵 Adjudicado │
│ │
│ Nuevo estado: │
│ ⚪ Licitación (no permitido - regresión) │
│ 🔵 Adjudicado (estado actual) │
│ 🟢 Ejecución ✓ PERMITIDO │
│ ⚪ Entregado (no permitido - debe pasar por Ejecución) │
│ ⚪ Cerrado (no permitido - debe pasar por Entregado) │
│ │
│ Seleccionado: 🟢 Ejecución │
│ │
│ ✅ Condiciones para cambiar a Ejecución: │
│ ☑ Licencia de construcción obtenida │
│ ☑ Equipo de proyecto asignado │
│ ☑ Estructura del proyecto creada │
│ ☐ Fecha de inicio actualizada │
│ │
│ Notas del cambio (obligatorio): │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Licencias obtenidas, inicio de construcción │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Actualizar fecha de inicio real: [📅 2025-11-15] │
│ │
│ [Cancelar] [Cambiar Estado] │
└───────────────────────────────────────────────────────────┘
```
**Y** solo debo poder seleccionar estados permitidos según flujo
**Y** debo completar el checklist de condiciones (si aplica)
**Y** debo ingresar nota obligatoria del cambio
---
### ✅ AC3: Validación de Transiciones Permitidas
**Reglas de flujo:**
| Estado Actual | Estados Permitidos | Condiciones |
|---------------|-------------------|-------------|
| Licitación | Adjudicado | - Monto de contrato definido<br>- Cliente asignado |
| Adjudicado | Ejecución | - Licencia de construcción<br>- Equipo asignado<br>- Estructura creada |
| Ejecución | Entregado | - Avance físico >= 95%<br>- Finiquitos firmados<br>- Acta de entrega |
| Entregado | Cerrado | - Garantías verificadas<br>- Documentación completa<br>- Cierre administrativo |
**Dado** que el proyecto está en "Ejecución"
**Cuando** intento cambiar directamente a "Cerrado"
**Entonces** sistema debe:
- Mostrar error: "No se puede cambiar de Ejecución a Cerrado directamente. Debe pasar por Entregado primero"
- No permitir seleccionar estado "Cerrado"
- Resaltar en rojo opciones no permitidas
---
### ✅ AC4: Actualización Automática de Fechas
**Cuando** cambio el estado del proyecto
**Entonces** sistema debe actualizar fechas automáticamente:
| Transición | Campo Actualizado | Valor |
|------------|-------------------|-------|
| Licitación → Adjudicado | `awardDate` | Fecha actual |
| Adjudicado → Ejecución | `actualStartDate` | Fecha seleccionada en modal |
| Ejecución → Entregado | `deliveryDate` | Fecha seleccionada en modal |
| Entregado → Cerrado | `closureDate` | Fecha actual |
**Y** si una fecha ya existe (transición repetida), debe preguntarse:
```
⚠️ Ya existe una fecha de inicio: 2025-06-01
¿Deseas actualizarla a la nueva fecha: 2025-11-15?
[Mantener fecha anterior] [Actualizar fecha]
```
---
### ✅ AC5: Checklist de Condiciones por Transición
**Adjudicado → Ejecución:**
- [ ] Licencia de construcción obtenida
- [ ] Equipo de proyecto asignado (mínimo: 1 Director, 1 Residente)
- [ ] Estructura del proyecto creada (al menos 1 etapa)
- [ ] Presupuesto aprobado (si módulo presupuesto está activo)
**Ejecución → Entregado:**
- [ ] Avance físico global >= 95%
- [ ] Finiquitos firmados
- [ ] Acta de entrega-recepción firmada
- [ ] Bitácora de obra cerrada
- [ ] Planos as-built entregados
**Entregado → Cerrado:**
- [ ] Garantías verificadas y vigentes
- [ ] Documentación legal completa
- [ ] Cierre administrativo aprobado
- [ ] Sin pendientes legales o financieros
- [ ] Archivo de proyecto respaldado
**Cuando** el checklist no está 100% completo
**Entonces** sistema debe mostrar advertencia:
```
⚠️ Advertencia: 1 condición pendiente
No se ha marcado: "Planos as-built entregados"
¿Deseas continuar de todos modos? (requiere aprobación de Admin)
[Regresar a completar] [Continuar (Admin)]
```
**Y** si no soy Admin, no debo poder continuar sin checklist completo
---
### ✅ AC6: Notificaciones de Cambio de Estado
**Cuando** se cambia el estado de un proyecto
**Entonces** sistema debe enviar notificaciones a:
| Destinatarios | Tipo | Ejemplo |
|---------------|------|---------|
| Equipo del proyecto (todos) | Email + In-app | "El proyecto PROJ-2025-001 cambió a estado Ejecución" |
| Director del proyecto | Email | Resumen detallado con próximos pasos |
| Administradores | In-app | Registro de auditoría |
| Cliente (opcional) | Email | Solo en transiciones: Ejecución, Entregado, Cerrado |
**Contenido de notificación:**
```
Asunto: Proyecto PROJ-2025-001 cambió a estado "Ejecución"
Proyecto: Fraccionamiento Los Pinos
Estado anterior: Adjudicado
Estado nuevo: Ejecución
Fecha de cambio: 15/11/2025 10:30
Cambiado por: Juan Pérez (Director)
Notas:
"Licencias obtenidas, inicio de construcción"
Fecha de inicio actualizada: 15/11/2025
Próximos pasos:
- Asignar cuadrillas de construcción
- Iniciar control de avances semanales
- Programar juntas de obra quincenales
[Ver Proyecto en Sistema]
```
---
### ✅ AC7: Historial y Auditoría de Cambios
**Dado** que estoy viendo el detalle de un proyecto
**Cuando** accedo a la pestaña "Historial"
**Entonces** debo ver un timeline completo de cambios de estado:
```
┌─────────────────────────────────────────────────────────────┐
│ Historial de Estados │
├─────────────────────────────────────────────────────────────┤
│ │
│ ● 🟢 Ejecución │
│ 15/11/2025 10:30 - Juan Pérez │
│ "Licencias obtenidas, inicio de construcción" │
│ Actualizado: actualStartDate → 2025-11-15 │
│ │
│ ● 🔵 Adjudicado │
│ 10/10/2025 09:15 - María López │
│ "Contrato firmado con INFONAVIT" │
│ Actualizado: awardDate → 2025-10-10 │
│ │
│ ● 🟰 Licitación │
│ 01/09/2025 14:00 - Sistema │
│ "Proyecto creado" │
│ │
└─────────────────────────────────────────────────────────────┘
```
**Y** cada registro debe incluir:
- Timestamp exacto
- Usuario que realizó el cambio
- Estado anterior y nuevo
- Notas/motivo del cambio
- Campos actualizados automáticamente
---
### ✅ AC8: Permisos por Rol
| Acción | Director | Residente | Ingeniero | Supervisor | Admin |
|--------|----------|-----------|-----------|------------|-------|
| Cambiar estado | ✅ | ❌ | ❌ | ❌ | ✅ |
| Ver historial | ✅ | ✅ | ✅ | ✅ | ✅ |
| Forzar transición sin checklist | ❌ | ❌ | ❌ | ❌ | ✅ (con aprobación) |
| Revertir estado (regresión) | ❌ | ❌ | ❌ | ❌ | ✅ (con justificación) |
**Dado** que soy Residente
**Cuando** intento cambiar el estado de un proyecto
**Entonces** sistema muestra error: "Solo Director y Admin pueden cambiar el estado del proyecto"
**Y** el botón "Cambiar Estado" no debe estar visible
---
## Escenarios de Prueba
### Escenario 1: Transición Exitosa Adjudicado → Ejecución
**Given** proyecto en estado "Adjudicado"
**And** soy Director autenticado
**And** condiciones cumplidas:
- Licencia obtenida ✅
- Equipo asignado ✅
- Estructura creada ✅
**When** hago clic en "Cambiar Estado"
**And** selecciono "Ejecución"
**And** ingreso nota "Inicio de obra"
**And** selecciono fecha inicio: 2025-11-15
**And** hago clic en "Cambiar Estado"
**Then** estado cambia a "Ejecución"
**And** actualStartDate = 2025-11-15
**And** se envían notificaciones a equipo
**And** se registra en historial
---
### Escenario 2: Transición Bloqueada por Falta de Condiciones
**Given** proyecto en estado "Adjudicado"
**And** soy Director
**And** NO hay equipo asignado
**When** intento cambiar a "Ejecución"
**Then** sistema muestra checklist con:
- ☐ Equipo de proyecto asignado (PENDIENTE)
**And** muestra advertencia
**And** botón "Cambiar Estado" está deshabilitado hasta completar
---
### Escenario 3: Intento de Transición Inválida
**Given** proyecto en estado "Ejecución"
**When** intento cambiar directamente a "Cerrado"
**Then** opción "Cerrado" aparece deshabilitada (gris)
**And** tooltip muestra: "Debe pasar por Entregado primero"
**And** no puedo seleccionar "Cerrado"
---
### Escenario 4: Regresión de Estado (Solo Admin)
**Given** proyecto en estado "Ejecución"
**And** soy Admin
**When** solicito revertir a "Adjudicado" (regresión)
**Then** sistema muestra confirmación:
```
⚠️ ADVERTENCIA: Regresión de Estado
Estás a punto de revertir el proyecto de "Ejecución" a "Adjudicado".
Esta es una acción excepcional y quedará registrada en auditoría.
Motivo de regresión (obligatorio):
[_______________________________________________________]
[Cancelar] [Confirmar Regresión]
```
**And** registro queda marcado en auditoría como "REGRESIÓN"
---
### Escenario 5: Notificación de Cambio de Estado
**Given** proyecto "PROJ-2025-001" cambia a "Ejecución"
**When** se completa el cambio de estado
**Then** equipo del proyecto recibe email
**And** notificación in-app aparece en dashboard
**And** cliente recibe email (si configurado)
---
## Mockups / Wireframes
### Modal de Cambio de Estado
```
┌───────────────────────────────────────────────────────────┐
│ Cambiar Estado del Proyecto [✕] │
│ PROJ-2025-001 - Fraccionamiento Los Pinos │
├───────────────────────────────────────────────────────────┤
│ │
│ Estado actual: 🔵 Adjudicado │
│ │
│ Selecciona nuevo estado: │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ ⚪ Licitación [bloqueado]│ │
│ │ ● 🔵 Adjudicado [actual] │ │
│ │ ○ 🟢 Ejecución [permitido] │ │
│ │ ⚪ Entregado [bloqueado]│ │
│ │ ⚪ Cerrado [bloqueado]│ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ✅ Condiciones para Ejecución: │
│ ☑ Licencia de construcción obtenida │
│ ☑ Equipo de proyecto asignado │
│ ☐ Estructura del proyecto creada [PENDIENTE] │
│ │
│ ⚠️ 1 condición pendiente │
│ │
│ Notas del cambio *: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Fecha de inicio real: [📅 __/__/____] │
│ │
│ ☐ Notificar al cliente │
│ │
│ [Cancelar] [Cambiar Estado] │
│ [deshabilitado]│
└───────────────────────────────────────────────────────────┘
```
### Timeline de Historial
```
┌─────────────────────────────────────────────────────────────┐
│ Historial de Estados [Exportar]│
├─────────────────────────────────────────────────────────────┤
│ │
│ ●──────────────────────────────────────────────── │
│ │ │
│ 🟢 Ejecución │
│ 15/11/2025 10:30 │
│ 👤 Juan Pérez (Director) │
│ 📝 "Licencias obtenidas, inicio de construcción" │
│ 🔄 actualStartDate → 2025-11-15 │
│ │ │
│ ●──────────────────────────────────────────────── │
│ │ │
│ 🔵 Adjudicado │
│ 10/10/2025 09:15 │
│ 👤 María López (Admin) │
│ 📝 "Contrato firmado con INFONAVIT" │
│ 🔄 awardDate → 2025-10-10 │
│ │ │
│ ●──────────────────────────────────────────────── │
│ │ │
│ 🟰 Licitación │
│ 01/09/2025 14:00 │
│ 👤 Sistema (Auto) │
│ 📝 "Proyecto creado" │
│ │
└─────────────────────────────────────────────────────────────┘
```
---
## Definición de Done (DoD)
- [ ] Validación de transiciones según flujo implementada (backend)
- [ ] Modal de cambio de estado funcional (frontend)
- [ ] Checklist de condiciones por transición implementado
- [ ] Actualización automática de fechas funcionando
- [ ] Historial de cambios de estado visible y completo
- [ ] Notificaciones enviadas a equipo y cliente
- [ ] Permisos por rol implementados
- [ ] Tests unitarios de validación de transiciones (>80% coverage)
- [ ] Tests de integración para flujo completo de cambio
- [ ] Regresión de estado (solo Admin) implementada con auditoría
- [ ] Documentación de API actualizada (Swagger)
- [ ] Código revisado y aprobado
- [ ] Probado en QA con diferentes escenarios
- [ ] Sin issues de seguridad o performance
---
## Notas Técnicas
### Backend
**Endpoint:**
```typescript
PUT /api/projects/:id/status
Body:
{
"newStatus": "ejecucion",
"notes": "Licencias obtenidas, inicio de construcción",
"actualStartDate": "2025-11-15",
"notifyClient": true,
"checklist": {
"licenseObtained": true,
"teamAssigned": true,
"structureCreated": true
}
}
Response:
{
"id": "uuid",
"status": "ejecucion",
"actualStartDate": "2025-11-15",
"updatedBy": "userId",
"updatedAt": "2025-11-15T10:30:00Z",
"statusHistory": [...]
}
```
**Service Method:**
```typescript
async changeStatus(
id: string,
newStatus: ProjectStatus,
dto: ChangeStatusDto,
userId: string
): Promise<Project> {
const project = await this.findOne(id);
// Validate transition
this.validateStatusTransition(project.status, newStatus);
// Check conditions (if applicable)
await this.validateConditions(project, newStatus, dto.checklist);
// Update status and dates
const oldStatus = project.status;
project.status = newStatus;
this.updateStatusDates(project, newStatus, dto);
// Save and emit event
const updated = await this.projectRepo.save(project);
this.eventEmitter.emit('project.status_changed', {
project: updated,
oldStatus,
newStatus,
changedBy: userId,
notes: dto.notes
});
return updated;
}
```
### Frontend
**Components:**
- `ChangeStatusModal.tsx` - Modal de cambio de estado
- `StatusBadge.tsx` - Badge visual de estado
- `StatusTimeline.tsx` - Timeline de historial
- `StatusChecklist.tsx` - Checklist de condiciones
**State Machine (XState - opcional):**
```typescript
const projectStatusMachine = createMachine({
id: 'projectStatus',
initial: 'licitacion',
states: {
licitacion: {
on: { ADJUDICAR: 'adjudicado' }
},
adjudicado: {
on: { INICIAR_EJECUCION: 'ejecucion' }
},
ejecucion: {
on: { ENTREGAR: 'entregado' }
},
entregado: {
on: { CERRAR: 'cerrado' }
},
cerrado: {
type: 'final'
}
}
});
```
---
## Dependencias
**Depende de:**
- ✅ US-PROJ-001: Catálogo de Proyectos (necesita proyectos existentes)
- ✅ ET-PROJ-001: Especificación técnica de catálogo
**Bloquea a:**
- Ninguna (independiente)
**Relacionado con:**
- US-PROJ-007: Asignación de Equipo (condición para Ejecución)
- US-PROJ-003: Crear Estructura (condición para Ejecución)
---
## Criterios de Aceptación del Product Owner
- [ ] Solo se permiten transiciones válidas según flujo definido
- [ ] Checklist de condiciones se verifica antes de permitir cambio
- [ ] Fechas se actualizan automáticamente según transición
- [ ] Historial completo y auditable de todos los cambios
- [ ] Notificaciones enviadas correctamente a equipo
- [ ] Solo Director y Admin pueden cambiar estados
- [ ] Regresiones solo permitidas para Admin con justificación
- [ ] Modal es intuitivo y muestra claramente opciones permitidas/bloqueadas
---
**Fecha de generación:** 2025-11-17
**Autor:** Equipo de Producto
**Aprobado por:** Product Owner
**Estado:** ✅ Ready for Development