Refactor multi-tenant architecture to per-environment database isolation#1186
Merged
xuyushun441-sys merged 2 commits intomainfrom Apr 19, 2026
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…v5 migration skeleton Agent-Logs-Url: https://github.com/objectstack-ai/framework/sessions/52606e79-56bc-48cb-8a2a-da808a53104d Co-authored-by: xuyushun441-sys <255036401+xuyushun441-sys@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Refactor multi-tenant architecture to per-environment databases
Refactor multi-tenant architecture to per-environment database isolation
Apr 19, 2026
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.
The v3.4/v4.0 tenant model provisions one DB per organization and separates environments via an
env_idcolumn. This couples schema evolution across dev/test/prod, makes backup/DR and solution publishing fragile, and leaves a single missingWHERE env_idpredicate away from cross-environment data corruption. Turso/libSQL/Neon/D1 have made per-environment databases essentially free, so the isolation boundary should be physical, not logical.This PR lands the v4.1 protocol + service foundation for per-environment database isolation, with a hard Control Plane ↔ Data Plane split, a v4.x deprecation shim, and a v5.0 migration path. See
docs/adr/0002-environment-database-isolation.mdfor the full rationale.Protocol (
packages/spec/src/cloud/environment.zod.ts)Environment,EnvironmentDatabase(1:1 with environment),DatabaseCredential(rotatable,active/rotating/revoked),EnvironmentMember(owner/admin/maker/reader/guest), plusEnvironmentType/Status/Roleenums andProvisionEnvironment*/ProvisionOrganization*request-response schemas.TenantDatabaseSchematagged@deprecatedwith a pointer to the migration.Control-plane objects (
packages/services/service-tenant/src/objects/)sys_environment— UNIQUE(organization_id, slug), enforces one default env per org.sys_environment_database— UNIQUEenvironment_id, exactly one physical DB per environment.sys_database_credential— N:1 with the DB mapping; supports rotation without touching addressing.sys_environment_member— UNIQUE(environment_id, user_id); per-environment RBAC.sys_-prefixed, every field.describe()-annotated, every uniqueness constraint explicit.Service (
packages/services/service-tenant/src/environment-provisioning.ts)EnvironmentProvisioningServicewithprovisionOrganization(),provisionEnvironment(),rotateCredential().EnvironmentDatabaseAdapterkeyed by driver (tursoshipped;libsql/sqlite/postgresplug in without core changes) and pluggableSecretEncryptorfor KMS integration.Compatibility & migration
createTenantPlugin()registers the four new objects out of the box;sys_tenant_databasestays registered as a v4.x shim (opt out viaregisterLegacyTenantDatabase: false) and is scheduled for removal in v5.0.packages/services/service-tenant/migrations/v4-to-v5-env-migration.ts— idempotent, non-destructive: reuses each org's existing physical DB as its newprodenvironment DB (no data movement), re-encrypts the legacy auth token with the current KMS key, archives the legacy row.Field.picklist→Field.selectbug in the legacysys_tenant_database/sys_package_installationobject defs that would have crashed plugin init once exercised.Tests
postgresadapter), encryption hook, credential rotation, and object-definition invariants (sys_naming, UNIQUE indexes,.describe()coverage).Follow-ups (out of scope for this PR)
active_environment_idintegration.sys_quota; solution publishing on env DBs viasys_solution_history.