Forráskód Böngészése

feat: add operation logging and response interceptors

- Implemented OperationLogInterceptor for logging operations with options for success and error responses.
- Created ResponseInterceptor to standardize API responses, including error handling.
- Defined ApiResponse and PaginatedApiResponse interfaces for consistent response structure.
- Developed ExceptionService for handling exceptions and generating appropriate HTTP responses.
- Introduced MongoPrismaService and MysqlPrismaService for MongoDB and MySQL database interactions.
- Added SharedModule to encapsulate common services and modules, including PrismaModule and UtilsService.
- Updated package.json to correct the start script for the management API.
Dave 4 hónapja
szülő
commit
50c156ea6f
63 módosított fájl, 909 hozzáadás és 3 törlés
  1. 2 1
      apps/box-app-api/tsconfig.json
  2. 2 1
      apps/box-mgnt-api/tsconfig.json
  3. 2 0
      libs/common/src/common.module.d.ts
  4. 55 0
      libs/common/src/common.module.js
  5. 1 0
      libs/common/src/common.module.js.map
  6. 8 0
      libs/common/src/config/pino.config.d.ts
  7. 46 0
      libs/common/src/config/pino.config.js
  8. 1 0
      libs/common/src/config/pino.config.js.map
  9. 2 0
      libs/common/src/crypto/aes-gcm.d.ts
  10. 40 0
      libs/common/src/crypto/aes-gcm.js
  11. 1 0
      libs/common/src/crypto/aes-gcm.js.map
  12. 1 0
      libs/common/src/decorators/auth-user.decorator.d.ts
  13. 9 0
      libs/common/src/decorators/auth-user.decorator.js
  14. 1 0
      libs/common/src/decorators/auth-user.decorator.js.map
  15. 10 0
      libs/common/src/decorators/operation-log.decorator.d.ts
  16. 16 0
      libs/common/src/decorators/operation-log.decorator.js
  17. 1 0
      libs/common/src/decorators/operation-log.decorator.js.map
  18. 4 0
      libs/common/src/dto/page-list.dto.d.ts
  19. 38 0
      libs/common/src/dto/page-list.dto.js
  20. 1 0
      libs/common/src/dto/page-list.dto.js.map
  21. 6 0
      libs/common/src/filters/http-exception.filter.d.ts
  22. 81 0
      libs/common/src/filters/http-exception.filter.js
  23. 0 0
      libs/common/src/filters/http-exception.filter.js.map
  24. 13 0
      libs/common/src/guards/rate-limit.guard.d.ts
  25. 89 0
      libs/common/src/guards/rate-limit.guard.js
  26. 0 0
      libs/common/src/guards/rate-limit.guard.js.map
  27. 5 0
      libs/common/src/interceptors/correlation.interceptor.d.ts
  28. 31 0
      libs/common/src/interceptors/correlation.interceptor.js
  29. 1 0
      libs/common/src/interceptors/correlation.interceptor.js.map
  30. 6 0
      libs/common/src/interceptors/logging.interceptor.d.ts
  31. 32 0
      libs/common/src/interceptors/logging.interceptor.js
  32. 1 0
      libs/common/src/interceptors/logging.interceptor.js.map
  33. 14 0
      libs/common/src/interceptors/operation-log.interceptor.d.ts
  34. 60 0
      libs/common/src/interceptors/operation-log.interceptor.js
  35. 1 0
      libs/common/src/interceptors/operation-log.interceptor.js.map
  36. 5 0
      libs/common/src/interceptors/response.interceptor.d.ts
  37. 32 0
      libs/common/src/interceptors/response.interceptor.js
  38. 1 0
      libs/common/src/interceptors/response.interceptor.js.map
  39. 13 0
      libs/common/src/interfaces/api-response.interface.d.ts
  40. 3 0
      libs/common/src/interfaces/api-response.interface.js
  41. 1 0
      libs/common/src/interfaces/api-response.interface.js.map
  42. 7 0
      libs/common/src/interfaces/operation-logger.interface.d.ts
  43. 5 0
      libs/common/src/interfaces/operation-logger.interface.js
  44. 1 0
      libs/common/src/interfaces/operation-logger.interface.js.map
  45. 8 0
      libs/common/src/services/exception.service.d.ts
  46. 78 0
      libs/common/src/services/exception.service.js
  47. 1 0
      libs/common/src/services/exception.service.js.map
  48. 6 0
      libs/db/src/prisma/mongo-prisma.service.d.ts
  49. 24 0
      libs/db/src/prisma/mongo-prisma.service.js
  50. 1 0
      libs/db/src/prisma/mongo-prisma.service.js.map
  51. 6 0
      libs/db/src/prisma/mysql-prisma.service.d.ts
  52. 24 0
      libs/db/src/prisma/mysql-prisma.service.js
  53. 1 0
      libs/db/src/prisma/mysql-prisma.service.js.map
  54. 2 0
      libs/db/src/prisma/prisma.module.d.ts
  55. 22 0
      libs/db/src/prisma/prisma.module.js
  56. 1 0
      libs/db/src/prisma/prisma.module.js.map
  57. 2 0
      libs/db/src/shared.module.d.ts
  58. 25 0
      libs/db/src/shared.module.js
  59. 1 0
      libs/db/src/shared.module.js.map
  60. 7 0
      libs/db/src/utils.service.d.ts
  61. 49 0
      libs/db/src/utils.service.js
  62. 1 0
      libs/db/src/utils.service.js.map
  63. 1 1
      package.json

+ 2 - 1
apps/box-app-api/tsconfig.json

@@ -1,7 +1,8 @@
 {
   "extends": "../../tsconfig.json",
   "compilerOptions": {
-    "outDir": "../../dist/apps/box-app-api"
+    "outDir": "../../dist",
+    "rootDir": "../../"
   },
   "include": ["src/**/*.ts"]
 }

+ 2 - 1
apps/box-mgnt-api/tsconfig.json

