105 lines
3.3 KiB
JavaScript
105 lines
3.3 KiB
JavaScript
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();
|