- Add automatic route simulator (30s tick) that advances trucks and dispatches notifications without needing client-driven pull - Add GET /api/tracking/status protected by JWT for tunnel-view (each user only sees their own route + own inbox) - Add POST /api/tracking/reset-demo to wipe in-memory state without restarting the server (useful for repeated demos) - Add feedback module (POST /api/feedback, GET /api/feedback/me) with 4 feedback types and optional rating - Add addresses module: GET /colonias, GET/PUT /me with colonia validation against the catalog (rejects unknown colonias) - Add in-memory repos for route-state and notification inbox - Auto-register new users in the service mock with default route on register/login so they receive notifications immediately
55 lines
1.5 KiB
TypeScript
55 lines
1.5 KiB
TypeScript
/**
|
|
* set-my-address.use-case.ts
|
|
* Asigna una colonia al usuario logueado. Valida que la colonia exista
|
|
* en el catálogo y resuelve el routeId asociado.
|
|
*
|
|
* Cumple "validación de domicilio dentro de zona permitida" del reto:
|
|
* si la colonia no está en el catálogo, no se acepta.
|
|
*/
|
|
|
|
import { SetAddressDtoValidator } from "../../dtos/index.js";
|
|
import { CustomError } from "../../errors/custom.error.js";
|
|
import { colonias } from "../../../data/mocks/colonias.mock.js";
|
|
import { upsertUser, users } from "../../../data/mocks/users.mock.js";
|
|
|
|
export interface SetMyAddressResponse {
|
|
colonia: string;
|
|
routeId: string;
|
|
horarioEstimado: string;
|
|
}
|
|
|
|
export class SetMyAddressUseCase {
|
|
execute(
|
|
userId: number,
|
|
userName: string,
|
|
userEmail: string,
|
|
data: unknown,
|
|
): SetMyAddressResponse {
|
|
const dto = SetAddressDtoValidator.validate(data);
|
|
|
|
const match = colonias.find(
|
|
(c) => c.colonia.toLowerCase() === dto.colonia.toLowerCase(),
|
|
);
|
|
if (!match) {
|
|
throw CustomError.badRequest(
|
|
`La colonia "${dto.colonia}" no está dentro de la zona de cobertura`,
|
|
);
|
|
}
|
|
|
|
const existing = users.find((u) => u.id === userId);
|
|
upsertUser({
|
|
id: userId,
|
|
name: existing?.name ?? userName,
|
|
email: existing?.email ?? userEmail,
|
|
colonia: match.colonia,
|
|
routeId: match.routeId,
|
|
});
|
|
|
|
return {
|
|
colonia: match.colonia,
|
|
routeId: match.routeId,
|
|
horarioEstimado: match.horarioEstimado,
|
|
};
|
|
}
|
|
}
|