import { Injectable, NotFoundException } from "@nestjs/common"; import { Prisma } from "@prisma/client"; import { PrismaService } from "../prisma/prisma.service"; import { ActivityService } from "../activity/activity.service"; import type { CreateDomainDto, UpdateDomainDto, QueryDomainsDto } from "./dto"; /** * Service for managing domains */ @Injectable() export class DomainsService { constructor( private readonly prisma: PrismaService, private readonly activityService: ActivityService ) {} /** * Create a new domain */ async create( workspaceId: string, userId: string, createDomainDto: CreateDomainDto ) { const domain = await this.prisma.domain.create({ data: { ...createDomainDto, workspaceId, metadata: (createDomainDto.metadata || {}) as unknown as Prisma.InputJsonValue, sortOrder: 0, // Default to 0, consistent with other services }, include: { _count: { select: { tasks: true, events: true, projects: true, ideas: true }, }, }, }); // Log activity await this.activityService.logDomainCreated( workspaceId, userId, domain.id, { name: domain.name, } ); return domain; } /** * Get paginated domains with filters */ async findAll(query: QueryDomainsDto) { const page = query.page || 1; const limit = query.limit || 50; const skip = (page - 1) * limit; // Build where clause const where: any = { workspaceId: query.workspaceId, }; // Add search filter if provided if (query.search) { where.OR = [ { name: { contains: query.search, mode: "insensitive" } }, { description: { contains: query.search, mode: "insensitive" } }, ]; } // Execute queries in parallel const [data, total] = await Promise.all([ this.prisma.domain.findMany({ where, include: { _count: { select: { tasks: true, events: true, projects: true, ideas: true }, }, }, orderBy: { sortOrder: "asc", }, skip, take: limit, }), this.prisma.domain.count({ where }), ]); return { data, meta: { total, page, limit, totalPages: Math.ceil(total / limit), }, }; } /** * Get a single domain by ID */ async findOne(id: string, workspaceId: string) { const domain = await this.prisma.domain.findUnique({ where: { id, workspaceId, }, include: { _count: { select: { tasks: true, events: true, projects: true, ideas: true }, }, }, }); if (!domain) { throw new NotFoundException(`Domain with ID ${id} not found`); } return domain; } /** * Update a domain */ async update( id: string, workspaceId: string, userId: string, updateDomainDto: UpdateDomainDto ) { // Verify domain exists const existingDomain = await this.prisma.domain.findUnique({ where: { id, workspaceId }, }); if (!existingDomain) { throw new NotFoundException(`Domain with ID ${id} not found`); } const domain = await this.prisma.domain.update({ where: { id, workspaceId, }, data: updateDomainDto as any, include: { _count: { select: { tasks: true, events: true, projects: true, ideas: true }, }, }, }); // Log activity await this.activityService.logDomainUpdated( workspaceId, userId, id, { changes: updateDomainDto as Prisma.JsonValue, } ); return domain; } /** * Delete a domain */ async remove(id: string, workspaceId: string, userId: string) { // Verify domain exists const domain = await this.prisma.domain.findUnique({ where: { id, workspaceId }, }); if (!domain) { throw new NotFoundException(`Domain with ID ${id} not found`); } await this.prisma.domain.delete({ where: { id, workspaceId, }, }); // Log activity await this.activityService.logDomainDeleted( workspaceId, userId, id, { name: domain.name, } ); } }