mongo fix
This commit is contained in:
+170
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
* Data access layer for server components.
|
||||
*
|
||||
* These functions query MongoDB via Prisma and are called directly by
|
||||
* Next.js server components. The /api/* routes exist for external consumers
|
||||
* and for client-side infinite-scroll fetching.
|
||||
*/
|
||||
|
||||
import { prisma } from "@/lib/db";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Types
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export type BookMeta = {
|
||||
book: string;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
export type VerseRecord = {
|
||||
id: string;
|
||||
book: string;
|
||||
division: string | null;
|
||||
chapter: number;
|
||||
verse: number;
|
||||
verseEnd: number | null;
|
||||
reference: string;
|
||||
bookTitle: string;
|
||||
devanagari: string;
|
||||
bengali: string | null;
|
||||
transliteration: string;
|
||||
synonyms: { word: string; meanings: string[] }[];
|
||||
translation: string;
|
||||
purport: string[];
|
||||
};
|
||||
|
||||
export type VerseIndexEntry = {
|
||||
verse: number;
|
||||
verseEnd: number | null;
|
||||
reference: string;
|
||||
};
|
||||
|
||||
export type PaginatedVerses = {
|
||||
verses: VerseRecord[];
|
||||
total: number;
|
||||
page: number;
|
||||
limit: number;
|
||||
totalPages: number;
|
||||
hasMore: boolean;
|
||||
};
|
||||
|
||||
export type GlossaryRecord = {
|
||||
id: string;
|
||||
term: string;
|
||||
definition: string;
|
||||
definitionHtml: string;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Book meta
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get all book metas — each has { book, ...data } where data is the intro.json blob.
|
||||
*/
|
||||
export async function getAllBooks(): Promise<BookMeta[]> {
|
||||
const metas = await prisma.bookMeta.findMany();
|
||||
return metas.map((m) => ({
|
||||
book: m.book,
|
||||
...(m.data as Record<string, unknown>),
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single book's meta by slug ("bg", "sb", "cc").
|
||||
*/
|
||||
export async function getBookMeta(book: string): Promise<BookMeta | null> {
|
||||
const meta = await prisma.bookMeta.findUnique({ where: { book } });
|
||||
if (!meta) return null;
|
||||
return { book: meta.book, ...(meta.data as Record<string, unknown>) };
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Verse index (lightweight — for sidebar)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get the verse index for a chapter — returns only verse number, verseEnd,
|
||||
* and reference for every verse. This is lightweight enough to fetch all at
|
||||
* once even for chapters with 400+ verses (each entry is ~50 bytes).
|
||||
*
|
||||
* - BG: division is null
|
||||
* - SB: division is canto number as string ("1", "2", …)
|
||||
* - CC: division is līlā key ("adi", "madhya", "antya")
|
||||
*/
|
||||
export async function getChapterVerseIndex(
|
||||
book: string,
|
||||
division: string | null,
|
||||
chapter: number,
|
||||
): Promise<VerseIndexEntry[]> {
|
||||
const entries = await prisma.verse.findMany({
|
||||
where: { book, division, chapter },
|
||||
orderBy: { verse: "asc" },
|
||||
select: {
|
||||
verse: true,
|
||||
verseEnd: true,
|
||||
reference: true,
|
||||
},
|
||||
});
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Verses (paginated)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const DEFAULT_PAGE_SIZE = 20;
|
||||
|
||||
/**
|
||||
* Get a page of verses for a given book + division + chapter.
|
||||
*
|
||||
* Returns the verses for the requested page along with pagination metadata
|
||||
* so the client knows whether to fetch more.
|
||||
*/
|
||||
export async function getChapterVerses(
|
||||
book: string,
|
||||
division: string | null,
|
||||
chapter: number,
|
||||
page: number = 1,
|
||||
limit: number = DEFAULT_PAGE_SIZE,
|
||||
): Promise<PaginatedVerses> {
|
||||
const skip = (page - 1) * limit;
|
||||
|
||||
const where = { book, division, chapter };
|
||||
|
||||
const [verses, total] = await Promise.all([
|
||||
prisma.verse.findMany({
|
||||
where,
|
||||
orderBy: { verse: "asc" },
|
||||
skip,
|
||||
take: limit,
|
||||
}),
|
||||
prisma.verse.count({ where }),
|
||||
]);
|
||||
|
||||
return {
|
||||
verses: verses as unknown as VerseRecord[],
|
||||
total,
|
||||
page,
|
||||
limit,
|
||||
totalPages: Math.ceil(total / limit),
|
||||
hasMore: skip + verses.length < total,
|
||||
};
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Glossary
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get all glossary entries, ordered alphabetically by term.
|
||||
*/
|
||||
export async function getAllGlossaryEntries(): Promise<GlossaryRecord[]> {
|
||||
const entries = await prisma.glossaryEntry.findMany({
|
||||
orderBy: { term: "asc" },
|
||||
});
|
||||
|
||||
return entries as unknown as GlossaryRecord[];
|
||||
}
|
||||
Reference in New Issue
Block a user