Pressidian
花园入口
笔记
项目
关于
实验室
GitHub
花园入口
笔记
项目
关于
实验室
GitHub

KNOWLEDGE PATHS

笔记库
当前位置
笔记库/前端/项目笔记/代达罗斯

项目待做

3 分钟阅读 · Note

目录树 578 篇

          • 项目待做
          • 性能优化
          • UI设计
      • 前端技术栈
    • 笔记目录
    • CLAUDE.md
    • Vue 组件与 Render 函数

关联笔记 6

↗性能优化同一路径↗UI设计同一路径↗「Feature」Introduce Crate as an independent metadata entity[ˈentəti] | 引入 Crate 作为独立元数据实体共同主题↗表单数据获取&提交需要loading共同主题↗表单最佳实践指南共同主题↗不使用解构赋值共同主题
  • [x] 设计Archetype的页面

  • [ ] 全局的z-index token管理

  • [ ] 可以试试将服务转发出去用来填表

  • [x] 补充一些实用的skill

  • [x] 重构UI

  • [ ] ==去练习手动实现COD-88以及手动修正其中出现的bug==

  • [ ] schema化: ![Pasted image 20260709111050](../../../_assets/0838e5a-Pasted image 20260709111050.png)


第一条评论

  • 涉及文件: apps/app/src/pages/CratesPage/CrateDialog.tsx
  • 代码位置: 第 48-51 行附近。
  • 当前代码逻辑: 开发者正在使用 React 原生的 useState 钩子来管理表单的状态(const [form, setForm] = useState...)。
  • 审查意见: "Form should use react hook form"
    • 含义: 审查者建议不要直接使用 useState 来手动管理表单数据,而是应该引入并使用 react-hook-form 这个第三方库来处理表单。
    • 原因推测: react-hook-form 通常能提供更好的性能(减少不必要的重渲染)、更方便的验证机制以及更简洁的代码结构。

第二条评论

  • 涉及文件: packages/db-schema/src/tables/crates_table.ts
  • 代码位置: 第 3-6 行,定义了数据库表 crates 的结构。
  • 当前代码逻辑: 字段 type 被定义为普通的文本类型:type: text("type").notNull()。
  • 审查意见: "Enum it in the future"
    • 含义: 审查者指出,目前的 type 字段只是一个普通的文本字符串。他建议在未来将其改为“枚举”类型。
    • 原因推测: 如果 type 字段的值是固定的几种选项(例如:只有 "A", "B", "C" 三种类型),使用枚举可以限制数据的输入,防止出现拼写错误或不规范的数据,从而提高数据库的完整性。

总结

这位审查者主要在关注代码的最佳实践和数据结构的严谨性:

  1. 前端建议使用更专业的表单库 (react-hook-form)。
  2. 后端数据库设计建议未来优化字段类型(使用枚举)。

桶导出

循环导出

文档有关的

![Pasted image 20260626114108](../../../_assets/d0ffab3-Pasted image 20260626114108.png) 这不是无限套娃了

values: { id: crypto.randomUUID(), ...values }, ID 应该在数据库/服务层生成(Drizzle schema 的 defaultFn),而不是在 UI 组件中手动创建。这不仅打破了分层约定,而且绕过了一致性保证


apps\app\src\pages\CratesPage\CrateDialog.tsx

> Last Format Time:7/9/2026 23:46:20

好问题。CrateForm 本身完全可以用,但有一个小障碍——id。

看 第 67 行:

onCreate({ id: crypto.randomUUID(), ...payload })  // 多了 id

payload 的类型就是 CrateForm。如果 onCreate 声明为 (values: CrateForm) => void,TypeScript 会直接报错,因为 { id, ...CrateForm } 已经超出了 CrateForm 的范围。

正确的做法是两件事一起改:

  1. 把 id 的生成移到父组件(CratesPageContent.tsx),因为 dialog 本就不该负责生成 ID
  2. onCreate 和 onUpdate 都直接用 CrateForm
// CrateDialog.tsx — 类型收窄
interface CrateDialogProps {
  editing: Crate | null;
  onCreate: (values: CrateForm) => void;   // ✅ 精确类型
  onUpdate: (values: CrateForm) => void;   // ✅ 精确类型
  onClose: () => void;
}

// onSubmit 中移除 id 生成
const onSubmit = useCallback((values: CrateForm) => {
  const payload: CrateForm = {
    name: values.name.trim(),
    type: values.type,
    responsibility: values.responsibility.trim(),
    metadata: values.metadata?.trim() || undefined,
  };
  if (isEdit) {
    onUpdate(payload);
  } else {
    onCreate(payload);  // 不再加 id
  }
}, [isEdit, onCreate, onUpdate]);
// CratesPageContent.tsx — id 在这里生成
const handleCreate = useCallback(
  (values: Record<string, unknown>) => {
    createRecord({
      resource: ResourceName.crates,
      values: { id: crypto.randomUUID(), ...values },  // id 在这里加
    }, { onSuccess: () => setDialogOpen(false) });
  },
  [createRecord],
);

为什么 Record&lt;string, unknown&gt; 不好:

  • 丢失了所有类型安全——传错字段名、漏传必填字段都不会报错
  • 重构时编译器帮不了你
  • 跟项目"所有类型由 Zod infer 派生"的规范矛盾——明明有 CrateForm,却退化成了 Record&lt;string, unknown&gt;

你选中的 AiReviewsRulesPageContent.tsx:85 也是同样的问题——id 在 dialog 里生成,然后被迫用 Record&lt;string, unknown&gt; 来兜底。这是跨页面的共性问题,根源都是 id 生成放错了层级。

要我顺手把 CrateDialog 的这两个类型修掉吗?


Archetype 修正