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

KNOWLEDGE PATHS

笔记库
当前位置
笔记库/前端/项目笔记/代达罗斯/需求/COD-104

总结

4 分钟阅读 · Note

目录树 578 篇

              • 用于稳定描述代码结构的数据结构方案
              • 总结
            • 国际化
            • 需求整体流程
            • Linear
          • 项目待做
          • 性能优化
          • UI设计
      • 前端技术栈
    • 笔记目录
    • CLAUDE.md
    • Vue 组件与 Render 函数

关联笔记 6

↗用于稳定描述代码结构的数据结构方案同一路径↗「Feature」Introduce Crate as an independent metadata entity[ˈentəti] | 引入 Crate 作为独立元数据实体共同主题↗国际化共同主题↗实施计划:Archetype 管理 (COD-86)共同主题↗需求整体流程共同主题↗引入Archetype共同主题
  • 总结

总结

我现在用最直白、最直接、最不绕弯子的的话告诉你——调研的方案里没有一个能 npm install 直接用的。Daedalus 要解决的问题(AI 代码审查平台的代码结构元数据描述)本身就没人做过一模一样的

部分问题

> 👇下面是我个人总结的一些可能需要改进的方向

使用的统一的数据结构来描述各种概念

实体各自孤立建模,Crate、Archetype字段形态各异,无法用统一的查询接口遍历"Crate X 依赖哪些 Archetype"。我们需要提供一个基类去继承,如果有需要统一升级的能力,改基类就行可了。孤立建模无法用统一的关系来描述,每两个概念就需要一个关系来表示。

先写一个 TypeScript 层的"统一视图",让现有的 Crate/Archetype 表通过适配器看起来像同一个模型。不是一开始就改数据库 schema。


关系

Conditions

目前只有两种类型,text与archetype_ref,Archetype的Conditions归根结底是结构化的text

比如,我希望使用Archetype/Crate描述一个商品购买卡片,大概长这个样子: ![Pasted image 20260702212633](../../../../../_assets/be4ddcc-Pasted image 20260702212633.png)

商品购买卡片定义:

archetype: 组件设计最佳实践
archetype: 商品的定义
text: "卡片必须展示商品图片、名称、当前价格三个核心信息,缺一不可"
archetype:按钮
text: "卡片必须提供至少一个明确的购买操作入口(如「加入购物车」或「立即购买」按钮)"
text: "卡片必须能正确处理以下商品状态:正常售卖、已售罄、已下架、限时折扣中、即将开售"

组件设计最佳实践定义:

text: 组件有明确的单一职责
text: 组件被复用 2 次以上,或有明确的复用潜力
text: 支持 `asChild` 模式(使用 Radix Slot)
archetype: 桶导出

桶导出:

text: 每个目录有 index 文件:存在导出文件的目录必须有 `index.ts`
text: 桶导出文件中禁止使用 `export default`

按钮:

text: 能点击
text: ...

AI看到的:

// archetype 商品购买卡片
{
  archetype: {
    text: 组件有明确的单一职责
    text: 组件被复用 2 次以上,或有明确的复用潜力
    text: 支持 `asChild` 模式(使用 Radix Slot)
    archetype: {
      text: 每个目录有 index 文件:存在导出文件的目录必须有 `index.ts`
      text: 桶导出文件中禁止使用 `export default`
    }
  }
  archetype: {
    ...
  }
  text: "卡片必须展示商品图片、名称、当前价格三个核心信息,缺一不可"
  archetype:{
    text: 能点击
    text: ...
  }
  text: "卡片必须提供至少一个明确的购买操作入口(如「加入购物车」或「立即购买」按钮)"
  text: "卡片必须能正确处理以下商品状态:正常售卖、已售罄、已下架、限时折扣中、即将开售"
}

我们将这些内容交给AI后,AI 读到了 9 条文本,理解了,然后去读代码,输出审查结果。看起来很美好但是有几个问题:

  • 是否真的被复用 2 次以上
  • 目录中有没有index文件
  • 禁止使用 export default,到底使用了没
  • ...

系统自己无法验证任何东西,所有的能力都依托于AI去读text。审查结果需要可验证,约束需要部分可自动化。

所以我们要添加一些新的类型,比如路径,依赖方向,结构化约束,数量约束,联合约束

> 这里的话我想可以直接使用下面的Relation来表示

将关系作为一个实体单列出来并限制

除了已有的Archetype与其Conditions之间的关系,Crate之间,Archetype与Crate之间也存在关系,但他们之间的关系很难通过类似condition_dependencies 中仅存两外键的形式表示。缺少关系语义,是强依赖还是弱引用?为什么依赖?

