feat(遊戲化): 新增大廳、附身、時間流、後日談進度等遊戲化系統功能

新增角色大廳(lobby)邀約與通話、附身(possession)、時鐘(clock)抽象、
時間流與睡眠負債、後日談進度、行為選擇與旁觀反應等模組,並補齊對應冒煙
測試(R~V)與單元測試;同步調整 web/mobile 對應頁面與元件。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 09:10:26 +08:00
co-authored by Claude Sonnet 5
parent 127a59dafd
commit 1bea06e3cd
195 changed files with 17219 additions and 738 deletions
+7 -5
View File
@@ -27,7 +27,7 @@ async function get(path) {
// Q-1/Q-2/Q-3 目前都是行動 APP(React Native + Expo,apps/mobile)消費既有的 API 契約,
// 沒有為 Q 群組新增角色/對話端點——這裡驗證的是 Q 群組唯一新增的後端功能:推播通知(Q-3),
// 以及 APP 賴以運作的既有契約仍然完整(/health、/chat、/characters、/schedule)。
// 以及 APP 賴以運作的既有契約仍然完整(/health、/room(T38 起取代 /chat)、/characters、/schedule)。
// APP 本身的畫面/導覽/實際串接已在本群組以 `expo start --web` + 無頭瀏覽器手動驗證過
// (見 todo.md 實作記錄),不在這個純後端 smoke test 的範圍內。
export default async function smokeQ() {
@@ -54,10 +54,11 @@ export default async function smokeQ() {
initialRelationship: { userId: USER_ID, intimacy: 20, trust: 10 },
});
// Q-2 驗收(後端契約部分):聊天分頁依賴的 /chat 端點能完成一輪對話並回傳更新後的關係/情緒狀態。
const chatResult = await post(`/chat/${CHAR_ID}`, {
// Q-2 驗收(後端契約部分):聊天分頁依賴的房間端點(T38 併入 SOLO 房後取代舊版 /chat)能完成
// 一輪對話並回傳更新後的關係/情緒狀態。
const soloRoom = await post("/room/solo", { userId: USER_ID, characterId: CHAR_ID });
const chatResult = await post(`/room/${soloRoom.id}/message`, {
userId: USER_ID,
sessionId: "smoke-q-session",
text: "嗨,最近好嗎?",
});
if (!chatResult.text || !chatResult.context) {
@@ -111,7 +112,8 @@ export default async function smokeQ() {
throw new Error("任務觸發的推播內容應該包含提醒訊息本身");
}
// 清理本次測試建立的角色與推播資料(cascade 會一併清掉任務、關係、情緒狀態等)。
// 清理本次測試建立的角色與推播資料(cascade 會一併清掉任務、關係、情緒狀態等)與本次建立的 SOLO 房。
await prisma.room.deleteMany({ where: { id: soloRoom.id } });
await prisma.character.deleteMany({ where: { id: CHAR_ID } });
await prisma.pushToken.deleteMany({ where: { token: TOKEN } });
await prisma.pushNotificationLog.deleteMany({ where: { userId: USER_ID, title: { in: ["測試標題", "心音 Kokorone"] } } });