
Medusa 数据模型 TSDoc 注释规范为 DML 实体编写高质量 API 文档【免费下载链接】medusaThe worlds most flexible commerce platform for agents and developers项目地址: https://gitcode.com/GitHub_Trending/me/medusaMedusa 的模块数据模型Data Model位于packages/modules/*/src/models/下使用 DMLData Model Language的model.define(...)定义实体而这些源码中的 TSDoc 注释是官方 API 参考文档的生成来源。本文基于仓库内 writing-tsdocs 技能的>// ✅ 正确 — 完整句子 /** * A locale supported by a store. */ const StoreLocale model.define(StoreLocale, {// ✅ 同样正确 — 简短短语 /** * A product variants image. */ const ProductVariantProductImage model.define(ProductVariantProductImage, {仓库中已经落地的示例可以在 product.ts 中找到/** * A product in the catalog. */ const Product model.define(Product, {属性描述Property Descriptions每个属性都需要一行简短的功能描述。规范的完整示例如下摘自参考文档字段与 product-variant.ts 中的真实模型一一对应const ProductVariant model.define(ProductVariant, { // id: 省略不写 — 它是主键文档系统默认处理 /** * The variants stock keeping unit. */ sku: model.text().nullable(), /** * The variants display name. */ title: model.text(), /** * The variants position in the products variants list. */ variant_rank: model.number().default(0), /** * Whether inventory is tracked for this variant. */ manage_inventory: model.boolean().default(true), /** * The associated product. */ product: model.belongsTo(() Product, { mappedBy: variants, }), })要点解读描述的是「业务含义」而非「技术类型」。例如sku的注释是 The variants stock keeping unit.变体的库存单位而不是 A text field——字段类型model.text()、model.number()等由文档系统从定义中自动推导。默认值无需在注释里重复。.default(0)、.default(true)这类修饰符会被文档系统解析并展示注释只需说明字段语义。字段命名应直观使注释能与字段名互相印证若字段名本身自明注释依然不能省略——它是文档系统对外展示的唯一文案来源。since 标签标记本次新增内容版本标记是这套规范中最容易出错的点务必严格遵守以下两条规则。规则一仅标记「本次 diff 新增」的属性since version只能加在本次提交 diff 的新增行中出现的属性上。已存在的老属性一律不加——即使你恰好正在修改该模型文件const ProductVariant model.define(ProductVariant, { // ... 已存在的属性不加 since /** * The variants thumbnail image URL. * since 2.14.0 */ thumbnail: model.text().nullable(), /** * The variants images. * since 2.14.0 */ images: model.manyToMany(() ProductImage, { mappedBy: variants, pivotEntity: () ProductVariantProductImage, }), })仓库中真实存在同类注释。例如 product-variant.ts 中thumbnail与images两个属性均标注了since 2.11.2product.ts 中product_options属性则标注了since 2.16.0。这些示例说明since记录的是该属性在版本历史中的首次引入版本属于事实性元数据。规则二整个模型新增时在模型级加 since如果整个模型都是本次 diff 新增的则将since加在模型级描述上而不是逐属性重复/** * A locale supported by a store. * since 2.14.0 */ const StoreLocale model.define(StoreLocale, { /** * The BCP 47 language tag code of the locale. * example en-US */ locale_code: model.text().searchable(), /** * The associated store. */ store: model.belongsTo(() Store, { mappedBy: supported_locales }).nullable(), })example为非显而易见的取值格式补充示例当字段的期望取值格式无法从字段名直观推断时必须使用example给出真实示例。最常见的三类场景是语言代码、货币代码与时区标识符/** * The BCP 47 language tag code of the locale. * example en-US */ locale_code: model.text(), /** * The ISO 4217 currency code. * example usd */ currency_code: model.text(), /** * The IANA timezone identifier. * example America/New_York */ timezone: model.text().nullable(),判断是否需要example的实用标准字段名已自明如title、description、url→ 不需要字段名只给了领域概念、未给格式如locale_code可能是en-US也可能是en_uscurrency_code可能是usd也可能是USD→ 必须给。注意example中应写出字符串的字面形式带引号让读者可以直接复制使用。关系属性Relationship Properties关系属性.belongsTo、.hasMany、.manyToMany的注释使用统一的固定句式The associated [related model].其中[related model]是对端实体的名称/** * The associated store. */ store: model.belongsTo(() Store, { mappedBy: supported_locales }), /** * The products variants. */ variants: model.hasMany(() ProductVariant, { mappedBy: product }), /** * The variants images. */ images: model.manyToMany(() ProductImage, { mappedBy: variants }),仓库源码中的真实案例product.tsvariants: model.hasMany(() ProductVariant, { mappedBy: product })注释为 The products variants.product.tstype: model.belongsTo(() ProductType, ...)注释为 The associated product type.product-image.tsvariants: model.manyToMany(() ProductVariant, ...)关系product-category.ts自引用的parent_categorybelongsTo与category_childrenhasMany体现树形层级关系。使用统一句式的原因在于关系字段在生成的 API 参考中会被渲染为「关联实体」区块一致的措辞能保证跨模型、跨模块的文档观感统一也便于检索与引用。什么不该写What NOT to Document规范同样明确了两类「明确禁止」的情形// ❌ 不要注释 id主键永远隐含文档系统默认生成 id: model.id({ prefix: pv }).primaryKey(), // ❌ 不要给本次提交之前就已存在的属性加 since sku: model.text(),反例背后的理由id主键所有 DML 实体都以id作为主键参考 product-variant.ts 的id: model.id({ prefix: variant }).primaryKey()。这是既定约定写注释属于冗余噪音且可能与文档系统的自动生成内容冲突。误加since版本标记是增量事实只描述「这个属性在哪个版本被引入」。给老属性补since会污染版本历史导致 API 参考中呈现错误的引入版本。底层支撑DML 属性与修饰符一览为正确撰写注释理解 DML 提供的能力边界很有帮助。DML 的属性体系定义在 packages/core/utils/src/dml/properties包含text、number、float、boolean、json、bigNumber、enum、dateTime、array、id、autoincrement、computed等类型。所有属性类型共享BaseProperty基类见 base.ts它提供了以下常用修饰符这些修饰符会让文档系统自动生成对应的字段属性展示修饰符作用.nullable()字段值允许为null.default(value)设置默认值如model.number().default(0).index(name?)在该属性上创建索引索引名缺省时由系统生成.unique(name?)创建唯一索引.computed()标记为计算属性不落库、运行时计算.searchable()标记为可搜索字段在 product.ts 与 product-variant.ts 中可以看到这些修饰符的组合使用例如title: model.text().searchable().translatable()、weight: model.float().nullable()、status: model.enum(ProductUtils.ProductStatus).default(ProductUtils.ProductStatus.DRAFT)。撰写注释时属性描述应聚焦业务语义类型、默认值、可空性等信息由这些修饰符自动传达给文档系统无需在注释中重复。自查清单完成一个数据模型文件的 TSDoc 注释后按以下清单逐项检查每个模型的const上方有一句话实体描述每个属性除主键id外都有简短的功能描述本次 diff 新增的属性/模型标注了准确的since version已存在的旧属性没有误加sincelocale 代码、货币代码、时区等非直观格式均有example关系属性belongsTo / hasMany / manyToMany使用 The associated [related model]. 句式没有为主键id编写注释注释描述业务语义未重复字段类型与默认值等系统可推导信息。遵循这套规范仓库内所有模块的 DML 数据模型都能产出结构统一、版本信息准确、示例完备的 API 参考文档让使用者包括开发者和 AI 工具都能快速、准确地理解每个实体的含义与约束。【免费下载链接】medusaThe worlds most flexible commerce platform for agents and developers项目地址: https://gitcode.com/GitHub_Trending/me/medusa创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考