feat: add business blob limit (#5734)

This commit is contained in:
DarkSky
2024-01-29 16:32:35 +08:00
committed by GitHub
parent 0044be972f
commit fc8a48fb43
10 changed files with 136 additions and 70 deletions

View File

@@ -57,6 +57,12 @@ export class QuotaConfig {
return this.config.configs.blobLimit;
}
get businessBlobLimit() {
return (
this.config.configs.businessBlobLimit || this.config.configs.blobLimit
);
}
get storageQuota() {
return this.config.configs.storageQuota;
}

View File

@@ -71,11 +71,33 @@ export const Quotas: Quota[] = [
memberLimit: 3,
},
},
{
feature: QuotaType.FreePlanV1,
type: FeatureKind.Quota,
version: 3,
configs: {
// quota name
name: 'Free',
// single blob limit 10MB
blobLimit: 10 * OneMB,
// server limit will larger then client to handle a edge case:
// when a user downgrades from pro to free, he can still continue
// to upload previously added files that exceed the free limit
// NOTE: this is a product decision, may change in future
businessBlobLimit: 100 * OneMB,
// total blob limit 10GB
storageQuota: 10 * OneGB,
// history period of validity 7 days
historyPeriod: 7 * OneDay,
// member limit 3
memberLimit: 3,
},
},
];
export const Quota_FreePlanV1_1 = {
feature: Quotas[3].feature,
version: Quotas[3].version,
feature: Quotas[4].feature,
version: Quotas[4].version,
};
export const Quota_ProPlanV1 = {

View File

@@ -7,6 +7,8 @@ import { OneGB } from './constant';
import { QuotaService } from './service';
import { formatSize, QuotaQueryType } from './types';
type QuotaBusinessType = QuotaQueryType & { businessBlobLimit: number };
@Injectable()
export class QuotaManagementService {
constructor(
@@ -25,6 +27,7 @@ export class QuotaManagementService {
createAt: quota.createdAt,
expiredAt: quota.expiredAt,
blobLimit: quota.feature.blobLimit,
businessBlobLimit: quota.feature.businessBlobLimit,
storageQuota: quota.feature.storageQuota,
historyPeriod: quota.feature.historyPeriod,
memberLimit: quota.feature.memberLimit,
@@ -44,7 +47,7 @@ export class QuotaManagementService {
// get workspace's owner quota and total size of used
// quota was apply to owner's account
async getWorkspaceUsage(workspaceId: string): Promise<QuotaQueryType> {
async getWorkspaceUsage(workspaceId: string): Promise<QuotaBusinessType> {
const { user: owner } =
await this.permissions.getWorkspaceOwner(workspaceId);
if (!owner) throw new NotFoundException('Workspace owner not found');
@@ -52,6 +55,7 @@ export class QuotaManagementService {
feature: {
name,
blobLimit,
businessBlobLimit,
historyPeriod,
memberLimit,
storageQuota,
@@ -64,6 +68,7 @@ export class QuotaManagementService {
const quota = {
name,
blobLimit,
businessBlobLimit,
historyPeriod,
memberLimit,
storageQuota,
@@ -84,7 +89,7 @@ export class QuotaManagementService {
return quota;
}
private mergeUnlimitedQuota(orig: QuotaQueryType) {
private mergeUnlimitedQuota(orig: QuotaBusinessType) {
return {
...orig,
storageQuota: 1000 * OneGB,

View File

@@ -33,6 +33,7 @@ const quotaPlan = z.object({
storageQuota: z.number().positive().int(),
historyPeriod: z.number().positive().int(),
memberLimit: z.number().positive().int(),
businessBlobLimit: z.number().positive().int().nullish(),
}),
});

View File

@@ -128,7 +128,7 @@ export class WorkspaceBlobResolver {
Permission.Write
);
const { storageQuota, usedSize, blobLimit } =
const { storageQuota, usedSize, businessBlobLimit } =
await this.quota.getWorkspaceUsage(workspaceId);
const unlimited = await this.feature.hasWorkspaceFeature(
@@ -152,8 +152,10 @@ export class WorkspaceBlobResolver {
`storage size limit exceeded: ${total} > ${storageQuota}`
);
return true;
} else if (recvSize > blobLimit) {
this.logger.log(`blob size limit exceeded: ${recvSize} > ${blobLimit}`);
} else if (recvSize > businessBlobLimit) {
this.logger.log(
`blob size limit exceeded: ${recvSize} > ${businessBlobLimit}`
);
return true;
} else {
return false;