62 lines
2.5 KiB
TypeScript
62 lines
2.5 KiB
TypeScript
// The automatic intake's enabling-person metadata is an account-data share. The
|
|
// account kernel supplies the subject; this has no public procedure or bearer.
|
|
import type { TenantScope } from "@conusai-kit/core"
|
|
import { systemActor } from "@conusai-kit/core/worker"
|
|
import { DATA_SOURCE, SYSTEM_DATA } from "@conusai-kit/data"
|
|
import { type AccountDataContext, type AccountDataContribution, servedProjects } from "@conusai-kit/tenancy"
|
|
import { autoIndex } from "../contract/index.js"
|
|
|
|
async function* ownedOptIns(context: AccountDataContext) {
|
|
context.signal?.throwIfAborted()
|
|
const data = context.container.resolve(DATA_SOURCE)
|
|
const system = context.container.resolve(SYSTEM_DATA)
|
|
for await (const project of servedProjects(system)) {
|
|
context.signal?.throwIfAborted()
|
|
const scope: TenantScope = { level: "project", ...project, actor: systemActor("knowledge.account") }
|
|
for (let cursor: string | undefined; ; ) {
|
|
const page = await data
|
|
.forScope(scope)
|
|
.of(autoIndex)
|
|
.list({
|
|
where: [{ field: "enabledBy", op: "eq", value: context.subject }],
|
|
limit: 100,
|
|
...(cursor === undefined ? {} : { cursor }),
|
|
})
|
|
for (const row of page.items) yield { scope, row }
|
|
if (!page.hasMore || page.cursor === undefined) break
|
|
cursor = page.cursor
|
|
}
|
|
}
|
|
}
|
|
|
|
export const knowledgeAccountData: AccountDataContribution = {
|
|
key: "knowledge",
|
|
async export(context) {
|
|
const automaticIndexing = []
|
|
for await (const { scope, row } of ownedOptIns(context)) {
|
|
automaticIndexing.push({
|
|
orgId: scope.orgId,
|
|
workspaceId: scope.workspaceId,
|
|
projectId: scope.projectId,
|
|
collectionName: row.collectionName,
|
|
enabledAt: row.enabledAt,
|
|
})
|
|
}
|
|
return { automaticIndexing }
|
|
},
|
|
async erase(context) {
|
|
const data = context.container.resolve(DATA_SOURCE)
|
|
for await (const { scope, row } of ownedOptIns(context)) {
|
|
context.signal?.throwIfAborted()
|
|
await data.unitOfWork.run(scope, async (tx) => {
|
|
const repository = tx.of(autoIndex)
|
|
const current = repository.lock ? await repository.lock(row.id) : await repository.get(row.id)
|
|
// A different administrator may have replaced the opt-in since discovery.
|
|
if (!current || current.enabledBy !== context.subject) return
|
|
if (!repository.lock) await repository.update(current.id, {}, current.version)
|
|
await repository.delete(current.id)
|
|
})
|
|
}
|
|
},
|
|
}
|