// A project's automatic PDF indexing (template lesson core-11): an administrator opts the project in, // naming the collection its uploaded PDFs go into; no row is off. The administrator is recorded, // because the indexing job runs for nobody and re-checks that person's permission before each file. import { forbidden } from "@conusai-kit/core" import { autoIndex } from "../contract/index.js" import { requireCollection } from "./collections.js" import { type KnowledgeDeps, type KnowledgeScope, knowledgeEnabled } from "./ports.js" export interface AutoIndexView { /** The collection uploaded PDFs are indexed into, or null when automatic indexing is off. */ collectionName: string | null } export async function getAutoIndex(deps: Pick, scope: KnowledgeScope): Promise { const row = (await deps.data.forScope(scope).of(autoIndex).list({ limit: 1 })).items[0] return { collectionName: row?.collectionName ?? null } } /** Turns automatic indexing on into `collectionName` (which must exist), or off with `null`. */ export async function setAutoIndex( deps: KnowledgeDeps & { now?: () => number }, scope: KnowledgeScope, collectionName: string | null, ): Promise { if (collectionName !== null) { // The tenant-wall read first: another project's collection answers NotFound, never a policy refusal. await requireCollection(deps, scope, collectionName) if (!(await knowledgeEnabled(deps, scope))) throw forbidden("knowledge is switched off for this project") } await deps.data.unitOfWork.run(scope, async (tx) => { const row = (await tx.of(autoIndex).list({ limit: 1 })).items[0] if (collectionName === null) { if (row) await tx.of(autoIndex).delete(row.id) return } const patch = { collectionName, enabledBy: scope.actor.userId, enabledAt: new Date((deps.now ?? Date.now)()).toISOString(), } if (row) await tx.of(autoIndex).update(row.id, patch, row.version) else await tx.of(autoIndex).insert(patch) }) return { collectionName } }