import { db } from '$lib/server/db'; import { verseSubmissions, dailyVerses, user } from '$lib/server/db/schema'; import { eq, asc } from 'drizzle-orm'; import { getBookById } from '$lib/server/bible'; import { isAdmin } from '$lib/server/admin'; import type { PageServerLoad } from './$types'; export type ScheduledVerseRow = { scheduledDate: string; reference: string | null; verseText: string | null; bookId: string | null; bookName: string | null; selectedBookId: string; selectedChapter: number; selectedVerse: number; submittedAt: number; // server UTC millis submitterEmail: string | null; submitterName: string | null; submitterDeleted: boolean; }; export const load: PageServerLoad = async ({ locals }) => { // Not authenticated → signal the client to show the sign-in flow // (same pattern as /progress, /stats). if (!locals.user) { return { rows: [] as ScheduledVerseRow[], requiresAuth: true, authorized: false, user: null, session: null, }; } // Authenticated but wrong account → plain access-denied state. Don't leak // the existence of privileged data; just render "not authorized". if (!isAdmin(locals.user.email)) { return { rows: [] as ScheduledVerseRow[], requiresAuth: false, authorized: false, user: locals.user, session: locals.session, }; } const joined = await db .select({ scheduledDate: verseSubmissions.scheduledDate, selectedBookId: verseSubmissions.selectedBookId, selectedChapter: verseSubmissions.selectedChapter, selectedVerse: verseSubmissions.selectedVerse, submittedAt: verseSubmissions.submittedAt, dailyDate: dailyVerses.date, bookId: dailyVerses.bookId, reference: dailyVerses.reference, verseText: dailyVerses.verseText, userId: verseSubmissions.userId, userEmail: user.email, userFirstName: user.firstName, userLastName: user.lastName, }) .from(verseSubmissions) // LEFT JOINs so deleted accounts (ON DELETE SET NULL) still render — // the scheduled verse plays out regardless. .leftJoin(dailyVerses, eq(verseSubmissions.scheduledDate, dailyVerses.date)) .leftJoin(user, eq(verseSubmissions.userId, user.id)) .orderBy(asc(verseSubmissions.scheduledDate)); const rows: ScheduledVerseRow[] = joined.map((r) => { const book = r.bookId ? getBookById(r.bookId) : undefined; return { scheduledDate: r.scheduledDate, reference: r.reference, verseText: r.verseText, bookId: r.bookId, bookName: book?.name ?? null, selectedBookId: r.selectedBookId, selectedChapter: r.selectedChapter, selectedVerse: r.selectedVerse, submittedAt: r.submittedAt, submitterEmail: r.userEmail, submitterName: [r.userFirstName, r.userLastName].filter(Boolean).join(' ') || null, // userId is null when the account was deleted (ON DELETE SET NULL) submitterDeleted: r.userId === null, }; }); return { rows, requiresAuth: false, authorized: true, user: locals.user, session: locals.session, }; };