mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-07 11:55:42 +00:00
Merge pull request #39 from Tria-plc/freight_feature/booking/minio
add signed url
This commit is contained in:
@@ -2,13 +2,14 @@ import { Module } from "@nestjs/common";
|
|||||||
import { TypeOrmModule } from "@nestjs/typeorm";
|
import { TypeOrmModule } from "@nestjs/typeorm";
|
||||||
|
|
||||||
import { FilesModule } from "../files/files.module";
|
import { FilesModule } from "../files/files.module";
|
||||||
|
import { MinioModule } from "../minio/minio.module";
|
||||||
import { BookingsController } from "./bookings.controller";
|
import { BookingsController } from "./bookings.controller";
|
||||||
import { BookingsRepository } from "./bookings.repository";
|
import { BookingsRepository } from "./bookings.repository";
|
||||||
import { BookingsService } from "./bookings.service";
|
import { BookingsService } from "./bookings.service";
|
||||||
import { Booking } from "./entities/booking.entity";
|
import { Booking } from "./entities/booking.entity";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [TypeOrmModule.forFeature([Booking]), FilesModule],
|
imports: [TypeOrmModule.forFeature([Booking]), FilesModule, MinioModule],
|
||||||
controllers: [BookingsController],
|
controllers: [BookingsController],
|
||||||
providers: [BookingsService, BookingsRepository],
|
providers: [BookingsService, BookingsRepository],
|
||||||
exports: [BookingsService],
|
exports: [BookingsService],
|
||||||
|
|||||||
@@ -7,12 +7,14 @@ import {
|
|||||||
import { IsNull, Not } from "typeorm";
|
import { IsNull, Not } from "typeorm";
|
||||||
|
|
||||||
import { FilesService } from "../files/files.service";
|
import { FilesService } from "../files/files.service";
|
||||||
|
import { MinioService } from "../minio/minio.service";
|
||||||
import { BookingsRepository } from "./bookings.repository";
|
import { BookingsRepository } from "./bookings.repository";
|
||||||
import { CreateBookingDto } from "./dto/create-booking.dto";
|
import { CreateBookingDto } from "./dto/create-booking.dto";
|
||||||
import { FilterBookingDto } from "./dto/filter-booking.dto";
|
import { FilterBookingDto } from "./dto/filter-booking.dto";
|
||||||
import { UpdateBookingDto } from "./dto/update-booking.dto";
|
import { UpdateBookingDto } from "./dto/update-booking.dto";
|
||||||
import { UpdateStatusDto } from "./dto/update-status.dto";
|
import { UpdateStatusDto } from "./dto/update-status.dto";
|
||||||
import { Booking } from "./entities/booking.entity";
|
import { Booking } from "./entities/booking.entity";
|
||||||
|
import { FileRecord } from "../files/entities/file.entity";
|
||||||
|
|
||||||
/** Weight thresholds (tons) that trigger overweight surcharge alerts. */
|
/** Weight thresholds (tons) that trigger overweight surcharge alerts. */
|
||||||
const WEIGHT_LIMITS = {
|
const WEIGHT_LIMITS = {
|
||||||
@@ -29,6 +31,7 @@ export class BookingsService {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly bookingsRepository: BookingsRepository,
|
private readonly bookingsRepository: BookingsRepository,
|
||||||
private readonly filesService: FilesService,
|
private readonly filesService: FilesService,
|
||||||
|
private readonly minioService: MinioService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
// ── helpers ──────────────────────────────────────────────────────────
|
// ── helpers ──────────────────────────────────────────────────────────
|
||||||
@@ -233,15 +236,45 @@ export class BookingsService {
|
|||||||
if (!booking) {
|
if (!booking) {
|
||||||
throw new NotFoundException(`Booking ${id} not found`);
|
throw new NotFoundException(`Booking ${id} not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add signed URLs for files (5-minute expiration)
|
||||||
|
if (booking.files && booking.files.length > 0) {
|
||||||
|
booking.files = await Promise.all(
|
||||||
|
booking.files.map(async (file: FileRecord) => {
|
||||||
|
const objectName = this.extractObjectName(file.url);
|
||||||
|
const signedUrl = await this.minioService.getSignedUrl(objectName, 300);
|
||||||
|
return { ...file, signedUrl };
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return booking;
|
return booking;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Extract object name from Minio URL. */
|
||||||
|
private extractObjectName(url: string): string {
|
||||||
|
const parts = url.split("/");
|
||||||
|
return parts.slice(4).join("/");
|
||||||
|
}
|
||||||
|
|
||||||
/** Find booking by reference with files. */
|
/** Find booking by reference with files. */
|
||||||
async findByReference(reference: string): Promise<Booking> {
|
async findByReference(reference: string): Promise<Booking> {
|
||||||
const booking = await this.bookingsRepository.findByReferenceWithFiles(reference);
|
const booking = await this.bookingsRepository.findByReferenceWithFiles(reference);
|
||||||
if (!booking) {
|
if (!booking) {
|
||||||
throw new NotFoundException(`Booking with reference "${reference}" not found`);
|
throw new NotFoundException(`Booking with reference "${reference}" not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add signed URLs for files (5-minute expiration)
|
||||||
|
if (booking.files && booking.files.length > 0) {
|
||||||
|
booking.files = await Promise.all(
|
||||||
|
booking.files.map(async (file: FileRecord) => {
|
||||||
|
const objectName = this.extractObjectName(file.url);
|
||||||
|
const signedUrl = await this.minioService.getSignedUrl(objectName, 300);
|
||||||
|
return { ...file, signedUrl };
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return booking;
|
return booking;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,4 +72,13 @@ export class MinioService {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getSignedUrl(objectName: string, expirySeconds: number = 300): Promise<string> {
|
||||||
|
try {
|
||||||
|
return await this.client.presignedGetObject(this.bucket, objectName, expirySeconds);
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(`Failed to generate signed URL for ${objectName}:`, error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user