diff --git a/.changeset/25128-tenant-column-never-null-comments.md b/.changeset/25128-tenant-column-never-null-comments.md new file mode 100644 index 00000000000..0aad4fd92c9 --- /dev/null +++ b/.changeset/25128-tenant-column-never-null-comments.md @@ -0,0 +1,10 @@ +--- +'@objectstack/spec': patch +--- + +docs(spec): the `systemFields` docblock no longer says `organization_id` stays NULL on single-tenant stacks + +Clause-②: no (comment and docblock text only: no accept set, response, status, error, outcome or export moves) +Metadata-protocol: none + +The `organization_id` bullet of `ObjectSchema`'s `systemFields` docblock now says what the runtime does: org-scoping stamps the tenant column on insert (under `single` with the Default Organization), and it is never NULL (ADR-0131 D1). Only the column's index is still gated on multi-tenant mode. No schema, `.describe()` text or behavior changes. diff --git a/packages/objectql/src/registry-tenant-index-declaration.test.ts b/packages/objectql/src/registry-tenant-index-declaration.test.ts index 8ac0acf0584..08eab1551ad 100644 --- a/packages/objectql/src/registry-tenant-index-declaration.test.ts +++ b/packages/objectql/src/registry-tenant-index-declaration.test.ts @@ -149,7 +149,8 @@ describe('#6810 — a registry-backed object reads back valid at both /meta exit expect(tenantIndexes(def)).toEqual([]); // And the COLUMN is still provisioned either way — that decoupling is // older than this fix and must survive it (sudo writers stamp the column - // on single-tenant stacks; it just stays NULL). + // on single-tenant stacks; org-scoping stamps it on insert under `single` + // with the Default Organization, and it is never NULL, ADR-0131 D1). expect(def.fields.organization_id).toBeDefined(); }); diff --git a/packages/objectql/src/registry.ts b/packages/objectql/src/registry.ts index ac37fff7fff..c45b8ab4945 100644 --- a/packages/objectql/src/registry.ts +++ b/packages/objectql/src/registry.ts @@ -774,8 +774,9 @@ export function applySystemFields( // global multi-tenant flag. Decoupling "does the column exist" from "is // tenancy enabled" is what stops sudo writers (audit / messaging / inbox / // outbox …) from failing with "no column named organization_id" on - // single-tenant stacks: they can always stamp the column, it just stays NULL - // when no tenant context exists. The multi-tenant flag now governs only + // single-tenant stacks: they can always stamp the column, and org-scoping + // stamps it on insert (under `single` with the Default Organization), so it + // is never NULL (ADR-0131 D1). The multi-tenant flag now governs only // whether the column is INDEXED — on a single-tenant DB nothing ever filters // by organization, so the index would be dead weight. That is also why the // plan takes no `multiTenant` input: the flag cannot change what EXISTS, only diff --git a/packages/spec/src/data/object.zod.ts b/packages/spec/src/data/object.zod.ts index 01a03df6aea..a80dcd22824 100644 --- a/packages/spec/src/data/object.zod.ts +++ b/packages/spec/src/data/object.zod.ts @@ -2496,9 +2496,10 @@ const ObjectSchemaBase = strictObject( * * - `organization_id` — `lookup → sys_organization`. The COLUMN is * provisioned unconditionally (subject to the opt-outs below); only its - * DB index is gated on multi-tenant mode. It stays NULL on single-tenant - * stacks and is auto-stamped on insert by `@objectstack/organizations` - * (the `org-scoping` service) in multi-tenant mode. + * DB index is gated on multi-tenant mode. Org-scoping stamps it on + * insert (`@objectstack/organizations`, the `org-scoping` service, in + * multi-tenant mode; under `single` with the Default Organization), and + * it is never NULL (ADR-0131 D1). * - Audit columns — `created_at`, `created_by`, `updated_at`, `updated_by` * (`readonly` + `system`). Gated by `audit` below. * - `owner_id` — `lookup → sys_user`, auto-provisioned on user-authored