42 Commits

Author SHA1 Message Date
a906dc5635 Add getAddActivityPrePopulate handler and implement prepopulate data retrieval
- Introduced a new handler for adding activity prepopulation.
- Enhanced the PrePopulateService to fetch all necessary prepopulate data for the new activity.
- Updated the updateBankDetails handler to correctly inject host ID.
- Improved user data retrieval in HostService to include additional fields.
- Added validation for host ID in showSuggestionToAM handler.
2025-12-17 16:17:55 +05:30
8ec8cf4854 fixed the path 2025-12-16 19:11:15 +05:30
fab7642302 Implement parent document deletion and improve host retrieval logic in onboarding process 2025-12-16 17:34:10 +05:30
4d3796c5f3 Refactor companyTypes seeding and enhance host retrieval to include user email address 2025-12-16 16:36:15 +05:30
2f3c531c56 Merge branch 'sprint1' of http://git.wdipl.com/Mayank.Mishra/MinglarBackendNestJS into mayank 2025-12-16 16:09:28 +05:30
a2907929d4 updated serverless version 2025-12-16 16:08:59 +05:30
paritosh18
ef2b23ef83 Update serverless configuration to use exported stack output for Prisma Lambda Layer ARN, ensuring proper deployment functionality. 2025-12-16 16:07:03 +05:30
2767d29d79 Update parent company validation to allow optional fields and handle null values in company details submission. 2025-12-16 15:38:03 +05:30
46daec00ce fixed the keytooloong issue 2025-12-16 14:37:38 +05:30
43e494780d Refactor document name handling in host service to sanitize input and ensure valid connections for city, state, and country IDs during host creation and updates. 2025-12-16 13:16:22 +05:30
0da18b18f7 Add getSuggestionsForAM function and corresponding handler for retrieving suggestions based on host assignments. Update serverless configuration to include new API endpoint. 2025-12-16 12:07:42 +05:30
b5304b3c26 Refactor OTP email content for host registration and resend functionality to improve clarity and tone. 2025-12-15 16:53:12 +05:30
82340c2918 Implement email notifications for host application acceptance and rejection, including host details retrieval and email content customization. 2025-12-10 14:59:16 +05:30
b8f5f92c98 Add validation for city ID in company details submission to ensure existence in the database 2025-12-09 17:38:44 +05:30
3652d851f7 Enhance email notifications for host application approvals and rejections by including the host's first name in the greeting. 2025-12-09 15:02:15 +05:30
paritosh18
6166075967 Update service name in serverless configuration to 'minglar' and add 'zod' dependency in package-lock.json 2025-12-09 13:50:30 +05:30
paritosh18
b6cb5831c2 Refactor Prisma client usage and enhance service integration for improved connection management 2025-12-09 13:49:20 +05:30
paritosh18
a39cc1c3c8 Merge branch 'sprint1' of http://git.wdipl.com/Mayank.Mishra/MinglarBackendNestJS into paritosh-main1 2025-12-09 12:09:38 +05:30
paritosh18
ae76618f7a Add environment configuration template and update .gitignore for new env files 2025-12-09 12:09:21 +05:30
e957fc5c50 Add token blacklist check in JWT middlewares to enhance session management and security 2025-12-09 12:07:03 +05:30
paritosh18
856db687c3 Update service name in serverless configuration to 'minglarDev' for development environment 2025-12-08 17:58:38 +05:30
a020a28993 Update host application handlers to retrieve user details using hostXid instead of userInfo.id for accurate email notifications. 2025-12-08 17:31:55 +05:30
1a520ae9e1 Remove email parameter from resendOtpHelper and normalize email addresses to lowercase in the resend OTP handler for consistent processing. 2025-12-08 15:25:21 +05:30
d5d6951e64 Normalize email addresses to lowercase in OTP verification handler for consistent processing. 2025-12-08 15:19:31 +05:30
bbd55562af Add HOST_LINK environment variable and update related configurations. Normalize email addresses to lowercase in login and registration handlers. Enhance email notifications for approved and rejected applications with HOST_LINK. 2025-12-08 15:08:05 +05:30
9abadba8f5 Refactor database access by introducing prisma.lambda.service for centralized PrismaClient usage across modules. Update imports in various handlers and services to utilize the new service, ensuring consistent database interactions and improved maintainability. 2025-12-08 11:23:58 +05:30
747566497c Merge branch 'sprint1' of http://git.wdipl.com/Mayank.Mishra/MinglarBackendNestJS into mayank 2025-12-06 16:33:57 +05:30
6c3e5ccd60 Add multiple states, cities, and banks to seed data in prisma/seed.ts 2025-12-06 16:33:35 +05:30
ca9ba601ad Add additional states and cities to seed data in Prisma 2025-12-06 16:27:54 +05:30
eab6565e12 Merge branch 'sprint1' of http://git.wdipl.com/Mayank.Mishra/MinglarBackendNestJS into mayank 2025-12-06 16:11:53 +05:30
6a84876518 Remove profile completion percentage calculation from user update in MinglarService 2025-12-06 12:55:07 +05:30
d8fb4b242d Add roleXid field to user selection in MinglarService 2025-12-06 12:39:21 +05:30
51b053310f Add validation to prevent duplicate host accounts in addPaymentDetails method 2025-12-06 12:06:04 +05:30
06010ef6e8 Refactor API paths for acceptPQByAM and rejectPQQByAM to remove activityId from URL and update request body parsing for activityId 2025-12-05 19:21:19 +05:30
7b9763c668 Enhance getAllHostActivityForMinglar method to exclude activities with DRAFT_PQ status 2025-12-05 18:51:50 +05:30
4c1a04d043 Update serverless configuration to comment out Prisma client dependencies and enhance MinglarService to exclude draft activities from host activity retrieval. 2025-12-05 18:50:14 +05:30
paritosh18
ecf45c3e7c Merge branch 'mayank' of http://git.wdipl.com/Mayank.Mishra/MinglarBackendNestJS into mayank 2025-12-05 14:56:45 +05:30
paritosh18
20a931ab27 Add AWS Lambda Bundle Size Optimization Guide and update build scripts for Prisma layer 2025-12-05 14:56:43 +05:30
6a84fbc0c3 Merge branch 'sprint1' of http://git.wdipl.com/Mayank.Mishra/MinglarBackendNestJS into mayank 2025-12-05 14:38:32 +05:30
9fc8336bd9 fixed the routes 2025-12-05 14:37:37 +05:30
b049146664 Refactor serverless configuration to rename service, add Prisma layer support, and include AM_INVITATION_LINK in environment variables. Update validation schema and email invitation content for improved user experience. 2025-12-05 13:45:49 +05:30
963f84681c Enhance HostService to retrieve and utilize existing logo paths for host and parent companies, ensuring consistency in logo display across company details. 2025-12-04 20:18:22 +05:30
95 changed files with 1921 additions and 480 deletions

44
.env.example Normal file
View File

@@ -0,0 +1,44 @@
# Environment Configuration Template
# Copy this file to .env.dev, .env.test, or .env.uat and fill in the values
# Database
DATABASE_URL=
DB_USERNAME=
DB_PASSWORD=
DB_DATABASE_NAME=
DB_HOSTNAME=
DB_PORT=5432
# Email Bypass (set to true for dev/test, false for production-like environments)
BY_PASS_EMAIL=
BYPASS_OTP=
# Brevo Email Configuration
BREVO_EMAIL_API_KEY=
BREVO_API_BASEURL=https://api.brevo.com
BREVO_FROM_EMAIL=
BREVO_SMTP_HOST=smtp-relay.brevo.com
BREVO_SMTP_PORT=587
BREVO_SMTP_USER=
BREVO_SMTP_PASS=
# JWT Configuration
REFRESH_TOKEN_SECRET=
JWT_SECRET=
JWT_ACCESS_EXPIRATION_MINUTES=30
JWT_REFRESH_EXPIRATION_DAYS=7
JWT_RESET_PASSWORD_EXPIRATION_MINUTES=15
JWT_VERIFY_EMAIL_EXPIRATION_MINUTES=15
# Security
SALT_ROUNDS=
NODE_ENV=
# AWS S3
S3_BUCKET_NAME=
# Admin Configuration
MINGLAR_ADMIN_NAME=
MINGLAR_ADMIN_EMAIL=
AM_INVITATION_LINK=
HOST_LINK=

4
.gitignore vendored
View File

@@ -40,10 +40,14 @@ lerna-debug.log*
.env.test.local
.env.production.local
.env.local
.env.dev
.env.test
.env.uat
# temp
.tmp
.temp
undefined/
# Runtime data
pids

View File