@@ -1,7 +1,8 @@
 {
   "extends": "../../tsconfig.base.json",
   "compilerOptions": {
-    "outDir": "../../dist/apps/box-mgnt-api"
+    "outDir": "../../dist",
+    "rootDir": "../../"
   },
   "include": ["src/**/*"],
   "exclude": ["node_modules", "dist", "test", "**/*spec.ts"]

+ 2 - 0
libs/common/src/common.module.d.ts

@@ -0,0 +1,2 @@
+export declare class CommonModule {
+}

+ 55 - 0
libs/common/src/common.module.js

@@ -0,0 +1,55 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+    return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.CommonModule = void 0;
+const common_1 = require("@nestjs/common");
+const core_1 = require("@nestjs/core");
+const nestjs_pino_1 = require("nestjs-pino");
+const pino_config_1 = __importDefault(require("./config/pino.config"));
+const http_exception_filter_1 = require("./filters/http-exception.filter");
+const logging_interceptor_1 = require("./interceptors/logging.interceptor");
+const operation_log_interceptor_1 = require("./interceptors/operation-log.interceptor");
+const response_interceptor_1 = require("./interceptors/response.interceptor");
+const correlation_interceptor_1 = require("./interceptors/correlation.interceptor");
+const exception_service_1 = require("./services/exception.service");
+let CommonModule = class CommonModule {
+};
+exports.CommonModule = CommonModule;
+exports.CommonModule = CommonModule = __decorate([
+    (0, common_1.Module)({
+        imports: [nestjs_pino_1.LoggerModule.forRoot(pino_config_1.default)],
+        providers: [
+            {
+                provide: core_1.APP_INTERCEPTOR,
+                useClass: correlation_interceptor_1.CorrelationInterceptor,
+            },
+            {
+                provide: core_1.APP_INTERCEPTOR,
+                useClass: logging_interceptor_1.LoggingInterceptor,
+            },
+            {
+                provide: core_1.APP_INTERCEPTOR,
+                useClass: operation_log_interceptor_1.OperationLogInterceptor,
+            },
+            {
+                provide: core_1.APP_INTERCEPTOR,
+                useClass: response_interceptor_1.ResponseInterceptor,
+            },
+            {
+                provide: core_1.APP_FILTER,
+                useClass: http_exception_filter_1.HttpExceptionFilter,
+            },
+            exception_service_1.ExceptionService,
+        ],
+        exports: [],
+    })
+], CommonModule);
+//# sourceMappingURL=common.module.js.map

+ 1 - 0
libs/common/src/common.module.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"common.module.js","sourceRoot":"","sources":["common.module.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAwC;AACxC,uCAA2D;AAC3D,6CAA2C;AAC3C,uEAA8C;AAC9C,2EAAsE;AACtE,4EAAwE;AACxE,wFAAmF;AACnF,8EAA0E;AAC1E,oFAAgF;AAChF,oEAAgE;AA6BzD,IAAM,YAAY,GAAlB,MAAM,YAAY;CAAG,CAAA;AAAf,oCAAY;uBAAZ,YAAY;IA3BxB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,0BAAY,CAAC,OAAO,CAAC,qBAAU,CAAC,CAAC;QAC3C,SAAS,EAAE;YACT;gBACE,OAAO,EAAE,sBAAe;gBACxB,QAAQ,EAAE,gDAAsB;aACjC;YACD;gBACE,OAAO,EAAE,sBAAe;gBACxB,QAAQ,EAAE,wCAAkB;aAC7B;YACD;gBACE,OAAO,EAAE,sBAAe;gBACxB,QAAQ,EAAE,mDAAuB;aAClC;YACD;gBACE,OAAO,EAAE,sBAAe;gBACxB,QAAQ,EAAE,0CAAmB;aAC9B;YACD;gBACE,OAAO,EAAE,iBAAU;gBACnB,QAAQ,EAAE,2CAAmB;aAC9B;YACD,oCAAgB;SACjB;QACD,OAAO,EAAE,EAAE;KACZ,CAAC;GACW,YAAY,CAAG"}

+ 8 - 0
libs/common/src/config/pino.config.d.ts

@@ -0,0 +1,8 @@
+import pino from 'pino';
+declare const _default: {
+    pinoHttp: {
+        stream: pino.MultiStreamRes<pino.Level>;
+        autoLogging: boolean;
+    };
+};
+export default _default;

+ 46 - 0
libs/common/src/config/pino.config.js

@@ -0,0 +1,46 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+    return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+const pino_1 = __importDefault(require("pino"));
+const path_1 = require("path");
+const logDir = (0, path_1.join)(process.cwd(), 'logs');
+exports.default = {
+    pinoHttp: {
+        stream: pino_1.default.multistream([
+            pino_1.default.transport({
+                target: 'pino-pretty',
+                options: {
+                    colorize: true,
+                    translateTime: 'SYS:yyyy-mm-dd HH:MM:ss.l',
+                    ignore: 'pid,hostname,context,req,res',
+                    messageFormat: '{if context}[{context}] {end}{msg}',
+                },
+            }),
+            pino_1.default.transport({
+                target: 'pino/file',
+                options: {
+                    destination: (0, path_1.join)(logDir, 'info.log'),
+                    mkdir: true,
+                },
+                level: 'info',
+            }),
+            pino_1.default.transport({
+                target: 'pino-pretty',
+                options: {
+                    colorize: false,
+                    translateTime: 'SYS:yyyy-mm-dd HH:MM:ss.l',
+                    messageFormat: '[ERROR] [{context}] {msg}',
+                    ignore: 'pid,hostname,req,res',
+                    destination: (0, path_1.join)(logDir, 'error.log'),
+                    append: true,
+                    mkdir: true,
+                },
+                level: 'error',
+            }),
+        ]),
+        autoLogging: false,
+    },
+};
+//# sourceMappingURL=pino.config.js.map

+ 1 - 0
libs/common/src/config/pino.config.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"pino.config.js","sourceRoot":"","sources":["pino.config.ts"],"names":[],"mappings":";;;;;AACA,gDAAwB;AACxB,+BAA4B;AAE5B,MAAM,MAAM,GAAG,IAAA,WAAI,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;AAE3C,kBAAe;IACb,QAAQ,EAAE;QACR,MAAM,EAAE,cAAI,CAAC,WAAW,CAAC;YAEvB,cAAI,CAAC,SAAS,CAAC;gBACb,MAAM,EAAE,aAAa;gBACrB,OAAO,EAAE;oBACP,QAAQ,EAAE,IAAI;oBACd,aAAa,EAAE,2BAA2B;oBAC1C,MAAM,EAAE,8BAA8B;oBACtC,aAAa,EAAE,oCAAoC;iBACpD;aACF,CAAC;YAGF,cAAI,CAAC,SAAS,CAAC;gBACb,MAAM,EAAE,WAAW;gBACnB,OAAO,EAAE;oBACP,WAAW,EAAE,IAAA,WAAI,EAAC,MAAM,EAAE,UAAU,CAAC;oBACrC,KAAK,EAAE,IAAI;iBACZ;gBACD,KAAK,EAAE,MAAM;aACd,CAAC;YAGF,cAAI,CAAC,SAAS,CAAC;gBACb,MAAM,EAAE,aAAa;gBACrB,OAAO,EAAE;oBACP,QAAQ,EAAE,KAAK;oBACf,aAAa,EAAE,2BAA2B;oBAC1C,aAAa,EAAE,2BAA2B;oBAC1C,MAAM,EAAE,sBAAsB;oBAC9B,WAAW,EAAE,IAAA,WAAI,EAAC,MAAM,EAAE,WAAW,CAAC;oBACtC,MAAM,EAAE,IAAI;oBACZ,KAAK,EAAE,IAAI;iBACZ;gBACD,KAAK,EAAE,OAAO;aACf,CAAC;SACH,CAAC;QACF,WAAW,EAAE,KAAK;KACnB;CACF,CAAC"}

+ 2 - 0
libs/common/src/crypto/aes-gcm.d.ts

@@ -0,0 +1,2 @@
+export declare function aesGcmEncrypt(plaintext: string): string;
+export declare function aesGcmDecrypt(payloadB64: string): string;

+ 40 - 0
libs/common/src/crypto/aes-gcm.js

