import { AudienceCriteria, AudienceQueryOptions, AudienceExecutionResult } from '../types' import { CriteriaParser } from '../builders/CriteriaParser' /** * Executor para audiências estáticas (baseadas em filtros) * * NOTA: Este executor precisa de uma instância de ContactRepository * que deve ser injetada externamente quando usado no reachy-api */ export class StaticAudienceExecutor { private contactRepository: any constructor(contactRepository?: any) { this.contactRepository = contactRepository } /** * Define o ContactRepository */ setContactRepository(repository: any) { this.contactRepository = repository } /** * Executa query de audiência estática e retorna IDs de contatos */ async execute( criteria: AudienceCriteria, options: AudienceQueryOptions ): Promise { const startTime = Date.now() try { if (!this.contactRepository) { throw new Error('ContactRepository não foi configurado. Use setContactRepository() antes de executar.') } const parsed = CriteriaParser.parse(criteria) const validation = CriteriaParser.validate(parsed) if (!validation.valid) { return { contactIds: new Set(), contacts: [], count: 0, metadata: { executionTime: Date.now() - startTime, criteriaType: 'static' } } } const contactIds = await this.contactRepository.getContactIdsByAudienceCriteriaV2( options.organizationId, options.projectId, parsed ) let contacts: any[] | undefined if (options.includeCount || options.pagination) { const { page = 1, limit = 10 } = options.pagination || {} const contactIdsArray = Array.from(contactIds) if (contactIdsArray.length > 0) { const paginatedIds = contactIdsArray.slice((page - 1) * limit, page * limit) const { data } = await this.contactRepository.findByIds( options.organizationId, options.projectId, paginatedIds ) contacts = data || [] } } return { contactIds, contacts, count: contactIds.size, metadata: { executionTime: Date.now() - startTime, criteriaType: 'static' } } } catch (error) { throw error } } /** * Executa query e retorna apenas contagem (mais rápido) */ async executeCount( criteria: AudienceCriteria, options: Omit ): Promise { const result = await this.execute(criteria, { ...options, includeCount: true }) return result.count } }