fix issue

This commit is contained in:
Marshal
2026-07-16 00:33:31 +00:00
parent 234a74e812
commit 41fe04652f
51 changed files with 1895 additions and 206 deletions

View File

@@ -1,4 +1,5 @@
import { ConflictException, Injectable, NotFoundException } from '@nestjs/common';
import { DataSource } from 'typeorm';
import { CreateLocomotiveDto } from './dto/create-locomotive.dto';
import { FilterLocomotivesDto } from './dto/filter-locomotives.dto';
@@ -9,11 +10,23 @@ import {
type LocomotiveStatus,
type LocomotiveType,
} from './entities/locomotive.entity';
import { TrainLocomotive } from '../trains/entities/train-locomotive.entity';
import { LocomotivesRepository } from './locomotives.repository';
@Injectable()
export class LocomotivesService {
constructor(private readonly locomotivesRepository: LocomotivesRepository) {}
constructor(
private readonly locomotivesRepository: LocomotivesRepository,
private readonly dataSource: DataSource,
) {}
/** The built-train link (if any) coupling this locomotive to a fleet train. */
private findTrainLink(locomotiveId: string): Promise<TrainLocomotive | null> {
return this.dataSource.getRepository(TrainLocomotive).findOne({
where: { locomotiveId },
relations: { train: true },
});
}
findAll(filter: FilterLocomotivesDto): Promise<Locomotive[]> {
return this.locomotivesRepository.findAll({
@@ -94,6 +107,22 @@ export class LocomotivesService {
}
}
// A locomotive coupled to a built train follows the train: its yard and
// status are owned by the train-builder flow, not this generic PATCH.
const link = await this.findTrainLink(id);
if (link) {
if (dto.currentYardId !== undefined && dto.currentYardId !== link.train?.currentYardId) {
throw new ConflictException(
`Locomotive ${locomotive.code} is coupled to train ${link.train?.code}; move the train (train-builder yard change) instead`,
);
}
if (dto.status !== undefined && dto.status !== locomotive.status) {
throw new ConflictException(
`Locomotive ${locomotive.code} is coupled to train ${link.train?.code}; detach it before changing its status`,
);
}
}
const updated = await this.locomotivesRepository.update(id, {
...dto,
locomotiveType:
@@ -119,7 +148,16 @@ export class LocomotivesService {
}
async decommission(id: string): Promise<Locomotive> {
await this.findById(id);
const locomotive = await this.findById(id);
// Can't retire a locomotive that is still coupled to a built train — detach
// it in the train-builder first so the train never loses a live loco.
const link = await this.findTrainLink(id);
if (link) {
throw new ConflictException(
`Locomotive ${locomotive.code} is coupled to train ${link.train?.code}; detach it before taking it out of service`,
);
}
const updated = await this.locomotivesRepository.update(id, {
status: 'OUT_OF_SERVICE',