feat: bootstrap commercial AI drama platform
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import { stat } from "node:fs/promises";
|
||||
import { dbPath } from "./db.mjs";
|
||||
import { backupSummary } from "./backup.mjs";
|
||||
|
||||
function envValue(name) {
|
||||
return String(process.env[name] || "").trim();
|
||||
}
|
||||
|
||||
function configuredCheck(key, label, envName, detail) {
|
||||
const value = envValue(envName);
|
||||
return {
|
||||
key,
|
||||
label,
|
||||
status: value ? "configured" : "not-configured",
|
||||
severity: value ? "info" : "warning",
|
||||
blocking: false,
|
||||
detail: value ? `${detail}:已读取 ${envName}` : `${detail}:未设置 ${envName}`,
|
||||
envName
|
||||
};
|
||||
}
|
||||
|
||||
async function databaseCheck() {
|
||||
try {
|
||||
const file = await stat(dbPath);
|
||||
return {
|
||||
key: "business-database",
|
||||
label: "业务数据库",
|
||||
status: "active-local",
|
||||
severity: "warning",
|
||||
blocking: false,
|
||||
provider: "Node 24 node:sqlite",
|
||||
detail: "当前业务真源是本地 SQLite;尚未切换 PostgreSQL 高可用运行时。",
|
||||
path: dbPath,
|
||||
bytes: Number(file.size || 0),
|
||||
modifiedAt: file.mtime?.toISOString?.() || null
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
key: "business-database",
|
||||
label: "业务数据库",
|
||||
status: "failed",
|
||||
severity: "critical",
|
||||
blocking: true,
|
||||
provider: "Node 24 node:sqlite",
|
||||
detail: `数据库文件不可读:${error.message}`,
|
||||
path: dbPath
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function systemReadiness() {
|
||||
const backups = await backupSummary();
|
||||
const allowDevContext = process.env.AI_DRAMA_ALLOW_DEV_CONTEXT === "1";
|
||||
const sessionSecret = envValue("AI_DRAMA_SESSION_SECRET");
|
||||
const mfaKey = envValue("AI_DRAMA_MFA_ENCRYPTION_KEY");
|
||||
const oidcKey = envValue("AI_DRAMA_OIDC_STORAGE_KEY");
|
||||
const checks = [
|
||||
await databaseCheck(),
|
||||
configuredCheck("postgres-target", "PostgreSQL 目标", "PLATFORM_POSTGRES_URL", "目标数据库连接"),
|
||||
configuredCheck("redis-target", "Redis 目标", "PLATFORM_REDIS_URL", "目标队列/分布式锁连接"),
|
||||
configuredCheck("object-storage-target", "对象存储目标", "PLATFORM_OBJECT_STORAGE_ENDPOINT", "S3-compatible 存储端点"),
|
||||
{
|
||||
key: "security-secrets",
|
||||
label: "生产密钥",
|
||||
status: sessionSecret.length >= 32 && mfaKey.length >= 16 && oidcKey.length >= 16 ? "ready" : "needs-config",
|
||||
severity: sessionSecret.length >= 32 && mfaKey.length >= 16 && oidcKey.length >= 16 ? "info" : "critical",
|
||||
blocking: sessionSecret.length < 32 || mfaKey.length < 16 || oidcKey.length < 16,
|
||||
detail: "Session、MFA 和 OIDC 存储密钥必须通过环境变量注入,不写入数据库。",
|
||||
configured: { sessionSecret: sessionSecret.length >= 32, mfaKey: mfaKey.length >= 16, oidcKey: oidcKey.length >= 16 }
|
||||
},
|
||||
{
|
||||
key: "dev-context",
|
||||
label: "开发上下文旁路",
|
||||
status: allowDevContext ? "unsafe" : "ready",
|
||||
severity: allowDevContext ? "critical" : "info",
|
||||
blocking: allowDevContext,
|
||||
detail: allowDevContext ? "AI_DRAMA_ALLOW_DEV_CONTEXT=1,生产部署禁止启用。" : "请求头上下文旁路已关闭,使用真实 session/API client。"
|
||||
},
|
||||
{
|
||||
key: "database-backup",
|
||||
label: "数据库快照",
|
||||
status: backups.count ? "ready" : "missing",
|
||||
severity: backups.count ? "info" : "warning",
|
||||
blocking: false,
|
||||
detail: backups.count ? `已有 ${backups.count} 个本地快照,最近一次 ${backups.latest?.modifiedAt || "未知"}。` : "还没有本地 SQLite 快照;上线前应先创建并验证备份。"
|
||||
}
|
||||
];
|
||||
const blocking = checks.filter((check) => check.blocking && !["ready", "configured"].includes(check.status)).length;
|
||||
const attention = checks.filter((check) => check.severity === "warning" || check.severity === "critical").length;
|
||||
return {
|
||||
profile: process.env.NODE_ENV === "production" ? "production" : "local-development",
|
||||
activeRuntime: { database: "node:sqlite", queue: "database-lease-worker", objectStorage: "local-filesystem" },
|
||||
summary: { status: blocking ? "blocked" : attention ? "attention" : "ready", blocking, attention, ready: checks.length - attention },
|
||||
checks,
|
||||
backups,
|
||||
checkedAt: new Date().toISOString()
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user