fix: fully retire Director report permissions in F4
This commit is contained in:
@@ -1,10 +1,17 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
const legacyDirectorPermissions = [
|
||||
['inspection_reports.revise', 'Cargar versiones corregidas del informe para revisión directiva'],
|
||||
['inspection_reports.review', 'Aprobar la versión vigente del informe'],
|
||||
['inspection_reports.sign_final', 'Firmar electrónicamente el informe final aprobado'],
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Retira definitivamente el circuito legacy Director -> revisión -> aprobación -> firma.
|
||||
* Retira definitivamente el circuito activo legacy Director -> revisión -> aprobación -> firma.
|
||||
*
|
||||
* current_revision_number se conserva porque pertenece al versionado útil del INF y no
|
||||
* al circuito de aprobación retirado.
|
||||
* current_revision_number e inspection_report_revisions se conservan porque forman parte del
|
||||
* versionado útil del INF. inspection_report_signatures también se conserva como archivo
|
||||
* histórico: F4 quita sus endpoints/permisos pero no destruye evidencia documental ya emitida.
|
||||
*/
|
||||
export class F4RemoveDirectorReportLegacy1790000400000 implements MigrationInterface {
|
||||
name = 'F4RemoveDirectorReportLegacy1790000400000';
|
||||
@@ -17,6 +24,28 @@ export class F4RemoveDirectorReportLegacy1790000400000 implements MigrationInter
|
||||
WHERE recipient_kind = 'DIRECTOR'
|
||||
`);
|
||||
|
||||
// Retira permisos huérfanos del circuito anterior para que tampoco aparezcan
|
||||
// como capacidades administrables en RBAC una vez eliminados sus endpoints.
|
||||
await queryRunner.query(`
|
||||
DELETE FROM role_permissions
|
||||
WHERE permission_id IN (
|
||||
SELECT id FROM permissions
|
||||
WHERE code IN (
|
||||
'inspection_reports.revise',
|
||||
'inspection_reports.review',
|
||||
'inspection_reports.sign_final'
|
||||
)
|
||||
)
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
DELETE FROM permissions
|
||||
WHERE code IN (
|
||||
'inspection_reports.revise',
|
||||
'inspection_reports.review',
|
||||
'inspection_reports.sign_final'
|
||||
)
|
||||
`);
|
||||
|
||||
await queryRunner.query(`ALTER TABLE inspection_reports DROP COLUMN IF EXISTS approved_revision_id`);
|
||||
await queryRunner.query(`ALTER TABLE inspection_reports DROP COLUMN IF EXISTS approved_by`);
|
||||
await queryRunner.query(`ALTER TABLE inspection_reports DROP COLUMN IF EXISTS approved_at`);
|
||||
@@ -26,9 +55,9 @@ export class F4RemoveDirectorReportLegacy1790000400000 implements MigrationInter
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
// El rollback reconstruye la forma del esquema, pero no recrea entregas Director
|
||||
// ni datos de aprobación eliminados. El backup PRE-F4 es la fuente de recuperación
|
||||
// si alguna vez fuera necesario volver a ese circuito.
|
||||
// El rollback reconstruye el contrato técnico legacy, pero no recrea entregas Director
|
||||
// ni valores de aprobación eliminados. El backup PRE-F4 sigue siendo la fuente de
|
||||
// recuperación de esos datos históricos si alguna vez fuera necesario volver al circuito.
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE inspection_reports
|
||||
ADD COLUMN IF NOT EXISTS review_status varchar(32) NOT NULL DEFAULT 'PENDING_REVIEW'
|
||||
@@ -38,5 +67,47 @@ export class F4RemoveDirectorReportLegacy1790000400000 implements MigrationInter
|
||||
await queryRunner.query(`ALTER TABLE inspection_reports ADD COLUMN IF NOT EXISTS approved_at timestamptz`);
|
||||
await queryRunner.query(`ALTER TABLE inspection_reports ADD COLUMN IF NOT EXISTS review_note varchar(1000)`);
|
||||
await queryRunner.query(`ALTER TABLE inspection_reports ADD COLUMN IF NOT EXISTS signed_at timestamptz`);
|
||||
|
||||
await queryRunner.query(`
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE inspection_reports
|
||||
ADD CONSTRAINT chk_inspection_reports_review_status
|
||||
CHECK (review_status IN ('PENDING_REVIEW','APPROVED','SIGNED'));
|
||||
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE inspection_reports
|
||||
ADD CONSTRAINT fk_inspection_reports_approved_by
|
||||
FOREIGN KEY (approved_by) REFERENCES users(id) ON DELETE SET NULL;
|
||||
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE inspection_reports
|
||||
ADD CONSTRAINT fk_inspection_reports_approved_revision
|
||||
FOREIGN KEY (approved_revision_id) REFERENCES inspection_report_revisions(id) ON DELETE RESTRICT;
|
||||
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
|
||||
`);
|
||||
|
||||
for (const [code, description] of legacyDirectorPermissions) {
|
||||
await queryRunner.query(
|
||||
`INSERT INTO permissions (code, description) VALUES ($1, $2) ON CONFLICT (code) DO UPDATE SET description = EXCLUDED.description`,
|
||||
[code, description],
|
||||
);
|
||||
}
|
||||
await queryRunner.query(`
|
||||
WITH mapping(role_code, permission_code) AS (VALUES
|
||||
('director', 'inspection_reports.revise'),
|
||||
('director', 'inspection_reports.review'),
|
||||
('director', 'inspection_reports.sign_final')
|
||||
)
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT role.id, permission.id
|
||||
FROM mapping
|
||||
JOIN roles role ON role.code = mapping.role_code
|
||||
JOIN permissions permission ON permission.code = mapping.permission_code
|
||||
ON CONFLICT (role_id, permission_id) DO NOTHING
|
||||
`);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user