This commit is contained in:
2026-04-07 17:43:17 +02:00
parent 3956797020
commit e6ff54a15d
6 changed files with 121 additions and 14 deletions

View File

@@ -4,10 +4,12 @@
* "Test" * "Test"
*/ */
CREATE TYPE SUSPENDTERMINATE AS ENUM ('suspend','terminate');
CREATE TABLE IF NOT EXISTS pause_cancel_tasks ( CREATE TABLE IF NOT EXISTS pause_cancel_tasks (
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
iccid TEXT NOT NULL, iccid TEXT NOT NULL,
operation_type SUSPENDTERMINATE,
last_checked TIMESTAMPTZ, -- Última vez que se ha comprobado que no esté en test last_checked TIMESTAMPTZ, -- Última vez que se ha comprobado que no esté en test
activation_date TIMESTAMPTZ, -- Fecha de activacion para comprobar si ha pasdo un mes activation_date TIMESTAMPTZ, -- Fecha de activacion para comprobar si ha pasdo un mes
next_check TIMESTAMPTZ, -- Si se ha comprobado se asignará la siguiente fecha de revision next_check TIMESTAMPTZ, -- Si se ha comprobado se asignará la siguiente fecha de revision

View File

@@ -178,7 +178,7 @@ export class SimController {
dueDate: this.genDueDate(2 * 60).toISOString(), dueDate: this.genDueDate(2 * 60).toISOString(),
identifier: { identifier: {
identifierType: "ICCID", identifierType: "ICCID",
identifiers: [iccid] identifiers: [iccid] // Por algún motivo solo he puesto un iccd por identifier
} }
})) }))

View File

