diff --git a/apps/web/src/app/[locale]/awooop/page.tsx b/apps/web/src/app/[locale]/awooop/page.tsx index b071d814..31321056 100644 --- a/apps/web/src/app/[locale]/awooop/page.tsx +++ b/apps/web/src/app/[locale]/awooop/page.tsx @@ -1,13 +1,9 @@ // ============================================================================= -// WOOO AIOps - AwoooP Console 入口重導向 +// WOOO AIOps - AwoooP Console 入口頁 // ============================================================================= -import { redirect } from "next/navigation"; +import AwoooPWorkItemsPage from "./work-items/page"; -export default function AwoooPPage({ - params, -}: { - params: { locale: string }; -}) { - redirect(`/${params.locale}/awooop/work-items`); +export default function AwoooPPage() { + return ; } diff --git a/apps/web/src/components/dashboard/flywheel-kpi-card.tsx b/apps/web/src/components/dashboard/flywheel-kpi-card.tsx index 815e950b..21029834 100644 --- a/apps/web/src/components/dashboard/flywheel-kpi-card.tsx +++ b/apps/web/src/components/dashboard/flywheel-kpi-card.tsx @@ -108,7 +108,7 @@ export function FlywheelKPICard() { const fmt = (n: number | undefined, digits = 0) => n == null ? '--' : n.toLocaleString(undefined, { maximumFractionDigits: digits }) - const pct = (n: number | undefined) => + const pct = (n: number | null | undefined) => n == null ? '--' : `${Math.round(n * 100)}%` const kpis = [ diff --git a/apps/web/src/components/layout/page-tabs.tsx b/apps/web/src/components/layout/page-tabs.tsx index ed4ff8f6..97497347 100644 --- a/apps/web/src/components/layout/page-tabs.tsx +++ b/apps/web/src/components/layout/page-tabs.tsx @@ -23,6 +23,7 @@ */ import { useState, useCallback, useMemo, Suspense, type ReactNode } from 'react' +import type { Route } from 'next' import { useSearchParams, useRouter, usePathname } from 'next/navigation' import { useTranslations } from 'next-intl' import { cn } from '@/lib/utils' @@ -111,8 +112,8 @@ export function PageTabs({ tabs, defaultTab, syncWithUrl = true }: PageTabsProps params.set('tab', tabId) } const query = params.toString() - // @ts-expect-error — Next.js router.push 型別限制,但動態路徑是合法的 - router.push(`${pathname}${query ? `?${query}` : ''}`, { scroll: false }) + const nextPath = `${pathname}${query ? `?${query}` : ''}` as Route + router.push(nextPath, { scroll: false }) } }, [syncWithUrl, searchParams, router, pathname, defaultTab, tabs]) diff --git a/apps/web/src/components/layout/sidebar.tsx b/apps/web/src/components/layout/sidebar.tsx index 1939f56a..673eb5c3 100644 --- a/apps/web/src/components/layout/sidebar.tsx +++ b/apps/web/src/components/layout/sidebar.tsx @@ -87,7 +87,7 @@ const NAV_SECTIONS: NavSection[] = [ { id: 'security-compliance', href: '/security-compliance', labelKey: 'securityCompliance',Icon: Shield }, { id: 'knowledge', href: '/knowledge', labelKey: 'knowledge', Icon: BookOpen }, { id: 'governance', href: '/governance', labelKey: 'governance', Icon: ShieldCheck }, - { id: 'awooop', href: '/awooop', labelKey: 'awooop', Icon: BrainCircuit }, + { id: 'awooop', href: '/awooop/work-items', labelKey: 'awooop', Icon: BrainCircuit }, ], }, { diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 5313d210..742b4b9b 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,17 @@ +## 2026-05-06 | AwoooP root route no longer returns Next redirect error shell + +**背景**:`https://awoooi.wooo.work/zh-TW/awooop` 回傳 `307` 到 `/zh-TW/awooop/work-items`,但 response body 是 Next.js `__next_error__` + `NEXT_REDIRECT` shell;瀏覽器端可能顯示 `Application error: a client-side exception has occurred`。`/zh-TW/awooop/work-items` 本身正常 200,問題集中在 AwoooP root route redirect。 + +**本次修補**: +- `apps/web/src/app/[locale]/awooop/page.tsx` 不再呼叫 `redirect()`,直接渲染 `work-items` 頁面。 +- 主 sidebar 的 AwoooP 入口改連 `/awooop/work-items`,避免使用者先踩到 root redirect route。 +- 順手修正 web typecheck 既有阻塞:`execution_success_rate` 可為 `null`,以及 `page-tabs.tsx` 已不再需要 `@ts-expect-error`。 + +**驗證**: +- `pnpm --filter @awoooi/web typecheck` 通過。 +- `NEXT_PUBLIC_API_URL=https://awoooi.wooo.work pnpm --filter @awoooi/web build` 通過;無 `NEXT_PUBLIC_API_URL` 的本地 build 會依 Hard Rule 失敗。 +- 待 CD 部署後以 `/zh-TW/awooop` 直接回 200 驗收。 + ## 2026-05-06 | GCP Ollama direct endpoint hotfix for alert diagnosis **背景**:生產 log 顯示 alert path 的 provider order 已是 `ollama_gcp_a → ollama_gcp_b → ollama_local → gemini`,但 GCP-A/GCP-B 經 110 nginx bridge 各跑滿 120s 後回 `504 Gateway Time-out`,因此最後仍 fallback 到 Gemini 並產生成本。110 同時存在 `conf.d/ollama-gcp-proxy.conf`(120s)與 `sites-enabled/110-ollama-proxy.conf`(300s),較早載入的 `conf.d` 實際截斷了 qwen3:14b。