Editing Super Admin permissions and visual changes

This commit is contained in:
2026-09-20 12:07:05 +03:30
parent 4a9fe0b07c
commit 0e580b19c3
9 changed files with 621 additions and 231 deletions
+25 -10
View File
@@ -94,7 +94,7 @@ export class BillingService {
});
}
/** اشتراک محیط = BillingAccount اولین مالک فعال */
/** اشتراک محیط = BillingAccount اولین مالک فعال — برای عضو زیرمجموعه حساب جدید ساخته نمی‌شود */
async resolveForOrganization(organizationId: string) {
const owner = await this.prisma.membership.findFirst({
where: {
@@ -106,25 +106,25 @@ export class BillingService {
select: { userId: true },
});
if (!owner) return null;
let account = await this.getByOwnerUserId(owner.userId);
if (!account) {
account = await this.ensureTrialForOwner(owner.userId);
}
return account;
return this.getByOwnerUserId(owner.userId);
}
async requireActiveForOrganization(organizationId: string): Promise<SubscriptionSummaryDto> {
const account = await this.resolveForOrganization(organizationId);
if (!account) {
throw new UnauthorizedException('اشتراک این محیط یافت نشد');
throw new UnauthorizedException(
'اشتراک این محیط یافت نشد؛ مالک باید از پنل سوپرادمین پلن داشته باشد',
);
}
return this.assertActive(account);
}
async requireActiveForOwner(ownerUserId: string): Promise<SubscriptionSummaryDto> {
let account = await this.getByOwnerUserId(ownerUserId);
const account = await this.getByOwnerUserId(ownerUserId);
if (!account) {
account = await this.ensureTrialForOwner(ownerUserId);
throw new UnauthorizedException(
'اشتراک یافت نشد؛ ابتدا پلن را از سوپرادمین اعمال کنید',
);
}
return this.assertActive(account);
}
@@ -154,7 +154,12 @@ export class BillingService {
}
async assertCanCreateOrganization(ownerUserId: string) {
const summary = await this.requireActiveForOwner(ownerUserId);
let account = await this.getByOwnerUserId(ownerUserId);
if (!account) {
// اولین محیط مالک: trial خودکار
account = await this.ensureTrialForOwner(ownerUserId, { maxOrganizations: 1 });
}
const summary = await this.assertActive(account);
const ownedCount = await this.prisma.membership.count({
where: { userId: ownerUserId, role: 'owner', isActive: true },
});
@@ -169,6 +174,16 @@ export class BillingService {
ownerUserId: string,
dto: ApplyBillingPlanRequest,
): Promise<BillingAccountDto> {
const ownerMembership = await this.prisma.membership.findFirst({
where: { userId: ownerUserId, role: 'owner', isActive: true },
select: { id: true },
});
if (!ownerMembership) {
throw new BadRequestException(
'اشتراک فقط برای مالک محیط تعریف می‌شود؛ این کاربر مالک هیچ محیطی نیست',
);
}
const planCode = dto.planCode;
const now = new Date();
let expiresAt: Date;