08919752e3
Checkpoint multi-chantiers (arbre vert : tsc 0 erreur, 70 tests, build OK). - tâche 1.9 Phase 1 : schéma socle (machine_state/events/reports/raw_artifacts/ hardware/metrics + colonnes étendues) + wiring refresh/execute. Migration 0002. - tâche 1.9 Phase 2 : machine_credentials + machine_host_keys (non destructif, dual-read + backfill). Migration 0003. Fix séquence journal de migration. - tâche 2 : SJ-0 (types étendus rétro-compatibles, réducteur Docker, resolveTemplate), SJ-1 (update-analyze enrichi), SJ-2 (apply + diff dpkg + timeout inactivité SSH), SJ-3 (reboot vérifié boot_id). - WIP parallèle inclus : /api/capabilities, auth/apiTokens/apiClients, system metrics, scaffold app_rust, ajustements frontend. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
64 lines
1.9 KiB
TypeScript
64 lines
1.9 KiB
TypeScript
// server/services/machineState.ts
|
|
import { randomUUID } from "node:crypto";
|
|
import { db, schema } from "../db/client.js";
|
|
import type { UpdateSnapshot } from "@shared/types.js";
|
|
|
|
export interface AptDerivedState {
|
|
status: string;
|
|
aptStatus: string;
|
|
aptUpdatesCount: number;
|
|
aptRebootRequired: number;
|
|
aptLastAnalyzeAt: string;
|
|
}
|
|
|
|
/** Dérive le bloc APT de l'état courant depuis un snapshot (fonction pure). */
|
|
export function deriveAptState(snapshot: UpdateSnapshot): AptDerivedState {
|
|
return {
|
|
status: snapshot.status,
|
|
aptStatus: snapshot.status,
|
|
aptUpdatesCount: snapshot.apt.count,
|
|
aptRebootRequired: snapshot.apt.rebootRequired ? 1 : 0,
|
|
aptLastAnalyzeAt: snapshot.checkedAt,
|
|
};
|
|
}
|
|
|
|
type MachineStateInsert = typeof schema.machineState.$inferInsert;
|
|
|
|
/** Insère ou met à jour les champs fournis de machine_state pour une machine. */
|
|
export function upsertMachineState(
|
|
machineId: string,
|
|
fields: Partial<Omit<MachineStateInsert, "machineId" | "updatedAt" | "status">> & { status: string },
|
|
): void {
|
|
const now = new Date().toISOString();
|
|
db.insert(schema.machineState)
|
|
.values({ machineId, updatedAt: now, ...fields })
|
|
.onConflictDoUpdate({
|
|
target: schema.machineState.machineId,
|
|
set: { ...fields, updatedAt: now },
|
|
})
|
|
.run();
|
|
}
|
|
|
|
/** Ajoute une ligne à la timeline machine_events. */
|
|
export function recordEvent(input: {
|
|
machineId: string;
|
|
eventType: string;
|
|
severity: "info" | "warning" | "error";
|
|
actorType?: string;
|
|
snapshotId?: string;
|
|
executionId?: string;
|
|
message?: string;
|
|
}): void {
|
|
db.insert(schema.machineEvents).values({
|
|
id: randomUUID(),
|
|
machineId: input.machineId,
|
|
eventType: input.eventType,
|
|
severity: input.severity,
|
|
createdAt: new Date().toISOString(),
|
|
actorType: input.actorType ?? "system",
|
|
snapshotId: input.snapshotId,
|
|
executionId: input.executionId,
|
|
message: input.message,
|
|
}).run();
|
|
}
|