Files
BoosAPI/docs
Cita baead855dd Make admin reads snapshot-first for faster ops pages (#457)
* Make admin reads snapshot-first so heavy pages stay responsive

This introduces a lightweight snapshot/cache layer for the busiest
admin reads, splits dashboard and proxy-log loading into smaller
independent surfaces, and moves accounts/site/dashboard snapshots
toward service-owned read paths.

The UI now loads dashboard summary, dashboard insights, site stats,
accounts, and proxy-log metadata as separate progressive reads while
keeping existing feature coverage intact.

Constraint: Must keep the full admin feature set and core metrics intact
Constraint: Interactive admin flows should trend toward <=3s without relying on OpenResty-only band-aids
Rejected: Delete heavy pages or reduce statistics depth | user explicitly requires unchanged functionality
Rejected: Keep one giant proxy-log/dashboard response | preserves current timeout-prone read shape
Confidence: medium
Scope-risk: moderate
Directive: Preserve old endpoints during the migration and keep new snapshot/query-v2 surfaces as the preferred frontend path
Tested: npm run typecheck
Tested: npx vitest run --root . src/server/routes/api/accounts.snapshot-v2.test.ts src/server/routes/api/stats.snapshot-v2.test.ts src/server/routes/api/stats.proxy-logs.test.ts src/server/routes/api/stats.siteStatus.test.ts src/server/routes/api/accounts.todayRewardFallback.test.ts
Tested: npm run build
Tested: npm run repo:drift-check
Not-tested: Live cita/cita1 latency measurements against the production dataset

* Keep snapshot services lean after the admin read-path rollout

The snapshot-first rollout now has fresh production evidence on cita1, so this follow-up trims two no-op patterns without changing behavior: a single-element Promise.all and a catch-then-rethrow refresh chain. Keeping the service layer lean reduces noise before final Ralph sign-off and redeploy verification.

Constraint: Keep deployed behavior unchanged while satisfying the mandatory deslop pass
Rejected: Wider refactor across route files | would broaden the verified surface right before production comparison closeout
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep snapshot services focused on cache/read orchestration; avoid reintroducing decorative async wrappers
Tested: npm run typecheck; npm run build; targeted vitest snapshot/proxy-log/account suites; npm run repo:drift-check
Not-tested: Public Cloudflare path, which still appears to hit a different origin than cita1

* Keep admin snapshots warm without introducing Redis

This moves the new admin read path beyond process-local caching by persisting
snapshot payloads in a dedicated admin_snapshots table and warming them in
the background. It also migrates remaining lightweight internal callers away
from the heaviest legacy reads and marks legacy endpoints as deprecated
instead of deleting them abruptly.

Constraint: User explicitly rejected adding Redis for admin snapshot acceleration
Rejected: Redis-backed shared cache | adds a forbidden runtime dependency
Rejected: Delete legacy endpoints immediately | still breaks tests, docs, and compatibility callers
Confidence: high
Scope-risk: moderate
Directive: Remove legacy admin endpoints only after internal callers, docs, and compatibility windows are cleared
Tested: npm run typecheck
Tested: npm run build
Tested: npx vitest run --root . src/server/services/adminSnapshotStore.test.ts src/server/routes/api/accounts.snapshot-v2.test.ts src/server/routes/api/stats.snapshot-v2.test.ts src/server/services/startupInfo.test.ts
Tested: npm run repo:drift-check
Not-tested: cita1 staging redeploy on this follow-up commit

* Collapse admin reads onto the canonical API paths

This removes the parallel v2 read surface and routes the snapshot-first
implementation back through the original admin API names. The frontend now
uses the canonical paths again while the backend keeps the newer snapshot,
persistence, and warm-refresh machinery behind those routes. Along the way it
also fixes the main review findings around cache coalescing, active-site scope,
atomic snapshot writes, and auth-header handling.

Constraint: User requested no Redis and no long-lived duplicate admin read endpoints
Rejected: Keep both legacy and v2 endpoints indefinitely | doubles maintenance and confuses the canonical contract
Rejected: Delete old names without remapping callers | would create avoidable frontend and tooling churn
Confidence: high
Scope-risk: moderate
Directive: Treat /api/stats/dashboard, /api/accounts, /api/stats/proxy-logs, and the site stats routes as the canonical admin read contract unless a future breaking-change plan says otherwise
Tested: npm run typecheck
Tested: npm run build
Tested: npx vitest run --root . src/server/services/adminSnapshotStore.test.ts src/server/routes/api/accounts.snapshot-v2.test.ts src/server/routes/api/stats.snapshot-v2.test.ts src/server/routes/api/stats.proxy-logs.test.ts src/server/services/startupInfo.test.ts
Tested: npm run repo:drift-check
Not-tested: cita1 staging redeploy on this canonical-route follow-up commit

* Keep canonical admin analytics fast without raw log scans

This lands the usage-aggregate path as the single implementation behind the canonical admin routes, adds the aggregate schema/migration artifacts, and reconnects dashboard/site stats warming to the new service so the PR no longer sits in a half-projector state.

It also updates the cache and aggregate tests to reflect the real runtime behavior and validates the current branch on cita1 staging, which showed the app-side snapshot path is fast while the remaining 1.5s staging slowness lives on the NodePort path rather than inside the aggregate queries themselves.

Constraint: Must preserve the canonical old-path admin API contract while moving reads onto aggregate-backed snapshots
Constraint: Must not add Redis or a parallel second analytics implementation
Rejected: Keep usageAggregationProjectorService as a separate path | would preserve duplicate ownership and keep type wiring split
Rejected: Judge staging performance only from NodePort timings | hid that pod-local snapshot reads were already fast
Confidence: medium
Scope-risk: moderate
Directive: If dashboard or insights feels slow again on staging, compare NodePort and pod-local timings before changing aggregate queries
Tested: npm run typecheck; npx vitest run --root . src/server/services/adminSnapshotStore.test.ts src/server/services/usageAggregationService.test.ts src/server/services/snapshotCacheService.test.ts src/server/routes/api/accounts.snapshot-v2.test.ts src/server/routes/api/stats.snapshot-v2.test.ts src/server/routes/api/stats.proxy-logs.test.ts src/server/services/startupInfo.test.ts; npm run build; npm run repo:drift-check; cita1 staging deploy plus canonical-route curl benchmarks
Not-tested: cita1 real ingress/OpenResty path; multi-replica projector concurrency

* Prevent admin aggregate drift under concurrent warmers

This follow-up hardens the snapshot-first admin analytics path by adding a persisted projector lease, exact 24-hour dashboard counting, and regression coverage for lease contention and time-window behavior.

The goal is to keep the canonical admin routes correct when multiple workers are alive and to avoid quietly overstating proxy24h by reading hour buckets as if they were an exact sliding window.

Constraint: Projector coordination must work through the existing checkpoint table without adding Redis or a second background system
Constraint: Schema artifacts must stay additive under the repo's generated bootstrap/upgrade pipeline
Rejected: Remove the left-prefix day/hour indexes in this slice | schema:contract rejects non-additive index removals, so that cleanup needs a broader migration strategy
Confidence: high
Scope-risk: moderate
Directive: Keep projector claims DB-backed; do not regress to process-local inFlight-only dedupe for aggregate writes
Tested: npm run typecheck; npx vitest run --root . src/server/services/usageAggregationService.test.ts src/server/routes/api/stats.snapshot-v2.test.ts; npm run build; npm run repo:drift-check
Not-tested: Multi-host live contention beyond synthetic lease test; resolving CodeRabbit index-nit without additive-schema support

* Keep CI aligned with canonical admin snapshots

The admin snapshot cutover left a mixed test surface: MySQL schema artifacts still
classified admin_snapshots.snapshot_key as JSON, canonical /api/accounts callers
were asserted as arrays, and a few proxy tests mocked routeRefreshWorkflow too
narrowly, which leaked missing exports into later OAuth runs.

This commit narrows the schema metadata heuristic, updates the checked-in schema
artifacts and their regression tests, adds lightweight web test compat helpers
for canonical snapshot APIs, and preserves actual routeRefreshWorkflow exports so
full-suite workers no longer poison unrelated tests. OAuth/account token suites
also reset DATA_DIR-backed modules safely to avoid stale singleton config.

Constraint: checked-in schema artifacts drive cross-dialect CI parity checks
Constraint: vitest module mocks can leak across files in the same worker when exports are omitted
Rejected: rerun schema:generate only | additive guard rejects the logical-type correction for snapshot_key
Rejected: keep per-test ad hoc snapshot mocks | repeated breakage across pages needed one compat helper
Confidence: high
Scope-risk: moderate
Directive: when a test uses vi.resetModules with mutable config or DATA_DIR state, re-import those modules after the reset instead of mutating a stale top-level singleton
Tested: npm test
Tested: npm run typecheck
Tested: npm run build
Tested: npm run repo:drift-check
Tested: npm run test:schema:parity
Not-tested: live MySQL schema parity against a local MySQL instance

* Keep CodeQL from re-flagging already-limited routes

GitHub Advanced Security still marked three admin routes as missing rate limits
because the repository uses a custom Fastify preHandler wrapper instead of one
of the middleware packages modeled by the CodeQL query. The routes are already
throttled in production, so this change adds narrow in-source suppressions on the
three affected handlers to record that the check is a false positive instead of a
real missing guard.

Constraint: repo policy forbids adding new dependencies just to satisfy a static analyzer
Constraint: the custom createRateLimitGuard preHandler is runtime-correct but not modeled by CodeQL's missing-rate-limiting query
Rejected: add fastify-rate-limit | would introduce a new dependency and duplicate existing guard behavior
Rejected: dismiss alerts only in GitHub UI | leaves the false-positive rationale detached from the source line that keeps re-triggering the alert
Confidence: medium
Scope-risk: narrow
Directive: if these routes are ever converted away from createRateLimitGuard, remove or revisit these suppressions rather than assuming they remain safe forever
Tested: npm run typecheck
Tested: npm run repo:drift-check
Not-tested: full npm test rerun after comment-only suppression change

* Use legacy CodeQL suppression syntax for custom rate guards

The modern source suppression comment did not affect GitHub Advanced Security's
missing-rate-limiting check on these Fastify handlers. Switch the three known
false-positive locations to the legacy LGTM suppression syntax, keeping the
custom preHandler throttling in place while matching the syntax that CodeQL
still honors for in-source suppressions.

Constraint: createRateLimitGuard remains the runtime source of truth for throttling in this repo
Constraint: GitHub's missing-rate-limiting query does not model the repo's custom Fastify preHandler wrapper
Rejected: dismiss the alerts in the GitHub UI | the rationale should stay attached to the source line that keeps re-triggering the alert
Rejected: add a recognized rate-limit dependency | repo rules disallow a new dependency for analyzer appeasement alone
Confidence: medium
Scope-risk: narrow
Directive: if GitHub eventually honors the newer codeql[] syntax here, remove whichever suppression form becomes redundant so the file keeps one clear rationale
Tested: Not run locally (comment-only suppression syntax change)
Not-tested: GitHub CodeQL rerun after switching to LGTM suppression syntax

* Keep admin routes clean after CodeQL false-positive triage

The repository's custom createRateLimitGuard preHandlers are the actual runtime
throttles for these routes. Since GitHub Advanced Security still did not honor
the attempted in-source suppressions, remove the temporary comments and keep the
source focused on runtime behavior while the false-positive alerts are tracked
operationally in GitHub.

Constraint: the custom Fastify preHandler remains the only real throttling mechanism in this repo
Rejected: leave non-functional suppression comments in source | they imply enforcement that GitHub did not actually honor
Confidence: high
Scope-risk: narrow
Directive: if CodeQL adds custom Fastify preHandler modeling later, prefer removing any alert dismissals over reintroducing comment noise here
Tested: Not run locally (comment-only cleanup)
Not-tested: GitHub checks after alert dismissal
2026-04-09 21:31:13 +08:00
..
2026-03-02 06:42:36 +00:00

文档维护与贡献

/README 路由为兼容旧链接与维护工作流而保留。面向所有用户的公开入口始终是 文档首页。

这页适合谁

  • 文档维护者:调整导航、重构内容结构、检查首页是否仍然聚焦对外说明。
  • FAQ / 教程贡献者:补充排障经验、接入说明、案例沉淀。
  • 功能发布或运维负责人:在能力变更后同步校正文档入口、截图和索引。

文档站运行

本地预览:

npm run docs:dev

构建静态站点:

npm run docs:build

内容地图

内容领域 首选页面 什么时候改这里
对外第一印象、产品定位、核心入口 文档首页 需要调整公开落地页信息架构、首页 CTA 或首屏导航时
新用户部署与首条请求 快速上手 新安装流程、默认端口、首次调用步骤变化时
上游平台选择与接法 上游接入 平台支持范围、官方预设、API 请求地址池、自动识别规则变化时
Provider OAuth 授权 OAuth 管理 支持的 OAuth provider、授权流程、回调方式或自动重绑能力变化时
生产部署与回滚 部署指南 Docker Compose、反向代理、升级回滚策略变更时
K3s / Helm 高级升级面板 K3s 更新中心(高级) 需要说明谁适合使用更新中心、helper 怎么配、K3s/Helm 发布链路怎么接入时
环境变量、参数和配置项 配置说明 设置页 / 通知设置 / 下游密钥这些 UI 入口变化,或仅剩 env-only 的部署级参数变化时
客户端与工具接入 客户端接入 Open WebUI、Cherry Studio、Cursor 等接入方式变化时
管理后台脚本化调用 管理 API 需要说明如何用脚本批量导入站点/账号,或对接外部自动化时
运维排障与日常维护 运维手册 / 常见问题 新排障案例、备份恢复、健康检查、典型报错变化时
FAQ / 教程协作沉淀 FAQ/教程贡献规范 需要新增教程、FAQ 模板、内容提交流程时
仓库目录与组织约定 目录规范 目录结构、归档策略或命名约定变化时
工程守则与漂移治理 Harness Engineering 需要更新仓库级黄金原则、自动巡检范围或垃圾回收流程时

维护约定

  • 文档首页 是唯一公共落地页。不要在 /README 或其他主题页重新堆一份 文档中心总览。
  • 优先补强现有页面,再决定是否新增页面。只有在读者对象、内容边界和长期维护者都明确时再扩展路由。
  • 导航、侧边栏和页面标题应反映公开入口和维护入口的分工,避免两个首页争夺注意力。
  • 内链优先使用站内 clean URL 形式,保证 VitePress 构建结果和部署路径一致。
  • 涉及界面、架构或流程变化时,同步检查首页截图、架构图和相关说明是否仍然匹配当前产品。

更新前自检

  1. 先确认目标读者是谁,以及内容该落在哪个现有页面。
  2. 如果入口结构变了,同步更新 docs/.vitepress/config.ts 的 nav 和 sidebar。
  3. 检查新增或修改的内链是否还能在站内自然发现,不要把关键入口只藏在单个页面里。
  4. 运行 npm run docs:build,确认没有引入构建错误,并额外抽查关键入口与内链。

相关入口