Skip to content

修复可用性监控加载过慢#1186

Closed
tesgth032 wants to merge 4 commits into
ding113:devfrom
tesgth032:fix/availability-monitor-loading
Closed

修复可用性监控加载过慢#1186
tesgth032 wants to merge 4 commits into
ding113:devfrom
tesgth032:fix/availability-monitor-loading

Conversation

@tesgth032
Copy link
Copy Markdown
Contributor

@tesgth032 tesgth032 commented May 14, 2026

Related Issues & PRs

背景

可用性监控的聚合查询加载很久。排查后确认热路径查询原本依赖 message_request 上的部分索引:

idx_message_request_provider_created_at_finalized_active

该索引的谓词包含 deleted_at IS NULL AND status_code IS NOT NULL。近期查询条件改为 fn_is_message_request_finalized(...) 后,SQL 不再显式包含 status_code IS NOT NULL,Postgres 难以使用这个部分索引,导致 provider + 时间范围聚合容易退化为大范围扫描。

同时,可用性监控不能直接把 requesting 中已出现 providerChain / errorMessage 片段的请求计为终态,否则会把请求中的请求误算成失败。因此这里恢复用 status_code IS NOT NULL 作为可用性监控的终态边界,继续使用 fn_compute_message_request_success_rate_outcome(...) 对终态记录做成功/失败/排除分类。

改动

  • 将可用性监控终态过滤恢复为 statusCode IS NOT NULL,重新对齐现有部分索引。
  • 保留 success-rate outcome 函数作为终态记录分类逻辑,避免把请求中的中间状态误算为失败。
  • 更新 availability service 单元测试,断言查询包含 status_code IS NOT NULL,并继续覆盖 outcome 分类函数。

验证

  • bunx vitest run tests/unit/lib/availability-service.test.ts
  • bunx biome check src/lib/availability/availability-service.ts tests/unit/lib/availability-service.test.ts
  • bun run typecheck
  • bun run lint
  • bun run lint:fix
  • bun run test
  • bun run build

说明:bun run build 通过,过程中仍会输出仓库既有的 Edge Runtime 警告。

Greptile Summary

This PR restores status_code IS NOT NULL as the finalized-request boundary in availability monitoring, replacing the fn_is_message_request_finalized(...) call that was preventing PostgreSQL from using the partial index idx_message_request_provider_created_at_finalized_active, causing full-scan degradation on the hot aggregation path.

  • availability-service.ts: buildAvailabilityFinalizedCondition() now returns isNotNull(messageRequest.statusCode) (one line, uses the new isNotNull import). Outcome classification (fn_compute_message_request_success_rate_outcome) is preserved and still drives greenCount/redCount via FILTER (WHERE successRateOutcome IN ('success', 'failure')), so blocked/excluded records with a statusCode remain harmless.
  • availability-service.test.ts: extractFinalizedRequestsSql is hardened with a new findCteBoundary helper that uses a regex anchored to CTE keyword boundaries instead of a fragile indexOf. Four test assertions are updated from fn_is_message_request_finalized to "status_code" is not null; one previously missing assertion is added to the Gemini passthrough test.

Confidence Score: 5/5

Safe to merge — the change is a targeted one-line revert in the finalized condition, backed by updated tests that assert the correct SQL predicate appears in the generated query.

The core change is a single, well-scoped substitution: replacing a PL/pgSQL function call with a direct column null-check that the existing partial index was already designed to serve. Outcome classification is untouched and still controls which finalized records count as green or red. The test helper improvement is strictly additive and more correct than the previous indexOf-based extraction. No logic paths were removed or silently skipped.

No files require special attention.

Important Files Changed

Filename Overview
src/lib/availability/availability-service.ts Reverts finalized-condition from fn_is_message_request_finalized(...) to isNotNull(statusCode) to re-align with the partial index predicate; adds isNotNull import; updates JSDoc comment
tests/unit/lib/availability-service.test.ts Adds findCteBoundary() for more robust CTE boundary detection; updates assertions from fn_is_message_request_finalized to "status_code" is not null; adds one missing assertion to the Gemini passthrough test

Sequence Diagram