/**
 * 关系类型——描述两个结构单元之间的语义连接
 *
 * 借鉴:
 * - ADL Connector 作为一等公民的设计
 * - Backstage 的 well-known relations
 * - Property Graph 的有类型有属性边
 */
export const RelationTypeSchema = z.enum([
  "dependsOn",       // 运行时/编译时依赖(A 需要 B 才能工作)
  "dependencyOf",    // dependsOn 的反向
  "partOf",          // A 是 B 的组成部分(A → B 读作"A 属于 B")
  "hasPart",         // partOf 的反向(B 包含 A)
  "implements",      // A 实现了 B 定义的接口/契约
  "implementedBy",   // implements 的反向
  "references",      // A 引用 B(非依赖性的弱引用)
  "referencedBy",    // references 的反向
  "conformsTo",      // A 遵循 B 的约束(Crate → Archetype 的关系)
  "conformsFrom",    // conformsTo 的反向
  "extends",         // A 扩展/继承 B
  "extendedBy",      // extends 的反向
  "replaces",        // A 替代 B(版本迁移)
  "replacedBy",      // replaces 的反向
]);

定义Archetype:

// ═══════════════════════════════════════════════════════════
// Archetype: ecommerce-purchase-card
// 定义"一个合格的商品购买卡片应该满足什么条件"
// ═══════════════════════════════════════════════════════════

const purchaseCardArchetype: StructureUnit = {
  // ── 基础标识 ──
  uid: "archetype:default/ecommerce-purchase-card",
  unitKind: "archetype",
  unitTypes: ["design-contract", "ui-pattern", "ecommerce"],
  displayName: "E-commerce Purchase Card",
  description: `商品购买卡片的设计范式。
一个合格的商品购买卡片必须:
- 展示商品的核心信息(图片、名称、价格)
- 提供明确的购买/加入购物车操作
- 对缺货、已下架等状态有对应的 UI 反馈
- 有独立的测试和 Storybook 文档`,
  level: "crate",

  // ── 边界:这个 Archetype 本身没有代码边界,
  //   但它定义了"符合它的 Crate 应该有什么边界" ──
  boundary: {
    exposes: [
      {
        name: "ProductPurchaseCard",
        interfaceKind: "component",
        filePath: "src/components/ProductPurchaseCard/ProductPurchaseCard.tsx",
        signature: `(props: ProductPurchaseCardProps) => React.JSX.Element`,
        stable: true,
      },
    ],
    encapsulations: [
      "src/components/ProductPurchaseCard/**",
    ],
    visibility: "public",
  },

  // ── 扩展属性:这个 Archetype 的额外元数据 ──
  properties: {
    // 适用范围
    applicableTo: ["component", "ui", "ecommerce"],
    // 标签
    tags: ["purchase", "card", "product", "ecommerce"],
    // 示例仓库(如果存在符合此 Archetype 的参考实现)
    referenceImplementation: "crate:default/product-purchase-card",
    // 所属领域
    domain: "ecommerce",
    // 版本
    version: "1.0.0",
    // 来源
    _source: "archetypes_table",
  },
};

Archetype的Conditions:

