Add workspace DDL lock env var and maintenance mode UI (#19130)
## Summary - Add `WORKSPACE_SCHEMA_DDL_LOCKED` env-only boolean config variable that blocks all workspace schema DDL changes when set to `true`. This is intended for hot upgrades where logical replication cannot handle DDL changes. Enforced at two chokepoints: - `WorkspaceMigrationRunnerService.run` — blocks all metadata-driven DDL (object/field/index CRUD, app sync/uninstall, standard app sync, upgrade commands) - `WorkspaceDataSourceService.createWorkspaceDBSchema` / `deleteWorkspaceDBSchema` — blocks workspace creation (sign-up) and hard deletion. Uses a dedicated `WorkspaceDataSourceException` (not ForbiddenException) - Add maintenance mode feature with Admin Panel UI and user-facing banner: - **Backend**: `MaintenanceModeService` stores maintenance window (startAt, endAt, optional link) in `core.keyValuePair` as `CONFIG_VARIABLE`. Validates endAt > startAt. Uses `GraphQLISODateTime` scalar for date fields. Exposed via `clientConfig` REST endpoint and admin GraphQL mutations (`setMaintenanceMode`, `clearMaintenanceMode`) - **Admin Panel**: New "Maintenance Mode" section in Health tab with UTC datetime pickers and activate/deactivate controls - **Banner**: `InformationBannerMaintenance` displayed at the top of `DefaultLayout` for all users, using Temporal API for timezone-aware formatting with an optional "Learn more" link These two features are **independent** — the DDL lock is controlled via env var for operational use, while maintenance mode is a UI notification mechanism controlled from the admin panel.
This commit is contained in:
@@ -1737,6 +1737,12 @@ enum FeatureFlagKey {
|
||||
IS_DATASOURCE_MIGRATED
|
||||
}
|
||||
|
||||
type ClientConfigMaintenanceMode {
|
||||
startAt: DateTime!
|
||||
endAt: DateTime!
|
||||
link: String
|
||||
}
|
||||
|
||||
type ClientConfig {
|
||||
appVersion: String
|
||||
authProviders: AuthProviders!
|
||||
@@ -1765,6 +1771,8 @@ type ClientConfig {
|
||||
calendarBookingPageId: String
|
||||
isCloudflareIntegrationEnabled: Boolean!
|
||||
isClickHouseConfigured: Boolean!
|
||||
isWorkspaceSchemaDDLLocked: Boolean!
|
||||
maintenance: ClientConfigMaintenanceMode
|
||||
}
|
||||
|
||||
type UsageBreakdownItem {
|
||||
@@ -1961,6 +1969,12 @@ type AdminPanelHealthServiceData {
|
||||
queues: [AdminPanelWorkerQueueHealth!]
|
||||
}
|
||||
|
||||
type MaintenanceMode {
|
||||
startAt: DateTime!
|
||||
endAt: DateTime!
|
||||
link: String
|
||||
}
|
||||
|
||||
type ModelsDevModelSuggestion {
|
||||
modelId: String!
|
||||
name: String!
|
||||
@@ -3225,6 +3239,7 @@ type Query {
|
||||
getModelsDevProviders: [ModelsDevProviderSuggestion!]!
|
||||
getModelsDevSuggestions(providerType: String!): [ModelsDevModelSuggestion!]!
|
||||
getAdminAiUsageByWorkspace(periodStart: DateTime, periodEnd: DateTime): [UsageBreakdownItem!]!
|
||||
getMaintenanceMode: MaintenanceMode
|
||||
getUsageAnalytics(input: UsageAnalyticsInput): UsageAnalytics!
|
||||
getPostgresCredentials: PostgresCredentials
|
||||
findManyPublicDomains: [PublicDomain!]!
|
||||
@@ -3545,6 +3560,8 @@ type Mutation {
|
||||
removeAiProvider(providerName: String!): Boolean!
|
||||
addModelToProvider(providerName: String!, modelConfig: JSON!): Boolean!
|
||||
removeModelFromProvider(providerName: String!, modelName: String!): Boolean!
|
||||
setMaintenanceMode(startAt: DateTime!, endAt: DateTime!, link: String): Boolean!
|
||||
clearMaintenanceMode: Boolean!
|
||||
enablePostgresProxy: PostgresCredentials!
|
||||
disablePostgresProxy: PostgresCredentials!
|
||||
createPublicDomain(domain: String!): PublicDomain!
|
||||
|
||||
Reference in New Issue
Block a user