@@ -0,0 +1,40 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+    return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.aesGcmEncrypt = aesGcmEncrypt;
+exports.aesGcmDecrypt = aesGcmDecrypt;
+const crypto_1 = __importDefault(require("crypto"));
+function getKey() {
+    var _a;
+    const keyB64 = (_a = process.env.TWOFA_ENC_KEY) !== null && _a !== void 0 ? _a : '';
+    if (!keyB64) {
+        throw new Error('TWOFA_ENC_KEY is required');
+    }
+    const buf = Buffer.from(keyB64, 'base64');
+    if (buf.length !== 32) {
+        throw new Error('TWOFA_ENC_KEY must be 32 bytes when decoded from base64');
+    }
+    return buf;
+}
+function aesGcmEncrypt(plaintext) {
+    const KEY = getKey();
+    const iv = crypto_1.default.randomBytes(12);
+    const cipher = crypto_1.default.createCipheriv('aes-256-gcm', KEY, iv);
+    const enc = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
+    const tag = cipher.getAuthTag();
+    return Buffer.concat([iv, tag, enc]).toString('base64');
+}
+function aesGcmDecrypt(payloadB64) {
+    const KEY = getKey();
+    const buf = Buffer.from(payloadB64, 'base64');
+    const iv = buf.subarray(0, 12);
+    const tag = buf.subarray(12, 28);
+    const enc = buf.subarray(28);
+    const decipher = crypto_1.default.createDecipheriv('aes-256-gcm', KEY, iv);
+    decipher.setAuthTag(tag);
+    const dec = Buffer.concat([decipher.update(enc), decipher.final()]);
+    return dec.toString('utf8');
+}
+//# sourceMappingURL=aes-gcm.js.map

+ 1 - 0
libs/common/src/crypto/aes-gcm.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"aes-gcm.js","sourceRoot":"","sources":["aes-gcm.ts"],"names":[],"mappings":";;;;;AAcA,sCAOC;AAED,sCAUC;AAjCD,oDAA4B;AAE5B,SAAS,MAAM;;IACb,MAAM,MAAM,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,aAAa,mCAAI,EAAE,CAAC;IAC/C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC1C,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAgB,aAAa,CAAC,SAAiB;IAC7C,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,GAAG,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,gBAAM,CAAC,cAAc,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAC7D,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC9E,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IAChC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC1D,CAAC;AAED,SAAgB,aAAa,CAAC,UAAkB;IAC9C,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC9C,MAAM,EAAE,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACjC,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC7B,MAAM,QAAQ,GAAG,gBAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IACjE,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACpE,OAAO,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC"}

+ 1 - 0
libs/common/src/decorators/auth-user.decorator.d.ts

@@ -0,0 +1 @@
+export declare const AuthUser: (...dataOrPipes: any[]) => ParameterDecorator;

+ 9 - 0
libs/common/src/decorators/auth-user.decorator.js

@@ -0,0 +1,9 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.AuthUser = void 0;
+const common_1 = require("@nestjs/common");
+exports.AuthUser = (0, common_1.createParamDecorator)((_data, ctx) => {
+    const req = ctx.switchToHttp().getRequest();
+    return req.user;
+});
+//# sourceMappingURL=auth-user.decorator.js.map

+ 1 - 0
libs/common/src/decorators/auth-user.decorator.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"auth-user.decorator.js","sourceRoot":"","sources":["auth-user.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAAwE;AAQ3D,QAAA,QAAQ,GAAG,IAAA,6BAAoB,EAC1C,CAAC,KAAK,EAAE,GAAqB,EAAQ,EAAE;IACrC,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAAwB,CAAC;IAClE,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC,CACF,CAAC"}

+ 10 - 0
libs/common/src/decorators/operation-log.decorator.d.ts

@@ -0,0 +1,10 @@
+import { OperationType } from '@prisma/mysql/client';
+export declare const OPERATION_LOG_KEY = "operationLog";
+export interface OperationLogOptions {
+    description: string;
+    type: OperationType;
+    frontendAuth: string;
+    isSaveRequest: boolean;
+    isSaveResponse: boolean;
+}
+export declare const OperationLog: (description: string, type: OperationType, frontendAuth: string, isSaveRequest?: boolean, isSaveResponse?: boolean) => import("@nestjs/common").CustomDecorator<string>;

+ 16 - 0
libs/common/src/decorators/operation-log.decorator.js

@@ -0,0 +1,16 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.OperationLog = exports.OPERATION_LOG_KEY = void 0;
+const common_1 = require("@nestjs/common");
+exports.OPERATION_LOG_KEY = 'operationLog';
+const OperationLog = (description, type, frontendAuth, isSaveRequest = true, isSaveResponse = true) => {
+    return (0, common_1.SetMetadata)(exports.OPERATION_LOG_KEY, {
+        description,
+        type,
+        frontendAuth,
+        isSaveRequest,
+        isSaveResponse,
+    });
+};
+exports.OperationLog = OperationLog;
+//# sourceMappingURL=operation-log.decorator.js.map

+ 1 - 0
libs/common/src/decorators/operation-log.decorator.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"operation-log.decorator.js","sourceRoot":"","sources":["operation-log.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAGhC,QAAA,iBAAiB,GAAG,cAAc,CAAC;AAkBzC,MAAM,YAAY,GAAG,CAC1B,WAAmB,EACnB,IAAmB,EACnB,YAAoB,EACpB,aAAa,GAAG,IAAI,EACpB,cAAc,GAAG,IAAI,EACrB,EAAE;IACF,OAAO,IAAA,oBAAW,EAAC,yBAAiB,EAAE;QACpC,WAAW;QACX,IAAI;QACJ,YAAY;QACZ,aAAa;QACb,cAAc;KACQ,CAAC,CAAC;AAC5B,CAAC,CAAC;AAdW,QAAA,YAAY,gBAcvB"}

+ 4 - 0
libs/common/src/dto/page-list.dto.d.ts

@@ -0,0 +1,4 @@
+export declare class PageListDto {
+    page: number;
+    size: number;
+}

+ 38 - 0
libs/common/src/dto/page-list.dto.js

