Compare commits
6 Commits
pqq-optimi
...
Prisma_lay
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
507797d27a | ||
|
|
d8687edb9f | ||
|
|
6011318986 | ||
|
|
28175bbd7d | ||
|
|
572420823c | ||
|
|
9706e5b66b |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -44,6 +44,11 @@ lerna-debug.log*
|
|||||||
# temp
|
# temp
|
||||||
.tmp
|
.tmp
|
||||||
.temp
|
.temp
|
||||||
|
undefined/
|
||||||
|
|
||||||
|
# tsx cache/temp directories
|
||||||
|
**/tsx-*/
|
||||||
|
**/temp/tsx-*
|
||||||
|
|
||||||
# Runtime data
|
# Runtime data
|
||||||
pids
|
pids
|
||||||
|
|||||||
46
build-prisma-layer.ps1
Normal file
46
build-prisma-layer.ps1
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# build-prisma-layer.ps1
|
||||||
|
# Script to rebuild the Prisma layer for Lambda deployment
|
||||||
|
# Usage: .\build-prisma-layer.ps1
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$projectRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||||
|
$layerPath = Join-Path $projectRoot "layers\prisma\nodejs"
|
||||||
|
$nodeModulesPath = Join-Path $layerPath "node_modules"
|
||||||
|
|
||||||
|
Write-Host "🔄 Building Prisma layer for Lambda..." -ForegroundColor Cyan
|
||||||
|
|
||||||
|
# Step 1: Regenerate Prisma client
|
||||||
|
Write-Host "📦 Regenerating Prisma client..." -ForegroundColor Yellow
|
||||||
|
Push-Location $projectRoot
|
||||||
|
npx prisma generate
|
||||||
|
Pop-Location
|
||||||
|
|
||||||
|
# Step 2: Clean layer node_modules
|
||||||
|
Write-Host "🧹 Cleaning layer node_modules..." -ForegroundColor Yellow
|
||||||
|
if (Test-Path $nodeModulesPath) {
|
||||||
|
Remove-Item -Recurse -Force $nodeModulesPath
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 3: Install layer dependencies
|
||||||
|
Write-Host "📥 Installing layer dependencies..." -ForegroundColor Yellow
|
||||||
|
Push-Location $layerPath
|
||||||
|
npm install --production
|
||||||
|
Pop-Location
|
||||||
|
|
||||||
|
# Step 4: Copy generated Prisma client to layer
|
||||||
|
Write-Host "📋 Copying generated Prisma client to layer..." -ForegroundColor Yellow
|
||||||
|
$sourcePrisma = Join-Path $projectRoot "node_modules\.prisma\client"
|
||||||
|
$destPrisma = Join-Path $nodeModulesPath ".prisma\client"
|
||||||
|
|
||||||
|
New-Item -ItemType Directory -Force -Path (Split-Path $destPrisma) | Out-Null
|
||||||
|
Copy-Item -Path $sourcePrisma -Destination $destPrisma -Recurse -Force
|
||||||
|
|
||||||
|
# Step 5: Calculate layer size
|
||||||
|
$layerSize = (Get-ChildItem -Path $layerPath -Recurse -File | Measure-Object -Property Length -Sum).Sum / 1MB
|
||||||
|
Write-Host "✅ Layer built successfully!" -ForegroundColor Green
|
||||||
|
Write-Host "📊 Layer size: $([math]::Round($layerSize, 2)) MB" -ForegroundColor Cyan
|
||||||
|
|
||||||
|
# List contents
|
||||||
|
Write-Host "`n📁 Layer contents:" -ForegroundColor Cyan
|
||||||
|
Get-ChildItem $nodeModulesPath -Directory | ForEach-Object { Write-Host " - $($_.Name)" }
|
||||||
40
build-prisma-layer.sh
Normal file
40
build-prisma-layer.sh
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# build-prisma-layer.sh
|
||||||
|
# Script to rebuild the Prisma layer for Lambda deployment
|
||||||
|
# Usage: ./build-prisma-layer.sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
LAYER_PATH="$SCRIPT_DIR/layers/prisma/nodejs"
|
||||||
|
|
||||||
|
echo "🔄 Building Prisma layer for Lambda..."
|
||||||
|
|
||||||
|
# Step 1: Regenerate Prisma client
|
||||||
|
echo "📦 Regenerating Prisma client..."
|
||||||
|
cd "$SCRIPT_DIR"
|
||||||
|
npx prisma generate
|
||||||
|
|
||||||
|
# Step 2: Clean layer node_modules
|
||||||
|
echo "🧹 Cleaning layer node_modules..."
|
||||||
|
rm -rf "$LAYER_PATH/node_modules"
|
||||||
|
|
||||||
|
# Step 3: Install layer dependencies
|
||||||
|
echo "📥 Installing layer dependencies..."
|
||||||
|
cd "$LAYER_PATH"
|
||||||
|
npm install --production
|
||||||
|
|
||||||
|
# Step 4: Copy generated Prisma client to layer
|
||||||
|
echo "📋 Copying generated Prisma client to layer..."
|
||||||
|
mkdir -p "$LAYER_PATH/node_modules/.prisma"
|
||||||
|
cp -r "$SCRIPT_DIR/node_modules/.prisma/client" "$LAYER_PATH/node_modules/.prisma/client"
|
||||||
|
|
||||||
|
# Step 5: Calculate layer size
|
||||||
|
LAYER_SIZE=$(du -sh "$LAYER_PATH" | cut -f1)
|
||||||
|
echo "✅ Layer built successfully!"
|
||||||
|
echo "📊 Layer size: $LAYER_SIZE"
|
||||||
|
|
||||||
|
# List contents
|
||||||
|
echo ""
|
||||||
|
echo "📁 Layer contents:"
|
||||||
|
ls -d "$LAYER_PATH/node_modules"/*/ 2>/dev/null | xargs -n 1 basename | sed 's/^/ - /'
|
||||||
228
layers/prisma/nodejs/package-lock.json
generated
Normal file
228
layers/prisma/nodejs/package-lock.json
generated
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
{
|
||||||
|
"name": "prisma-layer",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "prisma-layer",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@prisma/adapter-pg": "^7.0.1",
|
||||||
|
"@prisma/client": "^7.0.1",
|
||||||
|
"pg": "^8.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@prisma/adapter-pg": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@prisma/adapter-pg/-/adapter-pg-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-01GpPPhLMoDMF4ipgfZz0L87fla/TV/PBQcmHy+9vV1ml6gUoqF8dUIRNI5Yf2YKpOwzQg9sn8C7dYD1Yio9Ug==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@prisma/driver-adapter-utils": "7.0.1",
|
||||||
|
"pg": "^8.16.3",
|
||||||
|
"postgres-array": "3.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@prisma/client": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-O74T6xcfaGAq5gXwCAvfTLvI6fmC3and2g5yLRMkNjri1K8mSpEgclDNuUWs9xj5AwNEMQ88NeD3asI+sovm1g==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@prisma/client-runtime-utils": "7.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19 || ^22.12 || >=24.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"prisma": "*",
|
||||||
|
"typescript": ">=5.4.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"prisma": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"typescript": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@prisma/client-runtime-utils": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@prisma/client-runtime-utils/-/client-runtime-utils-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-R26BVX9D/iw4toUmZKZf3jniM/9pMGHHdZN5LVP2L7HNiCQKNQQx/9LuMtjepbgRqSqQO3oHN0yzojHLnKTGEw==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
|
"node_modules/@prisma/debug": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-5+25XokVeAK2Z2C9W457AFw7Hk032Q3QI3G58KYKXPlpgxy+9FvV1+S1jqfJ2d4Nmq9LP/uACrM6OVhpJMSr8w==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
|
"node_modules/@prisma/driver-adapter-utils": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@prisma/driver-adapter-utils/-/driver-adapter-utils-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-sBbxm/yysHLLF2iMAB+qcX/nn3WFgsiC4DQNz0uM6BwGSIs8lIvgo0u8nR9nxe5gvFgKiIH8f4z2fgOEMeXc8w==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@prisma/debug": "7.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pg": {
|
||||||
|
"version": "8.16.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz",
|
||||||
|
"integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"pg-connection-string": "^2.9.1",
|
||||||
|
"pg-pool": "^3.10.1",
|
||||||
|
"pg-protocol": "^1.10.3",
|
||||||
|
"pg-types": "2.2.0",
|
||||||
|
"pgpass": "1.0.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16.0.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"pg-cloudflare": "^1.2.7"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"pg-native": ">=3.0.1"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"pg-native": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pg-cloudflare": {
|
||||||
|
"version": "1.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz",
|
||||||
|
"integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"node_modules/pg-connection-string": {
|
||||||
|
"version": "2.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz",
|
||||||
|
"integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/pg-int8": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pg-pool": {
|
||||||
|
"version": "3.10.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz",
|
||||||
|
"integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"pg": ">=8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pg-protocol": {
|
||||||
|
"version": "1.10.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz",
|
||||||
|
"integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/pg-types": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"pg-int8": "1.0.1",
|
||||||
|
"postgres-array": "~2.0.0",
|
||||||
|
"postgres-bytea": "~1.0.0",
|
||||||
|
"postgres-date": "~1.0.4",
|
||||||
|
"postgres-interval": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pg-types/node_modules/postgres-array": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pgpass": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"split2": "^4.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postgres-array": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postgres-bytea": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postgres-date": {
|
||||||
|
"version": "1.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
|
||||||
|
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postgres-interval": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"xtend": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/split2": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xtend": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
layers/prisma/nodejs/package.json
Normal file
10
layers/prisma/nodejs/package.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"name": "prisma-layer",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Lambda layer for Prisma 7 with pg driver adapter",
|
||||||
|
"dependencies": {
|
||||||
|
"@prisma/client": "^7.0.1",
|
||||||
|
"@prisma/adapter-pg": "^7.0.1",
|
||||||
|
"pg": "^8.13.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,9 @@
|
|||||||
"prisma:migrate": "prisma migrate dev",
|
"prisma:migrate": "prisma migrate dev",
|
||||||
"prisma:studio": "prisma studio",
|
"prisma:studio": "prisma studio",
|
||||||
"prisma:seed": "ts-node prisma/seed.ts",
|
"prisma:seed": "ts-node prisma/seed.ts",
|
||||||
"seeder": "tsx prisma/seed.ts"
|
"seeder": "tsx prisma/seed.ts",
|
||||||
|
"build:layer": "powershell -ExecutionPolicy Bypass -File ./build-prisma-layer.ps1",
|
||||||
|
"build:layer:unix": "chmod +x ./build-prisma-layer.sh && ./build-prisma-layer.sh"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-crypto/crc32c": "^5.2.0",
|
"@aws-crypto/crc32c": "^5.2.0",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
generator client {
|
generator client {
|
||||||
provider = "prisma-client-js"
|
provider = "prisma-client-js"
|
||||||
binaryTargets = ["native", "rhel-openssl-3.0.x"] // Add Linux target
|
// No binaryTargets or previewFeatures needed - Prisma 7 uses JS-based driver adapters (no native engines)
|
||||||
previewFeatures = ["multiSchema"]
|
// multiSchema and driverAdapters are now stable features
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
@@ -66,7 +66,6 @@ model User {
|
|||||||
friendOf Friends[] @relation("FriendUser")
|
friendOf Friends[] @relation("FriendUser")
|
||||||
userAddressDetails UserAddressDetails[]
|
userAddressDetails UserAddressDetails[]
|
||||||
userDocuments UserDocuments[]
|
userDocuments UserDocuments[]
|
||||||
activityTracks ActivityTrack[]
|
|
||||||
|
|
||||||
@@map("users")
|
@@map("users")
|
||||||
@@schema("usr")
|
@@schema("usr")
|
||||||
@@ -406,15 +405,12 @@ model FoodCuisines {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model CompanyTypes {
|
model CompanyTypes {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
companyTypeName String @unique @map("company_type_name") @db.VarChar(100)
|
companyTypeName String @unique @map("company_type_name") @db.VarChar(30)
|
||||||
displayOrder Int @map("display_order")
|
isActive Boolean @default(true) @map("is_active")
|
||||||
isActive Boolean @default(true) @map("is_active")
|
createdAt DateTime @default(now()) @map("created_at")
|
||||||
createdAt DateTime @default(now()) @map("created_at")
|
updatedAt DateTime @updatedAt @map("updated_at")
|
||||||
updatedAt DateTime @updatedAt @map("updated_at")
|
deletedAt DateTime? @map("deleted_at")
|
||||||
deletedAt DateTime? @map("deleted_at")
|
|
||||||
hostHeaders HostHeader[]
|
|
||||||
hostParents HostParent[]
|
|
||||||
|
|
||||||
@@map("company_types")
|
@@map("company_types")
|
||||||
@@schema("mst")
|
@@schema("mst")
|
||||||
@@ -668,13 +664,12 @@ model HostHeader {
|
|||||||
panNumber String? @map("pan_number") @db.VarChar(30)
|
panNumber String? @map("pan_number") @db.VarChar(30)
|
||||||
gstNumber String? @map("gst_number") @db.VarChar(30)
|
gstNumber String? @map("gst_number") @db.VarChar(30)
|
||||||
formationDate DateTime? @map("formation_date")
|
formationDate DateTime? @map("formation_date")
|
||||||
companyTypeXid Int? @map("company_type_xid")
|
companyType String? @map("company_type") @db.VarChar(30)
|
||||||
companyTypes CompanyTypes? @relation(fields: [companyTypeXid], references: [id], onDelete: Restrict)
|
websiteUrl String? @map("website_url") @db.VarChar(50)
|
||||||
websiteUrl String? @map("website_url") @db.VarChar(250)
|
instagramUrl String? @map("instagram_url") @db.VarChar(80)
|
||||||
instagramUrl String? @map("instagram_url") @db.VarChar(250)
|
facebookUrl String? @map("facebook_url") @db.VarChar(80)
|
||||||
facebookUrl String? @map("facebook_url") @db.VarChar(250)
|
linkedinUrl String? @map("linkedin_url") @db.VarChar(80)
|
||||||
linkedinUrl String? @map("linkedin_url") @db.VarChar(250)
|
twitterUrl String? @map("twitter_url") @db.VarChar(80)
|
||||||
twitterUrl String? @map("twitter_url") @db.VarChar(250)
|
|
||||||
currencyXid Int? @map("currency_xid")
|
currencyXid Int? @map("currency_xid")
|
||||||
currencies Currencies? @relation(fields: [currencyXid], references: [id], onDelete: Restrict)
|
currencies Currencies? @relation(fields: [currencyXid], references: [id], onDelete: Restrict)
|
||||||
stepper Int? @default(1) @map("stepper")
|
stepper Int? @default(1) @map("stepper")
|
||||||
@@ -696,7 +691,6 @@ model HostHeader {
|
|||||||
amountPerBooking Int? @map("amount_per_booking")
|
amountPerBooking Int? @map("amount_per_booking")
|
||||||
payoutDurationNum Int? @map("payout_duration_num")
|
payoutDurationNum Int? @map("payout_duration_num")
|
||||||
payoutDurationFrequency String? @map("payout_duration_frequency") @db.VarChar(20)
|
payoutDurationFrequency String? @map("payout_duration_frequency") @db.VarChar(20)
|
||||||
referencedBy String? @default("null") @map("referenced_by") @db.VarChar(100)
|
|
||||||
isActive Boolean @default(true) @map("is_active")
|
isActive Boolean @default(true) @map("is_active")
|
||||||
createdAt DateTime @default(now()) @map("created_at")
|
createdAt DateTime @default(now()) @map("created_at")
|
||||||
updatedAt DateTime @updatedAt @map("updated_at")
|
updatedAt DateTime @updatedAt @map("updated_at")
|
||||||
@@ -786,17 +780,17 @@ model HostParent {
|
|||||||
countries Countries? @relation(fields: [countryXid], references: [id], onDelete: Restrict)
|
countries Countries? @relation(fields: [countryXid], references: [id], onDelete: Restrict)
|
||||||
pinCode String? @map("pin_code") @db.VarChar(30)
|
pinCode String? @map("pin_code") @db.VarChar(30)
|
||||||
logoPath String? @map("logo_path") @db.VarChar(400)
|
logoPath String? @map("logo_path") @db.VarChar(400)
|
||||||
|
isSubsidairy Boolean @default(false) @map("is_subsidairy")
|
||||||
registrationNumber String? @map("registration_number") @db.VarChar(30)
|
registrationNumber String? @map("registration_number") @db.VarChar(30)
|
||||||
panNumber String? @map("pan_number") @db.VarChar(30)
|
panNumber String? @map("pan_number") @db.VarChar(30)
|
||||||
gstNumber String? @map("gst_number") @db.VarChar(30)
|
gstNumber String? @map("gst_number") @db.VarChar(30)
|
||||||
formationDate DateTime? @map("formation_date")
|
formationDate DateTime? @map("formation_date")
|
||||||
companyTypeXid Int? @map("company_type_xid")
|
companyType String? @map("company_type") @db.VarChar(30)
|
||||||
companyTypes CompanyTypes? @relation(fields: [companyTypeXid], references: [id], onDelete: Restrict)
|
websiteUrl String? @map("website_url") @db.VarChar(80)
|
||||||
websiteUrl String? @map("website_url") @db.VarChar(250)
|
instagramUrl String? @map("instagram_url") @db.VarChar(80)
|
||||||
instagramUrl String? @map("instagram_url") @db.VarChar(250)
|
facebookUrl String? @map("facebook_url") @db.VarChar(80)
|
||||||
facebookUrl String? @map("facebook_url") @db.VarChar(250)
|
linkedinUrl String? @map("linkedin_url") @db.VarChar(80)
|
||||||
linkedinUrl String? @map("linkedin_url") @db.VarChar(250)
|
twitterUrl String? @map("twitter_url") @db.VarChar(80)
|
||||||
twitterUrl String? @map("twitter_url") @db.VarChar(250)
|
|
||||||
isActive Boolean @default(true) @map("is_active")
|
isActive Boolean @default(true) @map("is_active")
|
||||||
createdAt DateTime @default(now()) @map("created_at")
|
createdAt DateTime @default(now()) @map("created_at")
|
||||||
updatedAt DateTime @updatedAt @map("updated_at")
|
updatedAt DateTime @updatedAt @map("updated_at")
|
||||||
@@ -910,7 +904,6 @@ model Activities {
|
|||||||
ActivityEquipmentTaxes ActivityEquipmentTaxes[]
|
ActivityEquipmentTaxes ActivityEquipmentTaxes[]
|
||||||
ScheduleHeader ScheduleHeader[]
|
ScheduleHeader ScheduleHeader[]
|
||||||
ItineraryActivities ItineraryActivities[]
|
ItineraryActivities ItineraryActivities[]
|
||||||
activityTracks ActivityTrack[]
|
|
||||||
|
|
||||||
@@map("activities")
|
@@map("activities")
|
||||||
@@schema("act")
|
@@schema("act")
|
||||||
@@ -935,25 +928,6 @@ model ActivityOtherDetails {
|
|||||||
@@schema("act")
|
@@schema("act")
|
||||||
}
|
}
|
||||||
|
|
||||||
model ActivityTrack {
|
|
||||||
id Int @id @default(autoincrement())
|
|
||||||
activityXid Int @map("activity_xid")
|
|
||||||
activity Activities @relation(fields: [activityXid], references: [id], onDelete: Cascade)
|
|
||||||
trackType String? @default("PQQ") @map("track_type")
|
|
||||||
updatedByRole String? @map("updated_by_role")
|
|
||||||
trackStatus String? @map("track_status")
|
|
||||||
updatedByXid Int? @map("updated_by_xid")
|
|
||||||
user User? @relation(fields: [updatedByXid], references: [id], onDelete: Cascade)
|
|
||||||
updatedOn DateTime? @map("updated_on")
|
|
||||||
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("activity_track")
|
|
||||||
@@schema("act")
|
|
||||||
}
|
|
||||||
|
|
||||||
model ActivitiesMedia {
|
model ActivitiesMedia {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
activityXid Int @map("activity_xid")
|
activityXid Int @map("activity_xid")
|
||||||
@@ -1141,8 +1115,8 @@ model ActivityPQQheader {
|
|||||||
activity Activities @relation(fields: [activityXid], references: [id], onDelete: Cascade)
|
activity Activities @relation(fields: [activityXid], references: [id], onDelete: Cascade)
|
||||||
pqqQuestionXid Int @map("pqq_question_xid")
|
pqqQuestionXid Int @map("pqq_question_xid")
|
||||||
pqqQuestions PQQQuestions @relation(fields: [pqqQuestionXid], references: [id], onDelete: Restrict)
|
pqqQuestions PQQQuestions @relation(fields: [pqqQuestionXid], references: [id], onDelete: Restrict)
|
||||||
pqqAnswerXid Int? @map("pqq_answer_xid")
|
pqqAnswerXid Int @map("pqq_answer_xid")
|
||||||
pqqAnswers PQQAnswers? @relation(fields: [pqqAnswerXid], references: [id], onDelete: Restrict)
|
pqqAnswers PQQAnswers @relation(fields: [pqqAnswerXid], references: [id], onDelete: Restrict)
|
||||||
comments String? @map("comments") @db.VarChar(200)
|
comments String? @map("comments") @db.VarChar(200)
|
||||||
isActive Boolean @default(true) @map("is_active")
|
isActive Boolean @default(true) @map("is_active")
|
||||||
createdAt DateTime @default(now()) @map("created_at")
|
createdAt DateTime @default(now()) @map("created_at")
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
import { PrismaClient } from '@prisma/client';
|
import { PrismaClient } from '@prisma/client';
|
||||||
import { PrismaPg } from '@prisma/adapter-pg';
|
|
||||||
import 'dotenv/config';
|
|
||||||
|
|
||||||
const prisma = new PrismaClient({
|
const prisma = new PrismaClient();
|
||||||
adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL }),
|
|
||||||
});
|
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
// ✅ Countries
|
// ✅ Countries
|
||||||
@@ -78,51 +74,35 @@ async function main() {
|
|||||||
create: { interestName: 'Chill and Zen', displayOrder: 1 },
|
create: { interestName: 'Chill and Zen', displayOrder: 1 },
|
||||||
});
|
});
|
||||||
const sweatmode = await prisma.interests.upsert({
|
const sweatmode = await prisma.interests.upsert({
|
||||||
where: { interestName: 'Sweat Mode On' },
|
where: { interestName: 'Sweat Mode' },
|
||||||
update: {},
|
update: {},
|
||||||
create: { interestName: 'Sweat Mode On', displayOrder: 2 },
|
create: { interestName: 'Sweat Mode', displayOrder: 2 },
|
||||||
});
|
});
|
||||||
const trackracer = await prisma.interests.upsert({
|
const gameon = await prisma.interests.upsert({
|
||||||
where: { interestName: 'Track Racer' },
|
where: { interestName: 'Game On' },
|
||||||
update: {},
|
update: {},
|
||||||
create: { interestName: 'Track Racer', displayOrder: 3 },
|
create: { interestName: 'Game On', displayOrder: 3 },
|
||||||
});
|
|
||||||
const circuitracer = await prisma.interests.upsert({
|
|
||||||
where: { interestName: 'Circuit Racer' },
|
|
||||||
update: {},
|
|
||||||
create: { interestName: 'Circuit Racer', displayOrder: 4 },
|
|
||||||
});
|
|
||||||
const thermalGliding = await prisma.interests.upsert({
|
|
||||||
where: { interestName: 'Thermal Gliding' },
|
|
||||||
update: {},
|
|
||||||
create: { interestName: 'Thermal Gliding', displayOrder: 5 },
|
|
||||||
});
|
});
|
||||||
const partycentral = await prisma.interests.upsert({
|
const partycentral = await prisma.interests.upsert({
|
||||||
where: { interestName: 'Party Central' },
|
where: { interestName: 'Party Central' },
|
||||||
update: {},
|
update: {},
|
||||||
create: { interestName: 'Party Central', displayOrder: 6 },
|
create: { interestName: 'Party Central', displayOrder: 4 },
|
||||||
});
|
});
|
||||||
const aqua = await prisma.interests.upsert({
|
const artsy = await prisma.interests.upsert({
|
||||||
where: { interestName: 'Aqua' },
|
where: { interestName: 'Artsy' },
|
||||||
update: {},
|
update: {},
|
||||||
create: { interestName: 'Aqua', displayOrder: 7 },
|
create: { interestName: 'Artsy', displayOrder: 5 },
|
||||||
});
|
});
|
||||||
const foodie = await prisma.interests.upsert({
|
const foodiediaries = await prisma.interests.upsert({
|
||||||
where: { interestName: 'Foodie' },
|
where: { interestName: 'Foodie Diaries' },
|
||||||
update: {},
|
update: {},
|
||||||
create: { interestName: 'Foodie', displayOrder: 8 },
|
create: { interestName: 'Foodie Diaries', displayOrder: 6 },
|
||||||
});
|
});
|
||||||
|
|
||||||
await prisma.activityTypes.createMany({
|
await prisma.activityTypes.createMany({
|
||||||
data: [
|
data: [
|
||||||
{ interestXid: aqua.id, activityTypeName: 'Scuba-Diving' },
|
{ interestXid: chillandzen.id, activityTypeName: 'Cricket' },
|
||||||
{ interestXid: sweatmode.id, activityTypeName: 'Cloudboarding' },
|
{ interestXid: chillandzen.id, activityTypeName: 'Football' },
|
||||||
{ interestXid: partycentral.id, activityTypeName: 'Soaring Glider' },
|
|
||||||
{ interestXid: sweatmode.id, activityTypeName: 'Speedway Racer' },
|
|
||||||
{ interestXid: aqua.id, activityTypeName: 'Aerial Surfing' },
|
|
||||||
{ interestXid: foodie.id, activityTypeName: 'Wine Tasting' },
|
|
||||||
{ interestXid: trackracer.id, activityTypeName: 'Track Racer' },
|
|
||||||
{ interestXid: thermalGliding.id, activityTypeName: 'Thermal Gliding' },
|
|
||||||
],
|
],
|
||||||
skipDuplicates: true,
|
skipDuplicates: true,
|
||||||
});
|
});
|
||||||
@@ -153,43 +133,6 @@ async function main() {
|
|||||||
skipDuplicates: true, // prevents error if already seeded
|
skipDuplicates: true, // prevents error if already seeded
|
||||||
});
|
});
|
||||||
|
|
||||||
// ✅ Company types data
|
|
||||||
await prisma.companyTypes.upsert({
|
|
||||||
where: { companyTypeName: 'Proprietory' },
|
|
||||||
update: {},
|
|
||||||
create: { companyTypeName: 'Proprietory', displayOrder: 1 },
|
|
||||||
});
|
|
||||||
|
|
||||||
await prisma.companyTypes.upsert({
|
|
||||||
where: { companyTypeName: 'One Person Company' },
|
|
||||||
update: {},
|
|
||||||
create: { companyTypeName: 'One Person Company', displayOrder: 2 },
|
|
||||||
});
|
|
||||||
|
|
||||||
await prisma.companyTypes.upsert({
|
|
||||||
where: { companyTypeName: 'Limited Liability Partnership' },
|
|
||||||
update: {},
|
|
||||||
create: { companyTypeName: 'Limited Liability Partnership', displayOrder: 3 },
|
|
||||||
});
|
|
||||||
|
|
||||||
await prisma.companyTypes.upsert({
|
|
||||||
where: { companyTypeName: 'Partnership Firm' },
|
|
||||||
update: {},
|
|
||||||
create: { companyTypeName: 'Partnership Firm', displayOrder: 4 },
|
|
||||||
});
|
|
||||||
|
|
||||||
await prisma.companyTypes.upsert({
|
|
||||||
where: { companyTypeName: 'Private Limited, Public Limited' },
|
|
||||||
update: {},
|
|
||||||
create: { companyTypeName: 'Private Limited, Public Limited', displayOrder: 5 },
|
|
||||||
});
|
|
||||||
|
|
||||||
await prisma.companyTypes.upsert({
|
|
||||||
where: { companyTypeName: 'Non-Profit Organisation' },
|
|
||||||
update: {},
|
|
||||||
create: { companyTypeName: 'Non-Profit Organisation', displayOrder: 6 },
|
|
||||||
});
|
|
||||||
|
|
||||||
// ✅ Food Types
|
// ✅ Food Types
|
||||||
await prisma.foodTypes.createMany({
|
await prisma.foodTypes.createMany({
|
||||||
data: [
|
data: [
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
service: minglarDev
|
service: minglar
|
||||||
|
|
||||||
provider:
|
provider:
|
||||||
name: aws
|
name: aws
|
||||||
@@ -6,6 +6,10 @@ provider:
|
|||||||
region: ap-south-1
|
region: ap-south-1
|
||||||
versionFunctions: false
|
versionFunctions: false
|
||||||
memorySize: 512
|
memorySize: 512
|
||||||
|
# Apply Prisma layer to all functions
|
||||||
|
# Use the published layer version ARN (works for full deploy and `deploy function`)
|
||||||
|
layers:
|
||||||
|
- ${cf:${self:service}-${sls:stage}.PrismaLambdaLayerQualifiedArn}
|
||||||
apiGateway:
|
apiGateway:
|
||||||
binaryMediaTypes:
|
binaryMediaTypes:
|
||||||
- '*/*'
|
- '*/*'
|
||||||
@@ -53,20 +57,34 @@ provider:
|
|||||||
- 'arn:aws:s3:::${env:S3_BUCKET_NAME}/*'
|
- 'arn:aws:s3:::${env:S3_BUCKET_NAME}/*'
|
||||||
|
|
||||||
custom:
|
custom:
|
||||||
|
serverless-offline:
|
||||||
|
reloadHandler: true
|
||||||
|
|
||||||
|
build:
|
||||||
esbuild:
|
esbuild:
|
||||||
bundle: true
|
bundle: true
|
||||||
minify: true
|
minify: true
|
||||||
sourcemap: false
|
sourcemap: false
|
||||||
target: node20
|
target: node20
|
||||||
platform: node
|
platform: node
|
||||||
concurrency: 5
|
|
||||||
external:
|
external:
|
||||||
|
# These are provided by the Prisma layer
|
||||||
- '@prisma/client'
|
- '@prisma/client'
|
||||||
|
- '@prisma/adapter-pg'
|
||||||
- '.prisma'
|
- '.prisma'
|
||||||
|
- 'pg'
|
||||||
exclude:
|
exclude:
|
||||||
- 'aws-sdk'
|
- 'aws-sdk'
|
||||||
serverless-offline:
|
|
||||||
reloadHandler: true
|
# Define layers
|
||||||
|
layers:
|
||||||
|
prisma:
|
||||||
|
path: layers/prisma
|
||||||
|
name: ${self:service}-prisma-layer-${sls:stage}
|
||||||
|
description: Prisma 7 client with pg driver adapter (no binary engines)
|
||||||
|
compatibleRuntimes:
|
||||||
|
- nodejs22.x
|
||||||
|
retain: false
|
||||||
|
|
||||||
package:
|
package:
|
||||||
individually: true
|
individually: true
|
||||||
@@ -88,7 +106,6 @@ functions:
|
|||||||
- ${file(./serverless/functions/host.yml)}
|
- ${file(./serverless/functions/host.yml)}
|
||||||
- ${file(./serverless/functions/minglaradmin.yml)}
|
- ${file(./serverless/functions/minglaradmin.yml)}
|
||||||
- ${file(./serverless/functions/prepopulate.yml)}
|
- ${file(./serverless/functions/prepopulate.yml)}
|
||||||
- ${file(./serverless/functions/pqq.yml)}
|
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
- serverless-offline
|
- serverless-offline
|
||||||
@@ -1,393 +1,680 @@
|
|||||||
# Host Module Functions
|
# Host Module Functions
|
||||||
|
|
||||||
# All authentication and host management endpoints
|
# All authentication and host management endpoints
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
getHosts:
|
getHosts:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/host.handler
|
handler: src/modules/host/handlers/host.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/host.*'
|
- 'src/modules/host/handlers/host.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host
|
path: /host
|
||||||
|
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
verifyOTP:
|
verifyOTP:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Host_Admin/onboarding/verifyOTP.handler
|
handler: src/modules/host/handlers/Host_Admin/onboarding/verifyOTP.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/verifyOtp.*'
|
- 'src/modules/host/handlers/verifyOtp.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/Host_Admin/onboarding/verify-otp
|
path: /host/Host_Admin/onboarding/verify-otp
|
||||||
|
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
login:
|
login:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Host_Admin/onboarding/login.handler
|
handler: src/modules/host/handlers/Host_Admin/onboarding/login.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/loginForHost.*'
|
- 'src/modules/host/handlers/loginForHost.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/Host_Admin/onboarding/login
|
path: /host/Host_Admin/onboarding/login
|
||||||
|
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
signUp:
|
signUp:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Host_Admin/onboarding/signUp.handler
|
handler: src/modules/host/handlers/Host_Admin/onboarding/signUp.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/registration.*'
|
- 'src/modules/host/handlers/registration.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/Host_Admin/onboarding/registration
|
path: /host/Host_Admin/onboarding/registration
|
||||||
|
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
createPassword:
|
createPassword:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Host_Admin/onboarding/createPassword.handler
|
handler: src/modules/host/handlers/Host_Admin/onboarding/createPassword.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/createPassword.*'
|
- 'src/modules/host/handlers/createPassword.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/Host_Admin/onboarding/create-password
|
path: /host/Host_Admin/onboarding/create-password
|
||||||
|
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
updateBankDetails:
|
updateBankDetails:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Host_Admin/onboarding/updateBankDetails.handler
|
handler: src/modules/host/handlers/Host_Admin/onboarding/updateBankDetails.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/addPaymentDetails.*'
|
- 'src/modules/host/handlers/addPaymentDetails.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/Host_Admin/onboarding/add-payment-details
|
path: /host/Host_Admin/onboarding/add-payment-details
|
||||||
|
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
saveActivity_ForPQQ:
|
saveActivity_ForPQQ:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/saveActivity_ForPQQ.handler
|
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/saveActivity_ForPQQ.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/addActivity.*'
|
- 'src/modules/host/handlers/addActivity.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/Activity_Hub/OnBoarding/add-activity
|
path: /host/Activity_Hub/OnBoarding/add-activity
|
||||||
|
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
getHostById:
|
getHostById:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/getbyidhandler.handler
|
handler: src/modules/host/handlers/getbyidhandler.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/getbyidhandler.*'
|
- 'src/modules/host/handlers/getbyidhandler.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/getById
|
path: /host/getById
|
||||||
|
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
getPQQ_ByQuestionId:
|
getPQQ_ByQuestionId:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/getPQQ_ByQuestionId.handler
|
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/getPQQ_ByQuestionId.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/getByIdPQQ.*'
|
- 'src/modules/host/handlers/getByIdPQQ.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/Activity_Hub/OnBoarding/get-pqq-question-details
|
path: /host/Activity_Hub/OnBoarding/get-pqq-question-details
|
||||||
|
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
getPQQ_LastUpdatedQuestion:
|
getPQQ_LastUpdatedQuestion:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/getPQQ_LastUpdatedQuestion.handler
|
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/getPQQ_LastUpdatedQuestion.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/getLatestQuestionDetailsPQQ.*'
|
- 'src/modules/host/handlers/getLatestQuestionDetailsPQQ.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/Activity_Hub/OnBoarding/get-latest-pqq-question-details
|
path: /host/Activity_Hub/OnBoarding/get-latest-pqq-question-details
|
||||||
|
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
prePopulateNewActivity:
|
|
||||||
|
|
||||||
|
getAllActivityType:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/getAllActivityType.handler
|
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/getAllActivityType.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/getActivityType.*'
|
- 'src/modules/host/handlers/getActivityType.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /host/Activity_Hub/OnBoarding/prepopulate-new-activity
|
|
||||||
|
path: /host/Activity_Hub/OnBoarding/get-activity-type
|
||||||
|
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
showSuggestion:
|
showSuggestion:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Host_Admin/onboarding/showSuggestion.handler
|
handler: src/modules/host/handlers/Host_Admin/onboarding/showSuggestion.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/Host_Admin/onboarding/showSuggestion.handler.*'
|
- 'src/modules/host/handlers/Host_Admin/onboarding/showSuggestion.handler.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/get-suggestion
|
path: /host/get-suggestion
|
||||||
|
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
getAllHostActivity:
|
getAllHostActivity:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/getAllHostActivity.handler
|
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/getAllHostActivity.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/Activity_Hub/OnBoarding/getAllHostActivity.*'
|
- 'src/modules/host/handlers/Activity_Hub/OnBoarding/getAllHostActivity.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/Activity_Hub/OnBoarding/get-all-host-activity
|
path: /host/Activity_Hub/OnBoarding/get-all-host-activity
|
||||||
|
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
acceptAggrement:
|
acceptAggrement:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Host_Admin/onboarding/acceptAggrement.handler
|
handler: src/modules/host/handlers/Host_Admin/onboarding/acceptAggrement.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/acceptAgreement.*'
|
- 'src/modules/host/handlers/acceptAgreement.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/Host_Admin/onboarding/accept-agreement
|
path: /host/Host_Admin/onboarding/accept-agreement
|
||||||
|
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
getStepperInfo:
|
getStepperInfo:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/getStepper.handler
|
handler: src/modules/host/handlers/getStepper.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/getStepper.*'
|
- 'src/modules/host/handlers/getStepper.*'
|
||||||
|
|
||||||
- 'src/common/utils/handlers/safeHandler.*'
|
- 'src/common/utils/handlers/safeHandler.*'
|
||||||
|
|
||||||
- 'src/common/database/**'
|
- 'src/common/database/**'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /stepper
|
path: /stepper
|
||||||
|
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Functions with S3/AWS SDK dependencies
|
# Functions with S3/AWS SDK dependencies
|
||||||
|
|
||||||
submitCompanyDetails:
|
submitCompanyDetails:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Host_Admin/onboarding/submitCompanyDetails.handler
|
handler: src/modules/host/handlers/Host_Admin/onboarding/submitCompanyDetails.handler
|
||||||
|
|
||||||
memorySize: 1024
|
memorySize: 1024
|
||||||
|
|
||||||
timeout: 30
|
timeout: 30
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/addCompanyDetails.*'
|
- 'src/modules/host/handlers/addCompanyDetails.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- 'src/common/**'
|
- 'src/common/**'
|
||||||
- 'node_modules/@prisma/client/**'
|
|
||||||
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
# Only include specific AWS SDK modules needed for S3
|
|
||||||
- 'node_modules/@aws-sdk/client-s3/**'
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
- 'node_modules/@aws-sdk/s3-request-presigner/**'
|
|
||||||
- 'node_modules/@aws-sdk/types/**'
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
- 'node_modules/@aws-sdk/middleware-logger/**'
|
|
||||||
- 'node_modules/@aws-sdk/util-utf8-node/**'
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
- 'node_modules/@aws-sdk/util-utf8-browser/**'
|
|
||||||
- 'node_modules/@smithy/**'
|
|
||||||
- 'node_modules/tslib/**'
|
|
||||||
# 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/**' # 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/**'
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/Host_Admin/onboarding/add-company-details
|
path: /host/Host_Admin/onboarding/add-company-details
|
||||||
|
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
submitPQQ_Answer:
|
submitPQQ_Answer:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/submitPQQ_Answer.handler
|
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/submitPQQ_Answer.handler
|
||||||
|
|
||||||
memorySize: 1024
|
memorySize: 1024
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/submitPqqAns.*'
|
- 'src/modules/host/handlers/submitPqqAns.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
- '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/**'
|
|
||||||
# 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/**' # AWS SDK includes its own
|
|
||||||
# - 'node_modules/@aws/util-uri-escape/**'
|
|
||||||
# - 'node_modules/@aws/util-middleware/**'
|
|
||||||
- 'node_modules/@aws/smithy-client/**'
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/Activity_Hub/OnBoarding/submit-pqq-answer
|
path: /host/Activity_Hub/OnBoarding/submit-pqq-answer
|
||||||
|
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
updatePQQ_LastAnswer:
|
updatePQQ_LastAnswer:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/getPQQScore.handler
|
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/getPQQScore.handler
|
||||||
|
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/submitPqqAns.*'
|
- 'src/modules/host/handlers/submitPqqAns.*'
|
||||||
|
|
||||||
- 'src/modules/host/services/**'
|
- 'src/modules/host/services/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/Activity_Hub/OnBoarding/submit-final-pqq-answer
|
path: /host/Activity_Hub/OnBoarding/submit-final-pqq-answer
|
||||||
|
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
|
|
||||||
submitPQQForReview:
|
|
||||||
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/submitPQQForReview.handler
|
|
||||||
memorySize: 384
|
|
||||||
package:
|
|
||||||
patterns:
|
|
||||||
- 'src/modules/host/handlers/Activity_Hub/OnBoarding/submitPQQForReview.*'
|
|
||||||
- 'src/modules/host/services/**'
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
|
||||||
events:
|
|
||||||
- httpApi:
|
|
||||||
path: /host/Activity_Hub/OnBoarding/submit-pqq-for-review
|
|
||||||
method: patch
|
|
||||||
|
|
||||||
getAllPQQwithSubmittedAns:
|
getAllPQQwithSubmittedAns:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/getAllPQQwithSubmittedAns.handler
|
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/getAllPQQwithSubmittedAns.handler
|
||||||
|
|
||||||
memorySize: 512
|
memorySize: 512
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/prepopulate/**'
|
- 'src/modules/prepopulate/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/Activity_Hub/OnBoarding/get-all-pqq-ques-submited-ans
|
path: /host/Activity_Hub/OnBoarding/get-all-pqq-ques-submited-ans
|
||||||
|
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
updateSuggestionAsReviewed:
|
updateSuggestionAsReviewed:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/updateSuggestionAsReviewed.handler
|
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/updateSuggestionAsReviewed.handler
|
||||||
|
|
||||||
memorySize: 512
|
memorySize: 512
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/Activity_Hub/OnBoarding/**'
|
- 'src/modules/host/handlers/Activity_Hub/OnBoarding/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /host/Activity_Hub/OnBoarding/update-suggestion-reviewed
|
path: /host/Activity_Hub/OnBoarding/update-suggestion-reviewed
|
||||||
|
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
resendOTPmail:
|
resendOTPmail:
|
||||||
|
|
||||||
handler: src/modules/host/handlers/resendOtp.handler
|
handler: src/modules/host/handlers/resendOtp.handler
|
||||||
|
|
||||||
memorySize: 512
|
memorySize: 512
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
patterns:
|
patterns:
|
||||||
|
|
||||||
- 'src/modules/host/handlers/resendOtp/**'
|
- 'src/modules/host/handlers/resendOtp/**'
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
|
|
||||||
- httpApi:
|
- httpApi:
|
||||||
|
|
||||||
path: /resend-otp
|
path: /resend-otp
|
||||||
|
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Minglar Admin Module Functions
|
# Minglar Admin Module Functions
|
||||||
# Admin dashboard and management endpoints
|
# Admin dashboard and management endpoints
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
minglarRegistration:
|
minglarRegistration:
|
||||||
handler: src/modules/minglaradmin/handlers/registration.handler
|
handler: src/modules/minglaradmin/handlers/registration.handler
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
@@ -58,22 +60,6 @@ updateMinglarProfile:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern1}
|
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern2}
|
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern3}
|
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern4}
|
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern5}
|
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern6}
|
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern7}
|
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern8}
|
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern9}
|
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern10}
|
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern11}
|
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern12}
|
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern13}
|
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern14}
|
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern15}
|
|
||||||
- ${file(./serverless/patterns/aws-s3.yml):pattern16}
|
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/update-profile
|
path: /minglaradmin/update-profile
|
||||||
@@ -94,6 +80,7 @@ prepopulateRole:
|
|||||||
path: /minglaradmin/prepopulate-Roles
|
path: /minglaradmin/prepopulate-Roles
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
|
|
||||||
getHostDetailsById:
|
getHostDetailsById:
|
||||||
handler: src/modules/minglaradmin/handlers/hosthub/hosts/getByIdHostDetails.handler
|
handler: src/modules/minglaradmin/handlers/hosthub/hosts/getByIdHostDetails.handler
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
@@ -280,8 +267,8 @@ assignAMToHost:
|
|||||||
path: /minglaradmin/hosthub/onboarding/assign-am
|
path: /minglaradmin/hosthub/onboarding/assign-am
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
editAgreementDetailsAndAccept:
|
editAgreementDetails:
|
||||||
handler: src/modules/minglaradmin/handlers/hosthub/onboarding/editAgreementDetailsAndAccept.handler
|
handler: src/modules/minglaradmin/handlers/hosthub/onboarding/editAgreementDetails.handler
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
package:
|
package:
|
||||||
patterns:
|
patterns:
|
||||||
@@ -293,24 +280,9 @@ editAgreementDetailsAndAccept:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/onboarding/edit-agreement-accept-host
|
path: /minglaradmin/hosthub/onboarding/edit-agreement
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
getAllPqqQuesAnsForAM:
|
|
||||||
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/getAllPQQwithSubmittedAns.handler
|
|
||||||
memorySize: 512
|
|
||||||
package:
|
|
||||||
patterns:
|
|
||||||
- 'src/modules/host/handlers/Activity_Hub/OnBoarding/getAllPQQwithSubmittedAns**'
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
|
||||||
events:
|
|
||||||
- httpApi:
|
|
||||||
path: /minglaradmin/hosthub/onboarding/get-all-pqq-ques-ans-for-am
|
|
||||||
method: get
|
|
||||||
|
|
||||||
acceptHostApplication:
|
acceptHostApplication:
|
||||||
handler: src/modules/minglaradmin/handlers/hosthub/hosts/acceptHostApplication.handler
|
handler: src/modules/minglaradmin/handlers/hosthub/hosts/acceptHostApplication.handler
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
@@ -340,15 +312,15 @@ RejectPQQByAM:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/hosts/reject-pq-by-am
|
path: /minglaradmin/hosthub/hosts/reject-pqq-by-am
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
acceptPQByAM:
|
acceptHostApplicationMinglar:
|
||||||
handler: src/modules/minglaradmin/handlers/hosthub/hosts/acceptPQByAM.handler
|
handler: src/modules/minglaradmin/handlers/hosthub/onboarding/acceptHostAppMinglar.handler
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
package:
|
package:
|
||||||
patterns:
|
patterns:
|
||||||
- 'src/modules/minglaradmin/handlers/hosthub/hosts/acceptPQByAM**'
|
- 'src/modules/minglaradmin/handlers/hosthub/onboarding/**'
|
||||||
- 'src/modules/minglaradmin/services/**'
|
- 'src/modules/minglaradmin/services/**'
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
@@ -356,7 +328,7 @@ acceptPQByAM:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/hosts/accept-pq-by-am
|
path: /minglaradmin/hosthub/onboarding/accept-host-application-minglar
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
rejectHostApplication:
|
rejectHostApplication:
|
||||||
@@ -373,7 +345,7 @@ rejectHostApplication:
|
|||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/onboarding/reject-host-application
|
path: /minglaradmin/hosthub/onboarding/reject-host-application
|
||||||
method: patch
|
method: post
|
||||||
|
|
||||||
rejectHostApplicationAM:
|
rejectHostApplicationAM:
|
||||||
handler: src/modules/minglaradmin/handlers/hosthub/hosts/rejectHostApplicationAM.handler
|
handler: src/modules/minglaradmin/handlers/hosthub/hosts/rejectHostApplicationAM.handler
|
||||||
@@ -389,7 +361,7 @@ rejectHostApplicationAM:
|
|||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/hosts/reject-host-application-am
|
path: /minglaradmin/hosthub/hosts/reject-host-application-am
|
||||||
method: patch
|
method: post
|
||||||
|
|
||||||
addPQQSuggestion:
|
addPQQSuggestion:
|
||||||
handler: src/modules/minglaradmin/handlers/hosthub/hosts/addPQQSuggestion.handler
|
handler: src/modules/minglaradmin/handlers/hosthub/hosts/addPQQSuggestion.handler
|
||||||
@@ -406,19 +378,3 @@ addPQQSuggestion:
|
|||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/hosts/add-Pqq-suggestion
|
path: /minglaradmin/hosthub/hosts/add-Pqq-suggestion
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
getAllPQPDetailsForAM:
|
|
||||||
handler: src/modules/minglaradmin/handlers/hosthub/pqp/getAllPQPDetailsForAM.handler
|
|
||||||
memorySize: 384
|
|
||||||
package:
|
|
||||||
patterns:
|
|
||||||
- 'src/modules/minglaradmin/handlers/hosthub/pqp/getAllPQPDetailsForAM**'
|
|
||||||
- 'src/modules/minglaradmin/services/**'
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
|
||||||
events:
|
|
||||||
- httpApi:
|
|
||||||
path: /minglaradmin/hosthub/pqp/pqp-details-for-am/{activityXid}
|
|
||||||
method: get
|
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
createActivityAndAllQuestionsEntry:
|
|
||||||
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/createActivityAndAllQuestionsEntry.handler
|
|
||||||
memorySize: 384
|
|
||||||
package:
|
|
||||||
patterns:
|
|
||||||
- 'src/modules/host/handlers/Activity_Hub/OnBoarding/createActivityAndAllQuestionsEntry**'
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
|
||||||
events:
|
|
||||||
- httpApi:
|
|
||||||
path: /host/Activity_Hub/OnBoarding/create-activity
|
|
||||||
method: post
|
|
||||||
|
|
||||||
submitPQAnswer:
|
|
||||||
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/submitPQAnswer.handler
|
|
||||||
memorySize: 384
|
|
||||||
package:
|
|
||||||
patterns:
|
|
||||||
- 'src/modules/host/handlers/Activity_Hub/OnBoarding/submitPQAnswer**'
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern1}
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
|
||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
|
||||||
events:
|
|
||||||
- httpApi:
|
|
||||||
path: /host/Activity_Hub/OnBoarding/submit-pq-answer
|
|
||||||
method: patch
|
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
# Base packaging patterns shared across all functions
|
# Base packaging patterns shared across all functions
|
||||||
|
# Note: Prisma 7 uses driver adapters (no binary engines) - everything is in the layer
|
||||||
pattern1: 'src/common/**'
|
pattern1: 'src/common/**'
|
||||||
pattern2: 'common/**'
|
pattern2: 'common/**'
|
||||||
pattern3: 'node_modules/@prisma/client/**'
|
# Prisma packages are now provided by the layer, no need to include in function package
|
||||||
pattern4: 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
|
pattern3: '!node_modules/@prisma/**'
|
||||||
pattern5: '!node_modules/.prisma/client/libquery_engine*'
|
pattern4: '!node_modules/.prisma/**'
|
||||||
|
pattern5: '!node_modules/pg/**'
|
||||||
@@ -23,16 +23,19 @@ export const STEPPER = {
|
|||||||
REJECTED: 6
|
REJECTED: 6
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const LAST_QUESTION_ID = {
|
||||||
|
Q_ID: 55
|
||||||
|
}
|
||||||
|
|
||||||
export const ACTIVITY_INTERNAL_STATUS = {
|
export const ACTIVITY_INTERNAL_STATUS = {
|
||||||
DRAFT_PQ: 'Draft - PQ',
|
DRAFT_PQ: 'Draft - PQ',
|
||||||
APPROVED: 'Approved',
|
APPROVED: 'Approved',
|
||||||
REJECTED: 'Rejected',
|
REJECTED: 'Rejected',
|
||||||
DRAFT: 'Draft',
|
DRAFT: 'Draft',
|
||||||
UNDER_REVIEW: 'Under-Review',
|
UNDER_REVIEW: 'Under-Review',
|
||||||
PQ_FAILED: 'PQ Failed',
|
PQQ_FAILED: 'PQQ Failed',
|
||||||
PQ_TO_UPDATE: 'PQ To Update',
|
PQQ_TO_UPDATE: 'PQ To Update',
|
||||||
PQ_SUBMITTED: 'PQ Submitted',
|
PQQ_SUBMITTED: 'PQ Submitted'
|
||||||
PQ_APPROVED: 'PQ Approved'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ACTIVITY_DISPLAY_STATUS = {
|
export const ACTIVITY_DISPLAY_STATUS = {
|
||||||
@@ -41,10 +44,9 @@ export const ACTIVITY_DISPLAY_STATUS = {
|
|||||||
REJECTED: 'Rejected',
|
REJECTED: 'Rejected',
|
||||||
DRAFT: 'Draft',
|
DRAFT: 'Draft',
|
||||||
UNDER_REVIEW: 'Under-Review',
|
UNDER_REVIEW: 'Under-Review',
|
||||||
PQ_FAILED: 'PQ Failed',
|
PQQ_FAILED: 'PQQ Failed',
|
||||||
ENHANCING: 'Enchancing',
|
ENHANCING: 'Enchancing',
|
||||||
PQ_IN_REVIEW: 'PQ In Review',
|
PQ_IN_REVIEW: 'PQ In Review'
|
||||||
PQ_APPROVED: 'PQ Approved'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ACTIVITY_AM_INTERNAL_STATUS = {
|
export const ACTIVITY_AM_INTERNAL_STATUS = {
|
||||||
@@ -53,10 +55,9 @@ export const ACTIVITY_AM_INTERNAL_STATUS = {
|
|||||||
REJECTED: 'Rejected',
|
REJECTED: 'Rejected',
|
||||||
DRAFT: 'Draft',
|
DRAFT: 'Draft',
|
||||||
UNDER_REVIEW: 'Under-Review',
|
UNDER_REVIEW: 'Under-Review',
|
||||||
PQ_FAILED: 'PQ Failed',
|
PQQ_FAILED: 'PQQ Failed',
|
||||||
PQ_REJECTED: 'PQ Rejected',
|
PQQ_REJECTED: 'PQ Rejected',
|
||||||
PQ_TO_REVIEW: 'PQ To Review',
|
PQQ_TO_REVIEW: 'PQ To Review'
|
||||||
PQ_APPROVED: 'PQ Approved'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ACTIVITY_AM_DISPLAY_STATUS = {
|
export const ACTIVITY_AM_DISPLAY_STATUS = {
|
||||||
@@ -65,9 +66,7 @@ export const ACTIVITY_AM_DISPLAY_STATUS = {
|
|||||||
REJECTED: 'Rejected',
|
REJECTED: 'Rejected',
|
||||||
DRAFT: 'Draft',
|
DRAFT: 'Draft',
|
||||||
UNDER_REVIEW: 'Under-Review',
|
UNDER_REVIEW: 'Under-Review',
|
||||||
PQ_FAILED: 'PQ Failed',
|
PQQ_FAILED: 'PQQ Failed',
|
||||||
ENHANCING: 'Enchancing',
|
ENHANCING: 'Enchancing',
|
||||||
NEW: 'New',
|
NEW: 'New'
|
||||||
PQ_APPROVED: 'PQ Approved',
|
|
||||||
REVISED: 'Revised'
|
|
||||||
}
|
}
|
||||||
@@ -25,35 +25,23 @@ export const MINGLAR_INVITATION_STATUS = {
|
|||||||
INVITED: 'Invited',
|
INVITED: 'Invited',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ACTIVITY_TRACK_TYPE = {
|
export const HOST_SUGGESTION_TITLES = {
|
||||||
PQ: 'PQ',
|
COMPANY_DETAILS: 'Complete Details',
|
||||||
ACTIVITY: 'Activity'
|
COMPANY_DOCUMENTATION: 'Company documentataion',
|
||||||
}
|
COMPANY_SOCIAL_PROOF: 'Social Proof',
|
||||||
|
ACTIVITY_INFORMATION: 'Activity Information',
|
||||||
export const ACTIVITY_TRACK_STATUS = {
|
ACTIVITY_LOCATION: 'Activity Location',
|
||||||
REJECTED_BY_AM: 'Rejected By AM',
|
PICKUP_DROP_LOCATION: 'Pickup-Drop Location',
|
||||||
ACCEPTED_BY_AM: 'Accepted By AM',
|
NUMBER_OF_PEOPLE: 'Number of People',
|
||||||
ENHANCING: 'Enhancing',
|
INCLUSION: 'Inclusion',
|
||||||
PQ_SUBMITTED: 'PQ Submitted'
|
TAX_SETUP: 'Tax Setup',
|
||||||
}
|
ENERGY_LEVEL: 'Energy Level',
|
||||||
|
ELIGIBILITY_CRITERIA: 'Eligibility Criteria',
|
||||||
// export const HOST_SUGGESTION_TITLES = {
|
AMENITIES: 'Amenities',
|
||||||
// COMPANY_DETAILS: 'Complete Details',
|
EXLUSIVE_NOTES: 'Exclusive Notes',
|
||||||
// COMPANY_DOCUMENTATION: 'Company documentataion',
|
CANCELLATION_POLICY: 'Cancellation Policy',
|
||||||
// COMPANY_SOCIAL_PROOF: 'Social Proof',
|
DOs_AND_DONTs: 'Do’s and Dont’s',
|
||||||
// ACTIVITY_INFORMATION: 'Activity Information',
|
TIPS_FOR_USERS: 'Tips for Users',
|
||||||
// ACTIVITY_LOCATION: 'Activity Location',
|
SUSTAINABILITY: 'Sustainability',
|
||||||
// PICKUP_DROP_LOCATION: 'Pickup-Drop Location',
|
TERMS_AND_CONDITION_FOR_USER: 'Terms and Conditions for User'
|
||||||
// NUMBER_OF_PEOPLE: 'Number of People',
|
};
|
||||||
// INCLUSION: 'Inclusion',
|
|
||||||
// TAX_SETUP: 'Tax Setup',
|
|
||||||
// ENERGY_LEVEL: 'Energy Level',
|
|
||||||
// ELIGIBILITY_CRITERIA: 'Eligibility Criteria',
|
|
||||||
// AMENITIES: 'Amenities',
|
|
||||||
// EXLUSIVE_NOTES: 'Exclusive Notes',
|
|
||||||
// CANCELLATION_POLICY: 'Cancellation Policy',
|
|
||||||
// DOs_AND_DONTs: 'Do’s and Dont’s',
|
|
||||||
// TIPS_FOR_USERS: 'Tips for Users',
|
|
||||||
// SUSTAINABILITY: 'Sustainability',
|
|
||||||
// TERMS_AND_CONDITION_FOR_USER: 'Terms and Conditions for User'
|
|
||||||
// };
|
|
||||||
|
|||||||
140
src/common/utils/validation/host/activity.validation.ts
Normal file
140
src/common/utils/validation/host/activity.validation.ts
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
/**
|
||||||
|
* Host Activity Validation Schemas
|
||||||
|
* Production-ready Zod validations for host activity management
|
||||||
|
*/
|
||||||
|
import { z } from 'zod';
|
||||||
|
import { idSchema, optionalIdSchema, searchQuerySchema, paginationSchema } from '../validation.utils';
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// CREATE ACTIVITY (FOR PQQ)
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create activity schema
|
||||||
|
*/
|
||||||
|
export const createActivitySchema = z.object({
|
||||||
|
activityTypeXid: idSchema.describe('Activity type ID'),
|
||||||
|
frequenciesXid: optionalIdSchema.describe('Frequency ID'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type CreateActivityInput = z.infer<typeof createActivitySchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// GET ACTIVITY TYPE
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all activity types query params
|
||||||
|
*/
|
||||||
|
export const getActivityTypeQuerySchema = z.object({
|
||||||
|
interestXid: z.coerce
|
||||||
|
.number()
|
||||||
|
.int('Interest ID must be an integer')
|
||||||
|
.positive('Interest ID must be positive')
|
||||||
|
.optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GetActivityTypeQuery = z.infer<typeof getActivityTypeQuerySchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// GET PQQ BY QUESTION ID
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get PQQ by question ID query params
|
||||||
|
*/
|
||||||
|
export const getPqqByQuestionIdQuerySchema = z.object({
|
||||||
|
question_xid: z.coerce
|
||||||
|
.number()
|
||||||
|
.int('Question ID must be an integer')
|
||||||
|
.positive('Question ID must be positive'),
|
||||||
|
activity_xid: z.coerce
|
||||||
|
.number()
|
||||||
|
.int('Activity ID must be an integer')
|
||||||
|
.positive('Activity ID must be positive'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GetPqqByQuestionIdQuery = z.infer<typeof getPqqByQuestionIdQuerySchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// SUBMIT PQQ ANSWER
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submit PQQ answer schema
|
||||||
|
*/
|
||||||
|
export const submitPqqAnswerSchema = z.object({
|
||||||
|
activityXid: idSchema.describe('Activity ID'),
|
||||||
|
questionXid: idSchema.describe('Question ID'),
|
||||||
|
answerXid: idSchema.describe('Answer ID'),
|
||||||
|
// For file uploads, these are handled separately
|
||||||
|
documentPath: z.string().max(500).optional(),
|
||||||
|
remarks: z.string().max(500, 'Remarks cannot exceed 500 characters').optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type SubmitPqqAnswerInput = z.infer<typeof submitPqqAnswerSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// UPDATE SUGGESTION AS REVIEWED
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update suggestion as reviewed schema
|
||||||
|
*/
|
||||||
|
export const updateSuggestionReviewedSchema = z.object({
|
||||||
|
activityPqqHeaderXid: idSchema.describe('Activity PQQ Header ID'),
|
||||||
|
activityPQQSuggestionId: idSchema.optional().describe('Activity PQQ Suggestion ID'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UpdateSuggestionReviewedInput = z.infer<typeof updateSuggestionReviewedSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// GET ALL HOST ACTIVITY
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all host activities query params
|
||||||
|
*/
|
||||||
|
export const getAllHostActivityQuerySchema = z.object({
|
||||||
|
hostXid: z.coerce
|
||||||
|
.number()
|
||||||
|
.int('Host ID must be an integer')
|
||||||
|
.positive('Host ID must be positive')
|
||||||
|
.optional(),
|
||||||
|
status: z
|
||||||
|
.enum(['pending', 'approved', 'rejected', 'draft'])
|
||||||
|
.optional(),
|
||||||
|
...paginationSchema.shape,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GetAllHostActivityQuery = z.infer<typeof getAllHostActivityQuerySchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// GET LATEST QUESTION (activity_xid query param)
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get latest PQQ question query params
|
||||||
|
*/
|
||||||
|
export const getLatestPqqQuestionQuerySchema = z.object({
|
||||||
|
activity_xid: z.coerce
|
||||||
|
.number()
|
||||||
|
.int('Activity ID must be an integer')
|
||||||
|
.positive('Activity ID must be positive'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GetLatestPqqQuestionQuery = z.infer<typeof getLatestPqqQuestionQuerySchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// SEARCH QUERY (optional)
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional search query params
|
||||||
|
*/
|
||||||
|
export const optionalSearchQuerySchema = z.object({
|
||||||
|
search: searchQuerySchema,
|
||||||
|
q: searchQuerySchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type OptionalSearchQuery = z.infer<typeof optionalSearchQuerySchema>;
|
||||||
@@ -1,35 +1,27 @@
|
|||||||
// validations/hostBankDetails.validation.ts
|
/**
|
||||||
import { z } from "zod";
|
* Host Bank Details Validation Schema
|
||||||
|
* Production-ready Zod validation for payment/bank details
|
||||||
|
*/
|
||||||
|
import { z } from 'zod';
|
||||||
|
import { idSchema, ifscCodeSchema, accountNumberSchema } from '../validation.utils';
|
||||||
|
|
||||||
export const hostBankDetailsSchema = z.object({
|
export const hostBankDetailsSchema = z.object({
|
||||||
accountNumber: z
|
accountNumber: accountNumberSchema,
|
||||||
.string()
|
|
||||||
.nonempty("Account number is required"),
|
|
||||||
|
|
||||||
accountHolderName: z
|
accountHolderName: z
|
||||||
.string()
|
.string()
|
||||||
.nonempty("Account holder name is required")
|
.min(2, 'Account holder name must be at least 2 characters')
|
||||||
.min(2, { message: "Account holder name must be at least 2 characters" }),
|
.max(100, 'Account holder name cannot exceed 100 characters'),
|
||||||
|
|
||||||
bankXid: z
|
ifscCode: ifscCodeSchema,
|
||||||
.number()
|
|
||||||
.int({ message: "Bank ID must be an integer" })
|
|
||||||
.positive({ message: "Bank ID must be a positive number" }),
|
|
||||||
|
|
||||||
hostXid: z
|
bankXid: idSchema.describe('Bank ID'),
|
||||||
.number()
|
|
||||||
.int({ message: "Host ID must be an integer" })
|
|
||||||
.positive({ message: "Host ID must be a positive number" }),
|
|
||||||
|
|
||||||
bankBranchXid: z
|
hostXid: idSchema.describe('Host ID'),
|
||||||
.number()
|
|
||||||
.int({ message: "Bank branch ID must be an integer" })
|
|
||||||
.positive({ message: "Bank branch ID must be a positive number" }),
|
|
||||||
|
|
||||||
currencyXid: z
|
bankBranchXid: idSchema.describe('Bank branch ID'),
|
||||||
.number()
|
|
||||||
.int({ message: "Currency ID must be an integer" })
|
currencyXid: idSchema.describe('Currency ID'),
|
||||||
.positive({ message: "Currency ID must be a positive number" }),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type HostBankDetailsSchema = z.infer<typeof hostBankDetailsSchema>;
|
export type HostBankDetailsInput = z.infer<typeof hostBankDetailsSchema>;
|
||||||
|
|||||||
139
src/common/utils/validation/host/auth.validation.ts
Normal file
139
src/common/utils/validation/host/auth.validation.ts
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
/**
|
||||||
|
* Host Onboarding Validation Schemas
|
||||||
|
* Production-ready Zod validations for host registration and authentication
|
||||||
|
* Compatible with Zod v4
|
||||||
|
*/
|
||||||
|
import { z } from 'zod';
|
||||||
|
import {
|
||||||
|
emailSchema,
|
||||||
|
simplePasswordSchema,
|
||||||
|
otpSchema,
|
||||||
|
nameSchema,
|
||||||
|
optionalNameSchema,
|
||||||
|
mobileNumberSchema,
|
||||||
|
isdCodeSchema,
|
||||||
|
} from '../validation.utils';
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// SIGNUP / REGISTRATION
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Host registration/signup schema
|
||||||
|
*/
|
||||||
|
export const hostSignUpSchema = z.object({
|
||||||
|
email: emailSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type HostSignUpInput = z.infer<typeof hostSignUpSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// OTP VERIFICATION
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OTP verification schema
|
||||||
|
*/
|
||||||
|
export const verifyOtpSchema = z.object({
|
||||||
|
otp: otpSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type VerifyOtpInput = z.infer<typeof verifyOtpSchema>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OTP verification with email schema (for verifyOTP handler)
|
||||||
|
*/
|
||||||
|
export const verifyOtpWithEmailSchema = z.object({
|
||||||
|
email: emailSchema,
|
||||||
|
otp: otpSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type VerifyOtpWithEmailInput = z.infer<typeof verifyOtpWithEmailSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// LOGIN
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Host login schema
|
||||||
|
*/
|
||||||
|
export const hostLoginSchema = z.object({
|
||||||
|
emailAddress: emailSchema,
|
||||||
|
userPassword: z
|
||||||
|
.string()
|
||||||
|
.min(1, 'Password is required'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type HostLoginInput = z.infer<typeof hostLoginSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// CREATE PASSWORD
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create password schema with confirmation matching
|
||||||
|
*/
|
||||||
|
export const createPasswordSchema = z
|
||||||
|
.object({
|
||||||
|
password: simplePasswordSchema,
|
||||||
|
confirmPassword: z.string().min(1, 'Confirm password is required'),
|
||||||
|
})
|
||||||
|
.refine((data) => data.password === data.confirmPassword, {
|
||||||
|
message: 'Password and confirm password do not match',
|
||||||
|
path: ['confirmPassword'],
|
||||||
|
});
|
||||||
|
|
||||||
|
export type CreatePasswordInput = z.infer<typeof createPasswordSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// RESEND OTP
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resend OTP schema
|
||||||
|
*/
|
||||||
|
export const resendOtpSchema = z.object({
|
||||||
|
email: emailSchema,
|
||||||
|
purpose: z
|
||||||
|
.enum(['Register', 'Login', 'ForgotPassword'])
|
||||||
|
.optional()
|
||||||
|
.default('Register'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type ResendOtpInput = z.infer<typeof resendOtpSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// UPDATE PROFILE
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Host profile update schema
|
||||||
|
*/
|
||||||
|
export const updateHostProfileSchema = z.object({
|
||||||
|
firstName: optionalNameSchema,
|
||||||
|
lastName: optionalNameSchema,
|
||||||
|
mobileNumber: mobileNumberSchema,
|
||||||
|
isdCode: isdCodeSchema,
|
||||||
|
dateOfBirth: z
|
||||||
|
.string()
|
||||||
|
.refine((val) => !val || !isNaN(Date.parse(val)), 'Invalid date format')
|
||||||
|
.optional(),
|
||||||
|
profileImage: z.string().max(500, 'Profile image path cannot exceed 500 characters').optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UpdateHostProfileInput = z.infer<typeof updateHostProfileSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// ACCEPT AGREEMENT
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accept agreement schema (just confirmation)
|
||||||
|
*/
|
||||||
|
export const acceptAgreementSchema = z.object({
|
||||||
|
agreementAccepted: z.literal(true, {
|
||||||
|
message: 'Agreement must be accepted',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type AcceptAgreementInput = z.infer<typeof acceptAgreementSchema>;
|
||||||
@@ -6,20 +6,20 @@ export const parentCompanySchema = z.object({
|
|||||||
.max(100, "Parent company name cannot exceed 100 characters"),
|
.max(100, "Parent company name cannot exceed 100 characters"),
|
||||||
|
|
||||||
address1: z.string()
|
address1: z.string()
|
||||||
.max(150, "Address1 cannot exceed 150 characters")
|
.min(1, "Address1 is required")
|
||||||
.optional(),
|
.max(150, "Address1 cannot exceed 150 characters"),
|
||||||
|
|
||||||
address2: z.string()
|
address2: z.string()
|
||||||
.max(150, "Address2 cannot exceed 150 characters")
|
.max(150, "Address2 cannot exceed 150 characters")
|
||||||
.optional(),
|
.optional(),
|
||||||
|
|
||||||
cityXid: z.number().optional(),
|
cityXid: z.number().min(1, "City is required"),
|
||||||
stateXid: z.number().optional(),
|
stateXid: z.number().min(1, "State is required"),
|
||||||
countryXid: z.number().optional(),
|
countryXid: z.number().min(1, "Country is required"),
|
||||||
|
|
||||||
pinCode: z.string()
|
pinCode: z.string()
|
||||||
.max(30, "Pincode cannot exceed 30 characters")
|
.min(4, "Pincode/Zipcode is required")
|
||||||
.optional(),
|
.max(30, "Pincode cannot exceed 30 characters"),
|
||||||
|
|
||||||
logoPath: z.string()
|
logoPath: z.string()
|
||||||
.max(400, "Logo path cannot exceed 400 characters")
|
.max(400, "Logo path cannot exceed 400 characters")
|
||||||
@@ -45,15 +45,15 @@ export const parentCompanySchema = z.object({
|
|||||||
message: "Formation date must be a valid date",
|
message: "Formation date must be a valid date",
|
||||||
}),
|
}),
|
||||||
|
|
||||||
companyTypeXid: z.number()
|
companyType: z.string()
|
||||||
.min(1, "Company type XID is required"),
|
.min(1, "Company type is required")
|
||||||
|
.max(30, "Company type cannot exceed 30 characters"),
|
||||||
websiteUrl: z.string().nullable().optional(),
|
|
||||||
instagramUrl: z.string().nullable().optional(),
|
|
||||||
facebookUrl: z.string().nullable().optional(),
|
|
||||||
linkedinUrl: z.string().nullable().optional(),
|
|
||||||
twitterUrl: z.string().nullable().optional(),
|
|
||||||
|
|
||||||
|
websiteUrl: z.string().url().max(80, "Website URL cannot exceed 80 characters").optional(),
|
||||||
|
instagramUrl: z.string().url().max(80, "Instagram URL cannot exceed 80 characters").optional(),
|
||||||
|
facebookUrl: z.string().url().max(80, "Facebook URL cannot exceed 80 characters").optional(),
|
||||||
|
linkedinUrl: z.string().url().max(80, "LinkedIn URL cannot exceed 80 characters").optional(),
|
||||||
|
twitterUrl: z.string().url().max(80, "Twitter URL cannot exceed 80 characters").optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -106,20 +106,15 @@ export const hostCompanyDetailsSchema = z.object({
|
|||||||
message: "Formation date must be a valid date",
|
message: "Formation date must be a valid date",
|
||||||
}),
|
}),
|
||||||
|
|
||||||
companyTypeXid: z.number()
|
companyType: z.string()
|
||||||
.int("Company type must be a valid integer")
|
.min(1, "Company type is required")
|
||||||
.min(1, "Company type is required"),
|
.max(30, "Company type cannot exceed 30 characters"),
|
||||||
|
|
||||||
|
|
||||||
referencedBy: z.string()
|
|
||||||
.optional(),
|
|
||||||
|
|
||||||
websiteUrl: z.string().nullable().optional(),
|
|
||||||
instagramUrl: z.string().nullable().optional(),
|
|
||||||
facebookUrl: z.string().nullable().optional(),
|
|
||||||
linkedinUrl: z.string().nullable().optional(),
|
|
||||||
twitterUrl: z.string().nullable().optional(),
|
|
||||||
|
|
||||||
|
websiteUrl: z.string().url().max(50, "Website URL cannot exceed 50 characters").optional(),
|
||||||
|
instagramUrl: z.string().url().max(80, "Instagram URL cannot exceed 80 characters").optional(),
|
||||||
|
facebookUrl: z.string().url().max(80, "Facebook URL cannot exceed 80 characters").optional(),
|
||||||
|
linkedinUrl: z.string().url().max(80, "LinkedIn URL cannot exceed 80 characters").optional(),
|
||||||
|
twitterUrl: z.string().url().max(80, "Twitter URL cannot exceed 80 characters").optional(),
|
||||||
|
|
||||||
parentCompany: parentCompanySchema.optional(),
|
parentCompany: parentCompanySchema.optional(),
|
||||||
});
|
});
|
||||||
|
|||||||
13
src/common/utils/validation/host/index.ts
Normal file
13
src/common/utils/validation/host/index.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Host Module Validation Schemas Index
|
||||||
|
* Export all host-related validation schemas
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Authentication & Onboarding
|
||||||
|
export * from './auth.validation';
|
||||||
|
export * from './login.validation';
|
||||||
|
export * from './addPaymentDetails.validation';
|
||||||
|
export * from './hostCompanyDetails.validation';
|
||||||
|
|
||||||
|
// Activity Management
|
||||||
|
export * from './activity.validation';
|
||||||
@@ -1,20 +1,16 @@
|
|||||||
// validations/hostBankDetails.validation.ts
|
/**
|
||||||
import { z } from "zod";
|
* Host Login Validation Schema
|
||||||
|
* Production-ready Zod validation for host login
|
||||||
|
*/
|
||||||
|
import { z } from 'zod';
|
||||||
|
import { emailSchema } from '../validation.utils';
|
||||||
|
|
||||||
export const loginForHostSchema = z.object({
|
export const loginForHostSchema = z.object({
|
||||||
|
emailAddress: emailSchema,
|
||||||
|
|
||||||
|
userPassword: z
|
||||||
emailAddress : z
|
.string()
|
||||||
.string()
|
.min(1, 'Password is required'),
|
||||||
.nonempty("Email is required"),
|
|
||||||
|
|
||||||
userPassword : z
|
|
||||||
.string()
|
|
||||||
.nonempty("Password is required")
|
|
||||||
.min(8, { message: "Password must be at least 8 characters" }),
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type loginForHostSchema = z.infer<typeof loginForHostSchema>;
|
export type LoginForHostInput = z.infer<typeof loginForHostSchema>;
|
||||||
|
|||||||
16
src/common/utils/validation/index.ts
Normal file
16
src/common/utils/validation/index.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* Validation Module Index
|
||||||
|
* Central export for all validation schemas and utilities
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Validation Utilities
|
||||||
|
export * from './validation.utils';
|
||||||
|
|
||||||
|
// Host Module Validations
|
||||||
|
export * as hostValidation from './host';
|
||||||
|
|
||||||
|
// Minglar Admin Module Validations
|
||||||
|
export * as minglarValidation from './minglaradmin';
|
||||||
|
|
||||||
|
// Prepopulate Module Validations
|
||||||
|
export * as prepopulateValidation from './prepopulate';
|
||||||
107
src/common/utils/validation/minglaradmin/auth.validation.ts
Normal file
107
src/common/utils/validation/minglaradmin/auth.validation.ts
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/**
|
||||||
|
* Minglar Admin Authentication Validation Schemas
|
||||||
|
* Production-ready Zod validations for admin authentication
|
||||||
|
* Compatible with Zod v4
|
||||||
|
*/
|
||||||
|
import { z } from 'zod';
|
||||||
|
import { emailSchema, simplePasswordSchema, otpSchema } from '../validation.utils';
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// REGISTRATION
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minglar admin registration schema
|
||||||
|
*/
|
||||||
|
export const minglarRegistrationSchema = z.object({
|
||||||
|
email: emailSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type MinglarRegistrationInput = z.infer<typeof minglarRegistrationSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// LOGIN
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minglar admin login schema
|
||||||
|
*/
|
||||||
|
export const minglarLoginSchema = z.object({
|
||||||
|
emailAddress: emailSchema,
|
||||||
|
userPassword: z
|
||||||
|
.string()
|
||||||
|
.min(1, 'Password is required'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type MinglarLoginInput = z.infer<typeof minglarLoginSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// CREATE PASSWORD
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create password schema with confirmation
|
||||||
|
*/
|
||||||
|
export const minglarCreatePasswordSchema = z
|
||||||
|
.object({
|
||||||
|
password: simplePasswordSchema,
|
||||||
|
confirmPassword: z.string().min(1, 'Confirm password is required'),
|
||||||
|
})
|
||||||
|
.refine((data) => data.password === data.confirmPassword, {
|
||||||
|
message: 'Password and confirm password do not match',
|
||||||
|
path: ['confirmPassword'],
|
||||||
|
});
|
||||||
|
|
||||||
|
export type MinglarCreatePasswordInput = z.infer<typeof minglarCreatePasswordSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// VERIFY OTP
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OTP verification schema
|
||||||
|
*/
|
||||||
|
export const minglarVerifyOtpSchema = z.object({
|
||||||
|
otp: otpSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type MinglarVerifyOtpInput = z.infer<typeof minglarVerifyOtpSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// UPDATE PROFILE
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Admin profile update schema
|
||||||
|
*/
|
||||||
|
export const minglarUpdateProfileSchema = z.object({
|
||||||
|
firstName: z
|
||||||
|
.string()
|
||||||
|
.min(1, 'First name is required')
|
||||||
|
.max(50, 'First name cannot exceed 50 characters')
|
||||||
|
.optional(),
|
||||||
|
lastName: z
|
||||||
|
.string()
|
||||||
|
.min(1, 'Last name is required')
|
||||||
|
.max(50, 'Last name cannot exceed 50 characters')
|
||||||
|
.optional(),
|
||||||
|
mobileNumber: z
|
||||||
|
.string()
|
||||||
|
.max(15, 'Mobile number cannot exceed 15 digits')
|
||||||
|
.regex(/^[0-9]*$/, 'Mobile number must contain only digits')
|
||||||
|
.optional(),
|
||||||
|
isdCode: z
|
||||||
|
.string()
|
||||||
|
.max(6, 'ISD code cannot exceed 6 characters')
|
||||||
|
.optional(),
|
||||||
|
dateOfBirth: z
|
||||||
|
.string()
|
||||||
|
.refine((val) => !val || !isNaN(Date.parse(val)), 'Invalid date format')
|
||||||
|
.optional(),
|
||||||
|
profileImage: z
|
||||||
|
.string()
|
||||||
|
.max(500, 'Profile image path cannot exceed 500 characters')
|
||||||
|
.optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type MinglarUpdateProfileInput = z.infer<typeof minglarUpdateProfileSchema>;
|
||||||
252
src/common/utils/validation/minglaradmin/hosthub.validation.ts
Normal file
252
src/common/utils/validation/minglaradmin/hosthub.validation.ts
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
/**
|
||||||
|
* Minglar Admin Host Hub Validation Schemas
|
||||||
|
* Production-ready Zod validations for host management by admins
|
||||||
|
*/
|
||||||
|
import { z } from 'zod';
|
||||||
|
import { idSchema, searchQuerySchema, paginationSchema } from '../validation.utils';
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// GET ALL HOST APPLICATIONS
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query params for getting all host applications
|
||||||
|
*/
|
||||||
|
export const getAllHostApplicationsQuerySchema = z.object({
|
||||||
|
search: searchQuerySchema,
|
||||||
|
userStatus: z
|
||||||
|
.string()
|
||||||
|
.max(20, 'Status cannot exceed 20 characters')
|
||||||
|
.optional(),
|
||||||
|
roleFilter: z
|
||||||
|
.string()
|
||||||
|
.max(30, 'Role filter cannot exceed 30 characters')
|
||||||
|
.optional(),
|
||||||
|
...paginationSchema.shape,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GetAllHostApplicationsQuery = z.infer<typeof getAllHostApplicationsQuerySchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// ASSIGN AM TO HOST
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign account manager to host schema
|
||||||
|
*/
|
||||||
|
export const assignAmToHostSchema = z.object({
|
||||||
|
hostXid: idSchema.describe('Host ID'),
|
||||||
|
accountManagerXid: idSchema.describe('Account Manager ID'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type AssignAmToHostInput = z.infer<typeof assignAmToHostSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// UPDATE HOST STATUS
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update host status schema
|
||||||
|
*/
|
||||||
|
export const updateHostStatusSchema = z.object({
|
||||||
|
hostXid: idSchema.describe('Host ID'),
|
||||||
|
status: z
|
||||||
|
.enum(['approved', 'rejected', 'pending', 'resubmit'])
|
||||||
|
.describe('New host status'),
|
||||||
|
remarks: z
|
||||||
|
.string()
|
||||||
|
.max(500, 'Remarks cannot exceed 500 characters')
|
||||||
|
.optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UpdateHostStatusInput = z.infer<typeof updateHostStatusSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// GET HOST BY ID
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get host by ID query params
|
||||||
|
*/
|
||||||
|
export const getHostByIdQuerySchema = z.object({
|
||||||
|
hostXid: z.coerce
|
||||||
|
.number()
|
||||||
|
.int('Host ID must be an integer')
|
||||||
|
.positive('Host ID must be positive'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GetHostByIdQuery = z.infer<typeof getHostByIdQuerySchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// ADD HOST SUGGESTION
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add suggestion to host schema
|
||||||
|
*/
|
||||||
|
export const addHostSuggestionSchema = z.object({
|
||||||
|
hostXid: idSchema.describe('Host ID'),
|
||||||
|
title: z
|
||||||
|
.string()
|
||||||
|
.min(1, 'Title is required')
|
||||||
|
.max(100, 'Title cannot exceed 100 characters'),
|
||||||
|
comments: z
|
||||||
|
.string()
|
||||||
|
.min(1, 'Comments are required')
|
||||||
|
.max(500, 'Comments cannot exceed 500 characters'),
|
||||||
|
isParent: z.boolean().optional().default(false),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type AddHostSuggestionInput = z.infer<typeof addHostSuggestionSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// AGREEMENT SETTINGS
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update agreement settings schema
|
||||||
|
*/
|
||||||
|
export const updateAgreementSettingsSchema = z.object({
|
||||||
|
hostXid: idSchema.describe('Host ID'),
|
||||||
|
agreementStartDate: z
|
||||||
|
.string()
|
||||||
|
.refine((val) => !isNaN(Date.parse(val)), 'Invalid date format'),
|
||||||
|
durationNumber: z
|
||||||
|
.number()
|
||||||
|
.int('Duration must be an integer')
|
||||||
|
.positive('Duration must be positive'),
|
||||||
|
durationFrequency: z.enum(['days', 'months', 'years']),
|
||||||
|
isCommisionBase: z.boolean(),
|
||||||
|
commisionPer: z
|
||||||
|
.number()
|
||||||
|
.min(0, 'Commission percentage must be at least 0')
|
||||||
|
.max(100, 'Commission percentage cannot exceed 100')
|
||||||
|
.optional(),
|
||||||
|
amountPerBooking: z
|
||||||
|
.number()
|
||||||
|
.int('Amount must be an integer')
|
||||||
|
.positive('Amount must be positive')
|
||||||
|
.optional(),
|
||||||
|
payoutDurationNum: z
|
||||||
|
.number()
|
||||||
|
.int('Payout duration must be an integer')
|
||||||
|
.positive('Payout duration must be positive')
|
||||||
|
.optional(),
|
||||||
|
payoutDurationFrequency: z.enum(['days', 'months', 'years']).optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UpdateAgreementSettingsInput = z.infer<typeof updateAgreementSettingsSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// ACCEPT/REJECT HOST APPLICATION (by hostXid)
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Host application action schema (accept/reject by AM or Admin)
|
||||||
|
*/
|
||||||
|
export const hostApplicationActionSchema = z.object({
|
||||||
|
hostXid: idSchema.describe('Host ID'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type HostApplicationActionInput = z.infer<typeof hostApplicationActionSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// ADD PQQ SUGGESTION
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add PQQ suggestion schema
|
||||||
|
*/
|
||||||
|
export const addPqqSuggestionSchema = z.object({
|
||||||
|
title: z
|
||||||
|
.string()
|
||||||
|
.min(1, 'Title is required')
|
||||||
|
.max(100, 'Title cannot exceed 100 characters'),
|
||||||
|
comments: z
|
||||||
|
.string()
|
||||||
|
.min(1, 'Comments are required')
|
||||||
|
.max(500, 'Comments cannot exceed 500 characters'),
|
||||||
|
activity_pqq_header_xid: idSchema.describe('Activity PQQ Header ID'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type AddPqqSuggestionInput = z.infer<typeof addPqqSuggestionSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// GET HOST BY ID (path param)
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get host by ID from path params
|
||||||
|
*/
|
||||||
|
export const getHostByIdPathSchema = z.object({
|
||||||
|
host_xid: z.coerce
|
||||||
|
.number()
|
||||||
|
.int('Host ID must be an integer')
|
||||||
|
.positive('Host ID must be positive'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GetHostByIdPathInput = z.infer<typeof getHostByIdPathSchema>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get host by ID from path params (alternative with 'id')
|
||||||
|
*/
|
||||||
|
export const getHostByIdAltPathSchema = z.object({
|
||||||
|
id: z.coerce
|
||||||
|
.number()
|
||||||
|
.int('Host ID must be an integer')
|
||||||
|
.positive('Host ID must be positive'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GetHostByIdAltPathInput = z.infer<typeof getHostByIdAltPathSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// REJECT PQQ BY AM
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reject PQQ by AM schema
|
||||||
|
*/
|
||||||
|
export const rejectPqqByAmSchema = z.object({
|
||||||
|
activityId: idSchema.describe('Activity ID'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type RejectPqqByAmInput = z.infer<typeof rejectPqqByAmSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// EDIT AGREEMENT DETAILS
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit agreement details schema
|
||||||
|
*/
|
||||||
|
export const editAgreementDetailsSchema = z.object({
|
||||||
|
host_xid: idSchema.describe('Host ID'),
|
||||||
|
agreementStartDate: z
|
||||||
|
.string()
|
||||||
|
.min(1, 'Agreement start date is required')
|
||||||
|
.refine((val) => !isNaN(Date.parse(val)), 'Invalid date format'),
|
||||||
|
duration: z
|
||||||
|
.number()
|
||||||
|
.int('Duration must be an integer')
|
||||||
|
.positive('Duration must be positive'),
|
||||||
|
isCommisionBase: z.boolean(),
|
||||||
|
commisionPer: z
|
||||||
|
.number()
|
||||||
|
.min(0, 'Commission percentage must be at least 0')
|
||||||
|
.max(100, 'Commission percentage cannot exceed 100')
|
||||||
|
.optional(),
|
||||||
|
amountPerBooking: z
|
||||||
|
.number()
|
||||||
|
.int('Amount must be an integer')
|
||||||
|
.positive('Amount must be positive')
|
||||||
|
.optional(),
|
||||||
|
durationFrequency: z.string().min(1, 'Duration frequency is required'),
|
||||||
|
payoutDurationNum: z
|
||||||
|
.number()
|
||||||
|
.int('Payout duration must be an integer')
|
||||||
|
.positive('Payout duration must be positive')
|
||||||
|
.optional(),
|
||||||
|
payoutDurationFrequency: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type EditAgreementDetailsInput = z.infer<typeof editAgreementDetailsSchema>;
|
||||||
13
src/common/utils/validation/minglaradmin/index.ts
Normal file
13
src/common/utils/validation/minglaradmin/index.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Minglar Admin Module Validation Schemas Index
|
||||||
|
* Export all minglar admin-related validation schemas
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Authentication
|
||||||
|
export * from './auth.validation';
|
||||||
|
|
||||||
|
// Teammate Management
|
||||||
|
export * from './teammate.validation';
|
||||||
|
|
||||||
|
// Host Hub Management
|
||||||
|
export * from './hosthub.validation';
|
||||||
117
src/common/utils/validation/minglaradmin/teammate.validation.ts
Normal file
117
src/common/utils/validation/minglaradmin/teammate.validation.ts
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
/**
|
||||||
|
* Minglar Admin Teammate Management Validation Schemas
|
||||||
|
* Production-ready Zod validations for teammate/invite management
|
||||||
|
*/
|
||||||
|
import { z } from 'zod';
|
||||||
|
import { emailSchema, idSchema, searchQuerySchema, paginationSchema } from '../validation.utils';
|
||||||
|
import { ROLE } from '../../constants/common.constant';
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// INVITE TEAMMATE
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invite teammate schema
|
||||||
|
*/
|
||||||
|
export const inviteTeammateSchema = z.object({
|
||||||
|
emailAddress: emailSchema,
|
||||||
|
|
||||||
|
roleXid: z
|
||||||
|
.number()
|
||||||
|
.int('Role ID must be an integer')
|
||||||
|
.refine(
|
||||||
|
(val) => [ROLE.CO_ADMIN, ROLE.ACCOUNT_MANAGER].includes(val),
|
||||||
|
'Invalid role. Only Co-Admin and Account Manager roles can be assigned'
|
||||||
|
),
|
||||||
|
|
||||||
|
isFixedSalary: z.boolean(),
|
||||||
|
|
||||||
|
perValue: z
|
||||||
|
.number()
|
||||||
|
.positive('Per value must be greater than 0')
|
||||||
|
.optional(),
|
||||||
|
}).refine(
|
||||||
|
(data) => {
|
||||||
|
// If Account Manager and not fixed salary, perValue is required
|
||||||
|
if (data.roleXid === ROLE.ACCOUNT_MANAGER && !data.isFixedSalary) {
|
||||||
|
return data.perValue !== undefined && data.perValue > 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message: 'Per value is required for commission-based Account Managers',
|
||||||
|
path: ['perValue'],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export type InviteTeammateInput = z.infer<typeof inviteTeammateSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// GET ALL COADMIN AND AM (with search)
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query params for getting co-admins and account managers
|
||||||
|
*/
|
||||||
|
export const getAllCoadminAndAMQuerySchema = z.object({
|
||||||
|
search: searchQuerySchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GetAllCoadminAndAMQuery = z.infer<typeof getAllCoadminAndAMQuerySchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// GET ALL INVITED COADMIN AND AM (with search)
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query params for getting invited co-admins and account managers
|
||||||
|
*/
|
||||||
|
export const getAllInvitedCoadminAndAMQuerySchema = z.object({
|
||||||
|
search: searchQuerySchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GetAllInvitedCoadminAndAMQuery = z.infer<typeof getAllInvitedCoadminAndAMQuerySchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// GET INVITATION DETAILS (with search)
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query params for getting invitation details
|
||||||
|
*/
|
||||||
|
export const getInvitationDetailsQuerySchema = z.object({
|
||||||
|
search: searchQuerySchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GetInvitationDetailsQuery = z.infer<typeof getInvitationDetailsQuerySchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// UPDATE TEAMMATE STATUS
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update teammate status schema
|
||||||
|
*/
|
||||||
|
export const updateTeammateStatusSchema = z.object({
|
||||||
|
userId: idSchema.describe('User ID'),
|
||||||
|
status: z.enum(['active', 'inactive', 'suspended']),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UpdateTeammateStatusInput = z.infer<typeof updateTeammateStatusSchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// ASSIGN REVENUE
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign revenue to teammate schema
|
||||||
|
*/
|
||||||
|
export const assignRevenueSchema = z.object({
|
||||||
|
userId: idSchema.describe('User ID'),
|
||||||
|
isFixedSalary: z.boolean(),
|
||||||
|
perValue: z
|
||||||
|
.number()
|
||||||
|
.positive('Per value must be greater than 0'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type AssignRevenueInput = z.infer<typeof assignRevenueSchema>;
|
||||||
6
src/common/utils/validation/prepopulate/index.ts
Normal file
6
src/common/utils/validation/prepopulate/index.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* Prepopulate Module Validation Schemas Index
|
||||||
|
* Export all prepopulate-related validation schemas
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './prepopulate.validation';
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* Prepopulate Module Validation Schemas
|
||||||
|
* Production-ready Zod validations for prepopulate endpoints
|
||||||
|
*/
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// GET BANK BRANCHES BY BANK ID
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get bank branches by bank ID query params
|
||||||
|
*/
|
||||||
|
export const getBankBranchesByBankIdQuerySchema = z.object({
|
||||||
|
bankXid: z.coerce
|
||||||
|
.number()
|
||||||
|
.int('Bank ID must be an integer')
|
||||||
|
.positive('Bank ID must be positive'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GetBankBranchesByBankIdQuery = z.infer<typeof getBankBranchesByBankIdQuerySchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// GET CITY BY STATE ID
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get city by state ID query params
|
||||||
|
*/
|
||||||
|
export const getCityByStateIdQuerySchema = z.object({
|
||||||
|
stateXid: z.coerce
|
||||||
|
.number()
|
||||||
|
.int('State ID must be an integer')
|
||||||
|
.positive('State ID must be positive'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GetCityByStateIdQuery = z.infer<typeof getCityByStateIdQuerySchema>;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// GET AM DETAIL BY ID (path param)
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get AM detail by ID path params
|
||||||
|
*/
|
||||||
|
export const getAmDetailByIdPathSchema = z.object({
|
||||||
|
amXid: z.coerce
|
||||||
|
.number()
|
||||||
|
.int('Account Manager ID must be an integer')
|
||||||
|
.positive('Account Manager ID must be positive'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GetAmDetailByIdPath = z.infer<typeof getAmDetailByIdPathSchema>;
|
||||||
358
src/common/utils/validation/validation.utils.ts
Normal file
358
src/common/utils/validation/validation.utils.ts
Normal file
@@ -0,0 +1,358 @@
|
|||||||
|
/**
|
||||||
|
* Production-Ready Validation Utilities
|
||||||
|
* Centralized validation helpers for Zod schemas
|
||||||
|
* Compatible with Zod v4
|
||||||
|
*/
|
||||||
|
import { z, ZodError, ZodSchema } from 'zod';
|
||||||
|
import ApiError from '../helper/ApiError';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats Zod validation errors into user-friendly messages
|
||||||
|
*/
|
||||||
|
export function formatZodErrors(error: ZodError): string {
|
||||||
|
return error.issues
|
||||||
|
.map((issue) => {
|
||||||
|
const path = issue.path.length > 0 ? `${issue.path.join('.')}: ` : '';
|
||||||
|
return `${path}${issue.message}`;
|
||||||
|
})
|
||||||
|
.join('; ');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates data against a Zod schema and throws ApiError on failure
|
||||||
|
* @param schema - Zod schema to validate against
|
||||||
|
* @param data - Data to validate
|
||||||
|
* @param errorCode - HTTP status code for validation errors (default: 400)
|
||||||
|
* @returns Validated and typed data
|
||||||
|
*/
|
||||||
|
export function validateSchema<T>(
|
||||||
|
schema: ZodSchema<T>,
|
||||||
|
data: unknown,
|
||||||
|
errorCode: number = 400
|
||||||
|
): T {
|
||||||
|
const result = schema.safeParse(data);
|
||||||
|
|
||||||
|
if (!result.success) {
|
||||||
|
const errorMessage = formatZodErrors(result.error);
|
||||||
|
throw new ApiError(errorCode, `Validation failed: ${errorMessage}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safe validation that returns result object instead of throwing
|
||||||
|
*/
|
||||||
|
export function safeValidate<T>(
|
||||||
|
schema: ZodSchema<T>,
|
||||||
|
data: unknown
|
||||||
|
): { success: true; data: T } | { success: false; errors: string } {
|
||||||
|
const result = schema.safeParse(data);
|
||||||
|
|
||||||
|
if (!result.success) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
errors: formatZodErrors(result.error),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: result.data,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses JSON body from API Gateway event safely
|
||||||
|
*/
|
||||||
|
export function parseBody<T>(
|
||||||
|
body: string | null,
|
||||||
|
schema: ZodSchema<T>
|
||||||
|
): T {
|
||||||
|
if (!body) {
|
||||||
|
throw new ApiError(400, 'Request body is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
let parsedBody: unknown;
|
||||||
|
try {
|
||||||
|
parsedBody = JSON.parse(body);
|
||||||
|
} catch {
|
||||||
|
throw new ApiError(400, 'Invalid JSON in request body');
|
||||||
|
}
|
||||||
|
|
||||||
|
return validateSchema(schema, parsedBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses query string parameters with validation
|
||||||
|
*/
|
||||||
|
export function parseQueryParams<T>(
|
||||||
|
params: Record<string, string | undefined> | null,
|
||||||
|
schema: ZodSchema<T>
|
||||||
|
): T {
|
||||||
|
return validateSchema(schema, params || {});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// COMMON REUSABLE FIELD SCHEMAS (Zod v4 compatible)
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Email validation with proper format
|
||||||
|
*/
|
||||||
|
export const emailSchema = z
|
||||||
|
.string()
|
||||||
|
.min(1, 'Email is required')
|
||||||
|
.email('Invalid email format')
|
||||||
|
.max(150, 'Email cannot exceed 150 characters')
|
||||||
|
.transform((val) => val.toLowerCase().trim());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password validation with security requirements
|
||||||
|
*/
|
||||||
|
export const passwordSchema = z
|
||||||
|
.string()
|
||||||
|
.min(8, 'Password must be at least 8 characters')
|
||||||
|
.max(255, 'Password cannot exceed 255 characters')
|
||||||
|
.regex(
|
||||||
|
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/,
|
||||||
|
'Password must contain at least one uppercase letter, one lowercase letter, one number and one special character'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple password (for cases where strong password isn't required)
|
||||||
|
*/
|
||||||
|
export const simplePasswordSchema = z
|
||||||
|
.string()
|
||||||
|
.min(8, 'Password must be at least 8 characters')
|
||||||
|
.max(255, 'Password cannot exceed 255 characters');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mobile number validation (international format)
|
||||||
|
*/
|
||||||
|
export const mobileNumberSchema = z
|
||||||
|
.string()
|
||||||
|
.min(7, 'Mobile number must be at least 7 digits')
|
||||||
|
.max(15, 'Mobile number cannot exceed 15 digits')
|
||||||
|
.regex(/^[0-9]+$/, 'Mobile number must contain only digits')
|
||||||
|
.optional();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ISD Code validation
|
||||||
|
*/
|
||||||
|
export const isdCodeSchema = z
|
||||||
|
.string()
|
||||||
|
.max(6, 'ISD code cannot exceed 6 characters')
|
||||||
|
.regex(/^\+?[0-9]+$/, 'Invalid ISD code format')
|
||||||
|
.optional();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name validation (first name, last name, etc.)
|
||||||
|
*/
|
||||||
|
export const nameSchema = z
|
||||||
|
.string()
|
||||||
|
.min(1, 'Name is required')
|
||||||
|
.max(50, 'Name cannot exceed 50 characters')
|
||||||
|
.regex(/^[a-zA-Z\s'-]+$/, 'Name can only contain letters, spaces, hyphens and apostrophes');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional name schema
|
||||||
|
*/
|
||||||
|
export const optionalNameSchema = nameSchema.optional();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Positive integer ID validation
|
||||||
|
*/
|
||||||
|
export const idSchema = z
|
||||||
|
.number()
|
||||||
|
.int('ID must be an integer')
|
||||||
|
.positive('ID must be a positive number');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional positive integer ID
|
||||||
|
*/
|
||||||
|
export const optionalIdSchema = z
|
||||||
|
.number()
|
||||||
|
.int('ID must be an integer')
|
||||||
|
.positive('ID must be a positive number')
|
||||||
|
.optional();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Coerce string to number for query params
|
||||||
|
*/
|
||||||
|
export const numericStringSchema = z
|
||||||
|
.string()
|
||||||
|
.transform((val) => parseInt(val, 10))
|
||||||
|
.pipe(z.number().int().positive());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional numeric string
|
||||||
|
*/
|
||||||
|
export const optionalNumericStringSchema = z
|
||||||
|
.string()
|
||||||
|
.optional()
|
||||||
|
.transform((val) => (val ? parseInt(val, 10) : undefined))
|
||||||
|
.pipe(z.number().int().positive().optional());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address line validation
|
||||||
|
*/
|
||||||
|
export const addressLine1Schema = z
|
||||||
|
.string()
|
||||||
|
.min(1, 'Address is required')
|
||||||
|
.max(150, 'Address cannot exceed 150 characters');
|
||||||
|
|
||||||
|
export const addressLine2Schema = z
|
||||||
|
.string()
|
||||||
|
.max(150, 'Address cannot exceed 150 characters')
|
||||||
|
.optional();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pin/Zip code validation
|
||||||
|
*/
|
||||||
|
export const pinCodeSchema = z
|
||||||
|
.string()
|
||||||
|
.min(4, 'Pin code must be at least 4 characters')
|
||||||
|
.max(30, 'Pin code cannot exceed 30 characters');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL validation
|
||||||
|
*/
|
||||||
|
export const urlSchema = z
|
||||||
|
.string()
|
||||||
|
.url('Invalid URL format')
|
||||||
|
.max(500, 'URL cannot exceed 500 characters')
|
||||||
|
.optional()
|
||||||
|
.or(z.literal(''));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Social media URL (with empty string handling)
|
||||||
|
*/
|
||||||
|
export const socialUrlSchema = z
|
||||||
|
.string()
|
||||||
|
.max(80, 'URL cannot exceed 80 characters')
|
||||||
|
.refine(
|
||||||
|
(val) => !val || val === '' || z.string().url().safeParse(val).success,
|
||||||
|
'Invalid URL format'
|
||||||
|
)
|
||||||
|
.optional();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date string validation
|
||||||
|
*/
|
||||||
|
export const dateStringSchema = z
|
||||||
|
.string()
|
||||||
|
.refine((val) => !isNaN(Date.parse(val)), 'Invalid date format')
|
||||||
|
.transform((val) => new Date(val));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional date string
|
||||||
|
*/
|
||||||
|
export const optionalDateStringSchema = z
|
||||||
|
.string()
|
||||||
|
.refine((val) => !val || !isNaN(Date.parse(val)), 'Invalid date format')
|
||||||
|
.optional();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Boolean schema with string coercion (for query params)
|
||||||
|
*/
|
||||||
|
export const booleanStringSchema = z
|
||||||
|
.string()
|
||||||
|
.transform((val) => val === 'true' || val === '1')
|
||||||
|
.pipe(z.boolean());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OTP validation (6 digits)
|
||||||
|
*/
|
||||||
|
export const otpSchema = z
|
||||||
|
.string()
|
||||||
|
.length(6, 'OTP must be exactly 6 digits')
|
||||||
|
.regex(/^[0-9]+$/, 'OTP must contain only digits');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search query validation
|
||||||
|
*/
|
||||||
|
export const searchQuerySchema = z
|
||||||
|
.string()
|
||||||
|
.max(100, 'Search query cannot exceed 100 characters')
|
||||||
|
.transform((val) => val.trim())
|
||||||
|
.optional();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pagination parameters
|
||||||
|
*/
|
||||||
|
export const paginationSchema = z.object({
|
||||||
|
page: z.coerce.number().int().positive().default(1),
|
||||||
|
limit: z.coerce.number().int().positive().max(100).default(10),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File path validation for S3
|
||||||
|
*/
|
||||||
|
export const filePathSchema = z
|
||||||
|
.string()
|
||||||
|
.max(500, 'File path cannot exceed 500 characters')
|
||||||
|
.optional();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registration/Reference number validation
|
||||||
|
*/
|
||||||
|
export const registrationNumberSchema = z
|
||||||
|
.string()
|
||||||
|
.max(30, 'Registration number cannot exceed 30 characters')
|
||||||
|
.optional();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PAN number validation (India)
|
||||||
|
*/
|
||||||
|
export const panNumberSchema = z
|
||||||
|
.string()
|
||||||
|
.max(30, 'PAN number cannot exceed 30 characters')
|
||||||
|
.regex(/^[A-Z]{5}[0-9]{4}[A-Z]{1}$/, 'Invalid PAN number format')
|
||||||
|
.optional()
|
||||||
|
.or(z.literal(''));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST number validation (India)
|
||||||
|
*/
|
||||||
|
export const gstNumberSchema = z
|
||||||
|
.string()
|
||||||
|
.max(30, 'GST number cannot exceed 30 characters')
|
||||||
|
.regex(
|
||||||
|
/^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/,
|
||||||
|
'Invalid GST number format'
|
||||||
|
)
|
||||||
|
.optional()
|
||||||
|
.or(z.literal(''));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IFSC code validation (India)
|
||||||
|
*/
|
||||||
|
export const ifscCodeSchema = z
|
||||||
|
.string()
|
||||||
|
.min(1, 'IFSC code is required')
|
||||||
|
.regex(/^[A-Z]{4}0[A-Z0-9]{6}$/, 'Invalid IFSC code format');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bank account number validation
|
||||||
|
*/
|
||||||
|
export const accountNumberSchema = z
|
||||||
|
.string()
|
||||||
|
.min(9, 'Account number must be at least 9 digits')
|
||||||
|
.max(18, 'Account number cannot exceed 18 digits')
|
||||||
|
.regex(/^[0-9]+$/, 'Account number must contain only digits');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Company name validation
|
||||||
|
*/
|
||||||
|
export const companyNameSchema = z
|
||||||
|
.string()
|
||||||
|
.min(1, 'Company name is required')
|
||||||
|
.max(100, 'Company name cannot exceed 100 characters');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token validation
|
||||||
|
*/
|
||||||
|
export const tokenSchema = z
|
||||||
|
.string()
|
||||||
|
.min(1, 'Authentication token is required');
|
||||||
@@ -90,6 +90,5 @@ export class AddPaymentDetailsDTO {
|
|||||||
this.accountHolderName = accountHolderName;
|
this.accountHolderName = accountHolderName;
|
||||||
this.ifscCode = ifscCode;
|
this.ifscCode = ifscCode;
|
||||||
this.hostXid = hostXid;
|
this.hostXid = hostXid;
|
||||||
this.currencyXid = currencyXid;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
|
|
||||||
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 { HostService } from '../../../services/host.service';
|
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
|
||||||
const hostService = new HostService(prismaService);
|
|
||||||
|
|
||||||
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 verifyHostToken(token);
|
|
||||||
|
|
||||||
let body: any = {};
|
|
||||||
try {
|
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (err) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { activityTypeXid, frequenciesXid } = body;
|
|
||||||
|
|
||||||
if (!activityTypeXid || !frequenciesXid) {
|
|
||||||
throw new ApiError(400, 'activityType and frequency ID is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get all host applications from service based on user role
|
|
||||||
const createdData = await hostService.createActivityAndAllQuestionsEntry(userInfo.id, activityTypeXid, frequenciesXid);
|
|
||||||
|
|
||||||
return {
|
|
||||||
statusCode: 200,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Access-Control-Allow-Origin': '*',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
success: true,
|
|
||||||
message: 'Activity created successfully',
|
|
||||||
data: createdData
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
);
|
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
|
import { verifyHostToken } from '@/common/middlewares/jwt/authForHost';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { HostService } from '../../../services/host.service';
|
import { HostService } from '../../../services/host.service';
|
||||||
import { PrePopulateService } from '../../../../prepopulate/services/prepopulate.service';
|
import { PrePopulateService } from '../../../../prepopulate/services/prepopulate.service';
|
||||||
|
import { parseQueryParams } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { optionalSearchQuerySchema } from '../../../../../common/utils/validation/host/activity.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const hostService = new HostService(prismaService);
|
const hostService = new HostService(prismaService);
|
||||||
const prePopulateService = new PrePopulateService(prismaService);
|
const prePopulateService = new PrePopulateService(prismaService);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add suggestion handler for host applications
|
* Get all activity types with interest handler
|
||||||
* Allows Minglar Admin, Co_Admin, and Account Manager to add suggestions
|
|
||||||
* Types: Setup Profile, Review Account, Add Payment Details, Agreement
|
|
||||||
*/
|
*/
|
||||||
export const handler = safeHandler(async (
|
export const handler = safeHandler(async (
|
||||||
event: APIGatewayProxyEvent,
|
event: APIGatewayProxyEvent,
|
||||||
@@ -28,11 +28,11 @@ export const handler = safeHandler(async (
|
|||||||
// Verify token and get user info
|
// Verify token and get user info
|
||||||
const userInfo = await verifyHostToken(token);
|
const userInfo = await verifyHostToken(token);
|
||||||
|
|
||||||
|
// Parse and validate query params using Zod
|
||||||
|
const { search, q } = parseQueryParams(event.queryStringParameters, optionalSearchQuerySchema);
|
||||||
|
const searchTerm = search || q || undefined;
|
||||||
|
|
||||||
// Read optional search query (supports ?search= or ?q=)
|
const data = await hostService.getAllActivityTypesWithInterest(searchTerm);
|
||||||
const search = event.queryStringParameters?.search || event.queryStringParameters?.q || undefined;
|
|
||||||
|
|
||||||
const data = await hostService.getAllActivityTypesWithInterest(search);
|
|
||||||
const frequencies = await prePopulateService.getAllFrequencies();
|
const frequencies = await prePopulateService.getAllFrequencies();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
|
import { verifyHostToken } from '@/common/middlewares/jwt/authForHost';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { HostService } from '../../../services/host.service';
|
import { HostService } from '../../../services/host.service';
|
||||||
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
|
import { parseQueryParams } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { optionalSearchQuerySchema } from '../../../../../common/utils/validation/host/activity.validation';
|
||||||
|
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
@@ -12,9 +13,7 @@ const hostService = new HostService(prismaService);
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add suggestion handler for host applications
|
* Get all host activities handler
|
||||||
* Allows Minglar Admin, Co_Admin, and Account Manager to add suggestions
|
|
||||||
* Types: Setup Profile, Review Account, Add Payment Details, Agreement
|
|
||||||
*/
|
*/
|
||||||
export const handler = safeHandler(async (
|
export const handler = safeHandler(async (
|
||||||
event: APIGatewayProxyEvent,
|
event: APIGatewayProxyEvent,
|
||||||
@@ -29,18 +28,11 @@ export const handler = safeHandler(async (
|
|||||||
// Verify token and get user info
|
// Verify token and get user info
|
||||||
const userInfo = await verifyHostToken(token);
|
const userInfo = await verifyHostToken(token);
|
||||||
|
|
||||||
// Get pagination params from event
|
// Parse and validate query params using Zod
|
||||||
const paginationParams = paginationService.getPaginationFromEvent(event);
|
const { search, q } = parseQueryParams(event.queryStringParameters, optionalSearchQuerySchema);
|
||||||
const paginationOptions = paginationService.parsePaginationParams(paginationParams);
|
const searchTerm = search || q || undefined;
|
||||||
|
|
||||||
// Read optional search query (supports ?search= or ?q=)
|
const data = await hostService.getAllHostActivity(searchTerm, Number(userInfo.id));
|
||||||
const search = event.queryStringParameters?.search || event.queryStringParameters?.q || undefined;
|
|
||||||
|
|
||||||
const result = await hostService.getAllHostActivity(
|
|
||||||
search ? String(search) : undefined,
|
|
||||||
Number(userInfo.id),
|
|
||||||
paginationOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -52,7 +44,8 @@ export const handler = safeHandler(async (
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
success: true,
|
success: true,
|
||||||
message: 'Data retrieved successfully',
|
message: 'Data retrieved successfully',
|
||||||
...result,
|
data,
|
||||||
|
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
import { verifyOnlyMinglarAdminToken } from '@/common/middlewares/jwt/authForOnlyMinglarAdmin';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
|
import { PrePopulateService } from '../../../../prepopulate/services/prepopulate.service';
|
||||||
import { HostService } from '../../../services/host.service';
|
import { HostService } from '../../../services/host.service';
|
||||||
import { verifyMinglarAdminHostToken } from '../../../../../common/middlewares/jwt/authForMinglarAdminHost';
|
import { verifyMinglarAdminHostToken } from '@/common/middlewares/jwt/authForMinglarAdmin&Host';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const hostService = new HostService(prismaService);
|
const hostService = new HostService(prismaService);
|
||||||
@@ -21,15 +23,7 @@ export const handler = safeHandler(async (
|
|||||||
// Authenticate user using the shared authForHost function
|
// Authenticate user using the shared authForHost function
|
||||||
await verifyMinglarAdminHostToken(token);
|
await verifyMinglarAdminHostToken(token);
|
||||||
|
|
||||||
const activity_xid = event.queryStringParameters?.activity_xid
|
const result = await hostService.getAllPQQQuesAndSubmittedAns();
|
||||||
? Number(event.queryStringParameters.activity_xid)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
if (!activity_xid) {
|
|
||||||
throw new ApiError(409, "Activity ID is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await hostService.getAllPQQQuesAndSubmittedAns(Number(activity_xid));
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import config from '../../../../../config/config';
|
import config from '@/config/config';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
|
||||||
import AWS from 'aws-sdk';
|
import AWS from 'aws-sdk';
|
||||||
import Busboy from 'busboy';
|
import Busboy from 'busboy';
|
||||||
@@ -8,36 +8,48 @@ import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHo
|
|||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { HostService } from '../../../services/host.service';
|
import { HostService } from '../../../services/host.service';
|
||||||
|
import { LAST_QUESTION_ID } from '@/common/utils/constants/host.constant';
|
||||||
|
|
||||||
const prisma = new PrismaService();
|
const prisma = new PrismaService();
|
||||||
const hostService = new HostService(prisma);
|
const pqqService = new HostService(prisma);
|
||||||
|
|
||||||
const s3 = new AWS.S3({ region: config.aws.region });
|
const s3 = new AWS.S3({ region: config.aws.region });
|
||||||
|
|
||||||
// Extract S3 key from URL
|
// Function to extract S3 key from URL
|
||||||
function getS3KeyFromUrl(url: string): string {
|
function getS3KeyFromUrl(url: string): string {
|
||||||
const bucketBaseUrl = `https://${config.aws.bucketName}.s3.${config.aws.region}.amazonaws.com/`;
|
const bucketBaseUrl = `https://${config.aws.bucketName}.s3.${config.aws.region}.amazonaws.com/`;
|
||||||
return url.replace(bucketBaseUrl, '');
|
return url.replace(bucketBaseUrl, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete file from S3
|
// Function to delete file from S3
|
||||||
async function deleteFromS3(s3Key: string): Promise<void> {
|
async function deleteFromS3(s3Key: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await s3.deleteObject({
|
await s3.deleteObject({
|
||||||
Bucket: config.aws.bucketName,
|
Bucket: config.aws.bucketName,
|
||||||
Key: s3Key,
|
Key: s3Key,
|
||||||
}).promise();
|
}).promise();
|
||||||
console.log(`✅ Deleted from S3: ${s3Key}`);
|
console.log(`✅ File deleted from S3: ${s3Key}`);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
console.error(`❌ Failed to delete from S3: ${s3Key}`, err);
|
console.error(`❌ Error deleting file from S3: ${s3Key}`, error);
|
||||||
|
// Don't throw error here, continue with upload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upload new file
|
async function uploadToS3(buffer: Buffer, mimeType: string, originalName: string, prefix: string, existingUrl?: string): Promise<string> {
|
||||||
async function uploadToS3(buffer: Buffer, mimeType: string, originalName: string, prefix: string): Promise<string> {
|
let s3Key: string;
|
||||||
const uniqueKey = `${crypto.randomUUID()}_${originalName}`;
|
|
||||||
const s3Key = `${prefix}/${uniqueKey}`;
|
|
||||||
|
|
||||||
|
// If existing URL provided, use the same S3 key to replace the file
|
||||||
|
if (existingUrl) {
|
||||||
|
s3Key = getS3KeyFromUrl(existingUrl);
|
||||||
|
// Delete existing file first
|
||||||
|
await deleteFromS3(s3Key);
|
||||||
|
} else {
|
||||||
|
// Generate new unique key for new file
|
||||||
|
const uniqueKey = `${crypto.randomUUID()}_${originalName}`;
|
||||||
|
s3Key = `${prefix}/${uniqueKey}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload new file (replaces existing if same key)
|
||||||
await s3.upload({
|
await s3.upload({
|
||||||
Bucket: config.aws.bucketName,
|
Bucket: config.aws.bucketName,
|
||||||
Key: s3Key,
|
Key: s3Key,
|
||||||
@@ -46,160 +58,253 @@ async function uploadToS3(buffer: Buffer, mimeType: string, originalName: string
|
|||||||
ACL: 'private'
|
ACL: 'private'
|
||||||
}).promise();
|
}).promise();
|
||||||
|
|
||||||
console.log(`✅ Uploaded to S3: ${s3Key}`);
|
console.log(`✅ File uploaded to S3: ${s3Key}`);
|
||||||
return `https://${config.aws.bucketName}.s3.${config.aws.region}.amazonaws.com/${s3Key}`;
|
return `https://${config.aws.bucketName}.s3.${config.aws.region}.amazonaws.com/${s3Key}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
|
export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
|
||||||
try {
|
try {
|
||||||
// AUTH
|
// 1) Auth
|
||||||
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
||||||
if (!token) throw new ApiError(401, 'Missing token');
|
if (!token) throw new ApiError(401, 'Missing token.');
|
||||||
|
|
||||||
const user = await verifyHostToken(token);
|
const user = await verifyHostToken(token);
|
||||||
|
|
||||||
// Content-Type
|
// 2) Content-Type check
|
||||||
const contentType = event.headers["content-type"] || event.headers["Content-Type"];
|
const contentType = event.headers["content-type"] || event.headers["Content-Type"];
|
||||||
if (!contentType?.startsWith("multipart/form-data"))
|
if (!contentType?.startsWith("multipart/form-data"))
|
||||||
throw new ApiError(400, "Content-Type must be multipart/form-data");
|
throw new ApiError(400, "Content-Type must be multipart/form-data");
|
||||||
|
|
||||||
if (!event.isBase64Encoded) throw new ApiError(400, "Body must be base64 encoded");
|
if (!event.isBase64Encoded)
|
||||||
|
throw new ApiError(400, "Body must be base64 encoded");
|
||||||
|
|
||||||
const bodyBuffer = Buffer.from(event.body!, "base64");
|
const bodyBuffer = Buffer.from(event.body!, "base64");
|
||||||
|
|
||||||
const fields: any = {};
|
const fields: any = {};
|
||||||
const files: Array<{ buffer: Buffer; mimeType: string; fileName: string; fieldName: string }> = [];
|
const files: Array<{ buffer: Buffer; mimeType: string; fileName: string; fieldName: string }> = [];
|
||||||
|
|
||||||
// Parse multipart
|
// 3) Parse multipart data
|
||||||
await new Promise<void>((resolve, reject) => {
|
await new Promise<void>((resolve, reject) => {
|
||||||
const bb = Busboy({ headers: { 'content-type': contentType } });
|
const bb = Busboy({ headers: { 'content-type': contentType } });
|
||||||
|
|
||||||
bb.on('file', (fieldname, file, info) => {
|
bb.on('file', (fieldname, file, info) => {
|
||||||
const { filename, mimeType } = info;
|
const { filename, mimeType } = info;
|
||||||
if (!filename) return file.resume();
|
|
||||||
|
// Skip if no filename (empty file field)
|
||||||
|
if (!filename) {
|
||||||
|
file.resume();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const chunks: Buffer[] = [];
|
const chunks: Buffer[] = [];
|
||||||
let size = 0;
|
let totalSize = 0;
|
||||||
|
const MAX_SIZE = 5 * 1024 * 1024; // 5 MB
|
||||||
file.on('data', chunk => {
|
|
||||||
size += chunk.length;
|
|
||||||
if (size > 5 * 1024 * 1024)
|
|
||||||
return reject(new ApiError(400, `File ${filename} exceeds 5MB limit`));
|
|
||||||
|
|
||||||
|
file.on('data', (chunk) => {
|
||||||
|
totalSize += chunk.length;
|
||||||
|
if (totalSize > MAX_SIZE) {
|
||||||
|
file.resume();
|
||||||
|
return reject(new ApiError(400, `File ${filename} exceeds 5MB limit.`));
|
||||||
|
}
|
||||||
chunks.push(chunk);
|
chunks.push(chunk);
|
||||||
});
|
});
|
||||||
|
|
||||||
file.on('end', () => {
|
file.on('end', () => {
|
||||||
|
// Only add file if we have data
|
||||||
if (chunks.length > 0) {
|
if (chunks.length > 0) {
|
||||||
files.push({
|
files.push({
|
||||||
buffer: Buffer.concat(chunks),
|
buffer: Buffer.concat(chunks),
|
||||||
mimeType,
|
mimeType,
|
||||||
fileName: filename,
|
fileName: filename,
|
||||||
fieldName: fieldname
|
fieldName: fieldname,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
file.on('error', (err) => {
|
||||||
|
reject(new ApiError(400, `File upload error: ${err.message}`));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
bb.on('field', (fieldname, val) => {
|
bb.on('field', (fieldname, val) => {
|
||||||
try { fields[fieldname] = JSON.parse(val); }
|
// Handle empty or null values
|
||||||
catch { fields[fieldname] = val; }
|
if (val === '' || val === 'null' || val === 'undefined') {
|
||||||
|
fields[fieldname] = null;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
fields[fieldname] = JSON.parse(val);
|
||||||
|
} catch {
|
||||||
|
fields[fieldname] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bb.on('close', () => {
|
||||||
|
console.log("✅ Busboy parsing completed");
|
||||||
|
console.log("📌 Fields:", fields);
|
||||||
|
console.log("📁 Files:", files.length);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
bb.on('error', (err) => {
|
||||||
|
console.error("❌ Busboy error:", err);
|
||||||
|
reject(new ApiError(400, `Multipart parsing error: ${err.message}`));
|
||||||
});
|
});
|
||||||
|
|
||||||
bb.on('close', resolve);
|
|
||||||
bb.on('error', err => reject(new ApiError(400, err.message)));
|
|
||||||
bb.end(bodyBuffer);
|
bb.end(bodyBuffer);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Required fields
|
// 4) Extract required fields - only activityXid, pqqQuestionXid, pqqAnswerXid are required
|
||||||
const activityXid = Number(fields.activityXid);
|
const activityXid = Number(fields.activityXid);
|
||||||
const pqqQuestionXid = Number(fields.pqqQuestionXid);
|
const pqqQuestionXid = Number(fields.pqqQuestionXid);
|
||||||
const pqqAnswerXid = Number(fields.pqqAnswerXid);
|
const pqqAnswerXid = Number(fields.pqqAnswerXid);
|
||||||
|
|
||||||
|
// Comments and files are optional
|
||||||
const comments = fields.comments || null;
|
const comments = fields.comments || null;
|
||||||
|
|
||||||
if (!activityXid || !pqqQuestionXid || !pqqAnswerXid)
|
// Validate required fields
|
||||||
throw new ApiError(400, "Missing required fields");
|
if (!activityXid || isNaN(activityXid)) throw new ApiError(400, "Valid activityXid is required");
|
||||||
|
if (!pqqQuestionXid || isNaN(pqqQuestionXid)) throw new ApiError(400, "Valid pqqQuestionXid is required");
|
||||||
|
if (pqqQuestionXid !== LAST_QUESTION_ID.Q_ID) throw new ApiError(400, "Wrong question id.")
|
||||||
|
if (!pqqAnswerXid || isNaN(pqqAnswerXid)) throw new ApiError(400, "Valid pqqAnswerXid is required");
|
||||||
|
|
||||||
|
// console.log(`📝 Processing - Activity: ${activityXid}, Question: ${pqqQuestionXid}, Answer: ${pqqAnswerXid}`);
|
||||||
|
// console.log(`💬 Comments: ${comments ? 'Provided' : 'Not provided'}`);
|
||||||
|
// console.log(`📎 Files: ${files.length}`);
|
||||||
|
|
||||||
|
// 5) UPSERT: Check if header already exists for this combination
|
||||||
|
const existingHeader = await pqqService.findHeaderByCompositeKey(
|
||||||
|
activityXid,
|
||||||
|
pqqQuestionXid,
|
||||||
|
pqqAnswerXid
|
||||||
|
);
|
||||||
|
|
||||||
// UPSERT header
|
|
||||||
const existingHeader = await hostService.findHeaderByCompositeKey(activityXid, pqqQuestionXid);
|
|
||||||
let header;
|
let header;
|
||||||
|
|
||||||
if (existingHeader) {
|
if (existingHeader) {
|
||||||
header = await hostService.updateHeader(existingHeader.id, pqqAnswerXid, comments);
|
console.log("🔄 Updating existing PQQ header");
|
||||||
|
// Update existing header (comments can be null)
|
||||||
|
header = await pqqService.updateHeader(
|
||||||
|
existingHeader.id,
|
||||||
|
comments
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
header = await hostService.createHeader(activityXid, pqqQuestionXid, pqqAnswerXid, comments);
|
console.log("🆕 Creating new PQQ header");
|
||||||
|
// Create new header (comments can be null)
|
||||||
|
header = await pqqService.createHeader(
|
||||||
|
activityXid,
|
||||||
|
pqqQuestionXid,
|
||||||
|
pqqAnswerXid,
|
||||||
|
comments
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
// Calculate score after answer submission
|
||||||
|
const score = await pqqService.calculatePqqScoreForUser(activityXid);
|
||||||
|
|
||||||
// SCORE
|
|
||||||
const score = await hostService.calculatePqqScoreForUser(activityXid);
|
|
||||||
|
|
||||||
// Existing supporting files
|
// 6) Get existing supporting files for this header
|
||||||
const existingSupportingFiles = await hostService.getSupportingFilesByHeaderId(header.id);
|
const existingSupportingFiles = await pqqService.getSupportingFilesByHeaderId(header.id);
|
||||||
|
console.log(`📁 Found ${existingSupportingFiles.length} existing supporting files`);
|
||||||
|
|
||||||
// Read deletedFiles from frontend
|
// 7) Handle file UPSERT - only if files are provided
|
||||||
const deletedFiles = Array.isArray(fields.deletedFiles) ? fields.deletedFiles : [];
|
const uploadedFiles: any[] = [];
|
||||||
|
|
||||||
const deleteResults = [];
|
|
||||||
const addResults = [];
|
|
||||||
|
|
||||||
// DELETE explicitly requested files (Case 3)
|
|
||||||
if (deletedFiles.length > 0) {
|
|
||||||
for (const del of deletedFiles) {
|
|
||||||
const id = Number(del.id);
|
|
||||||
const record = existingSupportingFiles.find(f => f.id === id);
|
|
||||||
if (!record) continue;
|
|
||||||
|
|
||||||
// Delete from S3
|
|
||||||
if (record.mediaFileName) {
|
|
||||||
const key = getS3KeyFromUrl(record.mediaFileName);
|
|
||||||
await deleteFromS3(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete from DB
|
|
||||||
await hostService.deleteSupportingFile(record.id);
|
|
||||||
deleteResults.push({ id: record.id, deleted: true });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ADD new uploaded files (Case 1 + Case 3 new files)
|
|
||||||
if (files.length > 0) {
|
if (files.length > 0) {
|
||||||
for (const file of files) {
|
console.log("📤 Processing file uploads...");
|
||||||
|
|
||||||
|
for (let i = 0; i < files.length; i++) {
|
||||||
|
const file = files[i];
|
||||||
|
const existingFile = existingSupportingFiles[i] || null;
|
||||||
|
|
||||||
const url = await uploadToS3(
|
const url = await uploadToS3(
|
||||||
file.buffer,
|
file.buffer,
|
||||||
file.mimeType,
|
file.mimeType,
|
||||||
file.fileName,
|
file.fileName,
|
||||||
`ActivityOnboarding/supportings/${activityXid}`
|
`ActivityOnboarding/supportings/${activityXid}`,
|
||||||
|
existingFile ? existingFile.mediaFileName : undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
const newRec = await hostService.addSupportingFile(header.id, file.mimeType, url);
|
let supporting;
|
||||||
addResults.push(newRec);
|
if (existingFile) {
|
||||||
|
// Update existing supporting file record
|
||||||
|
supporting = await pqqService.updateSupportingFile(
|
||||||
|
existingFile.id,
|
||||||
|
file.mimeType,
|
||||||
|
url
|
||||||
|
);
|
||||||
|
console.log(`🔄 Updated supporting file: ${existingFile.id}`);
|
||||||
|
} else {
|
||||||
|
// Create new supporting file record
|
||||||
|
supporting = await pqqService.addSupportingFile(
|
||||||
|
header.id,
|
||||||
|
file.mimeType,
|
||||||
|
url
|
||||||
|
);
|
||||||
|
console.log(`🆕 Created new supporting file: ${supporting.id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadedFiles.push(supporting);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8) Delete any remaining existing files that weren't replaced
|
||||||
|
if (existingSupportingFiles.length > files.length) {
|
||||||
|
const filesToDelete = existingSupportingFiles.slice(files.length);
|
||||||
|
console.log(`🗑️ Deleting ${filesToDelete.length} unused supporting files`);
|
||||||
|
|
||||||
|
for (const fileToDelete of filesToDelete) {
|
||||||
|
await pqqService.deleteSupportingFile(fileToDelete.id);
|
||||||
|
// Also delete from S3
|
||||||
|
const s3Key = getS3KeyFromUrl(fileToDelete.mediaFileName);
|
||||||
|
await deleteFromS3(s3Key);
|
||||||
|
console.log(`🗑️ Deleted supporting file: ${fileToDelete.id}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("📭 No files provided in request");
|
||||||
|
|
||||||
|
// If no files provided but existing files exist, delete them (cleanup)
|
||||||
|
if (existingSupportingFiles.length > 0) {
|
||||||
|
console.log(`🗑️ No new files provided, deleting ${existingSupportingFiles.length} existing files`);
|
||||||
|
for (const fileToDelete of existingSupportingFiles) {
|
||||||
|
await pqqService.deleteSupportingFile(fileToDelete.id);
|
||||||
|
const s3Key = getS3KeyFromUrl(fileToDelete.mediaFileName);
|
||||||
|
await deleteFromS3(s3Key);
|
||||||
|
console.log(`🗑️ Deleted supporting file: ${fileToDelete.id}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getAllUpdatedQuestionResponse = await hostService.getAllPQUpdatedResponse(activityXid)
|
// 9) Prepare response
|
||||||
|
const responseMessage = existingHeader ? "PQQ answer updated successfully" : "PQQ answer submitted successfully";
|
||||||
// CASE 2 — NO deletion & NO new files => DO NOTHING to existing files
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" },
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Access-Control-Allow-Origin": "*"
|
||||||
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
success: true,
|
success: true,
|
||||||
message: existingHeader ? "PQQ answer updated successfully" : "PQQ answer submitted successfully",
|
message: responseMessage,
|
||||||
data: {
|
data: {
|
||||||
headerId: header.id,
|
headerId: header.id,
|
||||||
activityXid,
|
activityXid,
|
||||||
pqqQuestionXid,
|
pqqQuestionXid,
|
||||||
pqqAnswerXid,
|
pqqAnswerXid,
|
||||||
comments,
|
comments: comments,
|
||||||
score,
|
score,
|
||||||
getAllUpdatedQuestionResponse
|
files: {
|
||||||
|
uploaded: uploadedFiles,
|
||||||
|
total: uploadedFiles.length
|
||||||
|
},
|
||||||
|
operation: existingHeader ? 'updated' : 'created',
|
||||||
|
fileOperation: files.length > 0 ?
|
||||||
|
(existingSupportingFiles.length > 0 ? 'replaced' : 'added') :
|
||||||
|
(existingSupportingFiles.length > 0 ? 'removed' : 'unchanged')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
} catch (err: any) {
|
} catch (error: any) {
|
||||||
console.error("❌ Error:", err);
|
console.error("❌ Error in submitPqqAnswer:", error);
|
||||||
throw err;
|
throw error;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
import { verifyMinglarAdminHostToken } from '../../../../../common/middlewares/jwt/authForMinglarAdminHost';
|
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { HostService } from '../../../services/host.service';
|
import { HostService } from '../../../services/host.service';
|
||||||
|
import { verifyMinglarAdminHostToken } from '@/common/middlewares/jwt/authForMinglarAdmin&Host';
|
||||||
|
import { parseQueryParams } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { getPqqByQuestionIdQuerySchema } from '../../../../../common/utils/validation/host/activity.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const hostService = new HostService(prismaService);
|
const hostService = new HostService(prismaService);
|
||||||
@@ -21,12 +23,11 @@ export const handler = safeHandler(async (
|
|||||||
const userInfo = await verifyMinglarAdminHostToken(token);
|
const userInfo = await verifyMinglarAdminHostToken(token);
|
||||||
const userId = Number(userInfo.id);
|
const userId = Number(userInfo.id);
|
||||||
|
|
||||||
const question_xid = Number(event.queryStringParameters?.question_xid);
|
// Parse and validate query params using Zod
|
||||||
const activity_xid = Number(event.queryStringParameters?.activity_xid);
|
const { question_xid, activity_xid } = parseQueryParams(
|
||||||
|
event.queryStringParameters,
|
||||||
if (!question_xid || !activity_xid) {
|
getPqqByQuestionIdQuerySchema
|
||||||
throw new ApiError(400, "Question and activity xid are required.")
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch user with their HostHeader stepper info
|
// Fetch user with their HostHeader stepper info
|
||||||
const pqqQuestionDetails = await hostService.getPQQQuestionDetail(question_xid, activity_xid);
|
const pqqQuestionDetails = await hostService.getPQQQuestionDetail(question_xid, activity_xid);
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda
|
|||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
|
import { verifyHostToken } from '@/common/middlewares/jwt/authForHost';
|
||||||
import { HostService } from '../../../services/host.service';
|
import { HostService } from '../../../services/host.service';
|
||||||
|
import { parseQueryParams } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { getLatestPqqQuestionQuerySchema } from '../../../../../common/utils/validation/host/activity.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const hostService = new HostService(prismaService);
|
const hostService = new HostService(prismaService);
|
||||||
@@ -21,26 +23,20 @@ export const handler = safeHandler(async (
|
|||||||
const userInfo = await verifyHostToken(token);
|
const userInfo = await verifyHostToken(token);
|
||||||
const userId = Number(userInfo.id);
|
const userId = Number(userInfo.id);
|
||||||
|
|
||||||
const activity_xid = event.queryStringParameters?.activity_xid
|
// Parse and validate query params using Zod
|
||||||
? Number(event.queryStringParameters.activity_xid)
|
const { activity_xid } = parseQueryParams(
|
||||||
: null;
|
event.queryStringParameters,
|
||||||
|
getLatestPqqQuestionQuerySchema
|
||||||
// Validate it
|
);
|
||||||
if (!activity_xid || isNaN(activity_xid)) {
|
|
||||||
throw new ApiError(400, "Activity id is required and must be a number.");
|
|
||||||
}
|
|
||||||
let result = null;
|
|
||||||
|
|
||||||
// Fetch user with their HostHeader stepper info
|
// Fetch user with their HostHeader stepper info
|
||||||
const pqqQuestionDetails = await hostService.getLatestQuestionDetailsPQQ(activity_xid);
|
const pqqQuestionDetails = await hostService.getLatestQuestionDetailsPQQ(activity_xid);
|
||||||
|
|
||||||
if (pqqQuestionDetails) {
|
const result = {
|
||||||
result = {
|
pqqQuestionXid: pqqQuestionDetails.pqqQuestionXid,
|
||||||
pqqQuestionXid: pqqQuestionDetails.pqqQuestionXid,
|
pqqAnswerXid: pqqQuestionDetails.pqqAnswerXid,
|
||||||
pqqAnswerXid: pqqQuestionDetails.pqqAnswerXid || null,
|
pqqSubCategoryXid: pqqQuestionDetails.pqqQuestions.pqqSubCategoryXid,
|
||||||
pqqSubCategoryXid: pqqQuestionDetails.pqqQuestions.pqqSubCategoryXid || null,
|
categoryXid: pqqQuestionDetails.pqqQuestions.pqqSubCategories.categoryXid
|
||||||
categoryXid: pqqQuestionDetails.pqqQuestions.pqqSubCategories.categoryXid || null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
|
import { verifyHostToken } from '@/common/middlewares/jwt/authForHost';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { HostService } from '../../../services/host.service';
|
import { HostService } from '../../../services/host.service';
|
||||||
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { createActivitySchema } from '../../../../../common/utils/validation/host/activity.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const hostService = new HostService(prismaService);
|
const hostService = new HostService(prismaService);
|
||||||
@@ -17,23 +19,13 @@ export const handler = safeHandler(async (
|
|||||||
|
|
||||||
const userInfo = await verifyHostToken(token);
|
const userInfo = await verifyHostToken(token);
|
||||||
|
|
||||||
let body: any = {};
|
// Parse and validate request body using Zod
|
||||||
try {
|
const { activityTypeXid, frequenciesXid } = parseBody(event.body, createActivitySchema);
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (err) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { activityTypeXid, frequenciesXid } = body;
|
|
||||||
|
|
||||||
if (!activityTypeXid) {
|
|
||||||
throw new ApiError(400, 'activityTypeXid is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
await hostService.createActivity(
|
await hostService.createActivity(
|
||||||
userInfo.id,
|
userInfo.id,
|
||||||
Number(activityTypeXid),
|
activityTypeXid,
|
||||||
frequenciesXid ? Number(frequenciesXid) : undefined,
|
frequenciesXid,
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,301 +0,0 @@
|
|||||||
import config from '../../../../../config/config';
|
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
|
|
||||||
import AWS from 'aws-sdk';
|
|
||||||
import Busboy from 'busboy';
|
|
||||||
import crypto from 'crypto';
|
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
|
||||||
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
|
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
|
||||||
import { HostService } from '../../../services/host.service';
|
|
||||||
|
|
||||||
const prisma = new PrismaService();
|
|
||||||
const hostService = new HostService(prisma);
|
|
||||||
|
|
||||||
const s3 = new AWS.S3({ region: config.aws.region });
|
|
||||||
|
|
||||||
// Function to extract S3 key from URL
|
|
||||||
function getS3KeyFromUrl(url: string): string {
|
|
||||||
const bucketBaseUrl = `https://${config.aws.bucketName}.s3.${config.aws.region}.amazonaws.com/`;
|
|
||||||
return url.replace(bucketBaseUrl, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to delete file from S3
|
|
||||||
async function deleteFromS3(s3Key: string): Promise<void> {
|
|
||||||
try {
|
|
||||||
await s3.deleteObject({
|
|
||||||
Bucket: config.aws.bucketName,
|
|
||||||
Key: s3Key,
|
|
||||||
}).promise();
|
|
||||||
console.log(`✅ File deleted from S3: ${s3Key}`);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`❌ Error deleting file from S3: ${s3Key}`, error);
|
|
||||||
// continue — we don't want S3 deletion failure to crash the whole request
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function uploadToS3(buffer: Buffer, mimeType: string, originalName: string, prefix: string, existingUrl?: string): Promise<string> {
|
|
||||||
// We intentionally do NOT reuse old key. If existingUrl is provided we delete old file and create a new random key.
|
|
||||||
if (existingUrl) {
|
|
||||||
try {
|
|
||||||
const oldKey = getS3KeyFromUrl(existingUrl);
|
|
||||||
await deleteFromS3(oldKey);
|
|
||||||
} catch (err) {
|
|
||||||
console.warn('Warning deleting existingUrl before upload', err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const uniqueKey = `${crypto.randomUUID()}_${originalName}`;
|
|
||||||
const s3Key = `${prefix}/${uniqueKey}`;
|
|
||||||
|
|
||||||
await s3.upload({
|
|
||||||
Bucket: config.aws.bucketName,
|
|
||||||
Key: s3Key,
|
|
||||||
Body: buffer,
|
|
||||||
ContentType: mimeType,
|
|
||||||
ACL: 'private'
|
|
||||||
}).promise();
|
|
||||||
|
|
||||||
console.log(`✅ File uploaded to S3: ${s3Key}`);
|
|
||||||
return `https://${config.aws.bucketName}.s3.${config.aws.region}.amazonaws.com/${s3Key}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
|
|
||||||
try {
|
|
||||||
// 1) Auth
|
|
||||||
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
|
||||||
if (!token) throw new ApiError(401, 'Missing token.');
|
|
||||||
const user = await verifyHostToken(token);
|
|
||||||
|
|
||||||
// 2) Content-Type check
|
|
||||||
const contentType = event.headers["content-type"] || event.headers["Content-Type"];
|
|
||||||
if (!contentType?.includes("multipart/form-data"))
|
|
||||||
throw new ApiError(400, "Content-Type must be multipart/form-data");
|
|
||||||
|
|
||||||
// 3) Body decoding
|
|
||||||
const bodyBuffer = event.isBase64Encoded
|
|
||||||
? Buffer.from(event.body!, "base64")
|
|
||||||
: Buffer.from(event.body!, "binary");
|
|
||||||
|
|
||||||
const fields: any = {};
|
|
||||||
const files: Array<{ buffer: Buffer; mimeType: string; fileName: string; fieldName: string }> = [];
|
|
||||||
|
|
||||||
// 4) Parse multipart data
|
|
||||||
await new Promise<void>((resolve, reject) => {
|
|
||||||
const bb = Busboy({ headers: { 'content-type': contentType } });
|
|
||||||
|
|
||||||
bb.on('file', (fieldname, file, info) => {
|
|
||||||
const { filename, mimeType } = info;
|
|
||||||
|
|
||||||
if (!filename) {
|
|
||||||
file.resume();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const chunks: Buffer[] = [];
|
|
||||||
let size = 0;
|
|
||||||
const MAX_SIZE = 5 * 1024 * 1024;
|
|
||||||
|
|
||||||
file.on("data", (chunk) => {
|
|
||||||
size += chunk.length;
|
|
||||||
if (size > MAX_SIZE) {
|
|
||||||
file.destroy(new Error(`File ${filename} exceeds 5MB limit.`));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
chunks.push(chunk);
|
|
||||||
});
|
|
||||||
|
|
||||||
file.on("end", () => {
|
|
||||||
if (chunks.length > 0) {
|
|
||||||
files.push({
|
|
||||||
buffer: Buffer.concat(chunks),
|
|
||||||
mimeType,
|
|
||||||
fileName: filename,
|
|
||||||
fieldName: fieldname,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
file.on("error", (err) =>
|
|
||||||
reject(new ApiError(400, `File upload error: ${err.message}`))
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
bb.on("field", (fieldname, val) => {
|
|
||||||
console.log(`FIELD RAW: ${fieldname} =`, val);
|
|
||||||
if (val === '' || val === 'null' || val === 'undefined') fields[fieldname] = null;
|
|
||||||
else {
|
|
||||||
try {
|
|
||||||
const cleaned = val.trim();
|
|
||||||
|
|
||||||
// If it starts and ends with quotes, remove them
|
|
||||||
const withoutQuotes =
|
|
||||||
(cleaned.startsWith('"') && cleaned.endsWith('"'))
|
|
||||||
? cleaned.slice(1, -1)
|
|
||||||
: cleaned;
|
|
||||||
|
|
||||||
fields[fieldname] = JSON.parse(withoutQuotes);
|
|
||||||
} catch {
|
|
||||||
fields[fieldname] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
bb.on("close", () => resolve());
|
|
||||||
bb.on("error", (err) =>
|
|
||||||
reject(new ApiError(400, `Multipart parsing error: ${err.message}`))
|
|
||||||
);
|
|
||||||
|
|
||||||
// IMPORTANT FIX for HTTP API
|
|
||||||
bb.write(bodyBuffer);
|
|
||||||
bb.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 5) Extract required fields
|
|
||||||
const activityXid = Number(fields.activityXid);
|
|
||||||
const pqqQuestionXid = Number(fields.pqqQuestionXid);
|
|
||||||
const pqqAnswerXid = Number(fields.pqqAnswerXid);
|
|
||||||
const comments = fields.comments || null;
|
|
||||||
|
|
||||||
if (!activityXid || isNaN(activityXid)) throw new ApiError(400, "Valid activityXid is required");
|
|
||||||
if (!pqqQuestionXid || isNaN(pqqQuestionXid)) throw new ApiError(400, "Valid pqqQuestionXid is required");
|
|
||||||
if (!pqqAnswerXid || isNaN(pqqAnswerXid)) throw new ApiError(400, "Valid pqqAnswerXid is required");
|
|
||||||
|
|
||||||
// 6) UPSERT header
|
|
||||||
const existingHeader = await hostService.findHeaderByCompositeKey(
|
|
||||||
activityXid,
|
|
||||||
pqqQuestionXid,
|
|
||||||
);
|
|
||||||
|
|
||||||
let header;
|
|
||||||
if (existingHeader) {
|
|
||||||
console.log("🔄 Updating existing PQQ header");
|
|
||||||
header = await hostService.updateHeader(
|
|
||||||
existingHeader.id,
|
|
||||||
pqqAnswerXid,
|
|
||||||
comments
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
console.log("🆕 Creating new PQQ header");
|
|
||||||
header = await hostService.createHeader(
|
|
||||||
activityXid,
|
|
||||||
pqqQuestionXid,
|
|
||||||
pqqAnswerXid,
|
|
||||||
comments
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7) Get existing supporting files
|
|
||||||
const existingSupportingFiles = await hostService.getSupportingFilesByHeaderId(header.id);
|
|
||||||
console.log(`📁 Found ${existingSupportingFiles.length} existing supporting files`);
|
|
||||||
|
|
||||||
// 8) Parse incoming control fields
|
|
||||||
// fields.deletedFiles should be array like [{ id: number, url: string }, ...] or null
|
|
||||||
const deletedFiles: Array<{ id: number; url?: string }> = Array.isArray(fields.deletedFiles) ? fields.deletedFiles : [];
|
|
||||||
// fields.existingFiles can be an array of urls; we accept it but do not require it
|
|
||||||
const existingFilesFromFront: string[] = Array.isArray(fields.existingFiles) ? fields.existingFiles : [];
|
|
||||||
|
|
||||||
// Prepare response trackers
|
|
||||||
const deletedResults: Array<{ id: number; success: boolean; reason?: string }> = [];
|
|
||||||
const addedResults: Array<any> = [];
|
|
||||||
|
|
||||||
// 9) Handle explicit deletions (ONLY delete ids provided in deletedFiles)
|
|
||||||
if (deletedFiles.length > 0) {
|
|
||||||
console.log(`🗑️ Processing ${deletedFiles.length} explicit deletions`);
|
|
||||||
// Build a map of existing supporting files by id for quick lookup
|
|
||||||
const existingById = new Map<number, any>();
|
|
||||||
for (const f of existingSupportingFiles) {
|
|
||||||
existingById.set(f.id, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const del of deletedFiles) {
|
|
||||||
const id = Number(del.id);
|
|
||||||
if (!id || !existingById.has(id)) {
|
|
||||||
deletedResults.push({ id, success: false, reason: 'Not found or invalid id' });
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const record = existingById.get(id);
|
|
||||||
try {
|
|
||||||
// delete from s3
|
|
||||||
if (record.mediaFileName) {
|
|
||||||
const s3Key = getS3KeyFromUrl(record.mediaFileName);
|
|
||||||
await deleteFromS3(s3Key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete DB record
|
|
||||||
await hostService.deleteSupportingFile(record.id);
|
|
||||||
|
|
||||||
deletedResults.push({ id: record.id, success: true });
|
|
||||||
console.log(`🗑️ Deleted supporting file record ${record.id}`);
|
|
||||||
} catch (err: any) {
|
|
||||||
console.error(`❌ Failed to delete supporting file id ${id}`, err);
|
|
||||||
deletedResults.push({ id, success: false, reason: err.message || 'delete failed' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('ℹ️ No explicit deletions requested (deletedFiles empty)');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 10) Handle new uploaded files (these are ALWAYS added as new rows)
|
|
||||||
if (files.length > 0) {
|
|
||||||
console.log(`📤 Processing ${files.length} uploaded new file(s)`);
|
|
||||||
for (const file of files) {
|
|
||||||
try {
|
|
||||||
const url = await uploadToS3(
|
|
||||||
file.buffer,
|
|
||||||
file.mimeType,
|
|
||||||
file.fileName,
|
|
||||||
`ActivityOnboarding/supportings/${activityXid}`
|
|
||||||
);
|
|
||||||
|
|
||||||
// create DB record
|
|
||||||
const supporting = await hostService.addSupportingFile(
|
|
||||||
header.id,
|
|
||||||
file.mimeType,
|
|
||||||
url
|
|
||||||
);
|
|
||||||
|
|
||||||
addedResults.push(supporting);
|
|
||||||
console.log(`🆕 Created new supporting file record: ${supporting.id}`);
|
|
||||||
} catch (err: any) {
|
|
||||||
console.error('❌ Error uploading/creating supporting file', err);
|
|
||||||
// push failure result but continue processing other files
|
|
||||||
addedResults.push({ success: false, reason: err.message || 'upload/create failed' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('📭 No new files uploaded in request');
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: We DO NOT delete or modify existing supporting files that were not listed in deletedFiles.
|
|
||||||
// This satisfies your Case 2: "if no files are provided, do not touch existing supporting files".
|
|
||||||
|
|
||||||
const allPQPQuestionAnswerResponse = await hostService.getAllPQUpdatedResponse(activityXid)
|
|
||||||
|
|
||||||
// 11) Compose response
|
|
||||||
const responseMessage = existingHeader ? "PQQ answer updated successfully" : "PQQ answer submitted successfully";
|
|
||||||
|
|
||||||
return {
|
|
||||||
statusCode: 200,
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Access-Control-Allow-Origin": "*"
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
success: true,
|
|
||||||
message: responseMessage,
|
|
||||||
data: {
|
|
||||||
responseOfUpdatedData: allPQPQuestionAnswerResponse,
|
|
||||||
operation: existingHeader ? 'updated' : 'created',
|
|
||||||
// summary label for UI convenience:
|
|
||||||
fileOperation: (deletedResults.length > 0 || addedResults.length > 0) ? 'modified' : 'unchanged'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
} catch (error: any) {
|
|
||||||
console.error("❌ Error in submitPqqAnswer:", error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
|
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult } 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 { HostService } from '../../../services/host.service';
|
|
||||||
|
|
||||||
const prisma = new PrismaService();
|
|
||||||
const pqqService = new HostService(prisma);
|
|
||||||
|
|
||||||
export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
|
|
||||||
try {
|
|
||||||
// 1) Auth
|
|
||||||
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
|
||||||
if (!token) throw new ApiError(401, 'Missing token.');
|
|
||||||
const user = await verifyHostToken(token);
|
|
||||||
|
|
||||||
const activity_xid = event.queryStringParameters?.activity_xid
|
|
||||||
? Number(event.queryStringParameters.activity_xid)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
await pqqService.submitpqqforreview(Number(activity_xid), Number(user.id))
|
|
||||||
|
|
||||||
return {
|
|
||||||
statusCode: 200,
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Access-Control-Allow-Origin": "*"
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
success: true,
|
|
||||||
message: "Your PQQ has been submitted for review.",
|
|
||||||
data: null
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
} catch (error: any) {
|
|
||||||
console.error("❌ Error in submitPqqAnswer:", error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import config from '../../../../../config/config';
|
import config from '@/config/config';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
|
||||||
import AWS from 'aws-sdk';
|
import AWS from 'aws-sdk';
|
||||||
import Busboy from 'busboy';
|
import Busboy from 'busboy';
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
|
import { verifyHostToken } from '@/common/middlewares/jwt/authForHost';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { HostService } from '../../../services/host.service';
|
import { HostService } from '../../../services/host.service';
|
||||||
@@ -30,24 +30,34 @@ async function deleteFromS3(s3Key: string): Promise<void> {
|
|||||||
console.log(`✅ File deleted from S3: ${s3Key}`);
|
console.log(`✅ File deleted from S3: ${s3Key}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`❌ Error deleting file from S3: ${s3Key}`, error);
|
console.error(`❌ Error deleting file from S3: ${s3Key}`, error);
|
||||||
// continue — we don't want S3 deletion failure to crash the whole request
|
// Don't throw error here, continue with upload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function uploadToS3(buffer: Buffer, mimeType: string, originalName: string, prefix: string, existingUrl?: string): Promise<string> {
|
async function uploadToS3(buffer: Buffer, mimeType: string, originalName: string, prefix: string, existingUrl?: string): Promise<string> {
|
||||||
// We intentionally do NOT reuse old key. If existingUrl is provided we delete old file and create a new random key.
|
let s3Key: string;
|
||||||
|
|
||||||
|
// If existing URL provided, use the same S3 key to replace the file
|
||||||
|
// if (existingUrl) {
|
||||||
|
// s3Key = getS3KeyFromUrl(existingUrl);
|
||||||
|
// // Delete existing file first
|
||||||
|
// await deleteFromS3(s3Key);
|
||||||
|
// } else {
|
||||||
|
// // Generate new unique key for new file
|
||||||
|
// const uniqueKey = `${crypto.randomUUID()}_${originalName}`;
|
||||||
|
// s3Key = `${prefix}/${uniqueKey}`;
|
||||||
|
// }
|
||||||
if (existingUrl) {
|
if (existingUrl) {
|
||||||
try {
|
// Delete old file, but DO NOT reuse its name
|
||||||
const oldKey = getS3KeyFromUrl(existingUrl);
|
const oldKey = getS3KeyFromUrl(existingUrl);
|
||||||
await deleteFromS3(oldKey);
|
await deleteFromS3(oldKey);
|
||||||
} catch (err) {
|
|
||||||
console.warn('Warning deleting existingUrl before upload', err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create new key always
|
||||||
const uniqueKey = `${crypto.randomUUID()}_${originalName}`;
|
const uniqueKey = `${crypto.randomUUID()}_${originalName}`;
|
||||||
const s3Key = `${prefix}/${uniqueKey}`;
|
s3Key = `${prefix}/${uniqueKey}`;
|
||||||
|
|
||||||
|
// Upload new file (replaces existing if same key)
|
||||||
await s3.upload({
|
await s3.upload({
|
||||||
Bucket: config.aws.bucketName,
|
Bucket: config.aws.bucketName,
|
||||||
Key: s3Key,
|
Key: s3Key,
|
||||||
@@ -72,7 +82,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
if (!contentType?.includes("multipart/form-data"))
|
if (!contentType?.includes("multipart/form-data"))
|
||||||
throw new ApiError(400, "Content-Type must be multipart/form-data");
|
throw new ApiError(400, "Content-Type must be multipart/form-data");
|
||||||
|
|
||||||
// 3) Body decoding
|
// 3) Body decoding (FIXED – same as addCompanyDetails)
|
||||||
const bodyBuffer = event.isBase64Encoded
|
const bodyBuffer = event.isBase64Encoded
|
||||||
? Buffer.from(event.body!, "base64")
|
? Buffer.from(event.body!, "base64")
|
||||||
: Buffer.from(event.body!, "binary");
|
: Buffer.from(event.body!, "binary");
|
||||||
@@ -80,7 +90,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
const fields: any = {};
|
const fields: any = {};
|
||||||
const files: Array<{ buffer: Buffer; mimeType: string; fileName: string; fieldName: string }> = [];
|
const files: Array<{ buffer: Buffer; mimeType: string; fileName: string; fieldName: string }> = [];
|
||||||
|
|
||||||
// 4) Parse multipart data
|
// 4) Parse multipart data (FIXED – using bb.write + bb.end exactly like working lambda)
|
||||||
await new Promise<void>((resolve, reject) => {
|
await new Promise<void>((resolve, reject) => {
|
||||||
const bb = Busboy({ headers: { 'content-type': contentType } });
|
const bb = Busboy({ headers: { 'content-type': contentType } });
|
||||||
|
|
||||||
@@ -142,32 +152,41 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
bb.end();
|
bb.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 5) Extract required fields
|
// 4) Extract required fields - only activityXid, pqqQuestionXid, pqqAnswerXid are required
|
||||||
const activityXid = Number(fields.activityXid);
|
const activityXid = Number(fields.activityXid);
|
||||||
const pqqQuestionXid = Number(fields.pqqQuestionXid);
|
const pqqQuestionXid = Number(fields.pqqQuestionXid);
|
||||||
const pqqAnswerXid = Number(fields.pqqAnswerXid);
|
const pqqAnswerXid = Number(fields.pqqAnswerXid);
|
||||||
|
|
||||||
|
// Comments and files are optional
|
||||||
const comments = fields.comments || null;
|
const comments = fields.comments || null;
|
||||||
|
|
||||||
|
// Validate required fields
|
||||||
if (!activityXid || isNaN(activityXid)) throw new ApiError(400, "Valid activityXid is required");
|
if (!activityXid || isNaN(activityXid)) throw new ApiError(400, "Valid activityXid is required");
|
||||||
if (!pqqQuestionXid || isNaN(pqqQuestionXid)) throw new ApiError(400, "Valid pqqQuestionXid is required");
|
if (!pqqQuestionXid || isNaN(pqqQuestionXid)) throw new ApiError(400, "Valid pqqQuestionXid is required");
|
||||||
if (!pqqAnswerXid || isNaN(pqqAnswerXid)) throw new ApiError(400, "Valid pqqAnswerXid is required");
|
if (!pqqAnswerXid || isNaN(pqqAnswerXid)) throw new ApiError(400, "Valid pqqAnswerXid is required");
|
||||||
|
|
||||||
// 6) UPSERT header
|
// console.log(`📝 Processing - Activity: ${activityXid}, Question: ${pqqQuestionXid}, Answer: ${pqqAnswerXid}`);
|
||||||
|
// console.log(`💬 Comments: ${comments ? 'Provided' : 'Not provided'}`);
|
||||||
|
// console.log(`📎 Files: ${files.length}`);
|
||||||
|
|
||||||
|
// 5) UPSERT: Check if header already exists for this combination
|
||||||
const existingHeader = await pqqService.findHeaderByCompositeKey(
|
const existingHeader = await pqqService.findHeaderByCompositeKey(
|
||||||
activityXid,
|
activityXid,
|
||||||
pqqQuestionXid,
|
pqqQuestionXid,
|
||||||
|
pqqAnswerXid
|
||||||
);
|
);
|
||||||
|
|
||||||
let header;
|
let header;
|
||||||
if (existingHeader) {
|
if (existingHeader) {
|
||||||
console.log("🔄 Updating existing PQQ header");
|
console.log("🔄 Updating existing PQQ header");
|
||||||
|
// Update existing header (comments can be null)
|
||||||
header = await pqqService.updateHeader(
|
header = await pqqService.updateHeader(
|
||||||
existingHeader.id,
|
existingHeader.id,
|
||||||
pqqAnswerXid,
|
|
||||||
comments
|
comments
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
console.log("🆕 Creating new PQQ header");
|
console.log("🆕 Creating new PQQ header");
|
||||||
|
// Create new header (comments can be null)
|
||||||
header = await pqqService.createHeader(
|
header = await pqqService.createHeader(
|
||||||
activityXid,
|
activityXid,
|
||||||
pqqQuestionXid,
|
pqqQuestionXid,
|
||||||
@@ -176,93 +195,79 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7) Get existing supporting files
|
// 6) Get existing supporting files for this header
|
||||||
const existingSupportingFiles = await pqqService.getSupportingFilesByHeaderId(header.id);
|
const existingSupportingFiles = await pqqService.getSupportingFilesByHeaderId(header.id);
|
||||||
console.log(`📁 Found ${existingSupportingFiles.length} existing supporting files`);
|
console.log(`📁 Found ${existingSupportingFiles.length} existing supporting files`);
|
||||||
|
|
||||||
// 8) Parse incoming control fields
|
// 7) Handle file UPSERT - only if files are provided
|
||||||
// fields.deletedFiles should be array like [{ id: number, url: string }, ...] or null
|
const uploadedFiles: any[] = [];
|
||||||
const deletedFiles: Array<{ id: number; url?: string }> = Array.isArray(fields.deletedFiles) ? fields.deletedFiles : [];
|
|
||||||
// fields.existingFiles can be an array of urls; we accept it but do not require it
|
|
||||||
const existingFilesFromFront: string[] = Array.isArray(fields.existingFiles) ? fields.existingFiles : [];
|
|
||||||
|
|
||||||
// Prepare response trackers
|
|
||||||
const deletedResults: Array<{ id: number; success: boolean; reason?: string }> = [];
|
|
||||||
const addedResults: Array<any> = [];
|
|
||||||
|
|
||||||
// 9) Handle explicit deletions (ONLY delete ids provided in deletedFiles)
|
|
||||||
if (deletedFiles.length > 0) {
|
|
||||||
console.log(`🗑️ Processing ${deletedFiles.length} explicit deletions`);
|
|
||||||
// Build a map of existing supporting files by id for quick lookup
|
|
||||||
const existingById = new Map<number, any>();
|
|
||||||
for (const f of existingSupportingFiles) {
|
|
||||||
existingById.set(f.id, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const del of deletedFiles) {
|
|
||||||
const id = Number(del.id);
|
|
||||||
if (!id || !existingById.has(id)) {
|
|
||||||
deletedResults.push({ id, success: false, reason: 'Not found or invalid id' });
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const record = existingById.get(id);
|
|
||||||
try {
|
|
||||||
// delete from s3
|
|
||||||
if (record.mediaFileName) {
|
|
||||||
const s3Key = getS3KeyFromUrl(record.mediaFileName);
|
|
||||||
await deleteFromS3(s3Key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete DB record
|
|
||||||
await pqqService.deleteSupportingFile(record.id);
|
|
||||||
|
|
||||||
deletedResults.push({ id: record.id, success: true });
|
|
||||||
console.log(`🗑️ Deleted supporting file record ${record.id}`);
|
|
||||||
} catch (err: any) {
|
|
||||||
console.error(`❌ Failed to delete supporting file id ${id}`, err);
|
|
||||||
deletedResults.push({ id, success: false, reason: err.message || 'delete failed' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('ℹ️ No explicit deletions requested (deletedFiles empty)');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 10) Handle new uploaded files (these are ALWAYS added as new rows)
|
|
||||||
if (files.length > 0) {
|
if (files.length > 0) {
|
||||||
console.log(`📤 Processing ${files.length} uploaded new file(s)`);
|
console.log("📤 Processing file uploads...");
|
||||||
for (const file of files) {
|
|
||||||
try {
|
|
||||||
const url = await uploadToS3(
|
|
||||||
file.buffer,
|
|
||||||
file.mimeType,
|
|
||||||
file.fileName,
|
|
||||||
`ActivityOnboarding/supportings/${activityXid}`
|
|
||||||
);
|
|
||||||
|
|
||||||
// create DB record
|
for (let i = 0; i < files.length; i++) {
|
||||||
const supporting = await pqqService.addSupportingFile(
|
const file = files[i];
|
||||||
|
const existingFile = existingSupportingFiles[i] || null;
|
||||||
|
|
||||||
|
const url = await uploadToS3(
|
||||||
|
file.buffer,
|
||||||
|
file.mimeType,
|
||||||
|
file.fileName,
|
||||||
|
`ActivityOnboarding/supportings/${activityXid}`,
|
||||||
|
existingFile ? existingFile.mediaFileName : undefined
|
||||||
|
);
|
||||||
|
|
||||||
|
let supporting;
|
||||||
|
if (existingFile) {
|
||||||
|
// Update existing supporting file record
|
||||||
|
supporting = await pqqService.updateSupportingFile(
|
||||||
|
existingFile.id,
|
||||||
|
file.mimeType,
|
||||||
|
url
|
||||||
|
);
|
||||||
|
console.log(`🔄 Updated supporting file: ${existingFile.id}`);
|
||||||
|
} else {
|
||||||
|
// Create new supporting file record
|
||||||
|
supporting = await pqqService.addSupportingFile(
|
||||||
header.id,
|
header.id,
|
||||||
file.mimeType,
|
file.mimeType,
|
||||||
url
|
url
|
||||||
);
|
);
|
||||||
|
console.log(`🆕 Created new supporting file: ${supporting.id}`);
|
||||||
|
}
|
||||||
|
|
||||||
addedResults.push(supporting);
|
uploadedFiles.push(supporting);
|
||||||
console.log(`🆕 Created new supporting file record: ${supporting.id}`);
|
}
|
||||||
} catch (err: any) {
|
|
||||||
console.error('❌ Error uploading/creating supporting file', err);
|
// 8) Delete any remaining existing files that weren't replaced
|
||||||
// push failure result but continue processing other files
|
if (existingSupportingFiles.length > files.length) {
|
||||||
addedResults.push({ success: false, reason: err.message || 'upload/create failed' });
|
const filesToDelete = existingSupportingFiles.slice(files.length);
|
||||||
|
console.log(`🗑️ Deleting ${filesToDelete.length} unused supporting files`);
|
||||||
|
|
||||||
|
for (const fileToDelete of filesToDelete) {
|
||||||
|
await pqqService.deleteSupportingFile(fileToDelete.id);
|
||||||
|
// Also delete from S3
|
||||||
|
const s3Key = getS3KeyFromUrl(fileToDelete.mediaFileName);
|
||||||
|
await deleteFromS3(s3Key);
|
||||||
|
console.log(`🗑️ Deleted supporting file: ${fileToDelete.id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('📭 No new files uploaded in request');
|
console.log("📭 No files provided in request");
|
||||||
|
|
||||||
|
// If no files provided but existing files exist, delete them (cleanup)
|
||||||
|
if (existingSupportingFiles.length > 0) {
|
||||||
|
console.log(`🗑️ No new files provided, deleting ${existingSupportingFiles.length} existing files`);
|
||||||
|
for (const fileToDelete of existingSupportingFiles) {
|
||||||
|
await pqqService.deleteSupportingFile(fileToDelete.id);
|
||||||
|
const s3Key = getS3KeyFromUrl(fileToDelete.mediaFileName);
|
||||||
|
await deleteFromS3(s3Key);
|
||||||
|
console.log(`🗑️ Deleted supporting file: ${fileToDelete.id}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: We DO NOT delete or modify existing supporting files that were not listed in deletedFiles.
|
// 9) Prepare response
|
||||||
// This satisfies your Case 2: "if no files are provided, do not touch existing supporting files".
|
|
||||||
|
|
||||||
// 11) Compose response
|
|
||||||
const responseMessage = existingHeader ? "PQQ answer updated successfully" : "PQQ answer submitted successfully";
|
const responseMessage = existingHeader ? "PQQ answer updated successfully" : "PQQ answer submitted successfully";
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -279,15 +284,15 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
activityXid,
|
activityXid,
|
||||||
pqqQuestionXid,
|
pqqQuestionXid,
|
||||||
pqqAnswerXid,
|
pqqAnswerXid,
|
||||||
comments,
|
comments: comments,
|
||||||
files: {
|
files: {
|
||||||
added: addedResults,
|
uploaded: uploadedFiles,
|
||||||
deleted: deletedResults,
|
total: uploadedFiles.length
|
||||||
existingKeptCount: (existingSupportingFiles.length - deletedResults.filter(d => d.success).length)
|
|
||||||
},
|
},
|
||||||
operation: existingHeader ? 'updated' : 'created',
|
operation: existingHeader ? 'updated' : 'created',
|
||||||
// summary label for UI convenience:
|
fileOperation: files.length > 0 ?
|
||||||
fileOperation: (deletedResults.length > 0 || addedResults.length > 0) ? 'modified' : 'unchanged'
|
(existingSupportingFiles.length > 0 ? 'replaced' : 'added') :
|
||||||
|
(existingSupportingFiles.length > 0 ? 'removed' : 'unchanged')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
|
import { verifyHostToken } from '@/common/middlewares/jwt/authForHost';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { HostService } from '../../../services/host.service';
|
import { HostService } from '../../../services/host.service';
|
||||||
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { updateSuggestionReviewedSchema } from '../../../../../common/utils/validation/host/activity.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const hostService = new HostService(prismaService);
|
const hostService = new HostService(prismaService);
|
||||||
@@ -17,18 +19,8 @@ export const handler = safeHandler(async (
|
|||||||
|
|
||||||
const userInfo = await verifyHostToken(token);
|
const userInfo = await verifyHostToken(token);
|
||||||
|
|
||||||
let body: any = {};
|
// Parse and validate body using Zod
|
||||||
try {
|
const { activityPqqHeaderXid, activityPQQSuggestionId } = parseBody(event.body, updateSuggestionReviewedSchema);
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (err) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { activityPqqHeaderXid, activityPQQSuggestionId } = body;
|
|
||||||
|
|
||||||
if (!activityPqqHeaderXid) {
|
|
||||||
throw new ApiError(400, 'activityPqqHeaderXid is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
await hostService.markPQQSuggestionReviewed(
|
await hostService.markPQQSuggestionReviewed(
|
||||||
userInfo.id,
|
userInfo.id,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
|
import { verifyHostToken } from '@/common/middlewares/jwt/authForHost';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
|||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { HostService } from '../../../services/host.service';
|
import { HostService } from '../../../services/host.service';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
|
import { verifyHostToken } from '@/common/middlewares/jwt/authForHost';
|
||||||
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { createPasswordSchema } from '../../../../../common/utils/validation/host/auth.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const hostService = new HostService(prismaService);
|
const hostService = new HostService(prismaService);
|
||||||
@@ -22,30 +24,8 @@ export const handler = safeHandler(async (
|
|||||||
const userInfo = await verifyHostToken(token);
|
const userInfo = await verifyHostToken(token);
|
||||||
const user_xid = userInfo.id;
|
const user_xid = userInfo.id;
|
||||||
|
|
||||||
// Parse request body
|
// Parse and validate request body using Zod
|
||||||
let body: { password?: string; confirmPassword?: string };
|
const { password } = parseBody(event.body, createPasswordSchema);
|
||||||
|
|
||||||
try {
|
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (error) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { password, confirmPassword } = body;
|
|
||||||
|
|
||||||
if (!password || !confirmPassword) {
|
|
||||||
throw new ApiError(400, 'Password and confirm password are required');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate password match
|
|
||||||
if (password !== confirmPassword) {
|
|
||||||
throw new ApiError(400, 'Password and confirm password do not match');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate password length
|
|
||||||
if (password.length < 8) {
|
|
||||||
throw new ApiError(400, 'Password must be at least 8 characters long');
|
|
||||||
}
|
|
||||||
|
|
||||||
await hostService.createPassword(user_xid, password);
|
await hostService.createPassword(user_xid, password);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import { TokenService } from '../../../services/token.service';
|
|||||||
import { GetHostLoginResponseDTO } from '../../../dto/host.dto';
|
import { GetHostLoginResponseDTO } from '../../../dto/host.dto';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import * as bcrypt from 'bcryptjs';
|
import * as bcrypt from 'bcryptjs';
|
||||||
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { hostLoginSchema } from '../../../../../common/utils/validation/host/auth.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const hostService = new HostService(prismaService);
|
const hostService = new HostService(prismaService);
|
||||||
@@ -15,20 +17,8 @@ export const handler = safeHandler(async (
|
|||||||
event: APIGatewayProxyEvent,
|
event: APIGatewayProxyEvent,
|
||||||
context?: Context
|
context?: Context
|
||||||
): Promise<APIGatewayProxyResult> => {
|
): Promise<APIGatewayProxyResult> => {
|
||||||
// Parse request body
|
// Parse and validate request body using Zod
|
||||||
let body: { emailAddress?: string; userPassword?: string };
|
const { emailAddress, userPassword } = parseBody(event.body, hostLoginSchema);
|
||||||
|
|
||||||
try {
|
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (error) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { emailAddress, userPassword } = body;
|
|
||||||
|
|
||||||
if (!emailAddress || !userPassword) {
|
|
||||||
throw new ApiError(400, 'Email and password are required');
|
|
||||||
}
|
|
||||||
|
|
||||||
const loginForHost = await hostService.loginForHost(emailAddress, userPassword);
|
const loginForHost = await hostService.loginForHost(emailAddress, userPassword);
|
||||||
|
|
||||||
@@ -40,6 +30,15 @@ export const handler = safeHandler(async (
|
|||||||
throw new ApiError(401, 'Invalid credentials');
|
throw new ApiError(401, 'Invalid credentials');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const matchPassword = await bcrypt.compare(
|
||||||
|
userPassword,
|
||||||
|
loginForHost.userPassword
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!matchPassword) {
|
||||||
|
throw new ApiError(401, 'Invalid credentials');
|
||||||
|
}
|
||||||
|
|
||||||
const generateTokenForHost = await tokenService.generateAuthToken(
|
const generateTokenForHost = await tokenService.generateAuthToken(
|
||||||
loginForHost.id
|
loginForHost.id
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
|||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { MinglarService } from '../../../../minglaradmin/services/minglar.service';
|
import { MinglarService } from '../../../../minglaradmin/services/minglar.service';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
|
import { verifyHostToken } from '@/common/middlewares/jwt/authForHost';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import * as bcrypt from 'bcryptjs';
|
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { ROLE } from '../../../../../common/utils/constants/common.constant';
|
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { encryptUserId } from '../../../../../common/utils/helper/CodeGenerator';
|
import * as bcrypt from 'bcryptjs';
|
||||||
import { OtpGeneratorSixDigit } from '../../../../../common/utils/helper/OtpGenerator';
|
import { OtpGeneratorSixDigit } from '../../../../../common/utils/helper/OtpGenerator';
|
||||||
|
import { encryptUserId } from '../../../../../common/utils/helper/CodeGenerator';
|
||||||
import { HostService } from '../../../services/host.service';
|
import { HostService } from '../../../services/host.service';
|
||||||
|
import { sendOtpEmailForHost } from '../../../services/sendOTPEmail.service';
|
||||||
|
import { ROLE } from '../../../../../common/utils/constants/common.constant';
|
||||||
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { hostSignUpSchema } from '../../../../../common/utils/validation/host/auth.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const hostService = new HostService(prismaService);
|
const hostService = new HostService(prismaService);
|
||||||
@@ -30,20 +33,8 @@ export const handler = safeHandler(async (
|
|||||||
event: APIGatewayProxyEvent,
|
event: APIGatewayProxyEvent,
|
||||||
context?: Context
|
context?: Context
|
||||||
): Promise<APIGatewayProxyResult> => {
|
): Promise<APIGatewayProxyResult> => {
|
||||||
// Parse request body
|
// Parse and validate request body using Zod
|
||||||
let body: { email?: string };
|
const { email } = parseBody(event.body, hostSignUpSchema);
|
||||||
|
|
||||||
try {
|
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (error) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { email } = body;
|
|
||||||
|
|
||||||
if (!email) {
|
|
||||||
throw new ApiError(400, 'Email is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use a single transaction for user creation/lookup and OTP storage
|
// Use a single transaction for user creation/lookup and OTP storage
|
||||||
const transactionResult = await prismaService.$transaction(async (tx) => {
|
const transactionResult = await prismaService.$transaction(async (tx) => {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
// modules/host/handlers/addCompanyDetails.ts
|
// modules/host/handlers/addCompanyDetails.ts
|
||||||
import config from '../../../../../config/config';
|
import config from '@/config/config';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
|
||||||
import AWS from 'aws-sdk';
|
import AWS from 'aws-sdk';
|
||||||
import Busboy from 'busboy';
|
import Busboy from 'busboy';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
|
import { verifyHostToken } from '@/common/middlewares/jwt/authForHost';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import {
|
import {
|
||||||
@@ -50,25 +50,6 @@ function cleanEmptyStrings(obj: any) {
|
|||||||
return cleaned;
|
return cleaned;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getS3KeyFromUrl(url: string): string {
|
|
||||||
const base = `https://${config.aws.bucketName}.s3.${config.aws.region}.amazonaws.com/`;
|
|
||||||
return url.replace(base, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteFromS3(key: string) {
|
|
||||||
try {
|
|
||||||
await s3.deleteObject({
|
|
||||||
Bucket: config.aws.bucketName,
|
|
||||||
Key: key
|
|
||||||
}).promise();
|
|
||||||
|
|
||||||
console.log("✅ Deleted from S3:", key);
|
|
||||||
} catch (err) {
|
|
||||||
console.error("❌ Failed to delete from S3:", key, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
|
export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
@@ -131,9 +112,6 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
bb.end();
|
bb.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
const deletedFiles = normalizeJsonField(fields, "deletedFiles") || [];
|
|
||||||
const parentDeletedFiles = normalizeJsonField(fields, "parentDeletedFiles") || [];
|
|
||||||
|
|
||||||
/** 4) Extract and clean isDraft flag */
|
/** 4) Extract and clean isDraft flag */
|
||||||
const isDraft = fields.isDraft === 'true' || fields.isDraft === true;
|
const isDraft = fields.isDraft === 'true' || fields.isDraft === true;
|
||||||
|
|
||||||
@@ -200,10 +178,15 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
const file = files.find((f) => f.fieldName === doc.fieldName);
|
const file = files.find((f) => f.fieldName === doc.fieldName);
|
||||||
|
|
||||||
// In DRAFT mode → allow missing documents
|
// In DRAFT mode → allow missing documents
|
||||||
if (!file) {
|
if (isDraft && !file) {
|
||||||
return { ...doc, file: null };
|
return { ...doc, file: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In FINAL mode → file must exist
|
||||||
|
if (!file) {
|
||||||
|
throw new ApiError(400, `File not found for field: ${doc.fieldName}`);
|
||||||
|
}
|
||||||
|
|
||||||
return { ...doc, file };
|
return { ...doc, file };
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -230,63 +213,6 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
parsedParentCompany = parsedCompany.parentCompany || null;
|
parsedParentCompany = parsedCompany.parentCompany || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 9.5) DELETE DOCUMENTS IF REQUESTED **/
|
|
||||||
if (Array.isArray(deletedFiles) && deletedFiles.length > 0) {
|
|
||||||
console.log(`🗑️ Deleting ${deletedFiles.length} documents...`);
|
|
||||||
|
|
||||||
for (const del of deletedFiles) {
|
|
||||||
const id = Number(del.id);
|
|
||||||
const url = del.url;
|
|
||||||
|
|
||||||
if (!id || !url) {
|
|
||||||
console.log("❌ Invalid delete entry:", del);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract S3 key
|
|
||||||
const s3Key = getS3KeyFromUrl(url);
|
|
||||||
|
|
||||||
// Delete from S3
|
|
||||||
await deleteFromS3(s3Key);
|
|
||||||
|
|
||||||
// Delete from DB
|
|
||||||
await prisma.hostDocuments.delete({
|
|
||||||
where: { id }
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(`🗑️ Deleted host document ID ${id}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 9.6) DELETE PARENT DOCUMENTS **/
|
|
||||||
if (parsedCompany.isSubsidairy && Array.isArray(parentDeletedFiles) && parentDeletedFiles.length > 0) {
|
|
||||||
console.log(`🗑️ Deleting ${parentDeletedFiles.length} PARENT documents...`);
|
|
||||||
|
|
||||||
for (const del of parentDeletedFiles) {
|
|
||||||
const id = Number(del.id);
|
|
||||||
const url = del.url;
|
|
||||||
|
|
||||||
if (!id || !url) {
|
|
||||||
console.log("⚠️ Invalid parent delete entry:", del);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const s3Key = getS3KeyFromUrl(url);
|
|
||||||
|
|
||||||
// Delete S3
|
|
||||||
await deleteFromS3(s3Key);
|
|
||||||
|
|
||||||
// Delete DB
|
|
||||||
await prisma.hostParenetDocuments.delete({
|
|
||||||
where: { id }
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(`🗑️ Deleted PARENT document ID ${id}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** 11) UPLOAD DOCUMENTS */
|
/** 11) UPLOAD DOCUMENTS */
|
||||||
async function uploadToS3(buffer, mimeType, originalName, folderType, documentTypeXid?, fieldName?) {
|
async function uploadToS3(buffer, mimeType, originalName, folderType, documentTypeXid?, fieldName?) {
|
||||||
const ext = originalName.split('.').pop() || 'jpg';
|
const ext = originalName.split('.').pop() || 'jpg';
|
||||||
@@ -323,7 +249,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
/** Upload host docs */
|
/** Upload host docs */
|
||||||
const uploadedHostDocs: Array<any> = [];
|
const uploadedHostDocs: Array<any> = [];
|
||||||
for (const doc of hostDocs) {
|
for (const doc of hostDocs) {
|
||||||
if (!doc.file) continue;
|
if (isDraft && !doc.file) continue;
|
||||||
|
|
||||||
const path = await uploadToS3(
|
const path = await uploadToS3(
|
||||||
doc.file.buffer,
|
doc.file.buffer,
|
||||||
@@ -344,7 +270,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
/** Upload parent docs */
|
/** Upload parent docs */
|
||||||
const uploadedParentDocs: Array<any> = [];
|
const uploadedParentDocs: Array<any> = [];
|
||||||
for (const doc of parentDocs) {
|
for (const doc of parentDocs) {
|
||||||
if (!doc.file) continue; // skip missing files in draft mode
|
if (!doc.file && isDraft) continue; // skip missing files in draft mode
|
||||||
|
|
||||||
const path = await uploadToS3(
|
const path = await uploadToS3(
|
||||||
doc.file.buffer,
|
doc.file.buffer,
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
|||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { HostService } from '../../../services/host.service';
|
import { HostService } from '../../../services/host.service';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
|
import { verifyHostToken } from '@/common/middlewares/jwt/authForHost';
|
||||||
import { hostBankDetailsSchema } from '../../../../../common/utils/validation/host/addPaymentDetails.validation';
|
import { hostBankDetailsSchema } from '@/common/utils/validation/host/addPaymentDetails.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const hostService = new HostService(prismaService);
|
const hostService = new HostService(prismaService);
|
||||||
@@ -33,7 +33,7 @@ export const handler = safeHandler(async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse request body
|
// Parse request body
|
||||||
let body: { bankXid?: number; bankBranchXid?: number; accountNumber?: string; confirmAccountNumber?: string; accountHolderName?: string; currencyXid?: number };
|
let body: { bankXid?: number; bankBranchXid?: number; accountNumber?: string; confirmAccountNumber?: string; accountHolderName?: string; ifscCode?: string; currencyXid?: number };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
body = event.body ? JSON.parse(event.body) : {};
|
||||||
@@ -54,16 +54,7 @@ export const handler = safeHandler(async (
|
|||||||
|
|
||||||
const validatedData = validationResult.data;
|
const validatedData = validationResult.data;
|
||||||
|
|
||||||
// Fetch IFSC code from bank branch
|
await hostService.addPaymentDetails(validatedData);
|
||||||
const bankBranch = await hostService.getBankBranchById(validatedData.bankBranchXid);
|
|
||||||
if (!bankBranch) {
|
|
||||||
throw new ApiError(404, 'Bank branch not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
await hostService.addPaymentDetails({
|
|
||||||
...validatedData,
|
|
||||||
ifscCode: bankBranch.ifscCode,
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda
|
|||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { HostService } from '../../../services/host.service';
|
import { HostService } from '../../../services/host.service';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
|
||||||
import { TokenService } from '../../../services/token.service';
|
import { TokenService } from '../../../services/token.service';
|
||||||
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { verifyOtpWithEmailSchema } from '../../../../../common/utils/validation/host/auth.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const hostService = new HostService(prismaService);
|
const hostService = new HostService(prismaService);
|
||||||
@@ -13,20 +14,8 @@ export const handler = safeHandler(async (
|
|||||||
event: APIGatewayProxyEvent,
|
event: APIGatewayProxyEvent,
|
||||||
context?: Context
|
context?: Context
|
||||||
): Promise<APIGatewayProxyResult> => {
|
): Promise<APIGatewayProxyResult> => {
|
||||||
// Parse request body
|
// Parse and validate request body using Zod
|
||||||
let body: { email?: string; otp?: string };
|
const { email, otp } = parseBody(event.body, verifyOtpWithEmailSchema);
|
||||||
|
|
||||||
try {
|
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (error) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { email, otp } = body;
|
|
||||||
|
|
||||||
if (!email || !otp) {
|
|
||||||
throw new ApiError(400, 'Email and OTP are required');
|
|
||||||
}
|
|
||||||
|
|
||||||
await hostService.verifyHostOtp(email, otp);
|
await hostService.verifyHostOtp(email, otp);
|
||||||
const user = await hostService.getHostByEmail(email);
|
const user = await hostService.getHostByEmail(email);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export const handler = safeHandler(async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fetch user with their HostHeader stepper info
|
// Fetch user with their HostHeader stepper info
|
||||||
const host = await hostService.getHostIdByUserXid(userId);
|
const host = await hostService.getHostById(userId);
|
||||||
|
|
||||||
if (!host) {
|
if (!host) {
|
||||||
throw new ApiError(404, 'Host record not found');
|
throw new ApiError(404, 'Host record not found');
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { verifyMinglarAdminHostToken } from '../../../common/middlewares/jwt/authForMinglarAdminHost';
|
import { verifyMinglarAdminHostToken } from '@/common/middlewares/jwt/authForMinglarAdmin&Host';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../common/database/prisma.service';
|
import { PrismaService } from '../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ export const handler = safeHandler(async (
|
|||||||
|
|
||||||
const result = await prisma.hostHeader.findMany({
|
const result = await prisma.hostHeader.findMany({
|
||||||
select: {
|
select: {
|
||||||
|
id: true,
|
||||||
hostParent: true,
|
hostParent: true,
|
||||||
hostRefNumber: true,
|
|
||||||
hostStatusDisplay: true,
|
hostStatusDisplay: true,
|
||||||
accountManager: true,
|
accountManager: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { safeHandler } from "../../../common/utils/handlers/safeHandler";
|
|||||||
import ApiError from "../../../common/utils/helper/ApiError";
|
import ApiError from "../../../common/utils/helper/ApiError";
|
||||||
import { resendOtpHelper } from "../../../common/utils/helper/resendOtpHelper";
|
import { resendOtpHelper } from "../../../common/utils/helper/resendOtpHelper";
|
||||||
import { resendOtpEmail } from "../services/resendOTPEmail.service";
|
import { resendOtpEmail } from "../services/resendOTPEmail.service";
|
||||||
|
import { parseBody } from "../../../common/utils/validation/validation.utils";
|
||||||
|
import { resendOtpSchema } from "../../../common/utils/validation/host/auth.validation";
|
||||||
|
|
||||||
const prisma = new PrismaService();
|
const prisma = new PrismaService();
|
||||||
|
|
||||||
@@ -13,33 +15,12 @@ type OtpPurpose = typeof ALLOWED_PURPOSES[number];
|
|||||||
|
|
||||||
export const handler = safeHandler(
|
export const handler = safeHandler(
|
||||||
async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
|
async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
|
||||||
// parse body safely
|
// Parse and validate body using Zod
|
||||||
let body: { email?: string; purpose?: string } = {};
|
const { email, purpose: purposeFromBody } = parseBody(event.body, resendOtpSchema);
|
||||||
try {
|
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch {
|
|
||||||
throw new ApiError(400, "Invalid JSON in request body");
|
|
||||||
}
|
|
||||||
|
|
||||||
// allow passing purpose via query string too (useful for GET requests)
|
// allow passing purpose via query string too (useful for GET requests)
|
||||||
const qsPurpose = event.queryStringParameters?.purpose;
|
const qsPurpose = event.queryStringParameters?.purpose;
|
||||||
const purposeRaw = (body.purpose || qsPurpose || "").trim();
|
const purpose = (purposeFromBody || qsPurpose || "Register") as OtpPurpose;
|
||||||
|
|
||||||
if (!purposeRaw) {
|
|
||||||
throw new ApiError(400, "purpose is required. Allowed values: Register, Login, ForgotPassword");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ALLOWED_PURPOSES.includes(purposeRaw as OtpPurpose)) {
|
|
||||||
throw new ApiError(
|
|
||||||
400,
|
|
||||||
`Invalid purpose '${purposeRaw}'. Allowed values: ${ALLOWED_PURPOSES.join(", ")}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const purpose = purposeRaw as OtpPurpose;
|
|
||||||
|
|
||||||
const email = (body.email || "").trim();
|
|
||||||
if (!email) throw new ApiError(400, "Email is required");
|
|
||||||
|
|
||||||
// find user (you can adapt the isActive / userStatus checks per your rules)
|
// find user (you can adapt the isActive / userStatus checks per your rules)
|
||||||
const user = await prisma.user.findUnique({
|
const user = await prisma.user.findUnique({
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,10 @@
|
|||||||
import { verifyMinglarAdminToken } from '../../../common/middlewares/jwt/authForMinglarAdmin';
|
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../common/database/prisma.service';
|
|
||||||
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../common/utils/helper/ApiError';
|
import { PrismaService } from '../../../common/database/prisma.service';
|
||||||
import { MinglarService } from '../services/minglar.service';
|
import { MinglarService } from '../services/minglar.service';
|
||||||
|
import { verifyMinglarAdminToken } from '@/common/middlewares/jwt/authForMinglarAdmin';
|
||||||
|
import { parseBody } from '../../../common/utils/validation/validation.utils';
|
||||||
|
import { minglarCreatePasswordSchema } from '../../../common/utils/validation/minglaradmin/auth.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
@@ -15,37 +16,15 @@ export const handler = safeHandler(async (
|
|||||||
// Extract token from headers
|
// Extract token from headers
|
||||||
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token']
|
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token']
|
||||||
if(!token) {
|
if(!token) {
|
||||||
throw new ApiError(400, 'This is a protected route. Please provide a valid token.');
|
throw new (await import('../../../common/utils/helper/ApiError')).default(400, 'This is a protected route. Please provide a valid token.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authenticate user using the shared authForHost function
|
// Authenticate user using the shared authForHost function
|
||||||
const userInfo = await verifyMinglarAdminToken(token);
|
const userInfo = await verifyMinglarAdminToken(token);
|
||||||
const user_xid = userInfo.id;
|
const user_xid = userInfo.id;
|
||||||
|
|
||||||
// Parse request body
|
// Parse and validate request body using Zod
|
||||||
let body: { password?: string; confirmPassword?: string };
|
const { password } = parseBody(event.body, minglarCreatePasswordSchema);
|
||||||
|
|
||||||
try {
|
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (error) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { password, confirmPassword } = body;
|
|
||||||
|
|
||||||
if (!password || !confirmPassword) {
|
|
||||||
throw new ApiError(400, 'Password and confirm password are required');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate password match
|
|
||||||
if (password !== confirmPassword) {
|
|
||||||
throw new ApiError(400, 'Password and confirm password do not match');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate password length
|
|
||||||
if (password.length < 8) {
|
|
||||||
throw new ApiError(400, 'Password must be at least 8 characters long');
|
|
||||||
}
|
|
||||||
|
|
||||||
await minglarService.createPassword(user_xid, password);
|
await minglarService.createPassword(user_xid, password);
|
||||||
const userDetails = await minglarService.getBasicUserDetails(user_xid)
|
const userDetails = await minglarService.getBasicUserDetails(user_xid)
|
||||||
|
|||||||
@@ -3,18 +3,19 @@ import {
|
|||||||
APIGatewayProxyResult,
|
APIGatewayProxyResult,
|
||||||
Context,
|
Context,
|
||||||
} from 'aws-lambda';
|
} from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../common/database/prisma.service';
|
|
||||||
import { verifyMinglarAdminToken } from '../../../common/middlewares/jwt/authForMinglarAdmin';
|
|
||||||
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../common/utils/helper/ApiError';
|
import { PrismaService } from '../../../common/database/prisma.service';
|
||||||
import { MinglarService } from '../services/minglar.service';
|
import { MinglarService } from '../services/minglar.service';
|
||||||
|
import ApiError from '../../../common/utils/helper/ApiError';
|
||||||
|
import { verifyMinglarAdminToken } from '../../../common/middlewares/jwt/authForMinglarAdmin';
|
||||||
|
import { parseQueryParams } from '../../../common/utils/validation/validation.utils';
|
||||||
|
import { getAmDetailByIdPathSchema } from '../../../common/utils/validation/prepopulate/prepopulate.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all host applications handler
|
* Get AM details by ID handler
|
||||||
* Returns host details with status, submission date, and account manager info
|
|
||||||
*/
|
*/
|
||||||
export const handler = safeHandler(
|
export const handler = safeHandler(
|
||||||
async (
|
async (
|
||||||
@@ -33,22 +34,12 @@ export const handler = safeHandler(
|
|||||||
|
|
||||||
await verifyMinglarAdminToken(token);
|
await verifyMinglarAdminToken(token);
|
||||||
|
|
||||||
const amXid = event.pathParameters?.amXid;
|
// Parse and validate path params using Zod
|
||||||
if (!amXid) {
|
const { amXid } = parseQueryParams(event.pathParameters, getAmDetailByIdPathSchema);
|
||||||
throw new ApiError(
|
|
||||||
400,
|
|
||||||
'Account Manager XID is required in path parameters.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const amId = Number(amXid);
|
|
||||||
if (Number.isNaN(amId)) {
|
|
||||||
throw new ApiError(400, 'Account Manager XID must be a valid number.');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Get all host applications from service based on user role
|
// Get AM details by ID from service
|
||||||
const getAmDetailsByid = await minglarService.getAMdetailById( amId );
|
const getAmDetailsByid = await minglarService.getAMdetailById(amXid);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
|
|||||||
@@ -3,22 +3,16 @@ import { PrismaService } from '../../../../../common/database/prisma.service';
|
|||||||
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
|
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { sendEmailToHostForApprovedApplication } from '../../../services/approvalMailtoHost.service';
|
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
|
import { sendEmailToHostForApprovedApplication } from '../../../services/approvalMailtoHost.service'
|
||||||
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { hostApplicationActionSchema } from '../../../../../common/utils/validation/minglaradmin/hosthub.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
|
|
||||||
interface AddSuggestionBody {
|
|
||||||
hostXid: number;
|
|
||||||
title: string;
|
|
||||||
comments: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add suggestion handler for host applications
|
* Accept host application handler
|
||||||
* Allows Minglar Admin, Co_Admin, and Account Manager to add suggestions
|
|
||||||
* Types: Setup Profile, Review Account, Add Payment Details, Agreement
|
|
||||||
*/
|
*/
|
||||||
export const handler = safeHandler(async (
|
export const handler = safeHandler(async (
|
||||||
event: APIGatewayProxyEvent,
|
event: APIGatewayProxyEvent,
|
||||||
@@ -33,16 +27,8 @@ export const handler = safeHandler(async (
|
|||||||
// Verify token and get user info
|
// Verify token and get user info
|
||||||
const userInfo = await verifyMinglarAdminToken(token);
|
const userInfo = await verifyMinglarAdminToken(token);
|
||||||
|
|
||||||
// Parse request body
|
// Parse and validate request body using Zod
|
||||||
let body: AddSuggestionBody;
|
const { hostXid } = parseBody(event.body, hostApplicationActionSchema);
|
||||||
|
|
||||||
try {
|
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (error) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { hostXid } = body;
|
|
||||||
|
|
||||||
|
|
||||||
// Add suggestion using service
|
// Add suggestion using service
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
|
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
|
||||||
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';
|
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
|
||||||
const minglarService = new MinglarService(prismaService);
|
|
||||||
|
|
||||||
export const handler = safeHandler(async (
|
|
||||||
event: APIGatewayProxyEvent,
|
|
||||||
context?: Context
|
|
||||||
): Promise<APIGatewayProxyResult> => {
|
|
||||||
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.');
|
|
||||||
|
|
||||||
const userInfo = await verifyMinglarAdminToken(token);
|
|
||||||
|
|
||||||
const activityId = event.pathParameters?.activityId;
|
|
||||||
|
|
||||||
if (!activityId) {
|
|
||||||
throw new ApiError(400, 'activityId is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
await minglarService.acceptPQByAM(
|
|
||||||
Number(activityId),
|
|
||||||
Number(userInfo.id)
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
statusCode: 201,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Access-Control-Allow-Origin': '*',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
success: true,
|
|
||||||
message: 'Approved PQ successfully',
|
|
||||||
data: null,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
@@ -1,20 +1,16 @@
|
|||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
|
||||||
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
|
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
// import { HOST_SUGGESTION_TITLES } from '../../../../../common/utils/constants/minglar.constant';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
|
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
|
||||||
|
import { HOST_SUGGESTION_TITLES } from '../../../../../common/utils/constants/minglar.constant';
|
||||||
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { addPqqSuggestionSchema } from '../../../../../common/utils/validation/minglaradmin/hosthub.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
|
|
||||||
interface AddSuggestionBody {
|
|
||||||
title: string;
|
|
||||||
comments: string;
|
|
||||||
activity_pqq_header_xid:number
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add suggestion handler for host applications
|
* Add suggestion handler for host applications
|
||||||
* Allows Minglar Admin, Co_Admin, and Account Manager to add suggestions
|
* Allows Minglar Admin, Co_Admin, and Account Manager to add suggestions
|
||||||
@@ -43,34 +39,14 @@ export const handler = safeHandler(async (
|
|||||||
throw new ApiError(404, 'User not found');
|
throw new ApiError(404, 'User not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse request body
|
// Parse and validate request body using Zod
|
||||||
let body: AddSuggestionBody;
|
const { title, comments, activity_pqq_header_xid } = parseBody(event.body, addPqqSuggestionSchema);
|
||||||
|
|
||||||
try {
|
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (error) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { title, comments , activity_pqq_header_xid} = body;
|
|
||||||
|
|
||||||
if (!title) {
|
|
||||||
throw new ApiError(400, 'Title is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!comments) {
|
|
||||||
throw new ApiError(400, 'Comments are required');
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!activity_pqq_header_xid){
|
|
||||||
throw new ApiError(400 , "Activity Pqq HeaderXid Required");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate title is one of the allowed types
|
// Validate title is one of the allowed types
|
||||||
// const allowedTitles = Object.values(HOST_SUGGESTION_TITLES);
|
const allowedTitles = Object.values(HOST_SUGGESTION_TITLES);
|
||||||
// if (!allowedTitles.includes(title)) {
|
if (!allowedTitles.includes(title)) {
|
||||||
// throw new ApiError(400, `Invalid title. Allowed values: ${allowedTitles.join(', ')}`);
|
throw new ApiError(400, `Invalid title. Allowed values: ${allowedTitles.join(', ')}`);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// Add suggestion using service
|
// Add suggestion using service
|
||||||
await minglarService.addPqqSuggestion(title, comments, activity_pqq_header_xid,user.id);
|
await minglarService.addPqqSuggestion(title, comments, activity_pqq_header_xid,user.id);
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
|
||||||
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
|
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
|
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
|
||||||
|
import { HOST_SUGGESTION_TITLES } from '../../../../../common/utils/constants/minglar.constant';
|
||||||
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { addHostSuggestionSchema } from '../../../../../common/utils/validation/minglaradmin/hosthub.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
|
|
||||||
interface AddSuggestionBody {
|
|
||||||
hostXid: number;
|
|
||||||
title: string;
|
|
||||||
comments: string;
|
|
||||||
isParent: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add suggestion handler for host applications
|
* Add suggestion handler for host applications
|
||||||
* Allows Minglar Admin, Co_Admin, and Account Manager to add suggestions
|
* Allows Minglar Admin, Co_Admin, and Account Manager to add suggestions
|
||||||
@@ -43,38 +39,17 @@ export const handler = safeHandler(async (
|
|||||||
throw new ApiError(404, 'User not found');
|
throw new ApiError(404, 'User not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse request body
|
// Parse and validate request body using Zod
|
||||||
let body: AddSuggestionBody;
|
const { hostXid, title, comments } = parseBody(event.body, addHostSuggestionSchema);
|
||||||
|
|
||||||
try {
|
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (error) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { hostXid, title, comments, isParent } = body;
|
|
||||||
|
|
||||||
// Validate required fields
|
|
||||||
if (!hostXid) {
|
|
||||||
throw new ApiError(400, 'Host ID is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!title) {
|
|
||||||
throw new ApiError(400, 'Title is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!comments) {
|
|
||||||
throw new ApiError(400, 'Comments are required');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate title is one of the allowed types
|
// Validate title is one of the allowed types
|
||||||
// const allowedTitles = Object.values(HOST_SUGGESTION_TITLES);
|
const allowedTitles = Object.values(HOST_SUGGESTION_TITLES);
|
||||||
// if (!allowedTitles.includes(title)) {
|
if (!allowedTitles.includes(title)) {
|
||||||
// throw new ApiError(400, `Invalid title. Allowed values: ${allowedTitles.join(', ')}`);
|
throw new ApiError(400, `Invalid title. Allowed values: ${allowedTitles.join(', ')}`);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// Add suggestion using service
|
// Add suggestion using service
|
||||||
await minglarService.addHostSuggestion(hostXid, title, comments, user.id, isParent);
|
await minglarService.addHostSuggestion(hostXid, title, comments, user.id);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
|
||||||
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
|
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
|
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
|
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
|
||||||
|
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
|
||||||
|
import { parseQueryParams } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { getAllHostApplicationsQuerySchema } from '../../../../../common/utils/validation/minglaradmin/hosthub.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
@@ -35,15 +37,15 @@ export const handler = safeHandler(async (
|
|||||||
throw new ApiError(404, 'User not found');
|
throw new ApiError(404, 'User not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get query parameters
|
// Parse and validate query params using Zod
|
||||||
const search = event.queryStringParameters?.search || '';
|
const { search, userStatus, roleFilter } = parseQueryParams(
|
||||||
const userStatus = event.queryStringParameters?.userStatus || '';
|
event.queryStringParameters,
|
||||||
const roleFilter = event.queryStringParameters?.roleFilter || '';
|
getAllHostApplicationsQuerySchema
|
||||||
|
);
|
||||||
|
|
||||||
// Parse pagination parameters
|
// Parse pagination parameters
|
||||||
const paginationParams = paginationService.getPaginationFromEvent(event);
|
const paginationParams = paginationService.getPaginationFromEvent(event);
|
||||||
const paginationOptions = paginationService.parsePaginationParams(paginationParams);
|
const paginationOptions = paginationService.parsePaginationParams(paginationParams);
|
||||||
const applicationStatus = event.queryStringParameters?.applicationStatus || '';
|
|
||||||
|
|
||||||
// Get paginated host applications
|
// Get paginated host applications
|
||||||
const { data, totalCount } = await minglarService.getAllHostApplications(
|
const { data, totalCount } = await minglarService.getAllHostApplications(
|
||||||
@@ -52,8 +54,7 @@ export const handler = safeHandler(async (
|
|||||||
search,
|
search,
|
||||||
userStatus,
|
userStatus,
|
||||||
paginationOptions,
|
paginationOptions,
|
||||||
roleFilter,
|
roleFilter
|
||||||
applicationStatus
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create paginated response
|
// Create paginated response
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { verifyMinglarAdminHostToken } from '@/common/middlewares/jwt/authForMinglarAdmin&Host';
|
||||||
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
|
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
|
import { PrismaService } from '@/common/database/prisma.service';
|
||||||
|
import { safeHandler } from '@/common/utils/handlers/safeHandler';
|
||||||
|
import ApiError from '@/common/utils/helper/ApiError';
|
||||||
|
import { verifyMinglarAdminToken } from '@/common/middlewares/jwt/authForMinglarAdmin';
|
||||||
|
import { parseQueryParams } from '@/common/utils/validation/validation.utils';
|
||||||
|
import { getHostByIdPathSchema } from '@/common/utils/validation/minglaradmin/hosthub.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
@@ -20,13 +23,8 @@ export const handler = safeHandler(async (
|
|||||||
|
|
||||||
await verifyMinglarAdminToken(token);
|
await verifyMinglarAdminToken(token);
|
||||||
|
|
||||||
const host_xid = event.pathParameters?.host_xid;
|
// Parse and validate path params using Zod
|
||||||
if (!host_xid) {
|
const { host_xid } = parseQueryParams(event.pathParameters, getHostByIdPathSchema);
|
||||||
throw new ApiError(
|
|
||||||
400,
|
|
||||||
'Host ID is required in path parameters.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const hostDetails = await minglarService.getHostDetailsById(Number(host_xid));
|
const hostDetails = await minglarService.getHostDetailsById(Number(host_xid));
|
||||||
|
|||||||
@@ -1,24 +1,18 @@
|
|||||||
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
|
import { verifyMinglarAdminToken } from '@/common/middlewares/jwt/authForMinglarAdmin';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
import { sendAMRejectionMailtoHost } from '../../../services/rejectionMailtoHost.service';
|
import { sendAMRejectionMailtoHost } from '../../../services/rejectionMailtoHost.service';
|
||||||
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { hostApplicationActionSchema } from '../../../../../common/utils/validation/minglaradmin/hosthub.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
|
|
||||||
interface AddSuggestionBody {
|
|
||||||
hostXid: number;
|
|
||||||
title: string;
|
|
||||||
comments: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add suggestion handler for host applications
|
* Reject host application handler for Account Managers
|
||||||
* Allows Minglar Admin, Co_Admin, and Account Manager to add suggestions
|
|
||||||
* Types: Setup Profile, Review Account, Add Payment Details, Agreement
|
|
||||||
*/
|
*/
|
||||||
export const handler = safeHandler(async (
|
export const handler = safeHandler(async (
|
||||||
event: APIGatewayProxyEvent,
|
event: APIGatewayProxyEvent,
|
||||||
@@ -33,16 +27,8 @@ export const handler = safeHandler(async (
|
|||||||
// Verify token and get user info
|
// Verify token and get user info
|
||||||
const userInfo = await verifyMinglarAdminToken(token);
|
const userInfo = await verifyMinglarAdminToken(token);
|
||||||
|
|
||||||
// Parse request body
|
// Parse and validate request body using Zod
|
||||||
let body: AddSuggestionBody;
|
const { hostXid } = parseBody(event.body, hostApplicationActionSchema);
|
||||||
|
|
||||||
try {
|
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (error) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { hostXid } = body;
|
|
||||||
|
|
||||||
|
|
||||||
// Add suggestion using service
|
// Add suggestion using service
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
import { verifyMinglarAdminToken } from '@/common/middlewares/jwt/authForMinglarAdmin';
|
||||||
|
import { MinglarService } from '@/modules/minglaradmin/services/minglar.service';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
|
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { rejectPqqByAmSchema } from '../../../../../common/utils/validation/minglaradmin/hosthub.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
@@ -17,16 +19,10 @@ export const handler = safeHandler(async (
|
|||||||
|
|
||||||
const userInfo = await verifyMinglarAdminToken(token);
|
const userInfo = await verifyMinglarAdminToken(token);
|
||||||
|
|
||||||
const activityId = event.pathParameters?.activityId;
|
// Parse and validate body using Zod
|
||||||
|
const { activityId } = parseBody(event.body, rejectPqqByAmSchema);
|
||||||
|
|
||||||
if (!activityId) {
|
await minglarService.rejectPQQbyAM(activityId);
|
||||||
throw new ApiError(400, 'activityId is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
await minglarService.rejectPQQbyAM(
|
|
||||||
Number(activityId),
|
|
||||||
Number(userInfo.id)
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
statusCode: 201,
|
statusCode: 201,
|
||||||
@@ -36,7 +32,7 @@ export const handler = safeHandler(async (
|
|||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
success: true,
|
success: true,
|
||||||
message: 'Rejected PQ successfully',
|
message: 'Rejected successfully',
|
||||||
data: null,
|
data: null,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
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 { sendEmailToHostForMinglarApproval } from '../../../services/approvalMailtoHost.service';
|
||||||
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { hostApplicationActionSchema } from '../../../../../common/utils/validation/minglaradmin/hosthub.validation';
|
||||||
|
|
||||||
|
const prismaService = new PrismaService();
|
||||||
|
const minglarService = new MinglarService(prismaService);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accept host application handler for Minglar Admin
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Parse and validate request body using Zod
|
||||||
|
const { hostXid } = parseBody(event.body, hostApplicationActionSchema);
|
||||||
|
|
||||||
|
|
||||||
|
// Add suggestion using service
|
||||||
|
await minglarService.acceptHostApplicationMinglarAdmin(hostXid, userInfo.id);
|
||||||
|
const hostDetails = await minglarService.getUserDetails(userInfo.id)
|
||||||
|
if (!hostDetails?.emailAddress) {
|
||||||
|
throw new ApiError(404, 'Host details or email address not found');
|
||||||
|
}
|
||||||
|
await sendEmailToHostForMinglarApproval(hostDetails.emailAddress)
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
message: 'Application accepted successfully',
|
||||||
|
data: null,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -3,20 +3,18 @@ import {
|
|||||||
APIGatewayProxyResult,
|
APIGatewayProxyResult,
|
||||||
Context,
|
Context,
|
||||||
} from 'aws-lambda';
|
} from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
|
||||||
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
|
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
|
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
|
||||||
|
import { sendAMEmailForHostAssign } from '../../../services/AMEmail.service';
|
||||||
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { assignAmToHostSchema } from '../../../../../common/utils/validation/minglaradmin/hosthub.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
|
|
||||||
interface assignAMToHostBody {
|
|
||||||
host_xid: number;
|
|
||||||
account_manager_xid: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all host applications handler
|
* Get all host applications handler
|
||||||
* Returns host details with status, submission date, and account manager info
|
* Returns host details with status, submission date, and account manager info
|
||||||
@@ -49,16 +47,11 @@ export const handler = safeHandler(
|
|||||||
throw new ApiError(404, 'User not found');
|
throw new ApiError(404, 'User not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse request body
|
// Parse and validate request body using Zod
|
||||||
let body: assignAMToHostBody;
|
const { hostXid: host_xid, accountManagerXid: account_manager_xid } = parseBody(
|
||||||
|
event.body,
|
||||||
try {
|
assignAmToHostSchema
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
);
|
||||||
} catch (error) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { host_xid, account_manager_xid } = body;
|
|
||||||
|
|
||||||
// Get all host applications from service based on user role
|
// Get all host applications from service based on user role
|
||||||
await minglarService.assignAMToHost(user.id, host_xid, account_manager_xid);
|
await minglarService.assignAMToHost(user.id, host_xid, account_manager_xid);
|
||||||
|
|||||||
@@ -1,25 +1,15 @@
|
|||||||
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
|
import { verifyOnlyMinglarAdminToken } from '@/common/middlewares/jwt/authForOnlyMinglarAdmin';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { editAgreementDetailsSchema } from '../../../../../common/utils/validation/minglaradmin/hosthub.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
|
|
||||||
interface assignAMToHostBody {
|
|
||||||
host_xid: number,
|
|
||||||
agreementStartDate: string,
|
|
||||||
duration: number,
|
|
||||||
isCommisionBase: boolean,
|
|
||||||
commisionPer: number,
|
|
||||||
amountPerBooking: number,
|
|
||||||
durationFrequency: string,
|
|
||||||
payoutDurationNum: number,
|
|
||||||
payoutDurationFrequency: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export const handler = safeHandler(async (
|
export const handler = safeHandler(async (
|
||||||
event: APIGatewayProxyEvent,
|
event: APIGatewayProxyEvent,
|
||||||
context?: Context
|
context?: Context
|
||||||
@@ -43,15 +33,7 @@ export const handler = safeHandler(async (
|
|||||||
throw new ApiError(404, 'User not found');
|
throw new ApiError(404, 'User not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse request body
|
// Parse and validate request body using Zod
|
||||||
let body: assignAMToHostBody;
|
|
||||||
|
|
||||||
try {
|
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (error) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
host_xid,
|
host_xid,
|
||||||
agreementStartDate,
|
agreementStartDate,
|
||||||
@@ -62,11 +44,10 @@ export const handler = safeHandler(async (
|
|||||||
durationFrequency,
|
durationFrequency,
|
||||||
payoutDurationNum,
|
payoutDurationNum,
|
||||||
payoutDurationFrequency
|
payoutDurationFrequency
|
||||||
} = body;
|
} = parseBody(event.body, editAgreementDetailsSchema);
|
||||||
|
|
||||||
await minglarService.acceptHostApplicationMinglarAdmin(
|
await minglarService.editAgreementDetails(
|
||||||
host_xid,
|
host_xid,
|
||||||
userInfo.id,
|
|
||||||
agreementStartDate,
|
agreementStartDate,
|
||||||
duration,
|
duration,
|
||||||
isCommisionBase,
|
isCommisionBase,
|
||||||
@@ -74,8 +55,8 @@ export const handler = safeHandler(async (
|
|||||||
amountPerBooking,
|
amountPerBooking,
|
||||||
durationFrequency,
|
durationFrequency,
|
||||||
payoutDurationNum,
|
payoutDurationNum,
|
||||||
payoutDurationFrequency);
|
payoutDurationFrequency
|
||||||
// await sendEmailToHostForMinglarApproval(hostDetails.emailAddress)
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
@@ -1,20 +1,20 @@
|
|||||||
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
|
import { verifyMinglarAdminToken } from '@/common/middlewares/jwt/authForMinglarAdmin';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { PrePopulateService } from '../../../../prepopulate/services/prepopulate.service';
|
import { PrePopulateService } from '../../../../prepopulate/services/prepopulate.service';
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
|
import { parseQueryParams } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { getHostByIdAltPathSchema } from '../../../../../common/utils/validation/minglaradmin/hosthub.validation';
|
||||||
|
import { optionalSearchQuerySchema } from '../../../../../common/utils/validation/host/activity.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
const prePopulateService = new PrePopulateService(prismaService);
|
const prePopulateService = new PrePopulateService(prismaService);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add suggestion handler for host applications
|
* Get all activities of a host handler
|
||||||
* Allows Minglar Admin, Co_Admin, and Account Manager to add suggestions
|
|
||||||
* Types: Setup Profile, Review Account, Add Payment Details, Agreement
|
|
||||||
*/
|
*/
|
||||||
export const handler = safeHandler(async (
|
export const handler = safeHandler(async (
|
||||||
event: APIGatewayProxyEvent,
|
event: APIGatewayProxyEvent,
|
||||||
@@ -29,20 +29,14 @@ export const handler = safeHandler(async (
|
|||||||
// Verify token and get user info
|
// Verify token and get user info
|
||||||
const userInfo = await verifyMinglarAdminToken(token);
|
const userInfo = await verifyMinglarAdminToken(token);
|
||||||
|
|
||||||
const hostXid = Number(event.pathParameters?.id)
|
// Parse and validate path params using Zod
|
||||||
|
const { id: hostXid } = parseQueryParams(event.pathParameters, getHostByIdAltPathSchema);
|
||||||
|
|
||||||
// Get pagination params from event
|
// Parse and validate query params using Zod
|
||||||
const paginationParams = paginationService.getPaginationFromEvent(event);
|
const { search, q } = parseQueryParams(event.queryStringParameters, optionalSearchQuerySchema);
|
||||||
const paginationOptions = paginationService.parsePaginationParams(paginationParams);
|
const searchTerm = search || q || undefined;
|
||||||
|
|
||||||
// Read optional search query (supports ?search= or ?q=)
|
const data = await minglarService.getAllHostActivityForMinglar(searchTerm, hostXid);
|
||||||
const search = event.queryStringParameters?.search || event.queryStringParameters?.q || undefined;
|
|
||||||
|
|
||||||
const result = await minglarService.getAllHostActivityForMinglar(
|
|
||||||
search ? String(search) : undefined,
|
|
||||||
hostXid,
|
|
||||||
paginationOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -54,7 +48,7 @@ export const handler = safeHandler(async (
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
success: true,
|
success: true,
|
||||||
message: 'Data retrieved successfully',
|
message: 'Data retrieved successfully',
|
||||||
...result,
|
data,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
|
import { verifyOnlyMinglarAdminToken } from '@/common/middlewares/jwt/authForOnlyMinglarAdmin';
|
||||||
import {
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
APIGatewayProxyEvent,
|
|
||||||
APIGatewayProxyResult,
|
|
||||||
Context,
|
|
||||||
} from 'aws-lambda';
|
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
|
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
@@ -17,70 +12,42 @@ const minglarService = new MinglarService(prismaService);
|
|||||||
* Get all host applications handler
|
* Get all host applications handler
|
||||||
* Returns host details with status, submission date, and account manager info
|
* Returns host details with status, submission date, and account manager info
|
||||||
*/
|
*/
|
||||||
export const handler = safeHandler(
|
export const handler = safeHandler(async (
|
||||||
async (
|
event: APIGatewayProxyEvent,
|
||||||
event: APIGatewayProxyEvent,
|
context?: Context
|
||||||
context?: Context,
|
): Promise<APIGatewayProxyResult> => {
|
||||||
): Promise<APIGatewayProxyResult> => {
|
// Verify authentication token
|
||||||
// Verify authentication token
|
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
||||||
const token =
|
if (!token) {
|
||||||
event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
throw new ApiError(401, 'This is a protected route. Please provide a valid token.');
|
||||||
if (!token) {
|
}
|
||||||
throw new ApiError(
|
|
||||||
401,
|
|
||||||
'This is a protected route. Please provide a valid token.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify token and get user info
|
// Verify token and get user info
|
||||||
const userInfo = await verifyOnlyMinglarAdminToken(token);
|
const userInfo = await verifyOnlyMinglarAdminToken(token);
|
||||||
|
|
||||||
// Get user details including role
|
// Get user details including role
|
||||||
const user = await prismaService.user.findUnique({
|
const user = await prismaService.user.findUnique({
|
||||||
where: { id: userInfo.id },
|
where: { id: userInfo.id },
|
||||||
select: { id: true, roleXid: true },
|
select: { id: true, roleXid: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new ApiError(404, 'User not found');
|
throw new ApiError(404, 'User not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract optional search query
|
// Get all host applications from service based on user role
|
||||||
const queryParams = event.queryStringParameters || {};
|
const hostApplications = await minglarService.getAllOnboardingHostApplications();
|
||||||
const search =
|
|
||||||
(queryParams.search as string) ||
|
|
||||||
(queryParams.q as string) ||
|
|
||||||
undefined;
|
|
||||||
|
|
||||||
// Pagination
|
return {
|
||||||
const paginationParams = paginationService.getPaginationFromEvent(event);
|
statusCode: 200,
|
||||||
const paginationOptions =
|
headers: {
|
||||||
paginationService.parsePaginationParams(paginationParams);
|
'Content-Type': 'application/json',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
// Get all host applications from service based on user role
|
},
|
||||||
const { data, totalCount } =
|
body: JSON.stringify({
|
||||||
await minglarService.getAllOnboardingHostApplications(
|
success: true,
|
||||||
paginationOptions,
|
message: 'Host applications retrieved successfully',
|
||||||
search,
|
data: hostApplications,
|
||||||
);
|
}),
|
||||||
|
};
|
||||||
const paginatedResponse = paginationService.createPaginatedResponse(
|
});
|
||||||
data,
|
|
||||||
totalCount,
|
|
||||||
paginationOptions,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
statusCode: 200,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Access-Control-Allow-Origin': '*',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
success: true,
|
|
||||||
message: 'Host applications retrieved successfully',
|
|
||||||
...paginatedResponse,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|||||||
@@ -1,35 +1,25 @@
|
|||||||
import {
|
|
||||||
APIGatewayProxyEvent,
|
|
||||||
APIGatewayProxyResult,
|
|
||||||
Context,
|
|
||||||
} from 'aws-lambda';
|
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
|
||||||
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
|
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 { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
|
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all NEW host applications handler
|
* Get all host applications handler
|
||||||
* Returns host details with status, submission date, and account manager info
|
* Returns host details with status, submission date, and account manager info
|
||||||
*/
|
*/
|
||||||
export const handler = safeHandler(
|
export const handler = safeHandler(async (
|
||||||
async (
|
|
||||||
event: APIGatewayProxyEvent,
|
event: APIGatewayProxyEvent,
|
||||||
context?: Context,
|
context?: Context
|
||||||
): Promise<APIGatewayProxyResult> => {
|
): Promise<APIGatewayProxyResult> => {
|
||||||
// Verify authentication token
|
// Verify authentication token
|
||||||
const token =
|
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
||||||
event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
throw new ApiError(
|
throw new ApiError(401, 'This is a protected route. Please provide a valid token.');
|
||||||
401,
|
|
||||||
'This is a protected route. Please provide a valid token.',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify token and get user info
|
// Verify token and get user info
|
||||||
@@ -37,50 +27,27 @@ export const handler = safeHandler(
|
|||||||
|
|
||||||
// Get user details including role
|
// Get user details including role
|
||||||
const user = await prismaService.user.findUnique({
|
const user = await prismaService.user.findUnique({
|
||||||
where: { id: userInfo.id },
|
where: { id: userInfo.id },
|
||||||
select: { id: true, roleXid: true },
|
select: { id: true, roleXid: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new ApiError(404, 'User not found');
|
throw new ApiError(404, 'User not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract optional search query
|
|
||||||
const queryParams = event.queryStringParameters || {};
|
|
||||||
const search =
|
|
||||||
(queryParams.search as string) ||
|
|
||||||
(queryParams.q as string) ||
|
|
||||||
undefined;
|
|
||||||
|
|
||||||
// Pagination
|
|
||||||
const paginationParams = paginationService.getPaginationFromEvent(event);
|
|
||||||
const paginationOptions =
|
|
||||||
paginationService.parsePaginationParams(paginationParams);
|
|
||||||
|
|
||||||
// Get all host applications from service based on user role
|
// Get all host applications from service based on user role
|
||||||
const { data, totalCount } =
|
const hostApplications = await minglarService.getAllOnboardingHostApplications_New();
|
||||||
await minglarService.getAllOnboardingHostApplications_New(
|
|
||||||
paginationOptions,
|
|
||||||
search,
|
|
||||||
);
|
|
||||||
|
|
||||||
const paginatedResponse = paginationService.createPaginatedResponse(
|
|
||||||
data,
|
|
||||||
totalCount,
|
|
||||||
paginationOptions,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Access-Control-Allow-Origin': '*',
|
'Access-Control-Allow-Origin': '*',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
success: true,
|
success: true,
|
||||||
message: 'Host applications retrieved successfully',
|
message: 'Host applications retrieved successfully',
|
||||||
...paginatedResponse,
|
data: hostApplications,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|||||||
@@ -1,24 +1,18 @@
|
|||||||
|
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
|
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
import { sendEmailToHostForRejectedApplication } from '../../../services/rejectionMailtoHost.service';
|
import { sendEmailToHostForRejectedApplication } from '../../../services/rejectionMailtoHost.service';
|
||||||
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { hostApplicationActionSchema } from '../../../../../common/utils/validation/minglaradmin/hosthub.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
|
|
||||||
interface AddSuggestionBody {
|
|
||||||
hostXid: number;
|
|
||||||
title: string;
|
|
||||||
comments: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add suggestion handler for host applications
|
* Reject host application handler for Minglar Admin
|
||||||
* Allows Minglar Admin, Co_Admin, and Account Manager to add suggestions
|
|
||||||
* Types: Setup Profile, Review Account, Add Payment Details, Agreement
|
|
||||||
*/
|
*/
|
||||||
export const handler = safeHandler(async (
|
export const handler = safeHandler(async (
|
||||||
event: APIGatewayProxyEvent,
|
event: APIGatewayProxyEvent,
|
||||||
@@ -33,16 +27,8 @@ export const handler = safeHandler(async (
|
|||||||
// Verify token and get user info
|
// Verify token and get user info
|
||||||
const userInfo = await verifyOnlyMinglarAdminToken(token);
|
const userInfo = await verifyOnlyMinglarAdminToken(token);
|
||||||
|
|
||||||
// Parse request body
|
// Parse and validate request body using Zod
|
||||||
let body: AddSuggestionBody;
|
const { hostXid } = parseBody(event.body, hostApplicationActionSchema);
|
||||||
|
|
||||||
try {
|
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (error) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { hostXid } = body;
|
|
||||||
|
|
||||||
|
|
||||||
// Add suggestion using service
|
// Add suggestion using service
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
|
||||||
import { verifyMinglarAdminHostToken } from '../../../../../common/middlewares/jwt/authForMinglarAdminHost';
|
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
|
||||||
const minglarService = new MinglarService(prismaService);
|
|
||||||
|
|
||||||
export const handler = safeHandler(async (
|
|
||||||
event: APIGatewayProxyEvent,
|
|
||||||
context?: Context
|
|
||||||
): Promise<APIGatewayProxyResult> => {
|
|
||||||
// Get host ID from path parameters
|
|
||||||
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.');
|
|
||||||
}
|
|
||||||
|
|
||||||
await verifyMinglarAdminHostToken(token);
|
|
||||||
|
|
||||||
const activityXid = event.pathParameters?.activityXid;
|
|
||||||
if (!activityXid) {
|
|
||||||
throw new ApiError(
|
|
||||||
400,
|
|
||||||
'Host ID is required in path parameters.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const pqpDetails = await minglarService.getAllPQPDetailsForAM(Number(activityXid));
|
|
||||||
|
|
||||||
if (!pqpDetails) {
|
|
||||||
throw new ApiError(404, 'Record not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
statusCode: 200,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Access-Control-Allow-Origin': '*',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
success: true,
|
|
||||||
message: 'PQ details retrieved successfully',
|
|
||||||
data: pqpDetails,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
@@ -5,6 +5,8 @@ import ApiError from '../../../common/utils/helper/ApiError';
|
|||||||
import { GetMinglarLoginResponseDTO } from '../dto/minglar.dto';
|
import { GetMinglarLoginResponseDTO } from '../dto/minglar.dto';
|
||||||
import { MinglarService } from '../services/minglar.service';
|
import { MinglarService } from '../services/minglar.service';
|
||||||
import { TokenService } from "../services/token.service";
|
import { TokenService } from "../services/token.service";
|
||||||
|
import { parseBody } from '../../../common/utils/validation/validation.utils';
|
||||||
|
import { minglarLoginSchema } from '../../../common/utils/validation/minglaradmin/auth.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarSerivce = new MinglarService(prismaService);
|
const minglarSerivce = new MinglarService(prismaService);
|
||||||
@@ -14,22 +16,10 @@ export const handler = safeHandler(async (
|
|||||||
event: APIGatewayProxyEvent,
|
event: APIGatewayProxyEvent,
|
||||||
context?: Context
|
context?: Context
|
||||||
): Promise<APIGatewayProxyResult> => {
|
): Promise<APIGatewayProxyResult> => {
|
||||||
// Parse request body
|
// Parse and validate request body using Zod
|
||||||
let body: { emailAddress?: string; userPassword?: string };
|
const { emailAddress, userPassword } = parseBody(event.body, minglarLoginSchema);
|
||||||
|
|
||||||
try {
|
const loginForMinglar = await minglarSerivce.loginForMinglar(emailAddress, userPassword);
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (error) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { emailAddress ,userPassword} = body;
|
|
||||||
|
|
||||||
if (!emailAddress) {
|
|
||||||
throw new ApiError(400, 'Email is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
const loginForMinglar = await minglarSerivce.loginForMinglar(emailAddress ,userPassword);
|
|
||||||
|
|
||||||
if (!loginForMinglar) {
|
if (!loginForMinglar) {
|
||||||
throw new ApiError(400, 'Failed to login');
|
throw new ApiError(400, 'Failed to login');
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import {
|
|||||||
APIGatewayProxyResult,
|
APIGatewayProxyResult,
|
||||||
Context,
|
Context,
|
||||||
} from 'aws-lambda';
|
} from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../common/database/prisma.service';
|
|
||||||
import { verifyMinglarAdminToken } from '../../../common/middlewares/jwt/authForMinglarAdmin';
|
|
||||||
import { ROLE } from '../../../common/utils/constants/common.constant';
|
|
||||||
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
||||||
|
import { PrismaService } from '../../../common/database/prisma.service';
|
||||||
import ApiError from '../../../common/utils/helper/ApiError';
|
import ApiError from '../../../common/utils/helper/ApiError';
|
||||||
|
import { ROLE } from '../../../common/utils/constants/common.constant';
|
||||||
|
import { verifyMinglarAdminToken } from '../../../common/middlewares/jwt/authForMinglarAdmin';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
export const handler = safeHandler(
|
export const handler = safeHandler(
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
import { ROLE, USER_STATUS } from '../../../common/utils/constants/common.constant';
|
import { ROLE, USER_STATUS } from '@/common/utils/constants/common.constant';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../common/database/prisma.service';
|
import { PrismaService } from '../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../common/utils/helper/ApiError';
|
import ApiError from '../../../common/utils/helper/ApiError';
|
||||||
import { generateOtpHelper } from '../../../common/utils/helper/sendOtp';
|
import { generateOtpHelper } from '../../../common/utils/helper/sendOtp';
|
||||||
|
import { sendOtpEmailForMinglarAdmin } from '../services/sendOTPEmail.service';
|
||||||
import { MinglarService } from './../services/minglar.service';
|
import { MinglarService } from './../services/minglar.service';
|
||||||
|
import { parseBody } from '../../../common/utils/validation/validation.utils';
|
||||||
|
import { minglarRegistrationSchema } from '../../../common/utils/validation/minglaradmin/auth.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
@@ -13,20 +16,8 @@ export const handler = safeHandler(async (
|
|||||||
event: APIGatewayProxyEvent,
|
event: APIGatewayProxyEvent,
|
||||||
context?: Context
|
context?: Context
|
||||||
): Promise<APIGatewayProxyResult> => {
|
): Promise<APIGatewayProxyResult> => {
|
||||||
// Parse request body
|
// Parse and validate request body using Zod
|
||||||
let body: { email?: string };
|
const { email } = parseBody(event.body, minglarRegistrationSchema);
|
||||||
|
|
||||||
try {
|
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (error) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { email } = body;
|
|
||||||
|
|
||||||
if (!email) {
|
|
||||||
throw new ApiError(400, 'Email is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = await prismaService.user.findUnique({
|
const user = await prismaService.user.findUnique({
|
||||||
where: { emailAddress: email, isActive: true, userStatus: USER_STATUS.INVITED },
|
where: { emailAddress: email, isActive: true, userStatus: USER_STATUS.INVITED },
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
|
import { verifyOnlyMinglarAdminToken } from '@/common/middlewares/jwt/authForOnlyMinglarAdmin';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
|
import { parseQueryParams } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { getAllCoadminAndAMQuerySchema } from '../../../../../common/utils/validation/minglaradmin/teammate.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
@@ -21,8 +23,8 @@ export const handler = safeHandler(async (
|
|||||||
// Authenticate user using the shared authForHost function
|
// Authenticate user using the shared authForHost function
|
||||||
await verifyOnlyMinglarAdminToken(token);
|
await verifyOnlyMinglarAdminToken(token);
|
||||||
|
|
||||||
// Extract search parameter from query string
|
// Parse and validate query params using Zod
|
||||||
const search = event.queryStringParameters?.search || '';
|
const { search } = parseQueryParams(event.queryStringParameters, getAllCoadminAndAMQuerySchema);
|
||||||
|
|
||||||
const response = await minglarService.getAllCoadminAndAM(search);
|
const response = await minglarService.getAllCoadminAndAM(search);
|
||||||
|
|
||||||
|
|||||||
@@ -1,65 +1,44 @@
|
|||||||
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
|
import { verifyOnlyMinglarAdminToken } from '@/common/middlewares/jwt/authForOnlyMinglarAdmin';
|
||||||
import {
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
APIGatewayProxyEvent,
|
|
||||||
APIGatewayProxyResult,
|
|
||||||
Context,
|
|
||||||
} from 'aws-lambda';
|
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
|
import { parseQueryParams } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { getInvitationDetailsQuerySchema } from '../../../../../common/utils/validation/minglaradmin/teammate.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
|
|
||||||
export const handler = safeHandler(
|
export const handler = safeHandler(async (
|
||||||
async (
|
event: APIGatewayProxyEvent,
|
||||||
event: APIGatewayProxyEvent,
|
context?: Context
|
||||||
context?: Context,
|
): Promise<APIGatewayProxyResult> => {
|
||||||
): Promise<APIGatewayProxyResult> => {
|
// Extract token from headers
|
||||||
// Extract token from headers
|
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token']
|
||||||
const token =
|
if(!token) {
|
||||||
event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
throw new ApiError(400, 'This is a protected route. Please provide a valid token.');
|
||||||
if (!token) {
|
}
|
||||||
throw new ApiError(
|
|
||||||
400,
|
|
||||||
'This is a protected route. Please provide a valid token.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Authenticate user using the shared authForHost function
|
// Authenticate user using the shared authForHost function
|
||||||
await verifyOnlyMinglarAdminToken(token);
|
await verifyOnlyMinglarAdminToken(token);
|
||||||
|
|
||||||
// Extract search parameter from query string
|
// Parse and validate query params using Zod
|
||||||
const search = event.queryStringParameters?.search || '';
|
const { search } = parseQueryParams(event.queryStringParameters, getInvitationDetailsQuerySchema);
|
||||||
|
|
||||||
const paginationParams = paginationService.getPaginationFromEvent(event);
|
const result = await minglarService.getAllInvitationDetails(search);
|
||||||
const paginationOptions =
|
|
||||||
paginationService.parsePaginationParams(paginationParams);
|
|
||||||
|
|
||||||
const { data, totalCount } = await minglarService.getAllInvitationDetails(
|
return {
|
||||||
search,
|
statusCode: 200,
|
||||||
paginationOptions,
|
headers: {
|
||||||
);
|
'Content-Type': 'application/json',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
message: 'Data retrieved successfully',
|
||||||
|
data: result,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const paginatedResponse = paginationService.createPaginatedResponse(
|
|
||||||
data,
|
|
||||||
totalCount,
|
|
||||||
paginationOptions,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
statusCode: 200,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Access-Control-Allow-Origin': '*',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
success: true,
|
|
||||||
message: 'Data retrieved successfully',
|
|
||||||
...paginatedResponse,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|||||||
@@ -1,64 +1,44 @@
|
|||||||
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
|
import { verifyOnlyMinglarAdminToken } from '@/common/middlewares/jwt/authForOnlyMinglarAdmin';
|
||||||
import {
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
APIGatewayProxyEvent,
|
|
||||||
APIGatewayProxyResult,
|
|
||||||
Context,
|
|
||||||
} from 'aws-lambda';
|
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
|
import { parseQueryParams } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { getAllInvitedCoadminAndAMQuerySchema } from '../../../../../common/utils/validation/minglaradmin/teammate.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
|
|
||||||
export const handler = safeHandler(
|
export const handler = safeHandler(async (
|
||||||
async (
|
event: APIGatewayProxyEvent,
|
||||||
event: APIGatewayProxyEvent,
|
context?: Context
|
||||||
context?: Context,
|
): Promise<APIGatewayProxyResult> => {
|
||||||
): Promise<APIGatewayProxyResult> => {
|
// Extract token from headers
|
||||||
// Extract token from headers
|
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token']
|
||||||
const token =
|
if(!token) {
|
||||||
event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
throw new ApiError(400, 'This is a protected route. Please provide a valid token.');
|
||||||
if (!token) {
|
}
|
||||||
throw new ApiError(
|
|
||||||
400,
|
|
||||||
'This is a protected route. Please provide a valid token.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Authenticate user using the shared authForHost function
|
// Authenticate user using the shared authForHost function
|
||||||
await verifyOnlyMinglarAdminToken(token);
|
await verifyOnlyMinglarAdminToken(token);
|
||||||
|
|
||||||
// Extract search parameter from query string
|
// Parse and validate query params using Zod
|
||||||
const search = event.queryStringParameters?.search || '';
|
const { search } = parseQueryParams(event.queryStringParameters, getAllInvitedCoadminAndAMQuerySchema);
|
||||||
|
|
||||||
// Pagination
|
const response = await minglarService.getAllInvitedCoadminAndAM(search);
|
||||||
const paginationParams = paginationService.getPaginationFromEvent(event);
|
|
||||||
const paginationOptions =
|
|
||||||
paginationService.parsePaginationParams(paginationParams);
|
|
||||||
|
|
||||||
const { data, totalCount } =
|
return {
|
||||||
await minglarService.getAllInvitedCoadminAndAM(search, paginationOptions);
|
statusCode: 200,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
message: 'Data retrieved successfully',
|
||||||
|
data: response,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const paginatedResponse = paginationService.createPaginatedResponse(
|
|
||||||
data,
|
|
||||||
totalCount,
|
|
||||||
paginationOptions,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
statusCode: 200,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Access-Control-Allow-Origin': '*',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
success: true,
|
|
||||||
message: 'Data retrieved successfully',
|
|
||||||
...paginatedResponse,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
);
|
|
||||||
@@ -1,22 +1,16 @@
|
|||||||
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
|
import { verifyOnlyMinglarAdminToken } from '@/common/middlewares/jwt/authForOnlyMinglarAdmin';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../../../common/database/prisma.service';
|
import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||||
import { ROLE } from '../../../../../common/utils/constants/common.constant';
|
|
||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { sendInvitationEmailForMinglarAdmin } from '../../../services/inviteTeammatesEmail.service';
|
import { sendInvitationEmailForMinglarAdmin } from '../../../services/inviteTeammatesEmail.service';
|
||||||
import { MinglarService } from '../../../services/minglar.service';
|
import { MinglarService } from '../../../services/minglar.service';
|
||||||
|
import { parseBody } from '../../../../../common/utils/validation/validation.utils';
|
||||||
|
import { inviteTeammateSchema } from '../../../../../common/utils/validation/minglaradmin/teammate.validation';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const minglarService = new MinglarService(prismaService);
|
const minglarService = new MinglarService(prismaService);
|
||||||
|
|
||||||
interface InviteTeammateBody {
|
|
||||||
emailAddress: string;
|
|
||||||
roleXid: number;
|
|
||||||
isFixedSalary: boolean;
|
|
||||||
perValue?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invite teammate handler
|
* Invite teammate handler
|
||||||
* Only accessible by MINGLAR_ADMIN (role_xid = 1)
|
* Only accessible by MINGLAR_ADMIN (role_xid = 1)
|
||||||
@@ -36,46 +30,13 @@ export const handler = safeHandler(async (
|
|||||||
// Verify token and get user info
|
// Verify token and get user info
|
||||||
const userInfo = await verifyOnlyMinglarAdminToken(token);
|
const userInfo = await verifyOnlyMinglarAdminToken(token);
|
||||||
|
|
||||||
// Parse request body
|
// Parse and validate request body using Zod
|
||||||
let body: InviteTeammateBody;
|
|
||||||
|
|
||||||
try {
|
|
||||||
body = event.body ? JSON.parse(event.body) : {};
|
|
||||||
} catch (error) {
|
|
||||||
throw new ApiError(400, 'Invalid JSON in request body');
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
emailAddress,
|
emailAddress,
|
||||||
roleXid,
|
roleXid,
|
||||||
isFixedSalary,
|
isFixedSalary,
|
||||||
perValue
|
perValue
|
||||||
} = body;
|
} = parseBody(event.body, inviteTeammateSchema);
|
||||||
|
|
||||||
// Validate required fields
|
|
||||||
if (!emailAddress) {
|
|
||||||
throw new ApiError(400, 'Email address is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!roleXid) {
|
|
||||||
throw new ApiError(400, 'Role is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate role is either Co_Admin or Account_Manager
|
|
||||||
if (![ROLE.CO_ADMIN, ROLE.ACCOUNT_MANAGER].includes(roleXid)) {
|
|
||||||
throw new ApiError(400, 'Invalid role. Only Co_Admin and Account_Manager roles can be assigned.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate revenue details
|
|
||||||
if (ROLE.ACCOUNT_MANAGER === roleXid) {
|
|
||||||
if (!isFixedSalary && !perValue) {
|
|
||||||
throw new ApiError(400, 'Revenue details are required');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (perValue && perValue <= 0) {
|
|
||||||
throw new ApiError(400, 'Per value must be greater than 0');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use single service method that encapsulates the transaction
|
// Use single service method that encapsulates the transaction
|
||||||
await minglarService.inviteTeammate(
|
await minglarService.inviteTeammate(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// modules/minglar/handlers/updateProfile.ts
|
// modules/minglar/handlers/updateProfile.ts
|
||||||
import config from '../../../config/config';
|
import config from '@/config/config';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import AWS from 'aws-sdk';
|
import AWS from 'aws-sdk';
|
||||||
import { PrismaService } from '../../../common/database/prisma.service';
|
import { PrismaService } from '../../../common/database/prisma.service';
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,10 @@
|
|||||||
import { verifyMinglarAdminHostToken } from '../../../common/middlewares/jwt/authForMinglarAdminHost';
|
import { verifyOnlyMinglarAdminToken } from '@/common/middlewares/jwt/authForOnlyMinglarAdmin';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../common/database/prisma.service';
|
import { PrismaService } from '../../../common/database/prisma.service';
|
||||||
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../common/utils/helper/ApiError';
|
import ApiError from '../../../common/utils/helper/ApiError';
|
||||||
import { PrePopulateService } from '../services/prepopulate.service';
|
import { PrePopulateService } from '../services/prepopulate.service';
|
||||||
|
import { verifyHostToken } from '@/common/middlewares/jwt/authForHost';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const prePopulateService = new PrePopulateService(prismaService);
|
const prePopulateService = new PrePopulateService(prismaService);
|
||||||
@@ -19,7 +20,7 @@ export const handler = safeHandler(async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Authenticate user using the shared authForHost function
|
// Authenticate user using the shared authForHost function
|
||||||
await verifyMinglarAdminHostToken(token);
|
await verifyHostToken(token);
|
||||||
|
|
||||||
const bankDetails = await prePopulateService.getAllBankDetails();
|
const bankDetails = await prePopulateService.getAllBankDetails();
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import { verifyMinglarAdminHostToken } from '@/common/middlewares/jwt/authForMinglarAdmin&Host';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../common/database/prisma.service';
|
import { PrismaService } from '../../../common/database/prisma.service';
|
||||||
import { verifyMinglarAdminHostToken } from '../../../common/middlewares/jwt/authForMinglarAdminHost';
|
|
||||||
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../common/utils/helper/ApiError';
|
import ApiError from '../../../common/utils/helper/ApiError';
|
||||||
import { PrePopulateService } from '../services/prepopulate.service';
|
import { PrePopulateService } from '../services/prepopulate.service';
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
import { verifyOnlyMinglarAdminToken } from '@/common/middlewares/jwt/authForOnlyMinglarAdmin';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../common/database/prisma.service';
|
import { PrismaService } from '../../../common/database/prisma.service';
|
||||||
import { verifyMinglarAdminHostToken } from '../../../common/middlewares/jwt/authForMinglarAdminHost';
|
|
||||||
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../common/utils/helper/ApiError';
|
import ApiError from '../../../common/utils/helper/ApiError';
|
||||||
import { PrePopulateService } from '../services/prepopulate.service';
|
import { PrePopulateService } from '../services/prepopulate.service';
|
||||||
|
import { verifyHostToken } from '@/common/middlewares/jwt/authForHost';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const prePopulateService = new PrePopulateService(prismaService);
|
const prePopulateService = new PrePopulateService(prismaService);
|
||||||
@@ -19,7 +20,7 @@ export const handler = safeHandler(async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Authenticate user using the shared authForHost function
|
// Authenticate user using the shared authForHost function
|
||||||
await verifyMinglarAdminHostToken(token);
|
await verifyHostToken(token);
|
||||||
|
|
||||||
const result = await prePopulateService.getAllFrequencies();
|
const result = await prePopulateService.getAllFrequencies();
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
import { verifyOnlyMinglarAdminToken } from '@/common/middlewares/jwt/authForOnlyMinglarAdmin';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
import { PrismaService } from '../../../common/database/prisma.service';
|
import { PrismaService } from '../../../common/database/prisma.service';
|
||||||
import { verifyMinglarAdminHostToken } from '../../../common/middlewares/jwt/authForMinglarAdminHost';
|
|
||||||
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../common/utils/helper/ApiError';
|
import ApiError from '../../../common/utils/helper/ApiError';
|
||||||
import { PrePopulateService } from '../services/prepopulate.service';
|
import { PrePopulateService } from '../services/prepopulate.service';
|
||||||
|
import { verifyHostToken } from '@/common/middlewares/jwt/authForHost';
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const prePopulateService = new PrePopulateService(prismaService);
|
const prePopulateService = new PrePopulateService(prismaService);
|
||||||
@@ -19,7 +20,7 @@ export const handler = safeHandler(async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Authenticate user using the shared authForHost function
|
// Authenticate user using the shared authForHost function
|
||||||
await verifyMinglarAdminHostToken(token);
|
await verifyHostToken(token);
|
||||||
|
|
||||||
const result = await prePopulateService.getAllPQQQuesAndAns();
|
const result = await prePopulateService.getAllPQQQuesAndAns();
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from "aws-lambda";
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from "aws-lambda";
|
||||||
import { PrismaService } from "../../../common/database/prisma.service";
|
import { PrismaService } from "../../../common/database/prisma.service";
|
||||||
import { verifyMinglarAdminHostToken } from "../../../common/middlewares/jwt/authForMinglarAdminHost";
|
|
||||||
import { safeHandler } from "../../../common/utils/handlers/safeHandler";
|
import { safeHandler } from "../../../common/utils/handlers/safeHandler";
|
||||||
import ApiError from "../../../common/utils/helper/ApiError";
|
import ApiError from "../../../common/utils/helper/ApiError";
|
||||||
import { PrePopulateService } from "../services/prepopulate.service";
|
import { PrePopulateService } from "../services/prepopulate.service";
|
||||||
|
import { verifyHostToken } from "@/common/middlewares/jwt/authForHost";
|
||||||
|
import { parseQueryParams } from "../../../common/utils/validation/validation.utils";
|
||||||
|
import { getBankBranchesByBankIdQuerySchema } from "../../../common/utils/validation/prepopulate/prepopulate.validation";
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const prePopulateService = new PrePopulateService(prismaService);
|
const prePopulateService = new PrePopulateService(prismaService);
|
||||||
@@ -26,14 +28,13 @@ export const handler = safeHandler(async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2) Authenticate user
|
// 2) Authenticate user
|
||||||
await verifyMinglarAdminHostToken(token);
|
await verifyHostToken(token);
|
||||||
|
|
||||||
// 3) Get bankXid from query params
|
// 3) Parse and validate query params using Zod
|
||||||
const bankXid = Number(event.queryStringParameters?.bankXid);
|
const { bankXid } = parseQueryParams(
|
||||||
|
event.queryStringParameters,
|
||||||
if (!bankXid || isNaN(bankXid)) {
|
getBankBranchesByBankIdQuerySchema
|
||||||
throw new ApiError(400, "Valid bankXid is required in query params.");
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// 4) Fetch branches for the bank
|
// 4) Fetch branches for the bank
|
||||||
const branches = await prePopulateService.getBankBranchesByBankId(bankXid);
|
const branches = await prePopulateService.getBankBranchesByBankId(bankXid);
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
import { verifyMinglarAdminHostToken } from '../../../common/middlewares/jwt/authForMinglarAdmin&Host';
|
||||||
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from "aws-lambda";
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from "aws-lambda";
|
||||||
import { PrismaService } from "../../../common/database/prisma.service";
|
import { PrismaService } from "../../../common/database/prisma.service";
|
||||||
import { verifyMinglarAdminHostToken } from "../../../common/middlewares/jwt/authForMinglarAdminHost";
|
|
||||||
import { safeHandler } from "../../../common/utils/handlers/safeHandler";
|
import { safeHandler } from "../../../common/utils/handlers/safeHandler";
|
||||||
import ApiError from "../../../common/utils/helper/ApiError";
|
import ApiError from "../../../common/utils/helper/ApiError";
|
||||||
import { PrePopulateService } from "../services/prepopulate.service";
|
import { PrePopulateService } from "../services/prepopulate.service";
|
||||||
|
import { parseQueryParams } from "../../../common/utils/validation/validation.utils";
|
||||||
|
import { getCityByStateIdQuerySchema } from "../../../common/utils/validation/prepopulate/prepopulate.validation";
|
||||||
|
|
||||||
const prismaService = new PrismaService();
|
const prismaService = new PrismaService();
|
||||||
const prePopulateService = new PrePopulateService(prismaService);
|
const prePopulateService = new PrePopulateService(prismaService);
|
||||||
@@ -28,14 +30,13 @@ export const handler = safeHandler(async (
|
|||||||
// 2) Authenticate user
|
// 2) Authenticate user
|
||||||
await verifyMinglarAdminHostToken(token);
|
await verifyMinglarAdminHostToken(token);
|
||||||
|
|
||||||
// 3) Get bankXid from query params
|
// 3) Parse and validate query params using Zod
|
||||||
const stateXid = Number(event.queryStringParameters?.stateXid);
|
const { stateXid } = parseQueryParams(
|
||||||
|
event.queryStringParameters,
|
||||||
|
getCityByStateIdQuerySchema
|
||||||
|
);
|
||||||
|
|
||||||
if (!stateXid || isNaN(stateXid)) {
|
// 4) Fetch cities for the state
|
||||||
throw new ApiError(400, "Valid stateXid is required in query params.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4) Fetch branches for the bank
|
|
||||||
const branches = await prePopulateService.getCityByStateId(stateXid);
|
const branches = await prePopulateService.getCityByStateId(stateXid);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -11,11 +11,15 @@ export class PrePopulateService {
|
|||||||
isActive: true,
|
isActive: true,
|
||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
},
|
},
|
||||||
select: {
|
include: {
|
||||||
id: true,
|
BankBranches: {
|
||||||
bankName: true,
|
select: {
|
||||||
|
id: true,
|
||||||
|
branchAddress: true,
|
||||||
|
ifscCode: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
orderBy: { bankName: 'asc' }
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,6 +28,7 @@ export class PrePopulateService {
|
|||||||
where: {
|
where: {
|
||||||
bankXid,
|
bankXid,
|
||||||
isActive: true,
|
isActive: true,
|
||||||
|
deletedAt: null
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
@@ -55,60 +60,37 @@ export class PrePopulateService {
|
|||||||
isActive: true,
|
isActive: true,
|
||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
},
|
},
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
currencyName: true,
|
|
||||||
currencySymbol: true,
|
|
||||||
},
|
|
||||||
orderBy: { currencyName: 'asc' }
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAllPQQQuesAndAns() {
|
async getAllPQQQuesAndAns() {
|
||||||
return await this.prisma.pQQCategories.findMany({
|
return await this.prisma.pQQCategories.findMany({
|
||||||
where: { isActive: true },
|
where: { isActive: true },
|
||||||
select: {
|
include: {
|
||||||
id: true,
|
|
||||||
categoryName: true,
|
|
||||||
displayOrder: true,
|
|
||||||
pqqsubCategories: {
|
pqqsubCategories: {
|
||||||
where: { isActive: true },
|
include: {
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
subCategoryName: true,
|
|
||||||
categoryXid: true,
|
|
||||||
displayOrder: true,
|
|
||||||
questions: {
|
questions: {
|
||||||
where: { isActive: true },
|
include: {
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
questionName: true,
|
|
||||||
maxPoints: true,
|
|
||||||
displayOrder: true,
|
|
||||||
PQQAnswers: {
|
PQQAnswers: {
|
||||||
where: { isActive: true },
|
orderBy: {
|
||||||
orderBy: { displayOrder: 'asc' },
|
displayOrder: 'asc'
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
answerName: true,
|
|
||||||
answerPoints: true,
|
|
||||||
displayOrder: true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
orderBy: { displayOrder: 'asc' }
|
orderBy: {
|
||||||
},
|
displayOrder: 'asc'
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
orderBy: { displayOrder: 'asc' },
|
orderBy: { displayOrder: 'asc' }
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
orderBy: { displayOrder: 'asc' },
|
orderBy: { displayOrder: 'asc' }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async getAllDocumentTypeWithCountryStateCity() {
|
async getAllDocumentTypeWithCountryStateCity() {
|
||||||
const [documentDetails, countryDetails, stateDetails, companyTypeDetails] =
|
const [documentDetails, countryDetails, stateDetails] =
|
||||||
await this.prisma.$transaction([
|
await this.prisma.$transaction([
|
||||||
this.prisma.documentType.findMany({
|
this.prisma.documentType.findMany({
|
||||||
where: { isActive: true, isVisible: true },
|
where: { isActive: true, isVisible: true },
|
||||||
@@ -119,15 +101,10 @@ export class PrePopulateService {
|
|||||||
}),
|
}),
|
||||||
this.prisma.states.findMany({
|
this.prisma.states.findMany({
|
||||||
where: { isActive: true },
|
where: { isActive: true },
|
||||||
orderBy: { stateName: 'asc' }
|
|
||||||
}),
|
|
||||||
this.prisma.companyTypes.findMany({
|
|
||||||
where: { isActive: true },
|
|
||||||
orderBy: { companyTypeName: 'asc' }
|
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return { documentDetails, countryDetails, stateDetails, companyTypeDetails };
|
return { documentDetails, countryDetails, stateDetails };
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAllFrequencies() {
|
async getAllFrequencies() {
|
||||||
|
|||||||
@@ -17,11 +17,10 @@ async function testStepperHandler() {
|
|||||||
const hostUser = await prisma.user.findFirst({
|
const hostUser = await prisma.user.findFirst({
|
||||||
where: { roleXid: 4 },
|
where: { roleXid: 4 },
|
||||||
include: {
|
include: {
|
||||||
HostHeader: {
|
hostHeaders: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
stepper: true,
|
stepper: true,
|
||||||
hostRefNumber: true,
|
|
||||||
companyName: true,
|
companyName: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -33,20 +32,19 @@ async function testStepperHandler() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hostUser.HostHeader || hostUser.HostHeader.length === 0) {
|
if (!hostUser.hostHeaders || hostUser.hostHeaders.length === 0) {
|
||||||
console.log('⚠️ Host user found but no HostHeader records.');
|
console.log('⚠️ Host user found but no HostHeader records.');
|
||||||
console.log(` User ID: ${hostUser.id}, Email: ${hostUser.emailAddress}`);
|
console.log(` User ID: ${hostUser.id}, Email: ${hostUser.emailAddress}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hostHeader = hostUser.HostHeader[0];
|
const hostHeader = hostUser.hostHeaders[0];
|
||||||
console.log(`✅ Found host user and HostHeader\n`);
|
console.log(`✅ Found host user and HostHeader\n`);
|
||||||
console.log(` User ID: ${hostUser.id}`);
|
console.log(` User ID: ${hostUser.id}`);
|
||||||
console.log(` Email: ${hostUser.emailAddress}`);
|
console.log(` Email: ${hostUser.emailAddress}`);
|
||||||
console.log(` First Name: ${hostUser.firstName}`);
|
console.log(` First Name: ${hostUser.firstName}`);
|
||||||
console.log(` Host ID: ${hostHeader.id}`);
|
console.log(` Host ID: ${hostHeader.id}`);
|
||||||
console.log(` Company: ${hostHeader.companyName}`);
|
console.log(` Company: ${hostHeader.companyName}`);
|
||||||
console.log(` Ref Number: ${hostHeader.hostRefNumber}`);
|
|
||||||
console.log(` Current Stepper: ${hostHeader.stepper}\n`);
|
console.log(` Current Stepper: ${hostHeader.stepper}\n`);
|
||||||
|
|
||||||
// 2. Simulate what the handler returns
|
// 2. Simulate what the handler returns
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
|||||||
{"code":"__filename=\"D:\\\\Minglar Backend NestJS\\\\src\\\\modules\\\\minglaradmin\\\\handlers\\\\getAmDetail_ById.ts\";(()=>{\nvar __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from===\"object\"||typeof from===\"function\"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,\"default\",{value:mod,enumerable:true}):target,mod));var __toCommonJS=mod=>__copyProps(__defProp({},\"__esModule\",{value:true}),mod);var getAmDetail_ById_exports={};__export(getAmDetail_ById_exports,{handler:()=>handler});module.exports=__toCommonJS(getAmDetail_ById_exports);var import_safeHandler=require(\"../../../common/utils/handlers/safeHandler\");var import_prisma=require(\"../../../common/database/prisma.service\");var import_minglar=require(\"../services/minglar.service\");var import_ApiError=__toESM(require(\"../../../common/utils/helper/ApiError\"));var import_authForMinglarAdmin=require(\"../../../common/middlewares/jwt/authForMinglarAdmin\");const prismaService=new import_prisma.PrismaService;const minglarService=new import_minglar.MinglarService(prismaService);const handler=(0,import_safeHandler.safeHandler)(async(event,context)=>{const token=event.headers[\"x-auth-token\"]||event.headers[\"X-Auth-Token\"];if(!token){throw new import_ApiError.default(401,\"This is a protected route. Please provide a valid token.\")}await(0,import_authForMinglarAdmin.verifyMinglarAdminToken)(token);const amXid=event.pathParameters?.amXid;if(!amXid){throw new import_ApiError.default(400,\"Account Manager XID is required in path parameters.\")}const amId=Number(amXid);if(Number.isNaN(amId)){throw new import_ApiError.default(400,\"Account Manager XID must be a valid number.\")}const getAmDetailsByid=await minglarService.getAMdetailById(amId);return{statusCode:200,headers:{\"Content-Type\":\"application/json\",\"Access-Control-Allow-Origin\":\"*\"},body:JSON.stringify({success:true,message:\"Host applications retrieved successfully\",data:getAmDetailsByid})}});0&&(module.exports={handler});\n})()\n","warnings":[],"map":{"version":3,"mappings":";m6BAAA,+IAKA,uBAA4B,sDAC5B,kBAA8B,mDAC9B,mBAA+B,uCAC/B,oBAAqB,0DACrB,+BAAwC,+DAExC,MAAM,cAAgB,IAAI,4BAC1B,MAAM,eAAiB,IAAI,8BAAe,aAAa,EAMhD,MAAM,WAAU,gCACrB,MACE,MACA,UACmC,CAEnC,MAAM,MACJ,MAAM,QAAQ,cAAc,GAAK,MAAM,QAAQ,cAAc,EAC/D,GAAI,CAAC,MAAO,CACV,MAAM,IAAI,gBAAAA,QACR,IACA,0DACF,CACF,CAEA,QAAM,oDAAwB,KAAK,EAEnC,MAAM,MAAQ,MAAM,gBAAgB,MACpC,GAAI,CAAC,MAAO,CACV,MAAM,IAAI,gBAAAA,QACR,IACA,qDACF,CACF,CAEA,MAAM,KAAO,OAAO,KAAK,EACzB,GAAI,OAAO,MAAM,IAAI,EAAG,CACtB,MAAM,IAAI,gBAAAA,QAAS,IAAK,6CAA6C,CACvE,CAIA,MAAM,iBAAmB,MAAM,eAAe,gBAAiB,IAAK,EAEpE,MAAO,CACL,WAAY,IACZ,QAAS,CACP,eAAgB,mBAChB,8BAA+B,GACjC,EACA,KAAM,KAAK,UAAU,CACnB,QAAS,KACT,QAAS,2CACT,KAAM,gBACR,CAAC,CACH,CACF,CACF","names":["ApiError"],"ignoreList":[],"sources":["D:\\Minglar Backend NestJS\\src\\modules\\minglaradmin\\handlers\\getAmDetail_ById.ts"],"sourcesContent":[null]}}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"code":"__filename=\"D:\\\\Minglar Backend NestJS\\\\src\\\\modules\\\\minglaradmin\\\\services\\\\AMEmail.service.ts\";(()=>{\nvar __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __name=(target,value)=>__defProp(target,\"name\",{value,configurable:true});var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from===\"object\"||typeof from===\"function\"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,\"default\",{value:mod,enumerable:true}):target,mod));var __toCommonJS=mod=>__copyProps(__defProp({},\"__esModule\",{value:true}),mod);var AMEmail_service_exports={};__export(AMEmail_service_exports,{sendAMEmailForHostAssign:()=>sendAMEmailForHostAssign});module.exports=__toCommonJS(AMEmail_service_exports);var import_brevoApi=require(\"@/common/email/brevoApi\");var import_ApiError=__toESM(require(\"@/common/utils/helper/ApiError\"));async function sendAMEmailForHostAssign(emailAddress){const subject=\"Minglar Admin: Host Assignment Notification\";const htmlContent=`\n <p>Hi,</p>\n\n <p>You\\u2019ve been assigned the <strong>Host</strong> role by Minglar Admin.</p>\n\n <p>Best regards,<br/>Minglar Admin Team</p>\n `;try{const result=await import_brevoApi.brevoService.sendEmail({recipients:[{email:emailAddress}],subject,htmlContent});console.log(\"\\u{1F4E7} Email sent successfully:\",result);return{sent:true}}catch(err){console.error(\"Brevo email send failed:\",err);throw new import_ApiError.default(500,\"Failed to send invitation via email.\")}}__name(sendAMEmailForHostAssign,\"sendAMEmailForHostAssign\");0&&(module.exports={sendAMEmailForHostAssign});\n})()\n","warnings":[],"map":{"version":3,"mappings":";i/BAAA,8KACA,oBAA6B,mCAC7B,oBAAqB,mDAErB,eAAsB,yBAAyB,aAG5C,CACD,MAAM,QAAU,8CAEhB,MAAM,YAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQpB,GAAI,CACF,MAAM,OAAS,MAAM,6BAAa,UAAU,CAC1C,WAAY,CAAC,CAAE,MAAO,YAAa,CAAC,EACpC,QACA,WACF,CAAC,EAED,QAAQ,IAAI,qCAA+B,MAAM,EAEjD,MAAO,CACL,KAAM,IAER,CACF,OAAS,IAAK,CACZ,QAAQ,MAAM,2BAA4B,GAAG,EAC7C,MAAM,IAAI,gBAAAA,QAAS,IAAK,sCAAsC,CAChE,CACF,CA/BsB","names":["ApiError"],"ignoreList":[],"sources":["D:\\Minglar Backend NestJS\\src\\modules\\minglaradmin\\services\\AMEmail.service.ts"],"sourcesContent":[null]}}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"code":"__filename=\"D:\\\\Minglar Backend NestJS\\\\src\\\\modules\\\\minglaradmin\\\\services\\\\AMEmail.service.ts\";(()=>{\nvar __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __name=(target,value)=>__defProp(target,\"name\",{value,configurable:true});var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from===\"object\"||typeof from===\"function\"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,\"default\",{value:mod,enumerable:true}):target,mod));var __toCommonJS=mod=>__copyProps(__defProp({},\"__esModule\",{value:true}),mod);var AMEmail_service_exports={};__export(AMEmail_service_exports,{sendAMEmailForHostAssign:()=>sendAMEmailForHostAssign});module.exports=__toCommonJS(AMEmail_service_exports);var import_brevoApi=require(\"@/common/email/brevoApi\");var import_ApiError=__toESM(require(\"@/common/utils/helper/ApiError\"));async function sendAMEmailForHostAssign(emailAddress){const subject=\"Minglar Admin: Host Assignment Notification\";const htmlContent=`\n <p>Hi,</p>\n\n <p>You\\u2019ve been assigned the <strong>Host</strong> role by Minglar Admin.</p>\n\n <p>Best regards,<br/>Minglar Admin Team</p>\n `;try{const result=await import_brevoApi.brevoService.sendEmail({recipients:[{email:emailAddress}],subject,htmlContent});console.log(\"\\u{1F4E7} Email sent successfully:\",result);return{sent:true}}catch(err){console.error(\"Brevo email send failed:\",err);throw new import_ApiError.default(500,\"Failed to send invitation via email.\")}}__name(sendAMEmailForHostAssign,\"sendAMEmailForHostAssign\");0&&(module.exports={sendAMEmailForHostAssign});\n})()\n","warnings":[],"map":{"version":3,"mappings":";i/BAAA,8KACA,oBAA6B,mCAC7B,oBAAqB,mDAErB,eAAsB,yBAAyB,aAG5C,CACD,MAAM,QAAU,8CAEhB,MAAM,YAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQpB,GAAI,CACF,MAAM,OAAS,MAAM,6BAAa,UAAU,CAC1C,WAAY,CAAC,CAAE,MAAO,YAAa,CAAC,EACpC,QACA,WACF,CAAC,EAED,QAAQ,IAAI,qCAA+B,MAAM,EAEjD,MAAO,CACL,KAAM,IAER,CACF,OAAS,IAAK,CACZ,QAAQ,MAAM,2BAA4B,GAAG,EAC7C,MAAM,IAAI,gBAAAA,QAAS,IAAK,sCAAsC,CAChE,CACF,CA/BsB","names":["ApiError"],"ignoreList":[],"sources":["D:\\Minglar Backend NestJS\\src\\modules\\minglaradmin\\services\\AMEmail.service.ts"],"sourcesContent":[null]}}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"code":"__filename=\"D:\\\\Minglar Backend NestJS\\\\src\\\\common\\\\utils\\\\constants\\\\host.constant.ts\";(()=>{\nvar __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from===\"object\"||typeof from===\"function\"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toCommonJS=mod=>__copyProps(__defProp({},\"__esModule\",{value:true}),mod);var host_constant_exports={};__export(host_constant_exports,{ACTIVITY_AM_DISPLAY_STATUS:()=>ACTIVITY_AM_DISPLAY_STATUS,ACTIVITY_AM_INTERNAL_STATUS:()=>ACTIVITY_AM_INTERNAL_STATUS,ACTIVITY_DISPLAY_STATUS:()=>ACTIVITY_DISPLAY_STATUS,ACTIVITY_INTERNAL_STATUS:()=>ACTIVITY_INTERNAL_STATUS,HOST_STATUS_DISPLAY:()=>HOST_STATUS_DISPLAY,HOST_STATUS_INTERNAL:()=>HOST_STATUS_INTERNAL,LAST_QUESTION_ID:()=>LAST_QUESTION_ID,STEPPER:()=>STEPPER});module.exports=__toCommonJS(host_constant_exports);const HOST_STATUS_INTERNAL={HOST_SUBMITTED:\"Host Submitted\",HOST_TO_UPDATE:\"Host To Update\",REJECTED:\"Rejected\",APPROVED:\"Approved\",DRAFT:\"Draft\"};const HOST_STATUS_DISPLAY={DRAFT:\"Draft\",UNDER_REVIEW:\"Under Review\",ENHANCING:\"Enhancing\",REJECTED:\"Rejected\",APPROVED:\"Approved\"};const STEPPER={NOT_SUBMITTED:1,UNDER_REVIEW:2,COMPANY_DETAILS_APPROVED:3,BANK_DETAILS_UPDATED:4,AGREEMENT_ACCEPTED:5,REJECTED:6};const LAST_QUESTION_ID={Q_ID:55};const ACTIVITY_INTERNAL_STATUS={DRAFT_PQ:\"Draft - PQ\",APPROVED:\"Approved\",REJECTED:\"Rejected\",DRAFT:\"Draft\",UNDER_REVIEW:\"Under-Review\",PQQ_FAILED:\"PQQ Failed\",PQQ_TO_UPDATE:\"PQ To Update\",PQQ_SUBMITTED:\"PQ Submitted\"};const ACTIVITY_DISPLAY_STATUS={DRAFT_PQ:\"Draft - PQ\",APPROVED:\"Approved\",REJECTED:\"Rejected\",DRAFT:\"Draft\",UNDER_REVIEW:\"Under-Review\",PQQ_FAILED:\"PQQ Failed\",ENHANCING:\"Enchancing\",PQ_IN_REVIEW:\"PQ In Review\"};const ACTIVITY_AM_INTERNAL_STATUS={DRAFT_PQ:\"Draft - PQ\",APPROVED:\"Approved\",REJECTED:\"Rejected\",DRAFT:\"Draft\",UNDER_REVIEW:\"Under-Review\",PQQ_FAILED:\"PQQ Failed\",PQQ_REJECTED:\"PQ Rejected\",PQQ_TO_REVIEW:\"PQ To Review\"};const ACTIVITY_AM_DISPLAY_STATUS={DRAFT_PQ:\"Draft - PQ\",APPROVED:\"Approved\",REJECTED:\"Rejected\",DRAFT:\"Draft\",UNDER_REVIEW:\"Under-Review\",PQQ_FAILED:\"PQQ Failed\",ENHANCING:\"Enchancing\",NEW:\"New\"};0&&(module.exports={ACTIVITY_AM_DISPLAY_STATUS,ACTIVITY_AM_INTERNAL_STATUS,ACTIVITY_DISPLAY_STATUS,ACTIVITY_INTERNAL_STATUS,HOST_STATUS_DISPLAY,HOST_STATUS_INTERNAL,LAST_QUESTION_ID,STEPPER});\n})()\n","warnings":[],"map":{"version":3,"mappings":";wpBAAA,seAAO,MAAM,qBAAuB,CAChC,eAAgB,iBAChB,eAAgB,iBAChB,SAAU,WACV,SAAU,WACV,MAAO,OACX,EAEO,MAAM,oBAAsB,CAC/B,MAAO,QACP,aAAc,eACd,UAAW,YACX,SAAU,WACV,SAAU,UACd,EAEO,MAAM,QAAU,CACnB,cAAe,EACf,aAAc,EACd,yBAA0B,EAC1B,qBAAsB,EACtB,mBAAoB,EACpB,SAAU,CACd,EAEO,MAAM,iBAAmB,CAC5B,KAAM,EACV,EAEO,MAAM,yBAA2B,CACpC,SAAU,aACV,SAAU,WACV,SAAU,WACV,MAAO,QACP,aAAc,eACd,WAAY,aACZ,cAAe,eACf,cAAe,cACnB,EAEO,MAAM,wBAA0B,CACnC,SAAU,aACV,SAAU,WACV,SAAU,WACV,MAAO,QACP,aAAc,eACd,WAAY,aACZ,UAAW,aACX,aAAc,cAClB,EAEO,MAAM,4BAA8B,CACvC,SAAU,aACV,SAAU,WACV,SAAU,WACV,MAAO,QACP,aAAc,eACd,WAAY,aACZ,aAAc,cACd,cAAe,cACnB,EAEO,MAAM,2BAA6B,CACtC,SAAU,aACV,SAAU,WACV,SAAU,WACV,MAAO,QACP,aAAc,eACd,WAAY,aACZ,UAAW,aACX,IAAK,KACT","names":[],"ignoreList":[],"sources":["D:\\Minglar Backend NestJS\\src\\common\\utils\\constants\\host.constant.ts"],"sourcesContent":[null]}}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"code":"__filename=\"D:\\\\Minglar Backend NestJS\\\\src\\\\common\\\\middlewares\\\\aws\\\\getPreSignedUrl.ts\";(()=>{\nvar __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __name=(target,value)=>__defProp(target,\"name\",{value,configurable:true});var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from===\"object\"||typeof from===\"function\"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,\"default\",{value:mod,enumerable:true}):target,mod));var __toCommonJS=mod=>__copyProps(__defProp({},\"__esModule\",{value:true}),mod);var getPreSignedUrl_exports={};__export(getPreSignedUrl_exports,{getPresignedUrl:()=>getPresignedUrl});module.exports=__toCommonJS(getPreSignedUrl_exports);var import_config=__toESM(require(\"@/config/config\"));var import_client_s3=require(\"@aws-sdk/client-s3\");var import_s3_request_presigner=require(\"@aws-sdk/s3-request-presigner\");const s3=new import_client_s3.S3Client({region:import_config.default.aws.region});const getPresignedUrl=__name(async(bucket,key)=>{const command=new import_client_s3.GetObjectCommand({Bucket:bucket,Key:key});return await(0,import_s3_request_presigner.getSignedUrl)(s3,command,{expiresIn:3600})},\"getPresignedUrl\");0&&(module.exports={getPresignedUrl});\n})()\n","warnings":[],"map":{"version":3,"mappings":";i/BAAA,4JACA,kBAAmB,oCACnB,qBAA2C,8BAC3C,gCAA6B,yCAE7B,MAAM,GAAK,IAAI,0BAAS,CACtB,OAAQ,cAAAA,QAAO,IAAI,MACrB,CAAC,EAEM,MAAM,gBAAkB,aAAO,OAAgB,MAAgB,CACpE,MAAM,QAAU,IAAI,kCAAiB,CACnC,OAAQ,OACR,IAAK,GACP,CAAC,EAGD,OAAO,QAAM,0CAAa,GAAI,QAAS,CAAE,UAAW,IAAK,CAAC,CAC5D,EAR+B","names":["config"],"ignoreList":[],"sources":["D:\\Minglar Backend NestJS\\src\\common\\middlewares\\aws\\getPreSignedUrl.ts"],"sourcesContent":[null]}}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"code":"__filename=\"D:\\\\Minglar Backend NestJS\\\\src\\\\common\\\\utils\\\\constants\\\\host.constant.ts\";(()=>{\nvar __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from===\"object\"||typeof from===\"function\"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toCommonJS=mod=>__copyProps(__defProp({},\"__esModule\",{value:true}),mod);var host_constant_exports={};__export(host_constant_exports,{ACTIVITY_AM_DISPLAY_STATUS:()=>ACTIVITY_AM_DISPLAY_STATUS,ACTIVITY_AM_INTERNAL_STATUS:()=>ACTIVITY_AM_INTERNAL_STATUS,ACTIVITY_DISPLAY_STATUS:()=>ACTIVITY_DISPLAY_STATUS,ACTIVITY_INTERNAL_STATUS:()=>ACTIVITY_INTERNAL_STATUS,HOST_STATUS_DISPLAY:()=>HOST_STATUS_DISPLAY,HOST_STATUS_INTERNAL:()=>HOST_STATUS_INTERNAL,LAST_QUESTION_ID:()=>LAST_QUESTION_ID,STEPPER:()=>STEPPER});module.exports=__toCommonJS(host_constant_exports);const HOST_STATUS_INTERNAL={HOST_SUBMITTED:\"Host Submitted\",HOST_TO_UPDATE:\"Host To Update\",REJECTED:\"Rejected\",APPROVED:\"Approved\",DRAFT:\"Draft\"};const HOST_STATUS_DISPLAY={DRAFT:\"Draft\",UNDER_REVIEW:\"Under Review\",ENHANCING:\"Enhancing\",REJECTED:\"Rejected\",APPROVED:\"Approved\"};const STEPPER={NOT_SUBMITTED:1,UNDER_REVIEW:2,COMPANY_DETAILS_APPROVED:3,BANK_DETAILS_UPDATED:4,AGREEMENT_ACCEPTED:5,REJECTED:6};const LAST_QUESTION_ID={Q_ID:55};const ACTIVITY_INTERNAL_STATUS={DRAFT_PQ:\"Draft - PQ\",APPROVED:\"Approved\",REJECTED:\"Rejected\",DRAFT:\"Draft\",UNDER_REVIEW:\"Under-Review\",PQQ_FAILED:\"PQQ Failed\",PQQ_TO_UPDATE:\"PQ To Update\",PQQ_SUBMITTED:\"PQ Submitted\"};const ACTIVITY_DISPLAY_STATUS={DRAFT_PQ:\"Draft - PQ\",APPROVED:\"Approved\",REJECTED:\"Rejected\",DRAFT:\"Draft\",UNDER_REVIEW:\"Under-Review\",PQQ_FAILED:\"PQQ Failed\",ENHANCING:\"Enchancing\",PQ_IN_REVIEW:\"PQ In Review\"};const ACTIVITY_AM_INTERNAL_STATUS={DRAFT_PQ:\"Draft - PQ\",APPROVED:\"Approved\",REJECTED:\"Rejected\",DRAFT:\"Draft\",UNDER_REVIEW:\"Under-Review\",PQQ_FAILED:\"PQQ Failed\",PQQ_REJECTED:\"PQ Rejected\",PQQ_TO_REVIEW:\"PQ To Review\"};const ACTIVITY_AM_DISPLAY_STATUS={DRAFT_PQ:\"Draft - PQ\",APPROVED:\"Approved\",REJECTED:\"Rejected\",DRAFT:\"Draft\",UNDER_REVIEW:\"Under-Review\",PQQ_FAILED:\"PQQ Failed\",ENHANCING:\"Enchancing\",NEW:\"New\"};0&&(module.exports={ACTIVITY_AM_DISPLAY_STATUS,ACTIVITY_AM_INTERNAL_STATUS,ACTIVITY_DISPLAY_STATUS,ACTIVITY_INTERNAL_STATUS,HOST_STATUS_DISPLAY,HOST_STATUS_INTERNAL,LAST_QUESTION_ID,STEPPER});\n})()\n","warnings":[],"map":{"version":3,"mappings":";wpBAAA,seAAO,MAAM,qBAAuB,CAChC,eAAgB,iBAChB,eAAgB,iBAChB,SAAU,WACV,SAAU,WACV,MAAO,OACX,EAEO,MAAM,oBAAsB,CAC/B,MAAO,QACP,aAAc,eACd,UAAW,YACX,SAAU,WACV,SAAU,UACd,EAEO,MAAM,QAAU,CACnB,cAAe,EACf,aAAc,EACd,yBAA0B,EAC1B,qBAAsB,EACtB,mBAAoB,EACpB,SAAU,CACd,EAEO,MAAM,iBAAmB,CAC5B,KAAM,EACV,EAEO,MAAM,yBAA2B,CACpC,SAAU,aACV,SAAU,WACV,SAAU,WACV,MAAO,QACP,aAAc,eACd,WAAY,aACZ,cAAe,eACf,cAAe,cACnB,EAEO,MAAM,wBAA0B,CACnC,SAAU,aACV,SAAU,WACV,SAAU,WACV,MAAO,QACP,aAAc,eACd,WAAY,aACZ,UAAW,aACX,aAAc,cAClB,EAEO,MAAM,4BAA8B,CACvC,SAAU,aACV,SAAU,WACV,SAAU,WACV,MAAO,QACP,aAAc,eACd,WAAY,aACZ,aAAc,cACd,cAAe,cACnB,EAEO,MAAM,2BAA6B,CACtC,SAAU,aACV,SAAU,WACV,SAAU,WACV,MAAO,QACP,aAAc,eACd,WAAY,aACZ,UAAW,aACX,IAAK,KACT","names":[],"ignoreList":[],"sources":["D:\\Minglar Backend NestJS\\src\\common\\utils\\constants\\host.constant.ts"],"sourcesContent":[null]}}
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
|||||||
{"code":"__filename=\"D:\\\\Minglar Backend NestJS\\\\src\\\\common\\\\middlewares\\\\aws\\\\getPreSignedUrl.ts\";(()=>{\nvar __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __name=(target,value)=>__defProp(target,\"name\",{value,configurable:true});var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from===\"object\"||typeof from===\"function\"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,\"default\",{value:mod,enumerable:true}):target,mod));var __toCommonJS=mod=>__copyProps(__defProp({},\"__esModule\",{value:true}),mod);var getPreSignedUrl_exports={};__export(getPreSignedUrl_exports,{getPresignedUrl:()=>getPresignedUrl});module.exports=__toCommonJS(getPreSignedUrl_exports);var import_config=__toESM(require(\"@/config/config\"));var import_client_s3=require(\"@aws-sdk/client-s3\");var import_s3_request_presigner=require(\"@aws-sdk/s3-request-presigner\");const s3=new import_client_s3.S3Client({region:import_config.default.aws.region});const getPresignedUrl=__name(async(bucket,key)=>{const command=new import_client_s3.GetObjectCommand({Bucket:bucket,Key:key});return await(0,import_s3_request_presigner.getSignedUrl)(s3,command,{expiresIn:3600})},\"getPresignedUrl\");0&&(module.exports={getPresignedUrl});\n})()\n","warnings":[],"map":{"version":3,"mappings":";i/BAAA,4JACA,kBAAmB,oCACnB,qBAA2C,8BAC3C,gCAA6B,yCAE7B,MAAM,GAAK,IAAI,0BAAS,CACtB,OAAQ,cAAAA,QAAO,IAAI,MACrB,CAAC,EAEM,MAAM,gBAAkB,aAAO,OAAgB,MAAgB,CACpE,MAAM,QAAU,IAAI,kCAAiB,CACnC,OAAQ,OACR,IAAK,GACP,CAAC,EAGD,OAAO,QAAM,0CAAa,GAAI,QAAS,CAAE,UAAW,IAAK,CAAC,CAC5D,EAR+B","names":["config"],"ignoreList":[],"sources":["D:\\Minglar Backend NestJS\\src\\common\\middlewares\\aws\\getPreSignedUrl.ts"],"sourcesContent":[null]}}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user