fix(objectql): stamp tenant org-key onto un-pinned business seed rows#2376
Merged
Conversation
…rows A published seed loaded in-process (the AI build agent's publish path) has no active user session, so `config.organizationId` is unset and the SQL driver's per-write org injection never fires — business seed rows land with `organization_id = NULL`. Under strict org-scoping the data API filters with `WHERE organization_id = <activeOrg>` (a NULL row matches nobody), so every list / kanban / read of the freshly-built app comes back empty even though the rows physically exist. (Metadata + dashboard datasets read via a system, non-org-scoped path, so the app shell and dashboard counts render — only the business data vanishes, which reads as "I built it and it's empty".) Fix: when no org is pinned, the SeedLoader resolves the tenant's SOLE organization and stamps BUSINESS seed rows with it — the same tenant key a normal create injects from the session. `sys_`/`cloud_`/`ai_` platform seeds never take the fallback (they stay intentionally global/cross-tenant); zero or several orgs leave rows org-less (genuinely ambiguous → unchanged behavior); an explicitly pinned `organizationId` still wins for every object. Also makes `os.org.id` resolvable in seed CEL on the un-pinned path (the fallback flows into the seed identity's `org`). Tests: src/seed-loader-org-fallback.test.ts — sole-org stamp, sys_ skip, ambiguous/no-org no-op, explicit-org precedence. Existing seed-loader + protocol suites green (no regression). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 14 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
An AI-built app lands empty in every list / kanban even though the seeded rows physically exist in the tenant DB.
Root cause (confirmed live on a built app): a published seed loaded in-process (the build agent's publish path) has no active user session, so
config.organizationIdis unset and the SQL driver's per-write org injection never fires → business seed rows persist withorganization_id = NULL. Under strict org-scoping the data API filtersWHERE organization_id = <activeOrg>and a NULL row matches nobody, so reads come backtotal:0.Metadata + dashboard datasets read via a system (non-org-scoped) path, so the app shell, views and dashboard counts render — only the business data is invisible. That's the "I built it and it's empty" footgun. (Single-org today it's only latent; the moment the env gains a second org / stricter scope the data disappears — an existing env is the live sample.)
Live evidence
On a freshly-built env, raw table had 12 work orders, all
organization_id = NULL;/api/v1/data/...returnedtotal:0. Stamping one row with the env's org made it (and only it) appear; stamping all 12 made the lists + kanban populate.Fix
When no org is pinned,
SeedLoaderServiceresolves the tenant's sole organization and stamps business seed rows with it — the tenant key a normal create would inject.sys_/cloud_/ai_platform seeds never take the fallback (stay global/cross-tenant).organizationIdstill wins, for every object (unchanged).os.org.idnow resolves in seed CEL on the un-pinned path.Tests
src/seed-loader-org-fallback.test.ts(5): sole-org stamp ·sys_skip · ambiguous no-op · no-org no-op · explicit-org precedence. Existing seed-loader + protocol suites green (12 → no regression).@objectstack/objectqlbuilds clean (DTS incl. deps).🤖 Generated with Claude Code