Merge branch 'dev' into alpha

This commit is contained in:
Stephanos A.
2026-05-22 18:19:36 +03:00
committed by GitHub
19 changed files with 9102 additions and 1042 deletions

7
.dockerignore Normal file
View File

@@ -0,0 +1,7 @@
**/node_modules
**/dist
**/.github
**/.vscode
**/.git
**/.env
.env

96
.github/workflows/deploy.yaml vendored Normal file
View File

@@ -0,0 +1,96 @@
name: Automatic Deployment
on:
push:
branches:
- dev
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
environment:
name: 🌍 Setup Environment
runs-on: [self-hosted]
outputs:
target: ${{ steps.dev.outputs.target || steps.staging.outputs.target }}
steps:
- name: Verify NPM Token
env:
# We map the secret here to check its existence
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
if [ -z "$NPM_TOKEN" ]; then
echo "::error::The NPM_TOKEN secret is missing or empty. Please add it to your GitHub Secrets."
exit 1
fi
echo "NPM_TOKEN is present, proceeding with build..."
- name: 🛠️ Set Development Environment
id: dev
if: ${{github.ref_name == 'dev'}}
run: |
echo "target=dev" >> $GITHUB_OUTPUT
- name: 🚀 Set Staging Environment
id: staging
if: ${{github.ref_name == 'staging'}}
run: |
echo "target=staging" >> $GITHUB_OUTPUT
build-base-image:
name: 🏗️ Build Base Image
runs-on: [self-hosted, dev]
needs: [environment]
steps:
- name: 🔍 Checkout
uses: actions/checkout@v4
- name: 🐳 Build Docker Image
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
set -euo pipefail
# Create the multi-line file
cat <<EOF > .npmrc_temp
@tria-plc:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
always-auth=true
EOF
# Build using the file
docker build --secret id=npmrc,src=.npmrc_temp -t edr-${{needs.environment.outputs.target}} .
docker build --secret id=npmrc,src=.npmrc_temp --target passenger-migration -t edr-passenger-migration-${{needs.environment.outputs.target}} .
# Shred/Remove the sensitive file
rm .npmrc_temp
deploy-service:
name: ${{ matrix.display_name }}
runs-on: [self-hosted, dev]
needs: [build-base-image, environment]
strategy:
fail-fast: false
matrix:
include:
- service: freight-api
env_file: .env.freight-api
display_name: 🚚 Deploy Freight API Service
- service: passenger-api
env_file: .env.passenger-api
display_name: 🧑‍🦲 Deploy Passenger API Service
steps:
- name: 🔍 Checkout
uses: actions/checkout@v4
- name: 📋 Copy ${{ matrix.service }} Environment
run: cp ~/environment/edr/${{needs.environment.outputs.target}}/${{ matrix.env_file }} .env
- name: 🧪 Run Passenger API migrations
if: ${{ matrix.service == 'passenger-api' }}
run: |
docker run --rm --env-file .env edr-passenger-migration-${{needs.environment.outputs.target}}
- name: 🚀 Start ${{ matrix.service }} Service
run: docker compose --project-name="edr-${{needs.environment.outputs.target}}" up -d --force-recreate ${{ matrix.service }} --build

3
.gitignore vendored
View File

@@ -21,4 +21,5 @@ coverage/
# OS/editor # OS/editor
.DS_Store .DS_Store
.idea/ .idea/
.vscode/ .vscode/
.npmrc

84
Dockerfile Normal file
View File

