描述
智栈MindStack是一款AI驱动的知识管理与项目协作平台。支持项目管理、任务看板、技术决策追踪、语义搜索、AI对话资产化、开发者画像分析等核心功能。
技术栈
创建时间
任务进度
技术决策
关联知识
状态
活跃自定义数据
{
"phase": "MVP开发",
"budget": "50万",
"version": "0.1.0",
"teamSize": 5,
"deployPlatform": "Vercel",
"developmentCycle": "3个月"
}Next.js 增量构建缓存失效与 .next 目录清理方案
## 问题描述 修改代码或添加新依赖后,开发服务器出现模块解析错误: ``` Error: Cannot find module './vendor-chunks/lucide-react.js' ``` ## 根本原因 Next.js 的增量构建缓存会在依赖变更后变得陈旧,导致模块引用失效。 ## 解决方案 清理 .next 缓存并重启服务器: ```powershell Remove-Item -Recurse -Force .next npm run dev ``` ## 预防措施 建议在 package.json 中添加脚本: ```json "scripts": { "dev:clean": "Remove-Item -Recurse -Force .next; npm run dev" } ```
PrismaClient 在 Client Component 中运行报错与 Server/Client 分离解决方案
## 问题描述 PrismaClient 无法在浏览器环境运行。当将页面组件改为 Client Component ("use client") 并直接使用 prisma 查询数据库时出现错误: ``` Error: PrismaClient is unable to run in this browser environment ``` ## 根本原因 PrismaClient 设计为仅在服务端执行,无法被打包到浏览器中运行。 ## 解决方案 采用 Server/Client Component 分离模式: 1. Server Component (page.tsx) 使用 Server Actions 获取数据 2. Client Component (Client.tsx) 负责状态管理和交互逻辑 3. 数据通过 props 从 Server 传递到 Client ## 关键代码示例 ```tsx // page.tsx - Server Component import { getProjectWithDetails } from "@/server/actions/project"; export default async function ProjectDetailPage({ params }) { const project = await getProjectWithDetails(params.id); return <ProjectDetailClient project={project} />; } // ProjectDetailClient.tsx - Client Component "use client"; export default function ProjectDetailClient({ project }) { const [tasks, setTasks] = useState(project.tasks); } ``` ## 注意事项 - 所有 Prisma 查询必须在 Server Actions 或 Server Component 中执行 - Client Component 只能通过 props 接收数据,不能直接访问数据库
Lucide React 图标库中不存在的图标名称与替代方案
## 问题描述 尝试导入 Test 图标时报错: ``` Error: Could not find icon Test in lucide-react ``` ## 根本原因 Test 图标在 Lucide React 中不存在。 ## 解决方案 1. 查阅 Lucide React 官方文档确认可用图标名称 2. 使用语义相近的图标替代:Terminal、Code、Bug 等 3. 保持图标名称与语义的一致性
React 父子组件状态同步的回调模式实现
## 问题描述 子组件(如 TaskBoard、TechDecisionPanel)更新了本地状态,但父组件(ProjectDetailClient)没有反映变化,导致 UI 不一致。 ## 根本原因 父组件通过 props 传递初始数据,但子组件使用 useState 管理自己的状态,子组件的状态变化不会自动传递回父组件。 ## 解决方案 实现回调式状态同步: 1. 父组件定义 onTasksUpdate/onDecisionsUpdate 回调函数 2. 通过 props 将回调传递给子组件 3. 子组件在状态变化时调用回调函数 4. 父组件收到回调后更新自己的状态 ## 关键代码示例 ```tsx // Parent const handleTasksUpdate = (updatedTasks) => { setTasks(updatedTasks); }; <TaskBoard tasks={tasks} onTasksUpdate={handleTasksUpdate} /> // Child const updateTasks = (newTasks) => { setTaskList(newTasks); onTasksUpdate?.(newTasks); }; ```
shadcn/ui 组件必须通过 CLI 安装而非手动创建
## 问题描述 手动创建 shadcn/ui 组件文件后,出现编译错误: ``` Module not found: Can't resolve '@radix-ui/react-slot' ``` 或 ``` Error: Missing required prop `asChild` ``` ## 根本原因 shadcn/ui 组件依赖特定版本的 radix-ui 基础组件和其他 peer dependencies,手动创建组件文件无法自动安装这些依赖。 ## 解决方案 始终通过 CLI 安装 shadcn/ui 组件: ```bash npx shadcn-ui@latest add <component-name> ``` 遇到依赖冲突时使用: ```bash npx shadcn-ui@latest add <component-name> --legacy-peer-deps # 或 npx shadcn-ui@latest add <component-name> --force ```
PostgreSQL 复合主键关联表的级联删除配置与验证
## 问题描述 ProjectKnowledge 是复合主键关联表,删除 Project 或 Knowledge 时,关联记录可能不会自动级联删除。 ## 根本原因 复合主键关联表需要为两个外键都配置级联删除。 ## 解决方案 1. 在 Prisma Schema 中为关联表的两个外键都配置 onDelete: Cascade 2. 验证实际删除行为,确保级联删除生效 3. 如果级联删除不生效,考虑使用触发器或手动删除 ## 关键代码示例 ```prisma model ProjectKnowledge { projectId String knowledgeId String project Project @relation(fields: [projectId], references: [id], onDelete: Cascade) knowledge Knowledge @relation(fields: [knowledgeId], references: [id], onDelete: Cascade) @@id([projectId, knowledgeId]) } ```
AIConfig 与 User 强关联时外键约束违规的排查与修复
## 问题描述 保存 AI Config 时报错: ``` Foreign key constraint failed on the field: `ai_config_userId_fkey` ``` ## 根本原因 前端硬编码 userId: 'system',但数据库中不存在该用户。 ## 解决方案 1. 创建共享常量文件 src/constants/user.ts,定义 FIXED_USER_ID 2. 所有使用 userId 的地方统一引用此常量 3. 在 Server Action 中添加用户存在性验证 4. 确保数据库 seed 脚本创建正确的测试用户 ## 关键代码示例 ```typescript // src/constants/user.ts export const FIXED_USER_ID = "550e8400-e29b-41d4-a716-446655440000"; // src/server/actions/ai-config.ts const userExists = await prisma.user.findUnique({ where: { id: validated.userId }, }); if (!userExists) { throw new Error("用户不存在,请重新登录"); } ```
DeepSeek API Base URL 配置与路径拼接的正确方式
## 问题描述 初始迁移设置 apiBase 默认值为 'https://api.deepseek.com/v1',但 ai-service.ts 中又拼接了 '/chat/completions',导致最终请求 URL 为 'https://api.deepseek.com/v1/chat/completions',存在路径不一致风险。 ## 根本原因 配置与代码之间的路径约定不一致。 ## 解决方案 1. apiBase 应设置为基础 URL:'https://api.deepseek.com' 2. 在代码中统一拼接完整路径:${apiBase}/chat/completions 3. 保持配置与代码的一致性,避免重复路径
pgvector 语义搜索时 embedding 字段为 NULL 的过滤策略
## 问题描述 当 knowledge 记录的 embedding 字段为 NULL 时,执行向量相似度查询会返回错误或意外结果。 ## 根本原因 pgvector 的 <=> 运算符无法处理 NULL 值。 ## 解决方案 在 $queryRaw 中添加 embedding IS NOT NULL 条件过滤: ```sql SELECT *, 1 - (embedding <=> ${queryEmbedding}::vector) as similarity FROM "knowledge" WHERE embedding IS NOT NULL AND 1 - (embedding <=> ${queryEmbedding}::vector) >= ${threshold} ORDER BY embedding <=> ${queryEmbedding}::vector LIMIT ${limit} ```
Prisma Json 类型字段的正确序列化方式与潜在陷阱
## 问题描述 在 createProject 中对 techStack 和 customData 调用 JSON.stringify,但 Prisma 的 Json 类型本身支持直接接收对象,导致存储的数据可能被双重序列化。 ## 根本原因 Prisma 的 Json 类型会自动处理序列化,无需手动调用 JSON.stringify。 ## 解决方案 1. Prisma 的 Json 类型会自动处理序列化,无需手动调用 JSON.stringify 2. 直接传递 JavaScript 对象给 Json 字段 3. 对于可选字段,使用 undefined 而非 null 跳过存储
Prisma 不支持 pgvector 类型的解决方案与 $queryRaw 使用模式
## 问题描述 Prisma Schema 中无法直接使用 vector(1536) 类型: ``` Error: Error validating model "Project": Invalid type `vector(1536)` for field `embedding` ``` ## 根本原因 Prisma 官方尚未原生支持 pgvector 类型。 ## 解决方案 1. 在 generator client 中添加 previewFeatures = ["postgresqlExtensions"] 2. 在 datasource db 中声明 extensions = [vector] 3. 使用 Unsupported("vector(1536)") 声明向量字段类型 4. 通过 $queryRaw 执行向量查询,使用 <=> 运算符计算相似度 ## 关键代码示例 ```typescript // schema.prisma generator client { provider = "prisma-client-js" previewFeatures = ["postgresqlExtensions"] } datasource db { provider = "postgresql" url = env("DATABASE_URL") extensions = [vector] } model Knowledge { embedding Unsupported("vector(1536)")? } ```
原生 HTML5 Drag-and-Drop 与 @dnd-kit 库对比及迁移方案
## 问题描述 原生 HTML5 拖拽存在以下问题: - 首次拖拽仅选中项目(显示缩放效果)但不移动 - 需要拖拽两次才能实际移动项目 - 鼠标悬停在交互元素上时显示禁止符号 ## 根本原因 原生 HTML5 拖拽 API 设计于 2000 年代,对现代 Web 应用的复杂交互支持不佳,特别是与嵌套交互元素共存时会出现冲突。 ## 解决方案 使用 @dnd-kit 库替代原生 HTML5 拖拽: 1. 安装依赖:npm install @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities 2. 使用 PointerSensor 配合 activationConstraint: { distance: 8 } 防止误触 3. 使用 useDroppable 包装列,支持向空列拖拽 4. 使用 closestCorners 碰撞检测算法
任务看板
项目资产全景展示页面开发
统计图表可视化、响应式布局、数据看板交互
完整测试套件执行
Jest 全量测试、Playwright 端到端测试、测试覆盖率达标
AI 对话资产化转换页面开发
对话输入界面、实时转换预览、资产化历史记录展示、QA/TIP/BRIEF 分类查看
性能优化与最终测试
API 响应时间优化、前端页面加载速度优化、测试覆盖率提升至 80%
项目资产大盘页面开发
DashboardCharts.tsx、Recharts 图表集成、项目统计可视化、任务进度展示、技术决策分布
配置 TailwindCSS 3 样式框架
tailwind.config.js 配置、postcss.config.js、globals.css 基础样式注入
项目 CRUD API 开发
Server Actions 模式、createProject/updateProject/deleteProject/getProjectById/getProjectWithDetails、customData JSONB 序列化处理
创建项目-知识关联表(ProjectKnowledge)
复合主键设计、Cascade 删除策略
开发者画像 API 开发
syncTechPreferencesFromProjects/analyzeTechPreferences/generateDeveloperCard/getDeveloperProfile、技术频率统计、level 自动计算
任务 CRUD API 开发
TaskSchema Zod 验证、createTask/updateTask/deleteTask/changeTaskStatus、TaskLog 自动记录状态变更
设计用户体系表(User)
UUID 主键设计、唯一索引 email、预留 password/provider 字段支持多认证方式
知识详情页面开发
KnowledgeDetailClient 状态管理、编辑模式集成、关联项目展示
技术决策 CRUD API 开发
TechDecisionSchema Zod 验证、createTechDecision/updateTechDecision/deleteTechDecision/changeDebtStatus、relatedContext JSON 处理
创建初始测试数据
seed.ts 脚本编写、用户/项目数据初始化、Prisma Client 事务处理
配置 Prisma ORM 与 PostgreSQL 16 连接
Prisma 初始化、schema.prisma 配置、DATABASE_URL 环境变量、pgvector 扩展声明
高级搜索 API 开发
advancedSearch 实现、keyword/semantic/hybrid 模式切换、搜索结果合并去重
语义搜索 API 开发
semanticSearch 实现、generateEmbedding 向量生成、$queryRaw 原生查询、pgvector <=> 运算符、similarity 计算
项目详情页面开发
Server + Client 分离模式、ProjectDetailClient 状态管理、任务看板集成、技术决策面板集成
配置 pgvector 插件并添加 embedding 字段
CREATE EXTENSION "vector"、Prisma previewFeatures postgresqlExtensions、Unsupported("vector(1536)") 类型声明
创建基础目录结构和工具函数
src/lib/utils.ts、cn 函数封装 (clsx + tailwind-merge)、src/server/db.ts PrismaClient 初始化
项目资产大盘统计 API 开发
getProjectStatistics/getTaskProgress/getTechDecisionStats、多表聚合查询、Promise.all 并行执行
能力提升建议 API 开发
getImprovementSuggestions/analyzeDeveloperHabits、初级→中级→高级升级建议、学习资源推荐
知识库 CRUD API 开发
KnowledgeSchema Zod 验证、createKnowledge/updateKnowledge/deleteKnowledge、tags JSONB 序列化
任务看板组件开发
TaskBoard.tsx、@dnd-kit/core 拖拽、PointerSensor 配置、closestCorners 碰撞检测、useDroppable 空列支持
执行数据库迁移
npx prisma migrate dev、migration.sql 生成验证、pgvector 扩展激活确认
搜索选择组件开发
search-select.tsx、异步搜索、已关联项自动排除、多选支持
AI 配置页面开发
ai-config/page.tsx、API Key 输入、模型选择、参数滑块、测试/保存按钮
知识库首页开发
KnowledgeList 组件、知识卡片展示、搜索筛选、标签过滤
标签输入组件开发
tag-input.tsx、Backspace 删除、Enter/Comma 添加、Tag 渲染
项目管理单元测试
project.test.ts、任务管理单元测试 task.test.ts、技术决策单元测试 techDecision.test.ts、知识库单元测试 knowledge.test.ts
组件单元测试
ProjectList.test.tsx、KnowledgeList.test.tsx、TaskBoard.test.tsx
关键词搜索 API 开发
searchKnowledge 实现、title/content 模糊匹配、insensitive 模式、OR 条件组合
项目列表页面开发
Server Component page.tsx、搜索过滤、点击排序、分页支持、项目卡片展示
资产化单元测试
assetization.test.ts、仪表盘单元测试 dashboard.test.ts、画像单元测试 profile.test.ts、溯源单元测试 trace.test.ts
开发通用布局组件(Layout)
Server Component 模式、MainContent + Sidebar 组合、meta 标签配置
双向溯源 API 开发
getKnowledgeByProject/getProjectsByKnowledge/associateProjectKnowledge/disassociateProjectKnowledge、重复关联检查、批量操作支持
开发者画像页面开发
profile/page.tsx、技术雷达展示、能力提升建议、开发者名片生成
开发侧边栏菜单组件(Sidebar)
路由链接配置、活动状态高亮、移动端折叠逻辑
设计开发者画像相关表(DeveloperProfile、TechPreference、AnalysisResult)
1:N 关系设计、TechPreference level/frequency 字段、AnalysisResult result JSONB 存储分析结果
开发顶部导航栏组件(Header)
shadcn/ui Button、Lucide React 图标集成、响应式布局
AI 对话资产化转换 API 开发
transformAsset 实现、conversation/knowledge 模式、summarizeConversation/analyzeConversationSkill/summarizeKnowledge AI 调用、自动生成 Knowledge 记录
实现模拟用户登录机制
Phase 1 匿名访问模式、FIXED_USER_ID 常量、环境变量配置
设计项目管理相关表(Project、Task、TaskLog、TechDecision)
Project 表 customData JSONB、Task 表 status/priority 枚举字段、TaskLog 状态变更记录、TechDecision 技术债追踪
AI 配置 API 开发
saveAIConfig/getAIConfig/testAIConfig、userId 验证、upsert 操作、API 测试连接
集成 shadcn/ui 无头 UI 组件库
npx shadcn-ui@latest init、@tailwindcss/vite 插件、Dark Mode 配置
AI 服务层开发
callAI 函数、API Base URL 拼接、消息格式构建、错误处理、token usage 记录
设计知识库相关表(Knowledge、KnowledgeAsset)
Knowledge 表 embedding vector(1536)、KnowledgeAsset 表 assetType 枚举(QA/TIP/BRIEF)、data JSONB 结构化存储
初始化 Next.js 14 项目
Node.js 环境配置、npm create next-app、TypeScript 模板选择、App Router 模式
技术决策
添加 outputTokens 独立配置项
中影响初始设计中 maxTokens 同时控制输入和输出,实际使用中发现需要分开控制,新增 outputTokens 字段
修复 AIConfig apiBase 默认值不一致问题
高影响初始迁移设置 apiBase 默认值为 'https://api.deepseek.com/v1',但 ai-service.ts 中又拼接了 '/chat/completions',导致 URL 重复,后续迁移修正为 'https://api.deepseek.com'
采用 Prisma Unsupported 类型声明 vector 字段
高影响Prisma 官方尚未原生支持 pgvector 类型,需要使用 Unsupported("vector(1536)") 绕过类型检查,通过 $queryRaw 执行向量查询
采用 Next.js App Router 架构
严重影响项目初始化阶段评估了 Pages Router 和 App Router,考虑到 Next.js 14 的新特性和服务端组件优势,选择 App Router
采用 JSONB 存储用户自定义项目字段
高影响项目需要支持用户自定义字段,但数量和类型不确定,JSONB 提供了灵活的动态字段存储方案
分离 Server Component 和 Client Component
严重影响最初尝试在 Client Component 中直接使用 PrismaClient,导致运行时报错,改为 Server Component 负责数据获取,Client Component 负责交互
采用统一 KnowledgeAsset 表替代独立 QA/TIP/BRIEF 表
高影响架构文档最初设计了 QuestionAnswer、SkillTip、KnowledgeBrief 三个独立表,实际实现时合并为单一 KnowledgeAsset 表,通过 assetType 字段区分类型,简化查询逻辑
采用 Server Actions 替代 API Routes
严重影响对比 RESTful API Routes 和 Server Actions 两种方案,Server Actions 更符合 Next.js App Router 架构,简化数据操作流程
模拟用户认证需要升级为完整认证体系
严重影响当前使用 FIXED_USER_ID 模拟认证,Phase 2 需要集成 NextAuth.js 支持 Credentials 和 OAuth2
将 pgvector 向量搜索引入 PostgreSQL
高影响知识库需要支持语义搜索,pgvector 是 PostgreSQL 的原生向量扩展,性能优于外部向量数据库
语义搜索 API 存在代码重复
中影响semanticSearch 函数中有 4 个相似的 $queryRaw 查询分支,仅 WHERE 条件不同,需要抽取公共逻辑
实现父子组件回调同步机制
中影响TaskBoard 和 TechDecisionPanel 组件的状态更新无法同步到父组件 ProjectDetailClient,采用回调函数模式解决状态同步问题
更新 AIConfig 默认模型为 deepseek-v4-flash
中影响初始迁移使用 deepseek-chat,后续发现 deepseek-v4-flash 是更优的选择,更新默认值并同步到前端
ProjectKnowledge 级联删除可能失效
中影响复合主键关联表在某些 PostgreSQL 版本下级联删除行为不一致,需要验证实际删除行为
真实 Embedding API 未实现
高影响generateRealEmbedding 函数抛出未实现错误,当前使用 generateMockEmbedding,需要接入真实的 embedding 服务
缺少输入输出 Token 使用量监控
中影响AIConfig 存储了配置参数,但缺少实际使用量的监控和统计
知识库搜索结果缺少高亮显示
低影响搜索 API 返回匹配结果,但未对匹配关键词进行高亮标记
选择 DeepSeek API 而非 OpenAI
高影响DeepSeek 提供更具性价比的中文模型和更高的 Token 限制,但生态不如 OpenAI 成熟
选择 @dnd-kit 而非 react-beautiful-dnd
中影响react-beautiful-dnd 已停止维护,@dnd-kit 更活跃且 API 设计更现代,但学习曲线较陡
选择 Prisma ORM 而非 TypeORM
严重影响对比了 Prisma 和 TypeORM,Prisma 的类型安全和自动生成的 Client 更适合快速开发,但 pgvector 支持不够完善需要 workaround
选择 Zod 而非 Yup 进行表单验证
中影响Zod 提供更好的 TypeScript 集成和类型推断,但 Yup API 更简洁。考虑到项目使用 TypeScript 严格模式,选择 Zod
JSONB 字段存在双重序列化风险
高影响createProject 和 updateProject 中对 techStack/customData 调用 JSON.stringify,而 Prisma Json 类型本身支持直接接收对象,存在重复序列化风险
选择 Server Actions 而非 tRPC
中影响tRPC 提供更完整的类型安全和自动 API 文档,但 Server Actions 更轻量且原生集成 Next.js,学习成本更低
添加自定义 Prompt 配置字段
中影响初始设计使用硬编码 Prompt,后续需要支持用户自定义 Prompt,添加 conversationPrompt/skillPrompt/knowledgePrompt 三个字段
选择 JSONB 存储 tags 而非独立关联表
中影响考虑了两种方案:独立 tags 表 + 关联表 vs JSONB 数组。选择 JSONB 是因为标签操作频率低且查询简单,但牺牲了多标签组合查询的性能
改用 @dnd-kit 替代原生 HTML5 拖拽
高影响原生 HTML5 拖拽在嵌套交互元素上表现不佳,首次拖拽仅选中不移动,改用 @dnd-kit 库实现流畅拖拽