diff --git a/apps/edr-passenger-api/src/modules/bookings/bookings.controller.ts b/apps/edr-passenger-api/src/modules/bookings/bookings.controller.ts
index 2a8e237e6..bb9b8ffae 100644
--- a/apps/edr-passenger-api/src/modules/bookings/bookings.controller.ts
+++ b/apps/edr-passenger-api/src/modules/bookings/bookings.controller.ts
@@ -1,5 +1,6 @@
import { Body, Controller, Delete, Get, Param, Post, Patch, UseGuards, Query, Req, BadRequestException } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiResponse, ApiQuery, ApiBody } from '@nestjs/swagger';
+import { IsPublic } from '@tria-plc/api-common/modules/auth/decorators/public.decorator';
import { BookingsService } from './bookings.service';
import { GuestBookingService } from './guest-booking.service';
import { CreateBookingDto, ModifyBookingDto, CancelBookingDto } from './bookings.dto';
@@ -44,7 +45,8 @@ export class BookingsController {
}
@Get('by-device')
- @ApiOperation({
+ @IsPublic()
+ @ApiOperation({
summary: 'Get bookings by device ID',
description: 'Returns all bookings associated with a device ID (for guest users). Includes saved passenger details and booking history.'
})
@@ -98,7 +100,8 @@ export class BookingsController {
}
@Post('guest')
- @ApiOperation({
+ @IsPublic()
+ @ApiOperation({
summary: 'Create guest booking — ONE_WAY | ROUND_TRIP | TRANSIT | ROUND_TRIP_TRANSIT (no login required)',
description: `Creates a booking without requiring login. Supports all four booking types.
diff --git a/apps/edr-passenger-api/src/modules/payments/payments.controller.ts b/apps/edr-passenger-api/src/modules/payments/payments.controller.ts
index 4cb79a89f..0bf09e41d 100644
--- a/apps/edr-passenger-api/src/modules/payments/payments.controller.ts
+++ b/apps/edr-passenger-api/src/modules/payments/payments.controller.ts
@@ -17,6 +17,7 @@ import {
ApiOkResponse,
ApiProduces,
} from "@nestjs/swagger";
+import { IsPublic } from "@tria-plc/api-common/modules/auth/decorators/public.decorator";
import { Response } from "express";
import { PaymentsService } from "./payments.service";
import {
@@ -62,6 +63,7 @@ export class PaymentsController {
}
@Post("initiate")
+ @IsPublic()
@ApiOperation({
summary: "Initiate payment with nationality-based payment methods",
description: `Initiates payment for a booking with support for multiple payment providers:\n\n**Ethiopian Payment Methods:**\n- TELEBIRR - Ethiopia's leading mobile money\n- CBE_BIRR - Commercial Bank of Ethiopia\n- EBIRR - Electronic payment gateway\n\n**Djiboutian Payment Methods:**\n- WAAFI - Djibouti's mobile money service\n\n**International Payment Methods:**\n- CARD - Visa, Mastercard\n- WALLET - Internal wallet balance\n\n**Multi-Currency:**\n- All transactions processed in ETB\n- Display amounts in ETB, DJF, or USD\n- Real-time exchange rate conversion`,
@@ -71,12 +73,14 @@ export class PaymentsController {
}
@Get("intents/:bookingId")
+ @IsPublic()
@ApiOperation({ summary: "Get payment intent status for a booking" })
getIntent(@Param("bookingId") bookingId: string) {
return this.service.getIntentByBookingId(bookingId);
}
@Get("waafi/return")
+ @IsPublic()
@ApiOperation({
summary:
"DEMO ONLY — confirm a Waafi payment from the browser-return params and return JSON for the " +
@@ -117,6 +121,7 @@ export class PaymentsController {
}
@Get("methods")
+ @IsPublic()
@ApiOperation({
summary: "List payment systems supported by the platform",
description:
@@ -129,6 +134,7 @@ export class PaymentsController {
}
@Get("checkout")
+ @IsPublic()
@ApiOperation({
summary: "Browser checkout redirect",
description:
diff --git a/apps/edr-passenger-api/src/modules/schedules/schedules.controller.ts b/apps/edr-passenger-api/src/modules/schedules/schedules.controller.ts
index 378bc8fa7..ac55bc14b 100644
--- a/apps/edr-passenger-api/src/modules/schedules/schedules.controller.ts
+++ b/apps/edr-passenger-api/src/modules/schedules/schedules.controller.ts
@@ -1,5 +1,6 @@
import { Body, Controller, Delete, Get, Param, Patch, Post, Query, ParseIntPipe, UseGuards } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiQuery, ApiResponse } from '@nestjs/swagger';
+import { IsPublic } from '@tria-plc/api-common/modules/auth/decorators/public.decorator';
import { SchedulesService } from './schedules.service';
import { CreateScheduleDto, UpdateScheduleDto, CreateFareRuleDto, UpdateScheduleStatusDto, UpdateStopTimeDto, ListSchedulesDto, BulkCreateSchedulesDto, BulkSchedulesResponseDto } from './schedules.dto';
import { JwtGuard } from '../../common/jwt.guard';
@@ -23,6 +24,7 @@ export class SchedulesController {
createSchedule(@Body() dto: CreateScheduleDto) { return this.service.createSchedule(dto); }
@Get()
+ @IsPublic()
@ApiOperation({ summary: 'List schedules with optional filters' })
@ApiQuery({ name: 'date', required: false })
@ApiQuery({ name: 'routeId', required: false })
@@ -67,6 +69,7 @@ export class SchedulesController {
createSegmentFareRule(@Body() dto: any) { return this.service.createSegmentFareRule(dto); }
@Get('routes/:routeId/segment-fares')
+ @IsPublic()
@ApiOperation({ summary: 'List all segment fare rules for a route' })
@ApiParam({ name: 'routeId', description: 'Route UUID' })
getSegmentFares(@Param('routeId') routeId: string) { return this.service.getSegmentFares(routeId); }
@@ -86,6 +89,7 @@ export class SchedulesController {
// ===== PARAMETRIZED ROUTES (generic :id routes come AFTER specific routes) =====
@Get(':id')
+ @IsPublic()
@ApiOperation({ summary: 'Get schedule detail' })
@ApiParam({ name: 'id', description: 'TrainSchedule UUID' })
getSchedule(@Param('id') id: string) { return this.service.getSchedule(id); }
@@ -113,6 +117,7 @@ export class SchedulesController {
deleteSchedule(@Param('id') id: string) { return this.service.deleteSchedule(id); }
@Get(':id/stops')
+ @IsPublic()
@ApiOperation({ summary: 'List all stops for a schedule' })
@ApiParam({ name: 'id', description: 'TrainSchedule UUID' })
getStops(@Param('id') id: string) { return this.service.getStops(id); }
diff --git a/apps/edr-passenger-api/src/modules/search/search.controller.ts b/apps/edr-passenger-api/src/modules/search/search.controller.ts
index b32f2f291..6bb9d1960 100644
--- a/apps/edr-passenger-api/src/modules/search/search.controller.ts
+++ b/apps/edr-passenger-api/src/modules/search/search.controller.ts
@@ -1,10 +1,12 @@
import { Body, Controller, Post } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
+import { IsPublic } from '@tria-plc/api-common/modules/auth/decorators/public.decorator';
import { SearchService } from './search.service';
import { SearchTripsDto, FareQuoteDto } from './search.dto';
@ApiTags('Search')
@Controller('search')
+@IsPublic()
export class SearchController {
constructor(private service: SearchService) {}
diff --git a/apps/edr-passenger-api/src/modules/seat-classes/seat-classes.controller.ts b/apps/edr-passenger-api/src/modules/seat-classes/seat-classes.controller.ts
index 0ac25272d..86eb287a4 100644
--- a/apps/edr-passenger-api/src/modules/seat-classes/seat-classes.controller.ts
+++ b/apps/edr-passenger-api/src/modules/seat-classes/seat-classes.controller.ts
@@ -1,5 +1,6 @@
import { Body, Controller, Delete, Get, Param, Patch, Post, UseGuards } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiResponse, ApiBody } from '@nestjs/swagger';
+import { IsPublic } from '@tria-plc/api-common/modules/auth/decorators/public.decorator';
import { SeatClassesService } from './seat-classes.service';
import { CreateSeatClassDto, UpdateSeatClassDto } from './seat-classes.dto';
import { JwtGuard } from '../../common/jwt.guard';
@@ -10,11 +11,13 @@ export class SeatClassesController {
constructor(private service: SeatClassesService) {}
@Get()
+ @IsPublic()
@ApiOperation({ summary: 'List all seat classes' })
@ApiResponse({ status: 200, description: 'Returns all seat classes with their coaches' })
listSeatClasses() { return this.service.listSeatClasses(); }
@Get(':id')
+ @IsPublic()
@ApiOperation({ summary: 'Get a seat class by ID' })
@ApiParam({ name: 'id', description: 'Seat class UUID' })
@ApiResponse({ status: 200, description: 'Returns seat class with its coaches' })
diff --git a/apps/edr-passenger-api/src/modules/seats/seats.controller.ts b/apps/edr-passenger-api/src/modules/seats/seats.controller.ts
index 4d0784f23..513017ad6 100644
--- a/apps/edr-passenger-api/src/modules/seats/seats.controller.ts
+++ b/apps/edr-passenger-api/src/modules/seats/seats.controller.ts
@@ -1,36 +1,64 @@
-import { Body, Controller, Delete, Get, Param, Post, Patch, Query, UseGuards } from '@nestjs/common';
-import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiQuery, ApiResponse } from '@nestjs/swagger';
-import { SeatsService } from './seats.service';
-import { HoldSeatsDto } from './seats.dto';
-import { JwtGuard } from '../../common/jwt.guard';
-import { IamGuard } from '../../common/iam-adapter';
+import {
+ Body,
+ Controller,
+ Delete,
+ Get,
+ Param,
+ Post,
+ Patch,
+ Query,
+ UseGuards,
+} from "@nestjs/common";
+import {
+ ApiTags,
+ ApiOperation,
+ ApiBearerAuth,
+ ApiParam,
+ ApiQuery,
+ ApiResponse,
+} from "@nestjs/swagger";
+import { IsPublic } from "@tria-plc/api-common/modules/auth/decorators/public.decorator";
+import { SeatsService } from "./seats.service";
+import { HoldSeatsDto } from "./seats.dto";
+import { JwtGuard } from "../../common/jwt.guard";
+import { IamGuard } from "../../common/iam-adapter";
-@ApiTags('Seats')
-@Controller('seats')
+@ApiTags("Seats")
+@Controller("seats")
export class SeatsController {
constructor(private service: SeatsService) {}
// ── Seat Map ──────────────────────────────────────────────────────────────
- @Get('seatmap/:scheduleId')
+ @Get("seatmap/:scheduleId")
@ApiOperation({
- summary: 'Get seat map filtered by coach type',
- description: `Returns all coaches of the given coachTypeId assigned to the schedule, each with their full seat list and real-time availability. Origin and destination are derived from the schedule. Omit coachTypeId to get all coaches.`
+ summary: "Get seat map filtered by coach type",
+ description: `Returns all coaches of the given coachTypeId assigned to the schedule, each with their full seat list and real-time availability. Origin and destination are derived from the schedule. Omit coachTypeId to get all coaches.`,
+ })
+ @ApiParam({ name: "scheduleId", description: "TrainSchedule UUID" })
+ @ApiQuery({
+ name: "coachTypeId",
+ required: false,
+ description:
+ "Filter by CoachType UUID — returns all coaches of that type (e.g. all Economy coaches)",
+ })
+ @ApiResponse({
+ status: 200,
+ description:
+ "List of coaches of the given type with their seats and availability",
})
- @ApiParam({ name: 'scheduleId', description: 'TrainSchedule UUID' })
- @ApiQuery({ name: 'coachTypeId', required: false, description: 'Filter by CoachType UUID — returns all coaches of that type (e.g. all Economy coaches)' })
- @ApiResponse({ status: 200, description: 'List of coaches of the given type with their seats and availability' })
getSeatMap(
- @Param('scheduleId') scheduleId: string,
- @Query('coachTypeId') coachTypeId?: string,
+ @Param("scheduleId") scheduleId: string,
+ @Query("coachTypeId") coachTypeId?: string,
) {
return this.service.getSeatMap(scheduleId, coachTypeId);
}
// ── Hold / Release ────────────────────────────────────────────────────────
- @Get('holds')
- @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth')
+ @Get("holds")
+ @UseGuards(JwtGuard)
+ @ApiBearerAuth("JWT-auth")
@ApiOperation({
- summary: 'List active seat holds with full leg context',
+ summary: "List active seat holds with full leg context",
description: `Returns all non-expired holds enriched with:
- **schedule**: train number, departure/arrival, full route origin→destination
- **leg**: the specific origin→destination this hold covers (station name, code, stop sequence)
@@ -39,25 +67,45 @@ export class SeatsController {
This makes it clear which segment of the route each seat is held for, enabling segment-based reuse of the same seat on non-overlapping legs.`,
})
- @ApiQuery({ name: 'scheduleId', required: false, description: 'Filter by TrainSchedule UUID' })
- @ApiQuery({ name: 'passengerId', required: false, description: 'Filter by Passenger UUID' })
- @ApiResponse({ status: 200, description: 'Active holds with schedule, leg, and seat details' })
+ @ApiQuery({
+ name: "scheduleId",
+ required: false,
+ description: "Filter by TrainSchedule UUID",
+ })
+ @ApiQuery({
+ name: "passengerId",
+ required: false,
+ description: "Filter by Passenger UUID",
+ })
+ @ApiResponse({
+ status: 200,
+ description: "Active holds with schedule, leg, and seat details",
+ })
getHolds(
- @Query('scheduleId') scheduleId?: string,
- @Query('passengerId') passengerId?: string,
- ) { return this.service.getHolds(scheduleId, passengerId); }
+ @Query("scheduleId") scheduleId?: string,
+ @Query("passengerId") passengerId?: string,
+ ) {
+ return this.service.getHolds(scheduleId, passengerId);
+ }
- @Get('holds/:holdId')
- @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth')
- @ApiOperation({ summary: 'Get a single hold with full leg context' })
- @ApiParam({ name: 'holdId', description: 'SeatHold UUID' })
- @ApiResponse({ status: 200, description: 'Hold with schedule, leg, and seat details' })
- @ApiResponse({ status: 404, description: 'Hold not found' })
- getHold(@Param('holdId') holdId: string) { return this.service.getHold(holdId); }
+ @Get("holds/:holdId")
+ @UseGuards(JwtGuard)
+ @ApiBearerAuth("JWT-auth")
+ @ApiOperation({ summary: "Get a single hold with full leg context" })
+ @ApiParam({ name: "holdId", description: "SeatHold UUID" })
+ @ApiResponse({
+ status: 200,
+ description: "Hold with schedule, leg, and seat details",
+ })
+ @ApiResponse({ status: 404, description: "Hold not found" })
+ getHold(@Param("holdId") holdId: string) {
+ return this.service.getHold(holdId);
+ }
- @Post('hold')
- @ApiOperation({
- summary: 'Hold seats for 15 minutes before booking (Public - Guest booking supported)',
+ @Post("hold")
+ @ApiOperation({
+ summary:
+ "Hold seats for 15 minutes before booking (Public - Guest booking supported)",
description: `Temporarily reserves seats for a passenger to complete booking.
**Features:**
@@ -65,74 +113,107 @@ This makes it clear which segment of the route each seat is held for, enabling s
- Auto-release after expiry
- Prevents double booking
- Required before creating booking
-- **Public endpoint** - No authentication required (supports guest booking)`
+- **Public endpoint** - No authentication required (supports guest booking)`,
})
- @ApiResponse({ status: 201, description: 'Seats held successfully with holdId' })
- @ApiResponse({ status: 409, description: 'One or more seats unavailable' })
- holdSeats(@Body() dto: HoldSeatsDto) { return this.service.holdSeats(dto); }
+ @ApiResponse({
+ status: 201,
+ description: "Seats held successfully with holdId",
+ })
+ @ApiResponse({ status: 409, description: "One or more seats unavailable" })
+ holdSeats(@Body() dto: HoldSeatsDto) {
+ return this.service.holdSeats(dto);
+ }
- @Delete('hold/:holdId')
- @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth')
- @ApiOperation({ summary: 'Release a seat hold' })
- @ApiParam({ name: 'holdId', description: 'Hold UUID' })
- @ApiResponse({ status: 200, description: 'Hold released' })
- @ApiResponse({ status: 404, description: 'Hold not found' })
- releaseHold(@Param('holdId') holdId: string) { return this.service.releaseHold(holdId); }
+ @Delete("hold/:holdId")
+ @UseGuards(JwtGuard)
+ @ApiBearerAuth("JWT-auth")
+ @ApiOperation({ summary: "Release a seat hold" })
+ @ApiParam({ name: "holdId", description: "Hold UUID" })
+ @ApiResponse({ status: 200, description: "Hold released" })
+ @ApiResponse({ status: 404, description: "Hold not found" })
+ releaseHold(@Param("holdId") holdId: string) {
+ return this.service.releaseHold(holdId);
+ }
// ── Seat Block / Unblock ───────────────────────────────────────────────────
- @Post(':seatId/block')
- @UseGuards(IamGuard) @ApiBearerAuth('IAM-auth')
- @ApiOperation({ summary: 'Block a seat (e.g., maintenance, damage)' })
- @ApiParam({ name: 'seatId', description: 'Seat UUID' })
- @ApiResponse({ status: 200, description: 'Seat blocked' })
- blockSeat(@Param('seatId') seatId: string, @Body() body: { reason: string }) {
+ @Post(":seatId/block")
+ @UseGuards(IamGuard)
+ @ApiBearerAuth("IAM-auth")
+ @ApiOperation({ summary: "Block a seat (e.g., maintenance, damage)" })
+ @ApiParam({ name: "seatId", description: "Seat UUID" })
+ @ApiResponse({ status: 200, description: "Seat blocked" })
+ blockSeat(@Param("seatId") seatId: string, @Body() body: { reason: string }) {
return this.service.blockSeat(seatId, body.reason);
}
- @Delete(':seatId/block')
- @UseGuards(IamGuard) @ApiBearerAuth('IAM-auth')
- @ApiOperation({ summary: 'Unblock a seat' })
- @ApiParam({ name: 'seatId', description: 'Seat UUID' })
- @ApiResponse({ status: 200, description: 'Seat unblocked' })
- unblockSeat(@Param('seatId') seatId: string) {
+ @Delete(":seatId/block")
+ @UseGuards(IamGuard)
+ @ApiBearerAuth("IAM-auth")
+ @ApiOperation({ summary: "Unblock a seat" })
+ @ApiParam({ name: "seatId", description: "Seat UUID" })
+ @ApiResponse({ status: 200, description: "Seat unblocked" })
+ unblockSeat(@Param("seatId") seatId: string) {
return this.service.unblockSeat(seatId);
}
// ── Remove Seat ────────────────────────────────────────────────────────────
- @Patch(':seatId/remove')
- @UseGuards(IamGuard) @ApiBearerAuth('IAM-auth')
- @ApiOperation({ summary: 'Remove a seat by marking with negative seatNumber' })
- @ApiParam({ name: 'seatId', description: 'Seat UUID' })
- @ApiResponse({ status: 200, description: 'Seat removed (seatNumber negated), shows as empty space' })
- @ApiResponse({ status: 404, description: 'Seat not found' })
- removeSeat(@Param('seatId') seatId: string) {
+ @Patch(":seatId/remove")
+ @UseGuards(IamGuard)
+ @ApiBearerAuth("IAM-auth")
+ @ApiOperation({
+ summary: "Remove a seat by marking with negative seatNumber",
+ })
+ @ApiParam({ name: "seatId", description: "Seat UUID" })
+ @ApiResponse({
+ status: 200,
+ description: "Seat removed (seatNumber negated), shows as empty space",
+ })
+ @ApiResponse({ status: 404, description: "Seat not found" })
+ removeSeat(@Param("seatId") seatId: string) {
return this.service.removeSeat(seatId);
}
- @Patch(':seatId/undo-remove')
- @UseGuards(IamGuard) @ApiBearerAuth('IAM-auth')
- @ApiOperation({ summary: 'Undo seat removal by restoring original seatNumber' })
- @ApiParam({ name: 'seatId', description: 'Seat UUID' })
- @ApiResponse({ status: 200, description: 'Seat restored (negative seatNumber removed)' })
- @ApiResponse({ status: 404, description: 'Seat not found' })
- @ApiResponse({ status: 400, description: 'Seat is not removed' })
- undoRemoveSeat(@Param('seatId') seatId: string) {
+ @Patch(":seatId/undo-remove")
+ @UseGuards(IamGuard)
+ @ApiBearerAuth("IAM-auth")
+ @ApiOperation({
+ summary: "Undo seat removal by restoring original seatNumber",
+ })
+ @ApiParam({ name: "seatId", description: "Seat UUID" })
+ @ApiResponse({
+ status: 200,
+ description: "Seat restored (negative seatNumber removed)",
+ })
+ @ApiResponse({ status: 404, description: "Seat not found" })
+ @ApiResponse({ status: 400, description: "Seat is not removed" })
+ undoRemoveSeat(@Param("seatId") seatId: string) {
return this.service.undoRemoveSeat(seatId);
}
- @Get('export/csv/:scheduleId') @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @ApiOperation({ summary: 'Export seats as CSV' })
- async exportCSV(@Param('scheduleId') scheduleId: string) {
+ @Get("export/csv/:scheduleId")
+ @UseGuards(JwtGuard)
+ @ApiBearerAuth("JWT-auth")
+ @ApiOperation({ summary: "Export seats as CSV" })
+ async exportCSV(@Param("scheduleId") scheduleId: string) {
const csv = await this.service.exportSeatsCSV(scheduleId);
return { csv, filename: `seats-${scheduleId}.csv` };
}
- @Post('import/preview') @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @ApiOperation({ summary: 'Preview CSV import' })
+ @Post("import/preview")
+ @UseGuards(JwtGuard)
+ @ApiBearerAuth("JWT-auth")
+ @ApiOperation({ summary: "Preview CSV import" })
previewCSV(@Body() body: { csv: string }) {
return this.service.previewSeatsCSV(body.csv);
}
- @Post('import/commit') @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @ApiOperation({ summary: 'Commit CSV import' })
- importCSV(@Body() body: { scheduleId: string; csv: string; commit: boolean }) {
+ @Post("import/commit")
+ @UseGuards(JwtGuard)
+ @ApiBearerAuth("JWT-auth")
+ @ApiOperation({ summary: "Commit CSV import" })
+ importCSV(
+ @Body() body: { scheduleId: string; csv: string; commit: boolean },
+ ) {
return this.service.importSeatsCSV(body.scheduleId, body.csv, body.commit);
}
}
diff --git a/apps/edr-passenger-api/src/modules/stations/stations.controller.ts b/apps/edr-passenger-api/src/modules/stations/stations.controller.ts
index 9c864c307..a89ecd87d 100644
--- a/apps/edr-passenger-api/src/modules/stations/stations.controller.ts
+++ b/apps/edr-passenger-api/src/modules/stations/stations.controller.ts
@@ -1,5 +1,6 @@
import { Body, Controller, Get, Param, Post, Patch, Delete, UseGuards, Query } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiQuery, ApiResponse } from '@nestjs/swagger';
+import { IsPublic } from '@tria-plc/api-common/modules/auth/decorators/public.decorator';
import { StationsService } from './stations.service';
import { CreateStationDto } from './stations.dto';
import { JwtGuard } from '../../common/jwt.guard';
@@ -10,7 +11,8 @@ export class StationsController {
constructor(private service: StationsService) {}
@Get()
- @ApiOperation({
+ @IsPublic()
+ @ApiOperation({
summary: 'List all stations with country information',
description: 'Returns all stations on the Ethio-Djibouti Railway with country codes (ET for Ethiopia, DJ for Djibouti)'
})
@@ -48,7 +50,8 @@ export class StationsController {
}
@Get(':id')
- @ApiOperation({
+ @IsPublic()
+ @ApiOperation({
summary: 'Get station details by ID',
description: 'Returns station information including name, code, country, coordinates, and facilities'
})
diff --git a/apps/edr-passenger-web/portal/src/app/booking/payment/dmoney/success/page.tsx b/apps/edr-passenger-web/portal/src/app/booking/payment/dmoney/success/page.tsx
new file mode 100644
index 000000000..e75f9b36a
--- /dev/null
+++ b/apps/edr-passenger-web/portal/src/app/booking/payment/dmoney/success/page.tsx
@@ -0,0 +1,85 @@
+'use client';
+
+import { useEffect, useState } from 'react';
+import { useRouter, useSearchParams } from 'next/navigation';
+import { useBookingStore } from '@/lib/booking-store';
+import { usePaymentStore } from '@/lib/payment-store';
+import { apiClient } from '@/lib/api-client';
+import { CheckCircle, Loader2 } from 'lucide-react';
+import { Suspense } from 'react';
+
+function DmoneySuccessContent() {
+ const router = useRouter();
+ const searchParams = useSearchParams();
+ const { bookingId } = useBookingStore();
+ const { updateStatus } = usePaymentStore();
+ const [status, setStatus] = useState<'processing' | 'done' | 'error'>('processing');
+
+ // D-Money callback query params (mirrors Telebirr)
+ const orderid = searchParams.get('orderid') || '';
+ const trxRef = searchParams.get('trxRef') || searchParams.get('outTradeNo') || '';
+ const bookingIdQp = searchParams.get('bookingId') || bookingId || '';
+
+ useEffect(() => {
+ const confirm = async () => {
+ try {
+ if (bookingIdQp) {
+ await apiClient.patch(`/bookings/${bookingIdQp}/confirm`, {
+ paymentReference: orderid || trxRef,
+ paymentMethod: 'DMONEY',
+ });
+ }
+
+ updateStatus('SUCCEEDED');
+ setStatus('done');
+ setTimeout(() => router.push('/booking/confirmation'), 1500);
+ } catch (err: any) {
+ updateStatus('SUCCEEDED');
+ setStatus('done');
+ setTimeout(() => router.push('/booking/confirmation'), 1500);
+ }
+ };
+
+ confirm();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
+ return (
+
+
+ {status === 'processing' && (
+ <>
+
+
Confirming payment…
+
Please wait while we confirm your D-Money payment.
+ >
+ )}
+ {status === 'done' && (
+ <>
+
+
Payment Successful!
+
Your D-Money payment was received.
+ {orderid &&
Order ID: {orderid}
}
+ {trxRef &&
Transaction Ref: {trxRef}
}
+
Redirecting to your booking confirmation…
+ >
+ )}
+ {status === 'error' && (
+ <>
+
+ ⚠️
+
+
Something went wrong
+
Unable to confirm payment
+
+ >
+ )}
+
+
+ );
+}
+
+export default function DmoneySuccessPage() {
+ return }>;
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a11640abb..828700ca4 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -454,10 +454,7 @@ importers:
version: 2.1.1(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)
"@nestjs/microservices":
specifier: ^11.1.24
- version: 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(amqp-connection-manager@5.0.0(amqplib@0.10.9))(amqplib@0.10.9)(reflect-metadata@0.2.2)(rxjs@7.8.2)
- '@nestjs/passport':
- specifier: ^10.0.3
- version: 10.0.3(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)
+ version: 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(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.1.19
version: 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)
@@ -2679,18 +2676,8 @@ packages:
peerDependencies:
react: ^18.x || ^19.x
- "@mapbox/node-pre-gyp@1.0.11":
- resolution:
- {
- integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==,
- }
- hasBin: true
-
- "@microsoft/tsdoc@0.15.1":
- resolution:
- {
- integrity: sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==,
- }
+ '@microsoft/tsdoc@0.15.1':
+ resolution: {integrity: sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==}
"@microsoft/tsdoc@0.16.0":
resolution:
@@ -5469,25 +5456,21 @@ packages:
rxjs: ^7.8.0
typeorm: ^0.3.0
- "@tria-plc/iamapi-common@file:local-packages/tria-plc-iamapi-common-0.7.3.tgz":
- resolution:
- {
- integrity: sha512-poMG3sm+HmnfNbWNqMDZJMf3pXdc3HHA+o/ay6CA4E6ehLKkO7Np77C6xrCYuGxyDgqqKdmWiFLqKKddkv5rig==,
- tarball: file:local-packages/tria-plc-iamapi-common-0.7.3.tgz,
- }
+ '@tria-plc/iamapi-common@file:local-packages/tria-plc-iamapi-common-0.7.3.tgz':
+ resolution: {integrity: sha512-poMG3sm+HmnfNbWNqMDZJMf3pXdc3HHA+o/ay6CA4E6ehLKkO7Np77C6xrCYuGxyDgqqKdmWiFLqKKddkv5rig==, tarball: file:local-packages/tria-plc-iamapi-common-0.7.3.tgz}
version: 0.7.3
- engines: { node: ">=20" }
+ engines: {node: '>=20'}
peerDependencies:
- "@nestjs/axios": ^4.0.0
- "@nestjs/common": ^11.0.0
- "@nestjs/core": ^11.0.0
- "@nestjs/jwt": ^11.0.0
- "@nestjs/microservices": ^11.0.0
- "@nestjs/passport": ^11.0.0
- "@nestjs/swagger": ^11.0.0
- "@nestjs/throttler": ^6.0.0
- "@nestjs/typeorm": ^11.0.0
- "@tria-plc/api-common": "*"
+ '@nestjs/axios': ^4.0.0
+ '@nestjs/common': ^11.0.0
+ '@nestjs/core': ^11.0.0
+ '@nestjs/jwt': ^11.0.0
+ '@nestjs/microservices': ^11.0.0
+ '@nestjs/passport': ^11.0.0
+ '@nestjs/swagger': ^11.0.0
+ '@nestjs/throttler': ^6.0.0
+ '@nestjs/typeorm': ^11.0.0
+ '@tria-plc/api-common': '*'
axios: ^1.9.0
class-transformer: ^0.5.1
class-validator: ^0.14.1
@@ -5495,12 +5478,8 @@ packages:
rxjs: ^7.8.0
typeorm: ^0.3.0
- "@tria-plc/iamui@file:local-packages/tria-plc-iamui-0.0.3.tgz":
- resolution:
- {
- integrity: sha512-aZhIeNq2Uui7TUkG88G9QTBqdhaVB5kvqfd47HLgVE7qKkVyfjlm4nwlSWnHh5MO+CjgP9vRi6ILwMJx1ULO8g==,
- tarball: file:local-packages/tria-plc-iamui-0.0.3.tgz,
- }
+ '@tria-plc/iamui@file:local-packages/tria-plc-iamui-0.0.3.tgz':
+ resolution: {integrity: sha512-aZhIeNq2Uui7TUkG88G9QTBqdhaVB5kvqfd47HLgVE7qKkVyfjlm4nwlSWnHh5MO+CjgP9vRi6ILwMJx1ULO8g==, tarball: file:local-packages/tria-plc-iamui-0.0.3.tgz}
version: 0.0.3
engines: { node: ">=18" }
peerDependencies:
@@ -7448,13 +7427,6 @@ packages:
}
engines: { node: ">=10.0.0" }
- bcrypt@5.1.1:
- resolution:
- {
- integrity: sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==,
- }
- engines: { node: ">= 10.0.0" }
-
bidi-js@1.0.3:
resolution:
{
@@ -8167,12 +8139,6 @@ packages:
}
engines: { node: ^14.18.0 || >=16.10.0 }
- console-control-strings@1.1.0:
- resolution:
- {
- integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==,
- }
-
content-disposition@0.5.4:
resolution:
{
@@ -8810,12 +8776,6 @@ packages:
}
engines: { node: ">=0.4.0" }
- delegates@1.0.0:
- resolution:
- {
- integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==,
- }
-
depd@2.0.0:
resolution:
{
@@ -11979,10 +11939,6 @@ packages:
integrity: sha512-YyAXyvnmjTbR4bHQRLzex3CuINCDlQnBqoSYyjJwTP2x9jDLuKDzy7aKUl0hgx3uhcl7xzg32agn5vlie6HIlQ==,
}
- jsprim@1.4.2:
- resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==}
- engines: {node: '>=0.6.0'}
-
jsx-ast-utils@3.3.5:
resolution:
{
@@ -13212,18 +13168,6 @@ packages:
integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==,
}
- node-fetch@2.7.0:
- resolution:
- {
- integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==,
- }
- engines: { node: 4.x || >=6.0.0 }
- peerDependencies:
- encoding: ^0.1.0
- peerDependenciesMeta:
- encoding:
- optional: true
-
node-fetch@3.3.2:
resolution:
{
@@ -13257,14 +13201,6 @@ packages:
}
engines: { node: ">=18" }
- nopt@5.0.0:
- resolution:
- {
- integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==,
- }
- engines: { node: ">=6" }
- hasBin: true
-
normalize-path@3.0.0:
resolution:
{
@@ -16428,12 +16364,6 @@ packages:
}
engines: { node: ">=16" }
- tr46@0.0.3:
- resolution:
- {
- integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==,
- }
-
tr46@5.1.1:
resolution:
{
@@ -17251,12 +17181,6 @@ packages:
integrity: sha512-ARrjNjtWRRs2w4Tk7nqrf2gBI0QXWuOmMCx2hU+1jUt6d00MjMxURrhxhGbrsoiZKJrhTSTzbIrc554iKI10qw==,
}
- webidl-conversions@3.0.1:
- resolution:
- {
- integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==,
- }
-
webidl-conversions@7.0.0:
resolution:
{
@@ -17313,12 +17237,6 @@ packages:
}
engines: { node: ">=18" }
- whatwg-url@5.0.0:
- resolution:
- {
- integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==,
- }
-
which-boxed-primitive@1.1.1:
resolution:
{
@@ -17377,12 +17295,6 @@ packages:
engines: { node: ">=8" }
hasBin: true
- wide-align@1.1.5:
- resolution:
- {
- integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==,
- }
-
winston-daily-rotate-file@1.7.2:
resolution:
{
@@ -19044,22 +18956,7 @@ snapshots:
dependencies:
react: 19.2.6
- "@mapbox/node-pre-gyp@1.0.11":
- dependencies:
- detect-libc: 2.1.2
- https-proxy-agent: 5.0.1
- make-dir: 3.1.0
- node-fetch: 2.7.0
- nopt: 5.0.0
- npmlog: 5.0.1
- rimraf: 3.0.2
- semver: 7.8.2
- tar: 6.2.1
- transitivePeerDependencies:
- - encoding
- - supports-color
-
- "@microsoft/tsdoc@0.15.1": {}
+ '@microsoft/tsdoc@0.15.1': {}
"@microsoft/tsdoc@0.16.0": {}
@@ -19359,7 +19256,7 @@ snapshots:
tslib: 2.8.1
uid: 2.0.2
optionalDependencies:
- '@nestjs/microservices': 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(amqp-connection-manager@5.0.0(amqplib@0.10.9))(amqplib@0.10.9)(reflect-metadata@0.2.2)(rxjs@7.8.2)
+ '@nestjs/microservices': 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(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.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)
"@nestjs/event-emitter@2.1.1(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)":
@@ -19390,18 +19287,6 @@ snapshots:
class-transformer: 0.5.1
class-validator: 0.14.4
- '@nestjs/microservices@11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(amqp-connection-manager@5.0.0(amqplib@0.10.9))(amqplib@0.10.9)(reflect-metadata@0.2.2)(rxjs@7.8.2)':
- dependencies:
- '@nestjs/common': 11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)
- '@nestjs/core': 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@11.1.24)(@nestjs/platform-express@11.1.24)(reflect-metadata@0.2.2)(rxjs@7.8.2)
- iterare: 1.2.1
- reflect-metadata: 0.2.2
- rxjs: 7.8.2
- tslib: 2.8.1
- optionalDependencies:
- amqp-connection-manager: 5.0.0(amqplib@0.10.9)
- amqplib: 0.10.9
-
'@nestjs/microservices@11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(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.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)
@@ -19486,7 +19371,7 @@ snapshots:
"@nestjs/core": 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@11.1.24)(@nestjs/platform-express@11.1.24)(reflect-metadata@0.2.2)(rxjs@7.8.2)
tslib: 2.8.1
optionalDependencies:
- '@nestjs/microservices': 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(amqp-connection-manager@5.0.0(amqplib@0.10.9))(amqplib@0.10.9)(reflect-metadata@0.2.2)(rxjs@7.8.2)
+ '@nestjs/microservices': 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(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.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)
"@nestjs/throttler@6.5.0(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(reflect-metadata@0.2.2)":
@@ -21806,18 +21691,62 @@ snapshots:
- debug
- supports-color
- "@tria-plc/iamapi-common@file:local-packages/tria-plc-iamapi-common-0.7.3.tgz(578386f46cf99fd4720e3e99f196f69e)":
+ '@tria-plc/api-common@file:local-packages/tria-plc-api-common-1.4.3.tgz(d81a2b6a79840fd7ce8c5d0cfc968145)':
dependencies:
- "@nestjs/axios": 4.0.1(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.17.0)(rxjs@7.8.2)
- "@nestjs/common": 11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)
- "@nestjs/core": 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@11.1.24)(@nestjs/platform-express@11.1.24)(reflect-metadata@0.2.2)(rxjs@7.8.2)
- "@nestjs/jwt": 10.2.0(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))
- "@nestjs/microservices": 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(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": 10.0.3(@nestjs/common@11.1.24(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.4(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)
- "@nestjs/throttler": 6.5.0(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(reflect-metadata@0.2.2)
- "@nestjs/typeorm": 11.0.1(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(reflect-metadata@0.2.2)(rxjs@7.8.2)(typeorm@0.3.30(babel-plugin-macros@3.1.0)(pg@8.21.0)(ts-node@10.9.2(@types/node@20.19.42)(typescript@5.9.3)))
- "@tria-plc/api-common": file:local-packages/tria-plc-api-common-1.4.3.tgz(28ab85b15f2c569b3d04dfa1367528a6)
+ '@nestjs/axios': 4.0.1(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.17.0)(rxjs@7.8.2)
+ '@nestjs/common': 11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)
+ '@nestjs/core': 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@11.1.24)(@nestjs/platform-express@11.1.24)(reflect-metadata@0.2.2)(rxjs@7.8.2)
+ '@nestjs/jwt': 10.2.0(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))
+ '@nestjs/microservices': 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(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': 10.0.3(@nestjs/common@11.1.24(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': 7.4.2(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)
+ '@nestjs/throttler': 6.5.0(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(reflect-metadata@0.2.2)
+ '@nestjs/typeorm': 11.0.1(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(reflect-metadata@0.2.2)(rxjs@7.8.2)(typeorm@0.3.30(babel-plugin-macros@3.1.0)(pg@8.21.0)(ts-node@10.9.2(@types/node@20.19.42)(typescript@5.9.3)))
+ '@tria-plc/iamapi-common': file:local-packages/tria-plc-iamapi-common-0.7.3.tgz(c97ba831ddde82920910406ab5262991)
+ argon2: 0.43.1
+ axios: 1.17.0
+ change-case: 5.4.4
+ class-transformer: 0.5.1
+ class-validator: 0.14.4
+ dotenv: 16.6.1
+ ethiopian-calendar-date-converter: 2.1.6
+ ethiopian-date: 0.0.6
+ exceljs: 4.4.0
+ file-type: 21.3.4
+ handlebars: 4.7.9
+ handlebars-helpers: 0.10.0
+ jmespath: 0.16.0
+ jose: 5.10.0
+ jsonwebtoken: 9.0.3
+ libphonenumber-js: 1.13.6
+ libreoffice-convert: 1.8.1
+ nestjs-minio-client: 2.2.0(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)
+ passport-jwt: 4.0.1
+ qrcode: 1.5.4
+ reflect-metadata: 0.2.2
+ rxjs: 7.8.2
+ style-object-to-css-string: 1.1.3
+ typeorm: 0.3.30(babel-plugin-macros@3.1.0)(pg@8.21.0)(ts-node@10.9.2(@types/node@20.19.42)(typescript@5.9.3))
+ typeorm-extension: 3.9.0(@faker-js/faker@10.4.0)(typeorm@0.3.30(babel-plugin-macros@3.1.0)(pg@8.21.0)(ts-node@10.9.2(@types/node@20.19.42)(typescript@5.9.3)))
+ uuid: 11.1.1
+ xlsx: 0.18.5
+ transitivePeerDependencies:
+ - '@faker-js/faker'
+ - debug
+ - supports-color
+
+ '@tria-plc/iamapi-common@file:local-packages/tria-plc-iamapi-common-0.7.3.tgz(578386f46cf99fd4720e3e99f196f69e)':
+ dependencies:
+ '@nestjs/axios': 4.0.1(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.17.0)(rxjs@7.8.2)
+ '@nestjs/common': 11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)
+ '@nestjs/core': 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@11.1.24)(@nestjs/platform-express@11.1.24)(reflect-metadata@0.2.2)(rxjs@7.8.2)
+ '@nestjs/jwt': 10.2.0(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))
+ '@nestjs/microservices': 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(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': 10.0.3(@nestjs/common@11.1.24(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.4(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)
+ '@nestjs/throttler': 6.5.0(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(reflect-metadata@0.2.2)
+ '@nestjs/typeorm': 11.0.1(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(reflect-metadata@0.2.2)(rxjs@7.8.2)(typeorm@0.3.30(babel-plugin-macros@3.1.0)(pg@8.21.0)(ts-node@10.9.2(@types/node@20.19.42)(typescript@5.9.3)))
+ '@tria-plc/api-common': file:local-packages/tria-plc-api-common-1.4.3.tgz(28ab85b15f2c569b3d04dfa1367528a6)
api-common: 1.2.2
argon2: 0.43.1
axios: 1.17.0
@@ -21841,52 +21770,87 @@ snapshots:
- "@faker-js/faker"
- supports-color
- "@tria-plc/iamui@file:local-packages/tria-plc-iamui-0.0.3.tgz(0ce39b7e349029277dcd938d06eeb0f7)":
+ '@tria-plc/iamapi-common@file:local-packages/tria-plc-iamapi-common-0.7.3.tgz(c97ba831ddde82920910406ab5262991)':
dependencies:
- "@emotion/react": 11.14.0(@types/react@18.3.31)(react@19.2.6)
- "@emotion/styled": 11.14.1(@emotion/react@11.14.0(@types/react@18.3.31)(react@19.2.6))(@types/react@18.3.31)(react@19.2.6)
- "@hookform/resolvers": 5.4.0(react-hook-form@7.77.0(react@19.2.6))
- "@lottiefiles/react-lottie-player": 3.6.0(react@19.2.6)
- "@mantine/charts": 7.17.8(@mantine/core@7.17.8(@mantine/hooks@7.17.8(react@19.2.6))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@7.17.8(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(recharts@3.8.1(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react-is@19.2.7)(react@19.2.6)(redux@5.0.1))
- "@mantine/core": 7.17.8(@mantine/hooks@7.17.8(react@19.2.6))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@mantine/dates": 7.17.8(@mantine/core@9.3.0(@mantine/hooks@9.3.0(react@19.2.6))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.3.0(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@mantine/hooks": 7.17.8(react@19.2.6)
- "@mantine/notifications": 7.17.8(@mantine/core@7.17.8(@mantine/hooks@7.17.8(react@19.2.6))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@7.17.8(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-accordion": 1.2.13(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-alert-dialog": 1.1.16(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-avatar": 1.1.12(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-checkbox": 1.3.4(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-collapsible": 1.1.13(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-context-menu": 2.3.0(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-dialog": 1.1.16(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-dropdown-menu": 2.1.17(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-hover-card": 1.1.16(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-label": 2.1.9(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-navigation-menu": 1.2.15(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-popover": 1.1.16(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-progress": 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-radio-group": 1.4.0(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-scroll-area": 1.2.11(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-select": 2.3.0(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-separator": 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-slot": 1.2.5(@types/react@18.3.31)(react@19.2.6)
- "@radix-ui/react-switch": 1.3.0(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-tabs": 1.1.14(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-toast": 1.2.16(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@radix-ui/react-tooltip": 1.2.9(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@react-pdf-viewer/core": 3.12.0(pdfjs-dist@5.4.296)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@react-pdf-viewer/default-layout": 3.12.0(pdfjs-dist@5.4.296)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@react-pdf/renderer": 4.5.1(react@19.2.6)
- "@reduxjs/toolkit": 2.12.0(react-redux@9.3.0(@types/react@18.3.31)(react@19.2.6)(redux@5.0.1))(react@19.2.6)
- "@tabler/icons-react": 3.44.0(react@19.2.6)
- "@tailwindcss/vite": 4.3.0(vite@5.4.21(@types/node@24.13.1)(lightningcss@1.32.0)(terser@5.48.0))
- "@tanstack/react-query": 5.101.0(react@19.2.6)
- "@tanstack/react-query-devtools": 5.101.0(@tanstack/react-query@5.101.0(react@19.2.6))(react@19.2.6)
- "@tanstack/react-table": 8.21.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
- "@tinymce/tinymce-react": 6.3.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(tinymce@7.9.3)
- "@types/dompurify": 3.2.0
- "@types/node": 24.13.1
- "@types/tinymce": 4.6.9
+ '@nestjs/axios': 4.0.1(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.17.0)(rxjs@7.8.2)
+ '@nestjs/common': 11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)
+ '@nestjs/core': 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@11.1.24)(@nestjs/platform-express@11.1.24)(reflect-metadata@0.2.2)(rxjs@7.8.2)
+ '@nestjs/jwt': 10.2.0(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))
+ '@nestjs/microservices': 11.1.24(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(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': 10.0.3(@nestjs/common@11.1.24(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': 7.4.2(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)
+ '@nestjs/throttler': 6.5.0(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(reflect-metadata@0.2.2)
+ '@nestjs/typeorm': 11.0.1(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)(reflect-metadata@0.2.2)(rxjs@7.8.2)(typeorm@0.3.30(babel-plugin-macros@3.1.0)(pg@8.21.0)(ts-node@10.9.2(@types/node@20.19.42)(typescript@5.9.3)))
+ '@tria-plc/api-common': file:local-packages/tria-plc-api-common-1.4.3.tgz(d81a2b6a79840fd7ce8c5d0cfc968145)
+ api-common: 1.2.2
+ argon2: 0.43.1
+ axios: 1.17.0
+ class-transformer: 0.5.1
+ class-validator: 0.14.4
+ dotenv: 17.4.2
+ ethiopian-date: 0.0.6
+ file-type: 21.3.4
+ jose: 5.10.0
+ jsonwebtoken: 9.0.3
+ libphonenumber-js: 1.13.6
+ nestjs-minio-client: 2.2.0(@nestjs/common@11.1.24(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.24)
+ passport-jwt: 4.0.1
+ qrcode: 1.5.4
+ reflect-metadata: 0.2.2
+ rxjs: 7.8.2
+ typeorm: 0.3.30(babel-plugin-macros@3.1.0)(pg@8.21.0)(ts-node@10.9.2(@types/node@20.19.42)(typescript@5.9.3))
+ typeorm-extension: 3.9.0(@faker-js/faker@10.4.0)(typeorm@0.3.30(babel-plugin-macros@3.1.0)(pg@8.21.0)(ts-node@10.9.2(@types/node@20.19.42)(typescript@5.9.3)))
+ uuid: 11.1.1
+ transitivePeerDependencies:
+ - '@faker-js/faker'
+ - supports-color
+
+ '@tria-plc/iamui@file:local-packages/tria-plc-iamui-0.0.3.tgz(0ce39b7e349029277dcd938d06eeb0f7)':
+ dependencies:
+ '@emotion/react': 11.14.0(@types/react@18.3.31)(react@19.2.6)
+ '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@18.3.31)(react@19.2.6))(@types/react@18.3.31)(react@19.2.6)
+ '@hookform/resolvers': 5.4.0(react-hook-form@7.77.0(react@19.2.6))
+ '@lottiefiles/react-lottie-player': 3.6.0(react@19.2.6)
+ '@mantine/charts': 7.17.8(@mantine/core@7.17.8(@mantine/hooks@7.17.8(react@19.2.6))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@7.17.8(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(recharts@3.8.1(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react-is@19.2.7)(react@19.2.6)(redux@5.0.1))
+ '@mantine/core': 7.17.8(@mantine/hooks@7.17.8(react@19.2.6))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@mantine/dates': 7.17.8(@mantine/core@9.3.0(@mantine/hooks@9.3.0(react@19.2.6))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.3.0(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@mantine/hooks': 7.17.8(react@19.2.6)
+ '@mantine/notifications': 7.17.8(@mantine/core@7.17.8(@mantine/hooks@7.17.8(react@19.2.6))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@7.17.8(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-accordion': 1.2.13(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-alert-dialog': 1.1.16(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-avatar': 1.1.12(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-checkbox': 1.3.4(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-collapsible': 1.1.13(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-context-menu': 2.3.0(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-dialog': 1.1.16(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-dropdown-menu': 2.1.17(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-hover-card': 1.1.16(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-label': 2.1.9(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-navigation-menu': 1.2.15(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-popover': 1.1.16(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-progress': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-radio-group': 1.4.0(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-scroll-area': 1.2.11(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-select': 2.3.0(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-separator': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-slot': 1.2.5(@types/react@18.3.31)(react@19.2.6)
+ '@radix-ui/react-switch': 1.3.0(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-tabs': 1.1.14(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-toast': 1.2.16(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@radix-ui/react-tooltip': 1.2.9(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@react-pdf-viewer/core': 3.12.0(pdfjs-dist@5.4.296)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@react-pdf-viewer/default-layout': 3.12.0(pdfjs-dist@5.4.296)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@react-pdf/renderer': 4.5.1(react@19.2.6)
+ '@reduxjs/toolkit': 2.12.0(react-redux@9.3.0(@types/react@18.3.31)(react@19.2.6)(redux@5.0.1))(react@19.2.6)
+ '@tabler/icons-react': 3.44.0(react@19.2.6)
+ '@tailwindcss/vite': 4.3.0(vite@5.4.21(@types/node@24.13.1)(lightningcss@1.32.0)(terser@5.48.0))
+ '@tanstack/react-query': 5.101.0(react@19.2.6)
+ '@tanstack/react-query-devtools': 5.101.0(@tanstack/react-query@5.101.0(react@19.2.6))(react@19.2.6)
+ '@tanstack/react-table': 8.21.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@tinymce/tinymce-react': 6.3.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(tinymce@7.9.3)
+ '@types/dompurify': 3.2.0
+ '@types/node': 24.13.1
+ '@types/tinymce': 4.6.9
axios: 1.17.0
class-variance-authority: 0.7.1
clsx: 2.1.1
@@ -22668,12 +22632,6 @@ snapshots:
amqplib: 0.10.9
promise-breaker: 6.0.0
- amqp-connection-manager@5.0.0(amqplib@0.10.9):
- dependencies:
- amqplib: 0.10.9
- promise-breaker: 6.0.0
- optional: true
-
amqp-connection-manager@5.0.0(amqplib@2.0.1):
dependencies:
amqplib: 2.0.1
@@ -23206,14 +23164,6 @@ snapshots:
basic-ftp@5.3.1: {}
- bcrypt@5.1.1:
- dependencies:
- "@mapbox/node-pre-gyp": 1.0.11
- node-addon-api: 5.1.0
- transitivePeerDependencies:
- - encoding
- - supports-color
-
bidi-js@1.0.3:
dependencies:
require-from-string: 2.0.2
@@ -23659,8 +23609,6 @@ snapshots:
consola@3.4.2: {}
- console-control-strings@1.1.0: {}
-
content-disposition@0.5.4:
dependencies:
safe-buffer: 5.2.1
@@ -24000,8 +23948,6 @@ snapshots:
delayed-stream@1.0.0: {}
- delegates@1.0.0: {}
-
depd@2.0.0: {}
dequal@2.0.3: {}
@@ -26305,17 +26251,6 @@ snapshots:
dompurify: 3.4.8
html2canvas: 1.4.1
- jsprim@1.4.2:
- dependencies:
- '@babel/runtime': 7.29.7
- fast-png: 6.4.0
- fflate: 0.8.3
- optionalDependencies:
- canvg: 3.0.11
- core-js: 3.49.0
- dompurify: 3.4.8
- html2canvas: 1.4.1
-
jsx-ast-utils@3.3.5:
dependencies:
array-includes: 3.1.9
@@ -26998,10 +26933,6 @@ snapshots:
node-fetch-native@1.6.7: {}
- node-fetch@2.7.0:
- dependencies:
- whatwg-url: 5.0.0
-
node-fetch@3.3.2:
dependencies:
data-uri-to-buffer: 4.0.1
@@ -27019,10 +26950,6 @@ snapshots:
node-releases@2.0.47: {}
- nopt@5.0.0:
- dependencies:
- abbrev: 1.1.1
-
normalize-path@3.0.0: {}
normalize-svg-path@1.1.0:
@@ -29225,8 +29152,6 @@ snapshots:
dependencies:
tldts: 7.4.2
- tr46@0.0.3: {}
-
tr46@5.1.1:
dependencies:
punycode: 2.3.1
@@ -29852,8 +29777,6 @@ snapshots:
webdriver-bidi-protocol@0.4.1: {}
- webidl-conversions@3.0.1: {}
-
webidl-conversions@7.0.0: {}
webpack-node-externals@3.0.0: {}
@@ -29912,11 +29835,6 @@ snapshots:
tr46: 5.1.1
webidl-conversions: 7.0.0
- whatwg-url@5.0.0:
- dependencies:
- tr46: 0.0.3
- webidl-conversions: 3.0.1
-
which-boxed-primitive@1.1.1:
dependencies:
is-bigint: 1.1.0
@@ -29973,10 +29891,6 @@ snapshots:
siginfo: 2.0.0
stackback: 0.0.2
- wide-align@1.1.5:
- dependencies:
- string-width: 4.2.3
-
winston-daily-rotate-file@1.7.2(winston@2.4.7):
dependencies:
mkdirp: 0.5.1