From f221035c8bc01c011a27a746395cd501506439ec Mon Sep 17 00:00:00 2001 From: Alvar San Martin Date: Wed, 25 Feb 2026 17:23:22 +0100 Subject: [PATCH] Visualizacion via api de las operaciones pendientes --- docs/sim-api/Get pending orders.bru | 16 +++++++ docs/sim-api/Order by id.bru | 16 +++++++ docs/sim-api/Orders by message_id.bru | 20 +++++++++ .../aplication/Order.controller.ts | 45 +++++++++++++------ .../aplication/Order.usecases.ts | 28 ++++++------ .../aplication/httpValidators.ts | 34 ++++++++++++++ .../infrastructure/orderRoutes.http.ts | 20 ++++++--- .../infrastructure/OrderRepository.test.ts | 3 +- .../infrastructure/OrderRepository.ts | 4 +- 9 files changed, 151 insertions(+), 35 deletions(-) create mode 100644 docs/sim-api/Get pending orders.bru create mode 100644 docs/sim-api/Order by id.bru create mode 100644 docs/sim-api/Orders by message_id.bru diff --git a/docs/sim-api/Get pending orders.bru b/docs/sim-api/Get pending orders.bru new file mode 100644 index 0000000..70b9eed --- /dev/null +++ b/docs/sim-api/Get pending orders.bru @@ -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 +} diff --git a/docs/sim-api/Order by id.bru b/docs/sim-api/Order by id.bru new file mode 100644 index 0000000..9940c4a --- /dev/null +++ b/docs/sim-api/Order by id.bru @@ -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 +} diff --git a/docs/sim-api/Orders by message_id.bru b/docs/sim-api/Orders by message_id.bru new file mode 100644 index 0000000..a37a6a6 --- /dev/null +++ b/docs/sim-api/Orders by message_id.bru @@ -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 +} diff --git a/packages/sim-entrada-eventos/aplication/Order.controller.ts b/packages/sim-entrada-eventos/aplication/Order.controller.ts index efed982..e52bf96 100644 --- a/packages/sim-entrada-eventos/aplication/Order.controller.ts +++ b/packages/sim-entrada-eventos/aplication/Order.controller.ts @@ -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({ 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 { * Representa el dato original *

Representa el dato después del mapeo */ - public controllerGenerator(args: { + public controllerGenerator(args: { validator?: BodyValidator, mapBody?: (body: O) => P, useCase: (args: P) => Promise, @@ -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 diff --git a/packages/sim-entrada-eventos/aplication/Order.usecases.ts b/packages/sim-entrada-eventos/aplication/Order.usecases.ts index bad367d..83b389b 100644 --- a/packages/sim-entrada-eventos/aplication/Order.usecases.ts +++ b/packages/sim-entrada-eventos/aplication/Order.usecases.ts @@ -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) } } diff --git a/packages/sim-entrada-eventos/aplication/httpValidators.ts b/packages/sim-entrada-eventos/aplication/httpValidators.ts index a9fc907..abff573 100644 --- a/packages/sim-entrada-eventos/aplication/httpValidators.ts +++ b/packages/sim-entrada-eventos/aplication/httpValidators.ts @@ -30,6 +30,30 @@ const offerExists = >{ validationFunc: (a: { offer: string }) => offers.has(a.offer), } +const isUuidv7 = >{ + field: "correlation_id", + errorMsg: "El uuid no es un uuidv7 valido", + validationFunc: (a) => a.correlation_id != undefined && a.correlation_id.length < 36 +} + +const definedId = >{ + field: "id", + errorMsg: "El id no se ha definido", + validationFunc: (e) => e.id != undefined +} + +const isIntegerId = >{ + field: "id", + errorMsg: "El id no se ha definido", + validationFunc: (e) => Number.isInteger(e.id) +} + +const validNumericId = >{ + 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 +]) diff --git a/packages/sim-entrada-eventos/infrastructure/orderRoutes.http.ts b/packages/sim-entrada-eventos/infrastructure/orderRoutes.http.ts index 71f10be..f8cf3fd 100644 --- a/packages/sim-entrada-eventos/infrastructure/orderRoutes.http.ts +++ b/packages/sim-entrada-eventos/infrastructure/orderRoutes.http.ts @@ -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 } diff --git a/packages/sim-shared/infrastructure/OrderRepository.test.ts b/packages/sim-shared/infrastructure/OrderRepository.test.ts index 68575dd..8b33947 100644 --- a/packages/sim-shared/infrastructure/OrderRepository.test.ts +++ b/packages/sim-shared/infrastructure/OrderRepository.test.ts @@ -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" } diff --git a/packages/sim-shared/infrastructure/OrderRepository.ts b/packages/sim-shared/infrastructure/OrderRepository.ts index b294559..86ddb14 100644 --- a/packages/sim-shared/infrastructure/OrderRepository.ts +++ b/packages/sim-shared/infrastructure/OrderRepository.ts @@ -72,12 +72,12 @@ export class OrderRepository { /** * Busqueda según la id de RabbitMq */ - public async getOrderByQueueId(data: { message_id: string }, pool?: PoolClient) { + public async getOrderByQueueId(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>(query, values) const result = await this.getFirst(queryPromise); return result