知识库

管理和搜索你的技术经验与知识

## 问题描述 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]) } ```

PostgreSQL
Foreign Key
Cascade Delete
+1
2026/7/15

## 问题描述 保存 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("用户不存在,请重新登录"); } ```

PostgreSQL
Foreign Key
Prisma
+2
2026/7/15

## 问题描述 子组件(如 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); }; ```

React
State Management
Callback Pattern
+1
2026/7/15

## 问题描述 手动创建 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 ```

shadcn/ui
CLI
Dependencies
+1
2026/7/15

## 问题描述 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)")? } ```

Prisma
pgvector
PostgreSQL
+1
2026/7/15

## 问题描述 修改代码或添加新依赖后,开发服务器出现模块解析错误: ``` 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" } ```

Next.js
Build Cache
Module Resolution
+1
2026/7/15

## 问题描述 尝试导入 Test 图标时报错: ``` Error: Could not find icon Test in lucide-react ``` ## 根本原因 Test 图标在 Lucide React 中不存在。 ## 解决方案 1. 查阅 Lucide React 官方文档确认可用图标名称 2. 使用语义相近的图标替代:Terminal、Code、Bug 等 3. 保持图标名称与语义的一致性

Lucide React
Icons
技巧
2026/7/15

## 问题描述 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 接收数据,不能直接访问数据库

Prisma
Next.js
Server Components
+2
2026/7/15

## 问题描述 当 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} ```

pgvector
Semantic Search
PostgreSQL
+1
2026/7/15

## 问题描述 在 createProject 中对 techStack 和 customData 调用 JSON.stringify,但 Prisma 的 Json 类型本身支持直接接收对象,导致存储的数据可能被双重序列化。 ## 根本原因 Prisma 的 Json 类型会自动处理序列化,无需手动调用 JSON.stringify。 ## 解决方案 1. Prisma 的 Json 类型会自动处理序列化,无需手动调用 JSON.stringify 2. 直接传递 JavaScript 对象给 Json 字段 3. 对于可选字段,使用 undefined 而非 null 跳过存储

Prisma
JSONB
Serialization
+1
2026/7/15

## 问题描述 初始迁移设置 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. 保持配置与代码的一致性,避免重复路径

DeepSeek
AI API
Configuration
+1
2026/7/15

## 问题描述 原生 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 碰撞检测算法

@dnd-kit
Drag and Drop
React
+1
2026/7/15