Files
ai-directory-platform/packages/core/scripts/setup-admin.ts
T
AI Directory Platform 4a1a034386 refactor: 主题系统 → monorepo 五个独立网站
- packages/core: @aidir/core 底座库(src/pages 页面组件体 1:1 镜像路由树 / kit 站点外壳工厂 / content/blog / scripts)
- sites/: 5 个独立 Next.js 网站(ai-stack / launchai / the-ai-ledger / devai-tools / findai)
  - 每站独立 package.json / next.config / tailwind / messages / .env / 构建
  - src/app 约 56 个薄路由文件(re-export 底座页面 + 内联路由段配置 revalidate/dynamic)
  - src/site/brand.tsx 站点配置 + src/site/home.tsx 站点首页(createMarketingLayout / createHomePage 工厂)
- generate-site.mjs: 站点生成器(新增网站 = SITES 加条目,零 Core 修改)
- start-all-sites.sh: 一键启动 3001-3005
- next-config.mjs: 底座统一 Next 配置工厂(next-intl + MDX + standalone)
- 五站共享同一套 PostgreSQL / Better Auth / Admin(设计文档 §42)
- 验证: 5 站 build OK / typecheck OK / 55 路由冒烟 200 / 品牌-内容-截图 差异确认 / 登录-投票-重复检测 e2e PASS
2026-09-08 19:19:33 +00:00

111 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env tsx
/**
* 管理员初始化脚本
* 用于设置第一个管理员账号
*
* 使用方法:
* 1. 设置环境变量 ADMIN_EMAIL
* 2. 运行: pnpm admin:setup
* 或直接运行: ADMIN_EMAIL=admin@example.com pnpm admin:setup
*/
import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import { eq } from "drizzle-orm";
import dotenv from "dotenv";
import { resolve } from "path";
import { pgTable, text, timestamp, boolean, integer } from "drizzle-orm/pg-core";
// 加载环境变量
dotenv.config({ path: resolve(process.cwd(), ".env.local") });
// 定义 user 表结构(复制自 schema)
const user = pgTable("user", {
id: text("id").primaryKey(),
name: text("name").notNull(),
email: text("email").notNull().unique(),
emailVerified: boolean("email_verified").default(false).notNull(),
image: text("image"),
credits: integer("credits").default(0).notNull(),
role: text("role").default("user").notNull(),
banned: boolean("banned").default(false).notNull(),
banReason: text("ban_reason"),
banExpires: timestamp("ban_expires"),
createdAt: timestamp("created_at").defaultNow().notNull(),
updatedAt: timestamp("updated_at")
.defaultNow()
.$onUpdate(() => new Date())
.notNull(),
});
async function setupAdmin() {
const adminEmail = process.env.ADMIN_EMAIL;
if (!adminEmail) {
console.error("❌ 请设置环境变量 ADMIN_EMAIL");
console.log("例如: ADMIN_EMAIL=admin@example.com pnpm admin:setup");
process.exit(1);
}
if (!process.env.DATABASE_URL) {
console.error("❌ 未找到 DATABASE_URL 环境变量");
console.log("请确保 .env.local 文件中设置了 DATABASE_URL");
process.exit(1);
}
// 创建数据库连接
const queryClient = postgres(process.env.DATABASE_URL);
const db = drizzle(queryClient);
try {
console.log("🔍 正在查找用户:", adminEmail);
// 检查用户是否存在
const existingUser = await db
.select()
.from(user)
.where(eq(user.email, adminEmail))
.limit(1);
if (existingUser.length === 0) {
console.error(`❌ 用户 ${adminEmail} 不存在`);
console.log("请先使用此邮箱注册一个账号,然后再运行此脚本");
await queryClient.end();
process.exit(1);
}
const currentUser = existingUser[0];
console.log(`✓ 找到用户: ${currentUser.name} (当前角色: ${currentUser.role})`);
if (currentUser.role === "admin") {
console.log(`✅ 用户 ${adminEmail} 已经是管理员`);
await queryClient.end();
process.exit(0);
}
// 更新用户为管理员
console.log("📝 正在更新用户角色...");
await db
.update(user)
.set({
role: "admin",
updatedAt: new Date()
})
.where(eq(user.email, adminEmail));
console.log(`✅ 成功将用户 ${adminEmail} 设置为管理员`);
console.log("🚀 现在你可以访问 /admin 路径来进入管理后台");
} catch (error) {
console.error("❌ 设置管理员失败:", error);
await queryClient.end();
process.exit(1);
}
// 关闭数据库连接
await queryClient.end();
process.exit(0);
}
// 运行脚本
setupAdmin();