sequenceDiagram
    participant Client
    participant AvailService as AvailabilityService
    participant DB as PostgreSQL

    Client->>AvailService: queryProviderAvailability(options)
    AvailService->>DB: "SELECT providers WHERE isEnabled=true"
    DB-->>AvailService: [providerList]

    AvailService->>DB: WITH finalized_requests AS (SELECT ... FROM message_request WHERE status_code IS NOT NULL AND deleted_at IS NULL), provider_bucket_stats AS (SELECT ... COUNT/AVG/PERCENTILE via fn_compute_outcome) SELECT ... FROM limited_provider_bucket_stats
    DB-->>AvailService: [bucketRows]
    AvailService-->>Client: AvailabilityQueryResult

    note over AvailService,DB: Previously: WHERE fn_is_message_request_finalized(...) skipped partial index
    note over AvailService,DB: Now: WHERE status_code IS NOT NULL hits idx_message_request_provider_created_at_finalized_active
Loading

Comments Outside Diff (1)

  1. tests/unit/lib/availability-service.test.ts, line 42-51 (link)

    P2 extractFinalizedRequestsSql silently passes if anchor text collides

    extractFinalizedRequestsSql slices between the first occurrence of "finalized_requests as" and "provider_bucket_stats as". If Drizzle ever quotes identifiers differently or the CTE names shift, both indexOf calls can return -1 and the guard throws — but if only the second sentinel is missing while the first is present, end === -1 is caught. More critically, if any literal string in the query accidentally contains "provider_bucket_stats as" earlier than the actual CTE definition, the slice would be silently truncated, causing assertions on the extracted snippet to produce false-positives. A more robust anchor using a regex with a CTE keyword boundary would make this helper more resilient to query text drift.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: tests/unit/lib/availability-service.test.ts
    Line: 42-51
    
    Comment:
    **`extractFinalizedRequestsSql` silently passes if anchor text collides**
    
    `extractFinalizedRequestsSql` slices between the first occurrence of `"finalized_requests as"` and `"provider_bucket_stats as"`. If Drizzle ever quotes identifiers differently or the CTE names shift, both `indexOf` calls can return `-1` and the guard throws — but if only the second sentinel is missing while the first is present, `end === -1` is caught. More critically, if any literal string in the query accidentally contains `"provider_bucket_stats as"` earlier than the actual CTE definition, the slice would be silently truncated, causing assertions on the extracted snippet to produce false-positives. A more robust anchor using a regex with a CTE keyword boundary would make this helper more resilient to query text drift.
    
    How can I resolve this? If you propose a fix, please make it concise.

Reviews (4): Last reviewed commit: "test: 优化 CTE 边界测试诊断" | Re-trigger Greptile

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

将可用性服务的“终态”判定从调用数据库函数替换为直接检查 messageRequest.statusCode IS NOT NULL,并改写单元测试中提取并断言 finalized_requests CTE 的逻辑(使用正则定位 CTE 边界并匹配 "status_code" is not null)。

变更清单

终态判定逻辑简化

Layer / File(s) Summary
终态条件实现
src/lib/availability/availability-service.ts
buildAvailabilityFinalizedCondition() 改为使用 isNotNull(messageRequest.statusCode) 替代对 fn_is_message_request_finalized() 的调用;调整 drizzle-orm 导入以添加 isNotNull;更新注释说明仅以 statusCode 非空判定为终态。
测试断言与 CTE 提取更新
tests/unit/lib/availability-service.test.ts
新增 findCteBoundary 并改写 extractFinalizedRequestsSql 为基于正则的 CTE 边界定位(支持可选引号);将多处对 finalized_requests 的断言从 fn_is_message_request_finalized 改为匹配 "status_code" is not null,覆盖聚合、排除进行中请求、Gemini passthrough、避免中间状态误判及 getCurrentProviderStatus 的校验场景。

估算代码审查工作量

🎯 3 (Moderate) | ⏱️ ~20 minutes

