import { Injectable } from '@nestjs/common'; import { DbService } from '../db/db.service'; type EdgeRow = { id: string; name: string; tag_count: number; current_tag_count: number; live_tag_count: number; last_data_at: Date | null; created_at: Date; updated_at: Date; }; type EdgeItem = { id: string; name: string; tagCount: number; currentTagCount: number; liveTagCount: number; lastDataAt: Date | null; createdAt: Date; updatedAt: Date; }; type EdgeResponse = { items: EdgeItem[]; }; @Injectable() export class EdgeService { constructor(private readonly db: DbService) {} // Возвращает каталог буровых с легкой сводкой по свежести данных для dashboard UI. async findAll(): Promise { const result = await this.db.query(` SELECT e.id, e.name, count(DISTINCT et.tag_id)::integer AS tag_count, count(DISTINCT cv.tag_id)::integer AS current_tag_count, count(DISTINCT cv.tag_id) FILTER ( WHERE cv.time >= now() - INTERVAL '30 seconds' )::integer AS live_tag_count, max(cv.time) AS last_data_at, e.created_at, e.updated_at FROM edge AS e LEFT JOIN edge_tag AS et ON et.edge_id = e.id LEFT JOIN current_values AS cv ON cv.edge_id = e.id AND cv.tag_id = et.tag_id GROUP BY e.id, e.name, e.created_at, e.updated_at ORDER BY e.name ASC, e.id ASC `); return { items: result.rows.map((row) => ({ id: row.id, name: row.name, tagCount: row.tag_count, currentTagCount: row.current_tag_count, liveTagCount: row.live_tag_count, lastDataAt: row.last_data_at, createdAt: row.created_at, updatedAt: row.updated_at, })), }; } }