@@ -0,0 +1,84 @@
FROM node:24.15.0 AS base
RUN corepack enable && corepack prepare pnpm@latest-11 --activate
WORKDIR /app
FROM base AS deps
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
COPY apps/edr-freight-api/package.json ./apps/edr-freight-api/
COPY apps/edr-passenger-api/package.json ./apps/edr-passenger-api/
COPY apps/edr-freight-web/backoffice/package.json ./apps/edr-freight-web/backoffice/
COPY apps/edr-freight-web/portal/package.json ./apps/edr-freight-web/portal/
COPY apps/edr-passenger-web/backoffice/package.json ./apps/edr-passenger-web/backoffice/
COPY apps/edr-passenger-web/portal/package.json ./apps/edr-passenger-web/portal/
COPY packages/api-common/package.json packages/api-common/
COPY packages/config/eslint-config/package.json packages/config/eslint-config/
COPY packages/config/prettier-config/package.json packages/config/prettier-config/
COPY packages/config/tsconfig/package.json packages/config/tsconfig/
COPY packages/types/package.json packages/types/
COPY packages/ui-common/package.json packages/ui-common/
RUN --mount=type=cache,id=pnpm,target=/pnpm/store\
--mount=type=secret,id=npmrc,target=./.npmrc \
pnpm install --frozen-lockfile
FROM deps AS build
COPY . .
RUN pnpm run build
FROM base AS freight-api
# RUN corepack enable && corepack prepare pnpm@9.12.0 --activate
WORKDIR /app/apps/edr-freight-api
ENV NODE_ENV=production
COPY --from=deps /app/node_modules ./../../node_modules
COPY --from=deps /app/apps/edr-freight-api/node_modules ./node_modules
COPY --from=build /app/apps/edr-freight-api/dist ./dist
COPY --from=build /app/apps/edr-freight-api/package.json ./package.json
COPY --from=build /app/packages ./../../packages
EXPOSE 3001
CMD ["node", "dist/main.js"]
FROM base AS passenger-api
RUN apt-get update -y && apt-get install -y openssl
# RUN corepack enable && corepack prepare pnpm@9.12.0 --activate
WORKDIR /app/apps/edr-passenger-api
ENV NODE_ENV=production
# Use build-stage node_modules (not deps): `pnpm run build` runs `prisma generate`, which
# writes the real @prisma/client (enums, types). deps never runs generate, so @IsEnum(ServiceClass)
# and similar would see undefined at runtime if we copied deps only.
COPY --from=build /app/node_modules ./../../node_modules
COPY --from=build /app/apps/edr-passenger-api/node_modules ./node_modules
COPY --from=build /app/apps/edr-passenger-api/dist ./dist
COPY --from=build /app/apps/edr-passenger-api/package.json ./package.json
COPY --from=build /app/packages ./../../packages
EXPOSE 3001
CMD ["node", "dist/main.js"]
FROM build as passenger-migration
WORKDIR /app/apps/edr-passenger-api
CMD pnpm run prisma:migrate && pnpm run prisma:seed
FROM nginx:1.27-alpine AS freight-web-portal
COPY --from=build /app/apps/edr-freight-web/portal/dist /usr/share/nginx/html
EXPOSE 5173
CMD ["nginx", "-g", "daemon off;"]
FROM nginx:1.27-alpine AS freight-web-backoffice
COPY --from=build /app/apps/edr-freight-web/backoffice/dist /usr/share/nginx/html
EXPOSE 5173
CMD ["nginx", "-g", "daemon off;"]

View File

@@ -1,26 +0,0 @@
FROM node:20-alpine AS base
RUN corepack enable && corepack prepare pnpm@9.12.0 --activate
WORKDIR /app
FROM base AS deps
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
COPY apps/edr-freight-api/package.json ./apps/edr-freight-api/
COPY packages ./packages
RUN pnpm install --frozen-lockfile --filter @edr/freight-api...
FROM deps AS build
COPY apps/edr-freight-api ./apps/edr-freight-api
RUN pnpm --filter @edr/freight-api build
FROM node:20-alpine AS runtime
RUN corepack enable && corepack prepare pnpm@9.12.0 --activate
WORKDIR /app/apps/edr-freight-api
ENV NODE_ENV=production
COPY --from=deps /app/node_modules ./../../node_modules
COPY --from=deps /app/apps/edr-freight-api/node_modules ./node_modules
COPY --from=build /app/apps/edr-freight-api/dist ./dist
COPY --from=build /app/apps/edr-freight-api/package.json ./package.json
EXPOSE 3001
CMD ["node", "dist/main.js"]

View File

@@ -1,18 +0,0 @@
FROM node:20-alpine AS base
RUN corepack enable && corepack prepare pnpm@9.12.0 --activate
WORKDIR /app
FROM base AS deps
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
COPY apps/edr-freight-web/backoffice/package.json ./apps/edr-freight-web/backoffice/
COPY packages ./packages
RUN pnpm install --frozen-lockfile --filter @edr/freight-backoffice...
FROM deps AS build
COPY apps/edr-freight-web/backoffice ./apps/edr-freight-web/backoffice
RUN pnpm --filter @edr/freight-backoffice build
FROM nginx:1.27-alpine AS runtime
COPY --from=build /app/apps/edr-freight-web/backoffice/dist /usr/share/nginx/html
EXPOSE 5183
CMD ["nginx", "-g", "daemon off;"]

