@jrosadob/ms-sophia-framework-mysql 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +101 -0
  2. package/package.json +105 -0
package/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # Sophia Framework
2
+
3
+ ## v47
4
+ Define propiedes dinamicas para el datasource:
5
+ entities, subscribers, synchronize, logging, logger: typeOrmLogger
6
+
7
+
8
+
9
+ ## Publish
10
+ + Actualizar version in package.json
11
+ + Run `./publish.sh`
12
+
13
+ ## CLI
14
+
15
+ ```bash
16
+ $ pnpm install
17
+ $ pnpm add @nestjs/config # Install package
18
+ $ pnpm run start # Development
19
+ $ pnpm run start:dev # Wath mode
20
+ $ pnpm run start:prod # Production mode
21
+
22
+ $ pnpm run test # Unit tests
23
+ $ pnpm run test:e2e # e2e tests
24
+ $ pnpm run test:cov # Coverage test
25
+ ```
26
+
27
+ ## Packages
28
+
29
+ ```bash
30
+ pnpm add @nestjs/config
31
+ pnpm add @nestjs/swagger
32
+ pnpm add @nestjs/typeorm
33
+ pnpm add axios
34
+ pnpm add class-transformer
35
+ pnpm add class-validator
36
+ pnpm add js
37
+ pnpm add js-yaml
38
+ pnpm add mysql2
39
+ pnpm add nanoid
40
+ pnpm add typeorm
41
+ pnpm add @nestjs/microservices
42
+ ```
43
+
44
+ ## PreHook
45
+
46
+ ```bash
47
+ app.useGlobalInterceptors(new LoggingInterceptor(configService));
48
+ app.useGlobalFilters(new AllExceptionsFilter());
49
+ ```
50
+
51
+ ## Idempotencia de Controladores TCP
52
+ Asegurarse de que sea idempotente
53
+ Si es para traer datos no hay problema
54
+ Pero si es para guardar datos, debe usarse una transaccion con una tabla que tiene PK ms-accounts, module-name y method-name.
55
+ Si todo sale bien enviar el ACK.
56
+ Si se detacto duplicado no ejecutar el metodo de negocio, pero enviar el ACK para que RabbitMQ no siga enviando mensajes.
57
+ ```TS
58
+ @MessagePattern({ cmd: 'charge' })
59
+ async handleCharge(@Payload() data: any, @Ctx() ctx: RmqContext) {
60
+ const channel = ctx.getChannelRef();
61
+ const msg = ctx.getMessage();
62
+
63
+ const key =
64
+ msg.properties?.headers?.['x-idempotency-key'] ||
65
+ msg.properties?.messageId;
66
+
67
+ if (!key) {
68
+ // Sin clave no hay deduplicación confiable
69
+ // Decide: rechazar o procesar con riesgo
70
+ channel.nack(msg, false, false);
71
+ return;
72
+ }
73
+
74
+ try {
75
+ await this.dataSource.transaction(async (manager) => {
76
+ // 1) Intentar registrar el mensaje
77
+ // Si falla por unique, es duplicado
78
+ await manager.query(
79
+ `INSERT INTO processed_messages (consumer_name, message_key)
80
+ VALUES (?, ?)`,
81
+ ['payments-consumer', key],
82
+ );
83
+
84
+ // 2) Lógica de negocio real (solo primera vez)
85
+ await this.paymentService.charge(data, manager);
86
+ });
87
+
88
+ // 3) Confirmar
89
+ channel.ack(msg);
90
+ } catch (e: any) {
91
+ // Duplicado por unique constraint: confirmar y salir
92
+ if (isDuplicateKeyError(e)) {
93
+ channel.ack(msg);
94
+ return;
95
+ }
96
+
97
+ // Error real: reintentar o enviar a DLQ según estrategia
98
+ channel.nack(msg, false, true);
99
+ }
100
+ }
101
+ ```
package/package.json ADDED
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "@jrosadob/ms-sophia-framework-mysql",
3
+ "version": "0.0.1",
4
+ "description": "Sophia Framework para microservicios en NestJS",
5
+ "main": "dist/core/index.js",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "peerDependencies": {
10
+ "@nestjs/common": "^11.0.1"
11
+ },
12
+ "keywords": [
13
+ "nest",
14
+ "nestjs",
15
+ "sophia",
16
+ "framework",
17
+ "microservices"
18
+ ],
19
+ "author": {
20
+ "name": "Javier A. Rosado Baltazar",
21
+ "email": "jrosadob@hotmail.com"
22
+ },
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "license": "MIT",
27
+ "dependencies": {
28
+ "@nestjs/common": "^11.0.1",
29
+ "@nestjs/config": "^4.0.2",
30
+ "@nestjs/core": "^11.0.1",
31
+ "@nestjs/microservices": "^11.1.27",
32
+ "@nestjs/platform-express": "^11.0.1",
33
+ "@nestjs/swagger": "^11.2.0",
34
+ "@nestjs/typeorm": "^11.0.0",
35
+ "amqp-connection-manager": "^5.0.0",
36
+ "amqplib": "^2.0.1",
37
+ "axios": "^1.12.2",
38
+ "class-transformer": "^0.5.1",
39
+ "class-validator": "^0.14.2",
40
+ "dotenv": "^17.2.3",
41
+ "js": "^0.1.0",
42
+ "js-yaml": "^4.1.0",
43
+ "mysql2": "^3.14.5",
44
+ "nanoid": "^5.1.5",
45
+ "reflect-metadata": "^0.2.2",
46
+ "rxjs": "^7.8.1",
47
+ "typeorm": "^0.3.26"
48
+ },
49
+ "devDependencies": {
50
+ "@eslint/eslintrc": "^3.2.0",
51
+ "@eslint/js": "^9.18.0",
52
+ "@nestjs/cli": "^11.0.0",
53
+ "@nestjs/schematics": "^11.0.0",
54
+ "@nestjs/testing": "^11.0.1",
55
+ "@types/express": "^5.0.0",
56
+ "@types/jest": "^30.0.0",
57
+ "@types/node": "^22.10.7",
58
+ "@types/supertest": "^6.0.2",
59
+ "eslint": "^9.18.0",
60
+ "eslint-config-prettier": "^10.0.1",
61
+ "eslint-plugin-prettier": "^5.2.2",
62
+ "globals": "^16.0.0",
63
+ "jest": "^30.0.0",
64
+ "prettier": "^3.4.2",
65
+ "source-map-support": "^0.5.21",
66
+ "supertest": "^7.0.0",
67
+ "ts-jest": "^29.2.5",
68
+ "ts-loader": "^9.5.2",
69
+ "ts-node": "^10.9.2",
70
+ "tsconfig-paths": "^4.2.0",
71
+ "typescript": "^5.7.3",
72
+ "typescript-eslint": "^8.20.0"
73
+ },
74
+ "jest": {
75
+ "moduleFileExtensions": [
76
+ "js",
77
+ "json",
78
+ "ts"
79
+ ],
80
+ "rootDir": "src",
81
+ "testRegex": ".*\\.spec\\.ts$",
82
+ "transform": {
83
+ "^.+\\.(t|j)s$": "ts-jest"
84
+ },
85
+ "collectCoverageFrom": [
86
+ "**/*.(t|j)s"
87
+ ],
88
+ "coverageDirectory": "../coverage",
89
+ "testEnvironment": "node"
90
+ },
91
+ "scripts": {
92
+ "build": "nest build",
93
+ "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
94
+ "start": "nest start",
95
+ "start:dev": "nest start --watch",
96
+ "start:debug": "nest start --debug --watch",
97
+ "start:prod": "node dist/main",
98
+ "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
99
+ "test": "jest",
100
+ "test:watch": "jest --watch",
101
+ "test:cov": "jest --coverage",
102
+ "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
103
+ "test:e2e": "jest --config ./test/jest-e2e.json"
104
+ }
105
+ }