feat: add instance management to dashboard

This commit is contained in:
chick
2026-07-07 23:04:32 +08:00
parent 182bd19c95
commit 2505ee561a
7 changed files with 267 additions and 12 deletions
+46
View File
@@ -3,11 +3,15 @@ import fastifyStatic from '@fastify/static'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import {
addInstanceToConfig,
buildClients,
collectInstanceStatus,
createSimAdminClient,
deleteInstanceFromConfig,
loadConfig,
proxyToInstance,
redactInstance,
updateInstanceInConfig,
} from './core.js'
const __filename = fileURLToPath(import.meta.url)
@@ -29,6 +33,16 @@ function clientById(id, reply) {
return client
}
function sendConfigError(reply, error) {
const message = String(error?.message || error)
const status = /not found/.test(message) ? 404 : /duplicate|required|invalid|URL/.test(message) ? 400 : 500
return reply.code(status).send({ error: message })
}
function refreshClientFor(instance) {
clients.set(instance.id, createSimAdminClient(instance))
}
app.get('/api/config', async () => ({
configPath: config.configPath,
instances: config.instances.map(redactInstance),
@@ -43,6 +57,38 @@ app.get('/api/config', async () => ({
app.get('/api/instances', async () => ({ instances: config.instances.map(redactInstance) }))
app.post('/api/instances', async (request, reply) => {
try {
const instance = await addInstanceToConfig(config, request.body || {})
refreshClientFor(instance)
return { instance: redactInstance(instance), configPath: config.configPath }
} catch (error) {
return sendConfigError(reply, error)
}
})
app.put('/api/instances/:id', async (request, reply) => {
try {
const oldId = request.params.id
const instance = await updateInstanceInConfig(config, oldId, request.body || {})
if (instance.id !== oldId) clients.delete(oldId)
refreshClientFor(instance)
return { instance: redactInstance(instance), configPath: config.configPath }
} catch (error) {
return sendConfigError(reply, error)
}
})
app.delete('/api/instances/:id', async (request, reply) => {
try {
const removed = await deleteInstanceFromConfig(config, request.params.id)
clients.delete(removed.id)
return { removed: redactInstance(removed), configPath: config.configPath }
} catch (error) {
return sendConfigError(reply, error)
}
})
app.get('/api/status', async () => ({
instances: await Promise.all([...clients.values()].map(collectInstanceStatus)),
}))