+- **Auto-injected `organization_id` system field on every user object** (`@objectstack/objectql`, `@objectstack/spec`, `@objectstack/plugin-security`) — `SchemaRegistry.registerObject()` now runs `applySystemFields(schema, { multiTenant })` before storing the contributor, splicing in an `organization_id` field (`lookup → sys_organization`, `hidden`/`readonly`/`indexed`) on every registered object that (a) doesn't already declare one and (b) isn't `managedBy: 'better-auth' | 'system' | 'platform'` and (c) hasn't opted out via the new `systemFields: false | { tenant?: false; owner?: false; audit?: false }` field on `ObjectSchema`. The registry honours `OS_MULTI_TENANT` (default `true`) the same way `SecurityPlugin` and the CLI startup banner do, so single-tenant deployments incur zero registration-time cost. Author-declared `organization_id` always wins (no overwrite). Combined with the existing SecurityPlugin auto-fill on insert and the `tenant_isolation` RLS policy, this means: out of the box, every CRM/business object built on ObjectStack is multi-tenant — schema authors no longer have to remember to declare `organization_id` per-object, and the long-standing footgun of "I just inserted a row but it's not visible because organization_id is NULL" is gone. Verified end-to-end with `pnpm dev:crm`: fresh DB → sign up → create org → `POST /api/v1/data/lead` → `organization_id` populated from `session.activeOrganizationId`; switch to a 2nd org → leads created there carry the 2nd org's id. Tests: 7 new cases in `registry.test.ts` covering injection, opt-out (`systemFields: false`), per-key opt-out (`systemFields: { tenant: false }`), `multiTenant: false`, manageBy skip, author-declared override.
0 commit comments