296 lines
8.4 KiB
TypeScript
296 lines
8.4 KiB
TypeScript
import { Request, Response } from "express"
|
|
import { SimUsecases } from "./Sim.usecases.js"
|
|
import { activationValidator, iccidValidator } from "./httpValidators.js"
|
|
import { companyFromIccid } from "#domain/companies.js"
|
|
import { BodyValidator } from "sim-shared/aplication/BodyValidator.js"
|
|
import { tryCatch } from "sim-shared/domain/Result.js"
|
|
import { mapCompanyService } from "#config/servicesProxy.js"
|
|
import axios, { AxiosError, isAxiosError } from "axios"
|
|
|
|
|
|
export class SimController {
|
|
private simUseCases: SimUsecases
|
|
|
|
constructor(args: {
|
|
simUseCases: SimUsecases,
|
|
}) {
|
|
this.simUseCases = args.simUseCases
|
|
|
|
this.activation = this.activation.bind(this)
|
|
}
|
|
|
|
/**
|
|
* TODO:
|
|
* En proceso, tiene varios problemas
|
|
*
|
|
* 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) => {
|
|
const body = req.body
|
|
// 1. Validacion del body
|
|
if (args.validator != undefined) {
|
|
const validationResult = args.validator.validate(body)
|
|
if (validationResult.error != undefined) {
|
|
res.status(422).json({
|
|
errors: {
|
|
...validationResult.error
|
|
}
|
|
})
|
|
args.onError(body, validationResult.error.msg)
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// 2. Transformacion del body
|
|
// TODO: sustituir el try cach
|
|
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
|
|
}
|
|
})
|
|
args.onError(body, String(e))
|
|
return 1;
|
|
}
|
|
|
|
// 3. Aplicacion del UseCase
|
|
// TODO: todos los use cases tienen que pasar a devolver un Result<>
|
|
const usecaseResult = await args.useCase(data) // no deberia hacer falta el trycatch
|
|
|
|
// 4. Casos de error del usecase
|
|
if (usecaseResult.error != undefined) {
|
|
// 4.1 Error del caso de uso
|
|
res.status(500).json({
|
|
errors: {
|
|
...usecaseResult.error
|
|
}
|
|
}).send()
|
|
args.onError(body, usecaseResult.error ?? "Error indefinido")
|
|
return 1;
|
|
}
|
|
|
|
// 5. Se devuelve al usuario el caso de exito
|
|
res.status(200).json(
|
|
usecaseResult.data
|
|
).send()
|
|
args.onSuccess(usecaseResult.data)
|
|
return 0;
|
|
|
|
}
|
|
}
|
|
|
|
public test() {
|
|
return this.controllerGenerator<{ iccid: string, offer: string }, { iccid: string }>({
|
|
validator: iccidValidator,
|
|
useCase: (args) => this.simUseCases.test(args),
|
|
onError: (data, error) => console.error(error),
|
|
onSuccess: (data) => {
|
|
console.log("OK", data)
|
|
}
|
|
})
|
|
}
|
|
|
|
public preactivation() {
|
|
return this.controllerGenerator<{ iccid: string, offer: string }, { iccid: string, offer: string, compañia: string }>({
|
|
validator: activationValidator,
|
|
mapBody: (b) => {
|
|
const { iccid, offer } = b
|
|
const compañia = companyFromIccid(iccid)
|
|
return { iccid, compañia, offer }
|
|
},
|
|
useCase: (args) => this.simUseCases.preActivation(args),
|
|
onError: (d, e) => console.error("[x] Error preactivation: ", d, e),
|
|
onSuccess: console.log
|
|
})
|
|
}
|
|
|
|
public activation() {
|
|
return this.controllerGenerator<{ iccid: string, offer: string }, { iccid: string, offer: string, compañia: string }>({
|
|
validator: activationValidator,
|
|
mapBody: (b) => {
|
|
const { iccid, offer } = b
|
|
const compañia = companyFromIccid(iccid)
|
|
return { iccid, compañia, offer }
|
|
},
|
|
useCase: (args) => this.simUseCases.activation(args),
|
|
onError: (d, e) => console.error("[x] Error activacion: ", d, e),
|
|
onSuccess: console.log
|
|
})
|
|
}
|
|
|
|
|
|
public reActivation() {
|
|
return this.controllerGenerator<{ iccid: string, offer: string }, { iccid: string, offer: string, compañia: string }>({
|
|
validator: iccidValidator,
|
|
mapBody: (b) => {
|
|
const { iccid, offer } = b
|
|
const compañia = companyFromIccid(iccid)
|
|
return { iccid, compañia, offer }
|
|
},
|
|
useCase: (args) => this.simUseCases.reActivation(args),
|
|
onError: (d, e) => console.error("[x] Error reactivacion: ", d, e),
|
|
onSuccess: console.log
|
|
})
|
|
}
|
|
|
|
public cancelation() {
|
|
return this.controllerGenerator<{ iccid: string }, { iccid: string, compañia: string }>({
|
|
validator: iccidValidator,
|
|
mapBody: (b) => {
|
|
const { iccid } = b
|
|
const compañia = companyFromIccid(iccid)
|
|
return { iccid, compañia }
|
|
},
|
|
useCase: (args) => this.simUseCases.cancelation(args),
|
|
// TODO: Meter en los mensajes el nombre de la operacion
|
|
onError: (d, e) => console.error("[x] Error cancelacion: ", d, e),
|
|
onSuccess: console.log
|
|
})
|
|
}
|
|
|
|
public pause() {
|
|
return this.controllerGenerator<{ iccid: string }, { iccid: string, compañia: string }>({
|
|
validator: iccidValidator,
|
|
mapBody: (b) => {
|
|
const { iccid } = b
|
|
const compañia = companyFromIccid(iccid)
|
|
return { iccid, compañia }
|
|
},
|
|
useCase: (args) => this.simUseCases.pause(args),
|
|
onError: (d, e) => console.error("[x] Error pausa: ", d, e),
|
|
onSuccess: console.log
|
|
})
|
|
|
|
}
|
|
|
|
public free() {
|
|
return async (req: Request, res: Response) => {
|
|
try {
|
|
iccidValidator.validate(req.body)
|
|
} catch (e) {
|
|
res.status(422).json({
|
|
errors: {
|
|
msg: e
|
|
}
|
|
})
|
|
}
|
|
|
|
const { iccid } = req.body
|
|
const compañia = companyFromIccid(iccid)
|
|
|
|
try {
|
|
await this.simUseCases.cancelation({ iccid, compañia })
|
|
res.status(200).json({
|
|
iccid: iccid,
|
|
operation: "liberacion"
|
|
})
|
|
} catch (err) {
|
|
console.error("Error liberando la sim ", req.body)
|
|
res.status(500).json({
|
|
errors: {
|
|
msg: "Error general de liberacion"
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Select no pasa por la cola de eventos al ser de solo lectura.
|
|
* Cada uno de los servicios de los proveedores tiene que aderirse al
|
|
* modelo común de datos de SIM + campo "raw"
|
|
*
|
|
* De momento se va a buscar por iccid, mas adlante por movil u otro criterio
|
|
*/
|
|
public select() {
|
|
return async (req: Request, res: Response) => {
|
|
try {
|
|
iccidValidator.validate(req.body)
|
|
} catch (e) {
|
|
res.status(422).json({
|
|
errors: {
|
|
msg: e
|
|
}
|
|
})
|
|
}
|
|
|
|
const { iccid } = req.body
|
|
const company = companyFromIccid(iccid)
|
|
const url = mapCompanyService.get(company)
|
|
const endpoint = "/select"
|
|
|
|
if (url == undefined) {
|
|
console.error("[x] Error buscando el servicio para el select del iccid ", iccid)
|
|
}
|
|
|
|
try {
|
|
const respSelect = await axios.get(url + endpoint)
|
|
res.json(respSelect.data)
|
|
// TODO: 200
|
|
} catch (err) {
|
|
if (isAxiosError(err)) {
|
|
const axiosErr = err as AxiosError
|
|
res.status(axiosErr.status ?? 500).json(err)
|
|
} else {
|
|
res.status(500).json({
|
|
errors: {
|
|
msg: "Error general buscando la sim"
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Esta funcion se plantea para guardar tarjetas que no han llegado desde
|
|
* un operador conocido
|
|
*/
|
|
public save() {
|
|
return async (req: Request, res: Response) => {
|
|
try {
|
|
iccidValidator.validate(req.body)
|
|
} catch (e) {
|
|
res.status(422).json({
|
|
errors: {
|
|
msg: e
|
|
}
|
|
})
|
|
}
|
|
|
|
const { iccid } = req.body
|
|
const compañia = companyFromIccid(iccid)
|
|
|
|
try {
|
|
await this.simUseCases.cancelation({ iccid, compañia })
|
|
res.status(200).json({
|
|
iccid: iccid,
|
|
operation: "cancelation"
|
|
})
|
|
} catch (err) {
|
|
console.error("Error activando la sim ", req.body)
|
|
res.status(500).json({
|
|
errors: {
|
|
msg: "Error general de activation"
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|