Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/pointer-pair-seed-resolution.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
---
"@objectstack/spec": minor
"@objectstack/metadata-protocol": minor
"@objectstack/plugin-audit": minor
---

Seeds can now address an ActivityPointer (#11339, ADR-0052 §5): a `text` field may declare `referenceVia: '<sibling>'`, marking it as the id half of a polymorphic pointer pair whose target object the sibling column names per row (`sys_activity.record_id` via `object_name`, `source_id` via `source_object` — both now declared). The seed loader resolves such pointers as natural keys against the object each row names — the same externalId probes, in-memory map and pass-2 deferral static lookup references use — so a packaged app's seed can ship timeline rows that actually attach to their records, and the shipped console filter `{ object_name, record_id }` matches them.

The accept/reject contract changes with it, deliberately: an unresolvable pointer on a DECLARED pair is now a loud, counted failure (`success: false`, `error`-level log, record dropped when no pass 2 can heal it) instead of the old silent verbatim store — a row that rendered on no timeline and matched no filter. Undeclared text columns are untouched: only `referenceVia` opts a pair in. Authoring contradictions are refused at parse time (`referenceVia` is text-only and mutually exclusive with `reference`) and at `ObjectSchema.create` (the sibling must be a declared field). Internal-id-shaped values still pass through verbatim, so seeds wiring real ids keep working.
1 change: 1 addition & 0 deletions content/docs/references/data/field.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -76,6 +76,7 @@ const result = CurrencyConfigSchema.parse(data);
| **maxSize** | `integer` | optional | Maximum permitted file size in BYTES for media fields. Enforced on write against the stored file size, not just checked in the browser. |
| **options** | `{ label: string; value: string; color?: string; default?: boolean; … }[]` | optional | Static options for select/multiselect |
| **reference** | `string` | optional | Target object name (snake_case) for lookup/master_detail fields. Required for relationship types. Used by $expand to resolve foreign key IDs into full objects. |
| **referenceVia** | `string` | optional | Declares this text field as the id half of a polymorphic pointer pair (ADR-0052 §5 ActivityPointer): the value is a record id of the object named by the SIBLING FIELD this key names — e.g. `record_id` with `referenceVia: 'object_name'`. The sibling must be a declared field on the same object holding an object machine name. Text fields only; mutually exclusive with `reference` (a static and a per-record target contradict). Enforced today at seed load: the value resolves as a natural key against the object the sibling column names, and an unresolvable pointer is refused loudly instead of stored verbatim. Adds no referential integrity or $expand behavior. |
| **deleteBehavior** | `Enum<'set_null' \| 'cascade' \| 'restrict'>` | optional (default: `"set_null"`) | What happens if referenced record is deleted |
| **inlineEdit** | `boolean \| Enum<'grid' \| 'form'>` | optional | Edit these child records inline within the parent's form (atomic master-detail). true = auto-pick grid/form by child shape; 'grid' = editable line-item grid; 'form' = list + per-row full form. |
| **inlineTitle** | `string` | optional | Title for the inline master-detail grid |
Expand Down
Loading
Loading