View File

@@ -1,18 +0,0 @@
FROM node:20-alpine AS base
RUN corepack enable && corepack prepare pnpm@9.12.0 --activate
WORKDIR /app
FROM base AS deps
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
COPY apps/edr-freight-web/portal/package.json ./apps/edr-freight-web/portal/
COPY packages ./packages
RUN pnpm install --frozen-lockfile --filter @edr/freight-portal...
FROM deps AS build
COPY apps/edr-freight-web/portal ./apps/edr-freight-web/portal
RUN pnpm --filter @edr/freight-portal build
FROM nginx:1.27-alpine AS runtime
COPY --from=build /app/apps/edr-freight-web/portal/dist /usr/share/nginx/html
EXPOSE 5173
CMD ["nginx", "-g", "daemon off;"]

View File

@@ -1,28 +0,0 @@
FROM node:20-alpine AS base
RUN corepack enable && corepack prepare pnpm@9.12.0 --activate
WORKDIR /app
FROM base AS deps
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
COPY apps/edr-passenger-api/package.json ./apps/edr-passenger-api/
COPY packages ./packages
RUN pnpm install --frozen-lockfile --filter @edr/passenger-api...
FROM deps AS build
COPY apps/edr-passenger-api ./apps/edr-passenger-api
RUN pnpm --filter @edr/passenger-api run prisma:generate
RUN pnpm --filter @edr/passenger-api build
FROM node:20-alpine AS runtime
RUN corepack enable && corepack prepare pnpm@9.12.0 --activate
WORKDIR /app/apps/edr-passenger-api
ENV NODE_ENV=production
COPY --from=deps /app/node_modules ./../../node_modules
COPY --from=deps /app/apps/edr-passenger-api/node_modules ./node_modules
COPY --from=build /app/apps/edr-passenger-api/dist ./dist
COPY --from=build /app/apps/edr-passenger-api/package.json ./package.json
COPY --from=build /app/apps/edr-passenger-api/prisma ./prisma
EXPOSE 4000
CMD ["node", "dist/main.js"]

View File