可能相关的 PR

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed 代码变更完整解决了#1168中报告的问题:通过恢复statusCode IS NOT NULL条件,使查询能重新利用部分索引idx_message_request_provider_created_at_finalized_active,避免CPU飙升时的大范围扫描。
Out of Scope Changes check ✅ Passed 所有代码变更均围绕恢复终态判定条件与测试完整性展开:availability-service.ts修改了buildAvailabilityFinalizedCondition();test文件加强了CTE提取健壮性并更新了相关断言,均为预期范围内。
Description check ✅ Passed PR 描述详细且完全关联到代码变更,清晰说明了性能问题根因、修复策略及验证方法。
Title check ✅ Passed PR 标题与主要代码变更相符。标题指向性能修复,而变更内容恢复了 statusCode IS NOT NULL 条件以启用数据库部分索引,直接解决了可用性监控查询导致 CPU 飙升的问题。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added bug Something isn't working area:statistics labels May 14, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request simplifies the logic for identifying finalized message requests by replacing a complex SQL function with a check for a non-null status code. This change, applied in the availability service and verified in unit tests, aims to prevent misclassifying active requests as failures. Feedback suggests that while this improves query performance by utilizing database indices, it may inadvertently exclude certain early-stage failures like DNS or connection timeouts, potentially leading to an overestimation of availability metrics.

Comment thread src/lib/availability/availability-service.ts
@github-actions github-actions Bot added the size/XS Extra Small PR (< 50 lines) label May 14, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

No significant issues identified in this PR. The change is a well-reasoned performance fix that restores partial index utilization by aligning the availability query's finalized condition with the existing status_code IS NOT NULL partial index predicate. The rationale for excluding intermediate states (where providerChain/errorMessage may be set but statusCode is still null) is clearly documented in the updated comment.

PR Size: XS

  • Lines changed: 26
  • Files changed: 2

Review Coverage

  • Logic and correctness - Clean. The change correctly narrows the finalized boundary to statusCode IS NOT NULL, which both matches the partial index predicate and avoids misclassifying in-progress requests as failed.
  • Security (OWASP Top 10) - Clean. No security-relevant changes; continues using Drizzle ORM parameterized SQL.
  • Error handling - Clean. No new error paths introduced.
  • Type safety - Clean. isNotNull import and usage are type-safe.
  • Documentation accuracy - Clean. The updated JSDoc comment accurately explains the rationale and tradeoffs.
  • Test coverage - Adequate. All 5 SQL assertion tests updated to match the new predicate, plus an additional assertion added in the Gemini passthrough test.
  • Code clarity - Good. The function is simplified from a multi-parameter SQL function call to a single Drizzle helper.

Automated review by Claude AI

@tesgth032
Copy link
Copy Markdown
Contributor Author

补充状态:

  • 已复核 Gemini 关于 statusCode IS NOT NULL 可能排除早期失败的提醒。当前代理失败持久化路径会为已终态失败写入明确的 statusCode(例如 499/500/502),而 status_code = NULL 更接近 in-flight / orphan / 未完整落库状态;纳入可用性监控会重新引入 requesting 中请求被误判为失败的问题,因此本 PR 不继续放宽终态条件。
  • 远端检查中 Unit TestsAPI TestsIntegration TestsCode QualityDocker Build Test 均已通过。
  • 唯一失败的 Codex PR Review 是权限门禁:当前 fork 作者 tesgth032 对上游仓库只有 read 权限,该 action 要求 write 权限;不是代码或测试失败。

@tesgth032
Copy link
Copy Markdown
Contributor Author

已按 Greptile 的建议补充一轮 follow-up:

  • 加固 extractFinalizedRequestsSql,改为按 CTE 边界匹配 finalized_requestsprovider_bucket_stats,避免简单 indexOf 在锚点漂移或碰撞时产生不稳定断言。
  • 本轮验证:
    • bunx vitest run tests/unit/lib/availability-service.test.ts
    • bunx biome check tests/unit/lib/availability-service.test.ts
    • bun run typecheck
    • git diff --check

请再跑一轮 AI review。

@coderabbitai review
@gemini-code-assist review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

@tesgth032 感谢您的更新!已收到以下改进信息:

  • extractFinalizedRequestsSql 加固:改为按 CTE 边界匹配 finalized_requestsprovider_bucket_stats,避免简单 indexOf 在锚点漂移或碰撞时产生不稳定断言,这是一个很好的改进。
  • 本轮验证均已完成(vitest、biome check、typecheck、git diff --check)。

正在触发新一轮 AI review,请稍候。

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/unit/lib/availability-service.test.ts (1)

42-59: 💤 Low value

建议增强输入验证以防御极端情况。