const purchaseCardConstraints: Constraint[] = [

  // ── 约束 1:文本约束 —— 说出这个 Archetype 的核心要求 ──
  {
    constraintType: "text",
    value: "卡片必须展示商品图片、名称、当前价格三个核心信息,缺一不可",
    severity: "error",
  },

  // ── 约束 2:文本约束 —— 交互行为要求 ──
  {
    constraintType: "text",
    value: "卡片必须提供至少一个明确的购买操作入口(如「加入购物车」或「立即购买」按钮)",
    severity: "error",
  },

  // ── 约束 3:文本约束 —— 状态覆盖要求 ──
  {
    constraintType: "text",
    value: "卡片必须能正确处理以下商品状态:正常售卖、已售罄、已下架、限时折扣中、即将开售",
    severity: "warning",
  },

  // ── 约束 4:引用约束 —— 同时必须遵循「组件设计最佳实践」Archetype ──
  {
    constraintType: "archetype_ref",
    archetypeUid: "archetype:default/component-design-best-practice",
    requirement: "must", // 强制依赖——不符合组件规范就不算合格的商品卡片
  },

  // ── 约束 5:文件路径约束 —— 必须有桶导出文件 ──
  {
    constraintType: "path_pattern",
    pattern: "src/components/ProductPurchaseCard/index.ts",
    modifier: "must_exist",
    recursive: false,
  },

  // ── 约束 6:文件路径约束 —— 禁止在 feature 外部直接引用卡片内部文件 ──
  {
    constraintType: "path_pattern",
    pattern: "src/features/*/components/*",
    modifier: "must_not_contain",
    contentPattern: "from.*ProductPurchaseCard/ProductPurchaseCard\\.tsx",
    recursive: false,
  },

  // ── 约束 7:依赖约束 —— 必须依赖商品数据类型定义 ──
  {
    constraintType: "dependency",
    direction: "depends_on",
    targetPattern: "**/types/product*",
    cardinality: "at_least_one",
    minStrength: "strong",
  },

  // ── 约束 8:依赖约束 —— 禁止直接依赖后端 SDK ──
  {
    constraintType: "dependency",
    direction: "not_depends_on",
    targetPattern: "**/api-client/**",
  },

  // ── 约束 9:结构化约束 —— 必须有 test 和 stories 文件 ──
  {
    constraintType: "structural",
    rule: "has_tests",
  },

  // ── 约束 10:结构化约束 ──
  {
    constraintType: "structural",
    rule: "has_stories",
  },

  // ── 约束 11:结构化约束 —— 必须使用命名导出 ──
  {
    constraintType: "structural",
    rule: "prefer_named_export",
  },

  // ── 约束 12:结构化约束 —— 不能有循环依赖 ──
  {
    constraintType: "structural",
    rule: "no_circular_deps",
  },

  // ── 约束 13:数量约束 —— 导出项数量范围 ──
  {
    constraintType: "quantity",
    target: "exports",
    operator: "between",
    value: 1,
    maxValue: 5,  // 最多导出 5 个符号(卡片组件 + 最多 4 个子类型)
  },

  // ── 约束 14:数量约束 —— 依赖数量控制 ──
  {
    constraintType: "quantity",
    target: "dependencies",
    operator: "lte",
    value: 8,  // 商品卡片不应过度依赖外部模块
  },
];

Crate定义:

// ═══════════════════════════════════════════════════════════
// Crate: ProductPurchaseCard
// 实际的代码组织单元——包含组件文件及其附属
// ═══════════════════════════════════════════════════════════

const productPurchaseCardCrate: StructureUnit = {
  // ── 基础标识 ──
  uid: "crate:default/product-purchase-card",
  unitKind: "crate",
  // ★ 多值类型标签——替代旧的固定枚举
  unitTypes: [
    "component",   // 它是 UI 组件
    "ui",          // 属于 UI 层
    "ecommerce",   // 属于电商领域
    "card",        // 是卡片类组件
  ],
  displayName: "ProductPurchaseCard",
  description: `商品购买卡片组件。

展示单个商品的关键购买信息(图片、名称、价格、库存状态),
并提供「加入购物车」和「立即购买」两个操作入口。

支持的商品状态:
- 正常售卖:显示价格和购买按钮
- 已售罄:灰色遮罩 + "已售罄"标签
- 已下架:淡化显示 + "已下架"提示
- 限时折扣:显示原价(划线)+ 折扣价 + 倒计时
- 即将开售:显示预告 + 开售倒计时`,

  // ── 层级定位 ──
  level: "crate",
  parentUid: "repository:default/my-ecommerce-app",

  // ── ★ 边界定义:这个 Crate 对外暴露什么、内部封装什么 ──
  boundary: {
    exposes: [
      {
        name: "ProductPurchaseCard",
        interfaceKind: "component",
        filePath: "src/components/ProductPurchaseCard/ProductPurchaseCard.tsx",
        signature:
          "(props: ProductPurchaseCardProps) => React.JSX.Element",
        stable: true,
        deprecated: false,
        docsUrl: "https://storybook.example.com/?path=/docs/product-purchase-card",
      },
      {
        name: "ProductPurchaseCardProps",
        interfaceKind: "type",
        filePath: "src/components/ProductPurchaseCard/ProductPurchaseCard.types.ts",
        signature: `{
  product: Product;
  onAddToCart: (productId: string, quantity: number) => void;
  onBuyNow: (productId: string) => void;
  variant?: "default" | "compact" | "hero";
  className?: string;
}`,
        stable: true,
      },
      {
        name: "ProductPurchaseCardSkeleton",
        interfaceKind: "component",
        filePath: "src/components/ProductPurchaseCard/ProductPurchaseCardSkeleton.tsx",
        signature: "() => React.JSX.Element",
        stable: true,
      },
    ],
    encapsulations: [
      "src/components/ProductPurchaseCard/**",
      "src/components/ProductPurchaseCard/__tests__/**",
      "src/components/ProductPurchaseCard/stories/**",
    ],
    // internal = 仅同一个 repository 内的代码可以导入
    visibility: "internal",
  },

  // ── 扩展属性 ──
  properties: {
    // 技术栈
    techStack: ["react", "typescript", "tailwindcss", "framer-motion"],
    // 关联的 Storybook 路径
    storybookPath: "/story/product-purchase-card--default",
    // 负责人
    owner: "ui-team",
    // 审查状态(飞轮指标)
    reviewStats: {
      lastReviewAt: "2026-07-01T10:00:00Z",
      findingsCount: 2,
      severity: "low",
    },
  },
};