@@ -1,7 +1,9 @@
{ {
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics", "collection": "@nestjs/schematics",
"sourceRoot": "src", "sourceRoot": "src",
"compilerOptions": { "compilerOptions": {
"deleteOutDir": true,
"plugins": ["@nestjs/swagger"], "plugins": ["@nestjs/swagger"],
"tsConfigPath": "tsconfig.build.json", "tsConfigPath": "tsconfig.build.json",
"watchAssets": true "watchAssets": true

View File

@@ -4,7 +4,7 @@
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "nest start --watch", "dev": "nest start --watch",
"build": "nest build", "build": "prisma generate && nest build",
"start": "node dist/main.js", "start": "node dist/main.js",
"start:prod": "node dist/main.js", "start:prod": "node dist/main.js",
"lint": "eslint src", "lint": "eslint src",

View File

@@ -1,19 +1,18 @@
import 'reflect-metadata'; import "reflect-metadata";
import { NestFactory } from '@nestjs/core'; import { NestFactory } from "@nestjs/core";
import { ValidationPipe } from '@nestjs/common'; import { ValidationPipe } from "@nestjs/common";
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
import { AppModule } from './app.module'; import { AppModule } from "./app.module";
import { HttpExceptionFilter } from './common/filters/http-exception.filter'; import { HttpExceptionFilter } from "./common/filters/http-exception.filter";
import { ResponseTransformInterceptor } from './common/interceptors/response-transform.interceptor'; import { ResponseTransformInterceptor } from "./common/interceptors/response-transform.interceptor";
import { SessionActivityInterceptor } from './common/interceptors/session-activity.interceptor';
async function bootstrap() { async function bootstrap() {
const app = await NestFactory.create(AppModule); const app = await NestFactory.create(AppModule);
app.enableCors({ app.enableCors({
origin: [ origin: [
process.env.FRONTEND_URL ?? 'http://localhost:3000', process.env.FRONTEND_URL ?? "http://localhost:3000",
process.env.PORTAL_URL ?? 'http://localhost:3001', process.env.PORTAL_URL ?? "http://localhost:3001",
], ],
}); });
@@ -25,196 +24,43 @@ async function bootstrap() {
app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true })); app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true }));
const config = new DocumentBuilder() const config = new DocumentBuilder()
.setTitle('EDR Passenger API') .setTitle("EDR Passenger API")
.setDescription( .setDescription(
`# Ethio-Djibouti Railway Passenger Booking API "Ethio-Djibouti Railway Passenger API — booking lifecycle, seat inventory, payment (Telebirr, CBE Birr, eBirr, Card, Wallet), loyalty, live tracking, and support.",
## Overview
Enterprise-grade REST API for the Ethio-Djibouti Railway passenger booking and management platform. Built with NestJS, TypeScript, PostgreSQL, and Prisma ORM.
## Authentication
### Passenger Authentication (JWT-auth)
Used for passenger-facing endpoints. Obtain token via \`POST /auth/login\`.
**Usage:** Add header \`Authorization: Bearer <token>\`
### Back-office Authentication (IAM-auth)
Used for agent, fraud, and reporting endpoints. Requires corporate IAM token.
**Usage:** Add header \`Authorization: Bearer <iam-token>\`
## Key Features
### 🎫 Booking Lifecycle
- Search trips with real-time availability
- Create bookings with seat selection
- Modify bookings (seat changes, passenger updates)
- Cancel bookings with automatic refunds
- Multi-segment journey support
### 💳 Payment Integration
- **Telebirr** - Ethiopia's leading mobile money
- **CBE Birr** - Commercial Bank of Ethiopia
- **eBirr** - Electronic payment gateway
- **Card** - International card payments
- **Wallet** - Internal wallet system
### 🪑 Seat Management
- Real-time seat availability
- Seat holds (15-minute expiry)
- Auto-assign seats with contiguous algorithm
- Seat blocking for maintenance
- Coach-level seat maps
### 🎟️ Ticketing
- QR code and barcode generation
- PDF ticket generation
- Gate validation with audit logs
- Offline validation support
### 🏆 Loyalty Program
- 4 tiers: Bronze, Silver, Gold, Platinum
- Points accumulation on trips
- Reward redemption
- Tier-based benefits
### 💰 Wallet System
- Top-up via payment methods
- Pay with wallet balance
- Transaction ledger
- Refund to wallet
### 📍 Live Tracking
- Real-time trip status
- Location updates
- Delay notifications
- Station crowd signals
### 🔒 Fraud Detection
- Velocity checks (multiple bookings)
- High-value transaction monitoring
- Failed payment pattern detection
- Automatic user blocking
### 🌍 Internationalization
- Multi-language support (English, Amharic, French, Oromo)
- Locale-based responses
- Currency formatting
### 👨‍💼 Agent Operations
- Counter booking
- Shift management
- Commission tracking
- Cash reconciliation
## Rate Limiting
- Auth endpoints: 5 requests/minute
- General endpoints: 100 requests/minute
- Webhook endpoints: No limit
## Error Handling
All errors follow standard format:
\`\`\`json
{
"statusCode": 400,
"message": "Validation failed",
"error": "Bad Request",
"timestamp": "2026-05-20T14:30:00.000Z",
"path": "/bookings"
}
\`\`\`
## Pagination
List endpoints support pagination:
- \`limit\`: Number of items (default: 20, max: 100)
- \`offset\`: Skip items (default: 0)
## Webhooks
Payment providers send notifications to:
- \`POST /payments/webhooks/telebirr\`
- \`POST /payments/webhooks/cbe-birr\`
- \`POST /payments/webhooks/ebirr\`
- \`POST /payments/webhooks/card\`
## Support
- **Email:** support@edr-platform.com
- **Documentation:** https://docs.edr-platform.com
- **Status Page:** https://status.edr-platform.com
`,
) )
.setVersion('1.0.0') .setVersion("1.0.0")
.addBearerAuth( .addBearerAuth(
{ { type: "http", scheme: "bearer", bearerFormat: "JWT", in: "header" },
type: 'http', "JWT-auth",
scheme: 'bearer',
bearerFormat: 'JWT',
in: 'header',
description: 'JWT token for passenger authentication. Obtain via POST /auth/login'
},
'JWT-auth'
) )
.addBearerAuth( .addTag("Auth", "Registration and login")
{ .addTag("Stations", "Station directory")
type: 'http', .addTag("Fleet", "Train services and coaches")
scheme: 'bearer', .addTag("Schedule", "Trips and fare rules")
bearerFormat: 'JWT', .addTag("Search", "Trip search and fare quotes")
in: 'header', .addTag("Seats", "Seat maps and holds")
description: 'Corporate IAM token for back-office operations (agents, fraud, reports)' .addTag("Booking", "Booking lifecycle")
}, .addTag("Payment", "Payment intents and refunds")
'IAM-auth' .addTag("Tickets", "QR ticket generation and validation")
) .addTag("Passenger", "Profiles, traveler profiles, saved routes")
.addTag('Auth', '🔐 Registration, login, OTP verification, password reset') .addTag("Notifications", "Push and email notifications")
.addTag('Agents', '👨‍💼 Agent booking, shifts, commissions, reconciliation') .addTag("Loyalty", "Points, tiers, and rewards")
.addTag('Booking', '🎫 Booking lifecycle, modification, cancellation, refunds') .addTag("Wallet", "Wallet balance and ledger")
.addTag('Dashboard', '📊 Home dashboard aggregated data') .addTag("Promotions", "Promo codes and campaigns")
.addTag('Fleet', '🚂 Trains, physical coaches, seat auto-generation, coach-to-schedule assignments') .addTag("Live Tracking", "Real-time trip status and crowd signals")
.addTag('Seat Classes', '🎨 Seat class management and configuration') .addTag("Support", "FAQ and chat support")
.addTag('Fraud Detection', '🔒 Fraud detection, risk scoring, user blocking') .addTag("Dashboard", "Home dashboard aggregate")
.addTag('Live Tracking', '📍 Real-time trip status, location updates, crowd signals') //.addServer('http://localhost:4000', 'Development')
.addTag('Loyalty', '🏆 Points accumulation, tier management, rewards redemption') // .addServer("https://api.edr-platform.com", "Production")
.addTag('Notifications', '🔔 Push, email, SMS notifications, preferences')
.addTag('Passenger', '👤 Profiles, traveler profiles, saved routes, preferences')
.addTag('Payment', '💳 Payment intents, status queries, refunds')
.addTag('Payment Webhooks', '🔗 Payment provider callback endpoints')
.addTag('Promotions', '🎁 Promo codes, campaigns, discount validation')
.addTag('Reports', '📈 Revenue reports, occupancy analytics, agent sales')
.addTag('Routes', '🗺️ Reusable route templates with ordered stops — referenced by schedules')
.addTag('Schedule', '🗓️ Train schedules (created from routes), stop time management, fare rules')
.addTag('Search', '🔍 Trip search, availability, fare quotes')
.addTag('Seats', '🪑 Seat maps, holds, releases, blocking, auto-assign')
.addTag('Segment-based Seats', '🎯 Segment-based seat availability and booking')
.addTag('Stations', '🚉 Station directory, information, crowd signals')
.addTag('Support', '💬 FAQ management, live chat conversations')
.addTag('Tickets', '🎟️ QR/barcode generation, PDF tickets, gate validation')
.addTag('Wallet', '💰 Wallet balance, top-up, transaction ledger')
.addServer('http://localhost:4000', 'Local Development')
.addServer('https://api-staging.edr-platform.com', 'Staging Environment')
.addServer('https://api.edr-platform.com', 'Production')
.build(); .build();
const document = SwaggerModule.createDocument(app, config); const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api-docs', app, document, { SwaggerModule.setup("api-docs", app, document, {
customSiteTitle: 'EDR Passenger API Documentation', customSiteTitle: "EDR Passenger API",
customfavIcon: 'https://edr-platform.com/favicon.ico', swaggerOptions: {
customCss: ` persistAuthorization: true,
.swagger-ui .topbar { display: none } docExpansion: "none",
.swagger-ui .info { margin: 20px 0 }
.swagger-ui .info .title { font-size: 36px; font-weight: bold }
.swagger-ui .scheme-container { background: #fafafa; padding: 15px; border-radius: 4px }
`,
swaggerOptions: {
persistAuthorization: true,
docExpansion: 'none',
filter: true, filter: true,
tagsSorter: 'alpha',
operationsSorter: 'alpha',
displayRequestDuration: true,
tryItOutEnabled: true,
syntaxHighlight: {
activate: true,
theme: 'monokai'
}
}, },
}); });

