chore: import DH V2 D5.6.4 production baseline
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
const newPermissions = [
|
||||
'assets.read_provenance',
|
||||
'assets.manage_provenance',
|
||||
'assets.verify_provenance',
|
||||
'assets.read_temporal',
|
||||
] as const;
|
||||
|
||||
const rolePermissionValues = `
|
||||
('admin', 'assets.read_provenance'),
|
||||
('admin', 'assets.manage_provenance'),
|
||||
('admin', 'assets.verify_provenance'),
|
||||
('admin', 'assets.read_temporal'),
|
||||
('director', 'assets.read_provenance'),
|
||||
('director', 'assets.verify_provenance'),
|
||||
('director', 'assets.read_temporal'),
|
||||
('supervisor', 'assets.read_provenance'),
|
||||
('supervisor', 'assets.manage_provenance'),
|
||||
('supervisor', 'assets.verify_provenance'),
|
||||
('supervisor', 'assets.read_temporal'),
|
||||
('inspector', 'assets.read_provenance'),
|
||||
('inspector', 'assets.manage_provenance'),
|
||||
('inspector', 'assets.read_temporal'),
|
||||
('auditor', 'assets.read_provenance'),
|
||||
('auditor', 'assets.read_temporal')
|
||||
`;
|
||||
|
||||
export class PhaseB5ProvenanceTemporal1786723203000 implements MigrationInterface {
|
||||
name = 'PhaseB5ProvenanceTemporal1786723203000';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE assets
|
||||
ADD COLUMN data_origin varchar(32) NOT NULL DEFAULT 'MANUAL',
|
||||
ADD COLUMN source_name varchar(160),
|
||||
ADD COLUMN source_reference varchar(255),
|
||||
ADD COLUMN source_observed_at timestamptz,
|
||||
ADD COLUMN source_notes text,
|
||||
ADD COLUMN provenance_verified_at timestamptz,
|
||||
ADD COLUMN provenance_verified_by uuid,
|
||||
ADD COLUMN provenance_updated_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
ADD COLUMN provenance_updated_by uuid,
|
||||
ADD CONSTRAINT chk_assets_data_origin CHECK (data_origin IN (
|
||||
'MANUAL', 'FIELD_SURVEY', 'PROVIDED_DOCUMENT', 'IMPORT', 'SYSTEM'
|
||||
)),
|
||||
ADD CONSTRAINT fk_assets_provenance_verified_by FOREIGN KEY (provenance_verified_by)
|
||||
REFERENCES users(id) ON DELETE SET NULL,
|
||||
ADD CONSTRAINT fk_assets_provenance_updated_by FOREIGN KEY (provenance_updated_by)
|
||||
REFERENCES users(id) ON DELETE SET NULL
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
UPDATE assets
|
||||
SET provenance_updated_by = updated_by
|
||||
`);
|
||||
await queryRunner.query(`CREATE INDEX idx_assets_data_origin ON assets (data_origin)`);
|
||||
await queryRunner.query(`
|
||||
CREATE INDEX idx_assets_provenance_verified_at
|
||||
ON assets (provenance_verified_at)
|
||||
`);
|
||||
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE asset_versions
|
||||
DROP CONSTRAINT chk_asset_versions_change_type
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE asset_versions
|
||||
ADD CONSTRAINT chk_asset_versions_change_type CHECK (change_type IN (
|
||||
'BASELINE', 'CREATED', 'UPDATED', 'STATUS_CHANGED',
|
||||
'GEOMETRY_UPDATED', 'GEOMETRY_REMOVED',
|
||||
'MEDIA_UPLOADED', 'MEDIA_UPDATED', 'MEDIA_REMOVED',
|
||||
'PROVENANCE_BASELINE', 'PROVENANCE_UPDATED', 'PROVENANCE_VERIFIED'
|
||||
))
|
||||
`);
|
||||
|
||||
await queryRunner.query(`
|
||||
WITH bumped AS (
|
||||
UPDATE assets
|
||||
SET current_version = current_version + 1
|
||||
RETURNING *
|
||||
)
|
||||
INSERT INTO asset_versions (
|
||||
asset_id, version_number, change_type, changed_fields, snapshot,
|
||||
actor_user_id, actor_username, source, request_id
|
||||
)
|
||||
SELECT
|
||||
asset.id,
|
||||
asset.current_version,
|
||||
'PROVENANCE_BASELINE',
|
||||
ARRAY['provenance']::text[],
|
||||
COALESCE(previous.snapshot, '{}'::jsonb) || JSONB_BUILD_OBJECT(
|
||||
'provenance', JSONB_BUILD_OBJECT(
|
||||
'origin', asset.data_origin,
|
||||
'sourceName', asset.source_name,
|
||||
'sourceReference', asset.source_reference,
|
||||
'observedAt', asset.source_observed_at,
|
||||
'notes', asset.source_notes,
|
||||
'verifiedAt', asset.provenance_verified_at,
|
||||
'verifiedBy', asset.provenance_verified_by,
|
||||
'updatedAt', asset.provenance_updated_at,
|
||||
'updatedBy', asset.provenance_updated_by
|
||||
),
|
||||
'currentVersion', asset.current_version
|
||||
),
|
||||
NULL,
|
||||
NULL,
|
||||
'SYSTEM',
|
||||
'migration:phase-b5-provenance-baseline'
|
||||
FROM bumped asset
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT version.snapshot
|
||||
FROM asset_versions version
|
||||
WHERE version.asset_id = asset.id
|
||||
ORDER BY version.version_number DESC
|
||||
LIMIT 1
|
||||
) previous ON true
|
||||
`);
|
||||
|
||||
await queryRunner.query(`
|
||||
INSERT INTO permissions (code, description)
|
||||
VALUES
|
||||
('assets.read_provenance', 'Consultar procedencia de datos de activos'),
|
||||
('assets.manage_provenance', 'Actualizar procedencia de datos de activos'),
|
||||
('assets.verify_provenance', 'Verificar procedencia de datos de activos'),
|
||||
('assets.read_temporal', 'Reconstruir el maestro de activos a una fecha')
|
||||
ON CONFLICT (code) DO UPDATE SET description = EXCLUDED.description
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
WITH mapping(role_code, permission_code) AS (VALUES ${rolePermissionValues})
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT role.id, permission.id
|
||||
FROM mapping
|
||||
INNER JOIN roles role ON role.code = mapping.role_code
|
||||
INNER JOIN permissions permission ON permission.code = mapping.permission_code
|
||||
ON CONFLICT (role_id, permission_id) DO NOTHING
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
WITH mapping(role_code, permission_code) AS (VALUES ${rolePermissionValues})
|
||||
DELETE FROM role_permissions role_permission
|
||||
USING roles role, permissions permission, mapping
|
||||
WHERE role_permission.role_id = role.id
|
||||
AND role_permission.permission_id = permission.id
|
||||
AND role.code = mapping.role_code
|
||||
AND permission.code = mapping.permission_code
|
||||
`);
|
||||
await queryRunner.query(
|
||||
`DELETE FROM permissions WHERE code = ANY($1::varchar[])
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM role_permissions WHERE permission_id = permissions.id
|
||||
)`,
|
||||
[newPermissions],
|
||||
);
|
||||
await queryRunner.query(`
|
||||
UPDATE asset_versions
|
||||
SET change_type = 'UPDATED'
|
||||
WHERE change_type IN (
|
||||
'PROVENANCE_BASELINE', 'PROVENANCE_UPDATED', 'PROVENANCE_VERIFIED'
|
||||
)
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE asset_versions
|
||||
DROP CONSTRAINT chk_asset_versions_change_type
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE asset_versions
|
||||
ADD CONSTRAINT chk_asset_versions_change_type CHECK (change_type IN (
|
||||
'BASELINE', 'CREATED', 'UPDATED', 'STATUS_CHANGED',
|
||||
'GEOMETRY_UPDATED', 'GEOMETRY_REMOVED',
|
||||
'MEDIA_UPLOADED', 'MEDIA_UPDATED', 'MEDIA_REMOVED'
|
||||
))
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE assets
|
||||
DROP CONSTRAINT fk_assets_provenance_verified_by,
|
||||
DROP CONSTRAINT fk_assets_provenance_updated_by,
|
||||
DROP CONSTRAINT chk_assets_data_origin,
|
||||
DROP COLUMN data_origin,
|
||||
DROP COLUMN source_name,
|
||||
DROP COLUMN source_reference,
|
||||
DROP COLUMN source_observed_at,
|
||||
DROP COLUMN source_notes,
|
||||
DROP COLUMN provenance_verified_at,
|
||||
DROP COLUMN provenance_verified_by,
|
||||
DROP COLUMN provenance_updated_at,
|
||||
DROP COLUMN provenance_updated_by
|
||||
`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user