Multi-environment and multi-user construction
This commit is contained in:
@@ -23,13 +23,24 @@ type RoleRow = {
|
||||
color: string;
|
||||
permissions: string[];
|
||||
systemKey: string | null;
|
||||
users: Array<{
|
||||
id: string;
|
||||
fullName: string;
|
||||
avatarStorageKey: string | null;
|
||||
memberships: Array<{
|
||||
user: {
|
||||
id: string;
|
||||
fullName: string;
|
||||
avatarStorageKey: string | null;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
|
||||
const ROLE_MEMBERS_INCLUDE = {
|
||||
memberships: {
|
||||
include: {
|
||||
user: { select: { id: true, fullName: true, avatarStorageKey: true } },
|
||||
},
|
||||
orderBy: { createdAt: 'asc' as const },
|
||||
},
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class OrgRolesService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
@@ -38,12 +49,7 @@ export class OrgRolesService {
|
||||
await this.ensureDefaultRoles(organizationId);
|
||||
const rows = await this.prisma.orgRole.findMany({
|
||||
where: { organizationId },
|
||||
include: {
|
||||
users: {
|
||||
select: { id: true, fullName: true, avatarStorageKey: true },
|
||||
orderBy: { fullName: 'asc' },
|
||||
},
|
||||
},
|
||||
include: ROLE_MEMBERS_INCLUDE,
|
||||
orderBy: [{ systemKey: 'asc' }, { createdAt: 'asc' }],
|
||||
});
|
||||
return rows.map((row) => this.toDto(row));
|
||||
@@ -73,12 +79,7 @@ export class OrgRolesService {
|
||||
color: dto.color ?? 'teal',
|
||||
permissions: dto.permissions?.length ? dto.permissions : [...ALL_ROLE_PERMISSIONS],
|
||||
},
|
||||
include: {
|
||||
users: {
|
||||
select: { id: true, fullName: true, avatarStorageKey: true },
|
||||
orderBy: { fullName: 'asc' },
|
||||
},
|
||||
},
|
||||
include: ROLE_MEMBERS_INCLUDE,
|
||||
});
|
||||
return this.toDto(row);
|
||||
} catch (e) {
|
||||
@@ -122,12 +123,7 @@ export class OrgRolesService {
|
||||
const row = await this.prisma.orgRole.update({
|
||||
where: { id: existing.id },
|
||||
data,
|
||||
include: {
|
||||
users: {
|
||||
select: { id: true, fullName: true, avatarStorageKey: true },
|
||||
orderBy: { fullName: 'asc' },
|
||||
},
|
||||
},
|
||||
include: ROLE_MEMBERS_INCLUDE,
|
||||
});
|
||||
return this.toDto(row);
|
||||
} catch (e) {
|
||||
@@ -189,15 +185,15 @@ export class OrgRolesService {
|
||||
byKey.set(seed.systemKey, created);
|
||||
}
|
||||
|
||||
const unassigned = await this.prisma.user.findMany({
|
||||
const unassigned = await this.prisma.membership.findMany({
|
||||
where: { organizationId, orgRoleId: null },
|
||||
select: { id: true, role: true },
|
||||
});
|
||||
for (const user of unassigned) {
|
||||
const role = byKey.get(user.role);
|
||||
for (const membership of unassigned) {
|
||||
const role = byKey.get(membership.role);
|
||||
if (!role) continue;
|
||||
await this.prisma.user.update({
|
||||
where: { id: user.id },
|
||||
await this.prisma.membership.update({
|
||||
where: { id: membership.id },
|
||||
data: { orgRoleId: role.id },
|
||||
});
|
||||
}
|
||||
@@ -253,11 +249,11 @@ export class OrgRolesService {
|
||||
color: row.color,
|
||||
permissions: sanitizePermissions(row.permissions),
|
||||
systemKey,
|
||||
userCount: row.users.length,
|
||||
members: row.users.map((user) => ({
|
||||
id: user.id,
|
||||
fullName: user.fullName,
|
||||
hasAvatar: Boolean(user.avatarStorageKey),
|
||||
userCount: row.memberships.length,
|
||||
members: row.memberships.map((membership) => ({
|
||||
id: membership.user.id,
|
||||
fullName: membership.user.fullName,
|
||||
hasAvatar: Boolean(membership.user.avatarStorageKey),
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user