@@ -0,0 +1,38 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var __metadata = (this && this.__metadata) || function (k, v) {
+    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.PageListDto = void 0;
+const swagger_1 = require("@nestjs/swagger");
+const class_validator_1 = require("class-validator");
+class PageListDto {
+}
+exports.PageListDto = PageListDto;
+__decorate([
+    (0, swagger_1.ApiProperty)({
+        description: 'Page number (starts from 1)',
+        example: 1,
+        default: 1,
+    }),
+    (0, class_validator_1.IsInt)(),
+    (0, class_validator_1.Min)(1),
+    __metadata("design:type", Number)
+], PageListDto.prototype, "page", void 0);
+__decorate([
+    (0, swagger_1.ApiProperty)({
+        description: 'Number of records per page',
+        example: 10,
+        default: 10,
+    }),
+    (0, class_validator_1.IsInt)(),
+    (0, class_validator_1.Min)(1),
+    __metadata("design:type", Number)
+], PageListDto.prototype, "size", void 0);
+//# sourceMappingURL=page-list.dto.js.map

+ 1 - 0
libs/common/src/dto/page-list.dto.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"page-list.dto.js","sourceRoot":"","sources":["page-list.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAC9C,qDAA6C;AAE7C,MAAa,WAAW;CAkBvB;AAlBD,kCAkBC;AAVC;IAPC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,6BAA6B;QAC1C,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;KACX,CAAC;IACD,IAAA,uBAAK,GAAE;IACP,IAAA,qBAAG,EAAC,CAAC,CAAC;;yCACM;AASb;IAPC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,4BAA4B;QACzC,OAAO,EAAE,EAAE;QACX,OAAO,EAAE,EAAE;KACZ,CAAC;IACD,IAAA,uBAAK,GAAE;IACP,IAAA,qBAAG,EAAC,CAAC,CAAC;;yCACM"}

+ 6 - 0
libs/common/src/filters/http-exception.filter.d.ts

@@ -0,0 +1,6 @@
+import { ArgumentsHost, ExceptionFilter } from '@nestjs/common';
+export declare class HttpExceptionFilter implements ExceptionFilter {
+    private readonly logger;
+    catch(exception: unknown, host: ArgumentsHost): void;
+    private mapStatusToCode;
+}

+ 81 - 0
libs/common/src/filters/http-exception.filter.js

@@ -0,0 +1,81 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var HttpExceptionFilter_1;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.HttpExceptionFilter = void 0;
+const common_1 = require("@nestjs/common");
+let HttpExceptionFilter = HttpExceptionFilter_1 = class HttpExceptionFilter {
+    constructor() {
+        this.logger = new common_1.Logger(HttpExceptionFilter_1.name);
+    }
+    catch(exception, host) {
+        const ctx = host.switchToHttp();
+        const response = ctx.getResponse();
+        const request = ctx.getRequest();
+        const status = exception instanceof common_1.HttpException
+            ? exception.getStatus()
+            : common_1.HttpStatus.INTERNAL_SERVER_ERROR;
+        const exceptionResponse = exception instanceof common_1.HttpException ? exception.getResponse() : null;
+        let message;
+        let code;
+        if (typeof exceptionResponse === 'object' && exceptionResponse !== null) {
+            const responseObj = exceptionResponse;
+            if (Array.isArray(responseObj.message)) {
+                message = responseObj.message.join(', ');
+            }
+            else if (typeof responseObj.message === 'string') {
+                message = responseObj.message;
+            }
+            else {
+                message = exception.message || 'Unknown error';
+            }
+            code = responseObj.code || this.mapStatusToCode(status);
+        }
+        else {
+            message =
+                exception instanceof Error
+                    ? exception.message
+                    : 'Internal server error';
+            code = this.mapStatusToCode(status);
+        }
+        const apiResponse = {
+            error: message,
+            status: 0,
+            code,
+            data: null,
+            timestamp: new Date().toISOString(),
+        };
+        if (status >= 500) {
+            this.logger.error(`${request.method} ${request.url} - ${status} - ${message}`, exception instanceof Error ? exception.stack : undefined);
+        }
+        else {
+            this.logger.warn(`${request.method} ${request.url} - ${status} - ${message}`);
+        }
+        response.status(200).send(apiResponse);
+    }
+    mapStatusToCode(status) {
+        const codeMap = {
+            400: 'BAD_REQUEST',
+            401: 'UNAUTHORIZED',
+            403: 'FORBIDDEN',
+            404: 'NOT_FOUND',
+            409: 'CONFLICT',
+            422: 'UNPROCESSABLE_ENTITY',
+            429: 'RATE_LIMITED',
+            500: 'INTERNAL_ERROR',
+            502: 'BAD_GATEWAY',
+            503: 'SERVICE_UNAVAILABLE',
+        };
+        return codeMap[status] || `HTTP_${status}`;
+    }
+};
+exports.HttpExceptionFilter = HttpExceptionFilter;
+exports.HttpExceptionFilter = HttpExceptionFilter = HttpExceptionFilter_1 = __decorate([
+    (0, common_1.Catch)()
+], HttpExceptionFilter);
+//# sourceMappingURL=http-exception.filter.js.map

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
libs/common/src/filters/http-exception.filter.js.map


+ 13 - 0
libs/common/src/guards/rate-limit.guard.d.ts

@@ -0,0 +1,13 @@
+import { CanActivate, ExecutionContext } from '@nestjs/common';
+export declare class RateLimitGuard implements CanActivate {
+    private readonly logger;
+    private readonly buckets;
+    private readonly limit;
+    private readonly windowMs;
+    private readonly cleanupInterval;
+    constructor();
+    canActivate(context: ExecutionContext): boolean;
+    private getClientIp;
+    private cleanup;
+    onModuleDestroy(): void;
+}

+ 89 - 0
libs/common/src/guards/rate-limit.guard.js

@@ -0,0 +1,89 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var __metadata = (this && this.__metadata) || function (k, v) {
+    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
+};
+var RateLimitGuard_1;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.RateLimitGuard = void 0;
+const common_1 = require("@nestjs/common");
+let RateLimitGuard = RateLimitGuard_1 = class RateLimitGuard {
+    constructor() {
+        this.logger = new common_1.Logger(RateLimitGuard_1.name);
+        this.buckets = new Map();
+        this.limit = 10;
+        this.windowMs = 60000;
+        this.cleanupInterval = setInterval(() => {
+            this.cleanup();
+        }, 5 * 60000);
+    }
+    canActivate(context) {
+        const request = context.switchToHttp().getRequest();
+        const ip = this.getClientIp(request);
+        const endpoint = `${request.method}:${request.url.split('?')[0]}`;
+        const key = `${ip}:${endpoint}`;
+        const now = Date.now();
+        let bucket = this.buckets.get(key);
+        if (!bucket || now > bucket.resetAt) {
+            bucket = {
+                count: 1,
+                resetAt: now + this.windowMs,
+            };
+            this.buckets.set(key, bucket);
+            return true;
+        }
+        bucket.count++;
+        if (bucket.count > this.limit) {
+            const retryAfter = Math.ceil((bucket.resetAt - now) / 1000);
+            this.logger.warn(`Rate limit exceeded for ${ip} on ${endpoint} (${bucket.count}/${this.limit})`);
+            throw new common_1.HttpException({
+                statusCode: 429,
+                message: `Too many requests. Please try again in ${retryAfter} seconds.`,
+                code: 'RATE_LIMITED',
+                retryAfter,
+            }, common_1.HttpStatus.TOO_MANY_REQUESTS);
+        }
+        return true;
+    }
+    getClientIp(request) {
+        const forwardedFor = request.headers['x-forwarded-for'];
+        if (forwardedFor) {
+            const ips = Array.isArray(forwardedFor) ? forwardedFor[0] : forwardedFor;
+            return ips.split(',')[0].trim();
+        }
+        const realIp = request.headers['x-real-ip'];
+        if (realIp) {
+            return Array.isArray(realIp) ? realIp[0] : realIp;
+        }
+        return request.ip || 'unknown';
+    }
+    cleanup() {
+        const now = Date.now();
+        let cleaned = 0;
+        for (const [key, bucket] of this.buckets.entries()) {
+            if (now > bucket.resetAt) {
+                this.buckets.delete(key);
+                cleaned++;
+            }
+        }
+        if (cleaned > 0) {
+            this.logger.debug(`Cleaned up ${cleaned} expired rate limit buckets`);
+        }
+    }
+    onModuleDestroy() {
+        if (this.cleanupInterval) {
+            clearInterval(this.cleanupInterval);
+        }
+    }
+};
+exports.RateLimitGuard = RateLimitGuard;
+exports.RateLimitGuard = RateLimitGuard = RateLimitGuard_1 = __decorate([
+    (0, common_1.Injectable)(),
+    __metadata("design:paramtypes", [])
+], RateLimitGuard);
+//# sourceMappingURL=rate-limit.guard.js.map

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
libs/common/src/guards/rate-limit.guard.js.map


+ 5 - 0
libs/common/src/interceptors/correlation.interceptor.d.ts

@@ -0,0 +1,5 @@
+import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
+import { Observable } from 'rxjs';
+export declare class CorrelationInterceptor implements NestInterceptor {
+    intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
+}

+ 31 - 0
libs/common/src/interceptors/correlation.interceptor.js

@@ -0,0 +1,31 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.CorrelationInterceptor = void 0;
+const common_1 = require("@nestjs/common");
+const crypto_1 = require("crypto");
+const operators_1 = require("rxjs/operators");
+let CorrelationInterceptor = class CorrelationInterceptor {
+    intercept(context, next) {
+        const ctx = context.switchToHttp();
+        const req = ctx.getRequest();
+        const res = ctx.getResponse();
+        const correlationId = req.headers['x-request-id'] ||
+            req.headers['x-correlation-id'] ||
+            (0, crypto_1.randomUUID)();
+        req.correlationId = correlationId;
+        res.header('x-request-id', correlationId);
+        res.header('x-correlation-id', correlationId);
+        return next.handle().pipe((0, operators_1.tap)(() => { }));
+    }
+};
+exports.CorrelationInterceptor = CorrelationInterceptor;
+exports.CorrelationInterceptor = CorrelationInterceptor = __decorate([
+    (0, common_1.Injectable)()
+], CorrelationInterceptor);
+//# sourceMappingURL=correlation.interceptor.js.map

+ 1 - 0
libs/common/src/interceptors/correlation.interceptor.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"correlation.interceptor.js","sourceRoot":"","sources":["correlation.interceptor.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAKwB;AACxB,mCAAoC;AAGpC,8CAAqC;AAG9B,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;IACjC,SAAS,CAAC,OAAyB,EAAE,IAAiB;QACpD,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,EAAkB,CAAC;QAC7C,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,EAAgB,CAAC;QAG5C,MAAM,aAAa,GAChB,GAAG,CAAC,OAAO,CAAC,cAAc,CAAY;YACtC,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAY;YAC3C,IAAA,mBAAU,GAAE,CAAC;QAGd,GAAW,CAAC,aAAa,GAAG,aAAa,CAAC;QAG3C,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC;QAC1C,GAAG,CAAC,MAAM,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;QAE9C,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAA,eAAG,EAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;CACF,CAAA;AArBY,wDAAsB;iCAAtB,sBAAsB;IADlC,IAAA,mBAAU,GAAE;GACA,sBAAsB,CAqBlC"}

+ 6 - 0
libs/common/src/interceptors/logging.interceptor.d.ts

@@ -0,0 +1,6 @@
+import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
+import { Observable } from 'rxjs';
+export declare class LoggingInterceptor implements NestInterceptor {
+    private readonly logger;
+    intercept(context: ExecutionContext, next: CallHandler): Observable<any>;
+}

+ 32 - 0
libs/common/src/interceptors/logging.interceptor.js

@@ -0,0 +1,32 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var LoggingInterceptor_1;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.LoggingInterceptor = void 0;
+const common_1 = require("@nestjs/common");
+const operators_1 = require("rxjs/operators");
+let LoggingInterceptor = LoggingInterceptor_1 = class LoggingInterceptor {
+    constructor() {
+        this.logger = new common_1.Logger(LoggingInterceptor_1.name);
+    }
+    intercept(context, next) {
+        const req = context.switchToHttp().getRequest();
+        const content = `${req.method} -> ${req.url}`;
+        this.logger.log(`+++ 请求:${content}`);
+        const now = Date.now();
+        return next.handle().pipe((0, operators_1.tap)(() => {
+            const duration = Date.now() - now;
+            this.logger.log(`--- 响应:${content} +${duration}ms`);
+        }));
+    }
+};
+exports.LoggingInterceptor = LoggingInterceptor;
+exports.LoggingInterceptor = LoggingInterceptor = LoggingInterceptor_1 = __decorate([
+    (0, common_1.Injectable)()
+], LoggingInterceptor);
+//# sourceMappingURL=logging.interceptor.js.map

+ 1 - 0
libs/common/src/interceptors/logging.interceptor.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"logging.interceptor.js","sourceRoot":"","sources":["logging.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAMwB;AAGxB,8CAAqC;AAG9B,IAAM,kBAAkB,0BAAxB,MAAM,kBAAkB;IAAxB;QACY,WAAM,GAAG,IAAI,eAAM,CAAC,oBAAkB,CAAC,IAAI,CAAC,CAAC;IAchE,CAAC;IAZC,SAAS,CAAC,OAAyB,EAAE,IAAiB;QACpD,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAkB,CAAC;QAChE,MAAM,OAAO,GAAG,GAAG,GAAG,CAAC,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,eAAG,EAAC,GAAG,EAAE;YACP,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC;QACtD,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF,CAAA;AAfY,gDAAkB;6BAAlB,kBAAkB;IAD9B,IAAA,mBAAU,GAAE;GACA,kBAAkB,CAe9B"}

+ 14 - 0
libs/common/src/interceptors/operation-log.interceptor.d.ts

@@ -0,0 +1,14 @@
+import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
+import { Reflector } from '@nestjs/core';
+import { Observable } from 'rxjs';
+import { ApiResponse } from '../interfaces/api-response.interface';
+import { IOperationLogger } from '../interfaces/operation-logger.interface';
+import { ExceptionService } from '../services/exception.service';
+export declare class OperationLogInterceptor implements NestInterceptor {
+    private readonly reflector;
+    private readonly operationLogger;
+    private readonly exceptionService;
+    constructor(reflector: Reflector, operationLogger: IOperationLogger | null, exceptionService: ExceptionService);
+    intercept(context: ExecutionContext, next: CallHandler): Observable<any>;
+    log(context: ExecutionContext, data: ApiResponse<unknown>, status: boolean): Promise<void>;
+}

+ 60 - 0
libs/common/src/interceptors/operation-log.interceptor.js

@@ -0,0 +1,60 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var __metadata = (this && this.__metadata) || function (k, v) {
+    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
+};
+var __param = (this && this.__param) || function (paramIndex, decorator) {
+    return function (target, key) { decorator(target, key, paramIndex); }
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.OperationLogInterceptor = void 0;
+const common_1 = require("@nestjs/common");
+const core_1 = require("@nestjs/core");
+const operators_1 = require("rxjs/operators");
+const operation_log_decorator_1 = require("../decorators/operation-log.decorator");
+const operation_logger_interface_1 = require("../interfaces/operation-logger.interface");
+const exception_service_1 = require("../services/exception.service");
+let OperationLogInterceptor = class OperationLogInterceptor {
+    constructor(reflector, operationLogger, exceptionService) {
+        this.reflector = reflector;
+        this.operationLogger = operationLogger;
+        this.exceptionService = exceptionService;
+    }
+    intercept(context, next) {
+        return next.handle().pipe((0, operators_1.tap)({
+            next: (data) => {
+                this.log(context, data, true).then();
+            },
+            error: (e) => {
+                const responseObj = this.exceptionService.getHttpResponse(e);
+                this.log(context, responseObj, false).then();
+            },
+        }));
+    }
+    async log(context, data, status) {
+        if (!this.operationLogger) {
+            return;
+        }
+        const options = this.reflector.get(operation_log_decorator_1.OPERATION_LOG_KEY, context.getHandler());
+        if (!options)
+            return;
+        const className = context.getClass().name;
+        const methodKey = context.getHandler().name;
+        const callMethod = `${className}.${methodKey}()`;
+        const req = context.switchToHttp().getRequest();
+        await this.operationLogger.createLog(req, options, data, callMethod, status);
+    }
+};
+exports.OperationLogInterceptor = OperationLogInterceptor;
+exports.OperationLogInterceptor = OperationLogInterceptor = __decorate([
+    (0, common_1.Injectable)(),
+    __param(1, (0, common_1.Optional)()),
+    __param(1, (0, common_1.Inject)(operation_logger_interface_1.OPERATION_LOGGER)),
+    __metadata("design:paramtypes", [core_1.Reflector, Object, exception_service_1.ExceptionService])
+], OperationLogInterceptor);
+//# sourceMappingURL=operation-log.interceptor.js.map

+ 1 - 0
libs/common/src/interceptors/operation-log.interceptor.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"operation-log.interceptor.js","sourceRoot":"","sources":["operation-log.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAOwB;AACxB,uCAAyC;AAGzC,8CAAqC;AACrC,mFAG+C;AAE/C,yFAGkD;AAClD,qEAAiE;AAG1D,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAClC,YACmB,SAAoB,EAGpB,eAAwC,EACxC,gBAAkC;QAJlC,cAAS,GAAT,SAAS,CAAW;QAGpB,oBAAe,GAAf,eAAe,CAAyB;QACxC,qBAAgB,GAAhB,gBAAgB,CAAkB;IAClD,CAAC;IAEJ,SAAS,CAAC,OAAyB,EAAE,IAAiB;QACpD,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,eAAG,EAAC;YACF,IAAI,EAAE,CAAC,IAA0B,EAAE,EAAE;gBACnC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YACvC,CAAC;YACD,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;gBACX,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;gBAC7D,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/C,CAAC;SACF,CAAC,CACH,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,GAAG,CACP,OAAyB,EACzB,IAA0B,EAC1B,MAAe;QAEf,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAE1B,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAChC,2CAAiB,EACjB,OAAO,CAAC,UAAU,EAAE,CACrB,CAAC;QACF,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC;QAC1C,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC;QAC5C,MAAM,UAAU,GAAG,GAAG,SAAS,IAAI,SAAS,IAAI,CAAC;QACjD,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAkB,CAAC;QAEhE,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,CAClC,GAAG,EACH,OAAO,EACP,IAAI,EACJ,UAAU,EACV,MAAM,CACP,CAAC;IACJ,CAAC;CACF,CAAA;AApDY,0DAAuB;kCAAvB,uBAAuB;IADnC,IAAA,mBAAU,GAAE;IAIR,WAAA,IAAA,iBAAQ,GAAE,CAAA;IACV,WAAA,IAAA,eAAM,EAAC,6CAAgB,CAAC,CAAA;qCAFG,gBAAS,UAIF,oCAAgB;GAN1C,uBAAuB,CAoDnC"}

+ 5 - 0
libs/common/src/interceptors/response.interceptor.d.ts

@@ -0,0 +1,5 @@
+import { CallHandler, ExecutionContext, NestInterceptor, StreamableFile } from '@nestjs/common';
+import { ApiResponse } from '../interfaces/api-response.interface';
+export declare class ResponseInterceptor implements NestInterceptor {
+    intercept(_context: ExecutionContext, next: CallHandler): import("rxjs").Observable<ApiResponse<unknown> | StreamableFile>;
+}

+ 32 - 0
libs/common/src/interceptors/response.interceptor.js

@@ -0,0 +1,32 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ResponseInterceptor = void 0;
+const common_1 = require("@nestjs/common");
+const operators_1 = require("rxjs/operators");
+let ResponseInterceptor = class ResponseInterceptor {
+    intercept(_context, next) {
+        return next.handle().pipe((0, operators_1.map)((data) => {
+            if (data instanceof common_1.StreamableFile) {
+                return data;
+            }
+            return {
+                error: '',
+                status: 1,
+                code: 'OK',
+                data,
+                timestamp: new Date().toISOString(),
+            };
+        }));
+    }
+};
+exports.ResponseInterceptor = ResponseInterceptor;
+exports.ResponseInterceptor = ResponseInterceptor = __decorate([
+    (0, common_1.Injectable)()
+], ResponseInterceptor);
+//# sourceMappingURL=response.interceptor.js.map

+ 1 - 0
libs/common/src/interceptors/response.interceptor.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"response.interceptor.js","sourceRoot":"","sources":["response.interceptor.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAMwB;AACxB,8CAAqC;AAI9B,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IAC9B,SAAS,CAAC,QAA0B,EAAE,IAAiB;QACrD,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,eAAG,EAAC,CAAC,IAAI,EAAyC,EAAE;YAClD,IAAI,IAAI,YAAY,uBAAc,EAAE,CAAC;gBACnC,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO;gBACL,KAAK,EAAE,EAAE;gBACT,MAAM,EAAE,CAAC;gBACT,IAAI,EAAE,IAAI;gBACV,IAAI;gBACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC;QACJ,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF,CAAA;AAlBY,kDAAmB;8BAAnB,mBAAmB;IAD/B,IAAA,mBAAU,GAAE;GACA,mBAAmB,CAkB/B"}

+ 13 - 0
libs/common/src/interfaces/api-response.interface.d.ts

@@ -0,0 +1,13 @@
+export interface ApiResponse<T = unknown> {
+    error: string;
+    status: 1 | 0;
+    code: string;
+    data: T;
+    timestamp: string;
+}
+export interface PaginatedApiResponse<T = unknown> extends ApiResponse<T[]> {
+    data: T[];
+    total: number;
+    page: number;
+    size: number;
+}

+ 3 - 0
libs/common/src/interfaces/api-response.interface.js

@@ -0,0 +1,3 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+//# sourceMappingURL=api-response.interface.js.map

+ 1 - 0
libs/common/src/interfaces/api-response.interface.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"api-response.interface.js","sourceRoot":"","sources":["api-response.interface.ts"],"names":[],"mappings":""}

+ 7 - 0
libs/common/src/interfaces/operation-logger.interface.d.ts

@@ -0,0 +1,7 @@
+import type { FastifyRequest } from 'fastify';
+import type { OperationLogOptions } from '../decorators/operation-log.decorator';
+import type { ApiResponse } from './api-response.interface';
+export interface IOperationLogger {
+    createLog(req: FastifyRequest, options: OperationLogOptions, data: ApiResponse<unknown>, callMethod: string, status: boolean): Promise<void>;
+}
+export declare const OPERATION_LOGGER: unique symbol;

+ 5 - 0
libs/common/src/interfaces/operation-logger.interface.js

@@ -0,0 +1,5 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.OPERATION_LOGGER = void 0;
+exports.OPERATION_LOGGER = Symbol('OPERATION_LOGGER');
+//# sourceMappingURL=operation-logger.interface.js.map

+ 1 - 0
libs/common/src/interfaces/operation-logger.interface.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"operation-logger.interface.js","sourceRoot":"","sources":["operation-logger.interface.ts"],"names":[],"mappings":";;;AAkBa,QAAA,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC"}

