import fs from 'node:fs/promises'; import path from 'node:path'; import type { ControlPlaneState } from '../../src/shared/contracts'; import { createDefaultState } from './config'; export class StateStore { constructor(private readonly statePath: string) {} async read(): Promise { await fs.mkdir(path.dirname(this.statePath), { recursive: true }); try { const raw = await fs.readFile(this.statePath, 'utf8'); const state = JSON.parse(raw) as ControlPlaneState; const migrated = migrateLegacyAdminServices(state); if (migrated !== state) { await this.write(migrated); } return migrated; } catch (error) { if ((error as NodeJS.ErrnoException).code !== 'ENOENT') { throw error; } const fallback = createDefaultState(); await this.write(fallback); return fallback; } } async write(state: ControlPlaneState): Promise { await fs.mkdir(path.dirname(this.statePath), { recursive: true }); await fs.writeFile(this.statePath, `${JSON.stringify(state, null, 2)}\n`, 'utf8'); } } function migrateLegacyAdminServices(state: ControlPlaneState): ControlPlaneState { const legacyServiceIds = new Set( state.system.services .filter((service) => (service as { command?: unknown }).command === 'admin') .map((service) => service.id), ); if (legacyServiceIds.size === 0) { return state; } return { ...state, service: { ...state.service, lastEvent: 'Legacy admin service removed from stored panel state', }, userRecords: state.userRecords.filter((user) => !legacyServiceIds.has(user.serviceId)), system: { ...state.system, services: state.system.services.filter((service) => !legacyServiceIds.has(service.id)), }, }; }