feat(hub): add /database admin surface with Feishu login

Adds a self-contained `/database/*` HTTP surface under hub/src/database:
- /database/admin: Feishu-only login page (Tailwind, light theme)
- /database/dashboard: session-gated sidebar + content shell
- /database/dev-login: DEV ONLY session bypass, double-gated by
  NODE_ENV != production AND HUB_DEV_LOGIN_BYPASS; never active in prod

hub.ts mounts the plugin after the admin plugin so the cookie parser and
/auth/feishu/* routes are available. The dev bypass logic is fully contained
in the database module; admin auth routes are untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-20 21:02:04 +08:00
parent 73cb0e5b47
commit df66691d24
5 changed files with 404 additions and 0 deletions
+9
View File
@@ -1,5 +1,6 @@
import Fastify from "fastify";
import { registerAdminPlugin } from "./admin/plugin.js";
import { registerDatabasePlugin } from "./database/plugin.js";
import { prisma } from "./db.js";
import { createLarkClient, startFeishuListenerWithClient } from "./feishu/client.js";
import { archiveFeishuBindingForLifecycleEvent } from "./feishu/bindingLifecycle.js";
@@ -143,6 +144,14 @@ export async function startHub(): Promise<void> {
secretEnvelope,
});
// `/database/*` surface. Registered after the admin plugin so the
// @fastify/cookie parser and /auth/* login routes are already available.
await registerDatabasePlugin(app, {
prisma,
sessionSecret,
siloOrganizationSlug: siloOrganization.slug,
});
const feishuListenerEnabled = booleanEnv("HUB_FEISHU_LISTENER_ENABLED", true);
if (feishuListenerEnabled) {
const feishuConfig = {