fix(门禁): 补 /games/lineage 的 Pingora 登记,并修掉被掩盖的 eslint 失败

- `server-rs/crates/pingora-gateway/src/main.rs`(MAIN_SPA_PATHS,:64-79):插入 `"/games/lineage"`(放在 `"/games/detail"` 之后,保持既有字典序)。这是主站 SPA 深链在 Pingora 网关下的登记,漏一条就把该深链打成 404;与上一提交补的三份 nginx 模板属同一条「新 SPA 路由三处同批更新」规则
- 矩阵与文档无需改:`deploy/pingora/nginx-route-parity.matrix.json` 的既有 `games_spa_fallback` 用例仍前缀匹配同一行 `location`(本次只改交替项、未新增 `location`),Pingora 试点文档的取值表同理未受影响
- `src/components/game-distribution/GameLineagePage.tsx:146`:把 `lineage?.nodes ?? []` 用 `useMemo(..., [lineage])` 稳定下来,消掉两条 `react-hooks/exhaustive-deps`。取值仍是同一表达式的结果,identity 只在 `lineage` 变化时改变,因此两个下游 useMemo(代际分组、可见 ID 集合)取值不变、只少做无谓重算;未用 disable 注释压掉告警
- 6 处 `simple-import-sort/imports` 用 `eslint --fix` 机械修(`apps/.../view/home/PlatformGameForkSection.tsx`、`apps/.../view/home/index.tsx`、`src/components/game-distribution/GameDetailPage.tsx`、`MyGamesPage.test.tsx`、`MyGamesPage.tsx`、`src/services/gameDistributionClient.ts`):逐文件比对「剥掉 import 行后的正文」——5 个文件完全一致,`GameDetailPage.tsx` 仅多一个 import 分组空行
- 这批修的是「修 nginx 时被前一道红掩盖的第二、第三个失败」:CI run 3387 卡在 `check:nginx-spa-routes`,`check:pingora-route-parity` 与 `lint:eslint` 从未跑到
- 本地验证:`check:repository-ci` 的 15 个 lint 环节 + `appSurface` vitest + `npm run build` + `git diff --check 6c9566058...HEAD` 全绿,仅两个**本机不可执行**项(`check:git-hooks` 的 Windows EBUSY、`check:generated-bindings` 的 AGC `export_bindings` 本地构建);另跑 `cargo test -p pingora-gateway` 40 passed、`npx vitest run apps/ai-game-creator-shell/tests` 1957 passed / 17 skipped
This commit is contained in:
2026-10-05 11:24:15 +08:00
parent 5795a07a7d
commit d2698cbb1d
8 changed files with 14 additions and 9 deletions
@@ -10,11 +10,11 @@
* 渲染层只做输入解析、加载态与失败分类。
*/
import { useRef, useState } from 'react';
import type { FormEvent } from 'react';
import { useRef, useState } from 'react';
import type { InitLocalProjectResult } from '../../app/types';
import { resolveTauriInvoke } from '../../app/tauri';
import type { InitLocalProjectResult } from '../../app/types';
import {
classifyPlatformForkFailure,
parsePlatformGameId,
@@ -20,13 +20,13 @@ import { resolveHomeCreationFailureMessage } from '../../features/app-shell/home
import { ConversationModelSelect } from '../../features/project-workspace/ConversationModelSelect';
import type { GameTemplateEntry } from '../../features/template-library/templateLibraryModel';
import type { ProjectOpenAnalytics } from '../../services/clientAnalytics';
import PlatformGameForkSection from './PlatformGameForkSection';
import RichInputArea, { UploadButton } from './components/RichInputArea';
import {
richTextToAttachments,
richTextToPrompt,
} from './components/RichInputArea/richTextToPrompt';
import { resolveHomeStartMode } from './homeStartMode';
import PlatformGameForkSection from './PlatformGameForkSection';
import TemplateRecommendations from './TemplateRecommendations';
import {
type HomeCreationType,
@@ -69,6 +69,7 @@ const MAIN_SPA_PATHS: &[&str] = &[
"/editor/canvas",
"/games",
"/games/detail",
"/games/lineage",
"/games/mine",
"/games/play",
"/games/publish",
@@ -6,6 +6,7 @@ import {
} from '@genarrative/shared/components';
import { ArrowLeft, Gamepad2, Maximize2 } from 'lucide-react';
import { useCallback, useEffect, useRef, useState } from 'react';
import {
GAME_DISTRIBUTION_FORK_AUTHORIZATION_LABELS,
type GameDistributionRecoveryAction,
@@ -143,7 +143,10 @@ export function GameLineagePage({
void loadLineage();
}, [loadLineage]);
const nodes = lineage?.nodes ?? [];
// `lineage?.nodes ?? []` 在缺省分支每次渲染都会产生新数组,直接喂给下面的 useMemo 会让依赖
// 每次渲染都变;这里把派生结果本身稳定下来:值仍是同一表达式的结果,identity 只在 `lineage`
// 变化时改变,因此两个下游 useMemo 的取值不变、只少做无谓重算。
const nodes = useMemo(() => lineage?.nodes ?? [], [lineage]);
const groups = useMemo(() => groupNodesByGeneration(nodes), [nodes]);
const visibleIds = useMemo(
() => new Set(nodes.map((node) => node.gameId)),
@@ -8,15 +8,15 @@ import { beforeEach, expect, test, vi } from 'vitest';
import {
cancelGameVersion,
deleteMyGame,
getDerivedGames,
type GameDistributionMyGame,
getDerivedGames,
getGameVersion,
listMyGames,
loadVersionRecoveryActions,
submitGameVersion,
unpublishGame,
updateMyGame,
updateGameForkAuthorization,
updateMyGame,
} from '../../services/gameDistributionClient';
import { AuthUiContext } from '../auth/AuthUiContext';
import { MyGamesPage } from './MyGamesPage';
@@ -6,20 +6,20 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
import type { GameDistributionRecoveryAction } from '../../../packages/shared/src/contracts/gameDistribution';
import {
canUpgradeGameForkAuthorization,
GAME_DISTRIBUTION_FORK_AUTHORIZATIONS,
GAME_DISTRIBUTION_FORK_AUTHORIZATION_LABELS,
GAME_DISTRIBUTION_FORK_AUTHORIZATION_SHORT_LABELS,
GAME_DISTRIBUTION_FORK_AUTHORIZATIONS,
type GameDistributionForkAuthorization,
resolveGameForkAuthorization,
} from '../../../packages/shared/src/contracts/gameDistribution';
import {
cancelGameVersion,
deleteMyGame,
getDerivedGames,
type GameDistributionLineageNode,
type GameDistributionMyGame,
type GameDistributionUpdateMyGameResponse,
type GameDistributionVersionStatusEntry,
getDerivedGames,
listMyGames,
loadVersionRecoveryActions,
submitGameVersion,
+1 -1
View File
@@ -14,8 +14,8 @@ import type {
GameDistributionReviewsResponse,
GameDistributionSaveReviewRequest,
GameDistributionSaveReviewResponse,
GameDistributionUpdateGameMetadataRequest,
GameDistributionSetForkAuthorizationRequest,
GameDistributionUpdateGameMetadataRequest,
GameDistributionVersionDetail,
GameDistributionVersionStatus as GameDistributionVersionStatusValue,
GameDistributionVersionSummary,