mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 12:55:00 +00:00
feat: improve query performence (#6764)
This commit is contained in:
@@ -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'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -81,7 +81,6 @@ export class WorkspaceManagementResolver {
|
||||
.addWorkspaceFeatures(
|
||||
workspaceId,
|
||||
feature,
|
||||
undefined,
|
||||
'add by experimental feature api'
|
||||
)
|
||||
.then(id => id > 0);
|
||||
|
||||
@@ -218,11 +218,7 @@ export class WorkspaceResolver {
|
||||
permissions: {
|
||||
create: {
|
||||
type: Permission.Owner,
|
||||
user: {
|
||||
connect: {
|
||||
id: user.id,
|
||||
},
|
||||
},
|
||||
userId: user.id,
|
||||
accepted: true,
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user