feat(f4): implement JEFE deadline policy and calendar administration

This commit is contained in:
2026-09-07 21:02:44 -03:00
parent d071e6be74
commit 9a79b7eb86
@@ -0,0 +1,160 @@
import { Injectable } from '@nestjs/common';
import { DataSource } from 'typeorm';
import { administrationAuditContext } from '../administration/common/administration-audit';
import { AuditService } from '../audit/audit.service';
import type { AuthPrincipal, RequestWithContext } from '../common/http/request-context';
import { AuditAction } from '../database/entities';
import type { UpdateDeadlinePolicyDto, UpsertBusinessCalendarDayDto } from './dto/update-deadline-policy.dto';
@Injectable()
export class InspectionDeadlineAdminService {
constructor(
private readonly dataSource: DataSource,
private readonly audit: AuditService,
) {}
async policy() {
const [row] = await this.dataSource.query(`
SELECT id,
urgent_days AS "urgentDays",
urgent_day_type AS "urgentDayType",
non_urgent_days AS "nonUrgentDays",
non_urgent_day_type AS "nonUrgentDayType",
updated_by AS "updatedBy",
updated_at AS "updatedAt"
FROM inspection_deadline_policies
ORDER BY created_at
LIMIT 1
`);
return row ?? {
urgentDays: 5,
urgentDayType: 'BUSINESS',
nonUrgentDays: 10,
nonUrgentDayType: 'BUSINESS',
};
}
async updatePolicy(
dto: UpdateDeadlinePolicyDto,
principal: AuthPrincipal,
request: RequestWithContext,
) {
const before = await this.policy();
const [existing] = await this.dataSource.query(`
SELECT id FROM inspection_deadline_policies ORDER BY created_at LIMIT 1
`) as Array<{ id: string }>;
if (existing) {
await this.dataSource.query(`
UPDATE inspection_deadline_policies
SET urgent_days=$2,
urgent_day_type=$3,
non_urgent_days=$4,
non_urgent_day_type=$5,
updated_by=$6,
updated_at=CURRENT_TIMESTAMP
WHERE id=$1
`, [
existing.id,
dto.urgentDays,
dto.urgentDayType,
dto.nonUrgentDays,
dto.nonUrgentDayType,
principal.userId,
]);
} else {
await this.dataSource.query(`
INSERT INTO inspection_deadline_policies(
urgent_days,urgent_day_type,non_urgent_days,non_urgent_day_type,updated_by
) VALUES($1,$2,$3,$4,$5)
`, [
dto.urgentDays,
dto.urgentDayType,
dto.nonUrgentDays,
dto.nonUrgentDayType,
principal.userId,
]);
}
const after = await this.policy();
await this.audit.record({
...administrationAuditContext(principal, request),
action: AuditAction.INSPECTION_DEADLINE_POLICY_UPDATED,
entityType: 'inspection_deadline_policy',
entityId: String((after as { id?: string }).id ?? 'singleton'),
beforeData: before as Record<string, unknown>,
afterData: after as Record<string, unknown>,
metadata: {
appliesOnlyToFutureLockedActs: true,
historicalActsKeepSnapshot: true,
},
});
return after;
}
async calendar() {
const data = await this.dataSource.query(`
SELECT id,date,is_business_day AS "isBusinessDay",label,
updated_by AS "updatedBy",created_at AS "createdAt",updated_at AS "updatedAt"
FROM inspection_business_calendar_days
ORDER BY date
`);
return { data };
}
async upsertCalendarDay(
dto: UpsertBusinessCalendarDayDto,
principal: AuthPrincipal,
request: RequestWithContext,
) {
const [before] = await this.dataSource.query(`
SELECT id,date,is_business_day AS "isBusinessDay",label
FROM inspection_business_calendar_days WHERE date=$1::date
`, [dto.date]);
await this.dataSource.query(`
INSERT INTO inspection_business_calendar_days(date,is_business_day,label,updated_by)
VALUES($1::date,$2,$3,$4)
ON CONFLICT(date) DO UPDATE SET
is_business_day=EXCLUDED.is_business_day,
label=EXCLUDED.label,
updated_by=EXCLUDED.updated_by,
updated_at=CURRENT_TIMESTAMP
`, [dto.date, dto.isBusinessDay, dto.label, principal.userId]);
const [after] = await this.dataSource.query(`
SELECT id,date,is_business_day AS "isBusinessDay",label,
updated_by AS "updatedBy",updated_at AS "updatedAt"
FROM inspection_business_calendar_days WHERE date=$1::date
`, [dto.date]);
await this.audit.record({
...administrationAuditContext(principal, request),
action: AuditAction.INSPECTION_BUSINESS_CALENDAR_UPDATED,
entityType: 'inspection_business_calendar_day',
entityId: String(after.id),
beforeData: before ?? null,
afterData: after,
});
return after;
}
async removeCalendarDay(
date: string,
principal: AuthPrincipal,
request: RequestWithContext,
) {
const [before] = await this.dataSource.query(`
SELECT id,date,is_business_day AS "isBusinessDay",label
FROM inspection_business_calendar_days WHERE date=$1::date
`, [date]);
if (before) {
await this.dataSource.query(`DELETE FROM inspection_business_calendar_days WHERE id=$1`, [before.id]);
await this.audit.record({
...administrationAuditContext(principal, request),
action: AuditAction.INSPECTION_BUSINESS_CALENDAR_UPDATED,
entityType: 'inspection_business_calendar_day',
entityId: String(before.id),
beforeData: before,
afterData: null,
metadata: { removed: true },
});
}
return { removed: Boolean(before), date };
}
}