@@ -0,0 +1,490 @@
# AWS Lambda Bundle Size Optimization Guide
## Overview
This guide documents how to optimize AWS Lambda function bundle sizes when using:
- **Serverless Framework v4** (with built-in esbuild)
- **Prisma ORM** (with driver adapters)
- **NestJS** or any Node.js framework
## Problem
Lambda functions can become bloated (25+ MB) due to:
1. **Prisma binary engines** (~50MB uncompressed)
2. **AWS SDK v3** being bundled (~5-10MB)
3. **Dependencies copied to node_modules** instead of being bundled
## Solution Architecture
```
┌─────────────────────────────────────────────────────────┐
│ Lambda Function │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Your Code (bundled by esbuild) ~50-500 KB │ │
│ └─────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Prisma Layer (shared) ~15 MB │ │
│ │ - @prisma/client │ │
│ │ - @prisma/adapter-pg │ │
│ │ - .prisma/client (generated) │ │
│ │ - pg driver │ │
│ └─────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ AWS Lambda Runtime │ │
│ │ - AWS SDK v3 (built-in for Node.js 18+) │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
```
---
## Step-by-Step Setup
### 1. Project Structure
```
your-project/
├── serverless.yml
├── package.json
├── prisma/
│ └── schema.prisma
├── layers/
│ └── prisma/
│ └── nodejs/
│ └── package.json
├── src/
│ └── ... your code
└── build-prisma-layer.ps1 (or .sh for Linux/Mac)
```
### 2. Prisma Schema Configuration
**`prisma/schema.prisma`**
```prisma
generator client {
provider = "prisma-client-js"
// For Prisma 7+ with driver adapters, no binary targets needed
// The WASM-based query engine is used automatically
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
```
> **Note**: Prisma 7+ uses WASM-based query compiler instead of binary engines when using driver adapters, which is much smaller.
### 3. Layer Package.json
**`layers/prisma/nodejs/package.json`**
```json
{
"name": "prisma-layer",
"version": "1.0.0",
"description": "Lambda layer for Prisma with pg driver adapter",
"dependencies": {
"@prisma/client": "^7.0.0",
"@prisma/adapter-pg": "^7.0.0",
"pg": "^8.13.0"
}
}
```
### 4. Serverless Configuration
**`serverless.yml`**
```yaml
service: your-service-name
provider:
name: aws
runtime: nodejs22.x
region: your-region
memorySize: 512
# Apply Prisma layer to ALL functions
layers:
- !Ref PrismaLambdaLayer
environment:
DATABASE_URL: ${env:DATABASE_URL}
# ... other env vars
# esbuild configuration (Serverless v4 built-in)
build:
esbuild:
bundle: true
minify: true
sourcemap: false
target: node20
platform: node
# Mark packages as external (not bundled into JS)
external:
- '@prisma/client'
- '@prisma/adapter-pg'
- '.prisma/client'
- '.prisma'
- 'pg'
- '@aws-sdk/*'
- '@smithy/*'
- '@aws-crypto/*'
# Exclude from npm install in zip (CRITICAL!)
exclude:
- 'aws-sdk'
- '@aws-sdk/*'
- '@smithy/*'
- '@aws-crypto/*'
- '@prisma/client'
- '@prisma/adapter-pg'
- '.prisma'
- '.prisma/client'
- 'pg'
- 'pg-*'
- 'postgres-*'
- 'pgpass'
- 'split2'
- 'xtend'
# Define the Prisma layer
layers:
prisma:
path: layers/prisma
name: ${self:service}-prisma-layer-${sls:stage}
description: Prisma client with pg driver adapter
compatibleRuntimes:
- nodejs22.x
retain: false
# Package configuration
package:
individually: true
patterns:
- '!node_modules/**'
- '!node_modules/@prisma/**'
- '!node_modules/.prisma/**'
- '!**/*.test.js'
- '!**/*.spec.js'
- '!**/test/**'
- '!**/__tests__/**'
- '!package-lock.json'
- '!yarn.lock'
- '!README.md'
- '!.git/**'
functions:
myFunction:
handler: src/handlers/myHandler.handler
events:
- httpApi:
path: /my-endpoint
method: get
plugins:
- serverless-offline
```
### 5. Build Script for Prisma Layer
**Windows (PowerShell) - `build-prisma-layer.ps1`**
```powershell
# Build Prisma Lambda Layer
$layerPath = "layers\prisma\nodejs"
Write-Host "Building Prisma Lambda Layer..." -ForegroundColor Cyan
# 1. Clean existing node_modules in layer
Write-Host "Cleaning layer node_modules..."
if (Test-Path "$layerPath\node_modules") {
Remove-Item -Recurse -Force "$layerPath\node_modules"
}
# 2. Install dependencies in layer
Write-Host "Installing layer dependencies..."
Push-Location $layerPath
npm install --omit=dev
Pop-Location
# 3. Generate Prisma client
Write-Host "Generating Prisma client..."
npx prisma generate
# 4. Copy .prisma/client to layer
Write-Host "Copying generated Prisma client to layer..."
$sourcePrisma = "node_modules\.prisma"
$destPrisma = "$layerPath\node_modules\.prisma"
if (Test-Path $sourcePrisma) {
if (Test-Path $destPrisma) {
Remove-Item -Recurse -Force $destPrisma
}
Copy-Item -Recurse $sourcePrisma $destPrisma
Write-Host "Copied .prisma/client successfully!" -ForegroundColor Green
} else {
Write-Host "ERROR: .prisma folder not found. Run 'npx prisma generate' first." -ForegroundColor Red
exit 1
}
# 5. Show layer size
$layerSize = (Get-ChildItem "$layerPath\node_modules" -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB
Write-Host "`nTotal layer size: $([math]::Round($layerSize, 2)) MB" -ForegroundColor Yellow
Write-Host "Prisma layer built successfully!" -ForegroundColor Green
```
**Linux/Mac (Bash) - `build-prisma-layer.sh`**
```bash
#!/bin/bash
set -e
LAYER_PATH="layers/prisma/nodejs"
echo "Building Prisma Lambda Layer..."
# 1. Clean existing node_modules in layer
echo "Cleaning layer node_modules..."
rm -rf "$LAYER_PATH/node_modules"
# 2. Install dependencies in layer
echo "Installing layer dependencies..."
cd "$LAYER_PATH"
npm install --omit=dev
cd -
# 3. Generate Prisma client
echo "Generating Prisma client..."
npx prisma generate
# 4. Copy .prisma/client to layer
echo "Copying generated Prisma client to layer..."
if [ -d "node_modules/.prisma" ]; then
rm -rf "$LAYER_PATH/node_modules/.prisma"
cp -r "node_modules/.prisma" "$LAYER_PATH/node_modules/.prisma"
echo "Copied .prisma/client successfully!"
else
echo "ERROR: .prisma folder not found. Run 'npx prisma generate' first."
exit 1
fi
# 5. Show layer size
LAYER_SIZE=$(du -sm "$LAYER_PATH/node_modules" | cut -f1)
echo "Total layer size: ${LAYER_SIZE} MB"
echo "Prisma layer built successfully!"
```
### 6. Prisma Client Usage
**`src/common/database/prisma.client.ts`**
```typescript
import { PrismaClient } from '@prisma/client';
import { PrismaPg } from '@prisma/adapter-pg';
import { Pool } from 'pg';
// Connection pool for serverless
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
max: 5, // Limit connections in Lambda
});
const adapter = new PrismaPg(pool);
// Single instance for Lambda warm starts
let prisma: PrismaClient;
export function getPrismaClient(): PrismaClient {
if (!prisma) {
prisma = new PrismaClient({
adapter,
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
});
}
return prisma;
}
export { prisma };
```
---
## Deployment Workflow
```bash
# 1. Build the Prisma layer (run after schema changes)
./build-prisma-layer.ps1 # Windows
# or
./build-prisma-layer.sh # Linux/Mac
# 2. Deploy
npx serverless deploy --stage=dev
# 3. Deploy single function (faster, uses existing layer)
npx serverless deploy function -f myFunction --stage=dev
```
---
## Key Configuration Explained
### esbuild `external` vs `exclude`
| Property | Purpose |
|----------|---------|
| `external` | Tells esbuild NOT to bundle these into the JS file. They become `require()` calls. |
| `exclude` | Tells Serverless NOT to `npm install` these packages into the function zip. |
**Both are required!**
- `external` alone = esbuild doesn't bundle, but Serverless still installs to node_modules
- `exclude` alone = Serverless doesn't install, but esbuild bundles the code
### Layer Reference
```yaml
# This creates a CloudFormation reference to the layer defined in the same stack
layers:
- !Ref PrismaLambdaLayer
```
The `PrismaLambdaLayer` name comes from the layer key (`prisma`) converted to PascalCase + `LambdaLayer`.
### Why Exclude pg-* packages?
When `pg` is external, its dependencies still get installed:
- `pg-connection-string`
- `pg-pool`
- `pg-protocol`
- `pg-types`
- etc.
These must all be in the `exclude` list to prevent duplication.
---
## Expected Results
| Function Type | Before | After |
|---------------|--------|-------|
| Simple handlers | 25+ MB | **50-100 kB** |
| With validation (zod/yup) | 25+ MB | **300-500 kB** |
| With S3 uploads | 30+ MB | **1-2 MB** |
---
## Troubleshooting
### 1. "Cannot find module '@prisma/client'"
**Cause**: Layer doesn't have the generated `.prisma/client`
**Fix**: Run `build-prisma-layer.ps1` to regenerate the layer
### 2. Function size still large
**Debug**: Extract and inspect the zip:
```powershell
Expand-Archive ".serverless\build\your-function.zip" -DestinationPath "extracted"
Get-ChildItem "extracted\node_modules" -Directory
```
If you see `@prisma` or `pg` folders, the `exclude` config isn't working.
### 3. "Cannot resolve CloudFormation reference"
**Cause**: Using `${cf:...}` reference before first deploy
**Fix**: Use `!Ref PrismaLambdaLayer` instead (works on first deploy)
### 4. Cold starts still slow
Consider:
- **Provisioned Concurrency**: Pre-warm instances
- **Reduce memory**: Sometimes lower memory = same speed, lower cost
- **Connection pooling**: Use tools like PgBouncer for RDS
---
## Additional Optimizations
### 1. Remove duplicate validation libraries
Pick ONE of: `zod`, `yup`, or `class-validator`. Don't use all three.
### 2. Tree-shake NestJS
If not using full NestJS, import only what you need:
```typescript
// Instead of
import { Controller, Get } from '@nestjs/common';
// For Lambda handlers, you might not need NestJS at all
```
### 3. Use AWS SDK v3 selectively
```yaml
external:
- '@aws-sdk/*' # Exclude all
```
Then in code:
```typescript
// AWS SDK v3 is available in Lambda runtime (Node.js 18+)
import { S3Client } from '@aws-sdk/client-s3';
```
---
## Quick Reference
```yaml
# Minimal serverless.yml for Prisma + Lambda optimization
build:
esbuild:
bundle: true
minify: true
external:
- '@prisma/client'
- '@prisma/adapter-pg'
- '.prisma/client'
- '.prisma'
- 'pg'
- '@aws-sdk/*'
exclude:
- '@prisma/client'
- '@prisma/adapter-pg'
- '.prisma'
- '.prisma/client'
- 'pg'
- 'pg-*'
- 'postgres-*'
- 'pgpass'
- 'split2'
- 'xtend'
- '@aws-sdk/*'
layers:
prisma:
path: layers/prisma
name: ${self:service}-prisma-${sls:stage}
compatibleRuntimes:
- nodejs22.x
provider:
layers:
- !Ref PrismaLambdaLayer
```
---
## Version Compatibility
| Tool | Tested Version |
|------|----------------|
| Serverless Framework | v4.x |
| Prisma | v7.x |
| Node.js | 20.x, 22.x |
| AWS Lambda Runtime | nodejs20.x, nodejs22.x |
---
*Last updated: December 2025*

51
build-prisma-layer.ps1 Normal file
View File

@@ -0,0 +1,51 @@
# Build Prisma Lambda Layer
# Run this script before deploying to ensure the layer has the generated client
$layerPath = "layers\prisma\nodejs"
Write-Host "Building Prisma Lambda Layer..." -ForegroundColor Cyan
# 1. Clean existing node_modules in layer
Write-Host "Cleaning layer node_modules..."
if (Test-Path "$layerPath\node_modules") {
Remove-Item -Recurse -Force "$layerPath\node_modules"
}
# 2. Install dependencies in layer
Write-Host "Installing layer dependencies..."
Push-Location $layerPath
npm install --omit=dev
Pop-Location
# 3. Generate Prisma client into the layer
Write-Host "Generating Prisma client into layer..."
# Set the output directory for Prisma client
$env:PRISMA_GENERATE_DATAPROXY = "false"
# Generate client - this creates .prisma/client
npx prisma generate
# 4. Copy .prisma/client to layer
Write-Host "Copying generated Prisma client to layer..."
$sourcePrisma = "node_modules\.prisma"
$destPrisma = "$layerPath\node_modules\.prisma"
if (Test-Path $sourcePrisma) {
if (Test-Path $destPrisma) {
Remove-Item -Recurse -Force $destPrisma
}
Copy-Item -Recurse $sourcePrisma $destPrisma
Write-Host "Copied .prisma/client successfully!" -ForegroundColor Green
} else {
Write-Host "ERROR: .prisma folder not found. Run 'npx prisma generate' first." -ForegroundColor Red
exit 1
}
# 5. Show layer size
Write-Host "`nLayer contents:"
Get-ChildItem "$layerPath\node_modules" -Directory | Select-Object Name
$layerSize = (Get-ChildItem "$layerPath\node_modules" -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB
Write-Host "`nTotal layer size: $([math]::Round($layerSize, 2)) MB" -ForegroundColor Yellow
Write-Host "`nPrisma layer built successfully!" -ForegroundColor Green
Write-Host "Run 'serverless deploy' to deploy with the updated layer."

238
layers/prisma/nodejs/package-lock.json generated Normal file
View File

@@ -0,0 +1,238 @@
{
"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",
"zod": "^4.1.12"
}
},
"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"
}
},
"node_modules/zod": {
"version": "4.1.13",
"resolved": "https://registry.npmjs.org/zod/-/zod-4.1.13.tgz",
"integrity": "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
}
}
}

View File

@@ -0,0 +1,11 @@
{
"name": "prisma-layer",
"version": "1.0.0",
"description": "Lambda layer for Prisma 7 with pg driver adapter and zod",
"dependencies": {
"@prisma/client": "^7.0.1",
"@prisma/adapter-pg": "^7.0.1",
"pg": "^8.13.0",
"zod": "^4.1.12"
}
}

10
package-lock.json generated
View File

