This commit is contained in:
paritosh18
2025-11-25 12:04:50 +05:30
15 changed files with 811 additions and 325 deletions

88
package-lock.json generated
View File

@@ -3865,9 +3865,9 @@
}
},
"node_modules/@prisma/client": {
"version": "6.16.0",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.16.0.tgz",
"integrity": "sha512-FYkFJtgwpwJRMxtmrB26y7gtpR372kyChw6lWng5TMmvn5V+uisy0OyllO5EJD1s8lX78V8X3XjhiXOoMLnu3w==",
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.19.0.tgz",
"integrity": "sha512-QXFT+N/bva/QI2qoXmjBzL7D6aliPffIwP+81AdTGq0FXDoLxLkWivGMawG8iM5B9BKfxLIXxfWWAF6wbuJU6g==",
"hasInstallScript": true,
"engines": {
"node": ">=18.18"
@@ -3886,70 +3886,60 @@
}
},
"node_modules/@prisma/config": {
"version": "6.16.0",
"resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.16.0.tgz",
"integrity": "sha512-Q9TgfnllVehvQziY9lJwRJLGmziX0OimZUEQ/MhCUBoJMSScj2VivCjw/Of2vlO1FfyaHXxrvjZAr7ASl7DVcw==",
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.19.0.tgz",
"integrity": "sha512-zwCayme+NzI/WfrvFEtkFhhOaZb/hI+X8TTjzjJ252VbPxAl2hWHK5NMczmnG9sXck2lsXrxIZuK524E25UNmg==",
"devOptional": true,
"dependencies": {
"c12": "3.1.0",
"deepmerge-ts": "7.1.5",
"effect": "3.16.12",
"effect": "3.18.4",
"empathic": "2.0.0"
}
},
"node_modules/@prisma/config/node_modules/effect": {
"version": "3.16.12",
"resolved": "https://registry.npmjs.org/effect/-/effect-3.16.12.tgz",
"integrity": "sha512-N39iBk0K71F9nb442TLbTkjl24FLUzuvx2i1I2RsEAQsdAdUTuUoW0vlfUXgkMTUOnYqKnWcFfqw4hK4Pw27hg==",
"devOptional": true,
"dependencies": {
"@standard-schema/spec": "^1.0.0",
"fast-check": "^3.23.1"
}
},
"node_modules/@prisma/debug": {
"version": "6.16.0",
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.16.0.tgz",
"integrity": "sha512-bxzro5vbVqAPkWyDs2A6GpQtRZunD8tyrLmSAchx9u0b+gWCDY6eV+oh5A0YtYT9245dIxQBswckayHuJG4u3w==",
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.19.0.tgz",
"integrity": "sha512-8hAdGG7JmxrzFcTzXZajlQCidX0XNkMJkpqtfbLV54wC6LSSX6Vni25W/G+nAANwLnZ2TmwkfIuWetA7jJxJFA==",
"devOptional": true
},
"node_modules/@prisma/engines": {
"version": "6.16.0",
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.16.0.tgz",
"integrity": "sha512-RHJGCH/zi017W4CWYWqg0Sv1pquGGFVo8T3auJ9sodDNaiRzbeNldydjaQzszVS8nscdtcvLuJzy7e65C3puqQ==",
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.19.0.tgz",
"integrity": "sha512-pMRJ+1S6NVdXoB8QJAPIGpKZevFjxhKt0paCkRDTZiczKb7F4yTgRP8M4JdVkpQwmaD4EoJf6qA+p61godDokw==",
"devOptional": true,
"hasInstallScript": true,
"dependencies": {
"@prisma/debug": "6.16.0",
"@prisma/engines-version": "6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43",
"@prisma/fetch-engine": "6.16.0",
"@prisma/get-platform": "6.16.0"
"@prisma/debug": "6.19.0",
"@prisma/engines-version": "6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773",
"@prisma/fetch-engine": "6.19.0",
"@prisma/get-platform": "6.19.0"
}
},
"node_modules/@prisma/engines-version": {
"version": "6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43",
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43.tgz",
"integrity": "sha512-ThvlDaKIVrnrv97ujNFDYiQbeMQpLa0O86HFA2mNoip4mtFqM7U5GSz2ie1i2xByZtvPztJlNRgPsXGeM/kqAA==",
"version": "6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773",
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773.tgz",
"integrity": "sha512-gV7uOBQfAFlWDvPJdQxMT1aSRur3a0EkU/6cfbAC5isV67tKDWUrPauyaHNpB+wN1ebM4A9jn/f4gH+3iHSYSQ==",
"devOptional": true
},
"node_modules/@prisma/fetch-engine": {
"version": "6.16.0",
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.16.0.tgz",
"integrity": "sha512-Mx5rml0XRIDizhB9eZxSP8c0nMoXYVITTiJJwxlWn9rNCel8mG8NAqIw+vJlN3gPR+kt3IBkP1SQVsplPPpYrA==",
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.19.0.tgz",
"integrity": "sha512-OOx2Lda0DGrZ1rodADT06ZGqHzr7HY7LNMaFE2Vp8dp146uJld58sRuasdX0OiwpHgl8SqDTUKHNUyzEq7pDdQ==",
"devOptional": true,
"dependencies": {
"@prisma/debug": "6.16.0",
"@prisma/engines-version": "6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43",
"@prisma/get-platform": "6.16.0"
"@prisma/debug": "6.19.0",
"@prisma/engines-version": "6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773",
"@prisma/get-platform": "6.19.0"
}
},
"node_modules/@prisma/get-platform": {
"version": "6.16.0",
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.16.0.tgz",
"integrity": "sha512-eaJOOvAoGslSUTjiQrtE9E0hoBdfL43j8SymOGD6LbdrKRNtIoiy6qiBaEr2fNYD+R/Qns7QOwPhl7SVHJayKA==",
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.19.0.tgz",
"integrity": "sha512-ym85WDO2yDhC3fIXHWYpG3kVMBA49cL1XD2GCsCF8xbwoy2OkDQY44gEbAt2X46IQ4Apq9H6g0Ex1iFfPqEkHA==",
"devOptional": true,
"dependencies": {
"@prisma/debug": "6.16.0"
"@prisma/debug": "6.19.0"
}
},
"node_modules/@sinclair/typebox": {
@@ -7380,10 +7370,10 @@
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
},
"node_modules/effect": {
"version": "3.19.6",
"resolved": "https://registry.npmjs.org/effect/-/effect-3.19.6.tgz",
"integrity": "sha512-Eh1E/CI+xCAcMSDC5DtyE29yWJINC0zwBbwHappQPorjKyS69rCA8qzpsHpfhKnPDYgxdg8zkknii8mZ+6YMQA==",
"dev": true,
"version": "3.18.4",
"resolved": "https://registry.npmjs.org/effect/-/effect-3.18.4.tgz",
"integrity": "sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==",
"devOptional": true,
"dependencies": {
"@standard-schema/spec": "^1.0.0",
"fast-check": "^3.23.1"
@@ -11270,14 +11260,14 @@
}
},
"node_modules/prisma": {
"version": "6.16.0",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-6.16.0.tgz",
"integrity": "sha512-TTh+H1Kw8N68KN9cDzdAyMroqMOvdCO/Z+kS2wKEVYR1nuR21qH5Q/Db/bZHsAgw7l/TPHtM/veG5VABcdwPDw==",
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-6.19.0.tgz",
"integrity": "sha512-F3eX7K+tWpkbhl3l4+VkFtrwJlLXbAM+f9jolgoUZbFcm1DgHZ4cq9AgVEgUym2au5Ad/TDLN8lg83D+M10ycw==",
"devOptional": true,
"hasInstallScript": true,
"dependencies": {
"@prisma/config": "6.16.0",
"@prisma/engines": "6.16.0"
"@prisma/config": "6.19.0",
"@prisma/engines": "6.19.0"
},
"bin": {
"prisma": "build/index.js"

View File

@@ -97,15 +97,15 @@ model UserAddressDetails {
}
model UserDocuments {
id Int @id @default(autoincrement())
userXid Int @map("user_xid")
user User @relation(fields: [userXid], references: [id], onDelete: Cascade)
id Int @id @default(autoincrement())
userXid Int @map("user_xid")
user User @relation(fields: [userXid], references: [id], onDelete: Cascade)
// documentTypeName String @map("document_type_name") @db.VarChar(50)
fileName String @map("file_name") @db.VarChar(500)
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
fileName String @map("file_name") @db.VarChar(500)
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@map("user_documents")
@@schema("usr")
@@ -655,7 +655,7 @@ model HostHeader {
cities Cities @relation(fields: [cityXid], references: [id], onDelete: Restrict)
stateXid Int @map("state_xid")
states States @relation(fields: [stateXid], references: [id], onDelete: Restrict)
countryXid Int? @map("country_xid")
countryXid Int? @map("country_xid")
countries Countries? @relation(fields: [countryXid], references: [id], onDelete: Restrict)
pinCode String @map("pin_code") @db.VarChar(30)
logoPath String? @map("logo_path") @db.VarChar(400)
@@ -670,14 +670,14 @@ model HostHeader {
facebookUrl String? @map("facebook_url") @db.VarChar(80)
linkedinUrl String? @map("linkedin_url") @db.VarChar(80)
twitterUrl String? @map("twitter_url") @db.VarChar(80)
currencyXid Int? @map("currency_xid")
currencies Currencies? @relation(fields: [currencyXid], references: [id], onDelete: Restrict)
stepper Int? @default(1) @map("stepper")
currencyXid Int? @map("currency_xid")
currencies Currencies? @relation(fields: [currencyXid], references: [id], onDelete: Restrict)
stepper Int? @default(1) @map("stepper")
hostStatusInternal String @default("pending") @map("host_status_internal") @db.VarChar(20)
hostStatusDisplay String @default("pending") @map("host_status_Display") @db.VarChar(20)
adminStatusInternal String @default("pending") @map("admin_status_internal") @db.VarChar(20)
adminStatusDisplay String @default("pending") @map("admin_status_display") @db.VarChar(20)
amStatus String? @default("pending") @map("am_status") @db.VarChar(20)
amStatus String? @default("pending") @map("am_status") @db.VarChar(20)
agreementAccepted Boolean @default(false) @map("agreement_accepted")
accountManagerXid Int? @map("account_manager_xid")
accountManager User? @relation("AccountManager", fields: [accountManagerXid], references: [id], onDelete: Restrict)
@@ -819,16 +819,17 @@ model HostParenetDocuments {
}
model HostTrack {
id Int @id @default(autoincrement())
hostXid Int @map("host_xid")
host HostHeader @relation(fields: [hostXid], references: [id], onDelete: Cascade)
trackStatus String @map("track_status") @db.VarChar(20)
updatedByXid Int @map("updated_by_xid")
updatedBy User @relation(fields: [updatedByXid], references: [id], onDelete: Restrict)
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
id Int @id @default(autoincrement())
hostXid Int @map("host_xid")
host HostHeader @relation(fields: [hostXid], references: [id], onDelete: Cascade)
updatedByRole String @map("updated_by_role") @db.VarChar(50)
trackStatus String @map("track_status") @db.VarChar(20)
updatedByXid Int @map("updated_by_xid")
updatedBy User @relation(fields: [updatedByXid], references: [id], onDelete: Restrict)
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@map("host_track")
@@schema("hst")

View File

@@ -5,19 +5,11 @@ provider:
runtime: nodejs22.x
region: ap-south-1
versionFunctions: false
iamRoleStatements:
- Effect: Allow
Action:
- s3:GetObject
- s3:ListBucket
Resource:
- arn:aws:s3:::minglar-dev-bucket
- arn:aws:s3:::minglar-dev-bucket/*
memorySize: 512 # Default memory for all functions (can be overridden per function)
apiGateway:
binaryMediaTypes:
- '*/*'
minimumCompressionSize: 0
minimumCompressionSize: 1024
environment:
DATABASE_URL: ${env:DATABASE_URL}
@@ -51,11 +43,11 @@ provider:
- s3:PutObject
- s3:GetObject
- s3:DeleteObject
Resource: 'arn:aws:s3:::${env:S3_BUCKET_NAME}/*'
- s3:ListBucket
Resource:
- 'arn:aws:s3:::${env:S3_BUCKET_NAME}'
- 'arn:aws:s3:::${env:S3_BUCKET_NAME}/*'
# ------------------------------------------------------------
# ESBUILD
# ------------------------------------------------------------
custom:
esbuild:
bundle: true
@@ -63,36 +55,40 @@ custom:
sourcemap: false
target: node20
platform: node
concurrency: 10
concurrency: 5
external:
- '@prisma/client'
- '.prisma'
exclude:
- 'aws-sdk'
# ------------------------------------------------------------
# GLOBAL PACKAGE CONFIG (EMPTY PACKAGE STRATEGY)
# ------------------------------------------------------------
package:
individually: true
patterns:
- '!**/*' # <-- DO NOT include anything globally
- '!node_modules/**'
- '!**/*.test.js'
- '!**/*.spec.js'
- '!**/test/**'
- '!**/__tests__/**'
- '!package-lock.json'
- '!yarn.lock'
- '!README.md'
- '!*.config.js'
- '!.git/**'
- '!.github/**'
# ------------------------------------------------------------
# FUNCTIONS (ONLY required files included)
# ------------------------------------------------------------
functions:
getHosts:
handler: src/modules/host/handlers/host.handler
memorySize: 384 # Lower memory for simple GET operations
package:
patterns:
- 'src/modules/host/handlers/host.*'
- 'src/modules/host/services/**'
- 'common/**'
- 'src/common/**'
- 'common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /host
@@ -100,15 +96,15 @@ functions:
verifyOtp:
handler: src/modules/host/handlers/verifyOtp.handler
memorySize: 384
package:
patterns:
- 'src/modules/host/handlers/verifyOtp.*'
- 'src/modules/host/services/**'
- 'common/**'
- 'src/common/**'
- 'common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /host/verify-otp
@@ -116,12 +112,13 @@ functions:
loginForHost:
handler: src/modules/host/handlers/loginForHost.handler
memorySize: 384
package:
patterns:
- 'src/modules/host/handlers/loginForHost.*'
- 'src/modules/host/services/**'
- 'common/**'
- 'src/common/**'
- 'common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
@@ -131,12 +128,13 @@ functions:
registrationOfHost:
handler: src/modules/host/handlers/registration.handler
memorySize: 384
package:
patterns:
- 'src/modules/host/handlers/registration.*'
- 'src/modules/host/services/**'
- 'common/**'
- 'src/common/**'
- 'common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
@@ -146,6 +144,7 @@ functions:
createPasswordForHost:
handler: src/modules/host/handlers/createPassword.handler
memorySize: 384
package:
patterns:
- 'src/modules/host/handlers/createPassword.*'
@@ -153,7 +152,6 @@ functions:
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /host/create-password
@@ -161,15 +159,15 @@ functions:
addPaymentDetailsForHost:
handler: src/modules/host/handlers/addPaymentDetails.handler
memorySize: 384
package:
patterns:
- 'src/modules/host/handlers/addPaymentDetails.*'
- 'src/modules/host/services/**'
- 'common/**'
- 'src/common/**'
- 'common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /host/add-payment-details
@@ -177,6 +175,7 @@ functions:
addActivity:
handler: src/modules/host/handlers/addActivity.handler
memorySize: 384
package:
patterns:
- 'src/modules/host/handlers/addActivity.*'
@@ -184,7 +183,6 @@ functions:
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /host/add-activity
@@ -192,6 +190,7 @@ functions:
getHostById:
handler: src/modules/host/handlers/getbyidhandler.handler
memorySize: 384
package:
patterns:
- 'src/modules/host/handlers/getbyidhandler.*'
@@ -199,7 +198,6 @@ functions:
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /host/getById
@@ -207,6 +205,7 @@ functions:
getPQQQuestionDetailsById:
handler: src/modules/host/handlers/getByIdPQQ.handler
memorySize: 384
package:
patterns:
- 'src/modules/host/handlers/getByIdPQQ.*'
@@ -214,7 +213,6 @@ functions:
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /host/get-pqq-question-details
@@ -222,6 +220,7 @@ functions:
getLatestPQQQuestionDetails:
handler: src/modules/host/handlers/getLatestQuestionDetailsPQQ.handler
memorySize: 384
package:
patterns:
- 'src/modules/host/handlers/getLatestQuestionDetailsPQQ.*'
@@ -229,7 +228,6 @@ functions:
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /host/get-latest-pqq-question-details
@@ -237,6 +235,7 @@ functions:
getActivityTypes:
handler: src/modules/host/handlers/getActivity.handler
memorySize: 384
package:
patterns:
- 'src/modules/host/handlers/getActivity.*'
@@ -244,7 +243,6 @@ functions:
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /host/get-activity
@@ -252,6 +250,7 @@ functions:
acceptMinglarAgreement:
handler: src/modules/host/handlers/acceptAgreement.handler
memorySize: 384
package:
patterns:
- 'src/modules/host/handlers/acceptAgreement.*'
@@ -259,7 +258,6 @@ functions:
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /host/accept-agreement
@@ -267,16 +265,16 @@ functions:
getStepperInfo:
handler: src/modules/host/handlers/getStepper.handler
memorySize: 384
package:
patterns:
- 'src/modules/host/handlers/getStepper.handler.*'
- 'src/modules/host/handlers/getStepper.*'
- 'src/common/utils/handlers/safeHandler.*'
- 'src/common/database/**'
- 'src/modules/host/services/**'
- 'common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /stepper
@@ -284,13 +282,13 @@ functions:
getSuggestion:
handler: src/modules/minglaradmin/handlers/getSuggestion.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/get-suggestion
@@ -298,13 +296,13 @@ functions:
minglarRegistration:
handler: src/modules/minglaradmin/handlers/registration.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/registration
@@ -312,13 +310,13 @@ functions:
minglarLoginForAdmin:
handler: src/modules/minglaradmin/handlers/loginForMinglar.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/login
@@ -326,25 +324,27 @@ functions:
minglarCreatePassword:
handler: src/modules/minglaradmin/handlers/createPassword.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/create-password
method: post
# Functions using AWS SDK - KEEP AS IS with higher memory
updateMinglarProfile:
handler: src/modules/minglaradmin/handlers/updateProfile.handler
memorySize: 512 # Higher memory for AWS SDK operations
timeout: 30
package:
patterns:
- 'src/modules/host/handlers/updateProfile.*'
- 'src/modules/host/services/**'
- 'src/modules/minglaradmin/handlers/updateProfile.*'
- 'src/modules/minglaradmin/services/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
@@ -352,7 +352,6 @@ functions:
- 'node_modules/@smithy/**'
- 'node_modules/tslib/**'
- 'node_modules/fast-xml-parser/**'
events:
- httpApi:
path: /minglaradmin/update-profile
@@ -360,13 +359,13 @@ functions:
prepopulateTeammate:
handler: src/modules/minglaradmin/handlers/prepopulateTeammate.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/prepopulate-Roles
@@ -374,13 +373,13 @@ functions:
inviteTeammate:
handler: src/modules/minglaradmin/handlers/inviteTeammate.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/invite-teammate
@@ -388,27 +387,55 @@ functions:
getAllHostApplication:
handler: src/modules/minglaradmin/handlers/getAllHostApplication.handler
memorySize: 512 # Higher memory for data-intensive operations
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/get-all-host-applications
path: /minglaradmin/get-all-host-applications-am
method: get
getAllOnboardingHostApplications:
handler: src/modules/minglaradmin/handlers/getAllOnboardingHosts.handler
memorySize: 512 # Higher memory for data-intensive operations
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/get-all-host-applications-admin
method: get
getAllOnboardingHostApplications_New:
handler: src/modules/minglaradmin/handlers/getOnboardingNewApplications.handler
memorySize: 512 # Higher memory for data-intensive operations
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/get-all-host-applications-admin-new
method: get
getAllInvitationDetails:
handler: src/modules/minglaradmin/handlers/getAllInvitationDetails.handler
memorySize: 512
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/get-all-invitation-details
@@ -416,13 +443,13 @@ functions:
addSuggestion:
handler: src/modules/minglaradmin/handlers/addSuggestion.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/add-suggestion
@@ -430,13 +457,13 @@ functions:
getAllCoadminAndAMDetails:
handler: src/modules/minglaradmin/handlers/getAllCoadminAndAM.handler
memorySize: 512
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/get-all-coadmin-and-am-details
@@ -444,13 +471,13 @@ functions:
getAllInvitedCoadminAndAMDetails:
handler: src/modules/minglaradmin/handlers/getAllInvitedCoadminAndAM.handler
memorySize: 512
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/get-all-invited-coadmin-and-am
@@ -458,27 +485,59 @@ functions:
getAllBankAndCurrencyDetails:
handler: src/modules/prepopulate/handlers/getAllBankDetails.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /prepopulate/get-all-bank-currency-details
method: get
getCityByState:
handler: src/modules/prepopulate/handlers/getCityByState.handler
memorySize: 384
package:
patterns:
- 'src/modules/prepopulate/handlers/getCityByState.*'
- 'src/modules/prepopulate/services/**'
- 'src/common/**'
- 'common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /prepopulate/get-city-by-state
method: get
getBranchByBankXid:
handler: src/modules/prepopulate/handlers/getBranchByBank.handler
memorySize: 384
package:
patterns:
- 'src/modules/prepopulate/handlers/getBranchByBank.*'
- 'src/modules/prepopulate/services/**'
- 'src/common/**'
- 'common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /prepopulate/get-branch-by-bank
method: get
getAllDocumentCountryStateCityDetails:
handler: src/modules/prepopulate/handlers/getAllDocTypeWithCountryState.handler
memorySize: 512
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /prepopulate/get-all-doc-country
@@ -486,13 +545,13 @@ functions:
getAllPqqQuesAns:
handler: src/modules/prepopulate/handlers/getAllPQQQuesWithAns.handler
memorySize: 512
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /prepopulate/get-all-pqq-ques-ans
@@ -500,13 +559,13 @@ functions:
getFrequenciesOfActivity:
handler: src/modules/prepopulate/handlers/getAllFrequencies.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /prepopulate/get-all-Frequencies
@@ -514,13 +573,13 @@ functions:
assignAMToHost:
handler: src/modules/minglaradmin/handlers/assignAM.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/assign-am-to-host
@@ -528,13 +587,13 @@ functions:
editAgreementDetails:
handler: src/modules/minglaradmin/handlers/editAgreementDetails.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/edit-agreement-details
@@ -542,13 +601,13 @@ functions:
acceptHostApplication:
handler: src/modules/minglaradmin/handlers/acceptHostApplication.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/accept-host-application
@@ -556,13 +615,13 @@ functions:
acceptHostApplicationMinglar:
handler: src/modules/minglaradmin/handlers/acceptHostAppMinglar.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/accept-host-application-minglar
@@ -570,13 +629,13 @@ functions:
rejectHostApplication:
handler: src/modules/minglaradmin/handlers/rejectHostApplication.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/reject-host-application
@@ -584,20 +643,23 @@ functions:
rejectHostApplicationAM:
handler: src/modules/minglaradmin/handlers/rejectHostApplicationAM.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
events:
- httpApi:
path: /minglaradmin/reject-host-application-am
method: patch
# Functions using AWS SDK and S3 - KEEP AS IS with higher memory
addCompanyDetails:
handler: src/modules/host/handlers/addCompanyDetails.handler
memorySize: 512
timeout: 30
package:
patterns:
- 'src/modules/host/handlers/addCompanyDetails.*'
@@ -605,19 +667,26 @@ functions:
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
- 'node_modules/@aws-sdk/**'
# Only include specific AWS SDK modules needed for S3
- 'node_modules/@aws-sdk/client-s3/**'
- 'node_modules/@aws-sdk/s3-request-presigner/**'
- 'node_modules/@aws-sdk/types/**'
- 'node_modules/@aws-sdk/middleware-logger/**'
- 'node_modules/@aws-sdk/util-utf8-node/**'
- 'node_modules/@aws-sdk/util-utf8-browser/**'
- 'node_modules/@smithy/**'
- 'node_modules/tslib/**'
- 'node_modules/fast-xml-parser/**'
- 'node_modules/lambda-multipart-parser/**'
# Remove these large/unnecessary packages:
- 'node_modules/fast-xml-parser/**' # Remove if not used
- 'node_modules/lambda-multipart-parser/**' # You're using busboy directly
- 'node_modules/busboy/**'
# Remove these AWS utility packages (included in main SDK):
- 'node_modules/@aws-crypto/**'
- 'node_modules/uuid/**'
- 'node_modules/@aws/util-uri-escape/**'
- 'node_modules/@aws/util-middleware/**'
# - 'node_modules/uuid/**' # AWS SDK includes its own
# - 'node_modules/@aws/util-uri-escape/**'
# - 'node_modules/@aws/util-middleware/**'
- 'node_modules/@aws/smithy-client/**'
- 'node_modules/@aws/lambda-invoke-store/**'
# - 'node_modules/@aws/lambda-invoke-store/**'
events:
- httpApi:
path: /host/add-company-details
@@ -625,6 +694,8 @@ functions:
submitPqqAnswer:
handler: src/modules/host/handlers/submitPqqAns.handler
memorySize: 512
timeout: 30
package:
patterns:
- 'src/modules/host/handlers/submitPqqAns.*'
@@ -644,7 +715,6 @@ functions:
- 'node_modules/@aws/util-middleware/**'
- 'node_modules/@aws/smithy-client/**'
- 'node_modules/@aws/lambda-invoke-store/**'
events:
- httpApi:
path: /host/submit-pqq-ans
@@ -652,6 +722,8 @@ functions:
submitFinalPqqAnswer:
handler: src/modules/host/handlers/getPQQScore.handler
memorySize: 512
timeout: 30
package:
patterns:
- 'src/modules/host/handlers/getPQQScore.*'
@@ -671,14 +743,14 @@ functions:
- 'node_modules/@aws/util-middleware/**'
- 'node_modules/@aws/smithy-client/**'
- 'node_modules/@aws/lambda-invoke-store/**'
events:
- httpApi:
path: /host/submit-final-pqq-ans
method: patch
addPQQSuggestion:
handler: src/modules/minglaradmin/handlers/addPQQSuggestion.handler
handler: src/modules/minglar/handlers/addPQQSuggestion.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/handlers/addPQQSuggestion.*'

View File

@@ -7,6 +7,15 @@ export const ROLE = {
USER: 6
}
export const ROLE_NAME = {
MINGLAR_ADMIN: 'Minglar Admin',
CO_ADMIN: 'Co-admin',
ACCOUNT_MANAGER: 'Account manager',
HOST: 'Host',
OPERATOR: 'Operator',
USER: 'User'
}
export const USER_STATUS = {
INVITED: "Invited",
ACTIVE: "Active",

View File

@@ -5,6 +5,7 @@ export const MINGLAR_STATUS_INTERNAL = {
AM_TO_REVIEW: 'AM To Review',
AM_REJECTED: 'AM Rejected',
AM_APPROVED: 'AM Approved',
DRAFT: 'Draft',
};
export const MINGLAR_STATUS_DISPLAY = {
@@ -14,6 +15,7 @@ export const MINGLAR_STATUS_DISPLAY = {
ENHANCING: 'Enhancing',
APPROVED: 'Approved',
REJECTED: 'Rejected',
DRAFT: 'Draft'
};
export const MINGLAR_INVITATION_STATUS = {

View File

@@ -65,7 +65,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
const fields: Record<string, any> = {};
const files: Array<{ buffer: Buffer; mimeType: string; fileName: string; fieldName: string }> = [];
// 3) parse with Busboy - FIXED VERSION
// 3) parse with Busboy
await new Promise<void>((resolve, reject) => {
const bb = Busboy({
headers: {
@@ -105,7 +105,6 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
});
bb.on('field', (fieldname, val) => {
// Store as string initially, parse later in normalizeJsonField
fields[fieldname] = val;
});
@@ -121,6 +120,9 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
bb.end();
});
// Extract isDraft flag from fields (default to false if not provided)
const isDraft = fields.isDraft === 'true' || fields.isDraft === true;
if (fields.userProfile) {
const userProfileRaw = normalizeJsonField(fields, "userProfile");
if (userProfileRaw) {
@@ -157,39 +159,31 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
if (existingHost) {
hostId = existingHost.id;
} else {
// For new hosts, we'll use user ID temporarily and update after host creation
hostId = userInfo.id;
}
// Define uploadToS3 function with proper folder structure using fieldName for filenames
// Define uploadToS3 function with proper folder structure using fieldName for filenames
// Define uploadToS3 function (same as before)
async function uploadToS3(buffer: Buffer, mimeType: string, originalName: string, folderType: 'logo' | 'documents' | 'parent_company', documentTypeXid?: number, fieldName?: string) {
let s3Key: string;
// Sanitize file name: remove special characters and spaces
const sanitizeFileName = (name: string) => {
return name
.toLowerCase()
.replace(/[^a-z0-9.]/g, '_') // Replace special characters with underscore
.replace(/_+/g, '_') // Replace multiple underscores with single
.replace(/^_+|_+$/g, ''); // Remove leading/trailing underscores
.replace(/[^a-z0-9.]/g, '_')
.replace(/_+/g, '_')
.replace(/^_+|_+$/g, '');
};
// Get file extension from original file name
const fileExtension = originalName.split('.').pop() || 'pdf';
// Determine folder structure based on type
if (folderType === 'logo') {
// Logo: Documents/Host/logo/{HostID}/{sanitized_filename}
const sanitizedFileName = sanitizeFileName(originalName);
s3Key = `Documents/Host/${hostId}/logo/${sanitizedFileName}`;
} else if (folderType === 'documents' && documentTypeXid && fieldName) {
// Host Documents: Documents/Host/documents/{HostID}/{documentTypeXid}_{fieldName}.{extension}
const fileName = `${documentTypeXid}_${fieldName}.${fileExtension}`;
const sanitizedFileName = sanitizeFileName(fileName);
s3Key = `Documents/Host/${hostId}/documents/${sanitizedFileName}`;
} else if (folderType === 'parent_company' && documentTypeXid && fieldName) {
// Parent Documents: Documents/Host/parent_company/{HostID}/{documentTypeXid}_{fieldName}.{extension}
const fileName = `${documentTypeXid}_${fieldName}.${fileExtension}`;
const sanitizedFileName = sanitizeFileName(fileName);
s3Key = `Documents/Host/${hostId}/parent_company/${sanitizedFileName}`;
@@ -197,7 +191,6 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
throw new ApiError(400, 'Invalid folder type or missing documentTypeXid/fieldName');
}
// Upload new file (S3 will automatically replace if same key exists)
await s3
.upload({
Bucket: config.aws.bucketName,
@@ -225,7 +218,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
console.log('Company logo uploaded:', logoPath);
}
// 6) Zod validation for companyDetails (includes optional parentCompany)
// 6) Zod validation for companyDetails
const companyValidation = hostCompanyDetailsSchema.safeParse(companyDetailsRaw);
if (!companyValidation.success) {
const message = companyValidation.error.issues.map((i) => i.message).join(', ');
@@ -246,7 +239,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
}
const documentsMetadata = documentsMetadataRaw.map((d: any) => ({
...d,
owner: d.owner || 'host', // default to host
owner: d.owner || 'host',
}));
// 8) Map uploaded files to metadata
@@ -260,12 +253,14 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
const hostDocs = documentMetadata.filter((d) => d.owner === 'host');
const parentDocs = documentMetadata.filter((d) => d.owner === 'parent');
// 10) Ensure required docs for host exist (IDs 1,2,3,4)
const hostUploadedTypes = hostDocs.map((d) => d.documentTypeXid);
const requiredHostTypes = Object.values(REQUIRED_DOC_TYPES);
const missingHostDocs = requiredHostTypes.filter((typeId) => !hostUploadedTypes.includes(typeId));
if (missingHostDocs.length > 0) {
throw new ApiError(400, `Missing mandatory documents for host: ${missingHostDocs.join(', ')}`);
// 10) If NOT draft, validate required documents
if (!isDraft) {
const hostUploadedTypes = hostDocs.map((d) => d.documentTypeXid);
const requiredHostTypes = Object.values(REQUIRED_DOC_TYPES);
const missingHostDocs = requiredHostTypes.filter((typeId) => !hostUploadedTypes.includes(typeId));
if (missingHostDocs.length > 0) {
throw new ApiError(400, `Missing mandatory documents for host: ${missingHostDocs.join(', ')}`);
}
}
// 11) If isSubsidairy === true and parentCompany provided -> validate parent company & docs
@@ -282,61 +277,65 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
}
parsedParentCompany = parsedCompany.parentCompany;
const parentUploadedTypes = parentDocs.map((d) => d.documentTypeXid);
const requiredParentTypes = Object.values(REQUIRED_DOC_TYPES);
const missingParentDocs = requiredParentTypes.filter((typeId) => !parentUploadedTypes.includes(typeId));
if (missingParentDocs.length > 0) {
throw new ApiError(400, `Missing mandatory documents for parent company: ${missingParentDocs.join(', ')}`);
// If NOT draft, validate required parent documents
if (!isDraft) {
const parentUploadedTypes = parentDocs.map((d) => d.documentTypeXid);
const requiredParentTypes = Object.values(REQUIRED_DOC_TYPES);
const missingParentDocs = requiredParentTypes.filter((typeId) => !parentUploadedTypes.includes(typeId));
if (missingParentDocs.length > 0) {
throw new ApiError(400, `Missing mandatory documents for parent company: ${missingParentDocs.join(', ')}`);
}
}
}
// 12) Upload files to S3 with proper folder structure using fieldName for filenames
// 12) Upload files to S3 (same for both draft and final submission)
const uploadedHostDocs: Array<{ documentTypeXid: number; documentName: string; filePath: string }> = [];
const uploadedParentDocs: Array<{ documentTypeXid: number; documentName: string; filePath: string }> = [];
// Upload host documents with proper folder structure using fieldName
// Upload host documents
for (const doc of hostDocs) {
const filePath = await uploadToS3(
doc.file.buffer,
doc.file.mimeType,
doc.file.fileName, // Use original file name for extension
doc.file.fileName,
'documents',
doc.documentTypeXid,
doc.fieldName // Use fieldName for the filename
doc.fieldName
);
uploadedHostDocs.push({
documentTypeXid: doc.documentTypeXid,
documentName: doc.fieldName, // Keep documentName for database
documentName: doc.fieldName,
filePath,
});
}
// Upload parent company documents with proper folder structure using fieldName
// Upload parent company documents
if (parentDocs.length > 0) {
for (const doc of parentDocs) {
const filePath = await uploadToS3(
doc.file.buffer,
doc.file.mimeType,
doc.file.fileName, // Use original file name for extension
doc.file.fileName,
'parent_company',
doc.documentTypeXid,
doc.fieldName // Use fieldName for the filename
doc.fieldName
);
uploadedParentDocs.push({
documentTypeXid: doc.documentTypeXid,
documentName: doc.documentName, // Keep documentName for database
documentName: doc.documentName,
filePath,
});
}
}
// 13) Persist using hostService
// 13) Persist using hostService - PASS isDraft flag
const createdOrUpdated = await hostService.addOrUpdateCompanyDetails(
userInfo.id,
parsedCompany,
uploadedHostDocs,
parsedParentCompany,
uploadedParentDocs
uploadedParentDocs,
isDraft // Pass the isDraft flag
);
if (!createdOrUpdated) throw new ApiError(400, 'Failed to add/update company details.');
@@ -347,25 +346,28 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
console.log(`Host created with ID: ${hostId}`);
}
const getSuggestionDetails = await hostService.getSuggestionDetails(userInfo.id)
// 14) Send emails only for FINAL submission (not draft)
if (!isDraft) {
const getSuggestionDetails = await hostService.getSuggestionDetails(userInfo.id)
if (getSuggestionDetails.hostDetails.accountManagerXid !== null) {
await sendEmailToAM(
getSuggestionDetails.hostDetails.accountManager.emailAddress,
getSuggestionDetails.hostDetails.accountManager.firstName,
getSuggestionDetails.hostDetails.companyName,
getSuggestionDetails.hostDetails.hostRefNumber
);
} else {
await sendEmailToMinglarAdmin(
config.MinglarAdminEmail,
config.MinglarAdminName,
getSuggestionDetails.hostDetails.companyName,
getSuggestionDetails.hostDetails.hostRefNumber
)
if (getSuggestionDetails.hostDetails.accountManagerXid !== null) {
await sendEmailToAM(
getSuggestionDetails.hostDetails.accountManager.emailAddress,
getSuggestionDetails.hostDetails.accountManager.firstName,
getSuggestionDetails.hostDetails.companyName,
getSuggestionDetails.hostDetails.hostRefNumber
);
} else {
await sendEmailToMinglarAdmin(
config.MinglarAdminEmail,
config.MinglarAdminName,
getSuggestionDetails.hostDetails.companyName,
getSuggestionDetails.hostDetails.hostRefNumber
)
}
}
// 14) Success
// 15) Success response
return {
statusCode: 200,
headers: {
@@ -374,8 +376,14 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
},
body: JSON.stringify({
success: true,
message: 'Company (and parent if provided) details and documents uploaded successfully.',
data: { id: createdOrUpdated.id, hostRefNumber: (createdOrUpdated as any).hostRefNumber }
message: isDraft
? 'Company details saved as draft successfully.'
: 'Company (and parent if provided) details and documents uploaded successfully.',
data: {
id: createdOrUpdated.id,
hostRefNumber: (createdOrUpdated as any).hostRefNumber,
isDraft
}
}),
};
} catch (error: any) {

View File

@@ -22,17 +22,10 @@ export const handler = safeHandler(async (
const userInfo = await verifyMinglarAdminHostToken(token);
const userId = Number(userInfo.id);
let body: { question_xid: number, activity_xid: number };
const question_xid = Number(event.queryStringParameters?.question_xid);
const activity_xid = Number(event.queryStringParameters?.activity_xid);
try {
body = event.body ? JSON.parse(event.body) : {};
} catch (error) {
throw new ApiError(400, 'Invalid JSON in request body');
}
const { question_xid, activity_xid } = body;
if(!question_xid || !activity_xid){
if (!question_xid || !activity_xid) {
throw new ApiError(400, "Question and activity xid are required.")
}

View File

@@ -182,14 +182,14 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
if (existingHeader) {
console.log("🔄 Updating existing PQQ header");
// Update existing header (comments can be null)
const header = await pqqService.updateHeader(
header = await pqqService.updateHeader(
existingHeader.id,
comments
);
} else {
console.log("🆕 Creating new PQQ header");
// Create new header (comments can be null)
const header = await pqqService.createHeader(
header = await pqqService.createHeader(
activityXid,
pqqQuestionXid,
pqqAnswerXid,

View File

@@ -9,7 +9,7 @@ import { z } from 'zod';
import { hostCompanyDetailsSchema } from '@/common/utils/validation/host/hostCompanyDetails.validation';
import { HOST_STATUS_DISPLAY, HOST_STATUS_INTERNAL, STEPPER } from '@/common/utils/constants/host.constant';
import { MINGLAR_STATUS_DISPLAY, MINGLAR_STATUS_INTERNAL } from '@/common/utils/constants/minglar.constant';
import { ROLE, USER_STATUS } from '@/common/utils/constants/common.constant';
import { ROLE, ROLE_NAME, USER_STATUS } from '@/common/utils/constants/common.constant';
import { getPresignedUrl } from '@/common/middlewares/aws/getPreSignedUrl';
import config from '@/config/config';
@@ -281,7 +281,8 @@ export class HostService {
companyData: HostCompanyDetailsInput,
documents: HostDocumentInput[],
parentCompanyData?: any | null,
parentDocuments?: HostDocumentInput[]
parentDocuments?: HostDocumentInput[],
isDraft: boolean = false // Add isDraft parameter with default false
) {
return await this.prisma.$transaction(async (tx) => {
// Check if host already has a company
@@ -290,13 +291,32 @@ export class HostService {
include: { hostParent: true },
});
// Determine status based on isDraft flag
const hostStatusInternal = isDraft
? HOST_STATUS_INTERNAL.DRAFT
: HOST_STATUS_INTERNAL.HOST_SUBMITTED;
const hostStatusDisplay = isDraft
? HOST_STATUS_DISPLAY.DRAFT
: HOST_STATUS_DISPLAY.UNDER_REVIEW;
const minglarStatusInternal = isDraft
? MINGLAR_STATUS_INTERNAL.DRAFT
: MINGLAR_STATUS_INTERNAL.ADMIN_TO_REVIEW;
const minglarStatusDisplay = isDraft
? MINGLAR_STATUS_DISPLAY.DRAFT
: MINGLAR_STATUS_DISPLAY.NEW;
// CREATE
if (!existingHostCompany) {
// Optionally check unique registration number
const existingByPan = await tx.hostHeader.findFirst({
where: { panNumber: companyData.panNumber },
});
if (existingByPan) throw new ApiError(400, 'Company already exists with this pan/bin number');
// Optionally check unique registration number (only for final submission)
if (!isDraft) {
const existingByPan = await tx.hostHeader.findFirst({
where: { panNumber: companyData.panNumber },
});
if (existingByPan) throw new ApiError(400, 'Company already exists with this pan/bin number');
}
const refNumber = await this.generateHostRefNumber(tx);
@@ -323,12 +343,11 @@ export class HostService {
facebookUrl: companyData.facebookUrl || null,
linkedinUrl: companyData.linkedinUrl || null,
twitterUrl: companyData.twitterUrl || null,
// currencyXid: companyData.currencyXid,
stepper: STEPPER.UNDER_REVIEW,
hostStatusInternal: HOST_STATUS_INTERNAL.HOST_SUBMITTED,
hostStatusDisplay: HOST_STATUS_DISPLAY.UNDER_REVIEW,
adminStatusInternal: MINGLAR_STATUS_INTERNAL.ADMIN_TO_REVIEW,
adminStatusDisplay: MINGLAR_STATUS_DISPLAY.NEW,
hostStatusInternal: hostStatusInternal,
hostStatusDisplay: hostStatusDisplay,
adminStatusInternal: minglarStatusInternal,
adminStatusDisplay: minglarStatusDisplay,
},
});
@@ -385,7 +404,6 @@ export class HostService {
}
// UPDATE existing
// Prevent changing hostRefNumber
const updatedHost = await tx.hostHeader.update({
where: { id: existingHostCompany.id },
data: {
@@ -408,9 +426,11 @@ export class HostService {
facebookUrl: companyData.facebookUrl || null,
linkedinUrl: companyData.linkedinUrl || null,
twitterUrl: companyData.twitterUrl || null,
// currencyXid: companyData.currencyXid,
stepper: STEPPER.UNDER_REVIEW
// hostRefNumber: DO NOT UPDATE
stepper: STEPPER.UNDER_REVIEW,
hostStatusInternal: hostStatusInternal,
hostStatusDisplay: hostStatusDisplay,
adminStatusInternal: minglarStatusInternal,
adminStatusDisplay: minglarStatusDisplay
},
});
@@ -428,7 +448,6 @@ export class HostService {
// Parent company create/update and replace parent docs
if (companyData.isSubsidairy) {
// existingHostCompany.hostParent may be array or single object depending on Prisma schema
let parentRecord = (existingHostCompany as any).hostParent;
if (Array.isArray(parentRecord)) parentRecord = parentRecord[0];
@@ -519,6 +538,19 @@ export class HostService {
}
}
const hostDetails = await this.prisma.hostHeader.findFirst({
where: { userXid: user_xid },
})
await this.prisma.hostTrack.create({
data: {
hostXid: hostDetails.id,
updatedByRole: ROLE_NAME.HOST,
updatedByXid: user_xid,
trackStatus: hostDetails.hostStatusInternal,
}
})
return updatedHost;
});
}
@@ -668,7 +700,12 @@ export class HostService {
let totalMaxPoints = 0;
// For category-wise scoring
const categories: any = {}; // { [categoryId]: { userPoints, maxPoints, name } }
const categories: Record<number, {
categoryId: number;
categoryName: string;
userPoints: number;
maxPoints: number;
}> = {};
for (const item of answers) {
const question = item.pqqQuestions;
@@ -680,7 +717,7 @@ export class HostService {
totalUserPoints += userPoints;
totalMaxPoints += maxPoints;
// Category info
// Category
const category = question.pqqSubCategories.category;
const categoryId = category.id;
@@ -689,7 +726,7 @@ export class HostService {
categoryId,
categoryName: category.categoryName,
userPoints: 0,
maxPoints: 0
maxPoints: 0,
};
}
@@ -698,19 +735,26 @@ export class HostService {
}
// Overall percent
const overallPercentage = totalMaxPoints > 0
? (totalUserPoints / totalMaxPoints) * 100
: 0;
const overallPercentage =
totalMaxPoints > 0 ? (totalUserPoints / totalMaxPoints) * 100 : 0;
// Category percentages
const categoryWise: any = {};
// ---------- 🔥 ONLY FIRST 2 CATEGORIES ----------
const categoryArray = Object.values(categories);
for (const catId in categories) {
const c = categories[catId];
// Sort by categoryId (or change to displayOrder if needed)
categoryArray.sort((a, b) => a.categoryId - b.categoryId);
// Take only first 2 categories
const topTwo = categoryArray.slice(0, 2);
const categoryWise: Record<string, number> = {};
for (const c of topTwo) {
categoryWise[c.categoryName] =
c.maxPoints > 0 ? (c.userPoints / c.maxPoints) * 100 : 0;
}
// Return final score object
return {
overallPercentage,
categoryWise
@@ -718,6 +762,7 @@ export class HostService {
}
async createHeader(
activityXid: number,
pqqQuestionXid: number,

View File

@@ -0,0 +1,53 @@
import { verifyOnlyMinglarAdminToken } from '@/common/middlewares/jwt/authForOnlyMinglarAdmin';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../common/database/prisma.service';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import ApiError from '../../../common/utils/helper/ApiError';
import { MinglarService } from '../services/minglar.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
/**
* Get all host applications handler
* Returns host details with status, submission date, and account manager info
*/
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
context?: Context
): Promise<APIGatewayProxyResult> => {
// Verify authentication token
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
if (!token) {
throw new ApiError(401, 'This is a protected route. Please provide a valid token.');
}
// Verify token and get user info
const userInfo = await verifyOnlyMinglarAdminToken(token);
// Get user details including role
const user = await prismaService.user.findUnique({
where: { id: userInfo.id },
select: { id: true, roleXid: true }
});
if (!user) {
throw new ApiError(404, 'User not found');
}
// Get all host applications from service based on user role
const hostApplications = await minglarService.getAllOnboardingHostApplications();
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
body: JSON.stringify({
success: true,
message: 'Host applications retrieved successfully',
data: hostApplications,
}),
};
});

View File

@@ -0,0 +1,53 @@
import { verifyOnlyMinglarAdminToken } from '@/common/middlewares/jwt/authForOnlyMinglarAdmin';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../common/database/prisma.service';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import ApiError from '../../../common/utils/helper/ApiError';
import { MinglarService } from '../services/minglar.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
/**
* Get all host applications handler
* Returns host details with status, submission date, and account manager info
*/
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
context?: Context
): Promise<APIGatewayProxyResult> => {
// Verify authentication token
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
if (!token) {
throw new ApiError(401, 'This is a protected route. Please provide a valid token.');
}
// Verify token and get user info
const userInfo = await verifyOnlyMinglarAdminToken(token);
// Get user details including role
const user = await prismaService.user.findUnique({
where: { id: userInfo.id },
select: { id: true, roleXid: true }
});
if (!user) {
throw new ApiError(404, 'User not found');
}
// Get all host applications from service based on user role
const hostApplications = await minglarService.getAllOnboardingHostApplications_New();
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
body: JSON.stringify({
success: true,
message: 'Host applications retrieved successfully',
data: hostApplications,
}),
};
});

View File

@@ -1,4 +1,4 @@
import { ROLE, USER_STATUS } from '@/common/utils/constants/common.constant';
import { ROLE, ROLE_NAME, USER_STATUS } from '@/common/utils/constants/common.constant';
import {
HOST_STATUS_DISPLAY,
HOST_STATUS_INTERNAL,
@@ -19,7 +19,7 @@ import { sendAMEmailForHostAssign } from './AMEmail.service';
@Injectable()
export class MinglarService {
constructor(private prisma: PrismaService) {}
constructor(private prisma: PrismaService) { }
async createPassword(user_xid: number, password: string): Promise<boolean> {
// Find user by id
@@ -597,7 +597,7 @@ export class MinglarService {
userStatus &&
userStatus.trim().toLowerCase() === MINGLAR_STATUS_DISPLAY.NEW.toLowerCase()
) {
filters.adminStatusDisplay = MINGLAR_STATUS_DISPLAY.NEW;
filters.adminStatusInternal = MINGLAR_STATUS_INTERNAL.ADMIN_TO_REVIEW;
}
/** -----------------------------------
@@ -670,6 +670,85 @@ export class MinglarService {
}));
}
async getAllOnboardingHostApplications() {
return await this.prisma.hostHeader.findMany({
where: { isActive: true },
select: {
id: true,
hostRefNumber: true,
companyName: true,
adminStatusDisplay: true,
assignedOn: true,
accountManagerXid: true,
createdAt: true,
user: {
select: {
id: true,
firstName: true,
lastName: true,
}
},
accountManager: {
select: {
id: true,
firstName: true,
lastName: true,
profileImage: true
}
}
}
})
}
async getAllOnboardingHostApplications_New() {
return await this.prisma.hostHeader.findMany({
where: { isActive: true, adminStatusInternal: MINGLAR_STATUS_INTERNAL.ADMIN_TO_REVIEW },
select: {
id: true,
hostRefNumber: true,
companyName: true,
adminStatusDisplay: true,
assignedOn: true,
accountManagerXid: true,
createdAt: true,
cities: {
select: {
id: true,
cityName: true
}
},
countries: {
select: {
id: true,
countryName: true,
}
},
states: {
select: {
id: true,
stateName: true
}
},
user: {
select: {
id: true,
firstName: true,
lastName: true,
}
},
accountManager: {
select: {
id: true,
firstName: true,
lastName: true,
profileImage: true
}
}
}
})
}
async getAllCoadminAndAM() {
// 1. Fetch all required users (Admin, Co-Admin, AM)
@@ -770,7 +849,7 @@ export class MinglarService {
if (
hostDetails.adminStatusInternal !==
MINGLAR_STATUS_INTERNAL.AM_NOT_ASSIGNED &&
MINGLAR_STATUS_INTERNAL.AM_NOT_ASSIGNED &&
hostDetails.adminStatusDisplay !== MINGLAR_STATUS_DISPLAY.AM_NOT_ASSIGNED
) {
throw new ApiError(400, 'Invalid host status');
@@ -861,7 +940,7 @@ export class MinglarService {
) {
// Check if host exists
const ActivityHeader = await this.prisma.activityPQQheader.findUnique({
where: { id: activity_pqq_header_xid , isActive:true},
where: { id: activity_pqq_header_xid, isActive: true },
select: { id: true },
});
@@ -934,41 +1013,65 @@ export class MinglarService {
}
async acceptHostApplication(host_xid: number, user_xid: number) {
return await this.prisma.hostHeader.update({
where: {
id: host_xid,
hostStatusInternal: HOST_STATUS_INTERNAL.HOST_SUBMITTED,
hostStatusDisplay: HOST_STATUS_DISPLAY.UNDER_REVIEW,
adminStatusInternal: MINGLAR_STATUS_INTERNAL.AM_TO_REVIEW,
adminStatusDisplay: MINGLAR_STATUS_DISPLAY.TO_REVIEW,
},
data: {
hostStatusInternal: HOST_STATUS_INTERNAL.APPROVED,
hostStatusDisplay: HOST_STATUS_DISPLAY.APPROVED,
adminStatusInternal: MINGLAR_STATUS_INTERNAL.AM_APPROVED,
adminStatusDisplay: MINGLAR_STATUS_DISPLAY.APPROVED,
stepper: STEPPER.COMPANY_DETAILS_APPROVED,
},
});
return await this.prisma.$transaction(async (tx) => {
await this.prisma.hostHeader.update({
where: {
id: host_xid,
hostStatusInternal: HOST_STATUS_INTERNAL.HOST_SUBMITTED,
hostStatusDisplay: HOST_STATUS_DISPLAY.UNDER_REVIEW,
adminStatusInternal: MINGLAR_STATUS_INTERNAL.AM_TO_REVIEW,
adminStatusDisplay: MINGLAR_STATUS_DISPLAY.TO_REVIEW,
},
data: {
hostStatusInternal: HOST_STATUS_INTERNAL.APPROVED,
hostStatusDisplay: HOST_STATUS_DISPLAY.APPROVED,
adminStatusInternal: MINGLAR_STATUS_INTERNAL.AM_APPROVED,
adminStatusDisplay: MINGLAR_STATUS_DISPLAY.APPROVED,
stepper: STEPPER.COMPANY_DETAILS_APPROVED,
},
});
await this.prisma.hostTrack.create({
data: {
hostXid: host_xid,
updatedByRole: ROLE_NAME.ACCOUNT_MANAGER,
updatedByXid: user_xid,
trackStatus: MINGLAR_STATUS_INTERNAL.AM_APPROVED,
}
})
})
}
async acceptHostApplicationMinglarAdmin(host_xid: number, user_xid: number) {
return await this.prisma.hostHeader.update({
where: {
id: host_xid,
hostStatusInternal: HOST_STATUS_INTERNAL.HOST_SUBMITTED,
hostStatusDisplay: HOST_STATUS_DISPLAY.UNDER_REVIEW,
adminStatusInternal: MINGLAR_STATUS_INTERNAL.ADMIN_TO_REVIEW,
adminStatusDisplay: MINGLAR_STATUS_DISPLAY.NEW,
},
data: {
isApproved: true,
hostStatusInternal: HOST_STATUS_INTERNAL.HOST_SUBMITTED,
hostStatusDisplay: HOST_STATUS_DISPLAY.UNDER_REVIEW,
adminStatusInternal: MINGLAR_STATUS_INTERNAL.AM_NOT_ASSIGNED,
adminStatusDisplay: MINGLAR_STATUS_DISPLAY.AM_NOT_ASSIGNED,
},
});
return await this.prisma.$transaction(async (tx) => {
await tx.hostHeader.update({
where: {
id: host_xid,
hostStatusInternal: HOST_STATUS_INTERNAL.HOST_SUBMITTED,
hostStatusDisplay: HOST_STATUS_DISPLAY.UNDER_REVIEW,
adminStatusInternal: MINGLAR_STATUS_INTERNAL.ADMIN_TO_REVIEW,
adminStatusDisplay: MINGLAR_STATUS_DISPLAY.NEW,
},
data: {
isApproved: true,
hostStatusInternal: HOST_STATUS_INTERNAL.HOST_SUBMITTED,
hostStatusDisplay: HOST_STATUS_DISPLAY.UNDER_REVIEW,
adminStatusInternal: MINGLAR_STATUS_INTERNAL.AM_NOT_ASSIGNED,
adminStatusDisplay: MINGLAR_STATUS_DISPLAY.AM_NOT_ASSIGNED,
},
});
await this.prisma.hostTrack.create({
data: {
hostXid: host_xid,
updatedByRole: ROLE_NAME.MINGLAR_ADMIN,
updatedByXid: user_xid,
trackStatus: MINGLAR_STATUS_INTERNAL.AM_NOT_ASSIGNED,
}
})
})
}
async rejectHostApplication(host_xid: number, user_xid: number) {
@@ -994,6 +1097,15 @@ export class MinglarService {
},
});
await this.prisma.hostTrack.create({
data: {
hostXid: hostDetails.id,
updatedByRole: ROLE_NAME.MINGLAR_ADMIN,
updatedByXid: user_xid,
trackStatus: MINGLAR_STATUS_INTERNAL.ADMIN_REJECTED,
}
})
await tx.user.update({
where: { id: hostDetails.userXid },
data: {
@@ -1004,25 +1116,36 @@ export class MinglarService {
}
async rejectHostApplicationAM(host_xid: number, user_xid: number) {
const hostDetails = await this.prisma.hostHeader.findFirst({
where: { id: host_xid },
select: { id: true, userXid: true },
});
if (!hostDetails) {
throw new Error('Host not found');
}
await this.prisma.hostHeader.update({
where: {
id: host_xid,
hostStatusInternal: HOST_STATUS_INTERNAL.HOST_SUBMITTED,
hostStatusDisplay: HOST_STATUS_DISPLAY.UNDER_REVIEW,
},
data: {
hostStatusInternal: HOST_STATUS_INTERNAL.REJECTED,
hostStatusDisplay: HOST_STATUS_DISPLAY.REJECTED,
adminStatusInternal: MINGLAR_STATUS_INTERNAL.ADMIN_REJECTED,
adminStatusDisplay: MINGLAR_STATUS_DISPLAY.REJECTED,
},
});
return await this.prisma.$transaction(async (tx) => {
const hostDetails = await this.prisma.hostHeader.findFirst({
where: { id: host_xid },
select: { id: true, userXid: true },
});
if (!hostDetails) {
throw new Error('Host not found');
}
await this.prisma.hostHeader.update({
where: {
id: host_xid,
hostStatusInternal: HOST_STATUS_INTERNAL.HOST_SUBMITTED,
hostStatusDisplay: HOST_STATUS_DISPLAY.UNDER_REVIEW,
},
data: {
hostStatusInternal: HOST_STATUS_INTERNAL.HOST_TO_UPDATE,
hostStatusDisplay: HOST_STATUS_DISPLAY.ENHANCING,
adminStatusInternal: MINGLAR_STATUS_INTERNAL.AM_REJECTED,
adminStatusDisplay: MINGLAR_STATUS_DISPLAY.ENHANCING,
},
});
await this.prisma.hostTrack.create({
data: {
hostXid: hostDetails.id,
updatedByRole: ROLE_NAME.ACCOUNT_MANAGER,
updatedByXid: user_xid,
trackStatus: MINGLAR_STATUS_INTERNAL.AM_REJECTED,
}
})
})
}
}

View File

@@ -0,0 +1,53 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from "aws-lambda";
import { PrismaService } from "../../../common/database/prisma.service";
import { safeHandler } from "../../../common/utils/handlers/safeHandler";
import ApiError from "../../../common/utils/helper/ApiError";
import { PrePopulateService } from "../services/prepopulate.service";
import { verifyHostToken } from "@/common/middlewares/jwt/authForHost";
const prismaService = new PrismaService();
const prePopulateService = new PrePopulateService(prismaService);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
context?: Context
): Promise<APIGatewayProxyResult> => {
// 1) Token check
const token =
event.headers["x-auth-token"] ||
event.headers["X-Auth-Token"];
if (!token) {
throw new ApiError(
400,
"This is a protected route. Please provide a valid token."
);
}
// 2) Authenticate user
await verifyHostToken(token);
// 3) Get bankXid from query params
const bankXid = Number(event.queryStringParameters?.bankXid);
if (!bankXid || isNaN(bankXid)) {
throw new ApiError(400, "Valid bankXid is required in query params.");
}
// 4) Fetch branches for the bank
const branches = await prePopulateService.getBankBranchesByBankId(bankXid);
return {
statusCode: 200,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
body: JSON.stringify({
success: true,
message: "Bank branches retrieved successfully",
data: branches
}),
};
});

View File

@@ -0,0 +1,53 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from "aws-lambda";
import { PrismaService } from "../../../common/database/prisma.service";
import { safeHandler } from "../../../common/utils/handlers/safeHandler";
import ApiError from "../../../common/utils/helper/ApiError";
import { PrePopulateService } from "../services/prepopulate.service";
import { verifyHostToken } from "@/common/middlewares/jwt/authForHost";
const prismaService = new PrismaService();
const prePopulateService = new PrePopulateService(prismaService);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
context?: Context
): Promise<APIGatewayProxyResult> => {
// 1) Token check
const token =
event.headers["x-auth-token"] ||
event.headers["X-Auth-Token"];
if (!token) {
throw new ApiError(
400,
"This is a protected route. Please provide a valid token."
);
}
// 2) Authenticate user
await verifyHostToken(token);
// 3) Get bankXid from query params
const stateXid = Number(event.queryStringParameters?.stateXid);
if (!stateXid || isNaN(stateXid)) {
throw new ApiError(400, "Valid stateXid is required in query params.");
}
// 4) Fetch branches for the bank
const branches = await prePopulateService.getCityByStateId(stateXid);
return {
statusCode: 200,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
body: JSON.stringify({
success: true,
message: "Bank branches retrieved successfully",
data: branches
}),
};
});

View File

@@ -3,7 +3,7 @@ import { PrismaService } from '../../../common/database/prisma.service';
@Injectable()
export class PrePopulateService {
constructor(private prisma: PrismaService) {}
constructor(private prisma: PrismaService) { }
async getAllBankDetails() {
return await this.prisma.banks.findMany({
@@ -23,6 +23,37 @@ export class PrePopulateService {
});
}
async getBankBranchesByBankId(bankXid: number) {
return await this.prisma.bankBranches.findMany({
where: {
bankXid,
isActive: true,
deletedAt: null
},
select: {
id: true,
branchAddress: true,
ifscCode: true,
}
});
}
async getCityByStateId(stateXid: number) {
return await this.prisma.cities.findMany({
where: {
stateXid,
isActive: true,
deletedAt: null
},
select: {
id: true,
cityName: true,
}
});
}
async getAllCurrencyDetails() {
return await this.prisma.currencies.findMany({
where: {
@@ -32,31 +63,31 @@ export class PrePopulateService {
});
}
async getAllPQQQuesAndAns() {
return await this.prisma.pQQCategories.findMany({
where: { isActive: true },
include: {
pqqsubCategories: {
include: {
questions: {
include: {
PQQAnswers: {
orderBy: {
displayOrder: 'asc'
}
}
},
orderBy: {
displayOrder: 'asc'
}
}
},
orderBy: { displayOrder: 'asc' }
async getAllPQQQuesAndAns() {
return await this.prisma.pQQCategories.findMany({
where: { isActive: true },
include: {
pqqsubCategories: {
include: {
questions: {
include: {
PQQAnswers: {
orderBy: {
displayOrder: 'asc'
}
}
},
orderBy: { displayOrder: 'asc' }
});
}
},
orderBy: {
displayOrder: 'asc'
}
}
},
orderBy: { displayOrder: 'asc' }
}
},
orderBy: { displayOrder: 'asc' }
});
}
async getAllDocumentTypeWithCountryStateCity() {
const [documentDetails, countryDetails, stateDetails, cityDetails] =