Refactor funciones de verificación y migración de activos para mejorar la legibilidad y eliminar parámetros innecesarios

This commit is contained in:
David Arranz 2026-10-10 11:09:34 +02:00
parent 4edc1268b4
commit 0996db18c7
4 changed files with 29 additions and 35 deletions

View File

@ -787,12 +787,7 @@ test("HTTP y MariaDB: configuración única, usuarios, sesiones y protección de
secondCompany.id,
database
);
await verifyInventory(
(...args) => operator.request(...args),
customer.id,
secondCompany.id,
database
);
await verifyInventory((...args) => operator.request(...args), customer.id, secondCompany.id);
await verifyRelationships(
(...args) => operator.request(...args),
customer.id,

View File

@ -7,15 +7,13 @@ import {
SaveDefinitionResponseSchema,
} from "@metis/assets/common";
import { CompanyResponseSchema } from "@metis/companies/common";
import type { Sequelize } from "sequelize";
import { z } from "zod/v4";
import { UniqueID } from "../../../packages/rdx-ddd/src/index";
export async function verifyInventory(
request: (path: string, body?: unknown, origin?: string, token?: string) => Promise<Response>,
companyId: string,
otherId: string,
database: Sequelize
otherId: string
) {
const path = `/assets/${companyId}`;
async function save(url: string, values: unknown) {

View File

@ -41,7 +41,9 @@ export async function verifyWorkstations(
assert.ok(person);
const otherPersonResponse = await request(`/companies/${otherId}/people`, personFields);
assert.equal(otherPersonResponse.status, 201);
const otherPerson = CompanyResponseSchema.parse(await otherPersonResponse.json()).company.people.at(-1);
const otherPerson = CompanyResponseSchema.parse(
await otherPersonResponse.json()
).company.people.at(-1);
assert.ok(otherPerson);
const input = {
name: "Puesto Ana",

View File

@ -102,17 +102,17 @@ export async function migrateLegacyAssetAssignments(database: Sequelize) {
if (!("personId" in assetColumns)) {
return;
}
const legacy = await database.query<LegacyAssignment>(
const legacyAssignments = await database.query<LegacyAssignment>(
"SELECT a.id,a.companyId,a.siteId,a.personId,p.name AS personName,s.name AS siteName,(SELECT r.actorId FROM asset_revisions r WHERE r.assetId=a.id ORDER BY r.position DESC LIMIT 1) AS actorId FROM assets a JOIN company_contacts p ON p.id=a.personId AND p.companyId=a.companyId LEFT JOIN company_sites s ON s.id=a.siteId AND s.companyId=a.companyId WHERE a.personId IS NOT NULL AND JSON_UNQUOTE(JSON_EXTRACT(a.`values`,'$.status')) <> 'retired'",
{ type: QueryTypes.SELECT }
);
const active = await database.query<ActiveWorkstationAsset>(
const activeWorkstationAssets = await database.query<ActiveWorkstationAsset>(
"SELECT wa.assetId,w.personId FROM workstation_assets wa JOIN workstations w ON w.id=wa.workstationId WHERE wa.activeKey IS NOT NULL",
{ type: QueryTypes.SELECT }
);
const activeByAsset = new Map(active.map((item) => [item.assetId, item]));
const activeByAsset = new Map(activeWorkstationAssets.map((item) => [item.assetId, item]));
const groups = new Map<string, LegacyAssignment[]>();
for (const assignment of legacy) {
for (const assignment of legacyAssignments) {
const existing = activeByAsset.get(assignment.id);
if (existing) {
if (existing.personId !== assignment.personId) {
@ -197,25 +197,24 @@ export async function migrateLegacyAssetAssignments(database: Sequelize) {
transaction,
});
});
const revisionColumns = await query.describeTable("asset_revisions");
for (const [table, columns] of [
["asset_revisions", revisionColumns],
["assets", assetColumns],
] as const) {
if (!("personId" in columns)) {
continue;
}
const constraints = await database.query<{ constraintName: string }>(
"SELECT CONSTRAINT_NAME AS constraintName FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=:table AND COLUMN_NAME='personId' AND REFERENCED_TABLE_NAME IS NOT NULL",
{ replacements: { table }, type: QueryTypes.SELECT }
);
for (const { constraintName } of constraints) {
await database.query(
`ALTER TABLE \`${table}\` DROP FOREIGN KEY \`${constraintName.replaceAll("`", "``")}\``
);
}
// Sequelize 6 y mariadb 3 devuelven una matriz inmutable para ALTER TABLE,
// que hace fallar QueryInterface.removeColumn después de ejecutar correctamente la migración.
await database.query(`ALTER TABLE \`${table}\` DROP COLUMN personId`);
}
await removeLegacyPersonColumn(database, "asset_revisions");
await removeLegacyPersonColumn(database, "assets");
}
async function removeLegacyPersonColumn(database: Sequelize, table: "assets" | "asset_revisions") {
const columns = await database.getQueryInterface().describeTable(table);
if (!("personId" in columns)) {
return;
}
const constraints = await database.query<{ constraintName: string }>(
"SELECT CONSTRAINT_NAME AS constraintName FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=:table AND COLUMN_NAME='personId' AND REFERENCED_TABLE_NAME IS NOT NULL",
{ replacements: { table }, type: QueryTypes.SELECT }
);
for (const { constraintName } of constraints) {
await database.query(
`ALTER TABLE \`${table}\` DROP FOREIGN KEY \`${constraintName.replaceAll("`", "``")}\``
);
}
// QueryInterface.removeColumn is incompatible with Sequelize 6 and mariadb 3 here.
await database.query(`ALTER TABLE \`${table}\` DROP COLUMN personId`);
}