Skip to content

Commit 79cdfe9

Browse files
claude[bot]claude
andauthored
docs(skills): master_detail deleteBehavior admits cascade/restrict only (#11869)
The published objectstack-data skill taught `deleteBehavior: 'set_null'` on a `master_detail` field in four places. That was already wrong before #9689 — the engine resolved every non-`restrict` value on this type to `cascade`, so the declaration promised keep-the-children and delivered delete-the-children — and since #9689 landed (PR #11406) it is a named parse-time rejection: an AI author following the skill produced metadata that fails publish with a 422. Teaches the per-type vocabulary instead: `master_detail` admits `cascade` / `restrict`; `set_null` belongs on `lookup`, where children survive the parent. Correction, not expansion — net line delta is exactly 0 in both files. Claude-Session: https://claude.ai/code/session_01RMTpSRF5CjMmQBFfPtPCwJ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 5997207 commit 79cdfe9

2 files changed

Lines changed: 7 additions & 7 deletions

File tree

skills/objectstack-data/rules/field-types.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ options: [
6868

6969
| Type | When to Use | Key Config |
7070
|:-----|:------------|:-----------|
71-
| `lookup` | Reference another object (independent) | `reference`, `lookupFilters`, `multiple` |
72-
| `master_detail` | Parent–child with lifecycle control | `reference`, `deleteBehavior` (cascade/restrict/set_null) |
71+
| `lookup` | Reference another object (independent) | `reference`, `lookupFilters`, `multiple`, `deleteBehavior` |
72+
| `master_detail` | Parent–child with lifecycle control | `reference`, `deleteBehavior` (`cascade`/`restrict``set_null` is refused) |
7373
| `tree` | Hierarchical self-reference | `reference` |
7474
| `user` | Person picker — a lookup specialized to `sys_user` (assignee, watchers). Stored identically to `lookup` | `multiple` (collaborators), `defaultValue: 'current_user'` |
7575

skills/objectstack-data/rules/relationships.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Guide for modeling relationships between objects using `lookup`, `master_detail`
1414

1515
### Use `lookup` When:
1616
- Child record can exist independently
17-
- Parent deletion should not affect child
17+
- Parent deletion should not affect child (`deleteBehavior: 'set_null'`)
1818
- No roll-up aggregations needed
1919
- Relationship is optional
2020
- **Example:** `task.assigned_to → user` (task can exist without assignment)
@@ -150,19 +150,19 @@ export default ObjectSchema.create({
150150

151151
## Delete Behaviors
152152

153-
Configure `deleteBehavior` on `master_detail` relationships:
153+
Configure `deleteBehavior` on `master_detail``cascade` or `restrict` **only**;
154+
an authored `set_null` is refused at publish (it would orphan the detail row).
154155

155156
| Behavior | Effect | Use Case |
156157
|:---------|:-------|:---------|
157158
| `cascade` | Delete all child records | Invoice → Line Items |
158159
| `restrict` | Prevent parent deletion if children exist | Department → Employees |
159-
| `set_null` | Set child reference to null | Manager → Employees (manager leaves) |
160160

161161
```typescript
162162
{
163163
type: 'master_detail',
164164
reference: 'parent_object',
165-
deleteBehavior: 'cascade', // or 'restrict' or 'set_null'
165+
deleteBehavior: 'cascade', // or 'restrict' 'set_null' is refused here
166166
}
167167
```
168168

@@ -402,7 +402,7 @@ export default ObjectSchema.create({
402402
1. **Use lookup by default** — Only use master_detail when lifecycle coupling is required
403403
2. **Unique constraints on junctions** — Prevent duplicate many-to-many entries
404404
3. **Meaningful junction names** — Use descriptive names like `project_assignment` not `project_employee`
405-
4. **deleteBehavior on master_detail** — Always specify cascade/restrict/set_null
405+
4. **deleteBehavior on master_detail** — Always specify `cascade` or `restrict`
406406
5. **Required on master_detail** — Child should always require parent
407407
6. **Roll-ups for aggregation** — Use summary fields on parent for counts/sums
408408
7. **lookupFilters for scoping** — Limit lookup options to relevant records (`lookupFilters: [{ field, operator: 'eq', value }]`)

0 commit comments

Comments
 (0)