mirror of
https://github.com/kennethnym/aris.git
synced 2026-03-23 02:21:17 +00:00
feat(backend): add admin API with provider config endpoint
Add /api/admin/* route group with admin role middleware and a PUT /api/admin/:sourceId/config endpoint for updating feed source provider config at runtime. Currently supports aelis.weather. Co-authored-by: Ona <no-reply@ona.com>
This commit is contained in:
88
apps/aelis-backend/src/admin/http.ts
Normal file
88
apps/aelis-backend/src/admin/http.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import type { Context, Hono } from "hono"
|
||||
|
||||
import { type } from "arktype"
|
||||
import { createMiddleware } from "hono/factory"
|
||||
|
||||
import type { AdminMiddleware } from "../auth/admin-middleware.ts"
|
||||
import type { Database } from "../db/index.ts"
|
||||
import type { UserSessionManager } from "../session/index.ts"
|
||||
|
||||
import { WeatherSourceProvider } from "../weather/provider.ts"
|
||||
|
||||
type Env = {
|
||||
Variables: {
|
||||
sessionManager: UserSessionManager
|
||||
db: Database
|
||||
}
|
||||
}
|
||||
|
||||
interface AdminHttpHandlersDeps {
|
||||
sessionManager: UserSessionManager
|
||||
adminMiddleware: AdminMiddleware
|
||||
db: Database
|
||||
}
|
||||
|
||||
export function registerAdminHttpHandlers(
|
||||
app: Hono,
|
||||
{ sessionManager, adminMiddleware, db }: AdminHttpHandlersDeps,
|
||||
) {
|
||||
const inject = createMiddleware<Env>(async (c, next) => {
|
||||
c.set("sessionManager", sessionManager)
|
||||
c.set("db", db)
|
||||
await next()
|
||||
})
|
||||
|
||||
app.put("/api/admin/:sourceId/config", inject, adminMiddleware, handleUpdateProviderConfig)
|
||||
}
|
||||
|
||||
const WeatherKitSourceProviderConfig = type({
|
||||
credentials: {
|
||||
privateKey: "string",
|
||||
keyId: "string",
|
||||
teamId: "string",
|
||||
serviceId: "string",
|
||||
},
|
||||
})
|
||||
|
||||
async function handleUpdateProviderConfig(c: Context<Env>) {
|
||||
const sourceId = c.req.param("sourceId")
|
||||
if (!sourceId) {
|
||||
return c.body(null, 404)
|
||||
}
|
||||
|
||||
const sessionManager = c.get("sessionManager")
|
||||
const db = c.get("db")
|
||||
|
||||
let body: unknown
|
||||
try {
|
||||
body = await c.req.json()
|
||||
} catch {
|
||||
return c.json({ error: "Invalid JSON" }, 400)
|
||||
}
|
||||
|
||||
switch (sourceId) {
|
||||
case "aelis.weather": {
|
||||
const parsed = WeatherKitSourceProviderConfig(body)
|
||||
if (parsed instanceof type.errors) {
|
||||
return c.json({ error: parsed.summary }, 400)
|
||||
}
|
||||
|
||||
const updated = new WeatherSourceProvider({
|
||||
db,
|
||||
credentials: parsed.credentials,
|
||||
})
|
||||
|
||||
try {
|
||||
await sessionManager.replaceProvider(updated)
|
||||
} catch (err) {
|
||||
console.error(`[admin] replaceProvider("${sourceId}") failed:`, err)
|
||||
return c.json({ error: "Failed to apply config" }, 500)
|
||||
}
|
||||
|
||||
return c.body(null, 204)
|
||||
}
|
||||
|
||||
default:
|
||||
return c.json({ error: `Provider "${sourceId}" not found` }, 404)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user