metis-desk/modules/assets/src/api/infrastructure/persistence/rename-workstations-from-primary-assets.ts

73 lines
2.8 KiB
TypeScript
Raw Normal View History

import { UniqueID } from "@repo/rdx-ddd";
import type { Sequelize } from "sequelize";
import { QueryTypes } from "sequelize";
import { z } from "zod/v4";
import { WorkstationInputSchema } from "../../domain/workstation-values";
const CandidateSchema = z.object({
id: z.uuid(),
name: WorkstationInputSchema.shape.name,
});
/** Corrección explícita de nombres; conserva las revisiones anteriores y la composición. */
export async function renameWorkstationsFromPrimaryAssets(database: Sequelize, actorId: string) {
const actor = z.uuid().parse(actorId);
return database.transaction(async (transaction) => {
const users = await database.query<{ id: string }>(
"SELECT id FROM users WHERE id=:actor AND active=1",
{ replacements: { actor }, transaction, type: QueryTypes.SELECT }
);
if (users.length !== 1) {
throw new Error("La corrección requiere un usuario activo para registrar las revisiones.");
}
// Mismo bloqueo por compañía que las escrituras ordinarias del inventario.
await database.query("SELECT id FROM companies ORDER BY id FOR UPDATE", {
transaction,
type: QueryTypes.SELECT,
});
const candidates = z.array(CandidateSchema).parse(
await database.query(
`SELECT w.id,a.name FROM workstations w
INNER JOIN assets a ON a.id=w.computerAssetId AND a.companyId=w.companyId
INNER JOIN workstation_members m ON m.workstationId=w.id AND m.assetId=a.id AND m.kind='exclusive'
WHERE BINARY w.name<>BINARY a.name FOR UPDATE`,
{ transaction, type: QueryTypes.SELECT }
)
);
for (const candidate of candidates) {
const replacements = {
id: candidate.id,
name: candidate.name,
revisionId: UniqueID.generateNewID().toPrimitive(),
actor,
recordedAt: new Date().toISOString(),
};
await database.query(
`INSERT INTO workstation_revisions
(id,workstationId,actorId,siteId,personId,computerAssetId,name,active,recordedAt,position)
SELECT :revisionId,w.id,:actor,w.siteId,w.personId,w.computerAssetId,:name,w.active,
GREATEST(:recordedAt,COALESCE(MAX(r.recordedAt),:recordedAt)),COALESCE(MAX(r.position),-1)+1
FROM workstations w LEFT JOIN workstation_revisions r ON r.workstationId=w.id
WHERE w.id=:id GROUP BY w.id,w.siteId,w.personId,w.computerAssetId,w.active`,
{ replacements, transaction }
);
await database.query(
`INSERT INTO workstation_revision_members (revisionId,assetId,kind,position)
SELECT :revisionId,assetId,kind,position FROM workstation_members WHERE workstationId=:id`,
{ replacements, transaction }
);
await database.query("UPDATE workstations SET name=:name WHERE id=:id", {
replacements,
transaction,
});
}
return candidates.length;
});
}