feat: M2-06 — Artifact model + KnowledgeItem.learnable + Admin AAPI
All checks were successful
Deploy API Server / build-and-deploy (push) Successful in 39s

- Artifact base model for future FlashcardSet/Quiz/StudyGuide
- KnowledgeItem.learnable boolean (default true) for M3 LearningSession
- Admin AAPI: GET candidates (by status/kbId), GET items (by kbId)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
WangDL 2026-05-24 13:34:24 +08:00
parent 68540b0d67
commit 06351c7381
3 changed files with 53 additions and 0 deletions

View File

@ -0,0 +1,16 @@
ALTER TABLE `KnowledgeItem` ADD COLUMN `learnable` BOOLEAN NOT NULL DEFAULT true;
CREATE TABLE IF NOT EXISTS `Artifact` (
`id` VARCHAR(191) NOT NULL,
`userId` VARCHAR(191) NOT NULL,
`kbId` VARCHAR(191) NOT NULL,
`type` VARCHAR(32) NOT NULL,
`title` VARCHAR(255) NOT NULL,
`configJson` JSON NULL,
`status` VARCHAR(16) NOT NULL DEFAULT 'draft',
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` DATETIME(3) NOT NULL,
INDEX `Artifact_userId_idx`(`userId`),
INDEX `Artifact_kbId_idx`(`kbId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

View File

@ -185,6 +185,21 @@ model KnowledgeBase {
@@index([status]) @@index([status])
} }
model Artifact {
id String @id @default(cuid())
userId String
kbId String
type String @db.VarChar(32)
title String @db.VarChar(255)
configJson Json?
status String @default("draft") @db.VarChar(16)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([userId])
@@index([kbId])
}
model KnowledgeItem { model KnowledgeItem {
id String @id @default(cuid()) id String @id @default(cuid())
userId String userId String
@ -194,6 +209,7 @@ model KnowledgeItem {
title String @db.VarChar(255) title String @db.VarChar(255)
content String? @db.LongText content String? @db.LongText
summary String? @db.Text summary String? @db.Text
learnable Boolean @default(true)
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)

View File

@ -67,4 +67,25 @@ export class AdminKnowledgeController {
take: 50, take: 50,
}); });
} }
// ── Candidates ──
@Get('candidates')
@ApiOperation({ summary: '候选知识点列表' })
async candidates(@Query('status') status?: string, @Query('kbId') kbId?: string) {
const where: any = {};
if (status) where.status = status;
if (kbId) where.knowledgeBaseId = kbId;
return this.prisma.importCandidate.findMany({ where, orderBy: { createdAt: 'desc' }, take: 100 });
}
// ── Knowledge items ──
@Get('items')
@ApiOperation({ summary: '知识点列表(管理员)' })
async items(@Query('kbId') kbId?: string, @Query('limit') limit = '50') {
const where: any = { deletedAt: null };
if (kbId) where.knowledgeBaseId = kbId;
return this.prisma.knowledgeItem.findMany({ where, orderBy: { createdAt: 'desc' }, take: parseInt(limit) });
}
} }