mirror of
https://github.com/kikootwo/ReadMeABook.git
synced 2026-06-20 05:00:09 +00:00
Implement centralized logging with RMABLogger
Replaces scattered console statements with a unified RMABLogger across backend API routes and services. Adds LOG_LEVEL-based filtering, job-aware database persistence, and context-based logging. Updates documentation to describe the new logging system and usage patterns. Also documents qBittorrent CSRF header fix
This commit is contained in:
@@ -14,6 +14,9 @@ import {
|
||||
isAlreadyRequested,
|
||||
isAlreadySwiped,
|
||||
} from '@/lib/bookdate/helpers';
|
||||
import { RMABLogger } from '@/lib/utils/logger';
|
||||
|
||||
const logger = RMABLogger.create('API.BookDate.Generate');
|
||||
|
||||
async function handler(req: AuthenticatedRequest) {
|
||||
try {
|
||||
@@ -54,7 +57,7 @@ async function handler(req: AuthenticatedRequest) {
|
||||
};
|
||||
|
||||
// Build prompt and call AI (same as recommendations endpoint, but doesn't check cache)
|
||||
console.log('[BookDate] Force generating new recommendations for user:', userId);
|
||||
logger.info('Force generating new recommendations for user', { userId });
|
||||
const prompt = await buildAIPrompt(userId, userPreferences);
|
||||
const aiResponse = await callAI(config.provider, config.model, config.apiKey, prompt);
|
||||
|
||||
@@ -62,7 +65,7 @@ async function handler(req: AuthenticatedRequest) {
|
||||
throw new Error('Invalid AI response format: missing recommendations array');
|
||||
}
|
||||
|
||||
console.log(`[BookDate] AI returned ${aiResponse.recommendations.length} recommendations`);
|
||||
logger.debug('AI returned recommendations', { count: aiResponse.recommendations.length });
|
||||
|
||||
// Match to Audnexus and filter
|
||||
const batchId = `batch_${Date.now()}`;
|
||||
@@ -88,14 +91,14 @@ async function handler(req: AuthenticatedRequest) {
|
||||
const audnexusMatch = await matchToAudnexus(rec.title, rec.author);
|
||||
|
||||
if (!audnexusMatch) {
|
||||
console.warn(`[BookDate] No Audnexus match: "${rec.title}" by ${rec.author}`);
|
||||
logger.warn('No Audnexus match', { title: rec.title, author: rec.author });
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check again if in library with ASIN for exact matching
|
||||
// This catches books that might have different titles (e.g., "The Tenant" vs "The Tenant (Unabridged)")
|
||||
if (await isInLibrary(userId, audnexusMatch.title, audnexusMatch.author, audnexusMatch.asin)) {
|
||||
console.log(`[BookDate] Book "${audnexusMatch.title}" (ASIN: ${audnexusMatch.asin}) is in library, skipping`);
|
||||
logger.debug('Book is in library, skipping', { title: audnexusMatch.title, asin: audnexusMatch.asin });
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -122,12 +125,12 @@ async function handler(req: AuthenticatedRequest) {
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.warn(`[BookDate] Match error for "${rec.title}":`, error);
|
||||
logger.warn('Match error', { title: rec.title, error: error instanceof Error ? error.message : String(error) });
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`[BookDate] Matched ${matched.length} new recommendations`);
|
||||
logger.info('Matched new recommendations', { count: matched.length });
|
||||
|
||||
if (matched.length === 0) {
|
||||
return NextResponse.json(
|
||||
@@ -163,7 +166,7 @@ async function handler(req: AuthenticatedRequest) {
|
||||
});
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('[BookDate] Generate error:', error);
|
||||
logger.error('Generate error', { error: error instanceof Error ? error.message : String(error) });
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: error.message || 'Failed to generate new recommendations',
|
||||
|
||||
Reference in New Issue
Block a user