mirror of
https://github.com/nocodb/nocodb.git
synced 2026-02-01 23:48:33 +00:00
refactor: sandbox to managed app backend
This commit is contained in:
@@ -370,12 +370,12 @@ export enum BaseVersion {
|
||||
V3 = 3,
|
||||
}
|
||||
|
||||
export enum SandboxVersionStatus {
|
||||
export enum ManagedAppVersionStatus {
|
||||
DRAFT = 'draft',
|
||||
PUBLISHED = 'published',
|
||||
}
|
||||
|
||||
export enum SandboxVisibility {
|
||||
export enum ManagedAppVisibility {
|
||||
PUBLIC = 'public',
|
||||
PRIVATE = 'private',
|
||||
UNLISTED = 'unlisted',
|
||||
|
||||
@@ -125,21 +125,21 @@ export const OPERATION_SCOPES = {
|
||||
extensionUpdate: 'base',
|
||||
extensionDelete: 'base',
|
||||
|
||||
// Sandbox Operations
|
||||
sandboxStoreList: 'org',
|
||||
sandboxList: 'workspace',
|
||||
sandboxGet: 'org',
|
||||
sandboxCreate: 'workspace',
|
||||
sandboxUpdate: 'base',
|
||||
sandboxDelete: 'base',
|
||||
sandboxPublish: 'base',
|
||||
sandboxCreateDraft: 'base',
|
||||
sandboxUnpublish: 'base',
|
||||
sandboxInstall: 'workspace',
|
||||
sandboxGetUpdates: 'base',
|
||||
sandboxVersionsList: 'base',
|
||||
sandboxInstallationsList: 'base',
|
||||
sandboxDeployments: 'base',
|
||||
sandboxVersionDeployments: 'base',
|
||||
sandboxDeploymentLogs: 'base',
|
||||
// Managed App Operations
|
||||
managedAppStoreList: 'org',
|
||||
managedAppList: 'workspace',
|
||||
managedAppGet: 'org',
|
||||
managedAppCreate: 'workspace',
|
||||
managedAppUpdate: 'base',
|
||||
managedAppDelete: 'base',
|
||||
managedAppPublish: 'base',
|
||||
managedAppCreateDraft: 'base',
|
||||
managedAppUnpublish: 'base',
|
||||
managedAppInstall: 'workspace',
|
||||
managedAppGetUpdates: 'base',
|
||||
managedAppVersionsList: 'base',
|
||||
managedAppInstallationsList: 'base',
|
||||
managedAppDeployments: 'base',
|
||||
managedAppVersionDeployments: 'base',
|
||||
managedAppDeploymentLogs: 'base',
|
||||
} as const;
|
||||
|
||||
@@ -138,7 +138,7 @@ export class NcErrorV1 extends NcErrorBase {
|
||||
schemaLocked(message?: string): never {
|
||||
return this.forbidden(
|
||||
message ||
|
||||
'Schema modifications are not allowed on installed sandbox bases',
|
||||
'Schema modifications are not allowed on managed apps',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,9 +131,9 @@ export class MetaService {
|
||||
[MetaTable.INSTALLATIONS]: 'inst',
|
||||
[MetaTable.AUTOMATIONS]: 'aut',
|
||||
[MetaTable.AUTOMATION_EXECUTIONS]: 'auex',
|
||||
[MetaTable.SANDBOXES]: 'sb',
|
||||
[MetaTable.SANDBOX_VERSIONS]: 'sbv',
|
||||
[MetaTable.SANDBOX_DEPLOYMENT_LOGS]: 'sbdl',
|
||||
[MetaTable.MANAGED_APPS]: 'ma',
|
||||
[MetaTable.MANAGED_APP_VERSIONS]: 'mav',
|
||||
[MetaTable.MANAGED_APP_DEPLOYMENT_LOGS]: 'madl',
|
||||
};
|
||||
|
||||
const prefix = prefixMap[target] || 'nc';
|
||||
|
||||
@@ -12,6 +12,7 @@ import * as nc_011_merge_workflows_scripts from './v0/nc_011_merge_workflows_scr
|
||||
import * as nc_012_workflow_delay from './v0/nc_012_workflow_delay';
|
||||
import * as nc_013_composite_pk_missing_tables from './v0/nc_013_composite_pk_missing_tables';
|
||||
import * as nc_014_sandboxes from './v0/nc_014_sandboxes';
|
||||
import * as nc_015_managed_apps from './v0/nc_015_managed_apps';
|
||||
|
||||
// Create a custom migration source class
|
||||
export default class XcMigrationSourcev0 {
|
||||
@@ -35,6 +36,7 @@ export default class XcMigrationSourcev0 {
|
||||
'nc_012_workflow_delay',
|
||||
'nc_013_composite_pk_missing_tables',
|
||||
'nc_014_sandboxes',
|
||||
'nc_015_managed_apps',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -72,6 +74,8 @@ export default class XcMigrationSourcev0 {
|
||||
return nc_013_composite_pk_missing_tables;
|
||||
case 'nc_014_sandboxes':
|
||||
return nc_014_sandboxes;
|
||||
case 'nc_015_managed_apps':
|
||||
return nc_015_managed_apps;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
262
packages/nocodb/src/meta/migrations/v0/nc_015_managed_apps.ts
Normal file
262
packages/nocodb/src/meta/migrations/v0/nc_015_managed_apps.ts
Normal file
@@ -0,0 +1,262 @@
|
||||
import type { Knex } from 'knex';
|
||||
import { MetaTable } from '~/utils/globals';
|
||||
|
||||
const up = async (knex: Knex) => {
|
||||
// Rename sandboxes table to managed_apps
|
||||
await knex.schema.renameTable(
|
||||
MetaTable.SANDBOXES_OLD,
|
||||
MetaTable.MANAGED_APPS,
|
||||
);
|
||||
|
||||
// Rename sandbox_versions table to managed_app_versions
|
||||
await knex.schema.renameTable(
|
||||
MetaTable.SANDBOX_VERSIONS_OLD,
|
||||
MetaTable.MANAGED_APP_VERSIONS,
|
||||
);
|
||||
|
||||
// Rename sandbox_deployment_logs table to managed_app_deployment_logs
|
||||
await knex.schema.renameTable(
|
||||
MetaTable.SANDBOX_DEPLOYMENT_LOGS_OLD,
|
||||
MetaTable.MANAGED_APP_DEPLOYMENT_LOGS,
|
||||
);
|
||||
|
||||
// Rename columns in managed_app_versions table (formerly sandbox_versions)
|
||||
await knex.schema.alterTable(MetaTable.MANAGED_APP_VERSIONS, (table) => {
|
||||
table.renameColumn('fk_sandbox_id', 'fk_managed_app_id');
|
||||
});
|
||||
|
||||
// Rename indexes in managed_app_versions table
|
||||
// Note: Index renaming varies by database. We'll drop and recreate them.
|
||||
await knex.schema.alterTable(MetaTable.MANAGED_APP_VERSIONS, (table) => {
|
||||
// Drop old indexes
|
||||
table.dropUnique(
|
||||
['fk_sandbox_id', 'version'],
|
||||
'nc_sandbox_versions_unique_idx',
|
||||
);
|
||||
table.dropUnique(
|
||||
['fk_sandbox_id', 'version_number'],
|
||||
'nc_sandbox_versions_number_unique_idx',
|
||||
);
|
||||
table.dropIndex(['fk_sandbox_id'], 'nc_sandbox_versions_sandbox_id_idx');
|
||||
table.dropIndex(
|
||||
['fk_sandbox_id', 'status'],
|
||||
'nc_sandbox_versions_status_idx',
|
||||
);
|
||||
table.dropIndex(
|
||||
['fk_sandbox_id', 'version_number'],
|
||||
'nc_sandbox_versions_ordering_idx',
|
||||
);
|
||||
});
|
||||
|
||||
await knex.schema.alterTable(MetaTable.MANAGED_APP_VERSIONS, (table) => {
|
||||
// Create new indexes with updated names
|
||||
table.unique(['fk_managed_app_id', 'version'], {
|
||||
indexName: 'nc_managed_app_versions_unique_idx',
|
||||
});
|
||||
table.unique(['fk_managed_app_id', 'version_number'], {
|
||||
indexName: 'nc_managed_app_versions_number_unique_idx',
|
||||
});
|
||||
table.index(
|
||||
['fk_managed_app_id'],
|
||||
'nc_managed_app_versions_managed_app_id_idx',
|
||||
);
|
||||
table.index(
|
||||
['fk_managed_app_id', 'status'],
|
||||
'nc_managed_app_versions_status_idx',
|
||||
);
|
||||
table.index(
|
||||
['fk_managed_app_id', 'version_number'],
|
||||
'nc_managed_app_versions_ordering_idx',
|
||||
);
|
||||
});
|
||||
|
||||
// Rename columns in managed_app_deployment_logs table (formerly sandbox_deployment_logs)
|
||||
await knex.schema.alterTable(
|
||||
MetaTable.MANAGED_APP_DEPLOYMENT_LOGS,
|
||||
(table) => {
|
||||
table.renameColumn('fk_sandbox_id', 'fk_managed_app_id');
|
||||
},
|
||||
);
|
||||
|
||||
// Rename indexes in managed_app_deployment_logs table
|
||||
await knex.schema.alterTable(
|
||||
MetaTable.MANAGED_APP_DEPLOYMENT_LOGS,
|
||||
(table) => {
|
||||
// Drop old indexes
|
||||
table.dropIndex(
|
||||
['fk_sandbox_id'],
|
||||
'nc_sandbox_deployment_logs_sandbox_id_idx',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
await knex.schema.alterTable(
|
||||
MetaTable.MANAGED_APP_DEPLOYMENT_LOGS,
|
||||
(table) => {
|
||||
// Create new indexes
|
||||
table.index(
|
||||
['fk_managed_app_id'],
|
||||
'nc_managed_app_deployment_logs_managed_app_id_idx',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
// Rename columns in bases table (PROJECT)
|
||||
await knex.schema.alterTable(MetaTable.PROJECT, (table) => {
|
||||
// Drop old indexes first
|
||||
table.dropIndex(
|
||||
['sandbox_id', 'auto_update'],
|
||||
'nc_bases_sandbox_auto_update_idx',
|
||||
);
|
||||
table.dropIndex(['sandbox_version_id'], 'nc_bases_sandbox_version_id_idx');
|
||||
table.dropIndex(['sandbox_id'], 'nc_bases_sandbox_id_idx');
|
||||
table.dropIndex(['sandbox_master'], 'nc_bases_sandbox_master_idx');
|
||||
});
|
||||
|
||||
await knex.schema.alterTable(MetaTable.PROJECT, (table) => {
|
||||
// Rename columns
|
||||
table.renameColumn('sandbox_master', 'managed_app_master');
|
||||
table.renameColumn('sandbox_id', 'managed_app_id');
|
||||
table.renameColumn('sandbox_version_id', 'managed_app_version_id');
|
||||
});
|
||||
|
||||
await knex.schema.alterTable(MetaTable.PROJECT, (table) => {
|
||||
// Create new indexes
|
||||
table.index(['managed_app_master'], 'nc_bases_managed_app_master_idx');
|
||||
table.index(['managed_app_id'], 'nc_bases_managed_app_id_idx');
|
||||
table.index(
|
||||
['managed_app_version_id'],
|
||||
'nc_bases_managed_app_version_id_idx',
|
||||
);
|
||||
table.index(
|
||||
['managed_app_id', 'auto_update'],
|
||||
'nc_bases_managed_app_auto_update_idx',
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const down = async (knex: Knex) => {
|
||||
// Revert columns in bases table (PROJECT)
|
||||
await knex.schema.alterTable(MetaTable.PROJECT, (table) => {
|
||||
// Drop new indexes
|
||||
table.dropIndex(
|
||||
['managed_app_id', 'auto_update'],
|
||||
'nc_bases_managed_app_auto_update_idx',
|
||||
);
|
||||
table.dropIndex(
|
||||
['managed_app_version_id'],
|
||||
'nc_bases_managed_app_version_id_idx',
|
||||
);
|
||||
table.dropIndex(['managed_app_id'], 'nc_bases_managed_app_id_idx');
|
||||
table.dropIndex(['managed_app_master'], 'nc_bases_managed_app_master_idx');
|
||||
});
|
||||
|
||||
await knex.schema.alterTable(MetaTable.PROJECT, (table) => {
|
||||
// Rename columns back
|
||||
table.renameColumn('managed_app_version_id', 'sandbox_version_id');
|
||||
table.renameColumn('managed_app_id', 'sandbox_id');
|
||||
table.renameColumn('managed_app_master', 'sandbox_master');
|
||||
});
|
||||
|
||||
await knex.schema.alterTable(MetaTable.PROJECT, (table) => {
|
||||
// Recreate old indexes
|
||||
table.index(['sandbox_master'], 'nc_bases_sandbox_master_idx');
|
||||
table.index(['sandbox_id'], 'nc_bases_sandbox_id_idx');
|
||||
table.index(['sandbox_version_id'], 'nc_bases_sandbox_version_id_idx');
|
||||
table.index(
|
||||
['sandbox_id', 'auto_update'],
|
||||
'nc_bases_sandbox_auto_update_idx',
|
||||
);
|
||||
});
|
||||
|
||||
// Revert indexes in managed_app_deployment_logs table
|
||||
await knex.schema.alterTable(
|
||||
MetaTable.MANAGED_APP_DEPLOYMENT_LOGS,
|
||||
(table) => {
|
||||
table.dropIndex(
|
||||
['fk_managed_app_id'],
|
||||
'nc_managed_app_deployment_logs_managed_app_id_idx',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
await knex.schema.alterTable(
|
||||
MetaTable.MANAGED_APP_DEPLOYMENT_LOGS,
|
||||
(table) => {
|
||||
table.index(
|
||||
['fk_sandbox_id'],
|
||||
'nc_sandbox_deployment_logs_sandbox_id_idx',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
// Revert columns in managed_app_deployment_logs table
|
||||
await knex.schema.alterTable(
|
||||
MetaTable.MANAGED_APP_DEPLOYMENT_LOGS,
|
||||
(table) => {
|
||||
table.renameColumn('fk_managed_app_id', 'fk_sandbox_id');
|
||||
},
|
||||
);
|
||||
|
||||
// Revert indexes in managed_app_versions table
|
||||
await knex.schema.alterTable(MetaTable.MANAGED_APP_VERSIONS, (table) => {
|
||||
table.dropIndex(
|
||||
['fk_managed_app_id', 'version_number'],
|
||||
'nc_managed_app_versions_ordering_idx',
|
||||
);
|
||||
table.dropIndex(
|
||||
['fk_managed_app_id', 'status'],
|
||||
'nc_managed_app_versions_status_idx',
|
||||
);
|
||||
table.dropIndex(
|
||||
['fk_managed_app_id'],
|
||||
'nc_managed_app_versions_managed_app_id_idx',
|
||||
);
|
||||
table.dropUnique(
|
||||
['fk_managed_app_id', 'version_number'],
|
||||
'nc_managed_app_versions_number_unique_idx',
|
||||
);
|
||||
table.dropUnique(
|
||||
['fk_managed_app_id', 'version'],
|
||||
'nc_managed_app_versions_unique_idx',
|
||||
);
|
||||
});
|
||||
|
||||
await knex.schema.alterTable(MetaTable.MANAGED_APP_VERSIONS, (table) => {
|
||||
table.unique(['fk_sandbox_id', 'version'], {
|
||||
indexName: 'nc_sandbox_versions_unique_idx',
|
||||
});
|
||||
table.unique(['fk_sandbox_id', 'version_number'], {
|
||||
indexName: 'nc_sandbox_versions_number_unique_idx',
|
||||
});
|
||||
table.index(['fk_sandbox_id'], 'nc_sandbox_versions_sandbox_id_idx');
|
||||
table.index(['fk_sandbox_id', 'status'], 'nc_sandbox_versions_status_idx');
|
||||
table.index(
|
||||
['fk_sandbox_id', 'version_number'],
|
||||
'nc_sandbox_versions_ordering_idx',
|
||||
);
|
||||
});
|
||||
|
||||
// Revert columns in managed_app_versions table
|
||||
await knex.schema.alterTable(MetaTable.MANAGED_APP_VERSIONS, (table) => {
|
||||
table.renameColumn('fk_managed_app_id', 'fk_sandbox_id');
|
||||
});
|
||||
|
||||
// Rename tables back
|
||||
await knex.schema.renameTable(
|
||||
MetaTable.MANAGED_APP_DEPLOYMENT_LOGS,
|
||||
MetaTable.SANDBOX_DEPLOYMENT_LOGS_OLD,
|
||||
);
|
||||
|
||||
await knex.schema.renameTable(
|
||||
MetaTable.MANAGED_APP_VERSIONS,
|
||||
MetaTable.SANDBOX_VERSIONS_OLD,
|
||||
);
|
||||
|
||||
await knex.schema.renameTable(
|
||||
MetaTable.MANAGED_APPS,
|
||||
MetaTable.SANDBOXES_OLD,
|
||||
);
|
||||
};
|
||||
|
||||
export { up, down };
|
||||
@@ -54,12 +54,12 @@ export default class Base implements BaseType {
|
||||
roles?: string;
|
||||
fk_custom_url_id?: string;
|
||||
|
||||
// sandbox props
|
||||
sandbox_master?: boolean; // Is this base a sandbox master?
|
||||
sandbox_id?: string; // Points to SANDBOXES (for both master and installed instances)
|
||||
sandbox_version_id?: string; // Current version ID from SANDBOX_VERSIONS
|
||||
// managed app props
|
||||
managed_app_master?: boolean; // Is this base a managed app master?
|
||||
managed_app_id?: string; // Points to MANAGED_APPS (for both master and installed instances)
|
||||
managed_app_version_id?: string; // Current version ID from MANAGED_APP_VERSIONS
|
||||
auto_update?: boolean; // For installed instances: auto-update to new published versions
|
||||
sandbox_schema_locked?: boolean; // Computed: whether schema modifications are allowed
|
||||
managed_app_schema_locked?: boolean; // Computed: whether schema modifications are allowed
|
||||
|
||||
constructor(base: Partial<Base>) {
|
||||
Object.assign(this, base);
|
||||
@@ -88,9 +88,9 @@ export default class Base implements BaseType {
|
||||
'color',
|
||||
'order',
|
||||
'version',
|
||||
'sandbox_master',
|
||||
'sandbox_id',
|
||||
'sandbox_version_id',
|
||||
'managed_app_master',
|
||||
'managed_app_id',
|
||||
'managed_app_version_id',
|
||||
'auto_update',
|
||||
]);
|
||||
|
||||
@@ -289,9 +289,9 @@ export default class Base implements BaseType {
|
||||
}
|
||||
const base = this.castType(baseData);
|
||||
|
||||
// Compute sandbox_schema_locked
|
||||
if (base && base.sandbox_id) {
|
||||
base.sandbox_schema_locked = await this.computeSchemaLocked(base);
|
||||
// Compute managed_app_schema_locked
|
||||
if (base && base.managed_app_id) {
|
||||
base.managed_app_schema_locked = await this.computeSchemaLocked(base);
|
||||
}
|
||||
|
||||
return base;
|
||||
@@ -370,9 +370,9 @@ export default class Base implements BaseType {
|
||||
if (baseData) {
|
||||
const base = this.castType(baseData);
|
||||
|
||||
// Compute sandbox_schema_locked
|
||||
if (base.sandbox_id) {
|
||||
base.sandbox_schema_locked = await this.computeSchemaLocked(base);
|
||||
// Compute managed_app_schema_locked
|
||||
if (base.managed_app_id) {
|
||||
base.managed_app_schema_locked = await this.computeSchemaLocked(base);
|
||||
}
|
||||
|
||||
await base.getSources(includeConfig, ncMeta);
|
||||
@@ -471,9 +471,9 @@ export default class Base implements BaseType {
|
||||
'password',
|
||||
'roles',
|
||||
'version',
|
||||
'sandbox_master',
|
||||
'sandbox_id',
|
||||
'sandbox_version_id',
|
||||
'managed_app_master',
|
||||
'managed_app_id',
|
||||
'managed_app_version_id',
|
||||
'auto_update',
|
||||
]);
|
||||
|
||||
|
||||
@@ -102,9 +102,12 @@ export enum MetaTable {
|
||||
AUTOMATION_EXECUTIONS = 'nc_automation_executions',
|
||||
DEPENDENCY_TRACKER = 'nc_dependency_tracker',
|
||||
INSTALLATIONS = 'nc_installations',
|
||||
SANDBOXES = 'nc_sandboxes',
|
||||
SANDBOX_VERSIONS = 'nc_sandbox_versions',
|
||||
SANDBOX_DEPLOYMENT_LOGS = 'nc_sandbox_deployment_logs',
|
||||
SANDBOXES_OLD = 'nc_sandboxes',
|
||||
SANDBOX_VERSIONS_OLD = 'nc_sandbox_versions',
|
||||
SANDBOX_DEPLOYMENT_LOGS_OLD = 'nc_sandbox_deployment_logs',
|
||||
MANAGED_APPS = 'nc_managed_apps',
|
||||
MANAGED_APP_VERSIONS = 'nc_managed_app_versions',
|
||||
MANAGED_APP_DEPLOYMENT_LOGS = 'nc_managed_app_deployment_logs',
|
||||
}
|
||||
|
||||
export const BaseRelatedMetaTables = [
|
||||
@@ -326,9 +329,9 @@ export enum CacheScope {
|
||||
DEPENDENCY_TRACKER = 'nc_dependency_tracker',
|
||||
INSTALLATION = 'installation',
|
||||
INSTALLATION_ALIAS = 'installationAlias',
|
||||
SANDBOX = 'sandbox',
|
||||
SANDBOX_VERSION = 'sandboxVersion',
|
||||
SANDBOX_DEPLOYMENT_LOG = 'sandboxDeploymentLog',
|
||||
MANAGED_APP = 'managedApp',
|
||||
MANAGED_APP_VERSION = 'managedAppVersion',
|
||||
MANAGED_APP_DEPLOYMENT_LOG = 'managedAppDeploymentLog',
|
||||
SUBSCRIPTIONS_ALIAS = 'subscriptionsAlias',
|
||||
}
|
||||
|
||||
@@ -377,9 +380,9 @@ export const RootScopeTables = {
|
||||
MetaTable.JOBS,
|
||||
MetaTable.FILE_REFERENCES,
|
||||
MetaTable.DATA_REFLECTION,
|
||||
MetaTable.SANDBOXES,
|
||||
MetaTable.SANDBOX_VERSIONS,
|
||||
MetaTable.SANDBOX_DEPLOYMENT_LOGS,
|
||||
MetaTable.MANAGED_APPS,
|
||||
MetaTable.MANAGED_APP_VERSIONS,
|
||||
MetaTable.MANAGED_APP_DEPLOYMENT_LOGS,
|
||||
// Temporarily added need to be discussed within team
|
||||
MetaTable.AUDIT,
|
||||
MetaTable.CUSTOM_URLS,
|
||||
|
||||
Reference in New Issue
Block a user