/** * Registers org-admin HTTP surface: auth, org APIs, and the static SPA shell. */ import cookie from "@fastify/cookie"; import type { PrismaClient } from "@prisma/client"; import type { FastifyInstance } from "fastify"; import { registerAuthRoutes } from "./routes/authRoutes.js"; import { registerOrgRoutes } from "./routes/orgRoutes.js"; import { registerStaticSpa } from "./static.js"; import type { LocalSecretEnvelope } from "../security/secretEnvelope.js"; import type { ProviderReadinessProbe } from "../connections/providerReadiness.js"; import type { FeishuReadinessProbe } from "../connections/feishuReadiness.js"; export interface AdminPluginConfig { readonly prisma: PrismaClient; readonly sessionSecret: string; readonly publicBaseUrl: string; readonly feishuAppId: string; readonly feishuAppSecret: string; readonly projectWorkspaceRoot: string; readonly secretEnvelope: LocalSecretEnvelope; readonly providerReadinessProbe?: ProviderReadinessProbe; readonly feishuConnectionReadinessProbe?: FeishuReadinessProbe; readonly cookieSecure?: boolean; readonly oauthScope?: string; readonly fetchImpl?: typeof fetch; readonly allowLegacyFeishuOAuth?: boolean; } export async function registerAdminPlugin( app: FastifyInstance, config: AdminPluginConfig, ): Promise { await app.register(cookie); const cookieSecure = config.cookieSecure ?? config.publicBaseUrl.startsWith("https://"); await registerAuthRoutes(app, { prisma: config.prisma, sessionSecret: config.sessionSecret, publicBaseUrl: config.publicBaseUrl, feishuAppId: config.feishuAppId, feishuAppSecret: config.feishuAppSecret, secretEnvelope: config.secretEnvelope, cookieSecure, ...(config.oauthScope !== undefined ? { oauthScope: config.oauthScope } : {}), ...(config.fetchImpl !== undefined ? { fetchImpl: config.fetchImpl } : {}), ...(config.allowLegacyFeishuOAuth !== undefined ? { allowLegacyFeishuOAuth: config.allowLegacyFeishuOAuth } : {}), }); await registerOrgRoutes(app, { prisma: config.prisma, sessionSecret: config.sessionSecret, projectWorkspaceRoot: config.projectWorkspaceRoot, secretEnvelope: config.secretEnvelope, ...(config.providerReadinessProbe !== undefined ? { providerReadinessProbe: config.providerReadinessProbe } : {}), ...(config.feishuConnectionReadinessProbe !== undefined ? { feishuConnectionReadinessProbe: config.feishuConnectionReadinessProbe } : {}), }); // After API + /admin/login so SPA fallback does not shadow auth routes. await registerStaticSpa(app); }