Relation定义:

// ═══════════════════════════════════════════════════════════
// Relation 1: Crate 符合 Archetype
// "ProductPurchaseCard 这个 Crate 遵循了
//  ecommerce-purchase-card 这个 Archetype 的设计契约"
// ═══════════════════════════════════════════════════════════

const conformsRelation: Relation = {
  id: "rel-card-001",
  sourceUid: "crate:default/product-purchase-card",
  targetUid: "archetype:default/ecommerce-purchase-card",
  relationType: "conformsTo",
  properties: {
    strength: "strong",
    direction: "unidirectional",
    reason: "ProductPurchaseCard 是电商商品卡片的标准实现,必须满足所有卡片设计契约",
    phase: "compile",
    extra: {
      conformanceScore: 0.92,     // 一致性评分
      verifiedAt: "2026-07-01",   // 最近一次验证通过时间
      verifiedBy: "scan-run-42",  // 由哪次审查运行验证
    },
  },
};

// ── 依赖关系:卡片依赖商品类型定义 ──

const productTypeCrate: StructureUnit = {
  uid: "crate:default/product-types",
  unitKind: "crate",
  unitTypes: ["types", "domain-model"],
  displayName: "Product Types",
  description: "商品领域的数据类型定义,包括 Product、ProductStatus、Price 等",
  level: "crate",
  boundary: {
    exposes: [
      {
        name: "Product",
        interfaceKind: "type",
        filePath: "src/types/product.ts",
        signature: `{
  id: string;
  name: string;
  description: string;
  images: string[];
  price: Price;
  status: ProductStatus;
  stockQuantity: number;
  category: string;
}`,
      },
    ],
    encapsulations: ["src/types/product*.ts"],
    visibility: "public", // 类型定义应对全仓库公开
  },
};

const dependsOnProductTypes: Relation = {
  id: "rel-card-002",
  sourceUid: "crate:default/product-purchase-card",
  targetUid: "crate:default/product-types",
  relationType: "dependsOn",
  properties: {
    strength: "strong",
    direction: "unidirectional",
    reason: "ProductPurchaseCardProps 引用了 Product 类型,卡片渲染依赖于商品数据结构",
    phase: "compile",
  },
};

// ── 层级关系:Crate 属于某个 Repository ──

const repository: StructureUnit = {
  uid: "repository:default/my-ecommerce-app",
  unitKind: "repository",
  unitTypes: ["monorepo", "turborepo", "ecommerce"],
  displayName: "My E-commerce App",
  description: "电商前端应用——包含商品浏览、购物车、下单等完整购买链路",
  level: "repository",
  boundary: {
    exposes: [],
    encapsulations: [
      "src/**",
      "packages/**",
      "apps/**",
    ],
    visibility: "public",
  },
};

const partOfRepo: Relation = {
  id: "rel-card-003",
  sourceUid: "crate:default/product-purchase-card",
  targetUid: "repository:default/my-ecommerce-app",
  relationType: "partOf",
  properties: {
    strength: "strong",
    reason: "商品购买卡片是电商应用的 UI 组件之一",
  },
};

// ── 引用关系:Storybook 文档引用了该组件 ──

const storybookPage: StructureUnit = {
  uid: "page:default/my-ecommerce-app/storybook/product-card",
  unitKind: "page",
  unitTypes: ["documentation", "storybook"],
  displayName: "ProductPurchaseCard Stories",
  level: "page",
};

const referencedByStorybook: Relation = {
  id: "rel-card-004",
  sourceUid: "page:default/my-ecommerce-app/storybook/product-card",
  targetUid: "crate:default/product-purchase-card",
  relationType: "references",
  properties: {
    strength: "weak",
    reason: "Storybook 文档引用组件作为演示对象",
  },
};

Repository ←─partOf── ProductCard ──conformsTo──→ Archetype
                         │                            │
                         │ dependsOn             archetype_ref
                         ▼                            ↓
                    ProductTypes               ComponentDesignBP
                         ▲
                         │ references (Storybook)
                         │
                   StorybookPage

