const BaseRepository = require('../../../src/database/repository'); const logger = require('../../../src/utils/logger'); class CampaignRepository extends BaseRepository { constructor() { super('pg_vt_campaigns'); } /** * Find campaigns with filters * @param {Object} filters - Filter criteria * @param {Object} options - Query options */ async findWithFilters(filters = {}, options = {}) { const criteria = {}; if (filters.site_id) criteria.site_id = filters.site_id; if (filters.campaign_type) criteria.campaign_type = filters.campaign_type; if (filters.status) criteria.status = filters.status; const orderBy = options.orderBy || 'created_at'; const orderDirection = options.orderDirection || 'desc'; const limit = options.limit; return await this.findAll(criteria, { orderBy, orderDirection, limit }); } /** * Get campaign by ID with related data * @param {string} campaignId - Campaign ID */ async findByIdWithDetails(campaignId) { const campaign = await this.findOne({ id: campaignId }); if (!campaign) return null; // Get response count const ResponseRepository = require('./ResponseRepository'); const responseRepo = new ResponseRepository(); const totalResponses = await responseRepo.count({ campaign_id: campaignId }); const answeredCount = await responseRepo.count({ campaign_id: campaignId, answered: true }); return { ...campaign, participation_count: answeredCount, total_invited: totalResponses, participation_percentage: totalResponses > 0 ? ((answeredCount / totalResponses) * 100).toFixed(2) : 0 }; } /** * Update campaign status * @param {string} campaignId - Campaign ID * @param {string} status - New status */ async updateStatus(campaignId, status) { const allowedStatuses = ['draft', 'scheduled', 'active', 'completed', 'cancelled']; if (!allowedStatuses.includes(status)) { throw new Error(`Invalid status: ${status}`); } return await this.updateById(campaignId, { status, updated_at: new Date().toISOString() }); } } module.exports = CampaignRepository;