tududi/backend/modules/inbox/service.js
Chris 542be2c1e9
Fix bug 366 (#764)
* Optimize DB

* Clean up names

* fixup! Clean up names

* fixup! fixup! Clean up names
2026-01-07 18:18:07 +02:00

154 lines
4 KiB
JavaScript

'use strict';
const _ = require('lodash');
const inboxRepository = require('./repository');
const { PUBLIC_ATTRIBUTES } = require('./repository');
const {
validateContent,
validateUid,
validateSource,
buildTitleFromContent,
} = require('./validation');
const { NotFoundError } = require('../../shared/errors');
const { processInboxItem } = require('./inboxProcessingService');
class InboxService {
/**
* Get all active inbox items for a user.
* Supports pagination if limit/offset provided.
*/
async getAll(userId, { limit, offset } = {}) {
const hasPagination = limit !== undefined || offset !== undefined;
if (hasPagination) {
const parsedLimit = parseInt(limit, 10) || 20;
const parsedOffset = parseInt(offset, 10) || 0;
const [items, totalCount] = await Promise.all([
inboxRepository.findAllActive(userId, {
limit: parsedLimit,
offset: parsedOffset,
}),
inboxRepository.countActive(userId),
]);
return {
items,
pagination: {
total: totalCount,
limit: parsedLimit,
offset: parsedOffset,
hasMore: parsedOffset + items.length < totalCount,
},
};
}
// Return simple array for backward compatibility
return inboxRepository.findAllActive(userId);
}
/**
* Get a single inbox item by UID.
*/
async getByUid(userId, uid) {
validateUid(uid);
const item = await inboxRepository.findByUidPublic(userId, uid);
if (!item) {
throw new NotFoundError('Inbox item not found.');
}
return item;
}
/**
* Create a new inbox item.
*/
async create(userId, { content, source }) {
const validatedContent = validateContent(content);
const validatedSource = validateSource(source);
const title = buildTitleFromContent(validatedContent);
const item = await inboxRepository.createForUser(userId, {
content: validatedContent,
title,
source: validatedSource,
});
return _.pick(item, PUBLIC_ATTRIBUTES);
}
/**
* Update an inbox item.
*/
async update(userId, uid, { content, status }) {
validateUid(uid);
const item = await inboxRepository.findByUid(userId, uid);
if (!item) {
throw new NotFoundError('Inbox item not found.');
}
const updateData = {};
if (content !== undefined && content !== null) {
const validatedContent = validateContent(content);
updateData.content = validatedContent;
updateData.title = buildTitleFromContent(validatedContent);
}
if (status !== undefined && status !== null) {
updateData.status = status;
}
await inboxRepository.updateItem(item, updateData);
return _.pick(item, PUBLIC_ATTRIBUTES);
}
/**
* Soft delete an inbox item.
*/
async delete(userId, uid) {
validateUid(uid);
const item = await inboxRepository.findByUid(userId, uid);
if (!item) {
throw new NotFoundError('Inbox item not found.');
}
await inboxRepository.softDelete(item);
return { message: 'Inbox item successfully deleted' };
}
/**
* Mark an inbox item as processed.
*/
async process(userId, uid) {
validateUid(uid);
const item = await inboxRepository.findByUid(userId, uid);
if (!item) {
throw new NotFoundError('Inbox item not found.');
}
await inboxRepository.markProcessed(item);
return _.pick(item, PUBLIC_ATTRIBUTES);
}
/**
* Analyze text content without creating an inbox item.
*/
analyzeText(content) {
validateContent(content);
return processInboxItem(content);
}
}
module.exports = new InboxService();