mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 17:10:56 +00:00
Project Initialization
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { Body, Controller, Get, Param, ParseUUIDPipe, Post, Query } from '@nestjs/common';
|
||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
|
||||
import { ConsignmentsService } from './consignments.service';
|
||||
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) {}
|
||||
|
||||
@Post()
|
||||
@ApiOperation({ summary: 'Create a new consignment' })
|
||||
create(@Body() dto: CreateConsignmentDto) {
|
||||
return this.consignmentsService.create(dto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'List consignments (paginated)' })
|
||||
findAll(@Query() filter: FilterConsignmentDto) {
|
||||
return this.consignmentsService.findAll(filter);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@ApiOperation({ summary: 'Get a consignment by ID' })
|
||||
findOne(@Param('id', ParseUUIDPipe) id: string) {
|
||||
return this.consignmentsService.findById(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { ConsignmentsController } from './consignments.controller';
|
||||
import { ConsignmentsRepository } from './consignments.repository';
|
||||
import { ConsignmentsService } from './consignments.service';
|
||||
import { Consignment } from './entities/consignment.entity';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Consignment])],
|
||||
controllers: [ConsignmentsController],
|
||||
providers: [ConsignmentsService, ConsignmentsRepository],
|
||||
exports: [ConsignmentsService],
|
||||
})
|
||||
export class ConsignmentsModule {}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { BaseRepository } from '@edr/api-common';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { Consignment } from './entities/consignment.entity';
|
||||
|
||||
@Injectable()
|
||||
export class ConsignmentsRepository extends BaseRepository<Consignment> {
|
||||
constructor(
|
||||
@InjectRepository(Consignment)
|
||||
repository: Repository<Consignment>,
|
||||
) {
|
||||
super(repository);
|
||||
}
|
||||
|
||||
/** Look up a consignment by its tracking number. */
|
||||
findByTrackingNumber(trackingNumber: string): Promise<Consignment | null> {
|
||||
return this.repository.findOne({ where: { trackingNumber } });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
|
||||
import { ConsignmentsRepository } from './consignments.repository';
|
||||
import { CreateConsignmentDto } from './dto/create-consignment.dto';
|
||||
import { FilterConsignmentDto } from './dto/filter-consignment.dto';
|
||||
import { Consignment } from './entities/consignment.entity';
|
||||
|
||||
@Injectable()
|
||||
export class ConsignmentsService {
|
||||
constructor(private readonly consignmentsRepository: ConsignmentsRepository) {}
|
||||
|
||||
/** Create a new consignment for a freight booking. */
|
||||
create(dto: CreateConsignmentDto): Promise<Consignment> {
|
||||
return this.consignmentsRepository.create(dto);
|
||||
}
|
||||
|
||||
/** Return a paginated list of consignments. */
|
||||
async findAll(filter: FilterConsignmentDto): Promise<{ items: Consignment[]; total: number }> {
|
||||
const page = filter.page ?? 1;
|
||||
const pageSize = filter.pageSize ?? 20;
|
||||
const [items, total] = await this.consignmentsRepository.findAndCount({
|
||||
where: {
|
||||
...(filter.status ? { status: filter.status } : {}),
|
||||
...(filter.bookingId ? { bookingId: filter.bookingId } : {}),
|
||||
},
|
||||
skip: (page - 1) * pageSize,
|
||||
take: pageSize,
|
||||
order: { createdAt: 'DESC' },
|
||||
});
|
||||
return { items, total };
|
||||
}
|
||||
|
||||
/** Get a single consignment by ID. */
|
||||
async findById(id: string): Promise<Consignment> {
|
||||
const consignment = await this.consignmentsRepository.findById(id);
|
||||
if (!consignment) {
|
||||
throw new NotFoundException(`Consignment ${id} not found`);
|
||||
}
|
||||
return consignment;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Freight } from '@edr/types';
|
||||
import { IsEnum, IsNumber, IsString, IsUUID, Min } from 'class-validator';
|
||||
|
||||
export class CreateConsignmentDto {
|
||||
@IsUUID()
|
||||
bookingId!: string;
|
||||
|
||||
@IsString()
|
||||
trackingNumber!: string;
|
||||
|
||||
@IsEnum(Freight.CargoType)
|
||||
cargoType!: Freight.CargoType;
|
||||
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
weightKg!: number;
|
||||
|
||||
@IsString()
|
||||
originStation!: string;
|
||||
|
||||
@IsString()
|
||||
destinationStation!: string;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Freight } from '@edr/types';
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsEnum, IsInt, IsOptional, IsUUID, Min } from 'class-validator';
|
||||
|
||||
export class FilterConsignmentDto {
|
||||
@IsOptional()
|
||||
@IsEnum(Freight.ConsignmentStatus)
|
||||
status?: Freight.ConsignmentStatus;
|
||||
|
||||
@IsOptional()
|
||||
@IsUUID()
|
||||
bookingId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
page?: number = 1;
|
||||
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
pageSize?: number = 20;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { BaseEntity } from '@edr/api-common';
|
||||
import { Freight } from '@edr/types';
|
||||
import { Column, Entity } from 'typeorm';
|
||||
|
||||
@Entity({ name: 'consignments' })
|
||||
export class Consignment extends BaseEntity {
|
||||
@Column({ name: 'booking_id', type: 'uuid' })
|
||||
bookingId!: string;
|
||||
|
||||
@Column({ name: 'tracking_number', type: 'varchar', length: 64, unique: true })
|
||||
trackingNumber!: string;
|
||||
|
||||
@Column({ name: 'cargo_type', type: 'enum', enum: Freight.CargoType })
|
||||
cargoType!: Freight.CargoType;
|
||||
|
||||
@Column({ name: 'weight_kg', type: 'numeric', precision: 12, scale: 2 })
|
||||
weightKg!: number;
|
||||
|
||||
@Column({
|
||||
name: 'status',
|
||||
type: 'enum',
|
||||
enum: Freight.ConsignmentStatus,
|
||||
default: Freight.ConsignmentStatus.Pending,
|
||||
})
|
||||
status!: Freight.ConsignmentStatus;
|
||||
|
||||
@Column({ name: 'origin_station', type: 'varchar', length: 128 })
|
||||
originStation!: string;
|
||||
|
||||
@Column({ name: 'destination_station', type: 'varchar', length: 128 })
|
||||
destinationStation!: string;
|
||||
}
|
||||
Reference in New Issue
Block a user