Repository navigation
Commit 863c580
docs(objectql,spec): the tenant column is stamped and never NULL on single-tenant stacks (C1) (#25135)
This PR carries **item C1 only** of #25128. Item B6 (narrowing the
blanket pre-18 relax rigs) moved to #25132 under the claim's split;
#25132 is not addressed here.
Fixes #25128
Clause-②: no (comment and docblock text only: no accept set, response,
status, error, outcome or export moves)
Metadata-protocol: none
## What changes
Since 7b-0 (#24940, merged as `5e9b100743`), a table the driver creates
carries its tenant column (`organization_id`) NOT NULL, and an insert is
stamped (under `single` with the Default Organization). Three comments
still said the column stays NULL on single-tenant stacks. Each now uses
the wording 7b-0 used for the two sites it corrected
(`applySystemFields`' docblock in `registry.ts` and
`SystemFieldName.ORGANIZATION_ID` in `system-names.ts`): org-scoping
stamps it on insert (under `single` with the Default Organization), and
it is never NULL (ADR-0131 D1). Each comment keeps the rest of what it
said; in particular the INDEX is still gated on multi-tenant mode.
| File | Site | +/- |
|---|---|---|
| `packages/objectql/src/registry.ts` | the comment at the
`organization_id` gate in `applySystemFields` ("it just stays NULL when
no tenant context exists") | +3 / -2 |
| `packages/objectql/src/registry-tenant-index-declaration.test.ts` |
the comment above `expect(def.fields.organization_id).toBeDefined()`
("it just stays NULL") | +2 / -1 |
| `packages/spec/src/data/object.zod.ts` | the `organization_id` bullet
of the `systemFields` docblock ("It stays NULL on single-tenant
stacks"). The multi-tenant attribution to `@objectstack/organizations`
(the `org-scoping` service) is kept | +4 / -3 |
| `.changeset/25128-tenant-column-never-null-comments.md` | `patch` for
`@objectstack/spec` | +10 |
No code, assertion, `.describe()` text or CHANGELOG changes.
**Cross-lane:** `packages/spec/src/data/object.zod.ts` is a
`domain:spec` file. The seat declares it to the spec seat.
## What `main` does (read before editing)
- **NOT NULL:** driver-sql `createColumn` takes a `tenantColumn`
argument, and `if (declaresColumnNotNull(field) || tenantColumn)` makes
the column not-nullable on both exits. Only the CREATE TABLE sites pass
it (`initObjects`' create branch, `ensureShardTable`). The driver-turso
remote face's `buildCreateTableSQL` does the same. Pinned by
`sql-driver-tenant-column-not-null.test.ts` and
`turso-remote-tenant-column-not-null.test.ts`.
- **The stamp under `single`:**
`ObjectQL.resolveSystemInsertOrganization`
(`packages/objectql/src/engine.ts`) runs after the beforeInsert hooks.
For a system insert that carries no organization, it calls
`resolveSystemWriteOrganization`
(`packages/core/src/security/system-write-organization.ts`), which
answers `derived` when exactly one organization exists under `single`
(the Default Organization). The engine threads that id as
`DriverOptions.tenantId`, and the driver stamps the column with it. The
comment's own block says "stamped with the derived organization or
refused below — never left NULL". A session write carries its
organization on the context.
- **Generator:** nothing committed is generated from the `systemFields`
docblock. `build-docs.ts` renders from `json-schema/` (built from
`.describe()`) plus each module's file-level header
(`renderFileDescription`), never a property docblock. A repo-wide `git
grep` of the docblock's text hits only `object.zod.ts`. After `pnpm
--filter @objectstack/spec build`, `git status` is clean and
`check:generated` reports all 14 artifacts up to date. The text does
ship, through the built `dist/` and `src/**/*.zod.ts` in spec's
`files[]`, so `@objectstack/spec` takes a `patch` changeset. objectql's
`files[]` is `dist` only: after a build, `dist/` holds
`applySystemFields` (positive control) and none of the comment text.
- **Census** (`git grep -i` for "stays NULL", "NULL on single-tenant",
"stays null", "remains NULL" and "left NULL", plus a single-tenant/NULL
regexp, over `packages/objectql` and `packages/spec`): only these three
tenant-column sites. The other hits are unrelated (`owner_id` "when left
NULL", nullable booleans, aggregates, `notNull`). Outside the fence, one
hand-written page has the same stale sentence. It is named under
Acceptance notes and not edited.
## Verification
All on head `ca06c671d`, which includes the merge of `origin/main`
`1b3b65e64`, unless marked otherwise.
- `pnpm exec turbo run build --concurrency=2` (under the verify lock):
77/77 tasks, VERDICT command-exit 0.
- `pnpm --filter @objectstack/objectql typecheck`: exit 0 (tsc and
check:test-typecheck OK).
- `pnpm --filter @objectstack/spec typecheck`: exit 0 (tsc,
scripts-typecheck and check:test-typecheck OK).
- `pnpm --filter @objectstack/objectql exec vitest run --maxWorkers=2
src/registry-tenant-index-declaration.test.ts`: 1 file, 12/12 tests
passed.
- `pnpm --filter @objectstack/spec check:generated`: exit 0, all 14
generated artifacts up to date, and the build left no tracked change.
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`, with no paths: 94 commands derived and 94
run, every exit code captured before any pipe. All 94 exited 0. `--ran`
reconciliation: "94 derived famil(ies) accounted for — 94 run, 0
NOT-MEASURED (a DERIVED zero — all 94 recorded an exit code and none of
them is 3)", exit 0.
- On the pre-merge head `3c3a5759b`, the same derivation ran 94 commands
(86, plus 8 once the changeset existed). All exited 0 except `pnpm
check:dual-build-cjs-loads`, which exited 3 (PREREQUISITE NOT MET: no
`dist/`). After the full build it ran again and exited 0.
- Not measured locally (CI's): the path-scheduled CI jobs and type-check
lanes the derivation names, Test Core shards, and `test:repo`.
- No ablation, because no tested behaviour changes.
## Acceptance notes
- `content/docs/protocol/objectql/schema.mdx` (section "Multi-Tenant
Schemas") still says the injected `organization_id` "stays NULL where no
organization context exists". It is a hand-written docs page outside
this card's file surface, so it is named here and not edited. Carrier:
none.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Xwr1aPkHuFRqE9RSahyogV)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 1b3b65e commit 863c580
4 files changed
Lines changed: 19 additions & 6 deletions
File tree
- .changeset
- packages
- objectql/src
- spec/src/data
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
149 | 149 | | |
150 | 150 | | |
151 | 151 | | |
152 | | - | |
| 152 | + | |
| 153 | + | |
153 | 154 | | |
154 | 155 | | |
155 | 156 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
774 | 774 | | |
775 | 775 | | |
776 | 776 | | |
777 | | - | |
778 | | - | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
779 | 780 | | |
780 | 781 | | |
781 | 782 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2496 | 2496 | | |
2497 | 2497 | | |
2498 | 2498 | | |
2499 | | - | |
2500 | | - | |
2501 | | - | |
| 2499 | + | |
| 2500 | + | |
| 2501 | + | |
| 2502 | + | |
2502 | 2503 | | |
2503 | 2504 | | |
2504 | 2505 | | |
| |||
0 commit comments