Reglas por confirmar
Decisiones que Royal Clean todavía no ha cerrado, con el supuesto conservador que se tomó.
Estas decisiones afectan a dinero, tiempo o permisos y no las ha confirmado Royal Clean. En cada caso se implementó la opción más conservadora y se dejó el sistema preparado para cambiarla sin reescribir nada.
Nada de esto bloquea el MVP.
Para preguntárselas a Royal Clean hay un correo redactado y listo para enviar en CORREO_CONSULTAS_CLIENTE.md: las mismas diez decisiones, agrupadas por tema y explicadas sin jerga.
1. Política de redondeo de horas
Pregunta. ¿Se paga el tiempo exacto, o se redondea al cuarto de hora, o a la media hora?
Asumido. EXACT — se paga el tiempo exacto.
Cómo está preparado. Configurable desde Configuración con tres opciones.
La función applyRoundingPolicy() centraliza el cálculo y tiene tests para las
tres. Cada PayrollPayment guarda la política con la que se calculó, así que un
recibo antiguo siempre puede explicarse.
Al confirmarse. Cambiar el valor en Configuración. No modifica los pagos ya registrados: su desglose está congelado.
Nota. El redondeo es al múltiplo más cercano, no siempre hacia arriba. Redondear siempre hacia arriba favorecería sistemáticamente a una de las partes, y esa decisión no está tomada.
2. Horas extra
Pregunta. ¿Existe una tarifa distinta a partir de cierto número de horas?
Asumido. No. Todas las horas se pagan a la misma tarifa.
Cómo está preparado. El cálculo pasa por
calculateServiceLaborCost(), que recibe un desglose por empleado y no un total
opaco. Añadir tramos de horas extra es cambiar esa función y sus tests, sin
tocar a ninguno de sus llamadores.
3. Domingos, feriados y nocturnidad
Pregunta. ¿Se paga distinto un domingo, un feriado o un turno nocturno?
Asumido. No hay recargos.
Cómo está preparado. Igual que el punto anterior. Las sesiones de trabajo guardan instantes absolutos, así que la información necesaria para segmentar por franja horaria o por día de la semana ya está registrada: no habría que recuperar datos perdidos.
4. Umbral de sesión demasiado larga
Pregunta. ¿A partir de cuántas horas abierto un servicio debe considerarse un olvido?
Asumido. 6 horas.
Cómo está preparado. Configurable. Al superarse, el servicio se marca con
hasTimeWarning y aparece destacado en el panel. El sistema nunca cierra la
sesión ni inventa una hora de finalización: sólo avisa para que un
administrador lo corrija con su motivo.
5. Visualización en dólares
Pregunta. ¿Con qué precisión y en qué pantallas debe aparecer el equivalente en USD?
Asumido. Aparece junto a los importes principales del panel y de las fichas, con el tipo de cambio que un administrador fija a mano.
Cómo está preparado. El colón es siempre la moneda oficial de cálculo. No se almacena ningún histórico en USD ni se depende de ningún servicio externo de cotización, para no introducir un coste recurrente ni una dependencia que pueda caerse.
6. Política de correo electrónico
Pregunta. ¿Debe el sistema enviar correos, y para qué eventos?
Asumido. No se envía ningún correo. Las notificaciones son internas.
Cómo está preparado. El correo es opcional en usuarios, empleados y
clientes. Las variables RESEND_API_KEY y EMAIL_FROM existen en
.env.example pero no hay integración activa. La aplicación funciona
íntegramente sin correo.
Al confirmarse. Implementar un módulo notifications/email.ts que lea esas
variables y se degrade en silencio si no están configuradas.
7. Registro de insumos por el personal
Pregunta. ¿Puede el personal de campo registrar insumos, o sólo un administrador?
Asumido. Sí puede, pero sus registros quedan en PENDING_REVIEW y no
cuentan en las cifras hasta que un administrador los aprueba.
Cómo está preparado. Interruptor employeesCanLogSupplies en Configuración.
El personal nunca ve costos internos ni márgenes de los insumos.
Al confirmarse. Si se decide que sólo administración registre insumos, basta con desactivar el interruptor.
8. Límites de vídeo
Pregunta. ¿Se admite vídeo como evidencia? ¿De qué duración y tamaño?
Asumido. El modelo de datos lo soporta (Evidence.mediaType = VIDEO) con un
límite conservador de 60 MB, pero la interfaz sólo ofrece fotografías.
Cómo está preparado. Los límites están en
src/modules/evidence/constants.ts. El MVP no transcodifica: el archivo se
guardaría tal cual llega.
Al confirmarse. Habilitar el tipo de archivo en el componente de captura y revisar los límites. Si se necesitan vídeos largos, habría que evaluar transcodificación, que es un proyecto aparte.
9. Retención posterior a los 12 meses
Pregunta. Al expirar la evidencia, ¿debe archivarse en frío en algún sitio o se elimina definitivamente?
Asumido. Se elimina el objeto y la metadata queda marcada como EXPIRED.
El historial del servicio se conserva íntegro: fechas, tareas, horas,
incidentes y cifras siguen ahí.
Cómo está preparado. El plazo es configurable. El trabajo de retención está
en expireOldEvidence(), con tests que comprueban que borra el objeto pero no el
historial.
10. Estrategia de respaldo externo
Pregunta. ¿Con qué frecuencia se respalda, dónde se guarda y quién verifica las restauraciones?
Asumido. Nada automatizado todavía. La estrategia recomendada está documentada en OPERATIONS.md: volcado diario, comprimido, cifrado y copiado fuera de la VPS.
Importante. Un volcado guardado únicamente en la misma VPS no es un respaldo: si se pierde el servidor, se pierde con él.
Cómo tratar estas reglas
Al implementar algo que las toque:
- No inventes una política irreversible.
- Elige el comportamiento conservador.
- Hazlo configurable si es barato.
- Documenta el supuesto aquí y en el código.
- Si afecta a un cálculo, escribe también el test de la política alternativa.