Repository navigation
feat: Batch 7 — Landing & Observability v1 (#18) - #39
Merged
Merged
Conversation
zh-CN + en-US gain `landing.*` (health overview) and `observe.*` (observability v1) trees; en-US `satisfies MessageSchema` enforces parity at typecheck. i18n.spec adds a recursive leaf-key cross-locale comparison plus a frozen REQUIRED_KEYS existence assertion for every key the Batch 7 views render — closing the recalled i18n-missing-key blind spot (a t() on an absent key otherwise passes typecheck/test/build and renders raw at runtime). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Both were devboard internals; @gocell/observability (Batch 7) needs them but business cells cannot import each other — only @gocell/core is shared. Move both (generic signature + role=status panel preserved) into core, export from the root barrel, and repoint all devboard consumers (CellTabBar, DepsViewBar, 5 tab components) to @gocell/core. No back-compat shim (no external consumers). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
package.json (deps + test scripts + view exports), vitest.config (80% gate). api/health.ts (BR-001 /admin/health/cells), api/system.ts (BR-002 /admin/system), api/observe.ts (BR-003 LGTM via @gocell/request BFF proxy paths /api/v1/observability/* — 方案 B, no bare fetch). Local types annotated for codegen cutover. lib/ pure helpers: formatUptime, formatBytes, healthStatus (status→variant + cell rollup). Endpoints 404 until backend lands → callers degrade. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
useHealthStore ('observe.health'): cells/summary/system with independent
health/system load status; refresh() runs both via allSettled; errors degrade
to status='unavailable' + errorKey (toI18nKey), never throw. useObserveStore
('observe.signals'): per-tab overview KPIs / logs / traces load actions over
the LGTM proxy api, RangePreset window via pure rangeFromPreset(preset, now).
useHealthPoll: 30s setInterval refresh, onScopeDispose cleanup. index.ts barrel.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Landing: CellHealthBadge (status→token dot + i18n label), CellHealthCard, SystemInfoCard (degrades to core UnavailablePanel). Observe: ObserveTabBar (core useRovingTablist; 3 live tabs + 4 aria-disabled Wave-2 spans), ObservabilityErrorBoundary (onErrorCaptured → degrade panel + retry; T703 net), OverviewPanel/LogsPanel/TracesPanel (store-driven, loading/unavailable/empty/ loaded states, all degrade gracefully while LGTM backend is absent). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
LandingView (/): polled (30s) cell-health grid + summary rollup + SystemInfoCard, degraded banner when BR-001/002 endpoints absent, intentional deploys/KPI placeholder cards (core UnavailablePanel), sr-only aria-live refresh announcement. ObserveView (/observe): roving-tablist tab bar (3 live + 4 Wave-2 disabled), active panel wrapped in ObservabilityErrorBoundary, active tab carried in ?tab=. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`/` now renders @gocell/observability/views/landing (Health overview) and is auth-gated (resolves the Batch 7 TODO); add `/observe` → @gocell/observability/views/observe, auth-only (no PDP — operational dashboards). Delete the HomeView placeholder; add @gocell/observability as a web dep. router/index + guards specs updated (unauth `/` → /login now asserted); e2e/health.spec covers degraded + ok health overview, observe tabs, and the protected-route redirect (the smoke deferred from earlier batches). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Six-dimension review + adversarial verification (18 confirmed / 5 refuted): - ObservabilityErrorBoundary: keep the h() render-fn (a plain template re-introduces the Vue block-patch crash) but move its styles to an unscoped block so they apply to h()-created nodes; restore focus to the slot wrapper on retry (WCAG 2.4.3). - LandingView: render the aria-live region unconditionally (first poll now announced); aria-hidden the decorative rollup counts; drop the duplicate system h2 (card owns it); font-sizes → tokens (--text-3xl/--text-base/--text-sm). - core: add --text-3xl: 26px (matches dev-observe KPI value); remove unused observe.range.* keys. - OverviewPanel KPI value → --text-3xl. CellHealthBadge: hoist KNOWN_STATUSES out of computed. - useObserveStore: kpis ref → shallowRef (matches logs/traces). observe.ts: coerce Prom timestamp. - Logs/TracesPanel: drop redundant @click.prevent (form @submit.prevent suffices). - devboard + observability READMEs corrected; e2e LGTM stub /observe → /observability. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## Playwright smoke(CI 阻塞,5→0 失败)
- Batch 7 把 `/` 改为 requiresAuth:true 后,原 smoke/health/auth e2e 仍按公开
`/` 假设编写:未登录访问 `/` 重定向 login,登录后又 `page.goto` 整页刷新清空
仅存内存的 Pinia token → 弹回 login。
- 新增 e2e/helpers.ts:stubSetupDone / loginAs(经登录后重定向落到目标路由,不
二次 page.goto)/ stubHealthEndpoints。health/smoke/auth 改为 SPA 导航 + stub。
- health OK 用例修正:契约为 envelope-less(fetchCellHealth 返回 res.data),
stub 去掉多余 {data} 信封并补全 CellHealthEntry 形状;system 端点 404 隔离。
- 本地 11/11 e2e 通过。
## 六维度 review Cx1/Cx2(19 条,跨 observability/core/devboard)
- TS:observe.ts 收紧 Loki/Tempo/Prom 类型守卫;PromRawResponse.status 缩窄并在
非 success 时抛错(不再静默吞成空数据);消除 `?? []` 死码。
- Vue:三面板 idle 态并入 loading 分支(消首帧空态闪烁);v-model 直写 store 改
setLogsQuery/setTracesService action;LandingView idle/loaded 分支显式化。
- 性能:ObserveView 三面板 defineAsyncComponent 懒加载拆 chunk;useHealthPoll 标签
页隐藏暂停轮询;useHealthStore fetch 并发去重防竞态;CellHealthCard lastError 改
O(n) 线性扫描。
- a11y:Wave-2 disabled tab 纳入 roving(core useRovingTablist 新增 disabledIds,
focus 可达但不激活);LandingView 合并多 role=status live region;错误边界错误时
程序化移焦 + 恢复 focus-visible 轮廓;Logs/Traces 表格补 sr-only caption。
- 设计:submit/retry 按钮 32→30px 对齐 PRD §4;KPI grid 改 minmax 防窄屏压缩;
starting 状态从 --accent 改 --ok;删死 i18n key(landing.cell/system.regionLabel)。
- 包边界:observability 补声明 @gocell/contracts;health/system API 加轻量运行时
形状守卫(缺字段即降级 unavailable);core README 补 UnavailablePanel/useRovingTablist;
LoadStatus 抽到 lib/loadStatus.ts 单一来源。
校验:pnpm -w lint / typecheck 绿;单测 1752 passed(useTheme 预存并发 flaky,单独
跑通过、本分支未触碰);@gocell/web build 绿;e2e 11/11;contracts git 干净。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Batch 7 (issue #18): the
/Health overview (Landing) and/observeObservability v1, both owned by@gocell/observability(its README scopes it to Landing/Observe). Per the directive, backend gaps are treated as non-blocking — BR-001 (/admin/health/cells), BR-002 (/admin/system), and BR-003 (LGTM) endpoints are unbuilt, so every data path degrades gracefully to an unavailable panel rather than erroring. That degradation is deliverable T703.Closes #18.
What shipped
/) — polled (30s) cell-health card grid + status rollup,SystemInfoCard, intentional deploys/KPI placeholder cards, degraded banner when BR-001/002 are absent,sr-onlyaria-liverefresh announcement. (T701)/observe) — accessible roving-tablist with 3 live tabs (Overview / Logs / Traces) + 4 disabled Wave-2 tabs (Anomalies / What changed / Service graph / Slice health) asaria-disabledspans; each tab is store-driven (real data path) and degrades to the unavailable panel while LGTM is absent; the active panel is wrapped inObservabilityErrorBoundary(onErrorCaptured). Active tab carried in?tab=. (T702 + T703)@gocell/corei18n gainslanding.*+observe.*(zh-CN + en-US;satisfies MessageSchemaenforces parity).Key decisions (confirmed with maintainer)
@gocell/requestBFF proxy paths (/api/v1/observability/{loki,tempo,prometheus}/*, BR-003 §3.4 方案 B) — not barefetchto LGTM origins (方案 A), which would violate the package-boundary no-fetch rule. Forward-compatible with the prod gateway; degrades by default since the proxy isn't implemented.@gocell/core—useRovingTablist+UnavailablePanelmoved from@gocell/devboardinto core (business cells can't import each other); all devboard consumers repointed. No back-compat shim.requiredAction) — operational dashboards for any authenticated admin./flips torequiresAuth: true(resolves the standing Batch 7 TODO).observenav stays in the Reserved group withpill: 'preview'(LGTM not deployed); no navConfig change.AI-robust note
Closes the recalled i18n-missing-key blind spot:
i18n.spec.tsnow deep-compares thelanding/observeleaf-key trees across locales and asserts every key the views render resolves to a non-empty string in both locales (vue-i18n is not key-typed, so a typo'dt()key otherwise passes typecheck/test/build and renders raw).Packages touched
@gocell/observability(46 files)@gocell/core(10)useRovingTablist+UnavailablePanel@gocell/devboard(10)apps/web(5)/+/observe), delete HomeView, router/guards specs,e2e/health.spec.tspackages/contracts/untouched — no codegen types exist for BR-001/002/003 yet; all backend shapes are local TS types annotated for codegen cutover once the schemas land.Test plan
pnpm -w lint— 0 issuespnpm -w typecheck— clean (all packages)pnpm -w test --run— 1714 passed / 118 filespnpm -F @gocell/web build— succeeds;LandingView/ObserveViewchunks emitted (subpath exports resolve)@gocell/core99%+ (gate 90%),@gocell/observability99% stmts / ~90% branches (gate 80%)e2e/health.spec.ts(degraded/ok health overview, observe tabs, protected/→login redirect) — added + parses; not executed locally (needs server/browsers), runs in CIDeferred (out of scope, follow-up)
🤖 Generated with Claude Code