/**
 * Pure query-building helpers for the aggregate `GET /posts` admin endpoint.
 *
 * Kept dependency-free (no Prisma, no DB) so the filter/sort logic that drives
 * cross-collection pagination is unit-testable in isolation. The route handler
 * in `api/handlers.ts` composes these into the actual Prisma queries.
 */
const DOCUMENT_STATUSES = new Set(['DRAFT', 'PUBLISHED', 'SCHEDULED', 'ARCHIVED']);
/**
 * Which collections a query should actually scan: a single requested type when
 * it's allowed, otherwise every allowed post collection. An unknown/forbidden
 * requested type collapses to an empty set so the query returns nothing rather
 * than leaking other collections.
 */
export function resolveQueryCollections(input) {
    const { allowedCollections, postType } = input;
    if (postType && postType !== 'all') {
        return allowedCollections.includes(postType) ? [postType] : [];
    }
    return allowedCollections;
}
/**
 * Build the Prisma `where` filter for the posts query. Returns a plain object
 * (typed loosely as the Prisma document filter) so it can be asserted in tests
 * without importing Prisma types.
 */
export function buildPostsWhere(input) {
    const collections = resolveQueryCollections(input);
    const where = {
        collection: { in: collections },
        deletedAt: null,
    };
    if (input.status && input.status !== 'all' && DOCUMENT_STATUSES.has(input.status)) {
        where.status = input.status;
    }
    if (input.author && input.author !== 'all') {
        where.createdById = input.author;
    }
    const search = input.search?.trim();
    if (search) {
        where.OR = [
            { title: { contains: search, mode: 'insensitive' } },
            { slug: { contains: search, mode: 'insensitive' } },
            { plainText: { contains: search, mode: 'insensitive' } },
        ];
    }
    return where;
}
/**
 * Map the UI sort field to a Prisma `orderBy`. `date`/`type`/`status`/`title`
 * map to scalar columns and `author` orders by the related user's name. `seo`
 * has no DB-sortable column (the score lives in the JSON `data` blob), so it
 * falls back to most-recently-updated — callers should treat seo as a
 * best-effort sort.
 */
export function buildPostsOrderBy(sortBy = 'date', dir = 'desc') {
    switch (sortBy) {
        case 'title':
            return { title: dir };
        case 'status':
            return { status: dir };
        case 'type':
            return { collection: dir };
        case 'author':
            return { createdBy: { name: dir } };
        case 'seo':
        case 'date':
        default:
            return { updatedAt: dir };
    }
}
/** Extract a numeric SEO score from a document's JSON data, if present. */
export function extractSeoScore(data) {
    if (!data || typeof data !== 'object')
        return null;
    const d = data;
    for (const key of ['seoScore', 'seo_score', 'metaScore']) {
        const v = d[key];
        if (typeof v === 'number' && Number.isFinite(v))
            return v;
    }
    return null;
}
//# sourceMappingURL=query.js.map