Orders en los consumidores y gestion de los demas casos de uso

This commit is contained in:
2026-02-26 17:30:32 +01:00
parent 18422fbe38
commit ca1144b55c
9 changed files with 204 additions and 52 deletions

View File

@@ -4,7 +4,6 @@ import { SimUseCases } from "./Sim.usecases.js";
import { SimEvents } from "sim-shared/domain/SimEvents.js";
import { Result } from "sim-shared/domain/Result.js";
import { env } from "#config/env/index.js";
import { s } from "node_modules/vitest/dist/chunks/reporters.d.CWXNI2jG.js";
/**
* La clase usa generadores de funciones para mantener el contexto
@@ -84,7 +83,7 @@ export class SimController {
throw new Error("Error activando la sim, no se ha especificado la oferta")
}
const resp = this.tryUseCase(msg, this.useCases.activate({
const resp = await this.tryUseCase(msg, this.useCases.activate({
dueDate: this.genDueDate(DUE_DATE_SECONDS).toISOString(),
customerAccountCode: env.OBJ_CUSTOMER_CODE,
identifier: {
@@ -118,7 +117,7 @@ export class SimController {
}
const iccid = msgData.payload.iccid
this.tryUseCase(msg, this.useCases.preActivate({
const res = await this.tryUseCase(msg, this.useCases.preActivate({
dueDate: this.genDueDate(2 * 60).toISOString(),
identifier: {
identifierType: "ICCID",
@@ -144,7 +143,7 @@ export class SimController {
}
const iccid = msgData.payload.iccid
this.tryUseCase(msg, this.useCases.suspend({
const res = await this.tryUseCase(msg, this.useCases.suspend({
dueDate: this.genDueDate(2 * 60).toISOString(),
identifier: {
identifierType: "ICCID",
@@ -169,7 +168,7 @@ export class SimController {
}
const iccid = msgData.payload.iccid
this.tryUseCase(msg, this.useCases.suspend({
const res = await this.tryUseCase(msg, this.useCases.suspend({
dueDate: this.genDueDate(2 * 60).toISOString(),
identifier: {
identifierType: "ICCID",
@@ -194,7 +193,7 @@ export class SimController {
}
const iccid = msgData.payload.iccid
console.log("Mensaje procesado", String(msgData))
this.tryUseCase(msg, this.useCases.terminate({
const res = await this.tryUseCase(msg, this.useCases.terminate({
dueDate: this.genDueDate(2 * 60).toISOString(),
identifier: {
identifierType: "ICCID",

View File

@@ -27,6 +27,8 @@ export class SimRouter {
/**
* Enruta el mensaje a la acción correspondiente basándose en la routing key
* TODO: No estoy seguro que deba meter el nack aqui
* - De moemento el ack-nack se gestiona en los controller, por si acaso hay casos
* limite en
*/
public route = async (msg: ConsumeMessage | null): Promise<void> => {
if (!msg) {

View File

@@ -3,6 +3,8 @@ import { HttpClient } from "sim-shared/infrastructure/HTTPClient.js"
import { AxiosError } from "axios"
import { Result } from "sim-shared/domain/Result.js"
import { ObjeniousOperation, IOperationsRepository as OperationsRepositoryPort } from "sim-shared/domain/operationsRepository.port.js"
import assert from "node:assert"
import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js"
// TODO:
// - Pasar a un archivo de DTOs
@@ -11,12 +13,16 @@ import { ObjeniousOperation, IOperationsRepository as OperationsRepositoryPort }
export class SimUseCases {
private readonly httpClient: HttpClient
private readonly operationRepository: OperationsRepositoryPort
private readonly orderRepository: OrderRepository
constructor(args: {
httpClient: HttpClient,
operationRepository: OperationsRepositoryPort
operationRepository: OperationsRepositoryPort,
orderRepository: OrderRepository
}) {
this.httpClient = args.httpClient
this.operationRepository = args.operationRepository
this.orderRepository = args.orderRepository
}
private async logOperation(data: ObjeniousOperation) {
@@ -25,6 +31,81 @@ export class SimUseCases {
})
}
/**
* Garantiza el flujo de todos los casos de uso de:
* - Petición según la acción
* - Control de errores
* - Siempre devuelve un Result
* - Almacena la operacion en la base de datos
* - Actualiza el estado del order
*
* Necesita:
* - Mas control según el codigo de error
*/
private generateUseCase<
PAYLOAD,
RESPONSETYPE extends { requestId: string }
>(args: {
correlation_id?: string,
url: string,
operation: string,
operationPayload: PAYLOAD,
iccid: string
onError: (_: any) => void
// on code response??
}): () => Promise<Result<string, boolean>> {
return async () => {
const req = this.httpClient.client.post<RESPONSETYPE>(args.url, {
...args.operationPayload
})
try {
const response = await req;
if (response.status == 200) {
assert(response.data.requestId != undefined)
// Creacion de la operacion inicial, antes de tener los datos
const operation: ObjeniousOperation = {
operation: args.operation,
iccids: String(args.iccid),
status: "noMassID",
request_id: response.data.requestId
}
this.logOperation(operation)
.then().catch(e => console.error(e))
if (args.correlation_id != undefined) {
this.orderRepository.updateOrder({
correlation_id: args.correlation_id!,
new_status: "running",
})
.then(e => console.log("Order actualizado: ", e))
.catch(e => console.error("Error actualizando order", args.correlation_id))
}
return <Result<string, boolean>>{
error: undefined,
data: true
}
} else {
return {
error: String(response.status),
data: undefined
}
}
} catch (error) {
console.error(`[Sim.usecase] Error ${args.operation}`, (error as AxiosError).response?.status)
return {
error: "Error general de la peticion",
data: undefined
}
}
}
}
public activate(activationData: ActivationData): () => Promise<Result<string, boolean>> {
const OPERATION_URL = "/actions/activateLine"
return async () => {
@@ -51,8 +132,6 @@ export class SimUseCases {
error: undefined,
data: true
}
} else {
// muy mejorable el control de errores
return {
@@ -117,14 +196,22 @@ export class SimUseCases {
})
try {
const e = await req
console.log("Sim reactivada con exito", e.data)
return <Result<string, boolean>>{
error: undefined,
data: true
const response = await req
if (response.status == 200) {
console.log("[o] Sim solicitud de reactivacion ", response.data)
return <Result<string, boolean>>{
error: undefined,
data: true
}
} else {
return {
error: String(response.status),
data: undefined
}
}
} catch (error) {
console.error("Error reactivacion", error)
console.error("[x] Error reactivacion", (error as AxiosError).response?.status)
return <Result<string, boolean>>{
error: "Error reactivando la sim" + pauseData.identifier,
data: undefined
@@ -141,11 +228,26 @@ export class SimUseCases {
})
try {
const e = await req
console.log("Sim pausada/suspendida con exito", e.data)
return <Result<string, boolean>>{
error: undefined,
data: true
const response = await req
if (response.status == 200) {
console.log("[o] Sim pausada/suspendida con exito", response.data)
const operation: ObjeniousOperation = {
operation: "susupend",
iccids: String(suspendData.identifier.identifiers),
status: "noMassID",
request_id: response.data.requestId
}
this.logOperation(operation).then().catch(e => console.error(e))
return <Result<string, boolean>>{
error: undefined,
data: true
}
} else {
// muy mejorable el control de errores
return {
error: String(response.status),
data: undefined
}
}
} catch (error) {
console.error("[Pausa Use case] Error pausa")
@@ -164,18 +266,30 @@ export class SimUseCases {
...terminationData
})
// TODO: para cuando estemos listos.
throw new Error("Peticion no reversible desactivada de momento")
try {
const e = await req
console.log("Sim cancelada con exito", e.data)
return <Result<string, boolean>>{
error: undefined,
data: true
const response = await req
if (response.status == 200) {
console.log("[o] Sim solicitud de cancelacion con exito", response.data)
const operation: ObjeniousOperation = {
operation: "terminate",
iccids: String(terminationData.identifier.identifiers),
status: "noMassID",
request_id: response.data.requestId
}
return <Result<string, boolean>>{
error: undefined,
data: true
}
} else {
return {
error: String(response.status),
data: undefined
}
}
} catch (error) {
console.error("Error pausa", error)
console.error("[x ] Error en la solicitud de terminacion", error)
return <Result<string, boolean>>{
error: "Error cancelando/terminate la sim" + terminationData.identifier,
data: undefined