+ 8 - 0
libs/common/src/services/exception.service.d.ts

@@ -0,0 +1,8 @@
+import { ApiResponse } from '../interfaces/api-response.interface';
+export declare class ExceptionService {
+    getHttpResponse(exception: unknown): ApiResponse<null>;
+    private handleHttpException;
+    private isClassValidatorException;
+    private handleUnknownException;
+    private getExceptionCode;
+}

+ 78 - 0
libs/common/src/services/exception.service.js

@@ -0,0 +1,78 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ExceptionService = void 0;
+const common_1 = require("@nestjs/common");
+const class_validator_1 = require("class-validator");
+let ExceptionService = class ExceptionService {
+    getHttpResponse(exception) {
+        let message;
+        let code = 'INTERNAL_ERROR';
+        if (exception instanceof common_1.HttpException) {
+            message = this.handleHttpException(exception);
+            code = this.getExceptionCode(exception);
+        }
+        else {
+            message = this.handleUnknownException(exception);
+        }
+        return {
+            error: message,
+            status: 0,
+            code,
+            data: null,
+            timestamp: new Date().toISOString(),
+        };
+    }
+    handleHttpException(exception) {
+        if (this.isClassValidatorException(exception)) {
+            const exceptionResponse = exception.getResponse();
+            return exceptionResponse.message.join(', ');
+        }
+        else {
+            return exception.message;
+        }
+    }
+    isClassValidatorException(exception) {
+        if (!(exception instanceof common_1.BadRequestException))
+            return false;
+        const exceptionResponse = exception.getResponse();
+        return (typeof exceptionResponse === 'object' &&
+            'message' in exceptionResponse &&
+            (0, class_validator_1.isArray)(exceptionResponse.message));
+    }
+    handleUnknownException(exception) {
+        return exception instanceof Error
+            ? exception.message
+            : 'Internal server error';
+    }
+    getExceptionCode(exception) {
+        const status = exception.getStatus();
+        const response = exception.getResponse();
+        if (typeof response === 'object' &&
+            response !== null &&
+            'code' in response) {
+            return response.code;
+        }
+        const codeMap = {
+            400: 'BAD_REQUEST',
+            401: 'UNAUTHORIZED',
+            403: 'FORBIDDEN',
+            404: 'NOT_FOUND',
+            409: 'CONFLICT',
+            422: 'UNPROCESSABLE_ENTITY',
+            429: 'RATE_LIMITED',
+            500: 'INTERNAL_ERROR',
+        };
+        return codeMap[status] || `HTTP_${status}`;
+    }
+};
+exports.ExceptionService = ExceptionService;
+exports.ExceptionService = ExceptionService = __decorate([
+    (0, common_1.Injectable)()
+], ExceptionService);
+//# sourceMappingURL=exception.service.js.map

