From f0b309b65caf01b06bd6346e74b04942e26b15e9 Mon Sep 17 00:00:00 2001 From: Michael Abebe Date: Fri, 15 May 2026 16:25:39 +0300 Subject: [PATCH 1/5] dep(freight:api): added latest iamapi packages for api, docker compose dev for removed passenger --- apps/edr-freight-api/package.json | 6 +++--- infrastructure/docker/docker-compose.db.dev.yml | 16 ---------------- pnpm-lock.yaml | 4 ++-- 3 files changed, 5 insertions(+), 21 deletions(-) diff --git a/apps/edr-freight-api/package.json b/apps/edr-freight-api/package.json index 09a312ad6..f320815dc 100644 --- a/apps/edr-freight-api/package.json +++ b/apps/edr-freight-api/package.json @@ -13,8 +13,6 @@ "type-check": "tsc --noEmit" }, "dependencies": { - "@tria-plc/api-common": "^0.1.0", - "@tria-plc/iamapi-common": "^0.1.0", "@edr/api-common": "workspace:*", "@edr/types": "workspace:*", "@nestjs/common": "^11.0.0", @@ -24,6 +22,8 @@ "@nestjs/platform-express": "^11.0.0", "@nestjs/swagger": "^11.4.2", "@nestjs/typeorm": "^11.0.1", + "@tria-plc/api-common": "^0.1.4", + "@tria-plc/iamapi-common": "^0.1.6", "class-transformer": "^0.5.1", "class-validator": "^0.14.1", "pg": "^8.13.0", @@ -33,9 +33,9 @@ }, "devDependencies": { "@edr/api-common": "workspace:*", - "@edr/types": "workspace:*", "@edr/eslint-config": "workspace:*", "@edr/tsconfig": "workspace:*", + "@edr/types": "workspace:*", "@nestjs/cli": "^11.0.0", "@nestjs/schematics": "^11.0.0", "@nestjs/testing": "^11.0.0", diff --git a/infrastructure/docker/docker-compose.db.dev.yml b/infrastructure/docker/docker-compose.db.dev.yml index 77b505ff6..443267b53 100644 --- a/infrastructure/docker/docker-compose.db.dev.yml +++ b/infrastructure/docker/docker-compose.db.dev.yml @@ -6,7 +6,6 @@ networks: volumes: postgres-freight-data: - postgres-passenger-data: redis-data: services: @@ -25,21 +24,6 @@ services: networks: - edr-network - postgres-passenger: - image: postgres:17-alpine - container_name: edr-postgres-passenger - restart: unless-stopped - environment: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: edr_passenger - ports: - - "5434:5432" - volumes: - - postgres-passenger-data:/var/lib/postgresql/data - networks: - - edr-network - redis: image: redis:7-alpine container_name: edr-redis diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 82b65bed9..11c51893a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -66,10 +66,10 @@ importers: specifier: ^11.0.1 version: 11.0.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2)(typeorm@0.3.29(babel-plugin-macros@3.1.0)(pg@8.20.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3))) '@tria-plc/api-common': - specifier: ^0.1.0 + specifier: ^0.1.4 version: 0.1.4(dlk6rffkpcjlebt3tne6hjqwx4) '@tria-plc/iamapi-common': - specifier: ^0.1.0 + specifier: ^0.1.6 version: 0.1.6(nhzmwbpvzw5m5dv4mcbu7ilapi) class-transformer: specifier: ^0.5.1 From 0e0d2ea45015728d815583b4ab5ee537d6913388 Mon Sep 17 00:00:00 2001 From: Michael Abebe Date: Mon, 18 May 2026 10:25:33 +0300 Subject: [PATCH 2/5] feat(freight:api): initial backend work --- apps/edr-freight-api/.env.example | 17 +++- apps/edr-freight-api/package.json | 4 + apps/edr-freight-api/src/app.module.ts | 4 + .../src/config/database.config.ts | 92 ++++++++++++++++++- apps/edr-freight-api/src/main.ts | 2 + .../src/modules/billing/billing.controller.ts | 1 - .../modules/bookings/bookings.controller.ts | 1 - .../consignments/consignments.controller.ts | 1 - .../modules/customers/customers.controller.ts | 1 - .../modules/tracking/tracking.controller.ts | 1 - .../src/modules/trains/trains.controller.ts | 1 - apps/edr-freight-api/tsconfig.json | 4 +- pnpm-lock.yaml | 64 +++++++++++-- 13 files changed, 177 insertions(+), 16 deletions(-) diff --git a/apps/edr-freight-api/.env.example b/apps/edr-freight-api/.env.example index 6c7738a7a..8e19ed4f7 100644 --- a/apps/edr-freight-api/.env.example +++ b/apps/edr-freight-api/.env.example @@ -9,8 +9,23 @@ DB_NAME=edr_freight DB_USER=postgres DB_PASSWORD= -# JWT (provided by external auth package — placeholder only) +# JWT (used by @tria-plc/api-common SharedAuthModule) JWT_SECRET= +JWT_ACCESS_TOKEN_SECRET= +JWT_REFRESH_TOKEN_SECRET= +JWT_EXPIRES_IN=3600 + +# IAM seed defaults (used by @tria-plc/iamapi-common on first boot) +SUPER_ADMIN_EMAIL=superadmin@tria.com +SUPER_ADMIN_PHONE= +DEFAULT_PASSWORD=password@tria + +# MinIO (used by @tria-plc/iamapi-common for file storage) +MINIO_ENDPOINT=localhost +MINIO_PORT=9000 +MINIO_USE_SSL=false +MINIO_ACCESS_KEY= +MINIO_SECRET_KEY= # Redis REDIS_HOST=localhost diff --git a/apps/edr-freight-api/package.json b/apps/edr-freight-api/package.json index f320815dc..813914bca 100644 --- a/apps/edr-freight-api/package.json +++ b/apps/edr-freight-api/package.json @@ -24,8 +24,11 @@ "@nestjs/typeorm": "^11.0.1", "@tria-plc/api-common": "^0.1.4", "@tria-plc/iamapi-common": "^0.1.6", + "amqp-connection-manager": "^5.0.0", + "amqplib": "^2.0.1", "class-transformer": "^0.5.1", "class-validator": "^0.14.1", + "dotenv": "^17.4.2", "pg": "^8.13.0", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", @@ -39,6 +42,7 @@ "@nestjs/cli": "^11.0.0", "@nestjs/schematics": "^11.0.0", "@nestjs/testing": "^11.0.0", + "@types/amqplib": "^0.10.8", "@types/express": "^5.0.0", "@types/jest": "^29.5.13", "@types/node": "^20.14.0", diff --git a/apps/edr-freight-api/src/app.module.ts b/apps/edr-freight-api/src/app.module.ts index 3eb7d30ec..7b21e906e 100644 --- a/apps/edr-freight-api/src/app.module.ts +++ b/apps/edr-freight-api/src/app.module.ts @@ -1,6 +1,8 @@ import { Module } from "@nestjs/common"; import { ConfigModule, ConfigService } from "@nestjs/config"; import { TypeOrmModule, TypeOrmModuleOptions } from "@nestjs/typeorm"; +import { IamModule } from "@tria-plc/iamapi-common"; +import { SharedAuthModule } from "@tria-plc/api-common/modules/auth/shared-auth.module"; import appConfig from "./config/app.config"; import databaseConfig from "./config/database.config"; @@ -24,6 +26,8 @@ import { NotificationsModule } from "./modules/notifications/notifications.modul useFactory: (config: ConfigService): TypeOrmModuleOptions => config.get("database")!, }), + SharedAuthModule, + IamModule, BookingsModule, ConsignmentsModule, TrainsModule, diff --git a/apps/edr-freight-api/src/config/database.config.ts b/apps/edr-freight-api/src/config/database.config.ts index fbcbeb1be..cf3dc9670 100644 --- a/apps/edr-freight-api/src/config/database.config.ts +++ b/apps/edr-freight-api/src/config/database.config.ts @@ -1,5 +1,94 @@ import { registerAs } from "@nestjs/config"; import { TypeOrmModuleOptions } from "@nestjs/typeorm"; +import { + DefaultPosition, + DefaultUnit, + EmployeePosition, + Employee, + OrganizationConfiguration, + GlobalOrganizationConfiguration, + OrganizationType, + Organization, + PositionConfiguration, + PositionPermission, + PositionTypeConfiguration, + PositionTypePermission, + PositionType, + Position, + Project, + UnitConfiguration, + GlobalUnitConfiguration, + Unit, + EmployeeSignature, + EmployeeStamp, + RecordFooter, + RecordHeader, + Seal, + AccountConfiguration, + Application, + DocumentaryRequirement, + Permission, + RolePermission, + Role, + Session, + UserCredential, + UserDocument, + UserRole, + UserVerification, + User, + Notification, + NotificationEvent, + NotificationPlaceholder, + NotificationReceiverField, + NotificationReceiver, + NotificationTemplate, +} from "@tria-plc/iamapi-common"; +import { OrganizationSetting } from "@tria-plc/iamapi-common/entities/iam/organization-structure/organization-setting.entity"; + +const iamEntities = [ + DefaultPosition, + DefaultUnit, + EmployeePosition, + Employee, + OrganizationConfiguration, + GlobalOrganizationConfiguration, + OrganizationSetting, + OrganizationType, + Organization, + PositionConfiguration, + PositionPermission, + PositionTypeConfiguration, + PositionTypePermission, + PositionType, + Position, + Project, + UnitConfiguration, + GlobalUnitConfiguration, + Unit, + EmployeeSignature, + EmployeeStamp, + RecordFooter, + RecordHeader, + Seal, + AccountConfiguration, + Application, + DocumentaryRequirement, + Permission, + RolePermission, + Role, + Session, + UserCredential, + UserDocument, + UserRole, + UserVerification, + User, + Notification, + NotificationEvent, + NotificationPlaceholder, + NotificationReceiverField, + NotificationReceiver, + NotificationTemplate, +]; export default registerAs( "database", @@ -10,7 +99,8 @@ export default registerAs( username: process.env.DB_USER ?? "postgres", password: process.env.DB_PASSWORD ?? "", database: process.env.DB_NAME ?? "edr_freight", - entities: [__dirname + "/../**/*.entity.{ts,js}"], + entities: [__dirname + "/../**/*.entity.{ts,js}", ...iamEntities], + autoLoadEntities: true, migrations: [__dirname + "/../../migrations/*.{ts,js}"], // Never enable synchronize in production. Use migrations. synchronize: process.env.NODE_ENV === "development", diff --git a/apps/edr-freight-api/src/main.ts b/apps/edr-freight-api/src/main.ts index 91910e8e5..8fb5d7130 100644 --- a/apps/edr-freight-api/src/main.ts +++ b/apps/edr-freight-api/src/main.ts @@ -1,4 +1,6 @@ import "reflect-metadata"; +import * as dotenv from "dotenv"; +dotenv.config(); import { NestFactory } from "@nestjs/core"; import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger"; import { diff --git a/apps/edr-freight-api/src/modules/billing/billing.controller.ts b/apps/edr-freight-api/src/modules/billing/billing.controller.ts index 05ea8af67..0091b5341 100644 --- a/apps/edr-freight-api/src/modules/billing/billing.controller.ts +++ b/apps/edr-freight-api/src/modules/billing/billing.controller.ts @@ -4,7 +4,6 @@ import { ApiOperation, ApiTags } from "@nestjs/swagger"; import { BillingService } from "./billing.service"; @ApiTags("billing") -// @UseGuards(JwtAuthGuard) — TODO: integrate @edr/auth @Controller("billing") export class BillingController { constructor(private readonly billingService: BillingService) {} diff --git a/apps/edr-freight-api/src/modules/bookings/bookings.controller.ts b/apps/edr-freight-api/src/modules/bookings/bookings.controller.ts index 4ed037cfc..d6fd41220 100644 --- a/apps/edr-freight-api/src/modules/bookings/bookings.controller.ts +++ b/apps/edr-freight-api/src/modules/bookings/bookings.controller.ts @@ -16,7 +16,6 @@ import { CreateBookingDto } from "./dto/create-booking.dto"; import { FilterBookingDto } from "./dto/filter-booking.dto"; @ApiTags("bookings") -// @UseGuards(JwtAuthGuard) — TODO: integrate @edr/auth @Controller("bookings") export class BookingsController { constructor(private readonly bookingsService: BookingsService) {} diff --git a/apps/edr-freight-api/src/modules/consignments/consignments.controller.ts b/apps/edr-freight-api/src/modules/consignments/consignments.controller.ts index 44220f52f..46ef22bf8 100644 --- a/apps/edr-freight-api/src/modules/consignments/consignments.controller.ts +++ b/apps/edr-freight-api/src/modules/consignments/consignments.controller.ts @@ -14,7 +14,6 @@ import { CreateConsignmentDto } from "./dto/create-consignment.dto"; import { FilterConsignmentDto } from "./dto/filter-consignment.dto"; @ApiTags("consignments") -// @UseGuards(JwtAuthGuard) — TODO: integrate @edr/auth @Controller("consignments") export class ConsignmentsController { constructor(private readonly consignmentsService: ConsignmentsService) {} diff --git a/apps/edr-freight-api/src/modules/customers/customers.controller.ts b/apps/edr-freight-api/src/modules/customers/customers.controller.ts index 65c4f42de..7eaa42d5b 100644 --- a/apps/edr-freight-api/src/modules/customers/customers.controller.ts +++ b/apps/edr-freight-api/src/modules/customers/customers.controller.ts @@ -12,7 +12,6 @@ import { CustomersService } from "./customers.service"; import { CreateCustomerDto } from "./dto/create-customer.dto"; @ApiTags("customers") -// @UseGuards(JwtAuthGuard) — TODO: integrate @edr/auth @Controller("customers") export class CustomersController { constructor(private readonly customersService: CustomersService) {} diff --git a/apps/edr-freight-api/src/modules/tracking/tracking.controller.ts b/apps/edr-freight-api/src/modules/tracking/tracking.controller.ts index 6d645c40a..0e996fe7c 100644 --- a/apps/edr-freight-api/src/modules/tracking/tracking.controller.ts +++ b/apps/edr-freight-api/src/modules/tracking/tracking.controller.ts @@ -4,7 +4,6 @@ import { ApiOperation, ApiTags } from "@nestjs/swagger"; import { TrackingService } from "./tracking.service"; @ApiTags("tracking") -// @UseGuards(JwtAuthGuard) — TODO: integrate @edr/auth @Controller("tracking") export class TrackingController { constructor(private readonly trackingService: TrackingService) {} diff --git a/apps/edr-freight-api/src/modules/trains/trains.controller.ts b/apps/edr-freight-api/src/modules/trains/trains.controller.ts index c087d59e3..86ce6856b 100644 --- a/apps/edr-freight-api/src/modules/trains/trains.controller.ts +++ b/apps/edr-freight-api/src/modules/trains/trains.controller.ts @@ -12,7 +12,6 @@ import { CreateTrainDto } from "./dto/create-train.dto"; import { TrainsService } from "./trains.service"; @ApiTags("trains") -// @UseGuards(JwtAuthGuard) — TODO: integrate @edr/auth @Controller("trains") export class TrainsController { constructor(private readonly trainsService: TrainsService) {} diff --git a/apps/edr-freight-api/tsconfig.json b/apps/edr-freight-api/tsconfig.json index e8cec7548..467c474ee 100644 --- a/apps/edr-freight-api/tsconfig.json +++ b/apps/edr-freight-api/tsconfig.json @@ -6,7 +6,9 @@ "rootDir": "./src", "noEmit": false, "incremental": true, - "tsBuildInfoFile": "./.tsbuildinfo" + "tsBuildInfoFile": "./.tsbuildinfo", + "module": "node16", + "moduleResolution": "node16" }, "include": ["src"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11c51893a..59554fd90 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -55,7 +55,7 @@ importers: version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@11.1.19)(@nestjs/platform-express@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/microservices': specifier: ^11.0.0 - version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(amqp-connection-manager@5.0.0(amqplib@2.0.1))(amqplib@2.0.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/platform-express': specifier: ^11.0.0 version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) @@ -71,12 +71,21 @@ importers: '@tria-plc/iamapi-common': specifier: ^0.1.6 version: 0.1.6(nhzmwbpvzw5m5dv4mcbu7ilapi) + amqp-connection-manager: + specifier: ^5.0.0 + version: 5.0.0(amqplib@2.0.1) + amqplib: + specifier: ^2.0.1 + version: 2.0.1 class-transformer: specifier: ^0.5.1 version: 0.5.1 class-validator: specifier: ^0.14.1 version: 0.14.4 + dotenv: + specifier: ^17.4.2 + version: 17.4.2 pg: specifier: ^8.13.0 version: 8.20.0 @@ -105,6 +114,9 @@ importers: '@nestjs/testing': specifier: ^11.0.0 version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(@nestjs/microservices@11.1.19)(@nestjs/platform-express@11.1.19) + '@types/amqplib': + specifier: ^0.10.8 + version: 0.10.8 '@types/express': specifier: ^5.0.0 version: 5.0.6 @@ -304,7 +316,7 @@ importers: version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@11.1.19)(@nestjs/platform-express@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/microservices': specifier: ^11.0.0 - version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(amqp-connection-manager@5.0.0(amqplib@2.0.1))(amqplib@2.0.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/platform-express': specifier: ^11.0.0 version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) @@ -3543,6 +3555,9 @@ packages: cpu: [arm64] os: [win32] + '@types/amqplib@0.10.8': + resolution: {integrity: sha512-vtDp8Pk1wsE/AuQ8/Rgtm6KUZYqcnTgNvEHwzCkX8rL7AGsC6zqAfKAAJhUZXFhM/Pp++tbnUHiam/8vVpPztA==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -4230,6 +4245,16 @@ packages: resolution: {integrity: sha512-GrTZLRpmp6wIC2ztrWW9MjjTgSKccffgFagbNDOX95/dcjEcYZibYTeaOntySQLcdw1ztBoFkviiUvTMbb9MYg==} engines: {node: '>=0.10.0'} + amqp-connection-manager@5.0.0: + resolution: {integrity: sha512-88yQzqa5RSBgnLl504XjvCQJ7d+osskdwvg35Lwm1LRbfLjNU9p7SQUMSP82BB7mseiq9tIUPJ3HE3eXQbpjEw==} + engines: {node: '>=10.0.0', npm: '>5.0.0'} + peerDependencies: + amqplib: '*' + + amqplib@2.0.1: + resolution: {integrity: sha512-a3P2MgfCf9nzVis12VxWEn0dS6hcqve7dlEAhXDtIWR27BlhtMkILOc+H9aeHjDi6i6r94dYKc2Kx2OFe3avvg==} + engines: {node: '>=18'} + ansi-bgblack@0.1.1: resolution: {integrity: sha512-tp8M/NCmSr6/skdteeo9UgJ2G1rG88X3ZVNZWXUxFw4Wh0PAGaAAWQS61sfBt/1QNcwMTY3EBKOMPujwioJLaw==} engines: {node: '>=0.10.0'} @@ -5659,6 +5684,10 @@ packages: resolution: {integrity: sha512-k8DaKGP6r1G30Lx8V4+pCsLzKr8vLmV2paqEj1Y55GdAgJuIqpRp5FfajGF8KtwMxCz9qJc6wUIJnm053d/WCw==} engines: {node: '>=12'} + dotenv@17.4.2: + resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} + engines: {node: '>=12'} + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} @@ -8914,6 +8943,9 @@ packages: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} + promise-breaker@6.0.0: + resolution: {integrity: sha512-BthzO9yTPswGf7etOBiHCVuugs2N01/Q/94dIPls48z2zCmrnDptUUZzfIb+41xq0MnYZ/BzmOd6ikDR4ibNZA==} + prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -12803,7 +12835,7 @@ snapshots: tslib: 2.8.1 uid: 2.0.2 optionalDependencies: - '@nestjs/microservices': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/microservices': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(amqp-connection-manager@5.0.0(amqplib@2.0.1))(amqplib@2.0.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/platform-express': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) '@nestjs/jwt@11.0.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))': @@ -12820,7 +12852,7 @@ snapshots: class-transformer: 0.5.1 class-validator: 0.14.4 - '@nestjs/microservices@11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/microservices@11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(amqp-connection-manager@5.0.0(amqplib@2.0.1))(amqplib@2.0.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@11.1.19)(@nestjs/platform-express@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -12828,6 +12860,9 @@ snapshots: reflect-metadata: 0.2.2 rxjs: 7.8.2 tslib: 2.8.1 + optionalDependencies: + amqp-connection-manager: 5.0.0(amqplib@2.0.1) + amqplib: 2.0.1 '@nestjs/passport@11.0.5(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)': dependencies: @@ -12880,7 +12915,7 @@ snapshots: '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@11.1.19)(@nestjs/platform-express@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 optionalDependencies: - '@nestjs/microservices': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/microservices': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(amqp-connection-manager@5.0.0(amqplib@2.0.1))(amqplib@2.0.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/platform-express': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) '@nestjs/throttler@6.5.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)': @@ -14458,7 +14493,7 @@ snapshots: '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@11.1.19)(@nestjs/platform-express@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/jwt': 11.0.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)) - '@nestjs/microservices': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/microservices': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(amqp-connection-manager@5.0.0(amqplib@2.0.1))(amqplib@2.0.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/passport': 11.0.5(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0) '@nestjs/swagger': 11.4.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2) '@nestjs/throttler': 6.5.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2) @@ -14502,7 +14537,7 @@ snapshots: '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@11.1.19)(@nestjs/platform-express@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/jwt': 11.0.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)) - '@nestjs/microservices': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/microservices': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(amqp-connection-manager@5.0.0(amqplib@2.0.1))(amqplib@2.0.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/passport': 11.0.5(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0) '@nestjs/swagger': 11.4.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2) '@nestjs/throttler': 6.5.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2) @@ -14826,6 +14861,10 @@ snapshots: '@turbo/windows-arm64@2.9.12': optional: true + '@types/amqplib@0.10.8': + dependencies: + '@types/node': 20.19.41 + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.29.3 @@ -15941,6 +15980,13 @@ snapshots: longest: 1.0.1 repeat-string: 1.6.1 + amqp-connection-manager@5.0.0(amqplib@2.0.1): + dependencies: + amqplib: 2.0.1 + promise-breaker: 6.0.0 + + amqplib@2.0.1: {} + ansi-bgblack@0.1.1: dependencies: ansi-wrap: 0.1.0 @@ -17600,6 +17646,8 @@ snapshots: dotenv@17.4.1: {} + dotenv@17.4.2: {} + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 @@ -21458,6 +21506,8 @@ snapshots: process@0.11.10: {} + promise-breaker@6.0.0: {} + prompts@2.4.2: dependencies: kleur: 3.0.3 From 4256a0891770d51494621bd00302d1c6fddd413e Mon Sep 17 00:00:00 2001 From: Michael Abebe Date: Mon, 18 May 2026 10:46:09 +0300 Subject: [PATCH 3/5] fix:(api): auth redirect --- apps/edr-freight-web/portal/src/App.tsx | 13 +++++++++-- apps/edr-freight-web/portal/src/main.tsx | 2 +- apps/edr-freight-web/portal/src/utils/api.ts | 23 +++++++++++++++++--- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/apps/edr-freight-web/portal/src/App.tsx b/apps/edr-freight-web/portal/src/App.tsx index 6b788db70..e1482c142 100644 --- a/apps/edr-freight-web/portal/src/App.tsx +++ b/apps/edr-freight-web/portal/src/App.tsx @@ -16,7 +16,7 @@ import TrackingPage from "./pages/tracking/TrackingPage"; import BillingPage from "./pages/billing/BillingPage"; import TrainsPage from "./pages/trains/TrainsPage"; import DashboardPage from "./pages/dashboard/DashboardPage"; -import { IamLoginPage } from "@tria-plc/iamui-common"; +import { IamLoginPage, LoadingScreen, useAuth } from "@tria-plc/iamui-common"; const sidebarItems: SidebarItem[] = [ { label: "Dashboard", href: "/" }, @@ -30,8 +30,13 @@ const sidebarItems: SidebarItem[] = [ const App = () => { const navigate = useNavigate(); const location = useLocation(); + const { user, loading } = useAuth(); - if (location.pathname === "/auth") { + if (loading) { + return ; + } + + if (!user) { return ( } /> @@ -40,6 +45,10 @@ const App = () => { ); } + if (location.pathname === "/auth") { + return ; + } + return ( { + const token = document.cookie + .split("; ") + .find((row) => row.startsWith("auth-token=")) + ?.split("=")[1]; + if (token) { + config.headers.Authorization = `Bearer ${token}`; + } + return config; +}); + +api.interceptors.response.use( + (response) => response, + (error) => { + if (error.response?.status === 401) { + window.location.href = "/auth"; + } + return Promise.reject(error); + }, +); From b46a7765e8031a78ebafe75a2922a29c8fdf8823 Mon Sep 17 00:00:00 2001 From: Michael Abebe Date: Mon, 18 May 2026 10:48:15 +0300 Subject: [PATCH 4/5] fix:(api:auth): added iam migrations to list of migrations --- apps/edr-freight-api/src/config/database.config.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/edr-freight-api/src/config/database.config.ts b/apps/edr-freight-api/src/config/database.config.ts index cf3dc9670..1bef01eca 100644 --- a/apps/edr-freight-api/src/config/database.config.ts +++ b/apps/edr-freight-api/src/config/database.config.ts @@ -101,7 +101,13 @@ export default registerAs( database: process.env.DB_NAME ?? "edr_freight", entities: [__dirname + "/../**/*.entity.{ts,js}", ...iamEntities], autoLoadEntities: true, - migrations: [__dirname + "/../../migrations/*.{ts,js}"], + migrations: [ + // IAM schema + tables must be created before freight entity sync + __dirname + + "/../../node_modules/@tria-plc/iamapi-common/dist/db/migrations/*.js", + __dirname + "/../../migrations/*.{ts,js}", + ], + migrationsRun: true, // Never enable synchronize in production. Use migrations. synchronize: process.env.NODE_ENV === "development", logging: process.env.NODE_ENV === "development", From 2940d20e06ba22b7f542ac7dcb20606a28d47173 Mon Sep 17 00:00:00 2001 From: Michael Abebe Date: Mon, 18 May 2026 11:07:09 +0300 Subject: [PATCH 5/5] fix:(freight:auth): finished integrating the freight api with the freight portal --- apps/edr-freight-api/.env.example | 3 +++ apps/edr-freight-api/src/app.module.ts | 14 ++++++++++---- apps/edr-freight-web/portal/src/main.tsx | 16 ++++++++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/apps/edr-freight-api/.env.example b/apps/edr-freight-api/.env.example index 8e19ed4f7..5f2d2b8ee 100644 --- a/apps/edr-freight-api/.env.example +++ b/apps/edr-freight-api/.env.example @@ -14,6 +14,9 @@ JWT_SECRET= JWT_ACCESS_TOKEN_SECRET= JWT_REFRESH_TOKEN_SECRET= JWT_EXPIRES_IN=3600 +# JWT expiry for @tria-plc/api-common token utils (jsonwebtoken timespan format) +JWT_ACCESS_TOKEN_EXPIRES=1h +JWT_REFRESH_TOKEN_EXPIRES=7d # IAM seed defaults (used by @tria-plc/iamapi-common on first boot) SUPER_ADMIN_EMAIL=superadmin@tria.com diff --git a/apps/edr-freight-api/src/app.module.ts b/apps/edr-freight-api/src/app.module.ts index 7b21e906e..8cde48e15 100644 --- a/apps/edr-freight-api/src/app.module.ts +++ b/apps/edr-freight-api/src/app.module.ts @@ -1,7 +1,7 @@ -import { Module } from "@nestjs/common"; +import { Module, OnApplicationBootstrap } from "@nestjs/common"; import { ConfigModule, ConfigService } from "@nestjs/config"; import { TypeOrmModule, TypeOrmModuleOptions } from "@nestjs/typeorm"; -import { IamModule } from "@tria-plc/iamapi-common"; +import { IamModule, DataSeeder } from "@tria-plc/iamapi-common"; import { SharedAuthModule } from "@tria-plc/api-common/modules/auth/shared-auth.module"; import appConfig from "./config/app.config"; @@ -27,7 +27,7 @@ import { NotificationsModule } from "./modules/notifications/notifications.modul config.get("database")!, }), SharedAuthModule, - IamModule, + IamModule.forRoot(), BookingsModule, ConsignmentsModule, TrainsModule, @@ -37,4 +37,10 @@ import { NotificationsModule } from "./modules/notifications/notifications.modul NotificationsModule, ], }) -export class AppModule {} +export class AppModule implements OnApplicationBootstrap { + constructor(private readonly seeder: DataSeeder) {} + + async onApplicationBootstrap() { + await this.seeder.run(); + } +} diff --git a/apps/edr-freight-web/portal/src/main.tsx b/apps/edr-freight-web/portal/src/main.tsx index 09408f6ec..665a9fc81 100644 --- a/apps/edr-freight-web/portal/src/main.tsx +++ b/apps/edr-freight-web/portal/src/main.tsx @@ -10,6 +10,7 @@ import { BrandingProvider, configureIam, UserProvider, + axiosInstance, } from "@tria-plc/iamui-common"; const queryClient = new QueryClient(); @@ -17,6 +18,21 @@ window.__IAM_CONFIG__ = { apiUrl: `${import.meta.env.VITE_BASE_API_URL}/api`, postLoginPath: "/", }; + +// Unwrap the StandardResponse envelope ({ success, data, timestamp }) that the +// freight API's ResponseTransformInterceptor adds to every response, so that +// iamui-common can read response.data.token / response.data fields as expected. +axiosInstance.interceptors.response.use((response) => { + if ( + response.data && + typeof response.data === "object" && + "success" in response.data && + "data" in response.data + ) { + response.data = response.data.data; + } + return response; +}); window.__USER_MANAGEMENT_BRANDING__ = { organizationName: "EDR Platform", appName: "EDR Portal",