Christian Mueller 8a5031649a feat: add datapoint delete, show emoji icons in preview
- DELETE /api/datapoints/:id endpoint + frontend button
- Preview shows emoji symbols instead of [icon] text

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 03:55:35 +02:00

140 lines
3.9 KiB
TypeScript

import { getDb } from '../../db/index';
import { applyTransform, type TransformConfig } from './transforms';
export interface Datapoint {
id: number;
name: string;
label: string;
unit: string | null;
value: string | null;
status: string;
source_type: string;
source_id: number;
topic_id: number | null;
query_id: number | null;
transform: string | null;
enabled: number;
updated_at: string;
}
export interface DatapointUpdate {
label?: string;
unit?: string;
transform?: string | null;
enabled?: number;
}
export function getAllDatapoints(): Datapoint[] {
const db = getDb();
return db
.prepare('SELECT * FROM datapoints WHERE enabled = 1')
.all() as Datapoint[];
}
export function getDatapointById(id: number): Datapoint | undefined {
const db = getDb();
return db
.prepare('SELECT * FROM datapoints WHERE id = ?')
.get(id) as Datapoint | undefined;
}
export function updateDatapointValue(id: number, rawValue: string): Datapoint | undefined {
const db = getDb();
const dp = db.prepare('SELECT * FROM datapoints WHERE id = ?').get(id) as Datapoint | undefined;
if (!dp) return undefined;
let config: TransformConfig | null = null;
if (dp.transform) {
try {
config = JSON.parse(dp.transform) as TransformConfig;
} catch {
config = null;
}
}
const transformed = applyTransform(rawValue, config);
db.prepare(
`UPDATE datapoints SET value = ?, status = 'ok', updated_at = datetime('now') WHERE id = ?`
).run(transformed, id);
return db.prepare('SELECT * FROM datapoints WHERE id = ?').get(id) as Datapoint | undefined;
}
export function updateDatapoint(id: number, data: DatapointUpdate): Datapoint | undefined {
const db = getDb();
const fields: string[] = [];
const values: unknown[] = [];
if (data.label !== undefined) {
fields.push('label = ?');
values.push(data.label);
}
if (data.unit !== undefined) {
fields.push('unit = ?');
values.push(data.unit);
}
if (data.transform !== undefined) {
fields.push('transform = ?');
values.push(data.transform);
}
if (data.enabled !== undefined) {
fields.push('enabled = ?');
values.push(data.enabled);
}
if (fields.length === 0) return getDatapointById(id);
values.push(id);
db.prepare(`UPDATE datapoints SET ${fields.join(', ')} WHERE id = ?`).run(...values);
return getDatapointById(id);
}
export function createDatapointFromMqtt(
brokerId: number,
topicId: number,
topicPath: string
): Datapoint {
const db = getDb();
const result = db.prepare(
`INSERT INTO datapoints (name, label, source_type, source_id, topic_id, enabled)
VALUES (?, ?, 'mqtt', ?, ?, 1)`
).run(topicPath, topicPath, brokerId, topicId);
const id = result.lastInsertRowid as number;
return db.prepare('SELECT * FROM datapoints WHERE id = ?').get(id) as Datapoint;
}
export function createDatapointFromPg(
sourceId: number,
queryId: number,
queryName: string
): Datapoint {
const db = getDb();
const result = db.prepare(
`INSERT INTO datapoints (name, label, source_type, source_id, query_id, enabled)
VALUES (?, ?, 'postgresql', ?, ?, 1)`
).run(queryName, queryName, sourceId, queryId);
const id = result.lastInsertRowid as number;
return db.prepare('SELECT * FROM datapoints WHERE id = ?').get(id) as Datapoint;
}
export function deleteDatapoint(id: number): boolean {
const db = getDb();
const result = db.prepare('DELETE FROM datapoints WHERE id = ?').run(id);
return (result.changes as number) > 0;
}
export function getDatapointByTopicId(topicId: number): Datapoint | undefined {
const db = getDb();
return db
.prepare('SELECT * FROM datapoints WHERE topic_id = ?')
.get(topicId) as Datapoint | undefined;
}
export function getDatapointByQueryId(queryId: number): Datapoint | undefined {
const db = getDb();
return db
.prepare('SELECT * FROM datapoints WHERE query_id = ?')
.get(queryId) as Datapoint | undefined;
}