import { Injectable } from '@nestjs/common'; import { PrismaService } from '../../infrastructure/database/prisma.service'; @Injectable() export class KnowledgeBaseRepository { constructor(private readonly prisma: PrismaService) {} async create(userId: string, dto: { title: string; description?: string; coverKey?: string; coverType?: string; coverIcon?: string; coverColor?: string; visibility?: string; }) { return this.prisma.knowledgeBase.create({ data: { userId, title: dto.title, description: dto.description ?? '', coverKey: dto.coverKey ?? null, coverType: dto.coverType ?? 'custom', coverIcon: dto.coverIcon ?? null, coverColor: dto.coverColor ?? null, visibility: dto.visibility ?? 'private', status: 'active', itemCount: 0, }, }); } async findById(id: string) { return this.prisma.knowledgeBase.findUnique({ where: { id } }); } async findAllByUserId( userId: string, opts?: { page?: number; limit?: number; visibility?: string; ownerType?: string; }, ) { const page = opts?.page ?? 1; const limit = opts?.limit ?? 20; const where: any = { userId, deletedAt: null }; if (opts?.visibility) where.visibility = opts.visibility; if (opts?.ownerType) where.ownerType = opts.ownerType; return this.prisma.knowledgeBase.findMany({ where, orderBy: [{ isPinned: 'desc' }, { updatedAt: 'desc' }], skip: (page - 1) * limit, take: limit, }); } async findAllPublic(opts?: { page?: number; limit?: number; search?: string }) { const page = opts?.page ?? 1; const limit = opts?.limit ?? 20; const where: any = { visibility: 'public', deletedAt: null }; if (opts?.search) { where.OR = [ { title: { contains: opts.search } }, { description: { contains: opts.search } }, ]; } return this.prisma.knowledgeBase.findMany({ where, orderBy: [{ isPinned: 'desc' }, { updatedAt: 'desc' }], skip: (page - 1) * limit, take: limit, }); } async countByUserId(userId: string) { return this.prisma.knowledgeBase.count({ where: { userId, deletedAt: null }, }); } async update(id: string, dto: { title?: string; description?: string; coverKey?: string; coverType?: string; coverIcon?: string; coverColor?: string; visibility?: string; isPinned?: boolean; }) { return this.prisma.knowledgeBase.update({ where: { id }, data: dto, }); } async togglePin(id: string, isPinned: boolean) { return this.prisma.knowledgeBase.update({ where: { id }, data: { isPinned }, }); } async setVisibility(id: string, visibility: string) { return this.prisma.knowledgeBase.update({ where: { id }, data: { visibility }, }); } async softDelete(id: string) { await this.prisma.knowledgeBase.update({ where: { id }, data: { deletedAt: new Date() }, }); return true; } // ── Subscription ── async subscribe(userId: string, knowledgeBaseId: string) { return this.prisma.knowledgeBaseSubscription.create({ data: { userId, knowledgeBaseId }, }); } async unsubscribe(userId: string, knowledgeBaseId: string) { await this.prisma.knowledgeBaseSubscription.deleteMany({ where: { userId, knowledgeBaseId }, }); return true; } async findSubscribed(userId: string, opts?: { page?: number; limit?: number }) { const page = opts?.page ?? 1; const limit = opts?.limit ?? 20; return this.prisma.knowledgeBase.findMany({ where: { subscriptions: { some: { userId } }, deletedAt: null, }, orderBy: { updatedAt: 'desc' }, skip: (page - 1) * limit, take: limit, }); } async isSubscribed(userId: string, knowledgeBaseId: string): Promise { const sub = await this.prisma.knowledgeBaseSubscription.findUnique({ where: { userId_knowledgeBaseId: { userId, knowledgeBaseId } }, }); return !!sub; } }