具有通用性

所有参考几乎都是,用户输入->数据实体->产出。 我们项目的过程其实是逆过程,产出->对照实体->输出问题。


用来表述的结构要AI友好

flat tree使用扁平的结构

flat tree 的核心好处:每个元素是一个独立的键值对,LLM 流式生成时不会因为少一个 } 导致整个 JSON 非法。这直接解决了 AI 生成嵌套 JSON 的"括号地狱"问题:

  // ❌ 嵌套 JSON(AI 流式生成时容易括号不闭合)
  { "type": "Card", "props": {...}, "children": [
    { "type": "Button", "props": {...}, "children": [
      { "type": "Icon", ... }
    ]}
  ]}

  // ✅ Flat tree + ID 引用(每个元素独立,ID 引用连接)
  {
    "root": "card-1",
    "elements": {
      "card-1": { "type": "Card", "props": {...}, "children": ["btn-1"] },
      "btn-1":  { "type": "Button", "props": {...}, "children": ["icon-1"] },
      "icon-1": { "type": "Icon", "props": {...}, "children": [] }
    }
  }

Zod Schema = 约束 + 运行时验证

要做好动态类型检验。json-render 的catalog.Validate()、wasp的tsc 类型检查-AI 输出后立即有反馈信号。没有验证层的AI生成是不可靠的。Structureunit 的zod schema应同时承担"给AI 看的 prompt"和"验证AI 输出的guard"双重角色。

表达式用 JSON DSL 而非 JS

{ "$state": "/form/hasError" }                    // 引用状态
{ "$cond": {...}, "$then": "home", "$else": "outline" }  // 条件

这些表达式是纯 JSON 值,不是代码字符串——AI 生成 JSON 远比生成"不会出 bug 的 JavaScript"可靠。

统一的数据结构

这点和上面的一样

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: my-service
spec:
  type: service
  owner: team-a
  lifecycle: production

不管你描述的是服务、数据库、API、团队还是文档,全部遵循 apiVersion + kind + metadata + spec 四段式。AI 不需要学习不同的格式——学会了 envelope,就能描述任何软件资产。

toPrompt() 机制

json-render 的杀手锏是 catalog.prompt()——一键把整个数据结构定义编译为 AI 可消费的 system prompt。Daedalus 的 StructureUnit + Relation + Constraint 模型如果真的落地,最核心的 AI 友好设计应该是:

// 定义一个archetype
const archetype = New Archetype({
	// init
})

const archetypePrompt = archetype.toPrompt()
// "这个结构单元是一个 React 组件。它必须满足:
//  1. 文件路径匹配 src/components/**/ComponentName.tsx
//  2. 必须有 .test.tsx 和 .stories.tsx 伴随文件
//  3. 只能从 @/ui 导入 UI 组件
//  4. ..."

这样 AI 审查代码时,不是收到一堆自由文本的 Condition,而是被一个结构化的、可验证的、由 Zod schema 约束的 Contract 所引导。这才是"AI 友好"的本质——数据结构的设计本身就是 AI 的 prompt。

有限词汇表

Backstage 的well-known relations、Structurizr的~20种元素、Wasp的固定spec声明类型——词汇表越小,AI 幻觉越少。Relation类型不要做成自由文本,要用discriminatorunion限定。

描述优于代码

所有方案的description 字段都不只是文档——它们是 AI prompt 的原材料。每个结构单元都应该有能让AI理解的语义描述。 Crate/Archetype 的description应该写得像给AI看的一样(目前已经是,但需保持)。


层级路径命名体系

借鉴三个来源:

  • Rust pub use:内部路径和公开路径可以不同
  • Backstage {kind}:{namespace}/{name}
  • Google AIP Resource Name 的层级路径

> 还有一个小问题,目前的rule,crate与archetype他们的UID都是在前端生成的,这个应该是后端去做的

UID 格式:  {kind}:{namespace}/{path}[/{sub-path}...]

部件说明:
  kind       = [a-z][a-z0-9_-]*        -- 结构单元种类
  namespace  = [a-z][a-z0-9_-]*        -- 命名空间(通常=repository 名)
  path       = [a-z][a-z0-9_/.-]*      -- 层级路径

示例:
  repository:default/daedalus
  crate:default/daedalus-app
  crate:default/daedalus-app/src/components/Button
  archetype:default/component-design-best-practice
  page:default/daedalus-app/src/pages/CrateList
  skill:default/react-component-creator          ← 未来
  item:default/typescript-sword                  ← 未来