feat(API-AI-081): add KnowledgeItem.sourceId FK to KnowledgeSource
All checks were successful
Deploy API Server / build-and-deploy (push) Successful in 43s

- Prisma schema: add sourceId field + @relation to KnowledgeSource
- KnowledgeSource: add items[] reverse relation + @index on sourceId
- KnowledgeItemsRepository: accept sourceId in create()
- ImportCandidateService.accept(): pass sourceId to create()
- DocumentImport worker: pass sourceId alongside sourceRef

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
wangdl 2026-06-18 21:54:58 +08:00
parent 76bdba330d
commit 939adcebd3
4 changed files with 10 additions and 1 deletions

View File

@ -247,6 +247,7 @@ model KnowledgeItem {
content String? @db.LongText content String? @db.LongText
summary String? @db.Text summary String? @db.Text
learnable Boolean @default(true) learnable Boolean @default(true)
sourceId String?
sourceType String? @db.VarChar(32) sourceType String? @db.VarChar(32)
sourceRef String? @db.VarChar(500) sourceRef String? @db.VarChar(500)
sourceDeleted Boolean @default(false) sourceDeleted Boolean @default(false)
@ -262,6 +263,7 @@ model KnowledgeItem {
user User @relation(fields: [userId], references: [id]) user User @relation(fields: [userId], references: [id])
knowledgeBase KnowledgeBase @relation(fields: [knowledgeBaseId], references: [id]) knowledgeBase KnowledgeBase @relation(fields: [knowledgeBaseId], references: [id])
source KnowledgeSource? @relation(fields: [sourceId], references: [id])
parent KnowledgeItem? @relation("KnowledgeItemRelations", fields: [parentId], references: [id]) parent KnowledgeItem? @relation("KnowledgeItemRelations", fields: [parentId], references: [id])
children KnowledgeItem[] @relation("KnowledgeItemRelations") children KnowledgeItem[] @relation("KnowledgeItemRelations")
tags KnowledgeItemTag[] tags KnowledgeItemTag[]
@ -270,6 +272,7 @@ model KnowledgeItem {
@@index([knowledgeBaseId]) @@index([knowledgeBaseId])
@@index([parentId]) @@index([parentId])
@@index([itemType]) @@index([itemType])
@@index([sourceId])
} }
model KnowledgeItemRelation { model KnowledgeItemRelation {
@ -881,6 +884,7 @@ model KnowledgeSource {
knowledgeBase KnowledgeBase @relation(fields: [knowledgeBaseId], references: [id]) knowledgeBase KnowledgeBase @relation(fields: [knowledgeBaseId], references: [id])
file UploadedFile? @relation(fields: [fileId], references: [id]) file UploadedFile? @relation(fields: [fileId], references: [id])
chunks KnowledgeChunk[] chunks KnowledgeChunk[]
items KnowledgeItem[]
imports DocumentImport[] imports DocumentImport[]
references SourceReference[] references SourceReference[]
candidates ImportCandidate[] candidates ImportCandidate[]

View File

@ -38,12 +38,14 @@ export class ImportCandidateService {
await this.repository.updateStatus(id, 'ACCEPTED'); await this.repository.updateStatus(id, 'ACCEPTED');
// 生成 KnowledgeItem关联到来源 // 生成 KnowledgeItem关联到来源
const sourceId = (candidate as any).sourceId ?? null;
await this.itemsRepo.create(candidate.userId, candidate.knowledgeBaseId, { await this.itemsRepo.create(candidate.userId, candidate.knowledgeBaseId, {
title: candidate.title, title: candidate.title,
content: (candidate.content as string) ?? '', content: (candidate.content as string) ?? '',
itemType: 'ai_generated', itemType: 'ai_generated',
orderIndex: candidate.orderIndex, orderIndex: candidate.orderIndex,
sourceRef: (candidate as any).sourceId ?? null, sourceId,
sourceRef: sourceId,
}); });
return { status: 'ACCEPTED' }; return { status: 'ACCEPTED' };

View File

@ -49,6 +49,7 @@ export class KnowledgeItemsRepository {
content?: string; content?: string;
parentId?: string; parentId?: string;
itemType?: string; itemType?: string;
sourceId?: string;
sourceType?: string; sourceType?: string;
sourceRef?: string; sourceRef?: string;
durationSeconds?: number; durationSeconds?: number;
@ -65,6 +66,7 @@ export class KnowledgeItemsRepository {
parentId: dto.parentId ?? null, parentId: dto.parentId ?? null,
itemType: dto.itemType ?? 'lesson', itemType: dto.itemType ?? 'lesson',
sourceType, sourceType,
sourceId: dto.sourceId ?? null,
sourceRef: dto.sourceRef ?? null, sourceRef: dto.sourceRef ?? null,
durationSeconds: dto.durationSeconds ?? 0, durationSeconds: dto.durationSeconds ?? 0,
fileSize: dto.fileSize ?? null, fileSize: dto.fileSize ?? null,

View File

@ -69,6 +69,7 @@ export class DocumentImportWorker extends WorkerHost {
content: kp.content, content: kp.content,
itemType: 'lesson', itemType: 'lesson',
orderIndex: kp.suggestedOrder ?? i + 1, orderIndex: kp.suggestedOrder ?? i + 1,
sourceId: sourceId,
sourceRef: sourceId, sourceRef: sourceId,
}); });
} }