import { getCollection } from '../../lib/datastore.js'; import type { FilterMap } from '@bytelyst/datastore'; import type { IntakeRuleDoc, IntakeJobDoc, IntakeJobStatus } from './types.js'; // ── Intake Rules ───────────────────────────────────────────────── function rulesCollection() { return getCollection('note_intake_rules', '/userId'); } export async function createIntakeRule(doc: IntakeRuleDoc): Promise { return rulesCollection().create(doc); } export async function getIntakeRule(id: string, userId: string): Promise { return rulesCollection().findById(id, userId); } export async function listIntakeRules( userId: string, productId: string, ): Promise { const filter: FilterMap = { productId }; // Fetch both user rules and built-in rules const userRules = await rulesCollection().findMany({ filter: { ...filter, userId }, sort: { priority: 1 }, limit: 100, offset: 0 }); const builtinRules = await rulesCollection().findMany({ filter: { ...filter, userId: '__builtin__' }, sort: { priority: 1 }, limit: 100, offset: 0 }); return [...userRules, ...builtinRules]; } export async function updateIntakeRule( id: string, userId: string, updates: Partial, ): Promise { return rulesCollection().update(id, userId, updates); } export async function deleteIntakeRule(id: string, userId: string): Promise { await rulesCollection().delete(id, userId); } export async function upsertBuiltinIntakeRule( rule: Omit, ): Promise { const now = new Date().toISOString(); return rulesCollection().upsert({ ...rule, createdAt: now, updatedAt: now, }); } // ── Intake Jobs ────────────────────────────────────────────────── function jobsCollection() { return getCollection('note_intake_jobs', '/userId'); } export async function createIntakeJob(doc: IntakeJobDoc): Promise { return jobsCollection().create(doc); } export async function getIntakeJob(id: string, userId: string): Promise { return jobsCollection().findById(id, userId); } export async function listIntakeJobs( userId: string, productId: string, options?: { statuses?: IntakeJobStatus[]; since?: string; limit?: number; offset?: number }, ): Promise { const filter: FilterMap = { userId, productId }; // If a single status is provided, use it as a direct filter for efficiency if (options?.statuses && options.statuses.length === 1) { filter.status = options.statuses[0]; } const limit = options?.limit ?? 20; // Fetch more if we need to filter client-side for multiple statuses const fetchLimit = options?.statuses && options.statuses.length > 1 ? Math.min(limit * 3, 100) : limit; let jobs = await jobsCollection().findMany({ filter, sort: { startedAt: -1 }, limit: fetchLimit, offset: options?.offset ?? 0, }); // Client-side filter for multiple statuses if (options?.statuses && options.statuses.length > 1) { const statusSet = new Set(options.statuses); jobs = jobs.filter((j) => statusSet.has(j.status)); jobs = jobs.slice(0, limit); } return jobs; } export async function updateIntakeJob( id: string, userId: string, updates: Partial, ): Promise { return jobsCollection().update(id, userId, updates); }