View File

@@ -1,18 +0,0 @@
FROM node:20-alpine AS base
RUN corepack enable && corepack prepare pnpm@9.12.0 --activate
WORKDIR /app
FROM base AS deps
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
COPY apps/edr-passenger-web/backoffice/package.json ./apps/edr-passenger-web/backoffice/
COPY packages ./packages
RUN pnpm install --frozen-lockfile --filter @edr/passenger-backoffice...
FROM deps AS build
COPY apps/edr-passenger-web/backoffice ./apps/edr-passenger-web/backoffice
RUN pnpm --filter @edr/passenger-backoffice build
FROM nginx:1.27-alpine AS runtime
COPY --from=build /app/apps/edr-passenger-web/backoffice/dist /usr/share/nginx/html
EXPOSE 5184
CMD ["nginx", "-g", "daemon off;"]

View File

@@ -1,18 +0,0 @@
FROM node:20-alpine AS base
RUN corepack enable && corepack prepare pnpm@9.12.0 --activate
WORKDIR /app
FROM base AS deps
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
COPY apps/edr-passenger-web/portal/package.json ./apps/edr-passenger-web/portal/
COPY packages ./packages
RUN pnpm install --frozen-lockfile --filter @edr/passenger-portal...
FROM deps AS build
COPY apps/edr-passenger-web/portal ./apps/edr-passenger-web/portal
RUN pnpm --filter @edr/passenger-portal build
FROM nginx:1.27-alpine AS runtime
COPY --from=build /app/apps/edr-passenger-web/portal/dist /usr/share/nginx/html
EXPOSE 5174
CMD ["nginx", "-g", "daemon off;"]