@@ -46,7 +46,7 @@
"prisma": "^7.0.1",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1",
"serverless": "4.17.0",
"serverless": "4.24.0",
"swagger-ui-express": "^5.0.0",
"tslib": "^2.8.1",
"uuid": "^13.0.0",
@@ -14467,12 +14467,12 @@
}
},
"node_modules/serverless": {
"version": "4.17.0",
"resolved": "https://registry.npmjs.org/serverless/-/serverless-4.17.0.tgz",
"integrity": "sha512-hoZmipwyN/h7y9HwkWGlJ0YT06RFq7WNOD7fFEiPfnSnnUMVTzeNHq2BRrUlpHhf5s9srCHDc2wx5I06acfq1Q==",
"version": "4.24.0",
"resolved": "https://registry.npmjs.org/serverless/-/serverless-4.24.0.tgz",
"integrity": "sha512-bgxFQ6QyOGJC9IZjZIXo4m6bdWMl9I7HNZ4jrmwSpdePdsRd46igGRpSnhdYFOc71GNplhSOeoCibL94yCHfrg==",
"hasInstallScript": true,
"dependencies": {
"axios": "^1.8.3",
"axios": "^1.12.1",
"axios-proxy-builder": "^0.1.2",
"rimraf": "^5.0.5",
"xml2js": "0.6.2"

View File

@@ -63,7 +63,7 @@
"prisma": "^7.0.1",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1",
"serverless": "4.17.0",
"serverless": "4.24.0",
"swagger-ui-express": "^5.0.0",
"tslib": "^2.8.1",
"uuid": "^13.0.0",

View File

@@ -1,8 +1,8 @@
// prisma.ts
import { PrismaClient } from '@prisma/client';
// Re-export from the main singleton for consistency
import { prisma } from '../src/common/database/prisma.client';
// The DATABASE_URL environment variable will be automatically used
export const prisma = new PrismaClient();
export { prisma };
process.on('SIGINT', async () => {
await prisma.$disconnect();

View File

@@ -33,11 +33,46 @@ async function main() {
update: {},
create: { countryXid: india.id, stateName: 'Maharashtra' },
});
const uttarpradesh = await prisma.states.upsert({
where: { stateName: 'Uttar-Pradesh' },
update: {},
create: { countryXid: india.id, stateName: 'Uttar-Pradesh' },
});
const Rajasthan = await prisma.states.upsert({
where: { stateName: 'Rajasthan' },
update: {},
create: { countryXid: india.id, stateName: 'Rajasthan' },
});
const Uttarakhand = await prisma.states.upsert({
where: { stateName: 'Uttarakhand' },
update: {},
create: { countryXid: india.id, stateName: 'Uttarakhand' },
});
const HimachalPradesh = await prisma.states.upsert({
where: { stateName: 'Himachal Pradesh' },
update: {},
create: { countryXid: india.id, stateName: 'Himachal Pradesh' },
});
const Gujrat = await prisma.states.upsert({
where: { stateName: 'Gujrat' },
update: {},
create: { countryXid: india.id, stateName: 'Gujrat' },
});
// ✅ Cities
await prisma.cities.createMany({
data: [
{ stateXid: maharashtra.id, cityName: 'Mumbai' },
{ stateXid: uttarpradesh.id, cityName: 'Azamgarh' },
{ stateXid: uttarpradesh.id, cityName: 'Lucknow' },
{ stateXid: uttarpradesh.id, cityName: 'Prayagraj' },
{ stateXid: Rajasthan.id, cityName: 'Jaipur' },
{ stateXid: Rajasthan.id, cityName: 'Jaisalmer' },
{ stateXid: Uttarakhand.id, cityName: 'Haridwar' },
{ stateXid: HimachalPradesh.id, cityName: 'Manali' },
{ stateXid: Gujrat.id, cityName: 'Surat' },
{ stateXid: Gujrat.id, cityName: 'Ahemdabad' },
{ stateXid: Gujrat.id, cityName: 'Rajkot' },
],
skipDuplicates: true,
});
@@ -56,6 +91,21 @@ async function main() {
update: {},
create: { countryXid: india.id, bankName: 'HDFC Bank' },
});
const indianBank = await prisma.banks.upsert({
where: { bankName: 'Indian Bank' },
update: {},
create: { countryXid: india.id, bankName: 'Indian Bank' },
});
const Kotak = await prisma.banks.upsert({
where: { bankName: 'Kotak Bank' },
update: {},
create: { countryXid: india.id, bankName: 'Kotak Bank' },
});
const BOI = await prisma.banks.upsert({
where: { bankName: 'Bank of India' },
update: {},
create: { countryXid: india.id, bankName: 'Bank of India' },
});
// ✅ Bank Branches
await prisma.bankBranches.createMany({
@@ -67,6 +117,27 @@ async function main() {
branchAddress: 'HDFC Fort Branch, Mumbai',
ifscCode: 'HDFC0001234',
},
{
bankXid: indianBank.id,
stateXid: maharashtra.id,
cityXid: (await prisma.cities.findFirst({ where: { cityName: 'Mumbai' } }))!.id,
branchAddress: 'Indian Bank Fort Branch, Mumbai',
ifscCode: 'IDIB0001234',
},
{
bankXid: Kotak.id,
stateXid: Uttarakhand.id,
cityXid: (await prisma.cities.findFirst({ where: { cityName: 'Haridwar' } }))!.id,
branchAddress: 'Kotak Fort Branch, Mumbai',
ifscCode: 'KTB0001234',
},
{
bankXid: BOI.id,
stateXid: uttarpradesh.id,
cityXid: (await prisma.cities.findFirst({ where: { cityName: 'Azamgarh' } }))!.id,
branchAddress: 'Bank of India Fort Branch, Mumbai',
ifscCode: 'BOI0001234',
},
],
skipDuplicates: true,
});
@@ -179,9 +250,9 @@ async function main() {
});
await prisma.companyTypes.upsert({
where: { companyTypeName: 'Private Limited, Public Limited' },
where: { companyTypeName: 'Private Limited' },
update: {},
create: { companyTypeName: 'Private Limited, Public Limited', displayOrder: 5 },
create: { companyTypeName: 'Private Limited', displayOrder: 5 },
});
await prisma.companyTypes.upsert({
@@ -190,6 +261,12 @@ async function main() {
create: { companyTypeName: 'Non-Profit Organisation', displayOrder: 6 },
});
await prisma.companyTypes.upsert({
where: { companyTypeName: 'Public Limited' },
update: {},
create: { companyTypeName: 'Public Limited', displayOrder: 7 },
});
// ✅ Food Types
await prisma.foodTypes.createMany({
data: [

View File

@@ -1,11 +1,27 @@
service: minglarDev
service: minglar
useDotenv: true
params:
dev:
stage: dev
test:
stage: test
uat:
stage: uat
provider:
name: aws
runtime: nodejs22.x
region: ap-south-1
stage: ${opt:stage, 'dev'}
versionFunctions: false
memorySize: 512
# Apply Prisma layer to all functions
# Reference the layer defined in this stack using CloudFormation Ref
layers:
# Use the exported stack output so deploy function works (expects a string ARN)
- ${cf:${self:service}-${sls:stage}.PrismaLambdaLayerQualifiedArn}
apiGateway:
binaryMediaTypes:
- '*/*'
@@ -38,6 +54,8 @@ provider:
S3_BUCKET_NAME: ${env:S3_BUCKET_NAME}
MINGLAR_ADMIN_NAME: ${env:MINGLAR_ADMIN_NAME}
MINGLAR_ADMIN_EMAIL: ${env:MINGLAR_ADMIN_EMAIL}
AM_INVITATION_LINK: ${env:AM_INVITATION_LINK}
HOST_LINK: ${env:HOST_LINK}
iam:
role:
@@ -53,25 +71,61 @@ provider:
- 'arn:aws:s3:::${env:S3_BUCKET_NAME}/*'
custom:
serverless-offline:
reloadHandler: true
build:
esbuild:
bundle: true
minify: true
sourcemap: false
target: node20
platform: node
concurrency: 5
# Mark as external so they're not bundled into the JS
external:
- '@prisma/client'
- '.prisma/client'
- '.prisma'
- '@prisma/adapter-pg'
- 'pg'
- 'zod'
- '@aws-sdk/*'
- '@smithy/*'
- '@aws-crypto/*'
# Exclude prevents npm install of these packages in the zip
exclude:
- 'aws-sdk'
serverless-offline:
reloadHandler: true
- '@aws-sdk/*'
- '@smithy/*'
- '@aws-crypto/*'
- '@prisma/adapter-pg'
- '@prisma/client'
- '.prisma'
- '.prisma/client'
- 'pg'
- 'zod'
- 'pg-*'
- 'postgres-*'
- 'pgpass'
- 'split2'
- 'xtend'
# 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:
individually: true
patterns:
- '!node_modules/**'
- '!node_modules/@prisma/**'
- '!node_modules/.prisma/**'
- '!**/*.test.js'
- '!**/*.spec.js'
- '!**/test/**'

View File

@@ -253,28 +253,6 @@ submitCompanyDetails:
- 'src/modules/host/handlers/addCompanyDetails.*'
- 'src/modules/host/services/**'
- 'src/common/**'
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
# Only include specific AWS SDK modules needed for S3
- 'node_modules/@aws-sdk/client-s3/**'
- 'node_modules/@aws-sdk/s3-request-presigner/**'
- 'node_modules/@aws-sdk/types/**'
- 'node_modules/@aws-sdk/middleware-logger/**'
- 'node_modules/@aws-sdk/util-utf8-node/**'
- 'node_modules/@aws-sdk/util-utf8-browser/**'
- 'node_modules/@smithy/**'
- 'node_modules/tslib/**'
# 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:
- httpApi:
path: /host/Host_Admin/onboarding/add-company-details
@@ -291,24 +269,6 @@ submitPQQ_Answer:
- ${file(./serverless/patterns/base.yml):pattern2}
- ${file(./serverless/patterns/base.yml):pattern3}
- ${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:
- httpApi:
path: /host/Activity_Hub/OnBoarding/submit-pqq-answer

View File

@@ -58,22 +58,6 @@ updateMinglarProfile:
- ${file(./serverless/patterns/base.yml):pattern2}
- ${file(./serverless/patterns/base.yml):pattern3}
- ${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:
- httpApi:
path: /minglaradmin/update-profile
@@ -422,3 +406,20 @@ getAllPQPDetailsForAM:
- httpApi:
path: /minglaradmin/hosthub/pqp/pqp-details-for-am/{activityXid}
method: get
getSuggestionsForAM:
handler: src/modules/minglaradmin/handlers/hosthub/onboarding/showSuggestionToAM.handler
memorySize: 384
package:
patterns:
- 'src/modules/minglaradmin/handlers/hosthub/onboarding/showSuggestionToAM**'
- '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/onboarding/show-suggestion-to-am/{hostXid}
method: get

View File

@@ -92,3 +92,18 @@ getFrequenciesOfActivity:
- httpApi:
path: /prepopulate/get-all-Frequencies
method: get
getAddActivityPrePopulate:
handler: src/modules/prepopulate/handlers/getAddActivityPrePopulate.handler
memorySize: 384
package:
patterns:
- 'src/modules/prepopulate/**'
- ${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: /prepopulate/get-add-activity-prepopulate
method: get

View File

@@ -1,6 +1,9 @@
# Base packaging patterns shared across all functions
pattern1: 'src/common/**'
pattern2: 'common/**'
pattern3: 'node_modules/@prisma/client/**'
pattern4: 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
# REMOVED: Prisma is now provided by Lambda layer - DO NOT include in function packages
# pattern3: 'node_modules/@prisma/client/**'
# pattern4: 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
pattern3: '!node_modules/@prisma/**'
pattern4: '!node_modules/.prisma/**'
pattern5: '!node_modules/.prisma/client/libquery_engine*'

View File

@@ -1,11 +1,29 @@
import { PrismaClient } from '@prisma/client';
import { PrismaPg } from '@prisma/adapter-pg';
// Singleton pattern for Prisma client - prevents "Too many database connections" error
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
function createPrismaClient() {
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
export const prisma = new PrismaClient({
return new PrismaClient({
adapter,
log: process.env.NODE_ENV === 'dev' ? ['query', 'info', 'warn', 'error'] : ['error'],
});
}
export const prisma = globalForPrisma.prisma ?? createPrismaClient();
if (process.env.NODE_ENV !== 'production') {
globalForPrisma.prisma = prisma;
}
// For serverless environments, always cache the client
if (process.env.IS_OFFLINE || process.env.AWS_LAMBDA_FUNCTION_NAME) {
globalForPrisma.prisma = prisma;
}

View File

@@ -0,0 +1,5 @@
// Re-export the singleton prisma client for Lambda handlers
// This ensures all Lambda functions use the same cached connection
import { prisma } from './prisma.client';
export const prismaClient = prisma;

View File

@@ -1,5 +1,5 @@
import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { PrismaService } from './prisma.lambda.service';
@Global()
@Module({

View File

@@ -1,15 +1,13 @@
import { Injectable, OnModuleInit, OnModuleDestroy, INestApplication } from '@nestjs/common';
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
import { PrismaPg } from '@prisma/adapter-pg';
import { prisma } from './prisma.client';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
constructor() {
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
super({
adapter,
log: process.env.NODE_ENV === 'dev' ? ['query', 'info', 'warn', 'error'] : ['error'],
});
super();
// Use the singleton instance
Object.assign(this, prisma);
}
async onModuleInit() {
@@ -19,10 +17,4 @@ export class PrismaService extends PrismaClient implements OnModuleInit, OnModul
async onModuleDestroy() {
await this.$disconnect();
}
async enableShutdownHooks(app: INestApplication) {
process.on('beforeExit', async () => {
await app.close();
});
}
}

View File

@@ -49,6 +49,17 @@ export async function verifyHostToken(token: string): Promise<{ id: number; role
include: { role: true },
});
const latestToken = await prisma.token.findFirst({
where: {
userXid: userId
},
orderBy: { id: 'desc' }
})
if (latestToken.isBlackListed == true) {
throw new ApiError(401, "This session is expired. Please login.")
}
if (!user) {
throw new ApiError(httpStatus.UNAUTHORIZED, 'User not found');
}

View File

@@ -49,6 +49,17 @@ export async function verifyMinglarAdminToken(token: string): Promise<{ id: numb
include: { role: true },
});
const latestToken = await prisma.token.findFirst({
where: {
userXid: userId
},
orderBy: { id: 'desc' }
})
if (latestToken.isBlackListed == true) {
throw new ApiError(401, "This session is expired. Please login.")
}
if (!user) {
throw new ApiError(httpStatus.UNAUTHORIZED, 'User not found');
}

View File

@@ -51,6 +51,17 @@ export async function verifyMinglarAdminHostToken(token: string): Promise<{ id:
include: { role: true },
});
const latestToken = await prisma.token.findFirst({
where: {
userXid: userId
},
orderBy: { id: 'desc' }
})
if (latestToken.isBlackListed == true) {
throw new ApiError(401, "This session is expired. Please login.")
}
if (!user) {
throw new ApiError(httpStatus.UNAUTHORIZED, 'User not found');
}

View File

@@ -49,6 +49,17 @@ export async function verifyOnlyMinglarAdminToken(token: string): Promise<{ id:
include: { role: true },
});
const latestToken = await prisma.token.findFirst({
where: {
userXid: userId
},
orderBy: { id: 'desc' }
})
if (latestToken.isBlackListed == true) {
throw new ApiError(401, "This session is expired. Please login.")
}
if (!user) {
throw new ApiError(httpStatus.UNAUTHORIZED, 'User not found');
}

View File

@@ -50,6 +50,17 @@ export async function verifyUserToken(token: string): Promise<{ id: number; role
include: { role: true },
});
const latestToken = await prisma.token.findFirst({
where: {
userXid: userId
},
orderBy: { id: 'desc' }
})
if (latestToken.isBlackListed == true) {
throw new ApiError(401, "This session is expired. Please login.")
}
if (!user) {
throw new ApiError(httpStatus.UNAUTHORIZED, 'User not found');
}

View File

@@ -12,7 +12,6 @@ export interface OtpResult {
export async function resendOtpHelper(
prisma: any,
userId: number,
email: string,
emailPurpose: "Register" | "Login" | "ForgotPassword",
otpLength: 4 | 6 = 4,
expiryMinutes: number = 5

View File

@@ -2,8 +2,8 @@ import { z } from "zod";
export const parentCompanySchema = z.object({
companyName: z.string()
.min(1, "Parent company name is required")
.max(100, "Parent company name cannot exceed 100 characters"),
.max(100, "Parent company name cannot exceed 100 characters")
.optional(),
address1: z.string()
.max(150, "Address1 cannot exceed 150 characters")
@@ -25,8 +25,6 @@ export const parentCompanySchema = z.object({
.max(400, "Logo path cannot exceed 400 characters")
.optional(),
isSubsidairy: z.boolean().optional(),
registrationNumber: z.string()
.max(30, "Registration number cannot exceed 30 characters")
.optional(),
@@ -46,7 +44,7 @@ export const parentCompanySchema = z.object({
}),
companyTypeXid: z.number()
.min(1, "Company type XID is required"),
.optional(),
websiteUrl: z.string().nullable().optional(),
instagramUrl: z.string().nullable().optional(),

View File

@@ -81,6 +81,9 @@ const envVarsSchema = yup
DB_PORT: yup.number().default(3306).required('DB Port is required'),
//OTP Bypass
BYPASS_OTP: yup.boolean().default(false).required('Bypass OTP is required'),
// Email links
AM_INVITATION_LINK: yup.string().required('Link to send in AM invitation mail is required'),
HOST_LINK: yup.string().required('Link to host panel is required')
})
.noUnknown(true);
@@ -158,6 +161,8 @@ function getConfig() {
//Minglar admin
MinglarAdminEmail: envVars.MINGLAR_ADMIN_EMAIL,
MinglarAdminName: envVars.MINGLAR_ADMIN_NAME,
AM_INVITATION_LINK: envVars.AM_INVITATION_LINK,
HOST_LINK: envVars.HOST_LINK,
// oneSignal: {
// appID: envVars.ONESIGNAL_APPID,
// restApiKey: envVars.ONESIGNAL_REST_APIKEY,

View File

@@ -4,13 +4,12 @@ import {
APIGatewayProxyResult,
Context,
} from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.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);
const hostService = new HostService(prismaClient);
export const handler = safeHandler(
async (

View File

@@ -1,14 +1,13 @@
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { HostService } from '../../../services/host.service';
import { PrePopulateService } from '../../../../prepopulate/services/prepopulate.service';
const prismaService = new PrismaService();
const hostService = new HostService(prismaService);
const prePopulateService = new PrePopulateService(prismaService);
const hostService = new HostService(prismaClient);
const prePopulateService = new PrePopulateService(prismaClient);
/**
* Add suggestion handler for host applications

View File

@@ -1,14 +1,13 @@
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { HostService } from '../../../services/host.service';
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
const prismaService = new PrismaService();
const hostService = new HostService(prismaService);
const hostService = new HostService(prismaClient);
/**

View File

@@ -1,12 +1,11 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { HostService } from '../../../services/host.service';
import { verifyMinglarAdminHostToken } from '../../../../../common/middlewares/jwt/authForMinglarAdminHost';
const prismaService = new PrismaService();
const hostService = new HostService(prismaService);
const hostService = new HostService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,

View File

@@ -3,14 +3,13 @@ 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 { prismaClient } from '../../../../../common/database/prisma.lambda.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 hostService = new HostService(prismaClient);
const s3 = new AWS.S3({ region: config.aws.region });

View File

@@ -1,12 +1,11 @@
import { verifyMinglarAdminHostToken } from '../../../../../common/middlewares/jwt/authForMinglarAdminHost';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.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);
const hostService = new HostService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
context?: Context

View File

@@ -1,12 +1,11 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
import { HostService } from '../../../services/host.service';
const prismaService = new PrismaService();
const hostService = new HostService(prismaService);
const hostService = new HostService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
context?: Context

View File

@@ -1,12 +1,11 @@
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.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);
const hostService = new HostService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,

View File

@@ -3,14 +3,13 @@ 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';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
const prisma = new PrismaService();
const hostService = new HostService(prisma);
const hostService = new HostService(prismaClient);
const s3 = new AWS.S3({ region: config.aws.region });

View File

@@ -1,12 +1,11 @@
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.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);
const pqqService = new HostService(prismaClient);
export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
try {

View File

@@ -3,14 +3,13 @@ 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 { prismaClient } from '../../../../../common/database/prisma.lambda.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 pqqService = new HostService(prisma);
const pqqService = new HostService(prismaClient);
const s3 = new AWS.S3({ region: config.aws.region });

View File

@@ -1,12 +1,11 @@
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.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);
const hostService = new HostService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,

View File

@@ -1,12 +1,11 @@
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.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);
const hostService = new HostService(prismaClient);
/**
* Add suggestion handler for host applications

View File

@@ -1,12 +1,11 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { HostService } from '../../../services/host.service';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
const prismaService = new PrismaService();
const hostService = new HostService(prismaService);
const hostService = new HostService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,

View File

@@ -1,15 +1,13 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { HostService } from '../../../services/host.service';
import { TokenService } from '../../../services/token.service';
import { GetHostLoginResponseDTO } from '../../../dto/host.dto';
import ApiError from '../../../../../common/utils/helper/ApiError';
import * as bcrypt from 'bcryptjs';
const prismaService = new PrismaService();
const hostService = new HostService(prismaService);
const tokenService = new TokenService(prismaService);
const hostService = new HostService(prismaClient);
const tokenService = new TokenService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
@@ -30,7 +28,9 @@ export const handler = safeHandler(async (
throw new ApiError(400, 'Email and password are required');
}
const loginForHost = await hostService.loginForHost(emailAddress, userPassword);
const emailToLowerCase = emailAddress.toLowerCase()
const loginForHost = await hostService.loginForHost(emailToLowerCase, userPassword);
if (!loginForHost) {
throw new ApiError(400, 'Failed to login');

View File

@@ -1,12 +1,11 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { MinglarService } from '../../../../minglaradmin/services/minglar.service';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
/**
* Get suggestions handler

View File

@@ -1,15 +1,15 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import * as bcrypt from 'bcryptjs';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { ROLE } from '../../../../../common/utils/constants/common.constant';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { encryptUserId } from '../../../../../common/utils/helper/CodeGenerator';
import { OtpGeneratorSixDigit } from '../../../../../common/utils/helper/OtpGenerator';
import { HostService } from '../../../services/host.service';
import { sendOtpEmailForHost } from '@/modules/host/services/sendOTPEmail.service';
const prismaService = new PrismaService();
const hostService = new HostService(prismaService);
const hostService = new HostService(prismaClient);
export async function generateHostRefNumber(tx: any) {
const lastrecord = await tx.user.findFirst({
@@ -45,10 +45,12 @@ export const handler = safeHandler(async (
throw new ApiError(400, 'Email is required');
}
const emailToLowerCase = email.toLowerCase()
// Use a single transaction for user creation/lookup and OTP storage
const transactionResult = await prismaService.$transaction(async (tx) => {
const transactionResult = await prismaClient.$transaction(async (tx) => {
const user = await tx.user.findUnique({
where: { emailAddress: email },
where: { emailAddress: emailToLowerCase },
select: { emailAddress: true, id: true, userPassword: true },
});
@@ -66,7 +68,7 @@ export const handler = safeHandler(async (
} else {
// create new user record within the transaction
newUserLocal = await tx.user.create({
data: { emailAddress: email, roleXid: ROLE.HOST, userRefNumber: referenceNumber },
data: { emailAddress: emailToLowerCase, roleXid: ROLE.HOST, userRefNumber: referenceNumber },
});
}
@@ -101,7 +103,7 @@ export const handler = safeHandler(async (
}
// Send OTP email outside the DB transaction
// await sendOtpEmailForHost(transactionResult.newUser.emailAddress, transactionResult.otp);
await sendOtpEmailForHost(transactionResult.newUser.emailAddress, transactionResult.otp);
return {
statusCode: 200,

View File

@@ -3,7 +3,7 @@ import config from '../../../../../config/config';
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import AWS from 'aws-sdk';
import Busboy from 'busboy';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
@@ -15,8 +15,17 @@ import {
import { HostService } from '../../../services/host.service';
import { sendEmailToAM, sendEmailToMinglarAdmin } from '../../../services/sendHostResubmitEmailToAM.service';
const prisma = new PrismaService();
const hostService = new HostService(prisma);
const hostService = new HostService(prismaClient);
function getExtensionFromMime(mimeType: string) {
const map: Record<string, string> = {
'image/jpeg': 'jpg',
'image/png': 'png',
'application/pdf': 'pdf',
'image/webp': 'webp',
};
return map[mimeType] || 'bin';
}
const s3 = new AWS.S3({
region: config.aws.region,
@@ -150,13 +159,22 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
}
}
if (
companyDetailsRaw.parentCompany &&
Object.values(companyDetailsRaw.parentCompany).every(
(v) => v === undefined || v === null
)
) {
companyDetailsRaw.parentCompany = null;
}
/** 6) Profile update if provided */
if (fields.userProfile) {
const userProfileRaw = normalizeJsonField(fields, 'userProfile');
if (userProfileRaw) {
const { firstName, lastName, mobileNumber } = userProfileRaw;
await prisma.user.update({
await prismaClient.user.update({
where: { id: userInfo.id },
data: {
...(firstName && { firstName }),
@@ -250,7 +268,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
await deleteFromS3(s3Key);
// Delete from DB
await prisma.hostDocuments.delete({
await prismaClient.hostDocuments.delete({
where: { id }
});
@@ -277,7 +295,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
await deleteFromS3(s3Key);
// Delete DB
await prisma.hostParenetDocuments.delete({
await prismaClient.hostParenetDocuments.delete({
where: { id }
});
@@ -285,11 +303,10 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
}
}
/** 11) UPLOAD DOCUMENTS */
async function uploadToS3(buffer, mimeType, originalName, folderType, documentTypeXid?, fieldName?) {
const ext = originalName.split('.').pop() || 'jpg';
// const ext = originalName.split('.').pop() || 'jpg';
const ext = getExtensionFromMime(mimeType);
let s3Key = '';
@@ -363,31 +380,67 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
}
/** UPLOAD LOGO (if provided) */
const logoFile = files.find((f) => f.fieldName === 'companyLogo' || f.fieldName === 'companyLogoFile');
if (logoFile) {
const logoUrl = await uploadToS3(logoFile.buffer, logoFile.mimeType, logoFile.fileName, 'logo');
const logoFile = files.find(
(f) => f.fieldName === 'companyLogo' || f.fieldName === 'companyLogoFile'
);
if (logoFile && logoFile.buffer && logoFile.fileName) {
const logoUrl = await uploadToS3(
logoFile.buffer,
logoFile.mimeType,
logoFile.fileName,
'logo'
);
parsedCompany.logoPath = logoUrl;
}
/** UPLOAD PARENT COMPANY LOGO (if provided) */
const parentLogoFile = files.find((f) => f.fieldName === 'parentCompanyLogo');
if (parentLogoFile) {
const parentLogoFile = files.find(
(f) => f.fieldName === 'parentCompanyLogo'
);
if (parentLogoFile && parentLogoFile.buffer && parentLogoFile.mimeType) {
// 🔒 Only upload when an actual file is present
const parentLogoUrl = await uploadToS3(
parentLogoFile.buffer,
parentLogoFile.mimeType,
parentLogoFile.fileName,
parentLogoFile.fileName, // safe here because it's a real file
'parent_company_logo',
);
if (parsedParentCompany) {
parsedParentCompany.logoPath = parentLogoUrl;
} else {
// if no parent object exists yet (drafts or other flows), attach it safely
parsedParentCompany = parsedParentCompany || {};
parsedParentCompany.logoPath = parentLogoUrl;
parsedParentCompany = {
logoPath: parentLogoUrl,
};
}
}
if (parsedCompany.cityXid) {
const city = await prismaClient.cities.findUnique({
where: { id: Number(parsedCompany.cityXid) }
});
if (!city) {
throw new ApiError(400, `City with ID ${parsedCompany.cityXid} not found`);
}
}
if (!parsedCompany.isSubsidairy) {
const parentDocuments = await hostService.getParentDocumentsByHostId(userInfo.id);
if (parentDocuments.length > 0) {
for (const doc of parentDocuments) {
try {
const s3Key = getS3KeyFromUrl(doc.filePath);
await deleteFromS3(s3Key);
} catch (e) {
console.error("S3 delete failed:", doc.filePath, e);
}
}
}
await hostService.deleteExistingParentRecords(userInfo.id)
}
/** 12) SAVE / UPDATE HOST ENTRY */
const createdOrUpdated = await hostService.addOrUpdateCompanyDetails(
userInfo.id,

View File

@@ -1,13 +1,12 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { HostService } from '../../../services/host.service';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHost';
import { hostBankDetailsSchema } from '../../../../../common/utils/validation/host/addPaymentDetails.validation';
const prismaService = new PrismaService();
const hostService = new HostService(prismaService);
const hostService = new HostService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
@@ -44,7 +43,7 @@ export const handler = safeHandler(async (
// ✅ Validate payload using Zod
const validationResult = hostBankDetailsSchema.safeParse({
...(body as object),
hostXid: host.id, // inject hostId from token (not from user input)
hostXid: host.host.id, // inject hostId from token (not from user input)
});
if (!validationResult.success) {

View File

@@ -1,13 +1,12 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { HostService } from '../../../services/host.service';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { TokenService } from '../../../services/token.service';
const prismaService = new PrismaService();
const hostService = new HostService(prismaService);
const tokenService = new TokenService(prismaService);
const hostService = new HostService(prismaClient);
const tokenService = new TokenService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
@@ -28,8 +27,10 @@ export const handler = safeHandler(async (
throw new ApiError(400, 'Email and OTP are required');
}
await hostService.verifyHostOtp(email, otp);
const user = await hostService.getHostByEmail(email);
const emailToLowerCase = email.toLowerCase();
await hostService.verifyHostOtp(emailToLowerCase, otp);
const user = await hostService.getHostByEmail(emailToLowerCase);
const generateTokenForHost = await tokenService.generateAuthToken(
user.id
);

View File

@@ -1,12 +1,11 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import { PrismaService } from '../../../common/database/prisma.service';
import { prismaClient } from '../../../common/database/prisma.lambda.service';
import ApiError from '../../../common/utils/helper/ApiError';
import { verifyHostToken } from '../../../common/middlewares/jwt/authForHost';
import { HostService } from '../services/host.service';
const prismaService = new PrismaService();
const hostService = new HostService(prismaService);
const hostService = new HostService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
context?: Context
@@ -28,10 +27,6 @@ export const handler = safeHandler(async (
// Fetch user with their HostHeader stepper info
const host = await hostService.getHostIdByUserXid(userId);
if (!host) {
throw new ApiError(404, 'Host record not found');
}
return {
statusCode: 200,
headers: {
@@ -42,7 +37,8 @@ export const handler = safeHandler(async (
success: true,
message: 'Stepper information retrieved successfully',
data: {
stepper: host.stepper,
stepper: host?.host?.stepper || null,
emailAddress: host.user?.emailAddress || null,
},
}),
};

View File

@@ -1,12 +1,11 @@
import { verifyMinglarAdminHostToken } from '../../../common/middlewares/jwt/authForMinglarAdminHost';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../common/database/prisma.service';
import { prismaClient } from '../../../common/database/prisma.lambda.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);
const hostService = new HostService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,

View File

@@ -1,8 +1,8 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaClient } from '@prisma/client';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import { prismaClient } from '../../../common/database/prisma.lambda.service';
const prisma = new PrismaClient();
const prisma = prismaClient;
export const handler = safeHandler(async (
event: APIGatewayProxyEvent
@@ -11,7 +11,6 @@ export const handler = safeHandler(async (
const result = await prisma.hostHeader.findMany({
select: {
hostParent: true,
hostRefNumber: true,
hostStatusDisplay: true,
accountManager: true,
},

View File

@@ -1,11 +1,11 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda";
import { PrismaService } from "../../../common/database/prisma.service";
import { prismaClient } from "../../../common/database/prisma.lambda.service";
import { safeHandler } from "../../../common/utils/handlers/safeHandler";
import ApiError from "../../../common/utils/helper/ApiError";
import { resendOtpHelper } from "../../../common/utils/helper/resendOtpHelper";
import { resendOtpEmail } from "../services/resendOTPEmail.service";
const prisma = new PrismaService();
const prisma = prismaClient;
// allowed purposes
const ALLOWED_PURPOSES = ["Register", "Login", "ForgotPassword"] as const;
@@ -41,9 +41,11 @@ export const handler = safeHandler(
const email = (body.email || "").trim();
if (!email) throw new ApiError(400, "Email is required");
const emailToLowerCase = email.toLowerCase();
// find user (you can adapt the isActive / userStatus checks per your rules)
const user = await prisma.user.findUnique({
where: { emailAddress: email, isActive: true },
where: { emailAddress: emailToLowerCase, isActive: true },
select: { id: true, emailAddress: true, role: true },
});
@@ -56,7 +58,6 @@ export const handler = safeHandler(
const otpResult = await resendOtpHelper(
prisma,
user.id,
user.emailAddress,
purpose,
6, // 6-digit OTP
5 // expires in 5 minutes

View File

@@ -1,6 +1,5 @@
// src/modules/host/services/host.service.ts
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../../common/database/prisma.service';
import {
AddPaymentDetailsDTO,
CreateHostDto,
@@ -9,28 +8,38 @@ import {
import * as bcrypt from 'bcryptjs';
import ApiError from '../../../common/utils/helper/ApiError';
import { User } from '@prisma/client';
import { PrismaClient } from '@prisma/client';
import { z } from 'zod';
import { hostCompanyDetailsSchema } from '@/common/utils/validation/host/hostCompanyDetails.validation';
import { hostCompanyDetailsSchema } from '../../../common/utils/validation/host/hostCompanyDetails.validation';
import {
ACTIVITY_AM_DISPLAY_STATUS,
ACTIVITY_AM_INTERNAL_STATUS,
ACTIVITY_DISPLAY_STATUS, ACTIVITY_INTERNAL_STATUS, HOST_STATUS_DISPLAY,
HOST_STATUS_INTERNAL,
STEPPER,
} from '@/common/utils/constants/host.constant';
} from '../../../common/utils/constants/host.constant';
import {
ACTIVITY_TRACK_STATUS,
ACTIVITY_TRACK_TYPE,
MINGLAR_STATUS_DISPLAY,
MINGLAR_STATUS_INTERNAL,
} from '@/common/utils/constants/minglar.constant';
} from '../../../common/utils/constants/minglar.constant';
import {
ROLE,
ROLE_NAME,
USER_STATUS,
} from '@/common/utils/constants/common.constant';
import { getPresignedUrl } from '@/common/middlewares/aws/getPreSignedUrl';
import config from '@/config/config';
} from '../../../common/utils/constants/common.constant';
import { getPresignedUrl } from '../../../common/middlewares/aws/getPreSignedUrl';
import config from '../../../config/config';
function sanitizeDocumentName(name?: string) {
if (!name) return null;
return name
.replace(/[^a-zA-Z0-9 _-]/g, '') // remove / .
.substring(0, 100);
}
type HostCompanyDetailsInput = z.infer<typeof hostCompanyDetailsSchema>;
@@ -63,7 +72,7 @@ const bucket = config.aws.bucketName;
@Injectable()
export class HostService {
constructor(private prisma: PrismaService) { }
constructor(private prisma: PrismaClient) { }
async createHost(data: CreateHostDto) {
return this.prisma.user.create({ data });
@@ -76,9 +85,14 @@ export class HostService {
async getHostIdByUserXid(user_xid: number) {
const host = await this.prisma.hostHeader.findFirst({
where: { userXid: user_xid },
select: { id: true, companyName: true, countryXid: true, stepper: true },
select: { id: true, stepper: true },
});
return host;
const user = await this.prisma.user.findUnique({
where: { id: user_xid },
select: { id: true, emailAddress: true },
})
return { host, user };
}
async getHostById(id: number) {
@@ -294,6 +308,10 @@ export class HostService {
select: {
id: true,
roleXid: true,
firstName: true,
lastName: true,
emailAddress: true,
mobileNumber: true,
userPassword: true,
userStatus: true
}
@@ -377,6 +395,19 @@ export class HostService {
async addPaymentDetails(data: AddPaymentDetailsDTO) {
return await this.prisma.$transaction(async (tx) => {
const existingAccount = await tx.hostBankDetails.findFirst({
where: {
accountNumber: data.accountNumber,
isActive: true,
},
});
if (existingAccount) {
throw new ApiError(
400,
'Host account with this account number already exists.'
);
}
const addedPaymentDetails = await tx.hostBankDetails.create({
data,
});
@@ -601,6 +632,52 @@ export class HostService {
});
}
async getParentDocumentsByHostId(userId: number) {
const host = await this.prisma.hostHeader.findFirst({
where: { userXid: userId },
select: { id: true },
});
if (!host) return [];
const parents = await this.prisma.hostParent.findMany({
where: { hostXid: host.id },
include: { HostParenetDocuments: true },
});
return parents.flatMap(p => p.HostParenetDocuments);
}
async deleteExistingParentRecords(userId: number) {
const host = await this.prisma.hostHeader.findFirst({
where: { userXid: userId },
select: { id: true },
});
if (!host) return;
const parents = await this.prisma.hostParent.findMany({
where: { hostXid: host.id },
select: { id: true },
});
if (!parents.length) return;
const parentIds = parents.map(p => p.id);
// 1⃣ Delete documents first
await this.prisma.hostParenetDocuments.deleteMany({
where: { hostParentXid: { in: parentIds } },
});
// 2⃣ Then delete parent records
await this.prisma.hostParent.deleteMany({
where: { id: { in: parentIds } },
});
}
async addOrUpdateCompanyDetails(
user_xid: number,
companyData: HostCompanyDetailsInput,
@@ -615,6 +692,19 @@ export class HostService {
where: { userXid: user_xid },
include: { hostParent: true },
});
console.log(existingHostCompany, "-: Existing hai")
let existingParentCompany;
if (existingHostCompany) {
existingParentCompany = await tx.hostParent.findFirst({
where: { hostXid: existingHostCompany.id },
select: {
id: true,
logoPath: true
}
})
}
let hostStatusInternal;
let hostStatusDisplay;
@@ -678,12 +768,14 @@ export class HostService {
// -------------------------------------------------------
if (!existingHostCompany) {
if (!isDraft) {
console.log("First time direct final submit.")
const existingByPan = await tx.hostHeader.findFirst({
where: { panNumber: companyData.panNumber },
});
if (existingByPan)
throw new ApiError(400, 'Company already exists with this pan/bin number');
}
console.log("First Time Aaya hai")
const createdHost = await tx.hostHeader.create({
data: {
@@ -725,7 +817,7 @@ export class HostService {
const docsData = documents.map((doc) => ({
hostXid: createdHost.id,
documentTypeXid: doc.documentTypeXid,
documentName: doc.documentName,
documentName: sanitizeDocumentName(doc.documentName),
filePath: doc.filePath,
}));
await tx.hostDocuments.createMany({ data: docsData });
@@ -733,20 +825,24 @@ export class HostService {
// parent create
if (companyData.isSubsidairy && parentCompanyData) {
console.log("Parent ke saath aaya hai first time.")
const createdParent = await tx.hostParent.create({
data: {
host: { connect: { id: createdHost.id } },
companyName: parentCompanyData.companyName,
companyName: parentCompanyData.companyName || null,
address1: parentCompanyData.address1 || null,
address2: parentCompanyData.address2 || null,
cities: parentCompanyData.cityXid
? { connect: { id: parentCompanyData.cityXid } }
// Safely handle city connection - only connect if valid ID exists
cities: parentCompanyData?.cityXid && !isNaN(Number(parentCompanyData.cityXid))
? { connect: { id: Number(parentCompanyData.cityXid) } }
: undefined,
states: parentCompanyData.stateXid
? { connect: { id: parentCompanyData.stateXid } }
states: parentCompanyData?.stateXid && !isNaN(Number(parentCompanyData.stateXid))
? { connect: { id: Number(parentCompanyData.stateXid) } }
: undefined,
countries: parentCompanyData.countryXid
? { connect: { id: parentCompanyData.countryXid } }
countries: parentCompanyData?.countryXid && !isNaN(Number(parentCompanyData.countryXid))
? { connect: { id: Number(parentCompanyData.countryXid) } }
: undefined,
pinCode: parentCompanyData.pinCode || null,
logoPath: parentCompanyData.logoPath || null,
@@ -772,7 +868,7 @@ export class HostService {
const parentDocsData = parentDocuments.map((doc) => ({
hostParentXid: createdParent.id,
documentTypeXid: doc.documentTypeXid,
documentName: doc.documentName,
documentName: sanitizeDocumentName(doc.documentName),
filePath: doc.filePath,
}));
await tx.hostParenetDocuments.createMany({ data: parentDocsData });
@@ -801,11 +897,22 @@ export class HostService {
companyName: companyData.companyName,
address1: companyData.address1,
address2: companyData.address2,
cities: companyData.cityXid ? { connect: { id: companyData.cityXid } } : undefined,
states: companyData.stateXid ? { connect: { id: companyData.stateXid } } : undefined,
countries: companyData.countryXid ? { connect: { id: companyData.countryXid } } : undefined,
// Safely handle city connection - only connect if valid ID exists
cities: companyData.cityXid && !isNaN(Number(companyData.cityXid))
? { connect: { id: Number(companyData.cityXid) } }
: undefined, // Don't change if not provided
// Same for state
states: companyData.stateXid && !isNaN(Number(companyData.stateXid))
? { connect: { id: Number(companyData.stateXid) } }
: undefined,
// Same for country
countries: companyData.countryXid && !isNaN(Number(companyData.countryXid))
? { connect: { id: Number(companyData.countryXid) } }
: undefined,
pinCode: companyData.pinCode,
logoPath: companyData.logoPath || null,
logoPath: companyData.logoPath || existingHostCompany.logoPath,
isSubsidairy: companyData.isSubsidairy,
registrationNumber: companyData.registrationNumber,
panNumber: companyData.panNumber,
@@ -833,6 +940,7 @@ export class HostService {
// documents UPSERT
if (documents?.length) {
for (const doc of documents) {
if (!doc.filePath) continue;
const existingDoc = await tx.hostDocuments.findFirst({
where: {
hostXid: updatedHost.id,
@@ -845,7 +953,7 @@ export class HostService {
where: { id: existingDoc.id },
data: {
filePath: doc.filePath,
documentName: doc.documentName || existingDoc.documentName,
documentName: sanitizeDocumentName(doc.documentName) || existingDoc.documentName,
},
});
} else {
@@ -853,7 +961,7 @@ export class HostService {
data: {
hostXid: updatedHost.id,
documentTypeXid: doc.documentTypeXid,
documentName: doc.documentName,
documentName: sanitizeDocumentName(doc.documentName),
filePath: doc.filePath,
},
});
@@ -865,25 +973,28 @@ export class HostService {
if (companyData.isSubsidairy) {
const parentRecords = existingHostCompany.hostParent;
const parentRecord = Array.isArray(parentRecords) ? parentRecords[0] : parentRecords;
console.log("Yaha aaya update in the apretn me")
if (!parentRecord) {
console.log("Parent record nahi mila to create kar raha hai.")
const createdParent = await tx.hostParent.create({
data: {
host: { connect: { id: updatedHost.id } },
companyName: parentCompanyData.companyName,
companyName: parentCompanyData.companyName || null,
address1: parentCompanyData.address1 || null,
address2: parentCompanyData.address2 || null,
cities: parentCompanyData.cityXid
? { connect: { id: parentCompanyData.cityXid } }
cities: parentCompanyData?.cityXid && !isNaN(Number(parentCompanyData.cityXid))
? { connect: { id: Number(parentCompanyData.cityXid) } }
: undefined,
states: parentCompanyData.stateXid
? { connect: { id: parentCompanyData.stateXid } }
states: parentCompanyData?.stateXid && !isNaN(Number(parentCompanyData.stateXid))
? { connect: { id: Number(parentCompanyData.stateXid) } }
: undefined,
countries: parentCompanyData.countryXid
? { connect: { id: parentCompanyData.countryXid } }
countries: parentCompanyData?.countryXid && !isNaN(Number(parentCompanyData.countryXid))
? { connect: { id: Number(parentCompanyData.countryXid) } }
: undefined,
pinCode: parentCompanyData.pinCode || null,
logoPath: parentCompanyData.logoPath || null,
logoPath: parentCompanyData?.logoPath || existingParentCompany?.logoPath || null,
registrationNumber: parentCompanyData.registrationNumber || null,
panNumber: parentCompanyData.panNumber || null,
gstNumber: parentCompanyData.gstNumber || null,
@@ -907,7 +1018,7 @@ export class HostService {
data: {
hostParentXid: createdParent.id,
documentTypeXid: doc.documentTypeXid,
documentName: doc.documentName,
documentName: sanitizeDocumentName(doc.documentName),
filePath: doc.filePath,
},
});
@@ -917,20 +1028,22 @@ export class HostService {
await tx.hostParent.update({
where: { id: parentRecord.id },
data: {
companyName: parentCompanyData.companyName,
companyName: parentCompanyData.companyName || null,
address1: parentCompanyData.address1 || null,
address2: parentCompanyData.address2 || null,
cities: parentCompanyData.cityXid
? { connect: { id: parentCompanyData.cityXid } }
cities: parentCompanyData?.cityXid && !isNaN(Number(parentCompanyData.cityXid))
? { connect: { id: Number(parentCompanyData.cityXid) } }
: undefined,
states: parentCompanyData.stateXid
? { connect: { id: parentCompanyData.stateXid } }
states: parentCompanyData?.stateXid && !isNaN(Number(parentCompanyData.stateXid))
? { connect: { id: Number(parentCompanyData.stateXid) } }
: undefined,
countries: parentCompanyData.countryXid
? { connect: { id: parentCompanyData.countryXid } }
countries: parentCompanyData?.countryXid && !isNaN(Number(parentCompanyData.countryXid))
? { connect: { id: Number(parentCompanyData.countryXid) } }
: undefined,
pinCode: parentCompanyData.pinCode || null,
logoPath: parentCompanyData.logoPath || null,
logoPath: parentCompanyData?.logoPath || existingParentCompany?.logoPath || null,
registrationNumber: parentCompanyData.registrationNumber || null,
panNumber: parentCompanyData.panNumber || null,
gstNumber: parentCompanyData.gstNumber || null,
@@ -962,7 +1075,7 @@ export class HostService {
where: { id: existingParentDoc.id },
data: {
filePath: doc.filePath,
documentName: doc.documentName || existingParentDoc.documentName,
documentName: sanitizeDocumentName(doc.documentName) || existingParentDoc.documentName,
},
});
} else {
@@ -970,7 +1083,7 @@ export class HostService {
data: {
hostParentXid: parentRecord.id,
documentTypeXid: doc.documentTypeXid,
documentName: doc.documentName,
documentName: sanitizeDocumentName(doc.documentName),
filePath: doc.filePath,
},
});
@@ -979,6 +1092,7 @@ export class HostService {
}
}
} else {
console.log("Last ke else block me aaya hai")
const previousParent = existingHostCompany.hostParent;
let prevParentId = null;
@@ -1761,6 +1875,7 @@ export class HostService {
isActive: true,
},
select: {
id: true,
comments: true,
pqqAnswerXid: true,
pqqQuestions: {
@@ -1826,15 +1941,20 @@ export class HostService {
const sub = q.pqqSubCategories;
const cat = sub.category;
// 1⃣ Category level
// 1⃣ Category level
if (!grouped[cat.id]) {
grouped[cat.id] = {
id: cat.id,
categoryName: cat.categoryName,
displayOrder: cat.displayOrder,
activityPqqHeaderId: item.id, // ✅ Added to match AM response
pqqsubCategories: []
};
} else if (!grouped[cat.id].activityPqqHeaderId) {
grouped[cat.id].activityPqqHeaderId = item.id; // Ensures it's set if missing
}
const category = grouped[cat.id];
// 2⃣ Subcategory level

View File

@@ -15,8 +15,8 @@ export async function resendOtpEmail(
const htmlContent = `
<p>Dear ${role},</p>
<p>Your new OTP is: <strong>${otp}</strong></p>
<p>This code is valid for 5 minutes. Please do not share it with anyone.</p>
<p>Best regards,<br/>Minglar Team</p>
<p>This code will be valid for the next 5 minutes.</p>
<p>Warm regards,<br/>Minglar Team</p>
`;
try {

View File

@@ -13,9 +13,10 @@ export async function sendOtpEmailForHost(
const htmlContent = `
<p>Dear Host,</p>
<p>Your OTP for registration is: <strong>${otp}</strong></p>
<p>This code is valid for 5 minutes. Please do not share it with anyone.</p>
<p>Best regards,<br/>Minglar Team</p>
<p>Youre almost all set! 🎉</p>
<p>Enter <strong>${otp}</strong> to wrap your registration.</p>
<p>This code will be valid for the next 5 minutes.</p>
<p>Warm regards,<br/>Minglar Team</p>
`;
try {

View File

@@ -1,10 +1,10 @@
import { PrismaService } from "../../../common/database/prisma.service";
import { PrismaClient } from '@prisma/client';
import jwt, { JwtPayload } from "jsonwebtoken";
import moment from "moment";
import config from "../../../config/config";
export class TokenService {
constructor(private readonly prisma: PrismaService = new PrismaService()) {}
constructor(private prisma: PrismaClient) { }
private generateToken(
user_xid: number,
@@ -53,6 +53,10 @@ export class TokenService {
config.jwt.secret
);
await this.prisma.token.deleteMany({
where: { userXid: user_xid }
})
await this.prisma.token.create({
data: {
token: refreshToken.token,
@@ -100,6 +104,10 @@ export class TokenService {
config.jwt.secret
);
await this.prisma.token.deleteMany({
where: { userXid: user_xid }
})
await this.prisma.token.create({
data: {
token: refreshToken.token,

View File

@@ -1,12 +1,11 @@
import { verifyMinglarAdminToken } from '../../../common/middlewares/jwt/authForMinglarAdmin';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../common/database/prisma.service';
import { prismaClient } from '../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import ApiError from '../../../common/utils/helper/ApiError';
import { MinglarService } from '../services/minglar.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,

View File

@@ -3,14 +3,13 @@ import {
APIGatewayProxyResult,
Context,
} from 'aws-lambda';
import { PrismaService } from '../../../common/database/prisma.service';
import { prismaClient } from '../../../common/database/prisma.lambda.service';
import { verifyMinglarAdminToken } from '../../../common/middlewares/jwt/authForMinglarAdmin';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import ApiError from '../../../common/utils/helper/ApiError';
import { MinglarService } from '../services/minglar.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
/**
* Get all host applications handler

View File

@@ -1,13 +1,12 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { sendEmailToHostForApprovedApplication } from '../../../services/approvalMailtoHost.service';
import { MinglarService } from '../../../services/minglar.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
interface AddSuggestionBody {
hostXid: number;
@@ -47,8 +46,8 @@ export const handler = safeHandler(async (
// Add suggestion using service
await minglarService.acceptHostApplication(hostXid, userInfo.id);
const hostDetails = await minglarService.getUserDetails(userInfo.id)
await sendEmailToHostForApprovedApplication(hostDetails.emailAddress)
const hostDetails = await minglarService.getUserDetails(hostXid)
await sendEmailToHostForApprovedApplication(hostDetails.emailAddress, hostDetails.firstName)
return {
statusCode: 200,

View File

@@ -1,12 +1,16 @@
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 { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { sendAMPQQAcceptanceMailtoHost } from '../../../../minglaradmin/services/approvalMailtoHost.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
interface Body {
activityId: number;
}
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
@@ -17,7 +21,16 @@ export const handler = safeHandler(async (
const userInfo = await verifyMinglarAdminToken(token);
const activityId = event.pathParameters?.activityId;
// Parse request body
let body: Body;
try {
body = event.body ? JSON.parse(event.body) : {};
} catch (error) {
throw new ApiError(400, 'Invalid JSON in request body');
}
const { activityId } = body;
if (!activityId) {
throw new ApiError(400, 'activityId is required');
@@ -27,6 +40,9 @@ export const handler = safeHandler(async (
Number(activityId),
Number(userInfo.id)
);
const hostXid = await minglarService.getHostXidByActivityId(activityId)
const hostDetails = await minglarService.getUserDetails(hostXid)
await sendAMPQQAcceptanceMailtoHost(hostDetails.emailAddress, hostDetails.firstName)
return {
statusCode: 201,

View File

@@ -1,13 +1,12 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { MinglarService } from '../../../services/minglar.service';
// import { HOST_SUGGESTION_TITLES } from '../../../../../common/utils/constants/minglar.constant';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
interface AddSuggestionBody {
title: string;
@@ -34,7 +33,7 @@ export const handler = safeHandler(async (
const userInfo = await verifyMinglarAdminToken(token);
// Get user details
const user = await prismaService.user.findUnique({
const user = await prismaClient.user.findUnique({
where: { id: userInfo.id },
select: { id: true, roleXid: true }
});

View File

@@ -1,12 +1,11 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { MinglarService } from '../../../services/minglar.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
interface AddSuggestionBody {
hostXid: number;
@@ -34,7 +33,7 @@ export const handler = safeHandler(async (
const userInfo = await verifyMinglarAdminToken(token);
// Get user details
const user = await prismaService.user.findUnique({
const user = await prismaClient.user.findUnique({
where: { id: userInfo.id },
select: { id: true, roleXid: true }
});

View File

@@ -1,13 +1,12 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
import { MinglarService } from '../../../services/minglar.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
/**
* Get all host applications handler with pagination
@@ -26,7 +25,7 @@ export const handler = safeHandler(async (
const userInfo = await verifyMinglarAdminToken(token);
// Get user details including role
const user = await prismaService.user.findUnique({
const user = await prismaClient.user.findUnique({
where: { id: userInfo.id },
select: { id: true, roleXid: true }
});

View File

@@ -1,12 +1,11 @@
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
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 { MinglarService } from '../../../services/minglar.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,

View File

@@ -1,13 +1,12 @@
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { MinglarService } from '../../../services/minglar.service';
import { sendAMRejectionMailtoHost } from '../../../services/rejectionMailtoHost.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
interface AddSuggestionBody {
hostXid: number;
@@ -47,8 +46,8 @@ export const handler = safeHandler(async (
// Add suggestion using service
await minglarService.rejectHostApplicationAM(hostXid, userInfo.id);
const hostDetails = await minglarService.getUserDetails(userInfo.id)
await sendAMRejectionMailtoHost(hostDetails.emailAddress)
const hostDetails = await minglarService.getUserDetails(hostXid)
await sendAMRejectionMailtoHost(hostDetails.emailAddress, hostDetails.firstName)
return {
statusCode: 200,

View File

@@ -1,12 +1,16 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { MinglarService } from '../../../services/minglar.service';
import { sendAMPQQRejectionMailtoHost } from '../../../../minglaradmin/services/rejectionMailtoHost.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
interface Body {
activityId: number;
}
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
@@ -17,7 +21,16 @@ export const handler = safeHandler(async (
const userInfo = await verifyMinglarAdminToken(token);
const activityId = event.pathParameters?.activityId;
// Parse request body
let body: Body;
try {
body = event.body ? JSON.parse(event.body) : {};
} catch (error) {
throw new ApiError(400, 'Invalid JSON in request body');
}
const { activityId } = body;
if (!activityId) {
throw new ApiError(400, 'activityId is required');
@@ -27,6 +40,9 @@ export const handler = safeHandler(async (
Number(activityId),
Number(userInfo.id)
);
const hostXid = await minglarService.getHostXidByActivityId(activityId)
const hostDetails = await minglarService.getUserDetails(hostXid)
await sendAMPQQRejectionMailtoHost(hostDetails.emailAddress, hostDetails.firstName)
return {
statusCode: 201,

View File

@@ -3,14 +3,13 @@ import {
APIGatewayProxyResult,
Context,
} from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { MinglarService } from '../../../services/minglar.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
interface assignAMToHostBody {
host_xid: number;
@@ -40,7 +39,7 @@ export const handler = safeHandler(
const userInfo = await verifyOnlyMinglarAdminToken(token);
// Get user details including role
const user = await prismaService.user.findUnique({
const user = await prismaClient.user.findUnique({
where: { id: userInfo.id },
select: { id: true, roleXid: true },
});

View File

@@ -1,12 +1,11 @@
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { MinglarService } from '../../../services/minglar.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
interface assignAMToHostBody {
host_xid: number,
@@ -34,7 +33,7 @@ export const handler = safeHandler(async (
const userInfo = await verifyOnlyMinglarAdminToken(token);
// Get user details including role
const user = await prismaService.user.findUnique({
const user = await prismaClient.user.findUnique({
where: { id: userInfo.id },
select: { id: true, roleXid: true }
});

View File

@@ -1,15 +1,14 @@
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { PrePopulateService } from '../../../../prepopulate/services/prepopulate.service';
import { MinglarService } from '../../../services/minglar.service';
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const prePopulateService = new PrePopulateService(prismaService);
const minglarService = new MinglarService(prismaClient);
const prePopulateService = new PrePopulateService(prismaClient);
/**
* Add suggestion handler for host applications

View File

@@ -4,14 +4,13 @@ import {
APIGatewayProxyResult,
Context,
} from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
import { MinglarService } from '../../../services/minglar.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
/**
* Get all host applications handler
@@ -36,7 +35,7 @@ export const handler = safeHandler(
const userInfo = await verifyOnlyMinglarAdminToken(token);
// Get user details including role
const user = await prismaService.user.findUnique({
const user = await prismaClient.user.findUnique({
where: { id: userInfo.id },
select: { id: true, roleXid: true },
});

View File

@@ -3,15 +3,14 @@ import {
APIGatewayProxyResult,
Context,
} from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
import { MinglarService } from '../../../services/minglar.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
/**
* Get all NEW host applications handler
@@ -36,7 +35,7 @@ export const handler = safeHandler(
const userInfo = await verifyOnlyMinglarAdminToken(token);
// Get user details including role
const user = await prismaService.user.findUnique({
const user = await prismaClient.user.findUnique({
where: { id: userInfo.id },
select: { id: true, roleXid: true },
});

View File

@@ -1,13 +1,12 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { MinglarService } from '../../../services/minglar.service';
import { sendEmailToHostForRejectedApplication } from '../../../services/rejectionMailtoHost.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
interface AddSuggestionBody {
hostXid: number;
@@ -47,7 +46,7 @@ export const handler = safeHandler(async (
// Add suggestion using service
await minglarService.rejectHostApplication(hostXid, userInfo.id);
const hostDetails = await minglarService.getUserDetails(userInfo.id)
const hostDetails = await minglarService.getUserDetails(hostXid)
if (!hostDetails?.emailAddress) {
throw new ApiError(404, 'Host details or email address not found');
}

View File

@@ -0,0 +1,51 @@
import { verifyMinglarAdminToken } from '@/common/middlewares/jwt/authForMinglarAdmin';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { MinglarService } from '../../../../minglaradmin/services/minglar.service';
const minglarService = new MinglarService(prismaClient);
/**
* Get suggestions handler
* Retrieves suggestions based on user's role and host assignments
*/
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
await verifyMinglarAdminToken(token);
const hostXid = Number(event.pathParameters?.hostXid)
if (!hostXid) {
throw new ApiError(
400,
'Host ID is required in path parameters.',
);
}
// Get suggestions using service
const suggestions = await minglarService.getSuggestionsForAM(hostXid);
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
body: JSON.stringify({
success: true,
message: 'Suggestions retrieved successfully',
data: suggestions,
}),
};
});

View File

@@ -1,12 +1,11 @@
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.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);
const minglarService = new MinglarService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,

View File

@@ -1,14 +1,13 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../common/database/prisma.service';
import { prismaClient } from '../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import ApiError from '../../../common/utils/helper/ApiError';
import { GetMinglarLoginResponseDTO } from '../dto/minglar.dto';
import { MinglarService } from '../services/minglar.service';
import { TokenService } from "../services/token.service";
const prismaService = new PrismaService();
const minglarSerivce = new MinglarService(prismaService);
const tokenService = new TokenService(prismaService);
const minglarSerivce = new MinglarService(prismaClient);
const tokenService = new TokenService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
@@ -29,7 +28,9 @@ export const handler = safeHandler(async (
throw new ApiError(400, 'Email is required');
}
const loginForMinglar = await minglarSerivce.loginForMinglar(emailAddress ,userPassword);
const emailToLowerCase = emailAddress.toLowerCase()
const loginForMinglar = await minglarSerivce.loginForMinglar(emailToLowerCase, userPassword);
if (!loginForMinglar) {
throw new ApiError(400, 'Failed to login');

View File

@@ -3,13 +3,13 @@ import {
APIGatewayProxyResult,
Context,
} from 'aws-lambda';
import { PrismaService } from '../../../common/database/prisma.service';
import { prismaClient } from '../../../common/database/prisma.lambda.service';
import { verifyMinglarAdminToken } from '../../../common/middlewares/jwt/authForMinglarAdmin';
import { ROLE } from '../../../common/utils/constants/common.constant';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import ApiError from '../../../common/utils/helper/ApiError';
const prismaService = new PrismaService();
const prismaService = prismaClient;
export const handler = safeHandler(
async (
event: APIGatewayProxyEvent,

View File

@@ -1,13 +1,13 @@
import { ROLE, USER_STATUS } from '../../../common/utils/constants/common.constant';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../common/database/prisma.service';
import { prismaClient } from '../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import ApiError from '../../../common/utils/helper/ApiError';
import { generateOtpHelper } from '../../../common/utils/helper/sendOtp';
import { MinglarService } from './../services/minglar.service';
import { sendOtpEmailForMinglarAdmin } from '../services/sendOTPEmail.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
@@ -27,11 +27,15 @@ export const handler = safeHandler(async (
if (!email) {
throw new ApiError(400, 'Email is required');
}
console.log(email, " -: Email")
const user = await prismaService.user.findUnique({
where: { emailAddress: email, isActive: true, userStatus: USER_STATUS.INVITED },
const emailToLowerCase = email.toLowerCase()
const user = await prismaClient.user.findUnique({
where: { emailAddress: emailToLowerCase, isActive: true, userStatus: USER_STATUS.INVITED },
select: { emailAddress: true, id: true, userPassword: true, roleXid: true },
});
console.log(user, "sljdfjdf")
if (!user) {
throw new ApiError(403, 'You are not allowed to register directly. Please contact minglar admin.');
@@ -54,7 +58,7 @@ export const handler = safeHandler(async (
}
const otpResult = await generateOtpHelper(
prismaService, // ⭐ pass Prisma from here
prismaClient, // ⭐ pass Prisma from here
Number(newUser?.id),
newUser?.emailAddress,
'Register',
@@ -67,7 +71,7 @@ export const handler = safeHandler(async (
throw new ApiError(500, 'Failed to send OTP');
}
// await sendOtpEmailForMinglarAdmin(newUser?.emailAddress, otpResult.otp);
await sendOtpEmailForMinglarAdmin(newUser?.emailAddress, otpResult.otp);
return {
statusCode: 200,

View File

@@ -1,12 +1,11 @@
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { MinglarService } from '../../../services/minglar.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,

View File

@@ -4,14 +4,13 @@ import {
APIGatewayProxyResult,
Context,
} from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { MinglarService } from '../../../services/minglar.service';
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
export const handler = safeHandler(
async (

View File

@@ -4,14 +4,13 @@ import {
APIGatewayProxyResult,
Context,
} from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { MinglarService } from '../../../services/minglar.service';
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
export const handler = safeHandler(
async (

View File

@@ -1,14 +1,14 @@
import { verifyOnlyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForOnlyMinglarAdmin';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../../../common/database/prisma.service';
import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
import { ROLE } from '../../../../../common/utils/constants/common.constant';
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { sendInvitationEmailForMinglarAdmin } from '../../../services/inviteTeammatesEmail.service';
import { MinglarService } from '../../../services/minglar.service';
import config from '../../../../../config/config';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
interface InviteTeammateBody {
emailAddress: string;
@@ -61,6 +61,8 @@ export const handler = safeHandler(async (
throw new ApiError(400, 'Role is required');
}
const emailToLowerCase = emailAddress.toLowerCase()
// 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.');
@@ -79,7 +81,7 @@ export const handler = safeHandler(async (
// Use single service method that encapsulates the transaction
await minglarService.inviteTeammate(
emailAddress,
emailToLowerCase,
roleXid,
isFixedSalary,
perValue || 0,
@@ -87,7 +89,7 @@ export const handler = safeHandler(async (
);
// send email after transaction commits
await sendInvitationEmailForMinglarAdmin(emailAddress);
await sendInvitationEmailForMinglarAdmin(emailToLowerCase, config.AM_INVITATION_LINK);
return {
statusCode: 200,

View File

@@ -2,15 +2,14 @@
import config from '../../../config/config';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import AWS from 'aws-sdk';
import { PrismaService } from '../../../common/database/prisma.service';
import { prismaClient } from '../../../common/database/prisma.lambda.service';
import { verifyMinglarAdminToken } from '../../../common/middlewares/jwt/authForMinglarAdmin';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import ApiError from '../../../common/utils/helper/ApiError';
import { parseJsonField, parseMultipartFormData } from '../../../common/utils/helper/parseMultipartFormData';
import { MinglarService } from '../services/minglar.service';
const prismaService = new PrismaService();
const minglarService = new MinglarService(prismaService);
const minglarService = new MinglarService(prismaClient);
const s3 = new AWS.S3({
region: config.aws.region,

View File

@@ -1,10 +1,10 @@
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../../common/database/prisma.service';
import { prismaClient } from '../../../common/database/prisma.lambda.service';
import { sendAMEmailForHostAssign } from './AMEmail.service';
@Injectable()
export class AMNotificationService {
constructor(private prisma: PrismaService) {}
private prisma = prismaClient;
/**
* Fetch account manager email by id and send assignment email.

View File

@@ -1,8 +1,10 @@
import { brevoService } from "@/common/email/brevoApi";
import ApiError from "@/common/utils/helper/ApiError";
import { brevoService } from "../../../common/email/brevoApi";
import ApiError from "../../../common/utils/helper/ApiError";
import config from "../../../config/config";
export async function sendEmailToHostForApprovedApplication(
emailAddress: string,
name: string
): Promise<{
sent: boolean;
// messageId: string
@@ -11,9 +13,11 @@ export async function sendEmailToHostForApprovedApplication(
const subject = "Approval for your application";
const htmlContent = `
<p>Dear Host,</p>
<p>Dear ${name},</p>
<p>Congratulations, Your application to minglar admin has been approved.</p>
<p>You can start onboarding your activities through the host panel.</p>
<p> You can login to your account using the link below:<br/>
<strong>Link:</strong> ${config.HOST_LINK} </p>
<p>Best regards,<br/>Minglar Team</p>
`;
@@ -70,3 +74,41 @@ export async function sendEmailToHostForMinglarApproval(
throw new ApiError(500, "Failed to send OTP to minglar admin via email.");
}
}
export async function sendAMPQQAcceptanceMailtoHost(
emailAddress: string,
name: string
): Promise<{
sent: boolean;
// messageId: string
}> {
const subject = "Approval for your activity onboarding application";
const htmlContent = `
<p>Dear ${name},</p>
<p>Congratulations, Your activity onboarding application to minglar admin has been approved.</p>
<p>You can start adding other details of your activity through the host panel.</p>
<p> You can login to your account using the link below:<br/>
<strong>Link:</strong> ${config.HOST_LINK} </p>
<p>Best regards,<br/>Minglar Team</p>
`;
try {
const result = await brevoService.sendEmail({
recipients: [{ email: emailAddress }],
subject,
htmlContent,
});
console.log("📧 Email sent successfully:", result);
return {
sent: true,
// messageId: result.messageId
};
} catch (err) {
console.error("Brevo email send failed:", err);
throw new ApiError(500, "Failed to send OTP to minglar admin via email.");
}
}

View File

@@ -3,6 +3,7 @@ import ApiError from "@/common/utils/helper/ApiError";
export async function sendInvitationEmailForMinglarAdmin(
emailAddress: string,
link: string
): Promise<{
sent: boolean;
// messageId: string
@@ -11,9 +12,19 @@ export async function sendInvitationEmailForMinglarAdmin(
const subject = "Minglar Admin: Your Team Invitation";
const htmlContent = `
<p>Dear,</p>
<p>You are invited to join the Minglar Admin team. Please click the link below to create your account.</p>
<p>Best regards,<br/>Minglar Admin Team</p>
<p>Hi there,</p>
<p>We're excited to invite you to join the <strong>Minglar Admin Team</strong>!<br/>
Please use the link below to set up your account and get started.</p>
<p><strong>Access Your Invitation:</strong><br/>
<a href="${link}">${link}</a></p>
<p>If you have any questions or need assistance, feel free to reach out — were here to help.<br/>
We look forward to having you on board!</p>
<p>Welcome aboard!<br/>
<strong>The Minglar Admin Team</strong></p>
`;
try {

View File

@@ -26,6 +26,7 @@ import { Injectable } from '@nestjs/common';
import { User } from '@prisma/client';
import * as bcrypt from 'bcryptjs';
import { PrismaService } from '../../../common/database/prisma.service';
import { PrismaClient } from '@prisma/client';
import ApiError from '../../../common/utils/helper/ApiError';
import { CreateMinglarDto, UpdateMinglarDto } from '../dto/minglar.dto';
import { sendAMEmailForHostAssign } from './AMEmail.service';
@@ -34,7 +35,7 @@ const bucket = config.aws.bucketName;
@Injectable()
export class MinglarService {
constructor(private prisma: PrismaService) { }
constructor(private prisma: PrismaService | PrismaClient) { }
async createPassword(user_xid: number, password: string): Promise<boolean> {
// Find user by id
@@ -135,10 +136,21 @@ export class MinglarService {
return this.prisma.user.findUnique({ where: { emailAddress: email } });
}
async getHostXidByActivityId(activityId: number) {
const activityDetails = await this.prisma.activities.findFirst({
where: { id: activityId }
})
return activityDetails.hostXid;
}
async getUserDetails(id: number) {
return await this.prisma.user.findUnique({
where: { id: id },
const hostDetail = await this.prisma.hostHeader.findFirst({
where: { id: id }
})
const userDetails = await this.prisma.user.findUnique({
where: { id: hostDetail.userXid },
});
return userDetails;
}
async verifyHostOtp(email: string, otp: string): Promise<boolean> {
@@ -260,6 +272,7 @@ export class MinglarService {
async getAllHostActivityForMinglar(search?: string, hostXid?: number, paginationOptions?: { page: number; limit: number; skip: number }) {
const whereClause: any = {
isActive: true,
activityInternalStatus: { notIn: [ACTIVITY_INTERNAL_STATUS.DRAFT_PQ] },
...(hostXid ? { hostXid } : {}),
};
@@ -600,6 +613,7 @@ export class MinglarService {
mobileNumber: true,
dateOfBirth: true,
profileImage: true,
roleXid: true,
userAddressDetails: {
where: { isActive: true },
take: 1,
@@ -628,51 +642,10 @@ export class MinglarService {
throw new ApiError(404, 'User not found after update');
}
// 5. Calculate profile completion percentage
// let percentage = 0;
// // Profile Image: 15%
// if (updatedUser.profileImage) percentage += 15;
// // Name and Phone Number: 15%
// if (
// updatedUser.firstName &&
// updatedUser.lastName &&
// updatedUser.mobileNumber
// ) {
// percentage += 15;
// }
// // Location Info: 25%
// if (updatedUser.userAddressDetails.length > 0) {
// const address = updatedUser.userAddressDetails[0];
// if (
// address.address1 &&
// address.stateXid &&
// address.countryXid &&
// address.cityXid &&
// address.pinCode
// ) {
// percentage += 25;
// }
// }
// // Documents: 45%
// if (updatedUser.userDocuments.length >= 2) {
// percentage += 45;
// } else if (updatedUser.userDocuments.length === 1) {
// percentage += 22.5;
// }
// const profilePercentage = Math.min(percentage, 100);
// Update profile completion status
// if (profilePercentage > 75) {
await tx.user.update({
where: { id: userId },
data: { isProfileUpdated: true },
});
// }
console.log('Transaction completed successfully');
@@ -684,6 +657,7 @@ export class MinglarService {
mobileNumber: updatedUser.mobileNumber,
dateOfBirth: updatedUser.dateOfBirth,
profileImage: updatedUser.profileImage,
roleXid: updatedUser.roleXid,
},
address: updatedUser.userAddressDetails[0] || null,
documents: updatedUser.userDocuments,
@@ -1449,6 +1423,25 @@ export class MinglarService {
return suggestions;
}
async getSuggestionsForAM(hostXid: number) {
const suggestions = await this.prisma.hostSuggestion.findMany({
where: { hostXid: hostXid, isreviewed: false, isActive: true },
select: {
id: true,
title: true,
comments: true,
isparent: true,
isreviewed: true,
reviewOn: true,
},
orderBy: {
id: 'asc',
},
});
return suggestions;
}
async acceptHostApplication(host_xid: number, user_xid: number) {
return await this.prisma.$transaction(async (tx) => {
await this.prisma.hostHeader.update({

View File

@@ -1,5 +1,6 @@
import { brevoService } from "@/common/email/brevoApi";
import ApiError from "@/common/utils/helper/ApiError";
import { brevoService } from "../../../common/email/brevoApi";
import ApiError from "../../../common/utils/helper/ApiError";
import config from "../../../config/config";
export async function sendEmailToHostForRejectedApplication(
emailAddress: string,
@@ -38,6 +39,7 @@ export async function sendEmailToHostForRejectedApplication(
export async function sendAMRejectionMailtoHost(
emailAddress: string,
name: string
): Promise<{
sent: boolean;
// messageId: string
@@ -46,11 +48,60 @@ export async function sendAMRejectionMailtoHost(
const subject = "Improvement of your application";
const htmlContent = `
<p>Dear Host,</p>
<p>Your account manager has made some suggestions on your application.<br/>
Please improve it and re-submit the application to onboard on minglar.</p>
<p>If you have any questions please contact to minglar admin.</p>
<p>Best regards,<br/>Minglar Team</p>
<p>Dear ${name},</p>
<p> Your account manager has reviewed your application and provided some suggestions. <br/>
Please make the necessary improvements and re-submit your application to proceed with the onboarding process on Minglar.</p>
<p> You may access your application using the link below:<br/>
<strong>Link:</strong> ${config.HOST_LINK} </p>
<p> If you have any questions, please feel free to contact the Minglar Support Team. </p>
<p> Best regards,<br/>
<strong>Minglar Team</strong> </p>
`;
try {
const result = await brevoService.sendEmail({
recipients: [{ email: emailAddress }],
subject,
htmlContent,
});
console.log("📧 Email sent successfully:", result);
return {
sent: true,
// messageId: result.messageId
};
} catch (err) {
console.error("Brevo email send failed:", err);
throw new ApiError(500, "Failed to send OTP to minglar admin via email.");
}
}
export async function sendAMPQQRejectionMailtoHost(
emailAddress: string,
name: string
): Promise<{
sent: boolean;
// messageId: string
}> {
const subject = "Improvement of your activity onboarding application";
const htmlContent = `
<p>Dear ${name},</p>
<p>Your account manager has reviewed your activity application and provided some suggestions.<br/>
Please make the necessary improvements and re-submit your activity application along with the pre-qualification answers to proceed with the onboarding process on Minglar.</p>
<p>You may access your activity onboarding application using the link below:<br/>
<strong>Link:</strong> ${config.HOST_LINK}</p>
<p>If you have any questions, please feel free to contact the Minglar Support Team.</p>
<p>Best regards,<br/>
<strong>Minglar Team</strong></p>
`;
try {

View File

@@ -1,10 +1,10 @@
import { PrismaService } from "../../../common/database/prisma.service";
import { PrismaClient } from '@prisma/client';
import jwt, { JwtPayload } from "jsonwebtoken";
import moment from "moment";
import config from "../../../config/config";
export class TokenService {
constructor(private readonly prisma: PrismaService = new PrismaService()) {}
constructor(private prisma: PrismaClient) { }
private generateToken(
user_xid: number,

View File

@@ -0,0 +1,38 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { prismaClient } from '../../../common/database/prisma.lambda.service';
import { verifyMinglarAdminHostToken } from '../../../common/middlewares/jwt/authForMinglarAdminHost';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import ApiError from '../../../common/utils/helper/ApiError';
import { PrePopulateService } from '../services/prepopulate.service';
const prePopulateService = new PrePopulateService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
context?: Context
): Promise<APIGatewayProxyResult> => {
// Extract token from headers
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.');
}
// Authenticate user using the shared authForHost function
await verifyMinglarAdminHostToken(token);
const result = await prePopulateService.getAllPrePopulateDataForAddActivity();
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
body: JSON.stringify({
success: true,
message: 'Data retrieved successfully',
data: result,
}),
};
});

View File

@@ -1,12 +1,11 @@
import { verifyMinglarAdminHostToken } from '../../../common/middlewares/jwt/authForMinglarAdminHost';
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../common/database/prisma.service';
import { prismaClient } from '../../../common/database/prisma.lambda.service';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import ApiError from '../../../common/utils/helper/ApiError';
import { PrePopulateService } from '../services/prepopulate.service';
const prismaService = new PrismaService();
const prePopulateService = new PrePopulateService(prismaService);
const prePopulateService = new PrePopulateService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,

View File

@@ -1,12 +1,11 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../common/database/prisma.service';
import { prismaClient } from '../../../common/database/prisma.lambda.service';
import { verifyMinglarAdminHostToken } from '../../../common/middlewares/jwt/authForMinglarAdminHost';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import ApiError from '../../../common/utils/helper/ApiError';
import { PrePopulateService } from '../services/prepopulate.service';
const prismaService = new PrismaService();
const prePopulateService = new PrePopulateService(prismaService);
const prePopulateService = new PrePopulateService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,

View File

@@ -1,12 +1,11 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../common/database/prisma.service';
import { prismaClient } from '../../../common/database/prisma.lambda.service';
import { verifyMinglarAdminHostToken } from '../../../common/middlewares/jwt/authForMinglarAdminHost';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import ApiError from '../../../common/utils/helper/ApiError';
import { PrePopulateService } from '../services/prepopulate.service';
const prismaService = new PrismaService();
const prePopulateService = new PrePopulateService(prismaService);
const prePopulateService = new PrePopulateService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,

View File

@@ -1,12 +1,11 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaService } from '../../../common/database/prisma.service';
import { prismaClient } from '../../../common/database/prisma.lambda.service';
import { verifyMinglarAdminHostToken } from '../../../common/middlewares/jwt/authForMinglarAdminHost';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import ApiError from '../../../common/utils/helper/ApiError';
import { PrePopulateService } from '../services/prepopulate.service';
const prismaService = new PrismaService();
const prePopulateService = new PrePopulateService(prismaService);
const prePopulateService = new PrePopulateService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,

View File

@@ -1,12 +1,11 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from "aws-lambda";
import { PrismaService } from "../../../common/database/prisma.service";
import { prismaClient } from "../../../common/database/prisma.lambda.service";
import { verifyMinglarAdminHostToken } from "../../../common/middlewares/jwt/authForMinglarAdminHost";
import { safeHandler } from "../../../common/utils/handlers/safeHandler";
import ApiError from "../../../common/utils/helper/ApiError";
import { PrePopulateService } from "../services/prepopulate.service";
const prismaService = new PrismaService();
const prePopulateService = new PrePopulateService(prismaService);
const prePopulateService = new PrePopulateService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,

View File

@@ -1,12 +1,11 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from "aws-lambda";
import { PrismaService } from "../../../common/database/prisma.service";
import { prismaClient } from "../../../common/database/prisma.lambda.service";
import { verifyMinglarAdminHostToken } from "../../../common/middlewares/jwt/authForMinglarAdminHost";
import { safeHandler } from "../../../common/utils/handlers/safeHandler";
import ApiError from "../../../common/utils/helper/ApiError";
import { PrePopulateService } from "../services/prepopulate.service";
const prismaService = new PrismaService();
const prePopulateService = new PrePopulateService(prismaService);
const prePopulateService = new PrePopulateService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,

View File

@@ -1,9 +1,8 @@
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../../common/database/prisma.service';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrePopulateService {
constructor(private prisma: PrismaService) { }
constructor(private prisma: PrismaClient) { }
async getAllBankDetails() {
return await this.prisma.banks.findMany({
@@ -142,4 +141,62 @@ export class PrePopulateService {
},
});
}
async getAllPrePopulateDataForAddActivity() {
const [
foodType,
cuisineDetails,
vehicleType,
navigationMode,
taxDetails,
energyLevel,
aminitiesDetails,
allowedEntryType,
ageRestrictionDetails
] =
await this.prisma.$transaction([
this.prisma.foodTypes.findMany({
where: { isActive: true },
orderBy: { foodTypeName: 'asc' },
}),
this.prisma.foodCuisines.findMany({
where: { isActive: true },
}),
this.prisma.transportModes.findMany({
where: { isActive: true },
}),
this.prisma.navigationModes.findMany({
where: { isActive: true },
}),
this.prisma.taxes.findMany({
where: { isActive: true },
}),
this.prisma.energyLevels.findMany({
where: { isActive: true },
}),
this.prisma.amenities.findMany({
where: { isActive: true },
}),
this.prisma.allowedEntryTypes.findMany({
where: { isActive: true },
orderBy: { allowedEntryTypeName: 'asc' }
}),
this.prisma.ageRestrictions.findMany({
where: { isActive: true },
orderBy: { ageRestrictionName: 'asc' }
}),
]);
return {
foodType,
cuisineDetails,
vehicleType,
navigationMode,
taxDetails,
energyLevel,
aminitiesDetails,
allowedEntryType,
ageRestrictionDetails
};
}
}