+ 1 - 0
libs/common/src/services/exception.service.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"exception.service.js","sourceRoot":"","sources":["exception.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAKwB;AACxB,qDAA0C;AAInC,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IAC3B,eAAe,CAAC,SAAkB;QAChC,IAAI,OAAe,CAAC;QACpB,IAAI,IAAI,GAAG,gBAAgB,CAAC;QAE5B,IAAI,SAAS,YAAY,sBAAa,EAAE,CAAC;YACvC,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;YAC9C,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,IAAI,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC;QACnD,CAAC;QAED,OAAO;YACL,KAAK,EAAE,OAAO;YACd,MAAM,EAAE,CAAC;YACT,IAAI;YACJ,IAAI,EAAE,IAAI;YACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;IACJ,CAAC;IAEO,mBAAmB,CAAC,SAAwB;QAClD,IAAI,IAAI,CAAC,yBAAyB,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9C,MAAM,iBAAiB,GAAG,SAAS,CAAC,WAAW,EAE9C,CAAC;YACF,OAAO,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,OAAO,SAAS,CAAC,OAAO,CAAC;QAC3B,CAAC;IACH,CAAC;IAEO,yBAAyB,CAAC,SAAwB;QACxD,IAAI,CAAC,CAAC,SAAS,YAAY,4BAAmB,CAAC;YAAE,OAAO,KAAK,CAAC;QAE9D,MAAM,iBAAiB,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QAClD,OAAO,CACL,OAAO,iBAAiB,KAAK,QAAQ;YACrC,SAAS,IAAI,iBAAiB;YAC9B,IAAA,yBAAO,EAAC,iBAAiB,CAAC,OAAO,CAAC,CACnC,CAAC;IACJ,CAAC;IAEO,sBAAsB,CAAC,SAAkB;QAC/C,OAAO,SAAS,YAAY,KAAK;YAC/B,CAAC,CAAC,SAAS,CAAC,OAAO;YACnB,CAAC,CAAC,uBAAuB,CAAC;IAC9B,CAAC;IAEO,gBAAgB,CAAC,SAAwB;QAC/C,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QAGzC,IACE,OAAO,QAAQ,KAAK,QAAQ;YAC5B,QAAQ,KAAK,IAAI;YACjB,MAAM,IAAI,QAAQ,EAClB,CAAC;YACD,OAAQ,QAAgB,CAAC,IAAI,CAAC;QAChC,CAAC;QAGD,MAAM,OAAO,GAA2B;YACtC,GAAG,EAAE,aAAa;YAClB,GAAG,EAAE,cAAc;YACnB,GAAG,EAAE,WAAW;YAChB,GAAG,EAAE,WAAW;YAChB,GAAG,EAAE,UAAU;YACf,GAAG,EAAE,sBAAsB;YAC3B,GAAG,EAAE,cAAc;YACnB,GAAG,EAAE,gBAAgB;SACtB,CAAC;QAEF,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,QAAQ,MAAM,EAAE,CAAC;IAC7C,CAAC;CACF,CAAA;AA5EY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,mBAAU,GAAE;GACA,gBAAgB,CA4E5B"}

