# Backend 踩坑记录 ## 2026-03-24 ### 1. site-content PUT 必须支持 upsert - 问题:原来 PUT 只做 update,key 不存在时静默失败 - 解决:检查 result.changes === 0 时执行 insert ### 2. 前台表单 API 必须写入 submissions 表 - 问题:contact/customize POST 写入 JSON 文件,但后台从 submissions DB 表读取,数据完全断开 - 解决:改为 db.insert(schema.submissions).values({ type, data: JSON.stringify(formData), ip }) - 保留:输入验证、IP 限流、飞书通知逻辑不变 ### 3. 数据迁移要覆盖所有 key - 问题:6 个前台数据 key(blog, faq, gallery, news, reviews, stories)没有导入 site_content 表 - 原因:原始 seed 脚本没有导入这些 key,只导入了 site_content 类的数据 - 解决:从 data/*.json 批量导入到 site_content 表 - 检查:迁移后对比 usePublicApi 中所有 key 与数据库实际 key,确保无遗漏 ### 4. pricing 数据不完整 - 问题:pricing.json 只有 products 数组,缺少 philosophy/included/excluded/intro/cta 字段,前台页面访问时 500 - 原因:原始 JSON 数据不完整,或这些字段在其他地方定义 - 解决:手动补全缺失字段到数据库 - 教训:数据导入后要逐页验证,不能假设 JSON 数据是完整的 ### 5. 产品数据归一化要同步前端 - 问题:后端把 itinerary 从字符串转为对象、faq 的 q/a 转为 question/answer,但前端模板还在用旧字段名 - 教训:数据格式变更必须后端+前端同步修改,不能只改一端 - 检查清单:改数据格式后,grep 所有使用该字段的前台页面,逐一确认适配 ### 6. Drizzle ORM 同步调用风格 - 项目使用 better-sqlite3(同步驱动),所有 DB 操作用 .run()/.all()/.get() - 不需要 await(除了 readBody/requireAdmin) - returning().all() 获取插入后的记录