import "./env"; import { dbGlobal } from "./lib/db"; import { categories, tags, items, itemTags } from "./lib/schema/collection"; import { users } from "./lib/schema/auth"; import { hash } from "bcryptjs"; async function main() { // Create demo user if not exists const [demoUser] = await dbGlobal .insert(users) .values({ username: "demo", password: await hash("demo1234", 12), nickname: "陈", role: "user", }) .onConflictDoNothing() .returning({ id: users.id }); const userId = demoUser?.id; if (!userId) { console.log("Demo user already exists, skipping seed."); // process.exit(0); } // Create categories const catDesign = await dbGlobal .insert(categories) .values({ name: "设计", icon: "🎨", color: "#c8a97e" }) .returning() .then((r) => r[0]); const catUI = await dbGlobal .insert(categories) .values({ name: "UI / 交互", icon: "🖥️", color: "#5db8a0", parentId: catDesign.id, sortOrder: 1 }) .returning() .then((r) => r[0]); const catFont = await dbGlobal .insert(categories) .values({ name: "字体排版", icon: "🔤", color: "#9d88d4", parentId: catDesign.id, sortOrder: 2 }) .returning() .then((r) => r[0]); const catAI = await dbGlobal .insert(categories) .values({ name: "AI / 技术", icon: "🤖", color: "#6da4d4" }) .returning() .then((r) => r[0]); const catRead = await dbGlobal .insert(categories) .values({ name: "阅读 / 思考", icon: "📚", color: "#d46d6d" }) .returning() .then((r) => r[0]); // Create tags const tagNames = ["值得深读", "灵感", "参考资料", "AI工具", "设计"]; const tagMap: Record = {}; for (const name of tagNames) { const [tag] = await dbGlobal .insert(tags) .values({ name, color: name === "灵感" ? "#9d88d4" : name === "AI工具" ? "#6da4d4" : name === "设计" ? "#5db8a0" : "#c8a97e" }) .returning(); tagMap[name] = tag.id; } // Demo items from prototype const demoItems = [ { type: "web" as const, title: "Vercel 设计系统 2024 更新:新组件库与动效规范", description: "Vercel 团队分享了最新的设计系统更新,包括全新的 Radix 组件封装、Motion 动效库集成和无障碍规范改进。", url: "https://vercel.com/design", sourceHost: "vercel.com", tagNames: ["设计", "参考资料"], starred: true, rating: 4, note: "重点关注他们的 Motion 实现方案,和我们的项目需求很贴近。", aiSummary: "文章详细介绍了 Vercel 如何重构其设计系统,核心思路是「组件即文档」——每个组件自带使用示例和无障碍说明。动效方面引入了基于物理的弹簧动画替代传统缓动曲线。", categoryId: catDesign.id, }, { type: "text" as const, title: "关于「慢阅读」的思考碎片", description: "在信息爆炸时代,我们需要主动降速。真正的理解需要摩擦感,需要反复咀嚼,需要停下来想一想。", sourceHost: "个人笔记", tagNames: ["灵感", "值得深读"], rating: 5, note: "这段话在地铁上想到的,和最近读《深度工作》有关。", aiSummary: "这段文字探讨了现代人与信息的关系——我们消费的速度远超消化的速度。提出「慢阅读」作为一种对抗信息焦虑的实践方法。", categoryId: catRead.id, }, { type: "web" as const, title: "2024 年最值得关注的 AI 设计工具合集", description: "涵盖 Galileo AI、Uizard、Framer AI 等 14 款工具的深度对比,从生成质量、可控性、工作流融合三个维度评分。", url: "https://uxdesign.cc/ai-design-tools", sourceHost: "uxdesign.cc", tagNames: ["AI工具", "设计"], starred: true, rating: 4, aiSummary: "文章系统比较了当前主流 AI 设计工具,结论是 Framer AI 在工作流融合上领先,但 Galileo AI 的生成质量更高。建议根据团队使用场景分开选择。", categoryId: catAI.id, }, { type: "image" as const, title: "Teenage Engineering OP-1 产品摄影参考", description: "极简主义硬件产品的摄影风格:高对比、单色背景、精准的光影层次,彰显工业美学。", sourceHost: "Dribbble", tagNames: ["灵感", "设计"], rating: 3, note: "下次产品拍摄可以参考这种风格。", aiSummary: "这组产品摄影展示了如何用极简布景突出产品本身的设计语言——没有任何多余道具,只有主体、光线和阴影的对话。", categoryId: catDesign.id, }, { type: "video" as const, title: "3Blue1Brown: 神经网络的可视化解释", description: "通过动态几何可视化,直觉上理解反向传播、梯度下降和神经元激活的工作原理,无需数学公式。", url: "https://youtube.com/watch?v=aircAruvnKk", sourceHost: "YouTube", tagNames: ["AI工具", "参考资料", "值得深读"], starred: true, rating: 5, note: "最好的 ML 入门视频,没有之一。准备在团队分享会上播放。", aiSummary: "Grant 用其标志性的数学可视化风格,将反向传播从一个抽象算法变成可以「看到」的几何变换过程,极大降低了理解门槛。", categoryId: catAI.id, }, { type: "doc" as const, title: "《设计系统:企业级 UI 的构建法则》PDF", description: "Nathan Curtis 的经典著作,详述如何从零搭建可维护的设计系统,包含 Figma 组织规范和开发交接流程。", sourceHost: "PDF 文档", tagNames: ["设计", "参考资料"], rating: 4, note: "第三章关于 Token 体系的部分要精读,跟我们的需求高度相关。", aiSummary: "本书是目前最系统的设计系统建设指南,核心观点:设计系统不是组件库,而是一套治理语言和协作流程。", }, { type: "web" as const, title: "Raycast 如何在产品增长上做了哪些正确的事", description: "从 0 到 100 万用户的增长路径复盘:产品主导增长、开发者社区、插件生态三大飞轮如何协同运转。", url: "https://raycast.com/blog", sourceHost: "raycast.com", tagNames: ["灵感", "值得深读"], rating: 3, aiSummary: "Raycast 的增长故事印证了「产品即渠道」的理念——当工具足够好用,用户自然成为传播者。插件生态是其最聪明的护城河策略。", categoryId: catRead.id, }, { type: "text" as const, title: "设计师应该学代码吗?我的答案变了三次", description: "从「完全没必要」到「会一点很好」再到「这个问题本身就是错的」——真正的边界在于理解,而不在于实现。", sourceHost: "个人笔记", tagNames: ["灵感", "设计"], starred: true, rating: 4, note: "这是我要写的下一篇文章的核心论点。", aiSummary: "作者认为「设计师要不要学代码」这个问题预设了一个错误的二元对立。更好的问题是:如何建立跨越学科的理解力?", categoryId: catDesign.id, }, ]; for (const d of demoItems) { const [item] = await dbGlobal .insert(items) .values({ userId, type: d.type, title: d.title, description: d.description, url: d.url || null, sourceHost: d.sourceHost, categoryId: d.categoryId || null, note: d.note || null, rating: d.rating || null, starred: d.starred ?? false, aiSummary: d.aiSummary || null, }) .returning(); if (d.tagNames && item) { for (const tn of d.tagNames) { const tagId = tagMap[tn]; if (tagId) { await dbGlobal.insert(itemTags).values({ itemId: item.id, tagId }); } } } } console.log("Seed complete! Demo user: demo / demo1234"); process.exit(0); } main().catch((e) => { console.error(e); process.exit(1); });