← back to Watches

services/affiliate-links.js

36 lines

import pool from '../database/connection.js';
import crypto from 'crypto';

const AFFILIATE_ID = process.env.AFFILIATE_ID || 'omega-platform';

export async function getAffiliatePrograms() {
  const result = await pool.query('SELECT * FROM affiliate_programs WHERE is_active = true');
  return result.rows;
}

export function generateAffiliateLink(baseUrl, watchRef, programId, userId = null) {
  const url = new URL(baseUrl);
  url.searchParams.set('ref', AFFILIATE_ID);
  url.searchParams.set('watch', watchRef);
  if (userId) url.searchParams.set('uid', crypto.createHash('md5').update(userId).digest('hex').slice(0, 8));
  return url.toString();
}

export async function trackClick(programId, watchId, userId, req) {
  await pool.query(`INSERT INTO affiliate_clicks (program_id, watch_id, user_id, ip_address, user_agent) VALUES ($1, $2, $3, $4, $5)`,
    [programId, watchId, userId, req.ip, req.headers['user-agent']]);
}

export async function getClickStats(days = 30) {
  const result = await pool.query(`
    SELECT p.name, COUNT(*) as clicks, COUNT(CASE WHEN c.converted THEN 1 END) as conversions,
           SUM(c.commission) as revenue
    FROM affiliate_clicks c JOIN affiliate_programs p ON c.program_id = p.id
    WHERE c.clicked_at > NOW() - INTERVAL '${days} days'
    GROUP BY p.name
  `);
  return result.rows;
}

export default { getAffiliatePrograms, generateAffiliateLink, trackClick, getClickStats };