@captiveorigins/payload-plugin-onepedigree

中文文档
0.1.0-alpha.18发布于 2026/11/10PolyForm-Noncommercial-1.0.0TypeScriptES Module构建来源已验证近 30 天下载 1721

OnePedigree for Payload: parentage fields, cycle-safe parentage writes, deletion policies, permission-aware pedigree endpoints for all 13 views, and Admin previews.

原始使用文档
文档目录8 节
  1. Identifiers beside names
  2. Modes
  3. Parent labels
  4. Cohorts are birthing events
  5. Integrity
  6. Endpoints
  7. Admin
  8. License

@captiveorigins/payload-plugin-onepedigree

OnePedigree for Payload CMS 3: parentage on your own collection, cycle-safe writes, deletion policies, permission-aware pedigree endpoints for all 13 views, and Admin components (pedigree preview, relatives, color theme settings).

import { onePedigree } from '@captiveorigins/payload-plugin-onepedigree'

export default buildConfig({
  collections: [Animals, Clutches],
  plugins: [
    onePedigree({
      collection: 'animals',
      mode: 'standard-fields', // or 'managed' (creates the collections) or 'mapped' (your fields)
      cohorts: { collection: 'clutches' },
      hiddenRecords: 'placeholder', // a private relative shows as an anonymous "private record"
      navigation: { individualUrl: '/animals/{id}' },
    }),
  ],
})

Identifiers beside names

fields.identifier shows a host identifier after each name in every view, relatives list and spoken name, e.g. "Mead (CO-AQCR6T)". Give a field path, or a function of the requester so each person can choose, for example a registry ID or their own studbook number:

fields: { identifier: ({ user }) => (user?.showStudbook ? 'studbookNo' : 'coId') }

A record the requester can't read never shows its identifier: its placeholder carries none. React's Terminology.identifierFormat (default {label} ({id})) changes how the two are joined.

Modes

  • managed: creates individuals-style and cohort collections from the factories (createIndividualsCollection, createCohortsCollection).
  • standard-fields (default): adds the parentage group (parents[{ individual, role }], reproductiveMode, cohort) to your existing collection.
  • mapped: uses your fields, e.g. { kind: 'role-fields', roles: { mother: 'dam', father: 'sire' }, cohort: 'clutch' } or { kind: 'parent-array', path: 'lineage', individualField: 'animal', roleField: 'role' }.

The plugin never creates collections for parents, roles, modes, graph edges or occurrences.

Parent labels

Stored roles stay mother / father; only the words change. terminology.parents sets the default ('mother-father' (default), 'dam-sire', 'female-male-parent', or custom { maternal, paternal }). Add createParentTermsPreferenceField() to your users collection and pass its path as terminology.userPreference: each user then sees their own choice in the Mother/Father pickers and in relatives.

Cohorts are birthing events

A cohort is one birthing event (a clutch, a litter, twins): one mother, fathers may differ per member. With cohorts.birthParentField (the cohort's field naming the mother), a member whose recorded mother differs is refused, and so is changing the cohort's mother while members disagree.

Integrity

On every write (Admin, REST, GraphQL, Local API, imports):

  • self-parents, duplicated parents and cycles are rejected with field-addressable errors; the cycle check walks the full stored descendant line;
  • a parent the editor cannot read is rejected, with the same message as a missing one;
  • host rules (e.g. taxonomy) run on the proposed record;
  • parentage changes are serialized: each updates a graph-revision global in the same transaction, so two concurrent edits that would together form a cycle cannot both commit (requires a MongoDB replica set or another adapter with transactions). The revision also serves as a cache key.

Deleting a recorded parent is refused (onReferencedIndividualDelete: 'restrict', default) or removes the references ('detach').

Endpoints

Route
GET /api/<collection>/:id/pedigree?view=…Projection + layout; ancestorDepth, descendantDepth, relatedId, cohortId, occurrenceMode, includeSiblings, orientation, maxNodes, layout=false
GET /api/<collection>/:id/relativesParents, offspring, siblings (full / partial / unresolved), cohort mates
POST /api/<collection>/:id/pedigree/validateCheck { parents, reproductiveMode, cohort } without saving (needs update access)
GET /api/<cohorts>/:id/membersMembers the requester may see

Every read runs as the requester (access control applies), is bounded by limits (maxDepth, maxNodes) and returns display projections, not documents. Records the requester cannot read are omitted or replaced by anonymous placeholders; their IDs, names and links never appear in responses.

The same holds for plain collection reads (REST, GraphQL, the Admin, and the Local API with overrideAccess: false), single or list, at any depth. A parent the reader can't read comes back as { "private": true } with hiddenRecords: 'placeholder', or is left out with 'omit'. GraphQL returns null for it. Trusted Local API reads (the default overrideAccess: true) are unchanged. When someone saves a record that showed them a private parent, that parent is kept as stored: a placeholder, an empty picker or a missing row means "unchanged", and replacing it with another parent is refused. The kept parent also passes the parent field's validation, which would otherwise look it up with the editor's access whenever the field has filterOptions (as the multi-tenant plugin adds); other values are validated as usual.

Add an index on the parent path (parentage.parents.individual, or your role fields) in production; the standard fields declare it.

Admin

  • A pedigree panel on the edit view: preview of the saved record in any view (pan, zoom, selection), relatives, and structural notices.
  • A Pedigree settings global: color theme (seven presets, per-view accents, hex editing) used by the preview; read it in your frontend to match.

License

PolyForm Noncommercial 1.0.0. Free for noncommercial use, with attribution; commercial use needs a separate license from Captive Origins. Versions published before this change remain under MIT.

版本与发布记录

@captiveorigins/payload-plugin-onepedigree 共发布 12 个版本,首次发布于 2026/11/01;过去 12 个月发布了 12 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.1.0-alpha.18latest2026/11/10今天
0.1.0-alpha.132026/11/09今天
0.1.0-alpha.152026/11/09今天
0.1.0-alpha.122026/11/063 天前
0.1.0-alpha.112026/11/036 天前
0.1.0-alpha.102026/11/036 天前

其他发布通道:alpha → 0.1.0-alpha.8。

关于 @captiveorigins/payload-plugin-onepedigree 的常见问题

@captiveorigins/payload-plugin-onepedigree 是什么?

OnePedigree for Payload: parentage fields, cycle-safe parentage writes, deletion policies, permission-aware pedigree endpoints for all 13 views, and Admin previews.

如何安装 @captiveorigins/payload-plugin-onepedigree?

在项目目录运行 npm install @captiveorigins/payload-plugin-onepedigree,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(>=19)、payload(^3.80.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@captiveorigins/payload-plugin-onepedigree 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@captiveorigins/payload-plugin-onepedigree 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@captiveorigins/payload-plugin-onepedigree 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@captiveorigins/payload-plugin-onepedigree 可以商用吗?

@captiveorigins/payload-plugin-onepedigree 使用 PolyForm-Noncommercial-1.0.0 许可。声明的许可为 PolyForm-Noncommercial-1.0.0,请阅读许可原文确认使用条件。以上为概括,不构成法律意见,请以许可原文为准。

@captiveorigins/payload-plugin-onepedigree 的下载量有多少?

根据 npm 官方下载统计,@captiveorigins/payload-plugin-onepedigree 在 2026/10/09 – 2026/11/07 这 30 天内被下载 1,721 次,日均约 57 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@captiveorigins/payload-plugin-onepedigree 还在维护吗?

最新版本 0.1.0-alpha.18 发布于 2026/11/10(今天);至今共发布 12 个版本,其中过去 12 个月发布了 12 个;首次发布于 2026/11/01。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。