feat: separate prior records behind an owner switch and count last-period questions

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-15 10:48:30 +03:30
co-authored by Cursor
parent 3a8a684aa4
commit 6bc5e1bec7
29 changed files with 775 additions and 77 deletions
+40
View File
@@ -1,6 +1,7 @@
import {
BadRequestException,
ConflictException,
ForbiddenException,
Injectable,
Logger,
NotFoundException,
@@ -412,6 +413,29 @@ export class AuthService {
return this.toAuthUserDto(user, organizationId);
}
async setPriorLens(
userId: string,
organizationId: string,
lens: 'current' | 'archive',
): Promise<AuthUserDto> {
const membership = await this.prisma.membership.findFirst({
where: { userId, organizationId, isActive: true },
include: { organization: { select: { enabledModules: true } } },
});
if (!membership?.priorArchiveEnabled) {
throw new ForbiddenException('بایگانی اطلاعات قبل برای شما فعال نیست');
}
const modules = this.billing.normalizeModules(membership.organization.enabledModules);
if (!modules.includes('prior_data_archive')) {
throw new ForbiddenException('بایگانی اطلاعات قبل برای این محیط فعال نیست');
}
await this.prisma.membership.update({
where: { id: membership.id },
data: { priorArchiveLens: lens },
});
return this.me(userId, organizationId);
}
async updateMe(userId: string, organizationId: string, dto: UpdateProfileDto): Promise<AuthUserDto> {
const fullName = dto.fullName.trim();
if (fullName.length < 2) {
@@ -653,9 +677,23 @@ export class AuthService {
),
subscription: sub,
isOrgOwner: role === 'owner',
priorArchive: this.priorArchiveFor(membership),
});
}
private priorArchiveFor(
membership: {
priorArchiveEnabled?: boolean;
priorArchiveLens?: string;
organization?: { enabledModules?: string[] };
} | null,
): AuthUserDto['priorArchive'] {
if (!membership?.priorArchiveEnabled) return undefined;
const modules = this.billing.normalizeModules(membership.organization?.enabledModules);
if (!modules.includes('prior_data_archive')) return undefined;
return { lens: membership.priorArchiveLens === 'archive' ? 'archive' : 'current' };
}
private async throttleChallenges(
kind: string,
email: string | null | undefined,
@@ -740,6 +778,7 @@ export class AuthService {
enabledModules?: OrgModuleKey[];
subscription?: SubscriptionSummaryDto | null;
isOrgOwner?: boolean;
priorArchive?: AuthUserDto['priorArchive'];
}): AuthUserDto {
return {
id: user.id,
@@ -753,6 +792,7 @@ export class AuthService {
...(user.enabledModules ? { enabledModules: user.enabledModules } : {}),
...(user.subscription ? { subscription: user.subscription } : {}),
...(user.isOrgOwner !== undefined ? { isOrgOwner: user.isOrgOwner } : {}),
...(user.priorArchive ? { priorArchive: user.priorArchive } : {}),
};
}
}