Files
hackathon-opti-1a67c9077937…/backend/src/domain/use-cases/addresses/set-my-address.use-case.ts
Diego Mireles 59fcad643a feat(backend): tracking simulator, RBAC status, feedback & addresses
- 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
2026-05-23 02:33:54 -06:00

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,
};
}
}