Skip to content

fix: scan watermark を導入して targeted fetch によるギャップ取りこぼしを解消#279

Merged
coji merged 3 commits intomainfrom
fix/scan-watermark-278
Apr 7, 2026
Merged

fix: scan watermark を導入して targeted fetch によるギャップ取りこぼしを解消#279
coji merged 3 commits intomainfrom
fix/scan-watermark-278

Conversation

@coji
Copy link
Copy Markdown
Owner

@coji coji commented Apr 7, 2026

Closes #278

Summary

  • crawlstopBeforegithubRawData.updatedAt の MAX を使っていたため、webhook 由来の targeted fetch (prNumbers 指定) が MAX を先に進め、ギャップ中にマージされた古い PR が次の full crawl の stopBefore の向こうに置き去りになるバグがあった
  • repositoriesscanWatermark カラムを追加し、full-sweep crawl が完走したときだけ前進させる。targeted fetch と部分失敗時は一切触らない
  • watermark 算出ロジックを computeAdvancedScanWatermark として純粋関数に抽出し、不変条件を JSDoc に明記 + 単体テストで縛る

変更点

  • スキーマ: repositories.scan_watermark TEXT NULL 追加、マイグレーションで既存 raw data の MAX(updated_at) からバックフィル
  • batch/github/store.ts: getLatestUpdatedAtgetScanWatermark / setScanWatermark
  • app/services/jobs/crawl.server.ts: stopBefore のソースを watermark に切り替え、完走時に前進
  • app/services/jobs/scan-watermark.ts: 純粋ロジック + 単体テスト(crawl watermark と PR updatedAt MAX の兼用による取りこぼしバグ #278 シナリオの end-to-end 再現を含む)

不変条件 (computeAdvancedScanWatermark)

  1. targeted fetch は絶対に前進させない — PR 番号指定の fetch は連続区間を保証しないため
  2. 部分失敗時は前進させない — 失敗 PR を次の sweep で再取得させるため
  3. 空スイープは前進させない — 何も確認していないため

対象外

  • GitHub App インストール時の即時バックフィル trigger は補助的対応として別 issue で扱う

Test plan

🤖 Generated with Claude Code

Summary by CodeRabbit

リリースノート

  • 新機能

    • PR スキャン処理の進捗追跡メカニズムを改善しました。リポジトリごとのスキャン効率が向上し、不要な重複取得が削減されます。
  • テスト

    • スキャン処理の新しいロジックに関する包括的なテストスイートを追加しました。

coji and others added 3 commits April 7, 2026 10:00
crawl の stopBefore に githubRawData.updatedAt の MAX を使っていたため、
webhook 由来の targeted fetch が max を先に進めてしまい、ギャップ中に
マージされた古い PR が次の full crawl の stopBefore の向こうに置き去り
になるバグを修正。

repositories テーブルに scanWatermark カラムを追加し、full-sweep crawl
が完走したときだけ前進させる。targeted fetch (prNumbers 指定) と
部分失敗時は watermark を動かさない。

Closes #278
getScanWatermark() 呼び出しは getOrganization が既に repositories に含めて
ロードしているため冗長。repo.scanWatermark を直接参照することで per-repo の
DB 往復と step.run オーバーヘッドを削減。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
サイズ比較だと savedPrNumbers に無関係な番号が混ざったケースで
誤って前進してしまう可能性があった。pure function としての
防御性を上げるため、prsToFetch の各番号が savedPrNumbers に
含まれることを明示的に確認する。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coji coji merged commit 5d10bde into main Apr 7, 2026
6 checks passed
@coji coji deleted the fix/scan-watermark-278 branch April 7, 2026 01:24
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 7, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 899a318c-8485-443d-bb9d-dec15d56dcbb

📥 Commits

Reviewing files that changed from the base of the PR and between b88839b and 0d1be6d.

⛔ Files ignored due to path filters (1)
  • db/migrations/tenant/atlas.sum is excluded by !**/*.sum
📒 Files selected for processing (9)
  • app/services/jobs/crawl.server.ts
  • app/services/jobs/scan-watermark.test.ts
  • app/services/jobs/scan-watermark.ts
  • app/services/tenant-type.ts
  • batch/db/queries.ts
  • batch/github/store.test.ts
  • batch/github/store.ts
  • db/migrations/tenant/20260407004753_add_scan_watermark.sql
  • db/tenant.sql

📝 Walkthrough

ウォークスルー

リポジトリの「スキャン済みの範囲」を表すウォーターマークを導入する変更。webhook由来の限定的な取得(targeted fetch)とは別に、full-sweep crawlのみが境界値を進める仕組みに替え、ギャップ期間の取りこぼしバグを防止します。データベース、ストア層、crawlジョブロジックにおいて関連する複数の変更を含みます。

変更内容

コホート / ファイル(s) 概要
データベーススキーマ
db/tenant.sql, db/migrations/tenant/20260407004753_add_scan_watermark.sql
repositoriesテーブルにscan_watermarkテキスト列を追加。既存PRの最大updatedAtから初期値を設定します。
型定義
app/services/tenant-type.ts
RepositoriesインターフェイスにscanWatermark: string | nullフィールドを追加。
クエリ層
batch/db/queries.ts
getTenantDataクエリのrepositories選択フィールドにscanWatermarkを追加。
ストア層
batch/github/store.ts, batch/github/store.test.ts
getLatestUpdatedAt()を削除し、getScanWatermark()setScanWatermark()を追加。ウォーターマークの永続化をリポジトリテーブルから管理します。
ウォーターマーク計算
app/services/jobs/scan-watermark.ts, app/services/jobs/scan-watermark.test.ts
新規関数computeAdvancedScanWatermarkと包括的なテストスイートを実装。targeted fetchではnullを返し、full-sweepのみ最大updatedAtを計算・返却します。
crawlジョブロジック
app/services/jobs/crawl.server.ts
lastFetchedAtの取得元をstore.getLatestUpdatedAt()からrepo.scanWatermarkに変更。成功したPR取得後にcomputeAdvancedScanWatermarkでウォーターマーク更新を判定し、setScanWatermarkで永続化します。

推定レビュー工数

🎯 3 (Moderate) | ⏱️ ~25 分

関連する可能性のあるPR

  • PR #276: PR取得の停止境界条件を修正(updatedAt == stopBeforeの比較)。本PRが導入するscanWatermarkに基づいた停止ロジックと関連しています。
  • PR #265: crawl.server.tsのPRリスト取得・早期停止ロジックを変更。本PRがscanWatermark駆動の流れに更新する対象となっている箇所です。
  • PR #208: crawl.server.tsのcrawlジョブロジックを修正。本PRと同じファイルのcrawl実装を変更するため関連しています。

🐰 ウォーターマークよ、前に進め
full-sweep のときだけ、ゆっくり
webhook の急かしに動じず
ギャップの古い PR も拾い上げ
穴のない爬虫類の足跡を 🌊

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/scan-watermark-278

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.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

crawl watermark と PR updatedAt MAX の兼用による取りこぼしバグ

1 participant