Skip to content

Commit a86a7a9

Browse files
jankeromneseasyCZ
authored andcommitted
[server] Introduce an explicit per-user 'usageAttributionId' and use it to implement 'billing-based attribution'
1 parent 08b4d40 commit a86a7a9

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

components/gitpod-protocol/src/protocol.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,10 @@ export interface AdditionalUserData {
150150
oauthClientsApproved?: { [key: string]: string };
151151
// to remember GH Orgs the user installed/updated the GH App for
152152
knownGitHubOrgs?: string[];
153-
154153
// Git clone URL pointing to the user's dotfile repo
155154
dotfileRepo?: string;
155+
// Identifies an explicit team or user ID to which all the user's workspace usage should be attributed to (e.g. for billing purposes)
156+
usageAttributionId?: string;
156157
}
157158

158159
export interface EmailNotificationSettings {

components/server/src/user/user-service.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,31 @@ export class UserService {
210210
* Identifies the team or user to which a workspace instance's running time should be attributed to
211211
* (e.g. for usage analytics or billing purposes).
212212
*
213+
* A. Billing-based attribution: If payments are enabled, we attribute all the user's usage to:
214+
* - An explicitly selected billing account (e.g. a team with usage-based billing enabled)
215+
* - Or, we default to the user for all usage (e.g. free tier or individual billing, regardless of project/team)
216+
*
217+
* B. Project-based attribution: If payments are not enabled (e.g. Self-Hosted), we attribute:
218+
* - To the owner of the project (user or team), if the workspace is linked to a project
219+
* - To the user, iff the workspace is not linked to a project
220+
*
213221
* @param user
214222
* @param projectId
215223
*/
216224
async getWorkspaceUsageAttributionId(user: User, projectId?: string): Promise<string | undefined> {
225+
// A. Billing-based attribution
226+
if (this.config.enablePayment) {
227+
if (!user.additionalData?.usageAttributionId) {
228+
// No explicit user attribution ID yet -- attribute all usage to the user by default (regardless of project/team).
229+
user.additionalData = user.additionalData || {};
230+
user.additionalData.usageAttributionId = `user:${user.id}`;
231+
await this.userDb.updateUserPartial(user);
232+
}
233+
// Return the user's explicit attribution ID.
234+
return user.additionalData.usageAttributionId;
235+
}
236+
237+
// B. Project-based attribution
217238
if (!projectId) {
218239
// No project -- attribute to the user.
219240
return `user:${user.id}`;

0 commit comments

Comments
 (0)