Visualizacion via api de las operaciones pendientes

This commit is contained in:
2026-02-25 17:23:22 +01:00
parent 02c80cd503
commit f221035c8b
9 changed files with 151 additions and 35 deletions

View File

@@ -0,0 +1,16 @@
meta {
name: Get pending orders
type: http
seq: 11
}
get {
url: {{baseurl}}/orders/pending
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}

View File

@@ -0,0 +1,16 @@
meta {
name: Order by id
type: http
seq: 9
}
get {
url: {{baseurl}}/orders/4
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}

View File

@@ -0,0 +1,20 @@
meta {
name: Orders by message_id
type: http
seq: 12
}
get {
url: {{baseurl}}/orders/message_id/019c93d3-014a-711d-b958-03dd629be78d
body: none
auth: inherit
}
params:query {
~message_id: 019c93d3-014a-711d-b958-03dd629be78d
}
settings {
encodeUrl: true
timeout: 0
}

View File

@@ -2,6 +2,7 @@ import { BodyValidator } from "sim-shared/aplication/BodyValidator.js"
import { OrderUsecases } from "./Order.usecases.js"
import { Request, Response } from "express"
import { PaginationArgs } from "#domain/common.js"
import { idValidator, uuidValidator } from "./httpValidators.js"
export class OrderController {
private orderUseCases: OrderUsecases
@@ -12,28 +13,28 @@ export class OrderController {
this.orderUseCases = args.orderUseCases
}
public getById(args: { id: number }) {
public getById() {
return this.controllerGenerator<{ id: number }, { id: number }>({
validator: undefined,
useCase: this.orderUseCases.getById(args),
validator: idValidator,
useCase: this.orderUseCases.getById(),
onError: (data, error) => { console.error(error) },
onSuccess: (data) => console.log(data)
})
}
public getPending(args: PaginationArgs) {
return this.controllerGenerator<{ id: number }, { id: number }>({
public getPending() {
return this.controllerGenerator<PaginationArgs, PaginationArgs>({
validator: undefined,
useCase: this.orderUseCases.getPending(args),
useCase: this.orderUseCases.getPending(),
onError: (data, error) => { console.error(error) },
onSuccess: (data) => console.log(data)
})
}
public getByQueueId(args: { message_id: string }) {
return this.controllerGenerator({
validator: undefined,
useCase: this.orderUseCases.getByQueueId(args),
public getByQueueId() {
return this.controllerGenerator<{ correlation_id: string }, { correlation_id: string }>({
validator: uuidValidator,
useCase: this.orderUseCases.getByQueueId(),
onError: (data, error) => { console.error(error) },
onSuccess: (data) => console.log(data)
})
@@ -44,6 +45,7 @@ export class OrderController {
* 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
@@ -51,7 +53,7 @@ export class OrderController {
* <O> Representa el dato original
* <P> Representa el dato después del mapeo
*/
public controllerGenerator<O extends Object, P extends Object>(args: {
public controllerGenerator<O extends object, P extends object>(args: {
validator?: BodyValidator<O>,
mapBody?: (body: O) => P,
useCase: (args: P) => Promise<any>,
@@ -59,7 +61,8 @@ export class OrderController {
onSuccess: (args: P) => void,
}) {
return async (req: Request, res: Response) => {
const body = req.body
//scketchy
const body = { ...req.body, ...req.params }
// 1. Validacion del body
try {
@@ -90,13 +93,27 @@ export class OrderController {
// 3. Aplicacion del UseCase
try {
const usecaseResult = await args.useCase(data)
// 4. Se devuelve al usuario el caso de exito
// 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.1 Error del caso de uso
// 4.3 Error del caso de uso
res.status(500).json({
errors: {
msg: "Error general:" + err

View File

@@ -11,25 +11,27 @@ export class OrderUsecases {
this.orderRepository = args.orderRepository
}
public getById(args: {
id: number
}) {
return async () => {
return await this.orderRepository.getOrderById(args)
public getById() {
return async (args: {
id: number
}) => {
const order = await this.orderRepository.getOrderById(args)
return order
}
}
public getByQueueId(args: {
message_id: string
}) {
return async () => {
return await this.orderRepository.getOrderByQueueId(args)
public getByQueueId() {
return async (args: {
correlation_id: string
}) => {
const order = await this.orderRepository.getOrderByQueueId(args)
return order
}
}
public getPending(args: PaginationArgs & {
}) {
return async () => {
public getPending() {
return async (args: PaginationArgs & {
}) => {
return await this.orderRepository.getPendingOrders(args)
}
}

View File

@@ -30,6 +30,30 @@ const offerExists = <Validator<{ offer: string }>>{
validationFunc: (a: { offer: string }) => offers.has(a.offer),
}
const isUuidv7 = <Validator<{ correlation_id?: string }>>{
field: "correlation_id",
errorMsg: "El uuid no es un uuidv7 valido",
validationFunc: (a) => a.correlation_id != undefined && a.correlation_id.length < 36
}
const definedId = <Validator<{ id?: number }>>{
field: "id",
errorMsg: "El id no se ha definido",
validationFunc: (e) => e.id != undefined
}
const isIntegerId = <Validator<{ id?: number }>>{
field: "id",
errorMsg: "El id no se ha definido",
validationFunc: (e) => Number.isInteger(e.id)
}
const validNumericId = <Validator<{ id?: number }>>{
field: "id",
errorMsg: "El id introducido no es un numero >= 0",
validationFunc: (e) => e.id! >= 0
}
export const activationValidator = new BodyValidator<{ iccid: string, offer: string }>(
[
iccidRequired,
@@ -46,3 +70,13 @@ export const iccidValidator = new BodyValidator<{ iccid: string, offer: string }
iccidWithValidCompany,
]
)
export const uuidValidator = new BodyValidator<{ correlation_id?: string }>([
isUuidv7
])
export const idValidator = new BodyValidator<{ id?: number }>([
definedId,
isIntegerId,
validNumericId
])

View File

@@ -5,10 +5,18 @@
import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js"
import { Router } from "express"
import { postgresClient } from '#config/postgreConfig.js';
import { OrderController } from "../aplication/Order.controller.js";
import { OrderUsecases } from "../aplication/Order.usecases.js";
const orderRoutes = Router()
// orderRepository no se trata como singleton
const orderRepository = new OrderRepository(postgresClient)
const orderUseCases = new OrderUsecases({
orderRepository: orderRepository
})
const orderController = new OrderController({
orderUseCases: orderUseCases
})
/**
* Todas las orders, o un resumen, admite filtros
@@ -18,13 +26,15 @@ const orderRepository = new OrderRepository(postgresClient)
* - fecha fin
* - pendientes
* */
orderRoutes.get("/")
orderRoutes.get("/", (req, res) => { res.send("ok") })
orderRoutes.get("/message_id/:correlation_id", orderController.getByQueueId())
orderRoutes.get("/pending", orderController.getPending())
/** Order por id (uuid del mensaje) */
orderRoutes.get("/{id}")
orderRoutes.get("/{status}")
orderRoutes.get("/:id", orderController.getById())
export { orderRoutes }

View File

@@ -63,7 +63,7 @@ describe("Test OrderRepository", {}, (ctx) => {
})
it("Find by correlation id should return a valid order", async () => {
const result = await orderRepo.getOrderByQueueId({ message_id: order1.correlation_id })
const result = await orderRepo.getOrderByQueueId({ correlation_id: order1.correlation_id })
assert(result.error == undefined)
assert(result.data != undefined)
@@ -74,6 +74,7 @@ describe("Test OrderRepository", {}, (ctx) => {
it("Get pending orders should return all pending orders in ASC order", async () => {
// We already have 'testId' from before block
// Insert two more orders
const orderA = { ...order1, correlation_id: "pending-A" }
const orderB = { ...order1, correlation_id: "pending-B" }

View File

@@ -72,12 +72,12 @@ export class OrderRepository {
/**
* Busqueda según la id de RabbitMq
*/
public async getOrderByQueueId<T>(data: { message_id: string }, pool?: PoolClient) {
public async getOrderByQueueId<T>(data: { correlation_id: string }, pool?: PoolClient) {
const query = `
SELECT * FROM order_tracking
WHERE correlation_id = $1
`
const values = [data.message_id]
const values = [data.correlation_id]
const queryPromise = this.pgClient.query<OrderTracking<T>>(query, values)
const result = await this.getFirst(queryPromise);
return result