Skip to content

multi-org: sys_upload_session is never org-stamped either — StorageMetadataStore.createSession inserts without a context #12928

Description

@os-litant

Found while implementing the #12745 ruling (sys_file forward stamping + backfill). ⛔ Deliberately NOT fixed there: the maintainer ruling that authorises the sys_file work is scoped to sys_file alone, and the backfill precedent (plugin-approvals/src/backfill-platform-row-organizations.ts) requires a maintainer order per table. This card records the sibling so the asymmetry is visible rather than discovered later.

⛔ Not graded, not routed — recorded only.

Measured, on origin/main at aef1b7e64

1. Same "tenancy-enabled, never written" shape as #12745.packages/services/service-storage/src/objects/system-upload-session.object.ts declares no tenancy key at all:

grep -n "tenancy" packages/services/service-storage/src/objects/system-upload-session.object.ts # exit 1, no match

so isTenancyDisabled() reads false and applySystemFields provisions organization_id on the object exactly as it does for sys_file.

2. The insert carries no context.packages/services/service-storage/src/metadata-store.ts:349:

awaitthis.engineOp('sys_upload_session','insert',SESSION_INSERT_CONSEQUENCE,(engine)=>engine.insert('sys_upload_session',full),);

No third argument, so the SQL driver's injectTenantOnInsert has no options.tenantId to stamp from and the column stays NULL — the same mechanism #12745 measured on sys_file.

3. The caller holds the session.storage-routes.ts's chunked-upload door calls requireUploadSession(...) and then store.createSession({...}) in the same handler that now threads the organization into store.createFile(...). The value is in hand at the call site; only the createSession signature has nowhere to put it.

What is different from #12745, and why that may change the answer

⚠️ These are NOT the same card, and the difference runs toward "maybe leave it":

  • Lifetime.sys_upload_session rows are transient — the object declares a retention/TTL sweep and rows are reaped after a session completes, fails or expires. sys_file is mostly-permanent business truth with compliance value. A read-visibility split on a table that reaps itself is a different cost from one on a table that grows with every upload.
  • Backfill. If the forward stamp is ruled in, whether a backfill is owed at all is a separate question here for the same reason: the existing NULL population ages out on its own, where sys_file's does not.
  • Subject. A sys_upload_session row names a file_id, so its organization could be derived from the sys_file row it belongs to. That derivation only exists AFTER multi-org: sys_file is never org-stamped — StorageMetadataStore.createFile inserts without a context while both callers hold the session #12745's work lands, which is another reason this could not have been folded in.

Not established here

Re-check

grep -c "tenancy" packages/services/service-storage/src/objects/system-upload-session.object.ts
grep -n "engine.insert('sys_upload_session'" packages/services/service-storage/src/metadata-store.ts

Dedup

Searched the storage + org-scoping family. #12745 is the sys_file sibling and is being implemented, not duplicated by this. #7667 (failed/expired status producers) and #5202 (audit rows per chunk) touch the same table on unrelated concerns. No match.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions