Skip to content

Commit c77ac65

Browse files
os-zhuangclaude
andauthored
docs: sync remaining 82 hand-written docs with actual implementation (audit pass 2) (#1904)
Finishes the implementation-accuracy audit started in #1866 (which covered 46 docs in getting-started/concepts/guides). This pass covers the remaining 82 hand-written docs — guides (incl. cheatsheets/contracts/metadata/runtime-services), protocol (objectos/objectql/objectui), releases, and the docs index. A multi-agent audit read each doc, located the real implementation in packages/, and adversarially verified every finding against the code (a second verifier re-checked each applied fix and repaired over-corrections). This applies 486 verified fixes across 73 docs, plus 28 verifier repairs. Auto-generated references/ docs (DO-NOT-EDIT, produced from packages/spec) were excluded. Recurring classes of fix: - broken-example / inaccurate-api: code samples and method names that don't exist or changed — fabricated transaction methods (tx.insert/tx.update), non-existent helpers (definePlugin), wrong package names (@objectstack/services/service-cache -> @objectstack/service-cache), ViewFieldSchema -> FormFieldSchema, wrong @objectstack/spec subpath imports. - fabricated-feature: field-type props that aren't in the schema (sanitize/allowed_tags/protocols/region/rows), a phantom `Workflow` metadata type with *.workflow.ts conventions, fabricated CLI scaffold output. - naming/enum drift: max_length -> maxLength; relationship/complex type lists corrected to real enum values; OWDModel value spellings (public_read/...). - security model: FLS non-editable write rejects with PermissionDeniedError (403) rather than silent strip; PermissionSet over Salesforce-style shapes. - outdated paths/env: OS_EMAIL__PROVIDER double-underscore, /v1 REST prefixes, config-resolution precedence and envKey coercion examples. Navigation-safe: no files moved, frontmatter preserved on every doc. Verified: `next build` compiles all 1113 pages clean (exit 0). Residual items the audit could not confirm against code, plus the observation that committed references/ have drifted from spec, are recorded in docs/audits/2026-06-handwritten-docs-accuracy-followups.md for a follow-up pass. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent ce1aba9 commit c77ac65

74 files changed

Lines changed: 3962 additions & 5517 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

content/docs/guides/airtable-dashboard-analysis.mdx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,7 @@ export const DashboardHeader: React.FC<DashboardHeaderProps> = ({
665665
### 5.1 Full Dashboard Definition (TypeScript)
666666

667667
```typescript
668-
import { Dashboard } from '@objectstack/spec';
668+
import { Dashboard } from '@objectstack/spec/ui';
669669

670670
export const salesPerformanceDashboard = Dashboard.create({
671671
name: 'sales_performance',
@@ -1068,7 +1068,6 @@ For reference, here's the same dashboard definition in pure JSON format:
10681068

10691069
- [Dashboard Metadata Guide](/docs/guides/metadata/dashboard) — Current dashboard protocol documentation
10701070
- [Chart Configuration Reference](/docs/references/ui/chart) — Chart type taxonomy and configuration
1071-
- [Airtable Interface Gap Analysis](/docs/design/airtable-interface-gap-analysis) — Interface-level gap analysis (superseded)
10721071

10731072
---
10741073

content/docs/guides/analytics-datasets.mdx

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,21 @@ measure values by hand:
167167

168168
## Migrating from inline queries
169169

170-
ADR-0021's terminal state is **one** author-facing shape. The migration runs in
171-
two steps so it can be verified safely:
172-
173-
1. **Dual-form (additive).** A report/widget keeps its legacy inline query AND
174-
gains a `dataset` binding. A read-only reconciliation harness asserts both
175-
forms return identical numbers (the financial-correctness gate).
176-
2. **Single-form (terminal).** Once every surface reconciles and `grep` shows no
177-
inline residue, the inline query fields and `ListChartConfigSchema` are
178-
removed and the union collapses to the single dataset shape.
170+
ADR-0021's terminal state is **one** author-facing shape, and the cutover is now
171+
complete: `report`, `dashboard` widgets, and list-view charts are all
172+
dataset-bound today (`ReportSchema`, `DashboardWidgetSchema`,
173+
`ListChartConfigSchema` in `packages/spec/src/ui`). The migration ran in two
174+
steps so it could be verified safely:
175+
176+
1. **Dual-form (additive).** A report/widget kept its legacy inline query AND
177+
gained a `dataset` binding. A read-only reconciliation harness asserted both
178+
forms returned identical numbers (the financial-correctness gate).
179+
2. **Single-form (terminal).** Once every surface reconciled, the inline query
180+
fields (`objectName`/`columns`/`groupings` on reports, `valueField`/`aggregate`
181+
on widgets, `xAxisField`/`yAxisFields`/`aggregation` on list charts) were
182+
removed and each schema collapsed to the single dataset shape. The
183+
presentation schemas themselves were kept — only their inline query fields
184+
went away.
179185

180186
Author new analytics directly in dataset form; reach for a **named** dataset when
181187
a metric is shared or must be certified, and an inline anonymous dataset for a

content/docs/guides/cheatsheets/backward-compatibility.mdx

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -111,26 +111,35 @@ v4.0.0 → Feature removed (earliest possible removal)
111111

112112
## Migration Support
113113

114-
### Automated Migrations
114+
### Linting Your Project
115115

116-
ObjectStack provides tooling to ease upgrades across MAJOR versions:
116+
The CLI's `lint` command validates your metadata against the current schema and surfaces issues. Adding `--fix` prints the suggested fix for each issue (dry-run; it does not modify files):
117117

118118
```bash
119-
# Check for deprecated usage in your project
120-
npx @objectstack/cli lint --deprecations
119+
# Validate metadata against the current schema
120+
os lint
121121

122-
# Auto-migrate to the latest schema version
123-
npx @objectstack/cli migrate --from 3.x --to 4.x
122+
# Show what could be auto-fixed (dry-run)
123+
os lint --fix
124+
125+
# Scan your source for deprecated ObjectStack patterns
126+
os doctor --scan-deprecations
127+
128+
# Compare two configs and detect breaking changes between versions
129+
os diff <before> <after> --breaking-only
124130
```
125131

132+
<Callout type="info">
133+
There is no `lint --deprecations` flag — deprecation scanning lives on `os doctor --scan-deprecations`. An automated `migrate`/`codemod` command is referenced in the migration guides but is not yet available; until then, combine `os doctor --scan-deprecations`, `os diff`, and the CHANGELOG migration notes (below) to upgrade across MAJOR versions.
134+
</Callout>
135+
126136
### Migration Guides
127137

128138
Each MAJOR release includes:
129139

130140
- **CHANGELOG.md** — Complete list of changes with migration notes
131141
- **RELEASE_NOTES.md** — High-level summary and upgrade instructions
132-
- **Codemods** — Automated code transformations where possible
133-
- **Schema Diff** — Machine-readable diff of all schema changes
142+
- **Schema Diff** — Use `os diff <before> <after>` to produce a machine-readable (`--json`) diff of breaking changes between two configs
134143

135144
### Support Windows
136145

@@ -160,7 +169,7 @@ The `@objectstack/spec` package provides additional stability guarantees:
160169

161170
### Runtime Behavior
162171

163-
- `z.parse()` results are guaranteed consistent within a MAJOR version
172+
- `Schema.parse()` results are guaranteed consistent within a MAJOR version
164173
- Default values applied by `.default()` are stable within a MAJOR version
165174
- Validation error messages may change in MINOR/PATCH releases (do not rely on exact error text)
166175

content/docs/guides/cheatsheets/error-catalog.mdx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ ObjectStack uses a structured error system with **9 error categories** and **41+
99

1010
<Callout type="info">
1111
**Source:** `packages/spec/src/api/errors.zod.ts`
12-
**Import:** `import { StandardErrorCodeSchema, ErrorCategorySchema, ErrorResponseSchema } from '@objectstack/spec/api'`
12+
**Import:** `import { StandardErrorCode, ErrorCategory, ErrorResponseSchema } from '@objectstack/spec/api'`
1313
</Callout>
1414

1515
---
@@ -63,7 +63,7 @@ ObjectStack uses a structured error system with **9 error categories** and **41+
6363

6464
### `invalid_field`
6565
**Cause:** A field name in the request does not exist on the target object.
66-
**Fix:** Check the object schema for valid field names. Use `objectstack explain <object>` to see available fields.
66+
**Fix:** Check the object schema for valid field names. Use `os meta get object <name>` to inspect the object's fields.
6767
**Retry:** `no_retry`
6868

6969
### `missing_required_field`
@@ -210,7 +210,7 @@ ObjectStack uses a structured error system with **9 error categories** and **41+
210210

211211
### `object_not_found`
212212
**Cause:** The specified object (table/entity) does not exist in the schema.
213-
**Fix:** Check the object name. Use `objectstack explain` to list available objects.
213+
**Fix:** Check the object name. Use `os meta list object` to list available objects.
214214
**Retry:** `no_retry`
215215

216216
### `record_not_found`
@@ -372,10 +372,11 @@ interface EnhancedApiError {
372372

373373
```typescript
374374
interface FieldError {
375-
field: string; // Field name that has the error
376-
message: string; // Human-readable error for this field
377-
code?: string; // Field-level error code
378-
value?: unknown; // The invalid value (if safe to include)
375+
field: string; // Field path (supports dot notation)
376+
code: StandardErrorCode; // Field-level error code
377+
message: string; // Human-readable error for this field
378+
value?: unknown; // The invalid value (if safe to include)
379+
constraint?: unknown; // The constraint that was violated (e.g., max length)
379380
}
380381
```
381382

content/docs/guides/cheatsheets/field-type-decision-tree.mdx

Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ flowchart TD
3838
TEXT -->|Secret value| T8[password]
3939
4040
%% Number branch
41-
NUM -->|Decimal number| N1[number]
42-
NUM -->|Whole number| N2[integer]
41+
NUM -->|Any number| N1[number]
4342
NUM -->|Money amount| N3[currency]
4443
NUM -->|Percentage| N4[percent]
4544
NUM -->|Star rating| N5[rating]
45+
NUM -->|Slider input| N6[slider]
4646
4747
%% Date branch
4848
DATE -->|Date only| D1[date]
@@ -61,28 +61,26 @@ flowchart TD
6161
REL -->|Reference another object| R1[lookup]
6262
REL -->|Parent-child cascade| R2[master_detail]
6363
REL -->|Self-referencing hierarchy| R3[tree]
64-
REL -->|Multiple object types| R4[polymorphic]
6564
6665
%% File branch
6766
FILE -->|Any file| F1[file]
6867
FILE -->|Image with preview| F2[image]
69-
FILE -->|Multiple files| F3[attachment]
68+
FILE -->|User profile picture| F3[avatar]
7069
7170
%% Computed branch
7271
COMP -->|Calculated value| K1[formula]
73-
COMP -->|Aggregate children| K2[rollup]
72+
COMP -->|Aggregate children| K2[summary]
7473
COMP -->|Auto-incrementing ID| K3[autonumber]
7574
7675
%% Structured branch
7776
STRUCT -->|Postal address| S1[address]
7877
STRUCT -->|GPS coordinates| S2[location]
7978
STRUCT -->|Color picker| S3[color]
8079
STRUCT -->|Arbitrary JSON| S4[json]
81-
STRUCT -->|Sensitive data| S5[encrypted]
80+
STRUCT -->|Sensitive secret value| S5[secret]
8281
8382
%% AI branch
84-
AI -->|Vector embedding| A1[vector]
85-
AI -->|Text embedding| A2[embedding]
83+
AI -->|Vector embedding for semantic search| A1[vector]
8684
8785
style START fill:#4f46e5,color:#fff
8886
style T1 fill:#059669,color:#fff
@@ -94,10 +92,10 @@ flowchart TD
9492
style T7 fill:#059669,color:#fff
9593
style T8 fill:#059669,color:#fff
9694
style N1 fill:#d97706,color:#fff
97-
style N2 fill:#d97706,color:#fff
9895
style N3 fill:#d97706,color:#fff
9996
style N4 fill:#d97706,color:#fff
10097
style N5 fill:#d97706,color:#fff
98+
style N6 fill:#d97706,color:#fff
10199
style D1 fill:#7c3aed,color:#fff
102100
style D2 fill:#7c3aed,color:#fff
103101
style D3 fill:#7c3aed,color:#fff
@@ -110,7 +108,6 @@ flowchart TD
110108
style R1 fill:#0284c7,color:#fff
111109
style R2 fill:#0284c7,color:#fff
112110
style R3 fill:#0284c7,color:#fff
113-
style R4 fill:#0284c7,color:#fff
114111
style F1 fill:#be185d,color:#fff
115112
style F2 fill:#be185d,color:#fff
116113
style F3 fill:#be185d,color:#fff
@@ -123,7 +120,6 @@ flowchart TD
123120
style S4 fill:#0d9488,color:#fff
124121
style S5 fill:#0d9488,color:#fff
125122
style A1 fill:#6d28d9,color:#fff
126-
style A2 fill:#6d28d9,color:#fff
127123
```
128124

129125
---
@@ -141,17 +137,18 @@ flowchart TD
141137
| `email` | Email address with validation | `email`, `contact_email` |
142138
| `url` | Web URL with validation | `website`, `linkedin_url` |
143139
| `phone` | Phone number | `phone`, `mobile` |
144-
| `password` | Secret/masked value (stored encrypted) | `api_key`, `secret` |
140+
| `password` | One-way hashed credential (owned by auth subsystem) | `user_password` |
141+
| `secret` | Reversible encrypted-at-rest value, masked on read | `api_key`, `db_password` |
145142

146143
### Number Types
147144

148145
| Type | Use When | Example |
149146
|:---|:---|:---|
150-
| `number` | Any decimal number | `price`, `weight`, `score` |
151-
| `integer` | Whole numbers only | `quantity`, `age`, `count` |
147+
| `number` | Any numeric value (set `precision`/`scale` for decimals) | `price`, `weight`, `quantity` |
152148
| `currency` | Money amounts with currency code | `amount`, `total_price` |
153149
| `percent` | Percentage values (0–100 or 0–1) | `completion`, `discount` |
154150
| `rating` | Star ratings (typically 1–5) | `satisfaction`, `difficulty` |
151+
| `slider` | Numeric value via slider UI | `volume`, `priority_level` |
155152

156153
### Date & Time Types
157154

@@ -179,7 +176,6 @@ flowchart TD
179176
| `lookup` | Reference another object (soft link) | `assigned_to → user` |
180177
| `master_detail` | Parent-child with cascade delete | `line_item → order` |
181178
| `tree` | Self-referencing hierarchy | `category → category` |
182-
| `polymorphic` | Reference multiple object types | `related_to → task\|project\|user` |
183179

184180
<Callout type="tip">
185181
**lookup vs master_detail:** Use `lookup` when the child can exist independently. Use `master_detail` when deleting the parent should delete all children (e.g., order → line items).
@@ -189,16 +185,16 @@ flowchart TD
189185

190186
| Type | Use When | Example |
191187
|:---|:---|:---|
192-
| `file` | Any single file upload | `contract`, `resume` |
193-
| `image` | Image with preview/thumbnail | `avatar`, `product_photo` |
194-
| `attachment` | Multiple file uploads | `documents`, `screenshots` |
188+
| `file` | File upload (set `multiple: true` for many files) | `contract`, `documents` |
189+
| `image` | Image with preview/thumbnail | `product_photo`, `screenshots` |
190+
| `avatar` | User profile picture | `avatar`, `profile_photo` |
195191

196192
### Computed Types
197193

198194
| Type | Use When | Example |
199195
|:---|:---|:---|
200196
| `formula` | Value calculated from other fields | `full_name = first + last` |
201-
| `rollup` | Aggregate from child records | `total_amount = SUM(items.price)` |
197+
| `summary` | Roll-up aggregate from child records | `total_amount = sum(items.price)` |
202198
| `autonumber` | Auto-incrementing display ID | `ticket_number: TICK-0001` |
203199

204200
### Structured Data Types
@@ -209,14 +205,13 @@ flowchart TD
209205
| `location` | GPS coordinates (lat/lng) | `office_location`, `delivery_point` |
210206
| `color` | Hex color value with picker | `brand_color`, `label_color` |
211207
| `json` | Arbitrary structured data | `configuration`, `metadata` |
212-
| `encrypted` | Sensitive data at rest | `ssn`, `tax_id` |
208+
| `code` | Code editor (JSON/SQL/JS) | `query_body`, `transform` |
213209

214210
### AI & ML Types
215211

216212
| Type | Use When | Example |
217213
|:---|:---|:---|
218-
| `vector` | High-dimensional vector for similarity search | `content_embedding` |
219-
| `embedding` | Text embedding for semantic search | `description_embedding` |
214+
| `vector` | High-dimensional embedding for similarity search (semantic search, RAG) | `content_embedding` |
220215

221216
---
222217

@@ -235,28 +230,28 @@ Can't find your use case above? Check this table:
235230
| Feature flags | `json` | Arbitrary key-value configuration |
236231
| User avatar | `image` | Single image with thumbnail support |
237232
| Support ticket ID | `autonumber` | Auto-incrementing human-readable identifier |
238-
| Total order value | `rollup` | SUM of child line item amounts |
233+
| Total order value | `summary` | Roll-up sum of child line item amounts |
239234
| Discount percentage | `percent` | 0–100 range with `%` display |
240235
| Terms accepted | `boolean` | Simple true/false, no UI toggle needed |
241236
| Search index | `vector` | Used for AI similarity search |
242-
| OAuth token | `encrypted` | Sensitive data stored encrypted at rest |
237+
| OAuth token | `secret` | Reversible value stored encrypted at rest |
243238

244239
---
245240

246241
## Decision Summary by Question
247242

248243
| Question | Answer → Field Type |
249244
|:---|:---|
250-
| "Can the user type free text?" | `text`, `textarea`, `richtext`, `markdown` |
251-
| "Is it a number I need to calculate with?" | `number`, `integer`, `currency`, `percent` |
245+
| "Can the user type free text?" | `text`, `textarea`, `richtext`, `markdown`, `html` |
246+
| "Is it a number I need to calculate with?" | `number`, `currency`, `percent`, `slider` |
252247
| "Does the user pick from a list?" | `select`, `multiselect`, `radio`, `checkboxes` |
253-
| "Does it reference another record?" | `lookup`, `master_detail`, `tree`, `polymorphic` |
254-
| "Is it a file the user uploads?" | `file`, `image`, `attachment` |
255-
| "Is the value computed automatically?" | `formula`, `rollup`, `autonumber` |
256-
| "Does it have internal structure?" | `address`, `location`, `color`, `json` |
257-
| "Is it sensitive/secret?" | `password`, `encrypted` |
258-
| "Is it for AI/ML?" | `vector`, `embedding` |
248+
| "Does it reference another record?" | `lookup`, `master_detail`, `tree` |
249+
| "Is it a file the user uploads?" | `file`, `image`, `avatar` |
250+
| "Is the value computed automatically?" | `formula`, `summary`, `autonumber` |
251+
| "Does it have internal structure?" | `address`, `location`, `color`, `json`, `code` |
252+
| "Is it sensitive/secret?" | `password`, `secret` |
253+
| "Is it for AI/ML?" | `vector` |
259254

260255
<Callout type="info">
261-
**Still unsure?** Start with `text` for strings or `number` for numerics. You can always change the field type later ObjectStack handles data migration automatically for compatible type changes.
256+
**Still unsure?** Start with `text` for strings or `number` for numerics. You can change the field type later, but ObjectStack does not auto-convert existing data: compatible changes pass cleanly, while narrowing or incompatible changes surface a build-time warning that existing values may not convert cleanly.
262257
</Callout>

0 commit comments

Comments
 (0)