feat: 完成 L 群組 — 戀愛關係軸與內容尺度
戀愛軸雙軸模型(Relationship 新增心動值/戀愛階段欄位,與親密度獨立、事件 驅動、衰減快)、告白事件狀態機(可拒絕、尷尬期、連續失敗傷關係、立即再 推進觸發警戒)、六原型戀愛曲線參數化(重用 G-3 tsundere gap 處理傲嬌)、 親密表現分層與里程碑(跳級拒絕+退縮反應+帳本、第一次做高權重記憶)、 心動事件與階段門檻(含推太急回落、關係危機與修復)。 角色年齡判定(apps/api/src/romance/age-determination.service.ts):僅 決定性/強證據可判定成年,外觀證據不可單獨採信,證據不足從嚴按未成年 處理,且不存最終結論、每次重新算。內容尺度三層邊界(引擎層):使用者 opt-in、角色資格(僅正史成年)、硬邊界(後日談推演成年者永久排除成人 模式);任何嘗試不論放行與否都記錄,判定完全不看對話內容,沒有「說服 角色」繞過的管道。 刻意收斂範圍:僅實作資格判定與硬邊界攔截機制,不實作任何成人向內容的 實際生成。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
6125d6e27f
commit
cd948f0026
@@ -0,0 +1,81 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "character_age_evidence" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"characterId" TEXT NOT NULL,
|
||||
"evidenceType" TEXT NOT NULL,
|
||||
"impliesAdult" BOOLEAN NOT NULL,
|
||||
"isEpilogue" BOOLEAN NOT NULL DEFAULT false,
|
||||
"description" TEXT NOT NULL,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "character_age_evidence_characterId_fkey" FOREIGN KEY ("characterId") REFERENCES "characters" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "romance_event_logs" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"characterId" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"eventType" TEXT NOT NULL,
|
||||
"delta" REAL NOT NULL DEFAULT 0,
|
||||
"detail" TEXT,
|
||||
"occurredAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "romance_event_logs_characterId_fkey" FOREIGN KEY ("characterId") REFERENCES "characters" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT "romance_event_logs_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "adult_mode_consents" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"userId" TEXT NOT NULL,
|
||||
"verifiedAdult" BOOLEAN NOT NULL DEFAULT false,
|
||||
"optedIn" BOOLEAN NOT NULL DEFAULT false,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "adult_mode_consents_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "adult_content_attempt_logs" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"characterId" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"allowed" BOOLEAN NOT NULL,
|
||||
"reason" TEXT NOT NULL,
|
||||
"attemptedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "adult_content_attempt_logs_characterId_fkey" FOREIGN KEY ("characterId") REFERENCES "characters" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT "adult_content_attempt_logs_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- RedefineTables
|
||||
PRAGMA defer_foreign_keys=ON;
|
||||
PRAGMA foreign_keys=OFF;
|
||||
CREATE TABLE "new_relationships" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"characterId" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"intimacy" INTEGER NOT NULL DEFAULT 0,
|
||||
"trust" INTEGER NOT NULL DEFAULT 0,
|
||||
"firstMet" DATETIME,
|
||||
"lastInteraction" DATETIME,
|
||||
"interactionCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"stage" TEXT NOT NULL DEFAULT 'STRANGER',
|
||||
"romanceMeter" INTEGER NOT NULL DEFAULT 0,
|
||||
"romanceStage" TEXT NOT NULL DEFAULT 'NONE',
|
||||
"lastRomanceEventAt" DATETIME,
|
||||
"awkwardUntil" DATETIME,
|
||||
"consecutiveRejections" INTEGER NOT NULL DEFAULT 0,
|
||||
"partnerSince" DATETIME,
|
||||
"romanceEventsInStage" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "relationships_characterId_fkey" FOREIGN KEY ("characterId") REFERENCES "characters" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT "relationships_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
INSERT INTO "new_relationships" ("characterId", "createdAt", "firstMet", "id", "interactionCount", "intimacy", "lastInteraction", "stage", "trust", "updatedAt", "userId") SELECT "characterId", "createdAt", "firstMet", "id", "interactionCount", "intimacy", "lastInteraction", "stage", "trust", "updatedAt", "userId" FROM "relationships";
|
||||
DROP TABLE "relationships";
|
||||
ALTER TABLE "new_relationships" RENAME TO "relationships";
|
||||
CREATE UNIQUE INDEX "relationships_characterId_userId_key" ON "relationships"("characterId", "userId");
|
||||
PRAGMA foreign_keys=ON;
|
||||
PRAGMA defer_foreign_keys=OFF;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "adult_mode_consents_userId_key" ON "adult_mode_consents"("userId");
|
||||
Reference in New Issue
Block a user