All checks were successful
ci/woodpecker/push/api Pipeline was successful
Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
131 lines
3.2 KiB
TypeScript
131 lines
3.2 KiB
TypeScript
import {
|
|
BadRequestException,
|
|
ConflictException,
|
|
Injectable,
|
|
NotFoundException,
|
|
} from "@nestjs/common";
|
|
import { TeamMemberRole } from "@prisma/client";
|
|
import { PrismaService } from "../prisma/prisma.service";
|
|
import { CreateTeamDto } from "./dto/create-team.dto";
|
|
import { ManageTeamMemberDto } from "./dto/manage-team-member.dto";
|
|
|
|
@Injectable()
|
|
export class TeamsService {
|
|
constructor(private readonly prisma: PrismaService) {}
|
|
|
|
async create(workspaceId: string, createTeamDto: CreateTeamDto) {
|
|
return this.prisma.team.create({
|
|
data: {
|
|
workspaceId,
|
|
name: createTeamDto.name,
|
|
description: createTeamDto.description ?? null,
|
|
},
|
|
});
|
|
}
|
|
|
|
async findAll(workspaceId: string) {
|
|
return this.prisma.team.findMany({
|
|
where: { workspaceId },
|
|
include: {
|
|
_count: {
|
|
select: { members: true },
|
|
},
|
|
},
|
|
orderBy: { createdAt: "asc" },
|
|
});
|
|
}
|
|
|
|
async addMember(workspaceId: string, teamId: string, dto: ManageTeamMemberDto) {
|
|
await this.ensureTeamInWorkspace(workspaceId, teamId);
|
|
|
|
const workspaceMember = await this.prisma.workspaceMember.findUnique({
|
|
where: {
|
|
workspaceId_userId: {
|
|
workspaceId,
|
|
userId: dto.userId,
|
|
},
|
|
},
|
|
select: { userId: true },
|
|
});
|
|
|
|
if (!workspaceMember) {
|
|
throw new BadRequestException(
|
|
`User ${dto.userId} must be a workspace member before being added to a team`
|
|
);
|
|
}
|
|
|
|
const existingTeamMember = await this.prisma.teamMember.findUnique({
|
|
where: {
|
|
teamId_userId: {
|
|
teamId,
|
|
userId: dto.userId,
|
|
},
|
|
},
|
|
select: { userId: true },
|
|
});
|
|
|
|
if (existingTeamMember) {
|
|
throw new ConflictException(`User ${dto.userId} is already a member of team ${teamId}`);
|
|
}
|
|
|
|
return this.prisma.teamMember.create({
|
|
data: {
|
|
teamId,
|
|
userId: dto.userId,
|
|
role: dto.role ?? TeamMemberRole.MEMBER,
|
|
},
|
|
include: {
|
|
user: {
|
|
select: {
|
|
id: true,
|
|
name: true,
|
|
email: true,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
async removeMember(workspaceId: string, teamId: string, userId: string): Promise<void> {
|
|
await this.ensureTeamInWorkspace(workspaceId, teamId);
|
|
|
|
const result = await this.prisma.teamMember.deleteMany({
|
|
where: {
|
|
teamId,
|
|
userId,
|
|
},
|
|
});
|
|
|
|
if (result.count === 0) {
|
|
throw new NotFoundException(`User ${userId} is not a member of team ${teamId}`);
|
|
}
|
|
}
|
|
|
|
async remove(workspaceId: string, teamId: string): Promise<void> {
|
|
const result = await this.prisma.team.deleteMany({
|
|
where: {
|
|
id: teamId,
|
|
workspaceId,
|
|
},
|
|
});
|
|
|
|
if (result.count === 0) {
|
|
throw new NotFoundException(`Team with ID ${teamId} not found`);
|
|
}
|
|
}
|
|
|
|
private async ensureTeamInWorkspace(workspaceId: string, teamId: string): Promise<void> {
|
|
const team = await this.prisma.team.findFirst({
|
|
where: {
|
|
id: teamId,
|
|
workspaceId,
|
|
},
|
|
select: { id: true },
|
|
});
|
|
|
|
if (!team) {
|
|
throw new NotFoundException(`Team with ID ${teamId} not found`);
|
|
}
|
|
}
|
|
}
|