// shared/types.ts export type OsFamily = "debian" | "ubuntu" | "proxmox" | "raspbian" | "unknown"; export type MachineStatus = "unknown" | "ok" | "updates_available" | "error" | "running"; export type AptProxyMode = "direct" | "runtime" | "persistent"; export type ActionType = | "apt_full_upgrade" | "reboot" | "apt_update_analyze" | "apt_upgrade" | "apt_dist_upgrade" | "apt_autoremove" | "apt_clean" | "reboot_verified" | "docker_scan" | "docker_inspect_current" | "docker_pull_check" | "docker_compose_apply" | "docker_prune_images" | "docker_compose_down" | "apt_proxy_persistent" | "machine_probe" | "post_install"; export type ExecutionStatus = "ok" | "warning" | "error"; export type ApiClientScope = "read" | "operate" | "admin" | "debug"; export type MachineKind = | "physical" | "vm" | "proxmox_host" | "lxc" | "raspberry_pi" | "workstation" | "unknown"; export type SnapshotStatus = "ok" | "updates_available" | "warning" | "error"; export interface ServerCapabilities { app: "system_update"; apiVersion: "1"; generatedAt: string; features: { machines: boolean; machineSnapshots: boolean; actions: boolean; aptFullUpgrade: boolean; reboot: boolean; reports: boolean; terminalOutput: boolean; interactiveSsh: boolean; docker: boolean; postInstall: boolean; hermes: boolean; settings: boolean; scheduledJobs: boolean; authTokens: boolean; }; endpoints: { capabilities: string; systemStatus: string; systemMetrics: string; machines: string; machineSnapshot: string; machineRefresh: string; machineActions: string; machineExecutions: string; executionReport: string; terminalOutputWs: string; }; } export interface SystemStatus { app: "system_update"; version: string; apiVersion: "1"; serverTime: string; uptimeSeconds: number; } export interface SystemMetrics { collectedAt: string; process: { uptimeSeconds: number; rssMb: number; heapUsedMb: number; heapTotalMb: number; }; host: { loadAverage1m: number; loadAverage5m: number; loadAverage15m: number; totalMemoryMb: number; freeMemoryMb: number; }; } export interface AptPackage { name: string; currentVersion: string | null; targetVersion: string; origin: string | null; arch?: string; operation?: "upgrade" | "install" | "remove" | "hold"; severityHint?: "normal" | "security"; } export interface AptSnapshotDetail { enabled: boolean; count: number; rebootRequired: boolean; packages: AptPackage[]; status?: SnapshotStatus; upgradeCount?: number; distUpgradeCount?: number; installed?: AptPackage[]; removed?: AptPackage[]; held?: string[]; rebootPkgs?: string[]; } export interface DockerSnapshotService { serviceName: string; image: string; currentImageId?: string | null; currentDigest?: string | null; candidateImageId?: string | null; candidateDigest?: string | null; currentVersion?: string | null; candidateVersion?: string | null; sourceUrl?: string | null; status?: "up_to_date" | "updates_available" | "warning" | "error"; } export interface DockerSnapshotStack { name: string; workingDir: string; composeFiles: string[]; projectName?: string | null; status: "candidate" | "enabled" | "ignored" | "error"; detectedBy?: "root_scan" | "label" | "manual"; services: DockerSnapshotService[]; } export interface DockerSnapshot { enabled: boolean; installed: boolean; count: number; declaredRoots?: string[]; stacks: DockerSnapshotStack[]; status?: SnapshotStatus; } export interface SnapshotError { source: "apt" | "docker" | "post_install" | "ssh" | "system"; kind: string; severity: "info" | "warning" | "error"; message: string; remediation?: string; importantLines?: string[]; } export interface UpdateSnapshot { machineId: string; hostname: string; os: { family: OsFamily; version: string }; checkedAt: string; // ISO 8601 status: MachineStatus; apt: AptSnapshotDetail; schemaVersion?: number; kind?: "apt_update_analyze" | "docker_scan" | "reboot_check" | "combined"; machineKind?: MachineKind; docker?: DockerSnapshot; errors?: SnapshotError[]; rawHints?: { logImportantLines: string[] }; } export interface AptChange { name: string; arch?: string; fromVersion: string | null; toVersion: string | null; operation: "upgraded" | "installed" | "removed" | "unchanged"; origin?: string | null; } export interface AptExecutionResult { planned: AptPackage[]; applied: AptChange[]; installed: AptChange[]; removed: AptChange[]; held: string[]; errors?: SnapshotError[]; rebootRequiredAfterRun: boolean; } export interface DockerImageChange { stack: string; serviceName?: string; imageRef?: string; fromImageId?: string | null; toImageId?: string | null; fromDigest?: string | null; toDigest?: string | null; operation: "pulled" | "recreated" | "pruned"; dedupKey?: string; // empreinte fonctionnelle (mutualisation Hermes) } export interface DockerExecutionResult { pull?: { changes: DockerImageChange[]; errors?: SnapshotError[] }; up?: { recreated: string[]; running: string[]; exited: string[]; errors?: SnapshotError[] }; prune?: { imagesDeleted: string[]; bytesReclaimed: number; errors?: SnapshotError[] }; errors?: SnapshotError[]; } export interface RebootResult { beforeBootId: string | null; afterBootId: string | null; requestedAt: string; sshWentDownAt: string | null; sshCameBackAt: string | null; waitedSeconds: number; status: "ok" | "reboot_command_failed" | "ssh_never_went_down" | "machine_did_not_return" | "boot_id_unchanged" | "timeout"; lastRebootDurationSeconds?: number; nextRecommendedWaitSeconds?: number; errors?: SnapshotError[]; } export interface AptRepositoriesAnalysis { osFamily: OsFamily; components: string[]; repos: { uri: string; suite: string; components: string[] }[]; proxmox?: { enterprise: boolean; noSubscription: boolean }; warnings: { kind: string; message: string }[]; notes: string[]; } export interface MachineMetricsSimple { collectedAt: string; cpu: { load1: number | null; load5: number | null; cores: number | null }; memory: { totalBytes: number | null; usedBytes: number | null; availableBytes: number | null; usedPercent: number | null }; filesystems: { mount: string; fstype: string; sizeBytes: number; usedBytes: number; usedPercent: number }[]; warnings: string[]; } export interface PostInstallResult { profilesRun: string[]; variablesUsed: Record; filesModified: string[]; packagesInstalled: string[]; servicesEnabled: string[]; rebootsRequested: boolean; networkChange?: { oldEndpoint: string | null; newEndpoint: string | null; reconnectHost: string | null }; errors?: SnapshotError[]; } export interface ExecutionResult { executionId: string; machineId: string; startedAt: string; finishedAt: string; mode: "manual" | "scheduled" | "hermes_requested"; action: ActionType; status: ExecutionStatus; rebootRequiredAfterRun: boolean; importantLogLines: string[]; rawLogRef: string; reportRef: string; schemaVersion?: number; apt?: AptExecutionResult; docker?: DockerExecutionResult; reboot?: RebootResult; postInstall?: PostInstallResult; errors?: SnapshotError[]; } /** Vue machine renvoyée par l'API — NE CONTIENT JAMAIS de secret. */ export interface MachineView { id: string; name: string; hostname: string; port: number; osFamily: OsFamily; username: string; aptProxyMode: AptProxyMode; aptProxyUrl: string | null; status: MachineStatus; lastCheckedAt: string | null; // Ajouts SJ-7 (optionnels, rétro-compatibles) : machineKind?: MachineKind; virtualization?: string | null; } /** Client API local/Hermes — ne contient jamais le token brut. */ export interface ApiClientView { id: string; name: string; tokenPrefix: string; scopes: ApiClientScope[]; createdAt: string; lastUsedAt: string | null; revokedAt: string | null; } export interface CreatedApiClient { client: ApiClientView; token: string; }