feat: improve query performence (#6764)

This commit is contained in:
darkskygit
2024-05-06 09:12:04 +00:00
parent 1303a6a8b4
commit 13f40f435d
12 changed files with 146 additions and 168 deletions

View File

@@ -138,19 +138,11 @@ export class FeatureManagementService {
async addWorkspaceFeatures(
workspaceId: string,
feature: FeatureType,
version?: number,
reason?: string
) {
const latestVersions = await this.feature.getFeaturesVersion();
// use latest version if not specified
const latestVersion = version || latestVersions[feature];
if (!Number.isInteger(latestVersion)) {
throw new Error(`Version of feature ${feature} not found`);
}
return this.feature.addWorkspaceFeature(
workspaceId,
feature,
latestVersion,
reason || 'add feature by api'
);
}

View File

@@ -8,33 +8,6 @@ import { FeatureKind, FeatureType } from './types';
@Injectable()
export class FeatureService {
constructor(private readonly prisma: PrismaClient) {}
async getFeaturesVersion() {
const features = await this.prisma.features.findMany({
where: {
type: FeatureKind.Feature,
},
select: {
feature: true,
version: true,
},
});
return features.reduce(
(acc, feature) => {
// only keep the latest version
if (acc[feature.feature]) {
if (acc[feature.feature] < feature.version) {
acc[feature.feature] = feature.version;
}
} else {
acc[feature.feature] = feature.version;
}
return acc;
},
{} as Record<string, number>
);
}
async getFeature<F extends FeatureType>(
feature: F
): Promise<FeatureConfigType<F> | undefined> {
@@ -80,14 +53,15 @@ export class FeatureService {
if (latestFlag) {
return latestFlag.id;
} else {
const latestVersion = await tx.features
.aggregate({
where: { feature },
_max: { version: true },
const featureId = await tx.features
.findFirst({
where: { feature, type: FeatureKind.Feature },
orderBy: { version: 'desc' },
select: { id: true },
})
.then(r => r._max.version);
.then(r => r?.id);
if (!latestVersion) {
if (!featureId) {
throw new Error(`Feature ${feature} not found`);
}
@@ -97,20 +71,8 @@ export class FeatureService {
reason,
expiredAt,
activated: true,
user: {
connect: {
id: userId,
},
},
feature: {
connect: {
feature_version: {
feature,
version: latestVersion,
},
type: FeatureKind.Feature,
},
},
userId,
featureId,
},
})
.then(r => r.id);
@@ -144,10 +106,8 @@ export class FeatureService {
async getUserFeatures(userId: string) {
const features = await this.prisma.userFeatures.findMany({
where: {
user: { id: userId },
feature: {
type: FeatureKind.Feature,
},
userId,
feature: { type: FeatureKind.Feature },
},
select: {
activated: true,
@@ -171,7 +131,7 @@ export class FeatureService {
async getActivatedUserFeatures(userId: string) {
const features = await this.prisma.userFeatures.findMany({
where: {
user: { id: userId },
userId,
feature: { type: FeatureKind.Feature },
activated: true,
OR: [{ expiredAt: null }, { expiredAt: { gt: new Date() } }],
@@ -242,7 +202,6 @@ export class FeatureService {
async addWorkspaceFeature(
workspaceId: string,
feature: FeatureType,
version: number,
reason: string,
expiredAt?: Date | string
) {
@@ -263,26 +222,27 @@ export class FeatureService {
if (latestFlag) {
return latestFlag.id;
} else {
// use latest version of feature
const featureId = await tx.features
.findFirst({
where: { feature, type: FeatureKind.Feature },
select: { id: true },
orderBy: { version: 'desc' },
})
.then(r => r?.id);
if (!featureId) {
throw new Error(`Feature ${feature} not found`);
}
return tx.workspaceFeatures
.create({
data: {
reason,
expiredAt,
activated: true,
workspace: {
connect: {
id: workspaceId,
},
},
feature: {
connect: {
feature_version: {
feature,
version,
},
type: FeatureKind.Feature,
},
},
workspaceId,
featureId,
},
})
.then(r => r.id);

View File

@@ -19,9 +19,7 @@ export class QuotaService {
async getUserQuota(userId: string) {
const quota = await this.prisma.userFeatures.findFirst({
where: {
user: {
id: userId,
},
userId,
feature: {
type: FeatureKind.Quota,
},
@@ -48,9 +46,7 @@ export class QuotaService {
async getUserQuotas(userId: string) {
const quotas = await this.prisma.userFeatures.findMany({
where: {
user: {
id: userId,
},
userId,
feature: {
type: FeatureKind.Quota,
},
@@ -96,14 +92,17 @@ export class QuotaService {
return;
}
const latestPlanVersion = await tx.features.aggregate({
where: {
feature: quota,
},
_max: {
version: true,
},
});
const featureId = await tx.features
.findFirst({
where: { feature: quota, type: FeatureKind.Quota },
select: { id: true },
orderBy: { version: 'desc' },
})
.then(f => f?.id);
if (!featureId) {
throw new Error(`Quota ${quota} not found`);
}
// we will deactivate all exists quota for this user
await tx.userFeatures.updateMany({
@@ -121,20 +120,8 @@ export class QuotaService {
await tx.userFeatures.create({
data: {
user: {
connect: {
id: userId,
},
},
feature: {
connect: {
feature_version: {
feature: quota,
version: latestPlanVersion._max.version || 1,
},
type: FeatureKind.Quota,
},
},
userId,
featureId,
reason: reason ?? 'switch quota',
activated: true,
expiredAt,

View File

@@ -81,7 +81,6 @@ export class WorkspaceManagementResolver {
.addWorkspaceFeatures(
workspaceId,
feature,
undefined,
'add by experimental feature api'
)
.then(id => id > 0);

View File

@@ -218,11 +218,7 @@ export class WorkspaceResolver {
permissions: {
create: {
type: Permission.Owner,
user: {
connect: {
id: user.id,
},
},
userId: user.id,
accepted: true,
},
},