虽然当前实现中 cteName 已通过正则转义处理,且实际调用时仅使用硬编码的 CTE 名称("finalized_requests"、"provider_bucket_stats"),但静态分析工具仍标记了潜在的 ReDoS 风险。考虑添加输入约束验证以明确防御边界并消除静态分析警告。

防御性验证建议
 function findCteBoundary(
   queryText: string,
   cteName: string
 ): { cteStart: number; boundaryStart: number } | null {
+  if (!/^[a-z_][a-z0-9_]*$/i.test(cteName)) {
+    throw new Error(`Invalid CTE name: ${cteName}`);
+  }
   const escapedName = cteName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
   const match = new RegExp(`(?:^|\\bwith\\s+|,\\s*)("?${escapedName}"?)\\s+as\\s*\\(`).exec(
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/lib/availability-service.test.ts` around lines 42 - 59, The
findCteBoundary function currently builds a dynamic regex from cteName; to
defend against ReDoS add defensive validation up-front: validate queryText is a
non-empty string and validate cteName is short (e.g. max length 100) and only
contains safe characters (alphanumerics, underscore, optionally quoted double
quotes), returning null or throwing if validation fails; after those checks
continue to construct escapedName and run the existing RegExp logic. This keeps
the existing behavior (use of escapedName, match extraction and returned
cteStart/boundaryStart) but prevents long/complex inputs from being used in the
regex and removes static-analysis warnings about ReDoS.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/unit/lib/availability-service.test.ts`:
- Around line 42-59: The findCteBoundary function currently builds a dynamic
regex from cteName; to defend against ReDoS add defensive validation up-front:
validate queryText is a non-empty string and validate cteName is short (e.g. max
length 100) and only contains safe characters (alphanumerics, underscore,
optionally quoted double quotes), returning null or throwing if validation
fails; after those checks continue to construct escapedName and run the existing
RegExp logic. This keeps the existing behavior (use of escapedName, match
extraction and returned cteStart/boundaryStart) but prevents long/complex inputs
from being used in the regex and removes static-analysis warnings about ReDoS.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b865efba-6a96-4187-8be3-d415093fb74d

📥 Commits

Reviewing files that changed from the base of the PR and between 7ea3382 and fa53488.

📒 Files selected for processing (1)
  • tests/unit/lib/availability-service.test.ts

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request simplifies the availability finalized condition by replacing a SQL function call with a direct null check on statusCode, which improves query performance by allowing the use of partial indexes. The unit tests have been updated to reflect this change and introduce a new findCteBoundary helper for more reliable SQL parsing. Feedback indicates that the implementation of this helper is somewhat fragile and could be improved by using capturing groups or the RegExp d flag to more robustly determine the start of the CTE name.

Comment thread tests/unit/lib/availability-service.test.ts
@tesgth032
Copy link
Copy Markdown
Contributor Author

已继续处理第二轮 AI review:

  • 针对 CodeRabbit 的 ReDoS 防御建议,为 findCteBoundary 增加 queryText 非空、cteName 长度与安全字符集约束。
  • 针对 Gemini 关于 match[0].indexOf(match[1]) 的脆弱性提醒,改为捕获 CTE 前缀并用前缀长度计算 cteStart
  • 本轮验证:
    • bunx vitest run tests/unit/lib/availability-service.test.ts
    • bunx biome check tests/unit/lib/availability-service.test.ts
    • bun run typecheck
    • git diff --check

请再跑一轮 AI review。

@coderabbitai review
@gemini-code-assist review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

@tesgth032 感谢您持续跟进并处理第二轮 review 意见!本轮改进摘要如下:

  • ReDoS 防御:为 findCteBoundary 增加了 queryText 非空守卫及 cteName 长度与字符集约束,有效防止正则表达式在极端输入下发生回溯灾难。
  • CTE 边界计算健壮性:将脆弱的 match[0].indexOf(match[1]) 替换为捕获 CTE 前缀并以前缀长度推算 cteStart,消除了因子串多次出现导致定位错误的风险。
  • 本轮验证均已通过(vitest、biome check、typecheck、git diff --check)。

正在触发新一轮完整 AI review,请稍候。

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request simplifies the availability monitoring logic by replacing a complex SQL function with a direct check for non-null status codes to improve database performance. It also enhances the test suite with a more robust helper for identifying SQL CTE boundaries. A review comment identifies a potential issue where this change might exclude network-level failures from monitoring if they lack a status code, which could lead to inaccurate availability metrics.

Comment thread src/lib/availability/availability-service.ts
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
tests/unit/lib/availability-service.test.ts (2)

42-63: 💤 Low value

输入验证有效防御了 ReDoS 风险,但建议添加注释说明。

静态分析工具标记了 50 行从变量构造正则表达式的潜在 ReDoS 风险。当前实现通过以下措施有效缓解了该风险:

  1. 长度限制:46 行限制 cteName 最大 100 字符
  2. 格式验证:46 行确保输入符合 SQL 标识符模式 [a-z_][a-z0-9_]*
  3. 特殊字符转义:50 行正确转义了所有正则元字符
  4. 受控调用:实际仅在 66-67 行用硬编码字符串调用

虽然当前代码安全,但建议在函数开头添加注释明确说明这些安全措施,便于后续维护者理解设计意图。

建议添加的注释
 function findCteBoundary(
   queryText: string,
   cteName: string
 ): { cteStart: number; boundaryStart: number } | null {
+  // Security: Input validation below prevents ReDoS attacks by constraining
+  // cteName length and format before using it in regex construction.
   if (queryText.length === 0 || cteName.length > 100 || !/^[a-z_][a-z0-9_]*$/i.test(cteName)) {

Based on learnings: 静态分析工具标记从变量构造正则表达式存在 ReDoS 风险(CWE-1333),需要通过输入验证或使用 recheck 等库来确保安全。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/lib/availability-service.test.ts` around lines 42 - 63, Add a
short comment at the top of function findCteBoundary explaining why constructing
a RegExp from cteName is safe: note the explicit input validation on cteName
(length <= 100 and format check /^[a-z_][a-z0-9_]*$/i), the escaping step that
produces escapedName via cteName.replace(...), and that the RegExp using
escapedName is only used in this controlled context; reference the variables
cteName, escapedName and the RegExp construction to make the rationale clear for
future maintainers and static analyzers.

65-74: ⚡ Quick win

改进错误消息以区分不同失败场景。

当前错误消息"Could not locate finalized_requests CTE in query text"无法区分以下三种失败情况:

  1. finalized_requests CTE 不存在
  2. provider_bucket_stats CTE 不存在
  3. 两个 CTE 存在但顺序错误

建议根据 startend 的值提供更具体的错误消息,便于调试测试失败时快速定位原因。

建议的改进
 function extractFinalizedRequestsSql(queryText: string): string {
   const start = findCteBoundary(queryText, "finalized_requests");
   const end = findCteBoundary(queryText, "provider_bucket_stats");

-  if (!start || !end || end.boundaryStart <= start.cteStart) {
-    throw new Error("Could not locate finalized_requests CTE in query text");
+  if (!start) {
+    throw new Error("Could not locate finalized_requests CTE in query text");
+  }
+  if (!end) {
+    throw new Error("Could not locate provider_bucket_stats CTE in query text");
+  }
+  if (end.boundaryStart <= start.cteStart) {
+    throw new Error("CTEs found in unexpected order or overlapping");
   }

   return queryText.slice(start.cteStart, end.boundaryStart);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/lib/availability-service.test.ts` around lines 65 - 74, In
extractFinalizedRequestsSql, improve the thrown Error to distinguish three
failure cases: missing finalized_requests CTE (start is falsy), missing
provider_bucket_stats CTE (end is falsy), and ordering issue (both present but
end.boundaryStart <= start.cteStart). Update the function to check these
conditions and throw distinct, descriptive messages that reference the CTE names
(e.g., "finalized_requests CTE not found", "provider_bucket_stats CTE not
found", "finalized_requests CTE appears after provider_bucket_stats CTE"), so
test failures clearly indicate which scenario occurred.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/unit/lib/availability-service.test.ts`:
- Around line 42-63: Add a short comment at the top of function findCteBoundary
explaining why constructing a RegExp from cteName is safe: note the explicit
input validation on cteName (length <= 100 and format check
/^[a-z_][a-z0-9_]*$/i), the escaping step that produces escapedName via
cteName.replace(...), and that the RegExp using escapedName is only used in this
controlled context; reference the variables cteName, escapedName and the RegExp
construction to make the rationale clear for future maintainers and static
analyzers.
- Around line 65-74: In extractFinalizedRequestsSql, improve the thrown Error to
distinguish three failure cases: missing finalized_requests CTE (start is
falsy), missing provider_bucket_stats CTE (end is falsy), and ordering issue
(both present but end.boundaryStart <= start.cteStart). Update the function to
check these conditions and throw distinct, descriptive messages that reference
the CTE names (e.g., "finalized_requests CTE not found", "provider_bucket_stats
CTE not found", "finalized_requests CTE appears after provider_bucket_stats
CTE"), so test failures clearly indicate which scenario occurred.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c1f8ac44-fc35-46c3-9270-46a80e13bc3b

📥 Commits

Reviewing files that changed from the base of the PR and between fa53488 and 039918d.

📒 Files selected for processing (1)
  • tests/unit/lib/availability-service.test.ts

@tesgth032
Copy link
Copy Markdown
Contributor Author

已处理第三轮 CodeRabbit 的两条 nitpick:

  • findCteBoundary 补充注释,说明 cteName 的长度/格式校验与 escapedName 转义后再参与受控测试正则构造。
  • 拆分 extractFinalizedRequestsSql 的 CTE 定位错误,分别区分 finalized_requests 缺失、provider_bucket_stats 缺失以及 CTE 顺序异常,方便后续测试失败定位。

本轮验证:

  • bunx biome check tests/unit/lib/availability-service.test.ts
  • bunx vitest run tests/unit/lib/availability-service.test.ts
  • bun run typecheck
  • git diff --check

请再跑一轮 AI review。

@coderabbitai review
@gemini-code-assist review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

@tesgth032 感谢您持续跟进并处理第三轮 nitpick!本轮改进摘要如下:

  • findCteBoundary 注释补充:明确说明了 cteName 的长度/格式校验逻辑,以及 escapedName 转义后再参与受控正则构造的意图,提升了代码可维护性。
  • extractFinalizedRequestsSql 错误分层:将 CTE 定位错误拆分为三类独立错误(finalized_requests 缺失、provider_bucket_stats 缺失、CTE 顺序异常),有利于后续测试失败时快速定位根因。
  • 本轮验证均已通过(biome check、vitest、typecheck、git diff --check)。

正在触发新一轮完整 AI review,请稍候。

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@tesgth032 tesgth032 changed the title 修复可用性监控加载过慢 [未完成] 修复可用性监控加载过慢 May 14, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request simplifies the availability monitoring logic by replacing the fn_is_message_request_finalized SQL function with a direct check for non-null status codes. Additionally, the unit tests were updated with a more robust findCteBoundary helper for parsing SQL strings. Feedback was provided to improve the findCteBoundary function by ensuring case-consistency between the input validation and the regex search to prevent potential mismatches.

Comment on lines +47 to +54
if (queryText.length === 0 || cteName.length > 100 || !/^[a-z_][a-z0-9_]*$/i.test(cteName)) {
return null;
}

const escapedName = cteName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const match = new RegExp(`(^|\\bwith\\s+|,\\s*)("?${escapedName}"?)\\s+as\\s*\\(`).exec(
queryText
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The findCteBoundary function performs a case-insensitive validation on cteName (using the /i flag on line 47), but the RegExp constructed on line 52 is case-sensitive. Since queryText is explicitly lowercased by normalizeSql, a cteName passed with uppercase characters would pass the initial validation but fail to match the query text. For consistency and robustness, the RegExp should also use the i flag, or cteName should be lowercased before constructing the regex.

Suggested change
if (queryText.length === 0 || cteName.length > 100 || !/^[a-z_][a-z0-9_]*$/i.test(cteName)) {
return null;
}
const escapedName = cteName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const match = new RegExp(`(^|\\bwith\\s+|,\\s*)("?${escapedName}"?)\\s+as\\s*\\(`).exec(
queryText
);
if (queryText.length === 0 || cteName.length > 100 || !/^[a-z_][a-z0-9_]*$/i.test(cteName)) {
return null;
}
const escapedName = cteName.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const match = new RegExp("(^|\\bwith\\s+|,\\s*)(\"?" + escapedName + "\"?)\\s+as\\s*\\(", "i").exec(
queryText
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:statistics bug Something isn't working size/XS Extra Small PR (< 50 lines)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants