fix issues

This commit is contained in:
Marshal
2026-07-03 13:40:10 +00:00
parent e14df58a47
commit 52f48b688d
11 changed files with 343 additions and 59 deletions

View File

@@ -16,15 +16,48 @@ export class RatesRepository implements IRatesRepository {
}
findLiveRates(): Promise<Rate[]> {
const now = new Date();
return this.repo
.createQueryBuilder('rate')
.where('rate.status = :status', { status: 'LIVE' })
.andWhere('rate.effective_from <= :now', { now })
.andWhere('(rate.effective_to IS NULL OR rate.effective_to > :now)', { now })
.getMany();
}
/**
* Find a non-superseded rate matching an identity pattern — the same tuple the
* `UQ_rates_pattern` unique index enforces. Used to reject duplicates before
* insert so the admin gets a friendly error instead of a raw constraint fault.
* NULL scope columns are matched with IS NULL, mirroring the COALESCE index.
*/
findByPattern(pattern: {
rateType: string;
containerTypeId?: string | null;
cargoTypeId?: string | null;
tradeDirection?: string | null;
}): Promise<Rate | null> {
const qb = this.repo
.createQueryBuilder('rate')
.where('rate.rate_type = :rateType', { rateType: pattern.rateType })
.andWhere('rate.status <> :superseded', { superseded: 'SUPERSEDED' });
if (pattern.containerTypeId) {
qb.andWhere('rate.container_type_id = :containerTypeId', { containerTypeId: pattern.containerTypeId });
} else {
qb.andWhere('rate.container_type_id IS NULL');
}
if (pattern.cargoTypeId) {
qb.andWhere('rate.cargo_type_id = :cargoTypeId', { cargoTypeId: pattern.cargoTypeId });
} else {
qb.andWhere('rate.cargo_type_id IS NULL');
}
if (pattern.tradeDirection) {
qb.andWhere('rate.trade_direction = :tradeDirection', { tradeDirection: pattern.tradeDirection });
} else {
qb.andWhere('rate.trade_direction IS NULL');
}
return qb.getOne();
}
findAll(options?: FindManyOptions<Rate>): Promise<Rate[]> {
return this.repo.find(options);
}

View File

@@ -22,7 +22,6 @@ export class WeightLimitRulesRepository implements IWeightLimitRulesRepository {
containerTypeId: string,
tradeDirection: string,
): Promise<WeightLimitRule[]> {
const now = new Date();
return this.repo
.createQueryBuilder('rule')
.innerJoinAndSelect('rule.containerType', 'ct')
@@ -31,11 +30,27 @@ export class WeightLimitRulesRepository implements IWeightLimitRulesRepository {
dir: tradeDirection,
both: 'BOTH',
})
.andWhere('rule.effective_from <= :now', { now })
.andWhere('(rule.effective_to IS NULL OR rule.effective_to > :now)', { now })
.getMany();
}
/**
* Find a rule matching the (containerType, tradeDirection) identity — the
* tuple enforced by `UQ_weight_limit_rules_pattern`. Used to reject duplicates
* before insert. Optionally excludes a row by id so updates don't self-collide.
*/
findByPattern(
containerTypeId: string,
tradeDirection: string,
excludeId?: string,
): Promise<WeightLimitRule | null> {
const qb = this.repo
.createQueryBuilder('rule')
.where('rule.container_type_id = :containerTypeId', { containerTypeId })
.andWhere('rule.trade_direction = :tradeDirection', { tradeDirection });
if (excludeId) qb.andWhere('rule.id <> :excludeId', { excludeId });
return qb.getOne();
}
findAll(options?: FindManyOptions<WeightLimitRule>): Promise<WeightLimitRule[]> {
return this.repo.find(options);
}