@@ -5,6 +5,7 @@ import { Result } from "sim-shared/domain/Result.js"
import { ObjeniousOperation, IOperationsRepository as OperationsRepositoryPort } from "sim-shared/domain/operationsRepository.port.js" import { ObjeniousOperation, IOperationsRepository as OperationsRepositoryPort } from "sim-shared/domain/operationsRepository.port.js"
import assert from "node:assert" import assert from "node:assert"
import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js" import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js"
import { CreatePauseCancelTaskDTO, PauseCancelTaskRepository } from "#adapters/PauseCancelTaskRepository.js"
// TODO: // TODO:
// - Pasar a un archivo de DTOs // - Pasar a un archivo de DTOs
@@ -12,21 +13,24 @@ import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js"
export class SimUseCases { export class SimUseCases {
private readonly httpClient: HttpClient private readonly httpClient: HttpClient
private readonly operationRepository: OperationsRepositoryPort private readonly objeniousRepository: OperationsRepositoryPort
private readonly orderRepository: OrderRepository private readonly orderRepository: OrderRepository
private readonly pauseRepository: PauseCancelTaskRepository
constructor(args: { constructor(args: {
httpClient: HttpClient, httpClient: HttpClient,
operationRepository: OperationsRepositoryPort, operationRepository: OperationsRepositoryPort,
orderRepository: OrderRepository orderRepository: OrderRepository,
pauseRepository: PauseCancelTaskRepository
}) { }) {
this.httpClient = args.httpClient this.httpClient = args.httpClient
this.operationRepository = args.operationRepository this.objeniousRepository = args.operationRepository
this.orderRepository = args.orderRepository this.orderRepository = args.orderRepository
this.pauseRepository = args.pauseRepository
} }
private async logOperation(data: ObjeniousOperation) { private async logOperation(data: ObjeniousOperation) {
await this.operationRepository.createOperation({ await this.objeniousRepository.createOperation({
...data ...data
}) })
} }
@@ -73,6 +77,8 @@ export class SimUseCases {
request_id: response.data.requestId request_id: response.data.requestId
} }
// TODO: Esto tiene poco sentido si la operacion ya se
// tenia que haber creado en el generador
this.logOperation(operation) this.logOperation(operation)
.then().catch(e => console.error(e)) .then().catch(e => console.error(e))
@@ -238,6 +244,93 @@ export class SimUseCases {
}) })
} }
/**
* Paso previo a la suspension para evitar errores cuando el billing es test
*/
public stage_suspend(suspendData: ActionData): () => Promise<Result<string, boolean>> {
return async (): Promise<Result<string, boolean>> => {
const correlation_id = suspendData.correlation_id
const newTask: CreatePauseCancelTaskDTO = {
iccid: suspendData.identifier.identifiers[0],
activation_date: new Date(), // TODO: BUSCAR LA DE VERDAD
next_check: undefined, // Que se haga instantaneamente al ser la primera
operation_type: "terminate"
}
const taskCreated = await this.pauseRepository.addTask(newTask)
// Caso que la task no se pueda crear en la BDD
if (taskCreated.error != undefined) {
console.error("[Sim.usecases]", taskCreated.error)
if (correlation_id != undefined) {
this.orderRepository.updateOrder({
correlation_id: correlation_id,
new_status: "failed"
})
}
return {
error: taskCreated.error
}
}
// Caso que se haya creado en la BDD
if (correlation_id != undefined) {
this.orderRepository.updateOrder({
correlation_id: correlation_id,
new_status: "running"
})
}
return {
data: true
}
}
}
/**
* Paso previo a la suspension para evitar errores cuando el billing es test
*/
public stage_terminate(terminateData: ActionData): () => Promise<Result<string, boolean>> {
return async (): Promise<Result<string, boolean>> => {
const correlation_id = terminateData.correlation_id
const newTask: CreatePauseCancelTaskDTO = {
iccid: terminateData.identifier.identifiers[0],
activation_date: new Date(), // TODO: BUSCAR LA DE VERDAD
next_check: undefined, // Que se haga instantaneamente al ser la primera
operation_type: "terminate"
}
const taskCreated = await this.pauseRepository.addTask(newTask)
// Caso que la task no se pueda crear en la BDD
if (taskCreated.error != undefined) {
console.error("[Sim.usecases]", taskCreated.error)
if (correlation_id != undefined) {
this.orderRepository.updateOrder({
correlation_id: correlation_id,
new_status: "failed"
})
}
return {
error: taskCreated.error
}
}
// Caso que se haya creado en la BDD
if (correlation_id != undefined) {
this.orderRepository.updateOrder({
correlation_id: correlation_id,
new_status: "running"
})
}
return {
data: true
}
}
}
public terminate(terminationData: ActionData): () => Promise<Result<string, boolean>> { public terminate(terminationData: ActionData): () => Promise<Result<string, boolean>> {
const OPERATION_URL = "/actions/terminateLine" const OPERATION_URL = "/actions/terminateLine"
return this.generateUseCase({ return this.generateUseCase({

View File

@@ -8,6 +8,7 @@ import { SimUseCases } from "./aplication/Sim.usecases.js"
import { SimController } from "./aplication/Sim.controller.js" import { SimController } from "./aplication/Sim.controller.js"
import { SimRouter } from "./aplication/Sim.router.js" import { SimRouter } from "./aplication/Sim.router.js"
import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js" import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js"
import { PauseCancelTaskRepository } from "#adapters/PauseCancelTaskRepository.js"
async function startWorker() { async function startWorker() {
const rmqClient = await startRMQClient() const rmqClient = await startRMQClient()
@@ -18,15 +19,21 @@ async function startWorker() {
await pgClient.checkDatabaseConnection() await pgClient.checkDatabaseConnection()
const operationRepository = new ObjeniousOperationsRepository(pgClient) const operationRepository = new ObjeniousOperationsRepository(
httpClient,
pgClient,
)
const orderRepository = new OrderRepository(pgClient) const orderRepository = new OrderRepository(pgClient)
const pauseRepository = new PauseCancelTaskRepository(pgClient)
const simActivationController = new SimController( const simActivationController = new SimController(
rmqClient, rmqClient,
new SimUseCases({ new SimUseCases({
httpClient: httpClient, httpClient: httpClient,
operationRepository: operationRepository, operationRepository: operationRepository,
orderRepository: orderRepository orderRepository: orderRepository,
pauseRepository: pauseRepository
}) })
) )
const simRouter = new SimRouter(simActivationController, rmqClient) const simRouter = new SimRouter(simActivationController, rmqClient)

View File

@@ -5,6 +5,7 @@ import assert from "node:assert";
const testTask: CreatePauseCancelTaskDTO = { const testTask: CreatePauseCancelTaskDTO = {
iccid: "1234", iccid: "1234",
operation_type: "suspend",
activation_date: new Date(), activation_date: new Date(),
next_check: new Date() next_check: new Date()
} }
@@ -21,6 +22,7 @@ describe("Test PauseCancelTaskRepository - DB", () => {
before(() => { before(() => {
}) })
after(() => { after(() => {
}) })

View File

@@ -6,6 +6,7 @@ import { AxiosError } from "axios";
export type PauseCancelTask = { export type PauseCancelTask = {
id: number; id: number;
iccid: string; iccid: string;
operation_type: "suspend" | "terminate",
last_checked?: Date | null; last_checked?: Date | null;
activation_date?: Date | null; activation_date?: Date | null;
next_check?: Date | null; next_check?: Date | null;
@@ -13,15 +14,18 @@ export type PauseCancelTask = {
error?: string | null; error?: string | null;
} }
export type CreatePauseCancelTaskDTO = Pick<PauseCancelTask, "iccid" | "activation_date" | "next_check"> export type CreatePauseCancelTaskDTO = Pick<PauseCancelTask, "iccid" | "activation_date" | "next_check" | "operation_type">
export type UpdatePauseCancelTaskDTO = Pick<PauseCancelTask, "id" | "next_check"> export type UpdatePauseCancelTaskDTO = Pick<PauseCancelTask, "id" | "next_check">
export type FinishPauseCancelTaskDTO = Pick<PauseCancelTask, "id" | "error"> export type FinishPauseCancelTaskDTO = Pick<PauseCancelTask, "id" | "error">
/**
* Repositorio para compensar los problemas de cacelcaiones/pausas de objenious a
* la hora aplicarlo sobre una linea con el billing a test.
*/
export class PauseCancelTaskRepository { export class PauseCancelTaskRepository {
constructor( constructor(
private readonly pgClient: PgClient private readonly pgClient: PgClient
) { ) {
} }
/** /**
@@ -51,12 +55,12 @@ export class PauseCancelTaskRepository {
public async addTask(task: CreatePauseCancelTaskDTO): Promise<Result<string, PauseCancelTask>> { public async addTask(task: CreatePauseCancelTaskDTO): Promise<Result<string, PauseCancelTask>> {
const sql = ` const sql = `
INSERT INTO pause_cancel_tasks (iccid, activation_date, next_check, last_checked) INSERT INTO pause_cancel_tasks (iccid, activation_date, next_check, last_checked, operation_type)
VALUES ($1, $2, $3, now()) VALUES ($1, $2, $3, now(), $4)
RETURNING *; RETURNING *;
`; `;
try { try {
const values = [task.iccid, task.activation_date, task.next_check]; const values = [task.iccid, task.activation_date, task.next_check, task.operation_type];
const res: QueryResult<PauseCancelTask> = await this.pgClient.query(sql, values); const res: QueryResult<PauseCancelTask> = await this.pgClient.query(sql, values);
return { return {
data: res.rows[0] data: res.rows[0]
@@ -66,7 +70,6 @@ export class PauseCancelTaskRepository {
error: (e as AxiosError).message error: (e as AxiosError).message
} }
} }
} }
/** /**