projects.service.ts 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import { ForbiddenException, Injectable, NotFoundException } from '@nestjs/common'
  2. import { ProjectsRepository } from './projects.repository'
  3. import { CreateProjectDto, UpdateProjectDto } from './dto/project.dto'
  4. import { OrgsService } from '../orgs/orgs.service'
  5. type OrgRole = 'org_admin' | 'project_manager' | 'viewer'
  6. @Injectable()
  7. export class ProjectsService {
  8. constructor(
  9. private readonly repo: ProjectsRepository,
  10. private readonly orgsService: OrgsService,
  11. ) {}
  12. private assertRole(role: OrgRole, allowed: OrgRole[]) {
  13. if (!allowed.includes(role)) {
  14. throw new ForbiddenException(`Role ${role} is not allowed for this action`) }
  15. }
  16. async create(dto: CreateProjectDto, userId: string) {
  17. const membership = await this.orgsService.ensureUserInOrg(userId, dto.orgId)
  18. this.assertRole(membership.role as OrgRole, ['org_admin', 'project_manager'])
  19. return this.repo.create(dto)
  20. }
  21. async findAll(userId: string, orgId?: string) {
  22. if (orgId) {
  23. await this.orgsService.ensureUserInOrg(userId, orgId)
  24. return this.repo.findAll(orgId)
  25. }
  26. const allowedOrgIds = await this.orgsService.getUserOrgIds(userId)
  27. if (allowedOrgIds.length === 0) return []
  28. const all = await this.repo.findAll()
  29. return all.filter((p) => allowedOrgIds.includes(p.orgId))
  30. }
  31. async findOne(id: string, userId: string) {
  32. const project = await this.repo.findById(id)
  33. if (!project) throw new NotFoundException(`Project ${id} not found`)
  34. await this.orgsService.ensureUserInOrg(userId, project.orgId)
  35. return project
  36. }
  37. async update(id: string, dto: UpdateProjectDto, userId: string) {
  38. const exists = await this.repo.findById(id)
  39. if (!exists) throw new NotFoundException(`Project ${id} not found`)
  40. const membership = await this.orgsService.ensureUserInOrg(userId, exists.orgId)
  41. this.assertRole(membership.role as OrgRole, ['org_admin', 'project_manager'])
  42. return this.repo.update(id, dto)
  43. }
  44. async remove(id: string, userId: string) {
  45. const exists = await this.repo.findById(id)
  46. if (!exists) throw new NotFoundException(`Project ${id} not found`)
  47. const membership = await this.orgsService.ensureUserInOrg(userId, exists.orgId)
  48. this.assertRole(membership.role as OrgRole, ['org_admin'])
  49. await this.repo.remove(id)
  50. return { success: true }
  51. }
  52. }