Skip to content

Commit 5414595

Browse files
committed
break down 4.4.1
1 parent ef33dad commit 5414595

File tree

2 files changed

+173
-17
lines changed

2 files changed

+173
-17
lines changed

pdd/001-infra-rollout-4.4.1.md

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# Product Design Document: 4.4.1 Schedule Maintenance Notification (API & Backend)
2+
3+
**References:**
4+
* PRD: [001-infra-rollout.md#4.4. Schedule Maintenance Notification (Optional)](../../prd/001-infra-rollout.md#44-schedule-maintenance-notification-optional)
5+
* Linear Issue: [CLC-1274](https://linear.app/gitpod/issue/CLC-1274/admin-schedule-maintenance-notification)
6+
* Related PDD (Maintenance Mode): [pdd/001-infra-rollout-4.3.md](./001-infra-rollout-4.3.md)
7+
8+
## 1. Overview
9+
This document details the technical design for the API and backend components of the "Schedule Maintenance Notification" feature. This feature allows organization owners to enable, disable, and set a custom notification message that can be displayed on the Gitpod dashboard. The actual display logic, including the use of a default message if no custom one is set, will be handled by the frontend (covered in PDD 4.4.2).
10+
11+
## 2. Goals
12+
* Define the API endpoints for managing scheduled maintenance notification settings (enabled status and custom message).
13+
* Specify the backend logic for storing and retrieving these settings.
14+
* Detail necessary database schema modifications for the `DBTeam` entity.
15+
* Ensure the backend implementation adheres to PRD requirements R4.1, R4.2, R4.3 (backend portion), and supports R4.5.
16+
17+
## 3. Proposed Solution (API & Backend)
18+
19+
### 3.1. Database Schema Update (`gitpod-db`)
20+
* **Target Entity:** `DBTeam` (represents an "Organization", likely in `components/gitpod-db/src/typeorm/entity/db-team.ts`).
21+
* **Action:** Add a new column `maintenanceNotification` to the `DBTeam` entity.
22+
* **Name:** `maintenanceNotification`
23+
* **Type:** `json` (or `jsonb` if preferred by the database)
24+
* **Structure:** The JSON object will store:
25+
```json
26+
{
27+
"enabled": boolean,
28+
"message": string | undefined
29+
}
30+
```
31+
* **Default Value (for the column in DB):** `{"enabled": false, "message": null}`
32+
* **Nullable (column itself):** `false` (the column should always exist, its content defines state).
33+
* **Migration:** A TypeORM migration script will be generated and applied to add this column with its default value.
34+
35+
### 3.2. API Definition (Protobuf - Public API)
36+
* **Target File:** `components/public-api/gitpod/v1/organization.proto` (or equivalent proto definition file for OrganizationService).
37+
* **Action:** Add new RPC methods and messages to the `OrganizationService`:
38+
```protobuf
39+
service OrganizationService {
40+
// ... existing RPCs ...
41+
42+
// GetScheduledMaintenanceNotification retrieves the scheduled maintenance notification settings for an organization.
43+
rpc GetScheduledMaintenanceNotification(GetScheduledMaintenanceNotificationRequest) returns (GetScheduledMaintenanceNotificationResponse) {}
44+
45+
// SetScheduledMaintenanceNotification sets the scheduled maintenance notification for an organization.
46+
rpc SetScheduledMaintenanceNotification(SetScheduledMaintenanceNotificationRequest) returns (SetScheduledMaintenanceNotificationResponse) {}
47+
}
48+
49+
message GetScheduledMaintenanceNotificationRequest {
50+
string organization_id = 1;
51+
}
52+
53+
message GetScheduledMaintenanceNotificationResponse {
54+
bool is_enabled = 1;
55+
string message = 2; // The custom message stored, if any. Empty or not present if no custom message is set.
56+
// The frontend will use its own default if this is empty/null and is_enabled is true.
57+
}
58+
59+
message SetScheduledMaintenanceNotificationRequest {
60+
string organization_id = 1;
61+
bool is_enabled = 2;
62+
optional string custom_message = 3; // User-provided custom message.
63+
// If not provided or empty, the backend stores null/empty for the message.
64+
}
65+
66+
message SetScheduledMaintenanceNotificationResponse {
67+
bool is_enabled = 1; // The new enabled state
68+
string message = 2; // The custom message that is now stored, if any.
69+
}
70+
```
71+
* Relevant code generation scripts will be run after this change.
72+
73+
### 3.3. API Implementation (`components/server/src/api/organization-service-api.ts`)
74+
* The `OrganizationServiceAPI` class will implement the new RPC methods.
75+
* **`getScheduledMaintenanceNotification` Implementation:**
76+
* Input: `GetScheduledMaintenanceNotificationRequest`.
77+
* Calls `this.orgService.getScheduledMaintenanceNotificationSettings(ctxUserId(), req.organizationId)`.
78+
* Maps the internal result (e.g., `{ enabled: boolean, message: string | null }`) to `GetScheduledMaintenanceNotificationResponse`.
79+
* `response.is_enabled = internalResult.enabled;`
80+
* `response.message = internalResult.message || "";` (Return empty string if message is null).
81+
* **`setScheduledMaintenanceNotification` Implementation:**
82+
* Input: `SetScheduledMaintenanceNotificationRequest`.
83+
* Calls `this.orgService.setScheduledMaintenanceNotificationSettings(ctxUserId(), req.organizationId, req.isEnabled, req.customMessage)`.
84+
* Maps the internal result to `SetScheduledMaintenanceNotificationResponse`.
85+
* `response.is_enabled = internalResult.enabled;`
86+
* `response.message = internalResult.message || "";`
87+
88+
### 3.4. Backend Service Logic (`components/server/src/orgs/organization-service.ts`)
89+
* The `OrganizationService` class will contain the core logic.
90+
* **Type definition for the notification settings (internal use):**
91+
```typescript
92+
interface MaintenanceNotificationSettings {
93+
enabled: boolean;
94+
message: string | undefined;
95+
}
96+
```
97+
* **`getScheduledMaintenanceNotificationSettings(userId: string, orgId: string): Promise<MaintenanceNotificationSettings>` method:**
98+
* Authorization: `await this.auth.checkPermissionOnOrganization(userId, "maintenance", orgId);`.
99+
* Logic:
100+
* Fetch `DBTeam` by `orgId` using `this.teamDB.findTeamById(orgId)`.
101+
* If not found, throw `ApplicationError(ErrorCodes.NOT_FOUND)`.
102+
* Let `dbNotificationConfig = team.maintenanceNotification;`
103+
* If `dbNotificationConfig` is null or parsing fails (though TypeORM usually handles JSON column parsing):
104+
* Return `{ enabled: false, message: undefined }`.
105+
* Else (valid JSON from DB):
106+
* Return `{ enabled: dbNotificationConfig.enabled, message: dbNotificationConfig.message === null ? undefined : dbNotificationConfig.message }`.
107+
* **`setScheduledMaintenanceNotificationSettings(userId: string, orgId: string, isEnabled: boolean, customMessage?: string | null): Promise<MaintenanceNotificationSettings>` method:**
108+
* Authorization: `await this.auth.checkPermissionOnOrganization(userId, "maintenance", orgId);`.
109+
* Logic:
110+
* Fetch `DBTeam`. If not found, throw `ApplicationError(ErrorCodes.NOT_FOUND)`.
111+
* Construct the new `MaintenanceNotificationSettings` object for internal logic:
112+
```typescript
113+
const newInternalNotificationConfig: MaintenanceNotificationSettings = {
114+
enabled: isEnabled,
115+
message: (customMessage && customMessage.trim() !== "") ? customMessage.trim() : undefined,
116+
};
117+
```
118+
* Prepare the object to be stored in the DB (JSON will store `null` for `undefined` message):
119+
```typescript
120+
const notificationConfigForDb = {
121+
enabled: newInternalNotificationConfig.enabled,
122+
message: newInternalNotificationConfig.message === undefined ? null : newInternalNotificationConfig.message,
123+
};
124+
```
125+
* Prepare update payload for `this.teamDB.updateTeam(orgId, updatePayload)`:
126+
* `updatePayload.maintenanceNotification = notificationConfigForDb;` (The DB driver will handle JSON serialization).
127+
* Persist changes: `const updatedTeam = await this.teamDB.updateTeam(orgId, updatePayload);`
128+
* Analytics:
129+
```typescript
130+
this.analytics.track({
131+
userId,
132+
event: isEnabled ? "scheduled_maintenance_notification_enabled" : "scheduled_maintenance_notification_disabled",
133+
properties: {
134+
organization_id: orgId,
135+
has_custom_message: isEnabled && !!newInternalNotificationConfig.message,
136+
},
137+
});
138+
```
139+
* Return the `newInternalNotificationConfig` object reflecting the logical state post-update.
140+
141+
## 4. Permissions & Auditing
142+
143+
### 4.1. Permissions
144+
* Backend service methods (`OrganizationService`) will use `await this.auth.checkPermissionOnOrganization(userId, "maintenance", orgId)` for both `getScheduledMaintenanceNotificationSettings` and `setScheduledMaintenanceNotificationSettings`. This aligns with the permission used for managing the Maintenance Mode feature (4.3) and ensures that users who can manage one can manage the other.
145+
146+
### 4.2. Auditing
147+
* Analytics tracking as detailed in section 3.4 covers basic auditing of enable/disable actions and presence of a custom message.
148+
* If more detailed `DbAuditLog` entries are required (e.g., logging the actual message content changes), they can be added within the `setScheduledMaintenanceNotificationSettings` method in `OrganizationService`.
149+
150+
## 5. Open Questions / Considerations (Backend Specific)
151+
* Ensuring the default value for the `maintenanceNotification` JSON column (`{"enabled": false, "message": null}`) is correctly applied by the migration and handled if the column is ever unexpectedly null.
152+
* Error handling during JSON parsing from the DB (though TypeORM typically handles this well for JSON columns).
153+
* The `message` field in `GetScheduledMaintenanceNotificationResponse` and `SetScheduledMaintenanceNotificationResponse` will be an empty string if no custom message is set (i.e., `null` in the DB). The frontend will be responsible for interpreting this as "use frontend default".

prd/001-infra-rollout.md

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,58 +4,61 @@
44

55
## 1. Overview
66

7-
This document outlines the requirements for improving the infrastructure update rollout experience for Gitpod administrators. The goal is to provide administrators with better tools for visibility, communication, and control during infrastructure maintenance, thereby reducing operational stress and minimizing the risk of incidents.
7+
This document outlines the requirements for improving the infrastructure update rollout experience for Gitpod org owners. The goal is to provide org owners with better tools for visibility, communication, and control during infrastructure maintenance, thereby reducing operational stress and minimizing the risk of incidents.
88

99
## 2. Background
1010

1111
Customers have reported significant challenges in coordinating infrastructure updates for their Gitpod installations. These challenges stem from several factors:
1212
* **Long Workspace Timeouts:** Workspaces can run for extended periods (e.g., 36 hours), making it difficult to find a suitable maintenance window without disrupting users.
1313
* **Ineffective Communication:** Company-internal communication channels and email announcements regarding maintenance are often missed or ignored by users.
14-
* **Lack of Determinism:** The unpredictability of user activity and workspace states during updates makes the process stressful for administrators.
14+
* **Lack of Determinism:** The unpredictability of user activity and workspace states during updates makes the process stressful for org owners.
1515

1616
These issues have led to difficult update experiences and, in some cases, service incidents, including data loss for customers. This project aims to address these problems by introducing a dedicated admin interface with tools to manage maintenance periods more effectively.
1717

1818
## 3. Goals
1919

20-
* Improve the predictability and reduce the stress of infrastructure updates for administrators.
20+
* Improve the predictability and reduce the stress of infrastructure updates for org owners.
2121
* Minimize disruption to end-users during maintenance windows.
2222
* Reduce the risk of data loss or other incidents related to infrastructure updates.
23-
* Provide administrators with clear visibility into running workspaces.
24-
* Enable administrators to effectively communicate upcoming maintenance to users.
25-
* Give administrators control over workspace creation and termination during maintenance.
23+
* Provide org owners with clear visibility into running workspaces.
24+
* Enable org owners to effectively communicate upcoming maintenance to users.
25+
* Give org owners control over workspace creation and termination during maintenance.
2626

2727
## 4. Requirements
2828

2929
An "Admin" section will be added to the Gitpod organization menu. This section will house the following features:
3030

3131
### 4.1. View Running Workspaces (Ref: [CLC-1240](https://linear.app/gitpod/issue/CLC-1240/admin-ability-to-see-running-workspaces))
32-
* **R1.1:** Administrators must be able to view a list of all currently running workspaces within their organization.
32+
* **R1.1:** Org owners must be able to view a list of all currently running workspaces within their organization.
3333
* **R1.2:** The list should include relevant information for each workspace (e.g., user, workspace ID, start time, project).
3434
* **R1.3:** This feature aims to restore or provide similar functionality to a previously available view that helped admins identify active users during upgrades.
3535

3636
### 4.2. Stop All Running Workspaces (Ref: [CLC-1275](https://linear.app/gitpod/issue/CLC-1275/admin-stop-all-running-workspaces-button-for-infra-update))
37-
* **R3.1:** Administrators must have an option (e.g., a button) to stop all currently running workspaces within their organization.
37+
* **R3.1:** Org owners must have an option (e.g., a button) to stop all currently running workspaces within their organization.
3838
* **R3.2:** This action is intended to ensure all running workspaces are backed up before an infrastructure update.
3939
* **R3.3:** The UI should provide a clear explanation of what this action does and its implications.
4040

4141
### 4.3. Maintenance Mode Toggle (Ref: [CLC-1273](https://linear.app/gitpod/issue/CLC-1273/admin-maintenance-mode-toggle))
42-
* **R2.1:** Administrators must be able to manually enable or disable a "Maintenance Mode" for their Gitpod instance.
42+
* **R2.1:** Org owners must be able to manually enable or disable a "Maintenance Mode" for their Gitpod instance.
4343
* **R2.2:** When Maintenance Mode is enabled:
4444
* Users must be prevented from starting new workspaces.
4545
* A clear warning or notification must be displayed on the dashboard indicating that the system is in maintenance.
4646
* The "Stop All Running Workspaces" button (from feature 4.2) must be enabled; otherwise, it must be disabled.
47-
* **R2.3:** This toggle allows administrators to control the state before, during, and after an update.
47+
* **R2.3:** This toggle allows org owners to control the state before, during, and after an update.
4848

4949
### 4.4. Schedule Maintenance Notification (Optional) (Ref: [CLC-1274](https://linear.app/gitpod/issue/CLC-1274/admin-schedule-maintenance-notification))
50-
* **R4.1:** Administrators must be able to schedule and display a maintenance notification banner on the Gitpod dashboard.
50+
* **R4.1:** Org owners must be able to schedule and display a maintenance notification banner on the Gitpod dashboard.
5151
* **R4.2:** The notification system must include an enable/disable toggle.
52-
* **R4.3:** Administrators must be able to provide custom text for the notification banner to explain the purpose, timing, and impact of the maintenance.
53-
* **R4.4:** A default notification message should be provided if no custom text is set.
52+
* **R4.3:** Org owners must be able to provide custom text for the notification banner via an input field, to explain the purpose, timing, and impact of the maintenance.
53+
* **R4.4:** A default notification message must be provided.
54+
* **R4.4.1:** This default message will be pre-filled as the default value in the "set notification message" input field.
55+
* **R4.4.2:** If the notification is enabled (R4.2) and no custom text is entered (i.e., the default message is used), this default message is stored on the backend. If custom text is provided, that custom text is stored.
56+
* **R4.5:** If both the "Maintenance Mode" notification (from feature 4.3) and this "Schedule Maintenance Notification" are enabled and active, only the "Maintenance Mode" notification must be displayed to users.
5457

5558
## 5. Design Considerations (High-Level)
5659

5760
* The new "Admin" page should be easily accessible from the organization menu.
58-
* The UI for these features should be intuitive and provide clear feedback to the administrator.
61+
* The UI for these features should be intuitive and provide clear feedback to the org owner.
5962
* Actions with significant impact (e.g., stopping all workspaces) should require confirmation.
6063

6164
## 6. Technical Considerations (High-Level)
@@ -73,7 +76,7 @@ An "Admin" section will be added to the Gitpod organization menu. This section w
7376
## 8. Deployment Considerations
7477

7578
* These features will be rolled out as part of a standard Gitpod update.
76-
* Documentation for administrators on how to use these new features will be required.
79+
* Documentation for org owners on how to use these new features will be required.
7780
* Consider feature flagging for a phased rollout if deemed necessary.
7881

7982
## 9. Implementation Progress
@@ -88,12 +91,12 @@ An "Admin" section will be added to the Gitpod organization menu. This section w
8891
| - API: Trigger stop all workspaces | Done (N/A) | Cline | (Leverages existing StopWorkspace API) |
8992
| - Logic: Iterate and stop workspaces | | | (Frontend orchestration) |
9093
| - UI: Button & Confirm | | | (Integrated into RunningWorkspacesCard) |
91-
| **4.3 Maintenance Mode Toggle** | | | |
94+
| **4.3 Maintenance Mode Toggle** | Done | Cline | [001-infra-rollout-4.3.md](pdd/001-infra-rollout-4.3.md) |
9295
| - API: Get/Set Maintenance Mode | | | |
9396
| - Logic: Prevent new workspace starts | | | |
9497
| - UI: Toggle & Dashboard Banner | | | |
9598
| - UI: Enable/disable "Stop All Workspaces" button | | | (Logic within RunningWorkspacesCard to check Maint. Mode) |
96-
| **4.4 Schedule Maintenance Notification (Optional)** | | | |
99+
| **4.4 Schedule Maintenance Notification (Optional)** | | | [001-infra-rollout-4.4.1.md](pdd/001-infra-rollout-4.4.1.md) (API/Backend) |
97100
| - API: Get/Set Notification | | | |
98101
| - UI: Form for scheduling & Dashboard Banner | | | |
99102
| **General** | | | |

0 commit comments

Comments
 (0)