Editing Super Admin permissions and visual changes
This commit is contained in:
@@ -651,6 +651,7 @@ export class AuthService {
|
||||
membership?.organization.enabledModules,
|
||||
),
|
||||
subscription: sub,
|
||||
isOrgOwner: role === 'owner',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -737,6 +738,7 @@ export class AuthService {
|
||||
avatarStorageKey?: string | null;
|
||||
enabledModules?: OrgModuleKey[];
|
||||
subscription?: SubscriptionSummaryDto | null;
|
||||
isOrgOwner?: boolean;
|
||||
}): AuthUserDto {
|
||||
return {
|
||||
id: user.id,
|
||||
@@ -749,6 +751,7 @@ export class AuthService {
|
||||
...(user.mobile ? { mobile: user.mobile } : {}),
|
||||
...(user.enabledModules ? { enabledModules: user.enabledModules } : {}),
|
||||
...(user.subscription ? { subscription: user.subscription } : {}),
|
||||
...(user.isOrgOwner !== undefined ? { isOrgOwner: user.isOrgOwner } : {}),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -688,6 +688,9 @@ export class PlatformService {
|
||||
organization: { id: string; name: string; isActive: boolean };
|
||||
}>;
|
||||
}): PlatformUserDto {
|
||||
const isBillingOwner = row.memberships.some(
|
||||
(m) => m.role === 'owner' && m.isActive,
|
||||
);
|
||||
return {
|
||||
id: row.id,
|
||||
email: row.email,
|
||||
@@ -696,9 +699,11 @@ export class PlatformService {
|
||||
isActive: row.isActive,
|
||||
lastLoginAt: row.lastLoginAt?.toISOString() ?? null,
|
||||
createdAt: row.createdAt.toISOString(),
|
||||
billing: row.billingAccount
|
||||
? this.billing.toDto(row.billingAccount)
|
||||
: null,
|
||||
isBillingOwner,
|
||||
billing:
|
||||
isBillingOwner && row.billingAccount
|
||||
? this.billing.toDto(row.billingAccount)
|
||||
: null,
|
||||
memberships: row.memberships.map((m) => ({
|
||||
membershipId: m.id,
|
||||
organizationId: m.organization.id,
|
||||
|
||||
Reference in New Issue
Block a user