51 lines
2.6 KiB
TypeScript
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 } }
|
|
);
|
|
}
|
|
}
|