feat: implement route assignment management and sequencing module with interactive data visualization and editing capabilities

This commit is contained in:
2026-08-31 17:56:33 -04:00
parent cd5c57c5ee
commit 9f42175afc
29 changed files with 458 additions and 218 deletions
@@ -1,3 +1,2 @@
export * from './pdv.schema';
export * from './usuario.schema';
export * from './params.schema';
@@ -1,11 +0,0 @@
import { z } from 'zod';
export const paramsSchema = z.object({
radioKm: z.union([z.literal(30), z.literal(50), z.literal(80)]),
velocidad: z.number().min(15).max(80),
});
export type Params = z.infer<typeof paramsSchema>;
// Urbano denso Santo Domingo: 22-28 km/h es más realista que 46 (autopista).
// P2-A default 28; 46 sigue disponible como "Mixto rápido" pero ya no default.
export const DEFAULT_PARAMS: Params = { radioKm: 50, velocidad: 28 };
@@ -17,8 +17,6 @@ export const PDV_NORMALIZED_REQUIRED = [
'segmentacion',
'latitud',
'longitud',
'visitas_semanales',
'duracion_visitahoras',
'prioridad',
] as const;
@@ -32,9 +30,19 @@ export const pdvRowSchema = z.object({
}),
latitud: z.number().min(-90, 'Latitud mínima -90').max(90, 'Latitud máxima 90'),
longitud: z.number().min(-180, 'Longitud mínima -180').max(180, 'Longitud máxima 180'),
visitas_semanales: z.number().int('Visitas semanales debe ser entero').min(1, 'Visitas semanales mínimo 1').max(7, 'Visitas semanales máximo 7'),
duracion_visitahoras: z.number().min(0.01, 'Duración visita debe ser >0').max(24, 'Duración visita máximo 24'),
visitas_semanales: z.number().int('Visitas semanales debe ser entero').min(1, 'Visitas semanales mínimo 1').max(7, 'Visitas semanales máximo 7').optional(),
duracion_visitahoras: z.number().min(0.01, 'Duración visita debe ser >0').max(168, 'Duración visita máximo 168').optional(),
minimo_horas_semana: z.number().min(0.01, 'Mínimo horas semana debe ser >0').max(168, 'Mínimo horas semana máximo 168').optional(),
prioridad: z.number().int('Prioridad debe ser entero').min(1, 'Prioridad mínimo 1').max(5, 'Prioridad máximo 5'),
}).superRefine((data, ctx) => {
const hasVisitsFormat = data.visitas_semanales !== undefined && data.duracion_visitahoras !== undefined;
if (!hasVisitsFormat && data.minimo_horas_semana === undefined) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ['minimo_horas_semana'],
message: 'Incluye Mínimo horas semana o Visitas semanales + Duración visita(horas)'
});
}
});
export type PdvRow = z.infer<typeof pdvRowSchema>;