const CoffeeRepository = require('../../repositories/subscriptions/CoffeeRepository'); const UnitOfWork = require('../../database/UnitOfWork'); const { logger } = require('../../middleware/logger'); function validate(data) { const errors = []; if (!data.title || String(data.title).trim() === '') errors.push('title'); if (!data.description || String(data.description).trim() === '') errors.push('description'); const price = Number(data.price); if (!Number.isFinite(price) || price < 0) errors.push('price'); if (typeof data.state !== 'boolean') errors.push('state'); if (data.currency && String(data.currency).length > 3) errors.push('currency'); if (typeof data.is_featured !== 'boolean') errors.push('is_featured'); // Enforce fixed billing defaults (month/1) if provided differently if (data.billing_interval && data.billing_interval !== 'month') errors.push('billing_interval'); if (data.interval_count && Number(data.interval_count) !== 1) errors.push('interval_count'); return errors; } class CoffeeService { async list() { return CoffeeRepository.listAll(); } async get(id) { return CoffeeRepository.getById(id); } async create(data) { // Force billing defaults data.billing_interval = 'month'; data.interval_count = 1; const errors = validate(data); if (errors.length) { logger.warn('[CoffeeService.create] validation_failed', { errors }); throw Object.assign(new Error('Validation failed'), { code: 'VALIDATION_ERROR', errors }); } const uow = new UnitOfWork(); try { await uow.start(); const result = await CoffeeRepository.create(data, uow.connection); await uow.commit(); return result; } catch (e) { try { await uow.rollback(e); } catch(_) {} throw e; } } async update(id, data) { // Keep billing values fixed regardless of incoming payload data.billing_interval = 'month'; data.interval_count = 1; const errors = validate(data); if (errors.length) { logger.warn('[CoffeeService.update] validation_failed', { id, errors }); throw Object.assign(new Error('Validation failed'), { code: 'VALIDATION_ERROR', errors }); } const uow = new UnitOfWork(); try { await uow.start(); await CoffeeRepository.update(id, data, uow.connection); const updated = await CoffeeRepository.getById(id, uow.connection); await uow.commit(); return updated; } catch (e) { try { await uow.rollback(e); } catch(_) {} throw e; } } async setState(id, state) { const uow = new UnitOfWork(); try { await uow.start(); await CoffeeRepository.setState(id, !!state, uow.connection); const updated = await CoffeeRepository.getById(id, uow.connection); await uow.commit(); return updated; } catch (e) { try { await uow.rollback(e); } catch(_) {} throw e; } } async delete(id) { const uow = new UnitOfWork(); try { await uow.start(); const ok = await CoffeeRepository.delete(id, uow.connection); await uow.commit(); return ok; } catch (e) { try { await uow.rollback(e); } catch(_) {} throw e; } } async listActive() { return CoffeeRepository.listActive(); } } module.exports = new CoffeeService();