Usecases
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|||||||
@@ -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({
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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(() => {
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user