47 lines
2.0 KiB
TypeScript
47 lines
2.0 KiB
TypeScript
// 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<KnowledgeDeps, "data">, scope: KnowledgeScope): Promise<AutoIndexView> {
|
|
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<AutoIndexView> {
|
|
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 }
|
|
}
|