feat(opsserver): introduce OpsServer (TypedRequest API) and new lightweight web UI; replace legacy Angular UI and add typed interfaces

This commit is contained in:
2026-02-24 18:15:44 +00:00
parent 84c47cd7f5
commit ba05cc84fe
143 changed files with 46631 additions and 20632 deletions

View File

@@ -131,9 +131,9 @@ export class OneboxDaemon {
// Start monitoring loop
this.startMonitoring();
// Start HTTP server
// Start OpsServer (serves new UI + TypedRequest API)
const httpPort = parseInt(this.oneboxRef.database.getSetting('httpPort') || '3000', 10);
await this.oneboxRef.httpServer.start(httpPort);
await this.oneboxRef.opsServer.start(httpPort);
logger.success('Onebox daemon started');
logger.info(`Web UI available at http://localhost:${httpPort}`);
@@ -163,8 +163,8 @@ export class OneboxDaemon {
// Stop monitoring
this.stopMonitoring();
// Stop HTTP server
await this.oneboxRef.httpServer.stop();
// Stop OpsServer
await this.oneboxRef.opsServer.stop();
// Remove PID file
await this.removePidFile();
@@ -280,31 +280,12 @@ export class OneboxDaemon {
}
/**
* Broadcast stats to WebSocket clients (real-time updates)
* Broadcast stats (placeholder for future WebSocket integration via OpsServer)
*/
private async broadcastStats(): Promise<void> {
try {
const services = this.oneboxRef.services.listServices();
const runningServices = services.filter(s => s.status === 'running' && s.containerID);
logger.info(`Broadcasting stats for ${runningServices.length} running services`);
for (const service of runningServices) {
try {
const stats = await this.oneboxRef.docker.getContainerStats(service.containerID!);
if (stats) {
logger.info(`Broadcasting stats for ${service.name}: CPU=${stats.cpuPercent.toFixed(1)}%, Mem=${Math.round(stats.memoryUsed / 1024 / 1024)}MB`);
this.oneboxRef.httpServer.broadcastStatsUpdate(service.name, stats);
} else {
logger.warn(`No stats returned for ${service.name} (containerID: ${service.containerID})`);
}
} catch (error) {
logger.warn(`Stats collection failed for ${service.name}: ${getErrorMessage(error)}`);
}
}
} catch (error) {
logger.error(`Broadcast stats error: ${getErrorMessage(error)}`);
}
// Stats broadcasting via WebSocket is not yet implemented in OpsServer.
// Metrics are still collected and stored in the DB by collectMetrics().
// The new UI fetches stats via TypedRequests on demand.
}
/**