Skip to content

Commit 476ec0a

Browse files
docs(skills): objectstack-data factual sweep (1/N) — field-types, relationships, indexing (#13687)
Six measured-false behavioral claims corrected against the implementation: - field-types.md: an unknown field key is REFUSED at parse (unrecognized_keys), not "silently stripped"; same for an authored vectorConfig. - field-types.md: a wrong-cased date token ({yyyy}) parses as a {field} reference and renders EMPTY — it is not emitted literally. - relationships.md: roll-up summary fields DO work over a lookup child. - relationships.md: master_detail required is forced only under sharingModel: 'controlled_by_parent'; elsewhere it is a lint warning. - indexing.md: foreign keys are NOT auto-indexed. Token ratchet: all three files shrink (-6 / -5 / -1 = -12). Part of #13675 Claude-Session: https://claude.ai/code/session_01EXxTW8mvPBhoHxmyPZ63de Co-authored-by: Claude <noreply@anthropic.com>
1 parent b8fc728 commit 476ec0a

3 files changed

Lines changed: 11 additions & 14 deletions

File tree

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
Quick reference for choosing the right field type from 49 available options.
44

55
> **Config columns list only real `FieldSchema` keys.** Per-type display knobs
6-
> beyond these do **not** exist — an unknown field key is silently stripped at
7-
> parse (dead metadata), so don't invent config like `theme`, `rows`, or
6+
> beyond these do **not** exist — an unknown field key is REFUSED at parse
7+
> (`unrecognized_keys`), so don't invent `theme`, `rows`, or
88
> `fileAttachmentConfig`. Source of truth:
99
> `node_modules/@objectstack/spec/src/data/field.zod.ts`.
1010
@@ -343,7 +343,7 @@ The `format` is literal text interleaved with `{...}` tokens:
343343
1. **Every `{field}` you interpolate must be `required: true`** and set before the record is created. An empty interpolated field makes the record number generation *throw* (the compile lint flags a non-existent field as an error, an optional one as a warning).
344344
2. **Put a delimiter between adjacent variable tokens** — `{section}-{zone}{000}`, not `{section}{zone}{000}`. Without one, `('AB','C')` and `('A','BC')` both render prefix `ABC` and share a counter (to keep numbers unique). The literal separator keeps distinct groups apart.
345345
3. **Pad width is a MINIMUM, not a cap.** `{000}``001``999`, then `1000` (it grows, never wraps). Size it for readability, not as a ceiling.
346-
4. **Only known tokens are interpolated.** Date tokens are **case-sensitive and exact** (`{YYYY}`, not `{yyyy}` or `{YYYY-MM}`). An unrecognized `{...}` is emitted **literally** into the number — `{ YYYY }` (spaces) renders the text `{ YYYY }`.
346+
4. **Only known tokens are interpolated.** Date tokens are **case-sensitive** `{yyyy}` parses as a `{field}` reference and renders **empty** (rule 1 applies). Only a spelling no field could have — `{ YYYY }`, `{YYYY-MM}` — is emitted **literally**.
347347
348348
### Vector (AI Embeddings)
349349
@@ -354,8 +354,8 @@ The `format` is literal text interleaved with `{...}` tokens:
354354
}
355355
```
356356
357-
There is **no** `vectorConfig` block — an authored `vectorConfig` is silently
358-
stripped (dead metadata). `dimensions` is the flat field-level key.
357+
There is **no** `vectorConfig` block — an authored `vectorConfig` is refused at
358+
parse. `dimensions` is the flat field-level key.
359359
360360
## Incorrect vs Correct
361361

skills/objectstack-data/rules/indexing.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ Guide for creating efficient database indexes in ObjectStack.
66

77
ObjectStack automatically creates indexes for:
88
- Primary keys (`id`)
9-
- Foreign keys (lookup/master_detail fields)
10-
- Unique constraints
9+
- Field-level `unique`**not** foreign keys: declare those
1110

1211
**Only declare non-default values.** `unique` defaults to `false` — omit it when using the default.
1312

@@ -83,7 +82,7 @@ Notes an author has to know:
8382

8483
### ✅ Always Index
8584

86-
1. **Foreign keys**Automatic, but verify
85+
1. **Foreign keys**declare them; never automatic
8786
2. **Filter fields** — Columns used in WHERE clauses
8887
3. **Sort fields** — Columns used in ORDER BY
8988
4. **Unique constraints** — Enforce uniqueness at DB level
@@ -328,7 +327,7 @@ SHOW INDEX FROM your_table;
328327

329328
## Best Practices
330329

331-
1. **Index foreign keys**Always (automatic in ObjectStack)
330+
1. **Index foreign keys**always; declare each one
332331
2. **Composite for common queries** — Combine frequently filtered columns
333332
3. **Order matters** — Most selective field first
334333
4. **Partial for subsets** — but build it in a migration, not a declaration

skills/objectstack-data/rules/relationships.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,21 @@ Guide for modeling relationships between objects using `lookup`, `master_detail`
66

77
| Type | Lifecycle | Required | Sharing | Roll-ups | Use Case |
88
|:-----|:----------|:---------|:--------|:---------|:---------|
9-
| `lookup` | Independent | Optional by default | Independent | Not available | "Related to" |
10-
| `master_detail` | Coupled (cascade delete) | Always required | Inherits parent | Supported via `summary` | "Owned by" |
9+
| `lookup` | Independent | Optional by default | Independent | Supported via `summary` | "Related to" |
10+
| `master_detail` | Coupled (cascade delete) | Forced only under `controlled_by_parent`; else lint-warned | Inherits parent | Supported via `summary` | "Owned by" |
1111
| `tree` | Self-reference | Optional | N/A | Not available | Hierarchical |
1212

1313
## When to Use lookup vs master_detail
1414

1515
### Use `lookup` When:
1616
- Child record can exist independently
17-
- Parent deletion should not affect child (`deleteBehavior: 'set_null'`)
18-
- No roll-up aggregations needed
17+
- Parent deletion should only clear the FK (`deleteBehavior: 'set_null'`, the default)
1918
- Relationship is optional
2019
- **Example:** `task.assigned_to → user` (task can exist without assignment)
2120

2221
### Use `master_detail` When:
2322
- Child record is meaningless without parent
2423
- Parent deletion should cascade to children
25-
- Need roll-up summaries (count, sum, min, max, avg)
2624
- Relationship is mandatory
2725
- **Example:** `invoice_line_item.invoice_id → invoice` (line items belong to invoice)
2826

0 commit comments

Comments
 (0)