Add reported-issues, Goodreads sync & notifs

Introduce user-reported-issues and Goodreads shelf sync features and wire them into notifications. Adds Prisma migrations and schema changes (ReportedIssue, GoodreadsShelf, GoodreadsBookMapping), API endpoints for reporting (POST /audiobooks/[asin]/report-issue) and admin management (list, resolve/dismiss, replace), and an admin UI section to view/dismiss/replace reported issues. Adds a new notification event (issue_reported) with updates to notification schemas, docs and provider handling, plus a notification-events constants file. Refactors request creation to use createRequestForUser service, adds a Goodreads sync processor/service/hooks/UI modals, a scrape-resilience util, and related tests and minor integration updates.
This commit is contained in:
kikootwo
2026-02-11 16:49:55 -05:00
parent b013538b63
commit 20c8fb0898
69 changed files with 4167 additions and 766 deletions
@@ -8,34 +8,28 @@
import { getNotificationService } from '../services/notification';
import { RMABLogger } from '../utils/logger';
import type { SendNotificationPayload } from '../services/job-queue.service';
export interface SendNotificationPayload {
jobId?: string;
event: 'request_pending_approval' | 'request_approved' | 'request_available' | 'request_error';
requestId: string;
title: string;
author: string;
userName: string;
message?: string;
timestamp: Date;
}
// Re-export for consumers that import from this module
export type { SendNotificationPayload } from '../services/job-queue.service';
/**
* Process send notification job
* Calls NotificationService to send notifications to all enabled backends
*/
export async function processSendNotification(payload: SendNotificationPayload): Promise<void> {
const { event, requestId, title, author, userName, message, jobId } = payload;
const { event, requestId, issueId, title, author, userName, message, jobId } = payload;
const logger = RMABLogger.forJob(jobId, 'SendNotification');
logger.info(`Processing notification: ${event}`, { requestId });
logger.info(`Processing notification: ${event}`, { requestId: requestId || issueId });
try {
const notificationService = getNotificationService();
await notificationService.sendNotification({
event,
requestId,
issueId,
title,
author,
userName,