Inställningssida med Spara & testa för Gemini/Jellyfin + statustester
All checks were successful
build-and-push / build (push) Successful in 12s
All checks were successful
build-and-push / build (push) Successful in 12s
- settings.json i /data (UI-värden har företräde framför env), hemligheter maskeras i GET (bara apiKeySet-flagga) - POST /api/settings/test kör live-test per tjänst: Gemini (nyckel+modell), Jellyfin (System/Info + användarlista för dropdown), Lidarr, Youtubarr (healthz + db-mount) - Inställningssida (kugghjulet): Spara & testa i samma steg per sektion, Jellyfin-användarväljare fylls från lyckat test - 6 nya tester, totalt 17 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01824ZrvG2mDYYrmwqypLNup
This commit is contained in:
@@ -9,6 +9,8 @@ import fastifyStatic from '@fastify/static'
|
||||
import { lidarrClient, LidarrError } from './lidarr.js'
|
||||
import { mbClient } from './musicbrainz.js'
|
||||
import { mapLidarrSearch } from './mapping.js'
|
||||
import { settingsStore } from './settings.js'
|
||||
import { makeTesters } from './testers.js'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
@@ -24,6 +26,8 @@ function passwordOk(given, expected) {
|
||||
export function buildApp(config, deps = {}) {
|
||||
const lidarr = deps.lidarr ?? lidarrClient(config)
|
||||
const mb = deps.musicbrainz ?? mbClient()
|
||||
const store = deps.store ?? settingsStore(config.dataDir ?? '/data')
|
||||
const testers = deps.testers ?? makeTesters({ config, store })
|
||||
const app = Fastify({ logger: true, trustProxy: true })
|
||||
|
||||
app.register(fastifyCookie)
|
||||
@@ -140,6 +144,43 @@ export function buildApp(config, deps = {}) {
|
||||
}
|
||||
})
|
||||
|
||||
app.get('/api/settings', async () => {
|
||||
const s = store.load()
|
||||
return {
|
||||
gemini: {
|
||||
apiKeySet: Boolean(s.gemini?.apiKey || config.gemini.apiKey),
|
||||
model: s.gemini?.model ?? config.gemini.model,
|
||||
},
|
||||
jellyfin: {
|
||||
url: s.jellyfin?.url ?? config.jellyfin.url,
|
||||
apiKeySet: Boolean(s.jellyfin?.apiKey || config.jellyfin.apiKey),
|
||||
userId: s.jellyfin?.userId ?? '',
|
||||
userName: s.jellyfin?.userName ?? '',
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
app.put('/api/settings', async (req) => {
|
||||
const body = req.body ?? {}
|
||||
// släpp bara igenom kända fält
|
||||
store.save({
|
||||
gemini: { apiKey: body.gemini?.apiKey, model: body.gemini?.model },
|
||||
jellyfin: {
|
||||
url: body.jellyfin?.url,
|
||||
apiKey: body.jellyfin?.apiKey,
|
||||
userId: body.jellyfin?.userId,
|
||||
userName: body.jellyfin?.userName,
|
||||
},
|
||||
})
|
||||
return { ok: true }
|
||||
})
|
||||
|
||||
app.post('/api/settings/test', async (req, reply) => {
|
||||
const service = req.body?.service
|
||||
if (!testers[service]) return reply.code(400).send({ error: 'okänd tjänst' })
|
||||
return testers[service]()
|
||||
})
|
||||
|
||||
// byggd frontend (finns bara i containern / efter npm run build)
|
||||
const publicDir = path.resolve(__dirname, '../public')
|
||||
if (existsSync(publicDir)) {
|
||||
|
||||
Reference in New Issue
Block a user