View File

@@ -7,8 +7,8 @@ export default defineConfig({
port: 5184, port: 5184,
host: "0.0.0.0", host: "0.0.0.0",
}, },
test: { // test: {
environment: "jsdom", // environment: "jsdom",
globals: true, // globals: true,
}, // },
}); });

View File

@@ -7,8 +7,8 @@ export default defineConfig({
port: 5174, port: 5174,
host: "0.0.0.0", host: "0.0.0.0",
}, },
test: { // test: {
environment: "jsdom", // environment: "jsdom",
globals: true, // globals: true,
}, // },
}); });

21
docker-compose.yaml Normal file
View File

@@ -0,0 +1,21 @@
services:
freight-api:
build:
context: .
dockerfile: ./Dockerfile
target: freight-api
env_file:
- .env
ports:
- ${PORT}:${PORT}
restart: unless-stopped
passenger-api:
build:
context: .
dockerfile: ./Dockerfile
target: passenger-api
env_file:
- .env
ports:
- ${PORT}:${PORT}
restart: unless-stopped

View File

@@ -42,7 +42,7 @@
"prettier --write" "prettier --write"
] ]
}, },
"packageManager": "pnpm@9.12.0", "packageManager": "pnpm@11.1.1+sha512.d1fdf5f73c617b64fa1a56a81c3c8dfe0e966e33a6010aa256b517ae77be21d93e05affc0de1a83b0e4f29d569f68b446ae8f068cd7247c0bb3df0fb4d7bdf9a",
"engines": { "engines": {
"node": ">=20" "node": ">=20"
} }

9539
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,21 @@
packages: packages:
- "apps/edr-freight-api"
- "apps/edr-freight-web/*"
- "apps/edr-passenger-api" - "apps/edr-passenger-api"
- "apps/edr-passenger-web/*" - "apps/edr-passenger-web/*"
- "packages/*" - "packages/*"
- "packages/config/*" - "packages/config/*"
allowBuilds:
'@nestjs/core': true
'@prisma/client': true
'@prisma/engines': true
'@scarf/scarf': true
argon2: true
bcrypt: true
core-js: true
es5-ext: true
esbuild: true
highlight.js: true
prisma: true
tesseract.js: true
uglifyjs-webpack-plugin: true