+ 6 - 0
libs/db/src/prisma/mongo-prisma.service.d.ts

@@ -0,0 +1,6 @@
+import { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
+import { PrismaClient as MongoPrismaClient } from '@prisma/mongo/client';
+export declare class MongoPrismaService extends MongoPrismaClient implements OnModuleInit, OnModuleDestroy {
+    onModuleInit(): Promise<void>;
+    onModuleDestroy(): Promise<void>;
+}

+ 24 - 0
libs/db/src/prisma/mongo-prisma.service.js

@@ -0,0 +1,24 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.MongoPrismaService = void 0;
+const common_1 = require("@nestjs/common");
+const client_1 = require("@prisma/mongo/client");
+let MongoPrismaService = class MongoPrismaService extends client_1.PrismaClient {
+    async onModuleInit() {
+        await this.$connect();
+    }
+    async onModuleDestroy() {
+        await this.$disconnect();
+    }
+};
+exports.MongoPrismaService = MongoPrismaService;
+exports.MongoPrismaService = MongoPrismaService = __decorate([
+    (0, common_1.Injectable)()
+], MongoPrismaService);
+//# sourceMappingURL=mongo-prisma.service.js.map

+ 1 - 0
libs/db/src/prisma/mongo-prisma.service.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"mongo-prisma.service.js","sourceRoot":"","sources":["mongo-prisma.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA2E;AAC3E,iDAAyE;AAGlE,IAAM,kBAAkB,GAAxB,MAAM,kBACX,SAAQ,qBAAiB;IAGzB,KAAK,CAAC,YAAY;QAChB,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;IAC3B,CAAC;CACF,CAAA;AAXY,gDAAkB;6BAAlB,kBAAkB;IAD9B,IAAA,mBAAU,GAAE;GACA,kBAAkB,CAW9B"}

+ 6 - 0
libs/db/src/prisma/mysql-prisma.service.d.ts

@@ -0,0 +1,6 @@
+import { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
+import { PrismaClient as MysqlPrismaClient } from '@prisma/mysql/client';
+export declare class MysqlPrismaService extends MysqlPrismaClient implements OnModuleInit, OnModuleDestroy {
+    onModuleInit(): Promise<void>;
+    onModuleDestroy(): Promise<void>;
+}

+ 24 - 0
libs/db/src/prisma/mysql-prisma.service.js

@@ -0,0 +1,24 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.MysqlPrismaService = void 0;
+const common_1 = require("@nestjs/common");
+const client_1 = require("@prisma/mysql/client");
+let MysqlPrismaService = class MysqlPrismaService extends client_1.PrismaClient {
+    async onModuleInit() {
+        await this.$connect();
+    }
+    async onModuleDestroy() {
+        await this.$disconnect();
+    }
+};
+exports.MysqlPrismaService = MysqlPrismaService;
+exports.MysqlPrismaService = MysqlPrismaService = __decorate([
+    (0, common_1.Injectable)()
+], MysqlPrismaService);
+//# sourceMappingURL=mysql-prisma.service.js.map

+ 1 - 0
libs/db/src/prisma/mysql-prisma.service.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"mysql-prisma.service.js","sourceRoot":"","sources":["mysql-prisma.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA2E;AAC3E,iDAAyE;AAGlE,IAAM,kBAAkB,GAAxB,MAAM,kBACX,SAAQ,qBAAiB;IAGzB,KAAK,CAAC,YAAY;QAChB,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;IAC3B,CAAC;CACF,CAAA;AAXY,gDAAkB;6BAAlB,kBAAkB;IAD9B,IAAA,mBAAU,GAAE;GACA,kBAAkB,CAW9B"}

+ 2 - 0
libs/db/src/prisma/prisma.module.d.ts

@@ -0,0 +1,2 @@
+export declare class PrismaModule {
+}

+ 22 - 0
libs/db/src/prisma/prisma.module.js

@@ -0,0 +1,22 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.PrismaModule = void 0;
+const common_1 = require("@nestjs/common");
+const mongo_prisma_service_1 = require("./mongo-prisma.service");
+const mysql_prisma_service_1 = require("./mysql-prisma.service");
+let PrismaModule = class PrismaModule {
+};
+exports.PrismaModule = PrismaModule;
+exports.PrismaModule = PrismaModule = __decorate([
+    (0, common_1.Module)({
+        providers: [mysql_prisma_service_1.MysqlPrismaService, mongo_prisma_service_1.MongoPrismaService],
+        exports: [mysql_prisma_service_1.MysqlPrismaService, mongo_prisma_service_1.MongoPrismaService],
+    })
+], PrismaModule);
+//# sourceMappingURL=prisma.module.js.map

+ 1 - 0
libs/db/src/prisma/prisma.module.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"prisma.module.js","sourceRoot":"","sources":["prisma.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AAExC,iEAA4D;AAC5D,iEAA4D;AAMrD,IAAM,YAAY,GAAlB,MAAM,YAAY;CAAG,CAAA;AAAf,oCAAY;uBAAZ,YAAY;IAJxB,IAAA,eAAM,EAAC;QACN,SAAS,EAAE,CAAC,yCAAkB,EAAE,yCAAkB,CAAC;QACnD,OAAO,EAAE,CAAC,yCAAkB,EAAE,yCAAkB,CAAC;KAClD,CAAC;GACW,YAAY,CAAG"}

+ 2 - 0
libs/db/src/shared.module.d.ts

@@ -0,0 +1,2 @@
+export declare class SharedModule {
+}

+ 25 - 0
libs/db/src/shared.module.js

@@ -0,0 +1,25 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.SharedModule = void 0;
+const axios_1 = require("@nestjs/axios");
+const common_1 = require("@nestjs/common");
+const utils_service_1 = require("./utils.service");
+const prisma_module_1 = require("./prisma/prisma.module");
+let SharedModule = class SharedModule {
+};
+exports.SharedModule = SharedModule;
+exports.SharedModule = SharedModule = __decorate([
+    (0, common_1.Global)(),
+    (0, common_1.Module)({
+        imports: [prisma_module_1.PrismaModule, axios_1.HttpModule],
+        providers: [utils_service_1.UtilsService],
+        exports: [prisma_module_1.PrismaModule, axios_1.HttpModule, utils_service_1.UtilsService],
+    })
+], SharedModule);
+//# sourceMappingURL=shared.module.js.map

+ 1 - 0
libs/db/src/shared.module.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"shared.module.js","sourceRoot":"","sources":["shared.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,yCAA2C;AAC3C,2CAAgD;AAChD,mDAA+C;AAC/C,0DAAsD;AAQ/C,IAAM,YAAY,GAAlB,MAAM,YAAY;CAAG,CAAA;AAAf,oCAAY;uBAAZ,YAAY;IANxB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,4BAAY,EAAE,kBAAU,CAAC;QACnC,SAAS,EAAE,CAAC,4BAAY,CAAC;QACzB,OAAO,EAAE,CAAC,4BAAY,EAAE,kBAAU,EAAE,4BAAY,CAAC;KAClD,CAAC;GACW,YAAY,CAAG"}

+ 7 - 0
libs/db/src/utils.service.d.ts

@@ -0,0 +1,7 @@
+import type { FastifyRequest } from 'fastify';
+export declare class UtilsService {
+    private qqwry;
+    getRealIp(req: FastifyRequest): string;
+    getIpRegion(ip: string): string;
+    getMd5(str: string): string;
+}

+ 49 - 0
libs/db/src/utils.service.js

@@ -0,0 +1,49 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+    return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.UtilsService = void 0;
+const common_1 = require("@nestjs/common");
+const crypto_1 = __importDefault(require("crypto"));
+const lib_qqwry_1 = __importDefault(require("lib-qqwry"));
+const lodash_1 = require("lodash");
+let UtilsService = class UtilsService {
+    constructor() {
+        this.qqwry = new lib_qqwry_1.default(true);
+    }
+    getRealIp(req) {
+        let clientIp = req.headers['x-forwarded-for'] || req.ip;
+        if ((0, lodash_1.isArray)(clientIp)) {
+            clientIp = clientIp[0];
+        }
+        clientIp = clientIp.split(',')[0];
+        return clientIp;
+    }
+    getIpRegion(ip) {
+        if (ip == null) {
+            return;
+        }
+        try {
+            const result = this.qqwry.searchIP(ip);
+            return result.Country;
+        }
+        catch (err) {
+            return '未知地区';
+        }
+    }
+    getMd5(str) {
+        return crypto_1.default.createHash('md5').update(str).digest('hex');
+    }
+};
+exports.UtilsService = UtilsService;
+exports.UtilsService = UtilsService = __decorate([
+    (0, common_1.Injectable)()
+], UtilsService);
+//# sourceMappingURL=utils.service.js.map

+ 1 - 0
libs/db/src/utils.service.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"utils.service.js","sourceRoot":"","sources":["utils.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,oDAA4B;AAE5B,0DAA8B;AAC9B,mCAAiC;AAG1B,IAAM,YAAY,GAAlB,MAAM,YAAY;IAAlB;QACG,UAAK,GAAG,IAAI,mBAAK,CAAC,IAAI,CAAC,CAAC;IA0BlC,CAAC;IAxBC,SAAS,CAAC,GAAmB;QAC3B,IAAI,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACxD,IAAI,IAAA,gBAAO,EAAC,QAAQ,CAAC,EAAE,CAAC;YACtB,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;QACD,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,WAAW,CAAC,EAAU;QACpB,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACvC,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,OAAO,gBAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC;CACF,CAAA;AA3BY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;GACA,YAAY,CA2BxB"}

+ 1 - 1
package.json

@@ -5,7 +5,7 @@
   "scripts": {
     "dev:mgnt": "nest start box-mgnt-api --watch",
     "build:mgnt": "nest build box-mgnt-api",
-    "start:mgnt": "node dist/apps/box-mgnt-api/main.js",
+    "start:mgnt": "node dist/apps/box-mgnt-api/src/main.js",
     "dev:app": "dotenv -e .env.app -- nest start box-app-api --watch",
     "build:app": "nest build box-app-api",
     "prisma:migrate:dev:mysql": "dotenv -e .env.mgnt -- prisma migrate dev --schema=prisma/mysql/schema",

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott