Files
sf-sim/packages/sim-entrada-eventos/aplication/Order.controller.ts

137 lines
3.9 KiB
TypeScript

import { BodyValidator } from "sim-shared/aplication/BodyValidator.js"
import { OrderUsecases } from "./Order.usecases.js"
import { Request, Response } from "express"
import { idValidator, uuidValidator } from "./httpValidators.js"
import { PaginationArgs } from "sim-shared/domain/PaginationArgs.js"
export class OrderController {
private orderUseCases: OrderUsecases
constructor(args: {
orderUseCases: OrderUsecases
}) {
this.orderUseCases = args.orderUseCases
}
public getById() {
return this.controllerGenerator<{ id: number }, { id: number }>({
validator: idValidator,
useCase: this.orderUseCases.getById(),
onError: (data, error) => { console.error(error) },
onSuccess: (data) => console.log(data)
})
}
public getPending() {
return this.controllerGenerator<PaginationArgs, PaginationArgs>({
validator: undefined,
useCase: this.orderUseCases.getPending(),
onError: (data, error) => { console.error(error) },
onSuccess: (data) => console.log(data)
})
}
public getByQueueId() {
return this.controllerGenerator<{ uuid: string }, { correlation_id: string }>({
validator: uuidValidator,
mapBody: (e) => ({ correlation_id: e.uuid }),
useCase: this.orderUseCases.getByQueueId(),
onError: (data, error) => { console.error(error) },
onSuccess: (data) => console.log(data)
})
}
public getByQuery() {
return this.controllerGenerator({
validator: undefined,
useCase: this.orderUseCases.getByQuery(),
onError: (data, error) => { console.error(error) },
onSuccess: (data) => console.log(data)
})
}
/**
* TODO:
* - En proceso de validacion, tiene varios problemas
* - Está copiado, planteado inyectarlo
* - Map para la respuesta?
*
* Abstrae el proceso de
* Peticion -> validacion del body -> map del body -> useCase -> OK/ERR
*
* <O> Representa el dato original
* <P> Representa el dato después del mapeo
*/
public controllerGenerator<O extends object, P extends object>(args: {
validator?: BodyValidator<O>,
mapBody?: (body: O) => P,
useCase: (args: P) => Promise<any>,
onError: (args: O | P, error: string) => void,
onSuccess: (args: P) => void,
}) {
return async (req: Request, res: Response) => {
//scketchy
const body = { ...req.body, ...req.params }
// 1. Validacion del body
try {
if (args.validator != undefined)
args.validator.validate(body)
} catch (e) {
if (args.onError != undefined) args.onError(body, e as string)
res.status(422).json({
errors: {
msg: e
}
})
}
// 2. Transformacion del body O => P
let data: P = body;
try {
if (args.mapBody != undefined)
data = args.mapBody(body)
} catch (e) {
res.status(422).json({
errors: {
msg: "Error parseando el body: " + e
}
})
}
// 3. Aplicacion del UseCase
try {
const usecaseResult = await args.useCase(data)
// 4.1 Se devuelve el caso de exito pero no encontrado
if (usecaseResult.data == undefined && usecaseResult.error == undefined) {
res.status(404).json(usecaseResult).send()
args.onSuccess(data)
return;
}
// 4.2 Caso de error controlado desde el caso de uso
if (usecaseResult.error != undefined) {
res.status(500).json(usecaseResult).send()
return;
}
// 4.2 Se devuelve al usuario el caso de exito de encontrado
res.status(200).json(
usecaseResult
).send()
args.onSuccess(data)
} catch (err) {
// 4.3 Error del caso de uso
res.status(500).json({
errors: {
msg: "Error general:" + err
}
}).send()
return;
}
}
}
}