From 4e02ea021d78c912eb59c8755a99f59705a54484 Mon Sep 17 00:00:00 2001 From: Alvar San Martin Date: Mon, 27 Apr 2026 09:33:55 +0200 Subject: [PATCH] Docs orders --- .../database/migrations/1.0.0_orders.sql | 1 - docs/sim-alai/Login.yml | 51 +++++++++++++ docs/sim-alai/New Order.yml | 15 ++++ docs/sim-alai/certificates/alai_cert.p12 | Bin 0 -> 6183 bytes docs/sim-alai/environments/local.yml | 2 +- docs/sim-alai/environments/prod.yml | 10 ++- docs/sim-alai/opencollection.yml | 16 ++++ docs/sim-api/Activate.bru | 70 ++++++++++++++++- docs/sim-api/Activation Email.bru | 2 +- docs/sim-api/Cancel.bru | 2 +- docs/sim-api/Docs.bru | 2 +- docs/sim-api/Health.bru | 2 +- .../{ => Orders}/Get pending orders.bru | 2 +- docs/sim-api/{ => Orders}/Order by id.bru | 2 +- .../{ => Orders}/Orders by message_id.bru | 6 +- docs/sim-api/Orders/folder.bru | 44 +++++++++++ docs/sim-api/Pause.bru | 2 +- docs/sim-api/Preactivate.bru | 2 +- docs/sim-api/ReActivate.bru | 2 +- docs/sim-api/collection.bru | 3 +- docs/sim-api/test proxy.bru | 2 +- .../aplication/SimAlai.controller.ts | 8 +- ...saccess_alaisecure_com_cert_client_new.p12 | Bin 0 -> 6183 bytes packages/sim-entrada-eventos/README.md | 0 .../aplication/Order.controller.ts | 13 +++- .../aplication/Order.usecases.ts | 7 ++ .../aplication/httpValidators.ts | 8 +- .../infrastructure/orderRoutes.http.ts | 8 +- .../infrastructure/simconnectionsRoutes.ts | 3 +- packages/sim-shared/domain/Order.ts | 17 ++++- .../infrastructure/OrderRepository.test.ts | 15 +++- .../infrastructure/OrderRepository.ts | 72 +++++++++++++++++- 32 files changed, 349 insertions(+), 40 deletions(-) create mode 100644 docs/sim-alai/Login.yml create mode 100644 docs/sim-alai/New Order.yml create mode 100644 docs/sim-alai/certificates/alai_cert.p12 rename docs/sim-api/{ => Orders}/Get pending orders.bru (94%) rename docs/sim-api/{ => Orders}/Order by id.bru (68%) rename docs/sim-api/{ => Orders}/Orders by message_id.bru (50%) create mode 100644 docs/sim-api/Orders/folder.bru create mode 100644 packages/sim-consumidor-alai/certificates/wsaccess_alaisecure_com_cert_client_new.p12 create mode 100644 packages/sim-entrada-eventos/README.md diff --git a/deployment/database/migrations/1.0.0_orders.sql b/deployment/database/migrations/1.0.0_orders.sql index 912710a..3278e9f 100644 --- a/deployment/database/migrations/1.0.0_orders.sql +++ b/deployment/database/migrations/1.0.0_orders.sql @@ -24,7 +24,6 @@ CREATE TABLE IF NOT EXISTS order_tracking ( payload JSONB, -- Duda si es optimo guardar la copia, es útil en caso de fallo -- Campos de reintentos? - status order_status NOT NULL DEFAULT 'pending', retry_count INT DEFAULT 0, error_message TEXT, -- Razón del fallo diff --git a/docs/sim-alai/Login.yml b/docs/sim-alai/Login.yml new file mode 100644 index 0000000..0256ae9 --- /dev/null +++ b/docs/sim-alai/Login.yml @@ -0,0 +1,51 @@ +info: + name: Login + type: http + seq: 2 + +http: + method: POST + url: "{{baseurl}}/v1/auth/login" + body: + type: json + data: |- + { + "username": "{{username}}", + "password": "{{password}}", + "brandID": "{{brandId}}" + } + auth: inherit + +runtime: + scripts: + - type: after-response + code: |- + const data = res.getBody(); + + if (data.staus != 200) { + console.error("Error de login: ", data) + return 1; + } + + if (data && data.accessToken) { + + bru.setEnvVar("alai_token", data.accessToken); + + if (data.tokenType) { + bru.setEnvVar("alai_token_type", data.tokenType); + } + + console.log("Token guardado correctamente"); + } else { + console.error("No se pudo encontrar el accessToken en la respuesta"); + } + +settings: + encodeUrl: true + timeout: 0 + followRedirects: true + maxRedirects: 5 + +docs: |- + Necesita un certificado p12 (PFX) y la contraseña asociada para efectuar la operacion. + Collection Settings => ClientCertificates => Add Certificate diff --git a/docs/sim-alai/New Order.yml b/docs/sim-alai/New Order.yml new file mode 100644 index 0000000..e342c26 --- /dev/null +++ b/docs/sim-alai/New Order.yml @@ -0,0 +1,15 @@ +info: + name: New Order + type: http + seq: 3 + +http: + method: POST + url: "{{baseurl}}/v1/order" + auth: inherit + +settings: + encodeUrl: true + timeout: 0 + followRedirects: true + maxRedirects: 5 diff --git a/docs/sim-alai/certificates/alai_cert.p12 b/docs/sim-alai/certificates/alai_cert.p12 new file mode 100644 index 0000000000000000000000000000000000000000..86217c6474c8032bdc1485aba51f4c088c4a789d GIT binary patch literal 6183 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 NVTw>a_djL&{{ZHzxsm_? literal 0 HcmV?d00001 diff --git a/docs/sim-alai/environments/local.yml b/docs/sim-alai/environments/local.yml index 678d231..db39cbc 100644 --- a/docs/sim-alai/environments/local.yml +++ b/docs/sim-alai/environments/local.yml @@ -2,6 +2,6 @@ name: local color: "#2E8A54" variables: - name: baseurl - value: http://localhost:3001 + value: http://localhost:3002 - secret: true name: token diff --git a/docs/sim-alai/environments/prod.yml b/docs/sim-alai/environments/prod.yml index 080fcff..58204fa 100644 --- a/docs/sim-alai/environments/prod.yml +++ b/docs/sim-alai/environments/prod.yml @@ -2,6 +2,12 @@ name: prod color: "#CE4F3B" variables: - name: baseurl - value: https://nosconnectcenter-api.iot-x.com + value: https://wsaccess.alaisecure.com/bssrest + - name: username + value: palomaibanez + - name: password + value: palomaibanez123 - secret: true - name: token + name: certPasswd + - name: brandId + value: savefamily diff --git a/docs/sim-alai/opencollection.yml b/docs/sim-alai/opencollection.yml index 297aed6..6d6bccb 100644 --- a/docs/sim-alai/opencollection.yml +++ b/docs/sim-alai/opencollection.yml @@ -2,6 +2,22 @@ opencollection: 1.0.0 info: name: sim-alai +config: + proxy: + inherit: true + config: + protocol: http + hostname: "" + port: "" + auth: + username: "" + password: "" + bypassProxy: "" + clientCertificates: + - domain: wsaccess.alaisecure.com + type: pkcs12 + pkcs12FilePath: certificates\alai_cert.p12 + passphrase: iHaaek+zyzWz6cH6rg== bundled: false extensions: bruno: diff --git a/docs/sim-api/Activate.bru b/docs/sim-api/Activate.bru index bbc6a60..46a58b0 100644 --- a/docs/sim-api/Activate.bru +++ b/docs/sim-api/Activate.bru @@ -6,16 +6,80 @@ meta { post { url: {{baseurl}}/sim/activate - body: formUrlEncoded + body: json auth: inherit } +body:json { + { + "iccid": "1234" + } +} + body:form-urlencoded { - iccid: 8933201125065156057 - offer: SAVEFAMILY1 + iccid: 123 + offer: mensual } settings { encodeUrl: true timeout: 0 } + +docs { + Campos de entrada: + ```ts + // Header requerido + // > content-type:application/x-www-form-urlencoded + // > content-type:application/json + // Cualquiera de los 2 es valido + + // Esquema body + { + iccid: string, + offer: "mensual" | "anual" | "SAVEFAMILY1" | "SAVEFAMILY2" + webhook?: string, + } + ``` + + En el campo `offer` "mensual" equivale a "SAVEFAMILY2" y "anual" a "SAVEFAMILY1" porque se mantien los códigos de Oferta de Objenious por compatibilidad pero se espera usar "mensual" y "anual" y hacer la conversión en el servicio de cada proveedor. + + Para las llamadas al webhook se va a usar siempre el metodo `POST`, ahora mismo no se firman los mensajes. Se introduce la URL completa tal que `https://dominion.com/v1/endpoint`. + + Respuestas: + - **200**: OK + ``` ts + // Esquema + { + iccid: string, + operation: string, + message_id: string, //uuidv7 + } + ``` + ``` json + // Ejemplo + { + "iccid": "89332011250651xxxxx", + "operation": "activation", + "message_id": "019dbeaf-8abb-7783-8b51-94fbd9f0b0df" + } + ``` + + *iccid*: Confirmación del iccid enviado. + *operation*: Confirmación de la operacion que se ha aplicado. + *message_id*: Id de la operación, para consultar en orders. + + > A futuro se va a incluir un campo `"ref":[]` para añadir los enlaces a las consultas de la operación. El body va a permitir tambien json. + + - **402**: Algún campo es incorrecto + Se indica que campo es incorrecto, si hubiese mas de uno solo aparecería el primero en comprobarse. + ```json + "errors": { + "msg": "La longitud del iccid es incorrecta debera ser de 19 caracteres", + "field": "iccid" + } + ``` + + - **500**: Error general + Ha ocurrido un error imprevisto durante la +} diff --git a/docs/sim-api/Activation Email.bru b/docs/sim-api/Activation Email.bru index 8f72b9e..2d7dec1 100644 --- a/docs/sim-api/Activation Email.bru +++ b/docs/sim-api/Activation Email.bru @@ -1,7 +1,7 @@ meta { name: Activation Email type: http - seq: 6 + seq: 7 } post { diff --git a/docs/sim-api/Cancel.bru b/docs/sim-api/Cancel.bru index 3e31352..a4f77ec 100644 --- a/docs/sim-api/Cancel.bru +++ b/docs/sim-api/Cancel.bru @@ -1,7 +1,7 @@ meta { name: Cancel type: http - seq: 1 + seq: 3 } post { diff --git a/docs/sim-api/Docs.bru b/docs/sim-api/Docs.bru index 613bf7b..d2e6145 100644 --- a/docs/sim-api/Docs.bru +++ b/docs/sim-api/Docs.bru @@ -1,7 +1,7 @@ meta { name: Docs type: http - seq: 12 + seq: 10 } get { diff --git a/docs/sim-api/Health.bru b/docs/sim-api/Health.bru index 5c7748b..ab5d247 100644 --- a/docs/sim-api/Health.bru +++ b/docs/sim-api/Health.bru @@ -1,7 +1,7 @@ meta { name: Health type: http - seq: 5 + seq: 6 } get { diff --git a/docs/sim-api/Get pending orders.bru b/docs/sim-api/Orders/Get pending orders.bru similarity index 94% rename from docs/sim-api/Get pending orders.bru rename to docs/sim-api/Orders/Get pending orders.bru index 70b9eed..3888958 100644 --- a/docs/sim-api/Get pending orders.bru +++ b/docs/sim-api/Orders/Get pending orders.bru @@ -1,7 +1,7 @@ meta { name: Get pending orders type: http - seq: 11 + seq: 10 } get { diff --git a/docs/sim-api/Order by id.bru b/docs/sim-api/Orders/Order by id.bru similarity index 68% rename from docs/sim-api/Order by id.bru rename to docs/sim-api/Orders/Order by id.bru index 80104c0..6d3d66a 100644 --- a/docs/sim-api/Order by id.bru +++ b/docs/sim-api/Orders/Order by id.bru @@ -5,7 +5,7 @@ meta { } get { - url: {{baseurl}}/orders/ + url: {{baseurl}}/orders/019dbeaf-8abb-7783-8b51-94fbd9f0b0df body: none auth: inherit } diff --git a/docs/sim-api/Orders by message_id.bru b/docs/sim-api/Orders/Orders by message_id.bru similarity index 50% rename from docs/sim-api/Orders by message_id.bru rename to docs/sim-api/Orders/Orders by message_id.bru index a37a6a6..787fd86 100644 --- a/docs/sim-api/Orders by message_id.bru +++ b/docs/sim-api/Orders/Orders by message_id.bru @@ -5,15 +5,11 @@ meta { } get { - url: {{baseurl}}/orders/message_id/019c93d3-014a-711d-b958-03dd629be78d + url: {{baseurl}}/orders/message_id/019dbeaf-8abb-7783-8b51-94fbd9f0b0df body: none auth: inherit } -params:query { - ~message_id: 019c93d3-014a-711d-b958-03dd629be78d -} - settings { encodeUrl: true timeout: 0 diff --git a/docs/sim-api/Orders/folder.bru b/docs/sim-api/Orders/folder.bru new file mode 100644 index 0000000..6623108 --- /dev/null +++ b/docs/sim-api/Orders/folder.bru @@ -0,0 +1,44 @@ +meta { + name: Orders +} + +auth { + mode: inherit +} + +docs { + # Orders + + Los *order* representan ordenes que se hacen al servidor y representan en que estado se encuentran las peticiones. Los *order* se generan cuando se solicita una operacion y devuelven su identificador en el campo `message_id` de todas las respuestas a peticiones que requieran cambios. Los identificadores de `order` son UUIDv7, aunque tambien tienen asociado un id tradicional BIGINT en la BDD. + + ## Ciclo de vida + + Cuando se crea un *order* comienza en estado `pending`, inicando que ha entrado en la cola y está pendiente de iniciarse; una vez se ha consumido por un servicio pasa a estado `running` indicando que la operacion asociada al *order* ha comenzado, el order continuara en este estado durante un tiempo indefinido (pueden pasar semanas para algunos casos), hasta que la tara finalize correctamente o con errores. En el caso que la tarea finalize con éxito el *order* pasará a estado `finished`, en caso de que haya habido un error el estado será `failed` y se almacenará el error en los campos `error_message` y opcionalemente en `error_stacktrace` según gravedad del error. + + - Caso normal + `pending` -> `running` -> `finished` + + - Error durante el consumo + `pending` -> `failed` + + - Error durante la operacion + `pending` -> `running` -> `failed` + + ## Endpoints + Estan sujetos a cambios en cuanto a mostrar información + + - [WIP]**GET** /orders?{query} + Devuelve todos los orders con un campo que tenga el valor especificado en la query + + - **GET** /orders/{id} + Devuelve el order objetivo según su UUID de mensaje (No según el uuid de mensaje) + + - **GET** /orders/base_id/{id} + Devuelve el id según su id de la bdd, no es el metodo normal de usar la api + + - **GET** /orders/pending + Devuelve todas las order que no hayan finalizado + + + +} diff --git a/docs/sim-api/Pause.bru b/docs/sim-api/Pause.bru index cfb5e5e..255b8ec 100644 --- a/docs/sim-api/Pause.bru +++ b/docs/sim-api/Pause.bru @@ -1,7 +1,7 @@ meta { name: Pause type: http - seq: 1 + seq: 4 } post { diff --git a/docs/sim-api/Preactivate.bru b/docs/sim-api/Preactivate.bru index c9053de..ed73ab1 100644 --- a/docs/sim-api/Preactivate.bru +++ b/docs/sim-api/Preactivate.bru @@ -1,7 +1,7 @@ meta { name: Preactivate type: http - seq: 1 + seq: 5 } post { diff --git a/docs/sim-api/ReActivate.bru b/docs/sim-api/ReActivate.bru index 6477b85..8fd13df 100644 --- a/docs/sim-api/ReActivate.bru +++ b/docs/sim-api/ReActivate.bru @@ -1,7 +1,7 @@ meta { name: ReActivate type: http - seq: 13 + seq: 11 } post { diff --git a/docs/sim-api/collection.bru b/docs/sim-api/collection.bru index 5fe677a..1ec9cfd 100644 --- a/docs/sim-api/collection.bru +++ b/docs/sim-api/collection.bru @@ -1,5 +1,6 @@ docs { - Los endpoint tienen unos campos comunes de entrada: + Todos los endpoint tienen unos campos comunes de entrada: + ```ts { iccid: string, diff --git a/docs/sim-api/test proxy.bru b/docs/sim-api/test proxy.bru index d4e17b0..cb85bc8 100644 --- a/docs/sim-api/test proxy.bru +++ b/docs/sim-api/test proxy.bru @@ -1,7 +1,7 @@ meta { name: test proxy type: http - seq: 14 + seq: 12 } get { diff --git a/packages/sim-consumidor-alai/aplication/SimAlai.controller.ts b/packages/sim-consumidor-alai/aplication/SimAlai.controller.ts index 1c4aac4..7e401da 100644 --- a/packages/sim-consumidor-alai/aplication/SimAlai.controller.ts +++ b/packages/sim-consumidor-alai/aplication/SimAlai.controller.ts @@ -1,6 +1,6 @@ import { ConsumeMessage } from "amqplib"; import { Request, Response } from "express" -import { SimNosUsecases } from "./SimNOS.usecases.js"; +import { SimAlaiUsecases } from "./SimAlai.usecases.js"; import { EventBus } from "sim-shared/domain/EventBus.port.js"; import { Result } from "sim-shared/domain/Result.js"; import { SimEvents } from "sim-shared/domain/SimEvents.js"; @@ -9,7 +9,7 @@ import { iccidValidator } from "./httpValidators.js"; export class SimAlaiController { constructor( - private uscases: SimNosUsecases, + private uscases: SimAlaiUsecases, private eventBus: EventBus, ) { } @@ -51,12 +51,12 @@ export class SimAlaiController { await this.eventBus.ack(msg) return result } else { - console.error("Error procesando el caso de uso (NOS)", result.error) + console.error("Error procesando el caso de uso (Alai)", result.error) this.eventBus.nack(msg) return result } } catch (e) { - console.error("Error general procesando el caso de uso (NOS)") + console.error("Error general procesando el caso de uso (Alai)") this.eventBus.nack(msg) return { error: String(e) diff --git a/packages/sim-consumidor-alai/certificates/wsaccess_alaisecure_com_cert_client_new.p12 b/packages/sim-consumidor-alai/certificates/wsaccess_alaisecure_com_cert_client_new.p12 new file mode 100644 index 0000000000000000000000000000000000000000..86217c6474c8032bdc1485aba51f4c088c4a789d GIT binary patch literal 6183 zcmai&RZJWJw{-^?thl>Ffik!=xLbju#ob|OaVv$v-QA%$#ogVCyHj*yHMAc2h?}{cGbW21K=9FyH+J))0%4Evn&3h{t+Th zfL1~D**k${D{#!t_^Zn?-uzSaujvVLS`GrsAmyL%sgoZcl9dSRuu{V~`~0I@9Jxa3 ze_}bE(5hwmYU<39=$CGx*0XVLCoya5ypb;=O!uy<>7jJ8^|3Ub2L$t%<$MG4>@=9H zL!uwEJ8~zDI&x}NDiL*`UZnyRVJdN3>I{f92-OYOiBA@I2mG)Wu)}A=-lW_NIN`S~ z)iSNS91#>6{Iy(d$Kz0Gx7G;>MHhlaw$qpQXrYKTBPcXpl=m72po-vu=XYj6JZd=l z@S^0f#s#>?<$PU}t2HkHq{J#pp=*~gn_3TV>BWm9Uw}d{Ux^Vmc?XRSB;(^7IKXuv zFI5in(#MGXH72HTKEPAf%{Jij^49b`Gx!qIMC{x?tP_x2O+)~8;@52>dvNtf8U zT18?WwZ`4ZS?QK&?G}NAuvMbky&R4@Rgy|o%%+8SY4BcIo>L&cx@cdqq7hX@D*=n4 zC=@w=w9_F5m2{*+N$a7tY!oP8tQgQ0hDr#O(;D@-JVB#1I2c|oeK%R|5dOSTTkBTp3Sa+l!K#2>TFGfJ)tlz zd+}KzktNIv+#^u#0A0;ewOebsz{b%^T6WXp5kXUKW+mxppNS-G_mO&+lcNh4QX=4d z=dg0<1ueIusz#*sWfY9XL84F$jxvix2LPBOjB)brTn3Bd=_Lyc%mew?*(nyJl{lMa zb{P^moO4Hq+D*2MzE8M=5+i zgJ@uvtGAo@W@~TvAttNAYeL6n^cJ^m>o>liN#Y4Hw2P^kmSJy4YMUkKqPLL1ka)Rg z*arT97C_ux-Z`3^O(^SPRX#%pUmr3L_Q!Wx+Z0}gq5$!JE15BQp!WwT8%R`a5V(Vt z9iSYP;)ShX-enfDlNjt=_uy~Si}4$^GEVIk*518NO3}4ly5L`OYppojB6N4&$XKmP z>5U)}S*MkL7SWNb-ba)LvH0B%Q95QC){Uxx-AJYwBK?V#_NAM~ zV&X<%$qoS}(F-)m=Z{JcW`VUk-z_@_aLwU>7jgE%HSS)D3KJ_g06uN7I$oaXr7YZ6 z<)g_R5xN4=ZWVUY95+MG5x)W$l{lQ@p!KnJ+t5ee|K4Zxp$Y;1l_l3|^5S6-V0gsL zNa*{?`MwQeE!KHDA0me0m#~nCkzFG2t=rqG*kbQzk4Rj0FRtpBZ)TdLU4;>C?p~;A z20JC7EMxI)MzDpakm+Ys)Gr5Wd!&s!iE*ZyA-#XpaBp41K_bqWAf4c{UeWiLZ>vS~ zPPcW!)WrIT9JS=QnkL)|QmXe$>W|%lu#QudMQzd^n6Yu|Pt*~%4P@7GBCwqJNx|C5 z20|K&QwxcIuWOY>?^>e*yBaUu8q)|%Uh-x<0K3x8Fqkf4lG*s9n)CM4Vw2i2Efks$ zl(MNC)>t07+Bxj8)siGsSju+BYF3#&1D3%mdPp>xA{p|XHwFt~s-NQ{>AShF&7}^c zMEN*LI6au||5_e`wE~oe9OdUu#~ub;v5^ukiD|G8ENACBGTkYCrE3O>AN+YFKcWwH z%38d)uX*9K$TWWLDsC@had)Z;auwL0KuKYpb}%tG9H z+FFu9#>Np$CIFw3Lmo91P#kE}3I1yIVr`3i(#{BE@Y!poxn5~mq9|a~THm^jI|Eaq z;CdTCb8O7dX#9JPL>g?#L3#2nn;(9>C)hAhP^nfXBLkG{Asj6lZpmyaTYHILEhjXr z$lKZp6^@Q&Sz&;gmTl<$Vo|QiD{a3F4)dy!nPh~FFQMebC!aJN?8JB9F~dcU=0&ht z4*o6a>vN59X!cJsbeqSP7On%AOl;neGz8B$l&dogWslqUnR^Zr@uzT0Gun)mV%+7& z>DuJQ?F6k zZ=FcQ?Pucb9pyISS9Lm%886BAC-~>2qf|Vk;Wj|YWLyqA@TmMDWIX1Z4-p$Bv~;X1 zn@DbzoAVe#8GU$M_@{MhtWcVx(Lq}QmDy3XW=-P{t*J+#`C6$0-X`NF!@Ae=w;m%U zN-Qu-zN~Q{_^aGr(=^lcv%X`1B@H`s773b20(3FWh#=W!U`ugA7|4e>mYJ+S=X^n^*n2?eu4!k}@H1HdJ^dZW&Mvh!riNEQKuudk%;D5NUfG zMl0=VR(R%To1hq`zdbOow?OuO6D@W03AShrV%In`hd}%o6HC`WUM-m}P?5E9;)TAn z+cM{*X30=bixM}ip2bn87zA<&?mKwawd3(o>5Fr8e+Va@K(?!*bbQKs^YU1(4eE87 zsWm4?*u&#$R92h%3@fApC%YdXb_9MtW$#fyZ`cJLfht!bFQ$$TIX~IR5|0Vv0Py$% zK(+wzUt1YXNv#-W(_swm!V-rom{3(l5k7(&=%-wN#3CTm%gK60Hfc8-dbTIsa9 zu9|DR;NPZleXwBiZoz~E zATcnr`hrm=-0Bze^HR>WHIdd$e6wnILoc6#G${3g_{K0~#V|eF>J2g)P%AUTz*a9( zZNc`H`oML3dI)5nbzA?_>NKT?ih-}j;`fcXFqO~-a8D~AvwWF2aD0B(t^i{ovA z{G9ws#%)+A#89fT7$iJEqOZa8#$>?Ts(`tL&RHidPXv^#=ven%$K)HG7-@wIAu1fLbPulnW~y( z_MoAg?!R>)LF)>eLduAoFwK4*Y6?FZ)#BslMxsI_|&ZKYL9ZZ@Oyn^mr{vDJWfi^L?wi3 zOND&_HgirUX&}NQ8o8`W$b;P98F5VUzdA*3UJkIa@!~2AQ>0uZfBvkuew`z1Z$-c4 zC*tmvn9UGLaS=0B8{^`HChnUhbZ*wxO|!MDiu3n%@vFTYnM2(syo_ZN7GWw=(!l7x zZ80ibD|<=EmkiqifjK{&t9{MA6oOpsv0+kC&q)0~n-1@vTy9TG;Fa+y`nr@!*3YjB zVmi=CCW?iX`}2AE>YOJhf5jpOj8vbPDh8B?!ly8(^%;Th=ZH^AJzeOAej0hjKaL;Mb-p5(S zMs<`pwi+4X|5BAi7b9fnPur@V;M^9oa+r*tttwAm>t887*#(l7rX=-_TIM18hqbAF zO5p$Q$86Rvd)4xa{1ho_-6cpkg|*TagQeJJSCYhgHvp!~a{Gjt#Exb8Q@5bB+upP> zLVuf~g2mjOsg1Q& z7I!U@^M&rbN#Ij2p>5C*VK$}R1jqt=%KjD%&C5(S{TvobRHTQ=aE*H{JySPM$C7iX z&HS9ZH@#xWxU6j?jMwva^E@EOXV0YEfd0B0Sps=}X+t;=>_Z2UU}tT*8B-Kz6Er zRdvJ2WE9BhL9I#1VY2?t?}Wa=#tHu5%qkCaL%w0IJ*7Kip$6a36*h}7(R8Z6JAmEC zxGRLW>834!-7n_GSLJB#aRxtKemr06@m(V4_^Urrri3={gPR}dlUQZrJ zXZ{rQ#bP|fY-;mT3I6X-(yr7hOP${bMQtS5A`;Pa}F2qENYU$VQ$<}&cez@1>u72EYZ^pvV`90#KJoGNc~8mf&j zF~h^bN|*9X_=cKD(|!2N6(=L#?KSw8cAO~mauN~>y%@yAyK6^8Fi@P9K_)F*mo46U zY<(#_Zs5Z?8WqOaMa!U(44`p4NHF|KyTCQM30$S8EbQT*>7Z=l7bG{V}`-xf$XI`$7l?ZK9{T+nRdcuxwl=+x_! z4oh7(Ldo8z*-yp8(&0zJG{;}OnLMqB&j@p#yiL|zYnoJOjjsx{9z|=c?%~9yEg}MI z+Z`^e++~Z9j{j`I_FstcH2xIG=MLEB&3YSFQ)u58K63QNlLh|W_NP4gHSbEjBO~el z^Vyfr@7x_Ld6H*Q8=t(h-^xpN=k60J&uFi+{49hqVAI@U?8CXO{-w#xO&w3#1L>j5 z5H@xb;+R?X5t3$h6#1*7BNJG7Xi>x2dtlm~*Hwat0H+w+F_+nhUT?>U_9KWk$k(Tp z)1En*x^PXsB?%nA0m(Orls<4~yZzX&L!s#w7Ru_onku6+6Gi_f4pF@Q^+xXgMLIA!;%e4}W(Q~QyNI#wvTgu^zNPM1R`zZZ}Y zf?O;e+FbTXbnXBrm^3A+$PH}bCfY-VjwuNK{`tPiQv10k5=xtKk%>GPCYgKw*Qr&Y zJw0(PqXg4#aV2-B-pN~2CKu01f`a}r(N6o9Z*?(GcNGsYns>{L$d4X|rkCf9XW!th z3fqhPXBLkVf(qUeveEyHtUt{Bc??(z>D=!A`--X5Br<-Srt|O5oOQVv;}_@mY3N*85)+ld#N*p77$^>~4eU9L;xAV;~ebO|s<3rkwdO zmOnLi8RDKjo=OfWa4>$O+pM9>Rw&zhhcqdC;OE`%6{ddDuZrDy2r}mu`HF~56C?rd zl_;etIIbnjH2t|)v^i z3#?R+X1bl1-pv?}lNdJsaICE0-=8p&4$k7I=hQ{^!FZ6o%)wo-y%mJ9x4f-$jwvb{ z8BBuRDCGTBPBxSD2?hE*a%2-+*e`soC2>9ka$f0CSzN8+ds-+7aF!KTdZc>eOoBr1 zy;zFFoI@&|o^2jN1n%ZLLm4s)?bFPEwmGu%qn59o65Na_)elLM?Kb*7As^B2l0A`r z>e@ng1qViNqvBB+;uGAH0BjUA6K_>YejZA{Mep@-^aav9(==4bvuB()uoImKI2M81*U}Z;1;guQ z1j!S67rVgX!2*?d@!$q({Kjopo573eVdiLb^m>B)Z_rWxlw&fBzKT<&p7isR`)DqJ zcKIVZ-4S=4tTF|1pi@xa*=4kQ^v9ETUYZMlDC{bJFt4GYYYX-o;X(>={2hYR<0?bbhX^bmc3H^ffEhxpW{i@Owc4){E17 zXqG2ti?Zul)-~-gNw?Uk1h*^_yL)n1o!%+e>UK|hRD&J~E7erOgwI^TJ_8QPUZk-N zdAkEmzz*Z~LJowt+}X!iNgov>{M^WasDn*g!C!4g&vNRv*xspBg$9p7w{SN_ZO6A| zii*GJDMrA5f3ZcVR$HJ9nGa!cE2?GJmtj@x(B56=azFgETWg2%Hn3h}@{Zln3%gObP7z~_xg-c!*Y!*4 z+k%&H#YZiIZzc=x2v02E#7H6QRI7qD`1o#;p~?8G#T0^#Lf_AD^?JrELR3lvM}B8? zu+H3h)aRJ#xc!aae$RAaa5@+j|XjZrqnqv;WDkxv{jrxZ(Di`MO8)0!J zVcF^W4~0g*=TKKK{z$+T>j+Zk6hEX|fim(Ev~q8QOc%}YRSG2M0w`#Ixg|Yb_b{9F z;!iVPo(-KW-(qvpx_)U`3je@p)xFCcBN#F~ z4=YB2%F52sqazD+^o?Mxlt*mV$Q0YYkKltpe@;pICf92rLp#~Qjf3C;#k>1Klz1pI zzsy(V5UeR%n>$mQFWh*Bv8xZp#V9UIwM>4TS54~DU)@los)0Bv$|Uaj_l18OVjrz~ zt!Y8s#Dvy{X0aNPb)a@43fN~n{1`QyOz0p<8s=o+p!-jyq7rZt0`Z-={bGx7I^Dx? z5<7s^QZuIz(rFG(4jK+rBt#ZW1b9+J01&@*{ARxYRPrq{kk5bj!a%@o8*2oJQcdT) NVTw>a_djL&{{ZHzxsm_? literal 0 HcmV?d00001 diff --git a/packages/sim-entrada-eventos/README.md b/packages/sim-entrada-eventos/README.md new file mode 100644 index 0000000..e69de29 diff --git a/packages/sim-entrada-eventos/aplication/Order.controller.ts b/packages/sim-entrada-eventos/aplication/Order.controller.ts index e52bf96..f924e96 100644 --- a/packages/sim-entrada-eventos/aplication/Order.controller.ts +++ b/packages/sim-entrada-eventos/aplication/Order.controller.ts @@ -32,14 +32,23 @@ export class OrderController { } public getByQueueId() { - return this.controllerGenerator<{ correlation_id: string }, { correlation_id: string }>({ + return this.controllerGenerator<{ uuid: string }, { correlation_id: string }>({ validator: uuidValidator, + mapBody: (e) => ({ correlation_id: e.uuid }), useCase: this.orderUseCases.getByQueueId(), onError: (data, error) => { console.error(error) }, onSuccess: (data) => console.log(data) }) } + public getByQuery() { + return this.controllerGenerator({ + validator: undefined, + useCase: this.orderUseCases.getByQuery(), + onError: (data, error) => { console.error(error) }, + onSuccess: (data) => console.log(data) + }) + } /** * TODO: @@ -77,7 +86,7 @@ export class OrderController { }) } - // 2. Transformacion del body + // 2. Transformacion del body O => P let data: P = body; try { if (args.mapBody != undefined) diff --git a/packages/sim-entrada-eventos/aplication/Order.usecases.ts b/packages/sim-entrada-eventos/aplication/Order.usecases.ts index 83b389b..01cc8a6 100644 --- a/packages/sim-entrada-eventos/aplication/Order.usecases.ts +++ b/packages/sim-entrada-eventos/aplication/Order.usecases.ts @@ -1,4 +1,5 @@ import { PaginationArgs } from "#domain/common.js"; +import { OrderQuery } from "sim-shared/domain/Order.js"; import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js"; @@ -36,4 +37,10 @@ export class OrderUsecases { } } + // WIP + public getByQuery() { + return async (args: OrderQuery) => { + return await this.orderRepository.getOrdersByQuery(args) + } + } } diff --git a/packages/sim-entrada-eventos/aplication/httpValidators.ts b/packages/sim-entrada-eventos/aplication/httpValidators.ts index ad566f8..b055b40 100644 --- a/packages/sim-entrada-eventos/aplication/httpValidators.ts +++ b/packages/sim-entrada-eventos/aplication/httpValidators.ts @@ -32,10 +32,10 @@ const offerExists = >{ validationFunc: (a: { offer: string }) => offers.has(a.offer), } -const isUuidv7 = >{ - field: "correlation_id", +const isUuidv7 = >{ + field: "uuid", errorMsg: "El uuid no es un uuidv7 valido", - validationFunc: (a) => a.correlation_id != undefined && a.correlation_id.length < 36 + validationFunc: (a) => a.uuid != undefined && a.uuid.length < 36 } const definedId = >{ @@ -73,7 +73,7 @@ export const iccidValidator = new BodyValidator<{ iccid: string }>( ] ) -export const uuidValidator = new BodyValidator<{ correlation_id?: string }>([ +export const uuidValidator = new BodyValidator<{ uuid?: string }>([ isUuidv7 ]) diff --git a/packages/sim-entrada-eventos/infrastructure/orderRoutes.http.ts b/packages/sim-entrada-eventos/infrastructure/orderRoutes.http.ts index 2c1fbfb..9d4d574 100644 --- a/packages/sim-entrada-eventos/infrastructure/orderRoutes.http.ts +++ b/packages/sim-entrada-eventos/infrastructure/orderRoutes.http.ts @@ -28,13 +28,17 @@ const orderController = new OrderController({ * */ orderRoutes.get("/", (req, res) => { res.send("ok") }) -orderRoutes.get("/message_id/:correlation_id", orderController.getByQueueId()) +/* + * Ahora es el id de bdd + * */ +orderRoutes.get("/message_id/:id", orderController.getById()) /** Operaciones pendientes */ orderRoutes.get("/pending", orderController.getPending()) /** Order por id (uuid del mensaje) */ -orderRoutes.get("/:id", orderController.getById()) +// TODO: falla +orderRoutes.get("/:id", orderController.getByQueueId()) export { orderRoutes } diff --git a/packages/sim-entrada-eventos/infrastructure/simconnectionsRoutes.ts b/packages/sim-entrada-eventos/infrastructure/simconnectionsRoutes.ts index 3f04022..b66e154 100644 --- a/packages/sim-entrada-eventos/infrastructure/simconnectionsRoutes.ts +++ b/packages/sim-entrada-eventos/infrastructure/simconnectionsRoutes.ts @@ -9,8 +9,7 @@ export const connectionsRoutes = Router() const CONNECTIONS_URL = env.CONNECTIONS_URL// TODO: Meter al ENV //const CONNECTIONS_URL = "http://sf-nfc-server.savefamilygps.net" -console.log("CONNURL: ", CONNECTIONS_URL) - +//console.log("CONNURL: ", CONNECTIONS_URL) connectionsRoutes.use("", createProxyMiddleware({ target: CONNECTIONS_URL, changeOrigin: true, diff --git a/packages/sim-shared/domain/Order.ts b/packages/sim-shared/domain/Order.ts index df1c2f3..027228e 100644 --- a/packages/sim-shared/domain/Order.ts +++ b/packages/sim-shared/domain/Order.ts @@ -94,4 +94,19 @@ export type ErrorOrderDTO = stackTrace?: string } - +/* + * Se considera cada entrada de conditions como un filtro sobre un campo + * cada fila se podrá expresar como campo:filtro + * ```json + * { + * "value": "-gte 200" // Un valor >= 200 + * "text": "-eq 'busqueda' " // El campo tiene que ser exactamente 'busqueada' + * } + * ``` + * TODO: sacar opciones de paginación + * */ +export type OrderQuery = { + conditions: Record, + limit?: number | undefined, + offset?: number | undefined, +} diff --git a/packages/sim-shared/infrastructure/OrderRepository.test.ts b/packages/sim-shared/infrastructure/OrderRepository.test.ts index 4636fe3..e5f1ce2 100644 --- a/packages/sim-shared/infrastructure/OrderRepository.test.ts +++ b/packages/sim-shared/infrastructure/OrderRepository.test.ts @@ -1,8 +1,9 @@ import { before, describe, it } from "node:test"; import { OrderRepository } from "./OrderRepository.js"; -import { CreateOrderDTO } from "../domain/Order.js"; +import { CreateOrderDTO, OrderQuery } from "../domain/Order.js"; import { postgresClient } from "../config/config.test.js"; import assert from "node:assert"; +import { Query } from "pg"; const order1 = { correlation_id: "fakeRMQid-1234", @@ -169,4 +170,16 @@ describe("Test OrderRepository", {}, (ctx) => { assert(result.data.status === "dlx") assert(result.data.finish_date != null) }) + + it("Query generates with parameters", async () => { + const params: OrderQuery = { + conditions: { + status: "-eq 'pending'" + } + } + //@ts-expect-error + const res = orderRepo.generateTableQuery("test", params) + console.log("Query:", res) + assert.ok(res != undefined) + }) }) diff --git a/packages/sim-shared/infrastructure/OrderRepository.ts b/packages/sim-shared/infrastructure/OrderRepository.ts index 26d05f0..1faa675 100644 --- a/packages/sim-shared/infrastructure/OrderRepository.ts +++ b/packages/sim-shared/infrastructure/OrderRepository.ts @@ -2,7 +2,7 @@ * TODO: Usar */ import { PoolClient, QueryResult, QueryResultRow } from "pg"; -import { CreateOrderDTO, ErrorOrderDTO, FinishOrderDTO, OrderTracking, UpdateOrderDTO } from "../domain/Order.js"; +import { CreateOrderDTO, ErrorOrderDTO, FinishOrderDTO, OrderQuery, OrderTracking, UpdateOrderDTO } from "../domain/Order.js"; import { Result, tryCatch } from "../domain/Result.js"; import { PgClient } from "./PgClient.js"; import assert from "node:assert"; @@ -55,7 +55,77 @@ export class OrderRepository { } } + /** + * Mapeo de prefijos a operadores SQL + */ + private OPERATOR_MAP: Record = { + "-eq": "=", + "-neq": "!=", + "-gt": ">", + "-gte": ">=", + "-lt": "<", + "-lte": "<=", + "-like": "LIKE", + }; + /** + * Tabla general para sacar datos de la tabla en base a unas condiciones + * TODO: + * - Dar la opción de generar los campos a devolver en vez de * + * - Garantizar el numero de parametros de respuesta + */ + private generateTableQuery(table: string, query: OrderQuery) { + const { conditions, limit, offset } = query; + const whereClauses: string[] = []; + const queryValues: any[] = []; + + let paramIndex = 1; // Para los parametros de PostgreSQL ($1, $2) (que empiezan por 1) + + for (const [column, filter] of Object.entries(conditions)) { + const match = filter.match(/^(-\w+)\s+(.+)$/); + + if (match) { + const [_, prefix, value] = match; + const operator = this.OPERATOR_MAP[prefix]; + + if (operator) { + // Eliminación de comillas + const cleanValue = value.replace(/^'|'$/g, ""); + + whereClauses.push(`${column} ${operator} $${paramIndex}`); + queryValues.push(operator === "LIKE" ? `%${cleanValue}%` : cleanValue); + paramIndex++; + } + } + } + + // 2. Query completa + // TODO: Cambair el * por parametros + let sql = `SELECT * FROM ${table}`; + + if (whereClauses.length > 0) { + sql += ` WHERE ${whereClauses.join(" AND ")}`; + } + + // 3. Paginacion + if (limit !== undefined) { + sql += ` LIMIT ${Number(limit)}`; + } + if (offset !== undefined) { + sql += ` OFFSET ${Number(offset)}`; + } + + return { + sql, + values: queryValues, + }; + } + + public async getOrdersByQuery(args: OrderQuery) { + const query = this.generateTableQuery('order_tracking', args) + const queryPromise = this.pgClient.query>>(query.sql, query.values) + const result = await this.getAll(queryPromise) + } /** * El tipo representa el contenido del mensaje de los order