import { Injectable } from '@nestjs/common'; import { EntityManager, EntityRepository } from '@mikro-orm/postgresql'; import { FilterQuery } from '@mikro-orm/core'; import { Contact } from '../entities/contact.entity'; import { PaginatedResult } from 'src/common/interfaces/pagination.interface'; import { ContactScope, ContactStatusEnum } from '../interface/interface'; type FindContactsOpts = { page?: number; limit?: number; search?: string; orderBy?: string; order?: 'asc' | 'desc'; status?: ContactStatusEnum; scope?: ContactScope; restaurantId?: string; }; @Injectable() export class ContactRepository extends EntityRepository { constructor(readonly em: EntityManager) { super(em, Contact); } /** * Find contacts with pagination and optional filters. * Supports: search (subject/content/phone), status, ordering. */ async findAllPaginated(opts: FindContactsOpts = {}): Promise> { const { page = 1, limit = 10, search, scope, orderBy = 'createdAt', order = 'desc', status, restaurantId } = opts; const offset = (page - 1) * limit; const where: FilterQuery = {}; if (status) { where.status = status; } if (scope) { where.scope = scope; } if (restaurantId) { where.restaurant = restaurantId; } if (search) { const pattern = `%${search}%`; where.$or = [{ subject: { $ilike: pattern } }, { content: { $ilike: pattern } }, { phone: { $ilike: pattern } }]; } const [data, total] = await this.findAndCount(where, { limit, offset, orderBy: { [orderBy]: order.toLowerCase() as 'asc' | 'desc' }, }); const totalPages = Math.ceil(total / limit); return { data, meta: { total, page, limit, totalPages, }, }; } }