diff --git a/packages/bff/.gitignore b/packages/bff/.gitignore index b7143a96..0dba2eb6 100644 --- a/packages/bff/.gitignore +++ b/packages/bff/.gitignore @@ -4,4 +4,5 @@ node_modules .env /dist pgdata +pgdata2 .DS_Store diff --git a/packages/bff/docker-compose.yml b/packages/bff/docker-compose.yml index 586d518e..38c99d28 100644 --- a/packages/bff/docker-compose.yml +++ b/packages/bff/docker-compose.yml @@ -1,7 +1,7 @@ version: '3' services: postgres: - image: postgres:latest + image: postgres:14 environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres @@ -9,17 +9,17 @@ services: ports: - "5433:5432" volumes: - - ./pgdata:/var/lib/postgresql/data + - ./pgdata2:/var/lib/postgresql/data - submission-service: - # build: . - platform: linux/x86_64 - image: ghcr.io/samagra-anamaya/workflow-bff:dev - depends_on: - - postgres - restart: unless-stopped - environment: - DATABASE_URL: ${DATABASE_URL} - ports: - - 3000:3000 + # submission-service: + # # build: . + # platform: linux/x86_64 + # image: ghcr.io/samagra-anamaya/workflow-bff:dev + # depends_on: + # - postgres + # restart: unless-stopped + # environment: + # DATABASE_URL: ${DATABASE_URL} + # ports: + # - 3000:3000 diff --git a/packages/bff/package-lock.json b/packages/bff/package-lock.json index 9dfe152f..f66c45de 100644 --- a/packages/bff/package-lock.json +++ b/packages/bff/package-lock.json @@ -10,6 +10,8 @@ "license": "UNLICENSED", "dependencies": { "@axiomhq/axiom-node": "^0.12.0", + "@godaddy/terminus": "^4.12.1", + "@nestjs/axios": "^3.0.1", "@nestjs/common": "^10.2.7", "@nestjs/config": "^3.1.1", "@nestjs/core": "^10.0.0", @@ -17,9 +19,9 @@ "@nestjs/jwt": "^10.1.1", "@nestjs/passport": "^10.0.2", "@nestjs/platform-express": "^10.2.7", - "@nestjs/swagger": "^7.1.12", + "@nestjs/swagger": "^7.1.14", + "@nestjs/terminus": "^10.1.1", "@nestjs/throttler": "^5.0.1", - "@prisma/client": "^5.3.1", "@types/multer": "^1.4.8", "bcrypt": "^5.1.1", "body-parser": "^1.20.2", @@ -31,7 +33,6 @@ "multer": "^1.4.5-lts.1", "passport": "^0.6.0", "passport-jwt": "^4.0.1", - "prisma": "^5.3.1", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1", "swagger-ui-express": "^5.0.0", @@ -42,6 +43,7 @@ "@nestjs/cli": "^10.0.0", "@nestjs/schematics": "^10.0.0", "@nestjs/testing": "^10.0.0", + "@prisma/client": "^5.6.0", "@types/express": "^4.17.17", "@types/jest": "^29.5.2", "@types/minio": "^7.1.1", @@ -54,6 +56,7 @@ "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "prettier": "^3.0.0", + "prisma": "^5.6.0", "source-map-support": "^0.5.21", "supertest": "^6.3.3", "ts-jest": "^29.1.0", @@ -1030,6 +1033,14 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.62.tgz", "integrity": "sha512-53Fhb08qfKwSNCIUtysIqw0ye+v1d5QCdL2kl8liKQFlOZTAo+nEYr/FztzMaHBFwB5H0ugF0PF0gmtojaNNiQ==" }, + "node_modules/@godaddy/terminus": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@godaddy/terminus/-/terminus-4.12.1.tgz", + "integrity": "sha512-Tm+wVu1/V37uZXcT7xOhzdpFoovQReErff8x3y82k6YyWa1gzxWBjTyrx4G2enjEqoXPnUUmJ3MOmwH+TiP6Sw==", + "dependencies": { + "stoppable": "^1.1.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.11", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", @@ -1570,6 +1581,17 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@nestjs/axios": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-3.0.1.tgz", + "integrity": "sha512-VlOZhAGDmOoFdsmewn8AyClAdGpKXQQaY1+3PGB+g6ceurGIdTxZgRX3VXc1T6Zs60PedWjg3A82TDOB05mrzQ==", + "peerDependencies": { + "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0", + "axios": "^1.3.1", + "reflect-metadata": "^0.1.12", + "rxjs": "^6.0.0 || ^7.0.0" + } + }, "node_modules/@nestjs/cli": { "version": "10.1.17", "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.1.17.tgz", @@ -1882,15 +1904,15 @@ } }, "node_modules/@nestjs/swagger": { - "version": "7.1.12", - "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.1.12.tgz", - "integrity": "sha512-Q1P/IE+cws0sJeNtbs+8uDalcVylpmAnaEUFenGOa3KSNnXF/8DOE84mET/uUhFXsiz9PLHK8Hy7o7B6fRpMhg==", + "version": "7.1.14", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.1.14.tgz", + "integrity": "sha512-2Ol4S6qHeYVVmkshkWBM8E/qkmEqEOUj2QIewr0jLSyo30H7f3v81pJyks6pTLy4PK0LGUXojMvIfFIE3mmGQQ==", "dependencies": { "@nestjs/mapped-types": "2.0.2", "js-yaml": "4.1.0", "lodash": "4.17.21", "path-to-regexp": "3.2.0", - "swagger-ui-dist": "5.7.2" + "swagger-ui-dist": "5.9.0" }, "peerDependencies": { "@fastify/static": "^6.0.0", @@ -1912,6 +1934,75 @@ } } }, + "node_modules/@nestjs/terminus": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@nestjs/terminus/-/terminus-10.1.1.tgz", + "integrity": "sha512-aDoPK/uaR9PHn56xzand6zqpp+S3Ibm+y/OrG3M01F1WnScLfo29hbS6MdnIMqmVRAS11r/8X3xWTSo8TT/Lig==", + "dependencies": { + "boxen": "5.1.2", + "check-disk-space": "3.4.0" + }, + "peerDependencies": { + "@grpc/grpc-js": "*", + "@grpc/proto-loader": "*", + "@mikro-orm/core": "*", + "@mikro-orm/nestjs": "*", + "@nestjs/axios": "^1.0.0 || ^2.0.0 || ^3.0.0", + "@nestjs/common": "^9.0.0 || ^10.0.0", + "@nestjs/core": "^9.0.0 || ^10.0.0", + "@nestjs/microservices": "^9.0.0 || ^10.0.0", + "@nestjs/mongoose": "^9.0.0 || ^10.0.0", + "@nestjs/sequelize": "^9.0.0 || ^10.0.0", + "@nestjs/typeorm": "^9.0.0 || ^10.0.0", + "@prisma/client": "*", + "mongoose": "*", + "reflect-metadata": "0.1.x", + "rxjs": "7.x", + "sequelize": "*", + "typeorm": "*" + }, + "peerDependenciesMeta": { + "@grpc/grpc-js": { + "optional": true + }, + "@grpc/proto-loader": { + "optional": true + }, + "@mikro-orm/core": { + "optional": true + }, + "@mikro-orm/nestjs": { + "optional": true + }, + "@nestjs/axios": { + "optional": true + }, + "@nestjs/microservices": { + "optional": true + }, + "@nestjs/mongoose": { + "optional": true + }, + "@nestjs/sequelize": { + "optional": true + }, + "@nestjs/typeorm": { + "optional": true + }, + "@prisma/client": { + "optional": true + }, + "mongoose": { + "optional": true + }, + "sequelize": { + "optional": true + }, + "typeorm": { + "optional": true + } + } + }, "node_modules/@nestjs/testing": { "version": "10.2.5", "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.2.5.tgz", @@ -2025,12 +2116,13 @@ } }, "node_modules/@prisma/client": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.3.1.tgz", - "integrity": "sha512-ArOKjHwdFZIe1cGU56oIfy7wRuTn0FfZjGuU/AjgEBOQh+4rDkB6nF+AGHP8KaVpkBIiHGPQh3IpwQ3xDMdO0Q==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.6.0.tgz", + "integrity": "sha512-mUDefQFa1wWqk4+JhKPYq8BdVoFk9NFMBXUI8jAkBfQTtgx8WPx02U2HB/XbAz3GSUJpeJOKJQtNvaAIDs6sug==", + "devOptional": true, "hasInstallScript": true, "dependencies": { - "@prisma/engines-version": "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59" + "@prisma/engines-version": "5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee" }, "engines": { "node": ">=16.13" @@ -2045,15 +2137,17 @@ } }, "node_modules/@prisma/engines": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.3.1.tgz", - "integrity": "sha512-6QkILNyfeeN67BNEPEtkgh3Xo2tm6D7V+UhrkBbRHqKw9CTaz/vvTP/ROwYSP/3JT2MtIutZm/EnhxUiuOPVDA==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.6.0.tgz", + "integrity": "sha512-Mt2q+GNJpU2vFn6kif24oRSBQv1KOkYaterQsi0k2/lA+dLvhRX6Lm26gon6PYHwUM8/h8KRgXIUMU0PCLB6bw==", + "dev": true, "hasInstallScript": true }, "node_modules/@prisma/engines-version": { - "version": "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59.tgz", - "integrity": "sha512-y5qbUi3ql2Xg7XraqcXEdMHh0MocBfnBzDn5GbV1xk23S3Mq8MGs+VjacTNiBh3dtEdUERCrUUG7Z3QaJ+h79w==" + "version": "5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee.tgz", + "integrity": "sha512-UoFgbV1awGL/3wXuUK3GDaX2SolqczeeJ5b4FVec9tzeGbSWJboPSbT0psSrmgYAKiKnkOPFSLlH6+b+IyOwAw==", + "devOptional": true }, "node_modules/@sinclair/typebox": { "version": "0.27.8", @@ -2849,6 +2943,14 @@ } } }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dependencies": { + "string-width": "^4.1.0" + } + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -3294,6 +3396,54 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/bplist-parser": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", @@ -3549,6 +3699,14 @@ "node": "*" } }, + "node_modules/check-disk-space": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/check-disk-space/-/check-disk-space-3.4.0.tgz", + "integrity": "sha512-drVkSqfwA+TvuEhFipiR1OC9boEGZL5RrWvVsOthdcvQNXyCCuKkEiTOTXZ7qxSf/GLwq4GvzfrQD/Wz325hgw==", + "engines": { + "node": ">=16" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -3624,6 +3782,17 @@ "validator": "^13.7.0" } }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -7873,12 +8042,13 @@ } }, "node_modules/prisma": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.3.1.tgz", - "integrity": "sha512-Wp2msQIlMPHe+5k5Od6xnsI/WNG7UJGgFUJgqv/ygc7kOECZapcSz/iU4NIEzISs3H1W9sFLjAPbg/gOqqtB7A==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.6.0.tgz", + "integrity": "sha512-EEaccku4ZGshdr2cthYHhf7iyvCcXqwJDvnoQRAJg5ge2Tzpv0e2BaMCp+CbbDUwoVTzwgOap9Zp+d4jFa2O9A==", + "dev": true, "hasInstallScript": true, "dependencies": { - "@prisma/engines": "5.3.1" + "@prisma/engines": "5.6.0" }, "bin": { "prisma": "build/index.js" @@ -8677,6 +8847,15 @@ "node": ">= 0.8" } }, + "node_modules/stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "engines": { + "node": ">=4", + "npm": ">=6" + } + }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -8848,9 +9027,9 @@ } }, "node_modules/swagger-ui-dist": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.7.2.tgz", - "integrity": "sha512-mVZc9QVQ6pTCV5crli3+Ng+DoMPwdtMHK8QLk2oX8Mtamp4D/hV+uYdC3lV0JZrDgpNEcjs0RrWTqMwwosuLPQ==" + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.9.0.tgz", + "integrity": "sha512-NUHSYoe5XRTk/Are8jPJ6phzBh3l9l33nEyXosM17QInoV95/jng8+PuSGtbD407QoPf93MH3Bkh773OgesJpA==" }, "node_modules/swagger-ui-express": { "version": "5.0.0", @@ -9352,7 +9531,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, "engines": { "node": ">=10" }, @@ -9729,6 +9907,17 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/windows-release": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-4.0.0.tgz", @@ -10735,6 +10924,14 @@ } } }, + "@godaddy/terminus": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@godaddy/terminus/-/terminus-4.12.1.tgz", + "integrity": "sha512-Tm+wVu1/V37uZXcT7xOhzdpFoovQReErff8x3y82k6YyWa1gzxWBjTyrx4G2enjEqoXPnUUmJ3MOmwH+TiP6Sw==", + "requires": { + "stoppable": "^1.1.0" + } + }, "@humanwhocodes/config-array": { "version": "0.11.11", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", @@ -11156,6 +11353,12 @@ } } }, + "@nestjs/axios": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-3.0.1.tgz", + "integrity": "sha512-VlOZhAGDmOoFdsmewn8AyClAdGpKXQQaY1+3PGB+g6ceurGIdTxZgRX3VXc1T6Zs60PedWjg3A82TDOB05mrzQ==", + "requires": {} + }, "@nestjs/cli": { "version": "10.1.17", "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.1.17.tgz", @@ -11343,15 +11546,24 @@ } }, "@nestjs/swagger": { - "version": "7.1.12", - "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.1.12.tgz", - "integrity": "sha512-Q1P/IE+cws0sJeNtbs+8uDalcVylpmAnaEUFenGOa3KSNnXF/8DOE84mET/uUhFXsiz9PLHK8Hy7o7B6fRpMhg==", + "version": "7.1.14", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.1.14.tgz", + "integrity": "sha512-2Ol4S6qHeYVVmkshkWBM8E/qkmEqEOUj2QIewr0jLSyo30H7f3v81pJyks6pTLy4PK0LGUXojMvIfFIE3mmGQQ==", "requires": { "@nestjs/mapped-types": "2.0.2", "js-yaml": "4.1.0", "lodash": "4.17.21", "path-to-regexp": "3.2.0", - "swagger-ui-dist": "5.7.2" + "swagger-ui-dist": "5.9.0" + } + }, + "@nestjs/terminus": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@nestjs/terminus/-/terminus-10.1.1.tgz", + "integrity": "sha512-aDoPK/uaR9PHn56xzand6zqpp+S3Ibm+y/OrG3M01F1WnScLfo29hbS6MdnIMqmVRAS11r/8X3xWTSo8TT/Lig==", + "requires": { + "boxen": "5.1.2", + "check-disk-space": "3.4.0" } }, "@nestjs/testing": { @@ -11422,22 +11634,25 @@ } }, "@prisma/client": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.3.1.tgz", - "integrity": "sha512-ArOKjHwdFZIe1cGU56oIfy7wRuTn0FfZjGuU/AjgEBOQh+4rDkB6nF+AGHP8KaVpkBIiHGPQh3IpwQ3xDMdO0Q==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.6.0.tgz", + "integrity": "sha512-mUDefQFa1wWqk4+JhKPYq8BdVoFk9NFMBXUI8jAkBfQTtgx8WPx02U2HB/XbAz3GSUJpeJOKJQtNvaAIDs6sug==", + "devOptional": true, "requires": { - "@prisma/engines-version": "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59" + "@prisma/engines-version": "5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee" } }, "@prisma/engines": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.3.1.tgz", - "integrity": "sha512-6QkILNyfeeN67BNEPEtkgh3Xo2tm6D7V+UhrkBbRHqKw9CTaz/vvTP/ROwYSP/3JT2MtIutZm/EnhxUiuOPVDA==" + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.6.0.tgz", + "integrity": "sha512-Mt2q+GNJpU2vFn6kif24oRSBQv1KOkYaterQsi0k2/lA+dLvhRX6Lm26gon6PYHwUM8/h8KRgXIUMU0PCLB6bw==", + "dev": true }, "@prisma/engines-version": { - "version": "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59.tgz", - "integrity": "sha512-y5qbUi3ql2Xg7XraqcXEdMHh0MocBfnBzDn5GbV1xk23S3Mq8MGs+VjacTNiBh3dtEdUERCrUUG7Z3QaJ+h79w==" + "version": "5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee.tgz", + "integrity": "sha512-UoFgbV1awGL/3wXuUK3GDaX2SolqczeeJ5b4FVec9tzeGbSWJboPSbT0psSrmgYAKiKnkOPFSLlH6+b+IyOwAw==", + "devOptional": true }, "@sinclair/typebox": { "version": "0.27.8", @@ -12112,6 +12327,14 @@ "ajv": "^8.0.0" } }, + "ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "requires": { + "string-width": "^4.1.0" + } + }, "ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -12463,6 +12686,38 @@ } } }, + "boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, "bplist-parser": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", @@ -12625,6 +12880,11 @@ "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==" }, + "check-disk-space": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/check-disk-space/-/check-disk-space-3.4.0.tgz", + "integrity": "sha512-drVkSqfwA+TvuEhFipiR1OC9boEGZL5RrWvVsOthdcvQNXyCCuKkEiTOTXZ7qxSf/GLwq4GvzfrQD/Wz325hgw==" + }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -12674,6 +12934,11 @@ "validator": "^13.7.0" } }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" + }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -15837,11 +16102,12 @@ } }, "prisma": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.3.1.tgz", - "integrity": "sha512-Wp2msQIlMPHe+5k5Od6xnsI/WNG7UJGgFUJgqv/ygc7kOECZapcSz/iU4NIEzISs3H1W9sFLjAPbg/gOqqtB7A==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.6.0.tgz", + "integrity": "sha512-EEaccku4ZGshdr2cthYHhf7iyvCcXqwJDvnoQRAJg5ge2Tzpv0e2BaMCp+CbbDUwoVTzwgOap9Zp+d4jFa2O9A==", + "dev": true, "requires": { - "@prisma/engines": "5.3.1" + "@prisma/engines": "5.6.0" } }, "process-nextick-args": { @@ -16435,6 +16701,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, + "stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==" + }, "streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -16562,9 +16833,9 @@ "dev": true }, "swagger-ui-dist": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.7.2.tgz", - "integrity": "sha512-mVZc9QVQ6pTCV5crli3+Ng+DoMPwdtMHK8QLk2oX8Mtamp4D/hV+uYdC3lV0JZrDgpNEcjs0RrWTqMwwosuLPQ==" + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.9.0.tgz", + "integrity": "sha512-NUHSYoe5XRTk/Are8jPJ6phzBh3l9l33nEyXosM17QInoV95/jng8+PuSGtbD407QoPf93MH3Bkh773OgesJpA==" }, "swagger-ui-express": { "version": "5.0.0", @@ -16903,8 +17174,7 @@ "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" }, "type-is": { "version": "1.6.18", @@ -17174,6 +17444,14 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "requires": { + "string-width": "^4.0.0" + } + }, "windows-release": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-4.0.0.tgz", diff --git a/packages/bff/package.json b/packages/bff/package.json index 0995709e..d5dc56c5 100644 --- a/packages/bff/package.json +++ b/packages/bff/package.json @@ -24,6 +24,8 @@ }, "dependencies": { "@axiomhq/axiom-node": "^0.12.0", + "@godaddy/terminus": "^4.12.1", + "@nestjs/axios": "^3.0.1", "@nestjs/common": "^10.2.7", "@nestjs/config": "^3.1.1", "@nestjs/core": "^10.0.0", @@ -31,9 +33,9 @@ "@nestjs/jwt": "^10.1.1", "@nestjs/passport": "^10.0.2", "@nestjs/platform-express": "^10.2.7", - "@nestjs/swagger": "^7.1.12", + "@nestjs/swagger": "^7.1.14", + "@nestjs/terminus": "^10.1.1", "@nestjs/throttler": "^5.0.1", - "@prisma/client": "^5.3.1", "@types/multer": "^1.4.8", "bcrypt": "^5.1.1", "body-parser": "^1.20.2", @@ -45,7 +47,6 @@ "multer": "^1.4.5-lts.1", "passport": "^0.6.0", "passport-jwt": "^4.0.1", - "prisma": "^5.3.1", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1", "swagger-ui-express": "^5.0.0", @@ -56,6 +57,7 @@ "@nestjs/cli": "^10.0.0", "@nestjs/schematics": "^10.0.0", "@nestjs/testing": "^10.0.0", + "@prisma/client": "^5.6.0", "@types/express": "^4.17.17", "@types/jest": "^29.5.2", "@types/minio": "^7.1.1", @@ -68,6 +70,7 @@ "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "prettier": "^3.0.0", + "prisma": "^5.6.0", "source-map-support": "^0.5.21", "supertest": "^6.3.3", "ts-jest": "^29.1.0", diff --git a/packages/bff/prisma/migrations/20231109065541_development/migration.sql b/packages/bff/prisma/migrations/20231109065541_development/migration.sql new file mode 100644 index 00000000..9528142a --- /dev/null +++ b/packages/bff/prisma/migrations/20231109065541_development/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "VillageData" ADD COLUMN "flagsRaised" INTEGER NOT NULL DEFAULT 0; diff --git a/packages/bff/prisma/schema.prisma b/packages/bff/prisma/schema.prisma index fa5778cc..c50c0a14 100644 --- a/packages/bff/prisma/schema.prisma +++ b/packages/bff/prisma/schema.prisma @@ -102,6 +102,7 @@ model VillageData { gpName String surveySubmitted Int @default(0) surveyToConduct Int @default(0) + flagsRaised Int @default(0) spdpVillageId Int @id @unique villageName String Schedule Schedule[] diff --git a/packages/bff/src/app.module.ts b/packages/bff/src/app.module.ts index 0e9213bc..5d9336ec 100644 --- a/packages/bff/src/app.module.ts +++ b/packages/bff/src/app.module.ts @@ -1,4 +1,4 @@ -import { Module } from '@nestjs/common'; +import { Logger, Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { SubmissionController } from './submission/submission.controller'; @@ -20,6 +20,11 @@ import { UploadService } from './upload/upload.service'; import { MinioService } from './minio/minio.service'; import { UploadController } from './upload/upload.controller'; import { ThrottlerModule } from '@nestjs/throttler'; +import { HttpHealthIndicator, TerminusModule } from '@nestjs/terminus'; +import { MinioHealthIndicator } from './minio/minio.health'; +import { HealthController } from './health/health.controller'; +import { HealthService } from './health/health.service'; +import { HttpModule } from '@nestjs/axios'; @Module({ imports: [ ConfigModule.forRoot({ @@ -33,6 +38,8 @@ import { ThrottlerModule } from '@nestjs/throttler'; }, ]), PrismaModule, + TerminusModule, + HttpModule, // EnumeratorModule, //ScheduleModule, UtilsModule, @@ -48,15 +55,27 @@ import { ThrottlerModule } from '@nestjs/throttler'; SubmissionModule, MinioModule, ], - controllers: [AppController, SubmissionController, UploadController], + controllers: [ + AppController, + SubmissionController, + UploadController, + HealthController, + ], providers: [ + { + provide: 'TERMINUS_LOGGER', + useClass: Logger, + }, AppService, + HttpHealthIndicator, PrismaService, MinioService, SubmissionService, // ScheduleService, CustomLogger, UploadService, + MinioHealthIndicator, + HealthService, ], }) export class AppModule {} diff --git a/packages/bff/src/health/health.controller.spec.ts b/packages/bff/src/health/health.controller.spec.ts new file mode 100644 index 00000000..0ab9987b --- /dev/null +++ b/packages/bff/src/health/health.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { HealthController } from './health.controller'; + +describe('HealthController', () => { + let controller: HealthController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [HealthController], + }).compile(); + + controller = module.get(HealthController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/packages/bff/src/health/health.controller.ts b/packages/bff/src/health/health.controller.ts new file mode 100644 index 00000000..0e72f8f9 --- /dev/null +++ b/packages/bff/src/health/health.controller.ts @@ -0,0 +1,23 @@ +// health.controller.ts +import { Controller, Get } from '@nestjs/common'; +import { HealthCheck, HealthCheckService } from '@nestjs/terminus'; + +import { HealthService } from './health.service'; + +@Controller('health') +export class HealthController { + constructor( + private health: HealthCheckService, + private servicesIndicator: HealthService, + ) {} + + @Get() + @HealthCheck() + check() { + return this.health.check([ + () => this.servicesIndicator.isMinioHealthy('minio'), + () => this.servicesIndicator.isPrismaHealthy('prisma'), + () => this.servicesIndicator.isUserServiceHealthy('user-service'), + ]); + } +} diff --git a/packages/bff/src/health/health.service.spec.ts b/packages/bff/src/health/health.service.spec.ts new file mode 100644 index 00000000..ff5d4e3e --- /dev/null +++ b/packages/bff/src/health/health.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { HealthService } from './health.service'; + +describe('HealthService', () => { + let service: HealthService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [HealthService], + }).compile(); + + service = module.get(HealthService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/packages/bff/src/health/health.service.ts b/packages/bff/src/health/health.service.ts new file mode 100644 index 00000000..a05e9566 --- /dev/null +++ b/packages/bff/src/health/health.service.ts @@ -0,0 +1,61 @@ +import { Injectable } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; +import { + HealthCheckError, + HealthIndicator, + HealthIndicatorResult, + HttpHealthIndicator, +} from '@nestjs/terminus'; +import { MinioService } from 'src/minio/minio.service'; +import { PrismaService } from 'src/prisma/prisma.service'; + +@Injectable() +export class HealthService extends HealthIndicator { + constructor( + private minioService: MinioService, + private prismaService: PrismaService, + private httpIndicator: HttpHealthIndicator, + private configService: ConfigService, + ) { + super(); + } + + async isMinioHealthy(key: string): Promise { + try { + const isHealthy = await this.minioService.minioClient.bucketExists( + this.configService.get('MINIO_BUCKET'), + ); + return this.getStatus(key, isHealthy, { isHealthy }); + } catch (error) { + const result = this.getStatus(key, false, { error: error.message }); + throw new HealthCheckError('MinioHealthIndicator failed', result); + } + } + + async isPrismaHealthy(key: string): Promise { + try { + await this.prismaService.$queryRaw`SELECT 1`; + return this.getStatus(key, true, {}); + } catch (error) { + const result = this.getStatus(key, false, { error: error.message }); + throw new HealthCheckError('PrismaHealthIndicator failed', result); + } + } + + async isUserServiceHealthy(key: string): Promise { + console.log({ key }); + const url = `${this.configService.get('USER_SERVICE')}/health`; + try { + const rr = await this.httpIndicator.pingCheck(key, url, { + timeout: 3000, + }); + console.log({ rr }); + return rr; + } catch (error) { + const result = this.getStatus(key, false, { + error: `Failed to ping ${url}: ${error.message}`, + }); + throw new HealthCheckError(`${key} health check failed`, result); + } + } +} diff --git a/packages/bff/src/minio/minio.health.ts b/packages/bff/src/minio/minio.health.ts new file mode 100644 index 00000000..bb0fc5a2 --- /dev/null +++ b/packages/bff/src/minio/minio.health.ts @@ -0,0 +1,32 @@ +// minio.health.ts +import { Injectable } from '@nestjs/common'; +import { + HealthIndicator, + HealthIndicatorResult, + HealthCheckError, +} from '@nestjs/terminus'; +import { MinioService } from './minio.service'; +import { ConfigService } from '@nestjs/config'; + +@Injectable() +export class MinioHealthIndicator extends HealthIndicator { + constructor( + private minioService: MinioService, + private configService: ConfigService, + ) { + super(); + } + + async isHealthy(key: string): Promise { + const isHealthy = await this.minioService.minioClient.bucketExists( + this.configService.get('MINIO_BUCKET'), + ); + const result = this.getStatus(key, isHealthy, { isHealthy: isHealthy }); + + if (isHealthy) { + return result; + } + + throw new HealthCheckError('MinioHealthIndicator failed', result); + } +} diff --git a/packages/bff/src/submission/submission.controller.ts b/packages/bff/src/submission/submission.controller.ts index 334566af..7ff6d6b9 100644 --- a/packages/bff/src/submission/submission.controller.ts +++ b/packages/bff/src/submission/submission.controller.ts @@ -180,6 +180,16 @@ export class SubmissionController { return await this.submissionService.updateSubmission(id, data); } + @Put('/flag/:id') + async raiseSubmissionFlag( + @Param('id') id: string, + @Body() details: UpdateSubmissionDto, // Use the Submission interface/type instead of 'any' + ): Promise { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + return await this.submissionService.raiseSubmissionFlag({ id, details }); + } + @Delete('deleteAll') async deleteSubmission(): Promise { return this.submissionService.deleteAllSubmission(); diff --git a/packages/bff/src/submission/submission.service.ts b/packages/bff/src/submission/submission.service.ts index d466ac29..9bc4b993 100644 --- a/packages/bff/src/submission/submission.service.ts +++ b/packages/bff/src/submission/submission.service.ts @@ -72,8 +72,9 @@ export class SubmissionService { const lastDigits = record.submissionData.aadharNumber.slice(-4); record.submissionData.lastDigits = lastDigits; record.submissionData.aadharNumber = hashedAadhar; + record.spdpVillageId = Number(villageId); } - return record; + return { ...record, spdpVillageId: Number(villageId) }; }), ); @@ -145,18 +146,17 @@ export class SubmissionService { async searchSubmissions(villageId: string, text: string) { try { - let submissions; - if (!Number.isNaN(Number(text))) { - submissions = await this.searchByAadhaar(text, villageId); - } else { - submissions = await this.prisma.$queryRawUnsafe( - `SELECT * FROM "public"."Submission" + // if (!Number.isNaN(Number(text))) { + // submissions = await this.searchByAadhaar(text, villageId); + // } else { + const submissions = await this.prisma.$queryRawUnsafe( + `SELECT * FROM "public"."Submission" WHERE - "spdpVillageId" = ${villageId} AND - "submissionData"->>'beneficiaryName' ILIKE '%${text}%' + "spdpVillageId" = ${villageId} AND ( + "submissionData"->>'claimantName' ILIKE '%${text}%' OR "submissionData"->>'landTitleSerialNumber' ILIKE '%${text}%' ) LIMIT 30`, - ); - } + ); + // } return { result: { submissions } }; } catch (error) { @@ -300,9 +300,41 @@ export class SubmissionService { throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); } } - // async deleteSubmission(id: number): Promise { - // return this.prisma.submission.delete({ - // where: { id }, - // }); - // } + + async raiseSubmissionFlag({ + id, + details, + }: { + id: string; + details: Record; + }): Promise { + console.log({ id, details }); + try { + const submission = await this.prisma.submission.findFirst({ + where: { + id, + }, + }); + + if (!submission) { + throw new NotFoundException(`Submission with id: ${id} not found`); + } + + const updateSubmission = await this.prisma.submission.update({ + where: { id }, + data: { + errors: details.data, + }, + }); + + const updatedVillage = await this.prisma.villageData.update({ + where: { spdpVillageId: submission.spdpVillageId }, + data: { flagsRaised: { increment: 1 } }, + }); + console.log({ updatedVillage }); + return { result: { data: updateSubmission, updatedVillage } }; + } catch (error) { + throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); + } + } } diff --git a/packages/bff/src/utils/utils.controller.ts b/packages/bff/src/utils/utils.controller.ts index ddf055f0..20e594d3 100644 --- a/packages/bff/src/utils/utils.controller.ts +++ b/packages/bff/src/utils/utils.controller.ts @@ -38,4 +38,25 @@ export class UtilsController { async clearVillageData(): Promise { return this.utilService.deleteAllVillage(); } + + @Get('villages/getGps') + async getGps( + @Query('page') page: string, + @Query('limit') limit: string, + ): Promise { + const validatedLimit = Number(limit) || 10; + const validatedPage = Number(page) || 1; + return this.utilService.getGps(validatedPage, validatedLimit); + } + + @Get('/villages/gp/:id') + async getVillageByGpId(@Param('id') id: number): Promise { + const gpCode = Number(id); + return this.utilService.getVillageByGpId(gpCode); + } + + @Get('/test') + async test(): Promise { + return this.utilService.test(); + } } diff --git a/packages/bff/src/utils/utils.service.ts b/packages/bff/src/utils/utils.service.ts index e75762db..07126fc8 100644 --- a/packages/bff/src/utils/utils.service.ts +++ b/packages/bff/src/utils/utils.service.ts @@ -50,4 +50,41 @@ export class UtilsService { async deleteAllVillage(): Promise { return this.prisma.villageData.deleteMany({}); } + + async getGps(page: number, pageSize: number): Promise { + const skip = (page - 1) * pageSize; + + const gps = await this.prisma.villageData.groupBy({ + by: ['gpCode', 'gpName'], + skip, + take: pageSize, + _count: { + gpCode: true, + }, + orderBy: { + gpCode: 'asc', // or 'desc' for descending order + }, + }); + + const totalCount = await this.prisma.villageData.groupBy({ + by: ['gpCode'], + }); + return { + result: { + villages: gps, + totalCount: totalCount?.length, + currentPage: page, + totalPages: Math.ceil(totalCount?.length / pageSize), + }, + }; + } + + async getVillageByGpId(gpCode: number): Promise { + return this.prisma.villageData.findMany({ where: { gpCode } }); + } + async test(): Promise { + return this.prisma.villageData.groupBy({ + by: ['gpCode', 'gpName'], + }); + } }