From 46aafce59e342e423c29db9cd9c01b8609ae3dc0 Mon Sep 17 00:00:00 2001 From: kdletters Date: Mon, 20 Apr 2026 08:11:42 +0000 Subject: [PATCH] fix merge fallout after master into stdb --- .../MASTER_TO_STDB_MERGE_RECORD_2026-04-20.md | 79 +++++++++++++++++++ docs/technical/README.md | 1 + src/components/auth/AccountModal.test.tsx | 5 ++ .../game-canvas/GameCanvasShared.tsx | 3 + src/services/storageService.ts | 19 +++-- 5 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 docs/technical/MASTER_TO_STDB_MERGE_RECORD_2026-04-20.md diff --git a/docs/technical/MASTER_TO_STDB_MERGE_RECORD_2026-04-20.md b/docs/technical/MASTER_TO_STDB_MERGE_RECORD_2026-04-20.md new file mode 100644 index 00000000..26badab5 --- /dev/null +++ b/docs/technical/MASTER_TO_STDB_MERGE_RECORD_2026-04-20.md @@ -0,0 +1,79 @@ +# 远端 master 合并到 stdb 记录(2026-04-20) + +## 1. 本次操作 + +- 合并时间:2026-04-20 +- 当前分支:`stdb` +- 合并来源:`origin/master` +- 生成提交:`69fc2428` + +对应命令: + +```bash +git fetch origin master stdb +git merge --no-ff origin/master +``` + +## 2. 合并目标 + +本次目标不是把 `stdb` 回退成 Node-only 架构,而是: + +- 吸收远端 `master` 上 2026-04-20 的最新业务功能、UI 和文档增量 +- 继续保留 `stdb` 分支当前的 SpacetimeDB 架构 +- 保留 `spacetimedb/` Rust 模块 +- 保留 `src/spacetime/` 客户端连接、generated bindings、mapper +- 保留 `src/services/authService.ts`、`src/services/storageService.ts` 当前基于 STDB 的认证与运行时存储链路 + +## 3. 合并结果 + +本次 `origin/master` 相对 `stdb` 只新增了 1 个提交: + +- `1c72066b` + +该提交主要带来了以下增量: + +- 新的剧情推进 / NPC 强度相关后端模块与测试 +- 多个前端面板、交互与样式更新 +- 若干 PRD、设计、体验文档更新 +- 部分 shared contract 与 prompt 内容更新 + +本次合并未出现手工冲突,Git 直接完成了 merge。合并后确认以下 STDB 架构仍然保留: + +- `spacetimedb/Cargo.toml` +- `spacetimedb/src/lib.rs` +- `spacetimedb/src/auth.rs` +- `spacetimedb/src/runtime.rs` +- `src/spacetime/client.ts` +- `src/spacetime/generated/*` +- `src/spacetime/mappers.ts` +- `docs/technical/SPACETIMEDB_SERVER_NODE_MIGRATION_2026-04-18.md` + +## 4. 本次保留原则 + +虽然这次没有进入手工冲突解决,但本次集成的判断基线仍然是: + +- `stdb` 是当前账户、运行时存档、自定义世界资料库的主架构分支 +- 前端只负责表现,认证状态、运行时数据与资料库存储继续以 STDB 为主链 +- `master` 的业务功能、UI 和文档更新可以吸收 +- 任何会删除 `spacetimedb/`、`src/spacetime/` 或让认证 / 存储退回旧链路的改动都不作为本次保留目标 + +## 5. 合并后重点核对 + +已重点核对以下入口仍指向 STDB: + +- `src/components/auth/AuthGate.tsx` + - 仍监听 `verification_prompt_event`、`kick_event`、`session_revocation_event` +- `src/services/authService.ts` + - 仍通过 `ensureSpacetimeConnection()` 读取会话、登录状态、风险记录和会话管理 +- `src/services/storageService.ts` + - 仍通过 `ensureSpacetimeConnection()` 读写快照、运行时设置、个人资料与自定义世界资料 + +## 6. 验证要求 + +根据仓库约束,本次合并后至少应执行: + +- `npm run check:encoding` +- `npm run server-node:test` +- `npm run typecheck` + +若后续继续推进 STDB 相关集成,仍应以 `docs/technical/SPACETIMEDB_SERVER_NODE_MIGRATION_2026-04-18.md` 为当前迁移说明基线。 diff --git a/docs/technical/README.md b/docs/technical/README.md index dafab7a9..a37d97d2 100644 --- a/docs/technical/README.md +++ b/docs/technical/README.md @@ -4,6 +4,7 @@ ## 文档列表 +- [MASTER_TO_STDB_MERGE_RECORD_2026-04-20.md](./MASTER_TO_STDB_MERGE_RECORD_2026-04-20.md):记录 2026-04-20 将 `origin/master` 合并到 `stdb` 的结果、保留边界与验证要求。 - [REPO_NOISE_CLEANUP_BASELINE_2026-04-19.md](./REPO_NOISE_CLEANUP_BASELINE_2026-04-19.md):落实工程清理审计第一阶段后的仓库噪音清理范围、忽略规则闭合点与后续约束。 - [PROMPT_DIRECTORY_MANAGEMENT_2026-04-19.md](./PROMPT_DIRECTORY_MANAGEMENT_2026-04-19.md):后端提示词收口到 `server-node/src/prompts/` 的目录方案、兼容策略与后续新增规则。 - [SPACETIME_DEV_URI_HOTFIX_2026-04-20.md](./SPACETIME_DEV_URI_HOTFIX_2026-04-20.md):修复开发默认配置把 Spacetime 连接误指向 Vite `3000` 端口的问题。 diff --git a/src/components/auth/AccountModal.test.tsx b/src/components/auth/AccountModal.test.tsx index f88a269d..c537018b 100644 --- a/src/components/auth/AccountModal.test.tsx +++ b/src/components/auth/AccountModal.test.tsx @@ -219,8 +219,11 @@ test('account panel includes merged security devices and audit sections', async sessions: [ { sessionId: 'session-1', + clientType: 'ios', clientLabel: 'iPhone 15 Pro', + userAgent: 'Mobile Safari', isCurrent: true, + createdAt: '2026-04-20T07:30:00.000Z', lastSeenAt: '2026-04-20T09:00:00.000Z', expiresAt: '2026-04-27T09:00:00.000Z', ipMasked: '10.0.*.*', @@ -229,10 +232,12 @@ test('account panel includes merged security devices and audit sections', async auditLogs: [ { id: 'log-1', + eventType: 'phone_login', title: '登录成功', detail: '通过手机号验证码完成登录。', createdAt: '2026-04-20T08:00:00.000Z', ipMasked: '10.0.*.*', + userAgent: 'Mobile Safari', }, ], }); diff --git a/src/components/game-canvas/GameCanvasShared.tsx b/src/components/game-canvas/GameCanvasShared.tsx index ac3c552a..73d5c708 100644 --- a/src/components/game-canvas/GameCanvasShared.tsx +++ b/src/components/game-canvas/GameCanvasShared.tsx @@ -90,6 +90,9 @@ export const SCENE_TRANSITION_SPEED_PX_PER_S = / SCENE_TRANSITION_REFERENCE_DURATION_S; export const SCENE_TRANSITION_UPPER_COMPANION_DELAY_S = 0.43; export const SCENE_TRANSITION_LOWER_COMPANION_DELAY_S = 0.93; +const DEFAULT_IMAGE_STYLE: React.CSSProperties = { + imageRendering: 'pixelated', +}; export function getCompanionSlotOffset(slot: CompanionRenderState['slot']) { return slot === 'upper' diff --git a/src/services/storageService.ts b/src/services/storageService.ts index bf26c8c9..c46e76e7 100644 --- a/src/services/storageService.ts +++ b/src/services/storageService.ts @@ -92,11 +92,14 @@ function toBigIntMs(isoValue?: string) { } function buildRequestMeta() { + const userAgent = + typeof navigator !== 'undefined' + ? navigator.userAgent.trim() || undefined + : undefined; return { clientType: 'web', - userAgent: - typeof navigator !== 'undefined' ? navigator.userAgent.trim() || null : null, - ip: null, + userAgent, + ip: undefined, }; } @@ -165,7 +168,7 @@ export async function putSaveSnapshot( bottomTab: snapshot.bottomTab, currentStoryJson: snapshot.currentStory === null || snapshot.currentStory === undefined - ? null + ? undefined : JSON.stringify(snapshot.currentStory), }); @@ -329,13 +332,13 @@ export async function upsertCustomWorldProfile( profileId: profile.id, payloadJson: JSON.stringify(profile), visibility: { tag: 'Draft' }, - publishedAtMs: null, + publishedAtMs: undefined, updatedAtMs: BigInt(Date.now()), authorDisplayName: '玩家', worldName: profile.name, subtitle: profile.subtitle, summaryText: profile.summary, - coverImageSrc: null, + coverImageSrc: undefined, themeMode: { tag: 'Mythic' }, playableNpcCount: profile.playableNpcs.length, landmarkCount: profile.landmarks.length, @@ -470,7 +473,7 @@ export async function upsertProfileBrowseHistory( worldName: entry.worldName, subtitle: entry.subtitle, summaryText: entry.summaryText, - coverImageSrc: entry.coverImageSrc, + coverImageSrc: entry.coverImageSrc ?? undefined, themeMode: mapThemeModeInput(entry.themeMode), authorDisplayName: entry.authorDisplayName, visitedAtMs: entry.visitedAt ? toBigIntMs(entry.visitedAt) : 0n, @@ -498,7 +501,7 @@ export async function syncProfileBrowseHistory( worldName: entry.worldName, subtitle: entry.subtitle, summaryText: entry.summaryText, - coverImageSrc: entry.coverImageSrc, + coverImageSrc: entry.coverImageSrc ?? undefined, themeMode: mapThemeModeInput(entry.themeMode), authorDisplayName: entry.authorDisplayName, visitedAtMs: entry.visitedAt ? toBigIntMs(entry.visitedAt) : 0n,