Skip to main content
Glama

π“‚€π“’π“‹Ήπ”Έβ„•π•Œπ”Ήπ•€π•Šπ“‹Ήπ“’π“‚€ - Intelligent Guidance for

by Hive-Academy
code-review.repository.tsβ€’8.14 kB
import { Injectable } from '@nestjs/common'; import { CodeReview, Prisma } from '../../../../../generated/prisma'; import { PrismaService } from '../../../../prisma/prisma.service'; import { CodeReviewFindManyOptions, CodeReviewIncludeOptions, CodeReviewStatus, ICodeReviewRepository, ReviewStatistics, } from '../interfaces/code-review.repository.interface'; import { CodeReviewSummary, CodeReviewWithRelations, PrismaTransaction, UpdateCodeReviewData, } from '../types/code-review.types'; @Injectable() export class CodeReviewRepository implements ICodeReviewRepository { constructor(private readonly prisma: PrismaService) {} async findById( id: number, include?: CodeReviewIncludeOptions, ): Promise<CodeReviewWithRelations | null> { return this.prisma.codeReview.findUnique({ where: { id }, include: this.buildInclude(include), }); } async findByTaskId( taskId: number, include?: CodeReviewIncludeOptions, ): Promise<CodeReviewWithRelations | null> { return this.prisma.codeReview.findFirst({ where: { taskId }, include: this.buildInclude(include), orderBy: { createdAt: 'desc' }, }); } async create( data: Prisma.CodeReviewCreateInput, ): Promise<CodeReviewWithRelations> { return this.prisma.codeReview.create({ data, include: { task: true }, }); } async update( id: number, data: UpdateCodeReviewData, ): Promise<CodeReviewWithRelations> { return this.prisma.codeReview.update({ where: { id }, data, include: { task: true }, }); } async delete(id: number): Promise<CodeReview> { return this.prisma.codeReview.delete({ where: { id }, }); } async findMany( options?: CodeReviewFindManyOptions, ): Promise<CodeReviewWithRelations[]> { return this.prisma.codeReview.findMany({ where: options?.where, include: this.buildInclude(options?.include), orderBy: options?.orderBy || { createdAt: 'desc' }, skip: options?.skip, take: options?.take, }); } async findByStatus( status: CodeReviewStatus, include?: CodeReviewIncludeOptions, ): Promise<CodeReviewWithRelations[]> { return this.prisma.codeReview.findMany({ where: { status }, include: this.buildInclude(include), orderBy: { createdAt: 'desc' }, }); } async findByDateRange( startDate: Date, endDate: Date, taskId?: number, ): Promise<CodeReviewWithRelations[]> { return this.prisma.codeReview.findMany({ where: { createdAt: { gte: startDate, lte: endDate, }, ...(taskId && { taskId }), }, include: { task: true }, orderBy: { createdAt: 'desc' }, }); } async findLatestByTaskId( taskId: number, ): Promise<CodeReviewWithRelations | null> { return this.prisma.codeReview.findFirst({ where: { taskId }, include: { task: true }, orderBy: { createdAt: 'desc' }, }); } async findReviewSummary(taskId: number): Promise<CodeReviewSummary> { const reviews = await this.prisma.codeReview.findMany({ where: { taskId }, orderBy: { createdAt: 'desc' }, }); const totalReviews = reviews.length; const currentStatus = reviews.length > 0 ? (reviews[0].status as | 'APPROVED' | 'APPROVED_WITH_RESERVATIONS' | 'NEEDS_CHANGES') : null; const lastReviewDate = reviews.length > 0 ? reviews[0].createdAt : null; // Extract key strengths const keyStrengths = reviews .map((review) => review.strengths) .filter((strength) => strength && strength.trim().length > 0) .slice(0, 5); // Top 5 strengths // Extract main issues const mainIssues = reviews .map((review) => review.issues) .filter((issue) => issue && issue.trim().length > 0) .slice(0, 5); // Top 5 issues // Build approval history const approvalHistory = reviews.map((review) => ({ status: review.status as | 'APPROVED' | 'APPROVED_WITH_RESERVATIONS' | 'NEEDS_CHANGES', date: review.createdAt, summary: review.summary, })); return { totalReviews, currentStatus, lastReviewDate, keyStrengths, mainIssues, approvalHistory, }; } async findPendingReviews(limit?: number): Promise<CodeReviewWithRelations[]> { return this.prisma.codeReview.findMany({ where: { status: 'NEEDS_CHANGES', }, include: { task: true }, orderBy: { createdAt: 'asc' }, ...(limit && { take: limit }), }); } async findApprovedReviews( taskId?: number, ): Promise<CodeReviewWithRelations[]> { return this.prisma.codeReview.findMany({ where: { status: { in: ['APPROVED', 'APPROVED_WITH_RESERVATIONS'], }, ...(taskId && { taskId }), }, include: { task: true }, orderBy: { createdAt: 'desc' }, }); } async findReviewsNeedingChanges( taskId?: number, ): Promise<CodeReviewWithRelations[]> { return this.prisma.codeReview.findMany({ where: { status: 'NEEDS_CHANGES', ...(taskId && { taskId }), }, include: { task: true }, orderBy: { createdAt: 'desc' }, }); } async updateReviewStatus( id: number, status: CodeReviewStatus, ): Promise<CodeReviewWithRelations> { return this.prisma.codeReview.update({ where: { id }, data: { status }, include: { task: true }, }); } async getReviewStatistics(taskId?: number): Promise<ReviewStatistics> { const where = taskId ? { taskId } : {}; const [ totalReviews, approvedCount, needsChangesCount, approvedWithReservationsCount, ] = await Promise.all([ this.prisma.codeReview.count({ where }), this.prisma.codeReview.count({ where: { ...where, status: 'APPROVED' }, }), this.prisma.codeReview.count({ where: { ...where, status: 'NEEDS_CHANGES' }, }), this.prisma.codeReview.count({ where: { ...where, status: 'APPROVED_WITH_RESERVATIONS' }, }), ]); // Calculate average review time (simplified - could be enhanced with actual review duration tracking) const reviews = await this.prisma.codeReview.findMany({ where, select: { createdAt: true, updatedAt: true }, }); const averageReviewTime = reviews.length > 0 ? reviews.reduce((sum, review) => { const reviewTime = review.updatedAt.getTime() - review.createdAt.getTime(); return sum + reviewTime; }, 0) / reviews.length : null; return { totalReviews, approvedCount, needsChangesCount, approvedWithReservationsCount, averageReviewTime, }; } async count(where?: Prisma.CodeReviewWhereInput): Promise<number> { return this.prisma.codeReview.count({ where }); } async hasApprovedReview(taskId: number): Promise<boolean> { const approvedReview = await this.prisma.codeReview.findFirst({ where: { taskId, status: { in: ['APPROVED', 'APPROVED_WITH_RESERVATIONS'], }, }, }); return !!approvedReview; } async createWithTransaction( data: Prisma.CodeReviewCreateInput, tx?: PrismaTransaction, ): Promise<CodeReviewWithRelations> { const prismaClient = tx || this.prisma; return prismaClient.codeReview.create({ data, include: { task: true }, }); } async updateWithTransaction( id: number, data: UpdateCodeReviewData, tx?: PrismaTransaction, ): Promise<CodeReviewWithRelations> { const prismaClient = tx || this.prisma; return prismaClient.codeReview.update({ where: { id }, data, include: { task: true }, }); } private buildInclude( include?: CodeReviewIncludeOptions, ): Prisma.CodeReviewInclude | undefined { if (!include) return undefined; return { task: include.task, }; } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Hive-Academy/Anubis-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server