metis-desk/modules/assets/src/api/infrastructure/persistence/asset-dashboard-reader.ts
2026-10-08 16:43:34 +02:00

51 lines
2.6 KiB
TypeScript

import type { Sequelize } from "sequelize";
import { QueryTypes } from "sequelize";
type Entry = {
eventId?: string;
id: string;
companyId: string;
companyName: string;
name: string;
recordedAt: string | null;
actorName: string | null;
};
/** Proyección de lectura acotada; no reconstruye inventarios ni agregados. */
export class AssetDashboardReader {
constructor(private readonly database: Sequelize) {}
stats(companyId?: string) {
return this.database.query<{ companyId: string; count: number }>(
"SELECT companyId,COUNT(*) AS count FROM assets WHERE (:companyId IS NULL OR companyId=:companyId) GROUP BY companyId",
{ type: QueryTypes.SELECT, replacements: { companyId: companyId ?? null } }
);
}
async entries(companyId?: string, issue?: string, page = 1) {
const where =
"WHERE (:companyId IS NULL OR a.companyId=:companyId)" +
(issue === "missing_site" ? " AND a.siteId IS NULL" : "");
const replacements = { companyId: companyId ?? null, offset: (page - 1) * 10 };
const counts = await this.database.query<{ total: number }>(
`SELECT COUNT(*) AS total FROM assets a ${where}`,
{ type: QueryTypes.SELECT, replacements }
);
const items = await this.database.query<Entry>(
`SELECT a.id,a.companyId,c.name AS companyName,JSON_UNQUOTE(JSON_EXTRACT(a.\`values\`,'$.name')) AS name,NULL AS recordedAt,NULL AS actorName FROM assets a JOIN companies c ON c.id=a.companyId ${where} ORDER BY name,a.id LIMIT 10 OFFSET :offset`,
{ type: QueryTypes.SELECT, replacements }
);
return { total: Number(counts[0]?.total ?? 0), items };
}
inactivePeople(companyId?: string) {
return this.database.query<{ id: string }>(
"SELECT DISTINCT p.id FROM assets a JOIN company_contacts p ON p.id=a.personId AND p.companyId=a.companyId WHERE p.active=0 AND JSON_UNQUOTE(JSON_EXTRACT(a.`values`,'$.status')) <> 'retired' AND (:companyId IS NULL OR a.companyId=:companyId)",
{ type: QueryTypes.SELECT, replacements: { companyId: companyId ?? null } }
);
}
activity(companyId?: string) {
return this.database.query<Entry>(
"SELECT a.id,r.id AS eventId,a.companyId,c.name AS companyName,JSON_UNQUOTE(JSON_EXTRACT(a.`values`,'$.name')) AS name,r.recordedAt,u.name AS actorName FROM asset_revisions r JOIN assets a ON a.id=r.assetId JOIN companies c ON c.id=a.companyId LEFT JOIN users u ON u.id=r.actorId WHERE (:companyId IS NULL OR a.companyId=:companyId) ORDER BY r.recordedAt DESC,r.id DESC LIMIT 6",
{ type: QueryTypes.SELECT, replacements: { companyId: companyId ?? null } }
);
}
}