feat(server): support query overcapacity member count of workspace (#12050)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Workspace quota information now includes a new metric: the count of members exceeding seat capacity ("overcapacityMemberCount"), available in both numeric and human-readable formats.
  - The workspace quota display and related queries have been updated to show this new overcapacity member count alongside existing quota metrics.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
forehalo
2025-04-30 09:47:50 +00:00
parent 04531508cb
commit f1605e246b
7 changed files with 34 additions and 1 deletions

View File

@@ -142,12 +142,16 @@ export class QuotaService {
const usedStorageQuota = quota.ownerQuota
? await this.getUserStorageUsage(quota.ownerQuota)
: await this.getWorkspaceStorageUsage(workspaceId);
const memberCount = await this.models.workspaceUser.count(workspaceId);
const memberCount =
await this.models.workspaceUser.chargedCount(workspaceId);
const overcapacityMemberCount =
await this.models.workspaceUser.insufficientSeatMemberCount(workspaceId);
return {
...quota,
usedStorageQuota,
memberCount,
overcapacityMemberCount,
usedSize: usedStorageQuota,
};
}
@@ -203,6 +207,7 @@ export class QuotaService {
historyPeriod: formatDate(quota.historyPeriod),
memberLimit: quota.memberLimit.toString(),
memberCount: quota.memberCount.toString(),
overcapacityMemberCount: quota.overcapacityMemberCount.toString(),
};
}

View File

@@ -85,6 +85,9 @@ export class WorkspaceQuotaHumanReadableType {
@Field()
memberCount!: string;
@Field()
overcapacityMemberCount!: string;
}
@ObjectType()
@@ -110,6 +113,9 @@ export class WorkspaceQuotaType implements Partial<WorkspaceQuota> {
@Field()
memberCount!: number;
@Field()
overcapacityMemberCount!: number;
@Field()
humanReadable!: WorkspaceQuotaHumanReadableType;

View File

@@ -289,6 +289,15 @@ export class WorkspaceUserModel extends BaseModel {
});
}
async insufficientSeatMemberCount(workspaceId: string) {
return this.db.workspaceUserRole.count({
where: {
workspaceId,
status: WorkspaceMemberStatus.NeedMoreSeat,
},
});
}
async getUserActiveRoles(
userId: string,
filter: { role?: WorkspaceRole } = {}

View File

@@ -1746,6 +1746,7 @@ type WorkspaceQuotaHumanReadableType {
memberCount: String!
memberLimit: String!
name: String!
overcapacityMemberCount: String!
storageQuota: String!
storageQuotaUsed: String!
}
@@ -1757,6 +1758,7 @@ type WorkspaceQuotaType {
memberCount: Int!
memberLimit: Int!
name: String!
overcapacityMemberCount: Int!
storageQuota: SafeInt!
usedSize: SafeInt! @deprecated(reason: "use `usedStorageQuota` instead")
usedStorageQuota: SafeInt!