feat: 完成 E 群組 — 關係子系統
- RelationshipService:E-1 未知對象自動建檔(禮貌+防備=intimacy/trust=0)、 E-3 親密度五階分層+跨階事件(@nestjs/event-emitter,StageChangeLogService 獨立訂閱)、 E-4 久未互動時親密度半衰期衰減並標記「久未見」 - SentimentLedgerService:E-2 關係帳本,負向事件套用放大係數,驗證同等級正負事件淨值為負 - IntentInterpreterService:E-6 依親密度將同一句模稜兩可的話解讀為玩笑或冒犯 - KeywordMemoryRetriever(C-6)擴充 E-5:新增 relatedUserId 加權,retrieve() 簽名改為接受 options 物件 - schema 新增 EpisodicMemory.relatedUserId,並補上所有子表對父表的 onDelete: Cascade/SetNull (E-2 測試時發現先前 B 群組遺漏這些規則會導致刪除關係時外鍵違反) - apps/api 新增 /relationships/* 端點作為引擎驗證介面 - scripts/smoke/E.mjs:涵蓋 E-1~E-6 全部驗收情境 npm run restart && npm run smoke -- E 皆通過(E-V),A/B/C/D 群組冒煙測試無回歸。 本次另排除一個本機環境限定的 Prisma CLI 網路 checkpoint 卡住問題,並從一次部分套用的 migration 中手動恢復資料庫一致性(過程記錄於 todo.md 實作記錄,供後續群組參考)。
This commit is contained in:
+13
-10
@@ -50,7 +50,8 @@ model User {
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
relationships Relationship[]
|
||||
relationships Relationship[]
|
||||
relatedMemories EpisodicMemory[]
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
@@ -72,7 +73,7 @@ model Work {
|
||||
model Character {
|
||||
id String @id @default(cuid())
|
||||
workId String?
|
||||
work Work? @relation(fields: [workId], references: [id])
|
||||
work Work? @relation(fields: [workId], references: [id], onDelete: SetNull)
|
||||
|
||||
source CharacterSource
|
||||
buildStatus CharacterBuildStatus @default(CANDIDATE)
|
||||
@@ -102,7 +103,7 @@ model Character {
|
||||
model CharacterAlias {
|
||||
id String @id @default(cuid())
|
||||
characterId String
|
||||
character Character @relation(fields: [characterId], references: [id])
|
||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||
formalName String // 正式名
|
||||
nickname String? // 暱稱
|
||||
calledByOthers String? // 他人稱呼(作品中其他角色如何稱呼)
|
||||
@@ -114,7 +115,7 @@ model CharacterAlias {
|
||||
model EpisodicMemory {
|
||||
id String @id @default(cuid())
|
||||
characterId String
|
||||
character Character @relation(fields: [characterId], references: [id])
|
||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||
content String
|
||||
occurredAt DateTime // 發生時間
|
||||
emotionTag EmotionTag
|
||||
@@ -123,6 +124,8 @@ model EpisodicMemory {
|
||||
lastRetrievedAt DateTime?
|
||||
source MemorySource
|
||||
weight Float @default(1) // 權重(供遺忘/檢索排序使用)
|
||||
relatedUserId String? // 這段記憶與哪位使用者相關(E-5 關係加權檢索用)
|
||||
relatedUser User? @relation(fields: [relatedUserId], references: [id], onDelete: SetNull)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("episodic_memories")
|
||||
@@ -131,7 +134,7 @@ model EpisodicMemory {
|
||||
model SemanticMemory {
|
||||
id String @id @default(cuid())
|
||||
characterId String
|
||||
character Character @relation(fields: [characterId], references: [id])
|
||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||
fact String // 去情境化事實
|
||||
about String // 對象(關於誰/什麼)
|
||||
createdAt DateTime @default(now())
|
||||
@@ -142,7 +145,7 @@ model SemanticMemory {
|
||||
model ProceduralRule {
|
||||
id String @id @default(cuid())
|
||||
characterId String
|
||||
character Character @relation(fields: [characterId], references: [id])
|
||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||
situation String // 情境
|
||||
responsePattern String // 回應模式
|
||||
weight Float @default(1)
|
||||
@@ -155,7 +158,7 @@ model ProceduralRule {
|
||||
model EmotionState {
|
||||
id String @id @default(cuid())
|
||||
characterId String @unique
|
||||
character Character @relation(fields: [characterId], references: [id])
|
||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||
|
||||
calm Float @default(100) // 平靜
|
||||
joy Float @default(0) // 愉悅
|
||||
@@ -172,9 +175,9 @@ model EmotionState {
|
||||
model Relationship {
|
||||
id String @id @default(cuid())
|
||||
characterId String
|
||||
character Character @relation(fields: [characterId], references: [id])
|
||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
intimacy Int @default(0) // 親密度 0~100
|
||||
trust Int @default(0) // 信任度 0~100
|
||||
@@ -195,7 +198,7 @@ model Relationship {
|
||||
model SentimentLedgerEntry {
|
||||
id String @id @default(cuid())
|
||||
relationshipId String
|
||||
relationship Relationship @relation(fields: [relationshipId], references: [id])
|
||||
relationship Relationship @relation(fields: [relationshipId], references: [id], onDelete: Cascade)
|
||||
date DateTime
|
||||
event String
|
||||
weight Float // 允許正負:正向事件為正值,負向事件為負值
|
||||
|
||||
Reference in New Issue
Block a user