refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消 - #554

Merged
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28
Jul 28, 2026
Merged

refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消#554
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

/goal によるリファクタリングスキル一括実行タスク。BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを並列実行してレビューし、検出された High 指摘全件と、関連する安全な Medium 項目を修正した。

Backend

  • services/agent/ 配下4モジュール(chat / resume_draft / resume_import / skill_display)に一言一句コピーされていた「LLM呼び出し→1回リトライ→トークン合算」ロジックを services/agent/llm/retry.py_utils.py(コードフェンス剥がし)に抽出(Rule of Three 到達済み)
  • 呼び出し元ゼロ・カバレッジ0%の死コード(intelligence_generator 系 PDF/Markdown、計約275行)を削除
  • routers/agent.pyrouters/github_link/endpoints.py に重複していた日次レート制限429変換ロジックを routers/_shared.py に抽出
  • resume.py の冗長なローカル import を解消
  • resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加(616 tests, 90% coverage)

Frontend

  • useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、失敗パスのテストを追加(CLAUDE.md「例外の握りつぶし禁止」ルール対応)
  • useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
  • useCareerExportActions.ts(認証ゲート・活性制御ロジック)のテストを新規追加(359 tests)

Cross-realm

  • 存在しない backend エンドポイントを参照していた死コード web/src/api/ai-resume.tsPATHS.aiResume を削除

見送った項目(レビュー自身が優先度低・時期尚早と判断したもの。過剰な抽象化を避けるため今回は対応しない)

  • Infra: cloud_run の secret_manager module 分割(Terraform state 影響あり)・CI matrix 化(挙動変更リスクあり)。HCL重複率は既に0%(過去のsymlink統合で解消済み)で緊急度なし
  • Backend Medium: routers/agent.py package化、resume_generator._build_html 分割、github_collector._collect_repo_signals 分割、_SequentialFakeLLM 統合
  • Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three 未達、2箇所のみ)、setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編

各レビューの詳細レポートは report/*.md(gitignore 対象のためリポジトリには含まれない)。

Test plan

  • make ci(lint-backend / typecheck-backend / test-backend / lint-web / test-web / build-web)全て green
  • backend: 616 passed, 90% coverage
  • web: 48 files / 359 tests passed
  • make codegen-types 差分なし確認済み(OpenAPI契約に影響する変更なし)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • AI-powered resume import, drafting, and skill suggestions now retry once when responses are invalid, improving successful completion and usage reporting.
    • Fenced or formatted AI responses are handled more reliably.
  • Bug Fixes

    • Agent-related actions now consistently enforce daily usage limits and return a clear rate-limit error when exceeded.
    • Authentication, master-data, and notification failures now provide warning feedback for improved troubleshooting.
  • Removed

    • Legacy AI resume snapshot and intelligence report generation capabilities were removed.

BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを実行し、
検出された High 指摘と関連する安全な Medium 項目を修正。
## Backend
- services/agent/ 配下4モジュール(chat/resume_draft/resume_import/skill_display)に
重複していた LLM リトライ+トークン集計ロジックを services/agent/llm/retry.py と
_utils.py(コードフェンス剥がし)に抽出
- 呼び出し元ゼロの死コード(intelligence_generator 系、PDF/Markdown 計約275行)を削除
- routers/agent.py と routers/github_link/endpoints.py に重複していた
日次レート制限429変換ロジックを routers/_shared.py に抽出
- resume.py の冗長なローカル import を解消
- resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加
## Frontend
- useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、
失敗パスのテストを追加(CLAUDE.md の例外握りつぶし禁止ルール対応)
- useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
- useCareerExportActions.ts のテストを新規追加(認証ゲート・活性制御の分岐)
## Cross-realm
- 存在しない backend エンドポイントを参照する死コード
web/src/api/ai-resume.ts と PATHS.aiResume を削除
## 見送った項目(レビュー自身が優先度低・時期尚早と判断)
- Infra: cloud_run の secret_manager 分割・CI matrix 化(state影響/挙動変更リスクに対し
実利小、HCL重複率は既に0%)
- Backend Medium: routers/agent.py package化、resume_generator._build_html分割、
github_collector._collect_repo_signals分割、_SequentialFakeLLM統合
- Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three未達)、
setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編
検証: make ci(lint / test-backend 616 passed / test-web 359 passed / build-web)全て green
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent refactor リファクタリング labels Jul 28, 2026
@coderabbitai

coderabbitaiBot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b8594c33-b945-48d4-a9dc-42af9491244d

📥 Commits

Reviewing files that changed from the base of the PR and between 60ab364 and 38efd10.

📒 Files selected for processing (5)
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/tests/test_routers_shared.py
📝 Walkthrough

Walkthrough

The PR centralizes agent LLM retry, parsing, usage accounting, and daily-limit handling; adds backend and frontend tests; removes obsolete intelligence-report and AI-resume API code; and adds frontend warning logs for caught errors.

Changes

Agent LLM orchestration

Layer / File(s)Summary
Shared parsing, usage, and retry contracts
backend/app/services/agent/_utils.py, backend/app/services/agent/llm/*
Shared code-fence parsing, AgentUsage, and single-retry orchestration are introduced.
Chat service integration
backend/app/services/agent/chat_service.py
Chat parsing, exports, retry handling, and usage accounting use the shared helpers.
Agent service migration and validation
backend/app/services/agent/resume_draft/*, backend/app/services/agent/resume_import/*, backend/app/services/agent/skill_display/*, backend/tests/test_resume_import_service.py
Agent services delegate parsing and retry behavior to the common helper, with resume-import retry and usage tests added.

Agent daily-limit routing

Layer / File(s)Summary
Shared daily-limit enforcement
backend/app/routers/_shared.py, backend/tests/test_routers_shared.py
Daily-limit checks, commits, and HTTP 429 conversion are extracted and tested.
Endpoint adoption
backend/app/routers/agent.py, backend/app/routers/github_link/endpoints.py
Agent-related endpoints call the shared enforcement helper.

Resume project sorting

Layer / File(s)Summary
Project period date parsing
backend/app/repositories/resume.py
Project sorting uses the module-level date type without changing parsing behavior.

Intelligence report removal

Layer / File(s)Summary
Remove intelligence report generators
backend/app/services/markdown/generators/..., backend/app/services/markdown/templates/..., backend/app/services/pdf/generators/...
Intelligence Markdown/PDF generators and template constants are removed.

Web API and error observability

Layer / File(s)Summary
Career export behavior coverage
web/src/hooks/career/useCareerExportActions.test.ts
Career export authentication, resume availability, actions, and disabled states are tested.
Frontend warning logging
web/src/hooks/useAuthSession.ts, web/src/hooks/useMasterData.ts, web/src/hooks/useNotifications.*
Caught frontend errors now emit warnings while existing fallback behavior remains.
Remove obsolete AI-resume routes
web/src/api/ai-resume.ts, web/src/api/paths.ts
The AI-resume API wrapper and route definitions are removed.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
participant AgentService
participant RetryHelper
participant LLM
participant Parser
AgentService->>RetryHelper: Submit generation request
RetryHelper->>LLM: Generate response
LLM-->>RetryHelper: Response and usage
RetryHelper->>Parser: Parse response
Parser-->>RetryHelper: Parsed output or error
RetryHelper->>LLM: Retry with feedback
LLM-->>RetryHelper: Retry response and usage
RetryHelper-->>AgentService: Output and aggregated usage
Loading

Possibly related PRs

Suggested labels:backend, web, test, agent, documentation

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 74.36% 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedPRの主目的であるBE/WEB/XRのリファクタリングレビューHigh指摘解消を端的に表しており、変更内容と整合しています。
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/all-skills-2026-07-28

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
backend/app/services/agent/resume_draft/draft_service.py (1)

21-21: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Shared types imported through ..chat_service instead of the canonical ..llm.base.llm/base.py is now documented as the source of truth for AgentResponseParseError / AgentUsage; the re-export in chat_service exists only for backward compatibility, so newly-migrated services needlessly depend on the chat module (including its import-time prompt file read).

  • backend/app/services/agent/resume_draft/draft_service.py#L21-L21: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/resume_import/import_service.py#L23-L23: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/skill_display/proposer.py#L20-L20: change to from ..llm.base import AgentResponseParseError, AgentUsage.
🤖 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 `@backend/app/services/agent/resume_draft/draft_service.py` at line 21, Update
the imports in draft_service.py (line 21), import_service.py (line 23), and
proposer.py (line 20) to source AgentResponseParseError and AgentUsage from the
canonical ..llm.base module instead of ..chat_service; no other changes are
needed.
backend/app/services/agent/_utils.py (1)

11-15: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Fence stripping only handles a lowercase json tag.

text.strip("")also removes any trailing backticks anywhere at the ends, andremoveprefix("json")missesJSON` / other language tags, leaving the tag in the payload and forcing an unnecessary retry. A regex-based fence strip would be more robust; behavior today still degrades safely via the parse-error retry path, so this is optional.

♻️ Optional: regex-based fence strip
+import re++_FENCE_RE = re.compile(r"^```[A-Za-z0-9_+-]*\s*\n?(.*?)\n?```$", re.DOTALL)+
def strip_code_fence(raw: str) -> str:
text = raw.strip()
- if text.startswith("```"):- text = text.strip("`")- text = text.removeprefix("json").strip()- return text+ match = _FENCE_RE.match(text)+ return match.group(1).strip() if match else text
🤖 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 `@backend/app/services/agent/_utils.py` around lines 11 - 15, Update
strip_code_fence to remove complete Markdown code fences without stripping
unrelated trailing backticks, and accept case-insensitive or arbitrary language
tags such as JSON. Use a compiled regex matching the opening fence, optional
language identifier, payload, and closing fence; return the trimmed captured
payload when matched, otherwise preserve the original trimmed text.
🤖 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.
Inline comments:
In `@backend/tests/test_routers_shared.py`:
- Around line 28-32: Update test_enforce_agent_daily_limit_allows_under_limit to
explicitly set AGENT_DAILY_LIMIT to 2 before calling enforce_agent_daily_limit,
using the test’s existing configuration/environment override mechanism so the
single request always remains under the limit.
---
Nitpick comments:
In `@backend/app/services/agent/_utils.py`:
- Around line 11-15: Update strip_code_fence to remove complete Markdown code
fences without stripping unrelated trailing backticks, and accept
case-insensitive or arbitrary language tags such as JSON. Use a compiled regex
matching the opening fence, optional language identifier, payload, and closing
fence; return the trimmed captured payload when matched, otherwise preserve the
original trimmed text.
In `@backend/app/services/agent/resume_draft/draft_service.py`:
- Line 21: Update the imports in draft_service.py (line 21), import_service.py
(line 23), and proposer.py (line 20) to source AgentResponseParseError and
AgentUsage from the canonical ..llm.base module instead of ..chat_service; no
other changes are needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c7e317f-2079-4b6e-87f8-94e785a2c554

📥 Commits

Reviewing files that changed from the base of the PR and between 6896b11 and 60ab364.

📒 Files selected for processing (23)
  • backend/app/repositories/resume.py
  • backend/app/routers/_shared.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/chat_service.py
  • backend/app/services/agent/llm/base.py
  • backend/app/services/agent/llm/retry.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/pdf/generators/intelligence_generator.py
  • backend/tests/test_resume_import_service.py
  • backend/tests/test_routers_shared.py
  • web/src/api/ai-resume.ts
  • web/src/api/paths.ts
  • web/src/hooks/career/useCareerExportActions.test.ts
  • web/src/hooks/useAuthSession.ts
  • web/src/hooks/useMasterData.ts
  • web/src/hooks/useNotifications.test.ts
  • web/src/hooks/useNotifications.ts
💤 Files with no reviewable changes (5)
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • web/src/api/ai-resume.ts
  • backend/app/services/pdf/generators/intelligence_generator.py
  • web/src/api/paths.ts

Comment threadbackend/tests/test_routers_shared.py Outdated
- draft_service.py / import_service.py / proposer.py の AgentResponseParseError /
AgentUsage の import を後方互換用の chat_service 経由から正本の llm.base に変更
- strip_code_fence を正規表現ベースに強化し、大文字小文字混在の言語タグや
無関係な末尾バッククォートの誤削除を防止
- test_enforce_agent_daily_limit_allows_under_limit で AGENT_DAILY_LIMIT を
明示的に設定し、環境依存で失敗しないよう決定論化
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit 6018f8c into mainJul 28, 2026
20 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge Agentbackendバックエンドrefactorリファクタリングtestテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消 - #554

Merged
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28
Jul 28, 2026
Merged

refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消#554
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

/goal によるリファクタリングスキル一括実行タスク。BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを並列実行してレビューし、検出された High 指摘全件と、関連する安全な Medium 項目を修正した。

Backend

  • services/agent/ 配下4モジュール(chat / resume_draft / resume_import / skill_display)に一言一句コピーされていた「LLM呼び出し→1回リトライ→トークン合算」ロジックを services/agent/llm/retry.py_utils.py(コードフェンス剥がし)に抽出(Rule of Three 到達済み)
  • 呼び出し元ゼロ・カバレッジ0%の死コード(intelligence_generator 系 PDF/Markdown、計約275行)を削除
  • routers/agent.pyrouters/github_link/endpoints.py に重複していた日次レート制限429変換ロジックを routers/_shared.py に抽出
  • resume.py の冗長なローカル import を解消
  • resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加(616 tests, 90% coverage)

Frontend

  • useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、失敗パスのテストを追加(CLAUDE.md「例外の握りつぶし禁止」ルール対応)
  • useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
  • useCareerExportActions.ts(認証ゲート・活性制御ロジック)のテストを新規追加(359 tests)

Cross-realm

  • 存在しない backend エンドポイントを参照していた死コード web/src/api/ai-resume.tsPATHS.aiResume を削除

見送った項目(レビュー自身が優先度低・時期尚早と判断したもの。過剰な抽象化を避けるため今回は対応しない)

  • Infra: cloud_run の secret_manager module 分割(Terraform state 影響あり)・CI matrix 化(挙動変更リスクあり)。HCL重複率は既に0%(過去のsymlink統合で解消済み)で緊急度なし
  • Backend Medium: routers/agent.py package化、resume_generator._build_html 分割、github_collector._collect_repo_signals 分割、_SequentialFakeLLM 統合
  • Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three 未達、2箇所のみ)、setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編

各レビューの詳細レポートは report/*.md(gitignore 対象のためリポジトリには含まれない)。

Test plan

  • make ci(lint-backend / typecheck-backend / test-backend / lint-web / test-web / build-web)全て green
  • backend: 616 passed, 90% coverage
  • web: 48 files / 359 tests passed
  • make codegen-types 差分なし確認済み(OpenAPI契約に影響する変更なし)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • AI-powered resume import, drafting, and skill suggestions now retry once when responses are invalid, improving successful completion and usage reporting.
    • Fenced or formatted AI responses are handled more reliably.
  • Bug Fixes

    • Agent-related actions now consistently enforce daily usage limits and return a clear rate-limit error when exceeded.
    • Authentication, master-data, and notification failures now provide warning feedback for improved troubleshooting.
  • Removed

    • Legacy AI resume snapshot and intelligence report generation capabilities were removed.

BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを実行し、
検出された High 指摘と関連する安全な Medium 項目を修正。
## Backend
- services/agent/ 配下4モジュール(chat/resume_draft/resume_import/skill_display)に
重複していた LLM リトライ+トークン集計ロジックを services/agent/llm/retry.py と
_utils.py(コードフェンス剥がし)に抽出
- 呼び出し元ゼロの死コード(intelligence_generator 系、PDF/Markdown 計約275行)を削除
- routers/agent.py と routers/github_link/endpoints.py に重複していた
日次レート制限429変換ロジックを routers/_shared.py に抽出
- resume.py の冗長なローカル import を解消
- resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加
## Frontend
- useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、
失敗パスのテストを追加(CLAUDE.md の例外握りつぶし禁止ルール対応)
- useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
- useCareerExportActions.ts のテストを新規追加(認証ゲート・活性制御の分岐)
## Cross-realm
- 存在しない backend エンドポイントを参照する死コード
web/src/api/ai-resume.ts と PATHS.aiResume を削除
## 見送った項目(レビュー自身が優先度低・時期尚早と判断)
- Infra: cloud_run の secret_manager 分割・CI matrix 化(state影響/挙動変更リスクに対し
実利小、HCL重複率は既に0%)
- Backend Medium: routers/agent.py package化、resume_generator._build_html分割、
github_collector._collect_repo_signals分割、_SequentialFakeLLM統合
- Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three未達)、
setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編
検証: make ci(lint / test-backend 616 passed / test-web 359 passed / build-web)全て green
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent refactor リファクタリング labels Jul 28, 2026
@coderabbitai

coderabbitaiBot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b8594c33-b945-48d4-a9dc-42af9491244d

📥 Commits

Reviewing files that changed from the base of the PR and between 60ab364 and 38efd10.

📒 Files selected for processing (5)
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/tests/test_routers_shared.py
📝 Walkthrough

Walkthrough

The PR centralizes agent LLM retry, parsing, usage accounting, and daily-limit handling; adds backend and frontend tests; removes obsolete intelligence-report and AI-resume API code; and adds frontend warning logs for caught errors.

Changes

Agent LLM orchestration

Layer / File(s)Summary
Shared parsing, usage, and retry contracts
backend/app/services/agent/_utils.py, backend/app/services/agent/llm/*
Shared code-fence parsing, AgentUsage, and single-retry orchestration are introduced.
Chat service integration
backend/app/services/agent/chat_service.py
Chat parsing, exports, retry handling, and usage accounting use the shared helpers.
Agent service migration and validation
backend/app/services/agent/resume_draft/*, backend/app/services/agent/resume_import/*, backend/app/services/agent/skill_display/*, backend/tests/test_resume_import_service.py
Agent services delegate parsing and retry behavior to the common helper, with resume-import retry and usage tests added.

Agent daily-limit routing

Layer / File(s)Summary
Shared daily-limit enforcement
backend/app/routers/_shared.py, backend/tests/test_routers_shared.py
Daily-limit checks, commits, and HTTP 429 conversion are extracted and tested.
Endpoint adoption
backend/app/routers/agent.py, backend/app/routers/github_link/endpoints.py
Agent-related endpoints call the shared enforcement helper.

Resume project sorting

Layer / File(s)Summary
Project period date parsing
backend/app/repositories/resume.py
Project sorting uses the module-level date type without changing parsing behavior.

Intelligence report removal

Layer / File(s)Summary
Remove intelligence report generators
backend/app/services/markdown/generators/..., backend/app/services/markdown/templates/..., backend/app/services/pdf/generators/...
Intelligence Markdown/PDF generators and template constants are removed.

Web API and error observability

Layer / File(s)Summary
Career export behavior coverage
web/src/hooks/career/useCareerExportActions.test.ts
Career export authentication, resume availability, actions, and disabled states are tested.
Frontend warning logging
web/src/hooks/useAuthSession.ts, web/src/hooks/useMasterData.ts, web/src/hooks/useNotifications.*
Caught frontend errors now emit warnings while existing fallback behavior remains.
Remove obsolete AI-resume routes
web/src/api/ai-resume.ts, web/src/api/paths.ts
The AI-resume API wrapper and route definitions are removed.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
participant AgentService
participant RetryHelper
participant LLM
participant Parser
AgentService->>RetryHelper: Submit generation request
RetryHelper->>LLM: Generate response
LLM-->>RetryHelper: Response and usage
RetryHelper->>Parser: Parse response
Parser-->>RetryHelper: Parsed output or error
RetryHelper->>LLM: Retry with feedback
LLM-->>RetryHelper: Retry response and usage
RetryHelper-->>AgentService: Output and aggregated usage
Loading

Possibly related PRs

Suggested labels:backend, web, test, agent, documentation

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 74.36% 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedPRの主目的であるBE/WEB/XRのリファクタリングレビューHigh指摘解消を端的に表しており、変更内容と整合しています。
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/all-skills-2026-07-28

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
backend/app/services/agent/resume_draft/draft_service.py (1)

21-21: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Shared types imported through ..chat_service instead of the canonical ..llm.base.llm/base.py is now documented as the source of truth for AgentResponseParseError / AgentUsage; the re-export in chat_service exists only for backward compatibility, so newly-migrated services needlessly depend on the chat module (including its import-time prompt file read).

  • backend/app/services/agent/resume_draft/draft_service.py#L21-L21: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/resume_import/import_service.py#L23-L23: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/skill_display/proposer.py#L20-L20: change to from ..llm.base import AgentResponseParseError, AgentUsage.
🤖 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 `@backend/app/services/agent/resume_draft/draft_service.py` at line 21, Update
the imports in draft_service.py (line 21), import_service.py (line 23), and
proposer.py (line 20) to source AgentResponseParseError and AgentUsage from the
canonical ..llm.base module instead of ..chat_service; no other changes are
needed.
backend/app/services/agent/_utils.py (1)

11-15: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Fence stripping only handles a lowercase json tag.

text.strip("")also removes any trailing backticks anywhere at the ends, andremoveprefix("json")missesJSON` / other language tags, leaving the tag in the payload and forcing an unnecessary retry. A regex-based fence strip would be more robust; behavior today still degrades safely via the parse-error retry path, so this is optional.

♻️ Optional: regex-based fence strip
+import re++_FENCE_RE = re.compile(r"^```[A-Za-z0-9_+-]*\s*\n?(.*?)\n?```$", re.DOTALL)+
def strip_code_fence(raw: str) -> str:
text = raw.strip()
- if text.startswith("```"):- text = text.strip("`")- text = text.removeprefix("json").strip()- return text+ match = _FENCE_RE.match(text)+ return match.group(1).strip() if match else text
🤖 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 `@backend/app/services/agent/_utils.py` around lines 11 - 15, Update
strip_code_fence to remove complete Markdown code fences without stripping
unrelated trailing backticks, and accept case-insensitive or arbitrary language
tags such as JSON. Use a compiled regex matching the opening fence, optional
language identifier, payload, and closing fence; return the trimmed captured
payload when matched, otherwise preserve the original trimmed text.
🤖 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.
Inline comments:
In `@backend/tests/test_routers_shared.py`:
- Around line 28-32: Update test_enforce_agent_daily_limit_allows_under_limit to
explicitly set AGENT_DAILY_LIMIT to 2 before calling enforce_agent_daily_limit,
using the test’s existing configuration/environment override mechanism so the
single request always remains under the limit.
---
Nitpick comments:
In `@backend/app/services/agent/_utils.py`:
- Around line 11-15: Update strip_code_fence to remove complete Markdown code
fences without stripping unrelated trailing backticks, and accept
case-insensitive or arbitrary language tags such as JSON. Use a compiled regex
matching the opening fence, optional language identifier, payload, and closing
fence; return the trimmed captured payload when matched, otherwise preserve the
original trimmed text.
In `@backend/app/services/agent/resume_draft/draft_service.py`:
- Line 21: Update the imports in draft_service.py (line 21), import_service.py
(line 23), and proposer.py (line 20) to source AgentResponseParseError and
AgentUsage from the canonical ..llm.base module instead of ..chat_service; no
other changes are needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c7e317f-2079-4b6e-87f8-94e785a2c554

📥 Commits

Reviewing files that changed from the base of the PR and between 6896b11 and 60ab364.

📒 Files selected for processing (23)
  • backend/app/repositories/resume.py
  • backend/app/routers/_shared.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/chat_service.py
  • backend/app/services/agent/llm/base.py
  • backend/app/services/agent/llm/retry.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/pdf/generators/intelligence_generator.py
  • backend/tests/test_resume_import_service.py
  • backend/tests/test_routers_shared.py
  • web/src/api/ai-resume.ts
  • web/src/api/paths.ts
  • web/src/hooks/career/useCareerExportActions.test.ts
  • web/src/hooks/useAuthSession.ts
  • web/src/hooks/useMasterData.ts
  • web/src/hooks/useNotifications.test.ts
  • web/src/hooks/useNotifications.ts
💤 Files with no reviewable changes (5)
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • web/src/api/ai-resume.ts
  • backend/app/services/pdf/generators/intelligence_generator.py
  • web/src/api/paths.ts

Comment threadbackend/tests/test_routers_shared.py Outdated
- draft_service.py / import_service.py / proposer.py の AgentResponseParseError /
AgentUsage の import を後方互換用の chat_service 経由から正本の llm.base に変更
- strip_code_fence を正規表現ベースに強化し、大文字小文字混在の言語タグや
無関係な末尾バッククォートの誤削除を防止
- test_enforce_agent_daily_limit_allows_under_limit で AGENT_DAILY_LIMIT を
明示的に設定し、環境依存で失敗しないよう決定論化
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit 6018f8c into mainJul 28, 2026
20 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge Agentbackendバックエンドrefactorリファクタリングtestテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消 - #554

Merged
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28
Jul 28, 2026
Merged

refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消#554
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

/goal によるリファクタリングスキル一括実行タスク。BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを並列実行してレビューし、検出された High 指摘全件と、関連する安全な Medium 項目を修正した。

Backend

  • services/agent/ 配下4モジュール(chat / resume_draft / resume_import / skill_display)に一言一句コピーされていた「LLM呼び出し→1回リトライ→トークン合算」ロジックを services/agent/llm/retry.py_utils.py(コードフェンス剥がし)に抽出(Rule of Three 到達済み)
  • 呼び出し元ゼロ・カバレッジ0%の死コード(intelligence_generator 系 PDF/Markdown、計約275行)を削除
  • routers/agent.pyrouters/github_link/endpoints.py に重複していた日次レート制限429変換ロジックを routers/_shared.py に抽出
  • resume.py の冗長なローカル import を解消
  • resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加(616 tests, 90% coverage)

Frontend

  • useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、失敗パスのテストを追加(CLAUDE.md「例外の握りつぶし禁止」ルール対応)
  • useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
  • useCareerExportActions.ts(認証ゲート・活性制御ロジック)のテストを新規追加(359 tests)

Cross-realm

  • 存在しない backend エンドポイントを参照していた死コード web/src/api/ai-resume.tsPATHS.aiResume を削除

見送った項目(レビュー自身が優先度低・時期尚早と判断したもの。過剰な抽象化を避けるため今回は対応しない)

  • Infra: cloud_run の secret_manager module 分割(Terraform state 影響あり)・CI matrix 化(挙動変更リスクあり)。HCL重複率は既に0%(過去のsymlink統合で解消済み)で緊急度なし
  • Backend Medium: routers/agent.py package化、resume_generator._build_html 分割、github_collector._collect_repo_signals 分割、_SequentialFakeLLM 統合
  • Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three 未達、2箇所のみ)、setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編

各レビューの詳細レポートは report/*.md(gitignore 対象のためリポジトリには含まれない)。

Test plan

  • make ci(lint-backend / typecheck-backend / test-backend / lint-web / test-web / build-web)全て green
  • backend: 616 passed, 90% coverage
  • web: 48 files / 359 tests passed
  • make codegen-types 差分なし確認済み(OpenAPI契約に影響する変更なし)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • AI-powered resume import, drafting, and skill suggestions now retry once when responses are invalid, improving successful completion and usage reporting.
    • Fenced or formatted AI responses are handled more reliably.
  • Bug Fixes

    • Agent-related actions now consistently enforce daily usage limits and return a clear rate-limit error when exceeded.
    • Authentication, master-data, and notification failures now provide warning feedback for improved troubleshooting.
  • Removed

    • Legacy AI resume snapshot and intelligence report generation capabilities were removed.

BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを実行し、
検出された High 指摘と関連する安全な Medium 項目を修正。
## Backend
- services/agent/ 配下4モジュール(chat/resume_draft/resume_import/skill_display)に
重複していた LLM リトライ+トークン集計ロジックを services/agent/llm/retry.py と
_utils.py(コードフェンス剥がし)に抽出
- 呼び出し元ゼロの死コード(intelligence_generator 系、PDF/Markdown 計約275行)を削除
- routers/agent.py と routers/github_link/endpoints.py に重複していた
日次レート制限429変換ロジックを routers/_shared.py に抽出
- resume.py の冗長なローカル import を解消
- resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加
## Frontend
- useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、
失敗パスのテストを追加(CLAUDE.md の例外握りつぶし禁止ルール対応)
- useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
- useCareerExportActions.ts のテストを新規追加(認証ゲート・活性制御の分岐)
## Cross-realm
- 存在しない backend エンドポイントを参照する死コード
web/src/api/ai-resume.ts と PATHS.aiResume を削除
## 見送った項目(レビュー自身が優先度低・時期尚早と判断)
- Infra: cloud_run の secret_manager 分割・CI matrix 化(state影響/挙動変更リスクに対し
実利小、HCL重複率は既に0%)
- Backend Medium: routers/agent.py package化、resume_generator._build_html分割、
github_collector._collect_repo_signals分割、_SequentialFakeLLM統合
- Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three未達)、
setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編
検証: make ci(lint / test-backend 616 passed / test-web 359 passed / build-web)全て green
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent refactor リファクタリング labels Jul 28, 2026
@coderabbitai

coderabbitaiBot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b8594c33-b945-48d4-a9dc-42af9491244d

📥 Commits

Reviewing files that changed from the base of the PR and between 60ab364 and 38efd10.

📒 Files selected for processing (5)
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/tests/test_routers_shared.py
📝 Walkthrough

Walkthrough

The PR centralizes agent LLM retry, parsing, usage accounting, and daily-limit handling; adds backend and frontend tests; removes obsolete intelligence-report and AI-resume API code; and adds frontend warning logs for caught errors.

Changes

Agent LLM orchestration

Layer / File(s)Summary
Shared parsing, usage, and retry contracts
backend/app/services/agent/_utils.py, backend/app/services/agent/llm/*
Shared code-fence parsing, AgentUsage, and single-retry orchestration are introduced.
Chat service integration
backend/app/services/agent/chat_service.py
Chat parsing, exports, retry handling, and usage accounting use the shared helpers.
Agent service migration and validation
backend/app/services/agent/resume_draft/*, backend/app/services/agent/resume_import/*, backend/app/services/agent/skill_display/*, backend/tests/test_resume_import_service.py
Agent services delegate parsing and retry behavior to the common helper, with resume-import retry and usage tests added.

Agent daily-limit routing

Layer / File(s)Summary
Shared daily-limit enforcement
backend/app/routers/_shared.py, backend/tests/test_routers_shared.py
Daily-limit checks, commits, and HTTP 429 conversion are extracted and tested.
Endpoint adoption
backend/app/routers/agent.py, backend/app/routers/github_link/endpoints.py
Agent-related endpoints call the shared enforcement helper.

Resume project sorting

Layer / File(s)Summary
Project period date parsing
backend/app/repositories/resume.py
Project sorting uses the module-level date type without changing parsing behavior.

Intelligence report removal

Layer / File(s)Summary
Remove intelligence report generators
backend/app/services/markdown/generators/..., backend/app/services/markdown/templates/..., backend/app/services/pdf/generators/...
Intelligence Markdown/PDF generators and template constants are removed.

Web API and error observability

Layer / File(s)Summary
Career export behavior coverage
web/src/hooks/career/useCareerExportActions.test.ts
Career export authentication, resume availability, actions, and disabled states are tested.
Frontend warning logging
web/src/hooks/useAuthSession.ts, web/src/hooks/useMasterData.ts, web/src/hooks/useNotifications.*
Caught frontend errors now emit warnings while existing fallback behavior remains.
Remove obsolete AI-resume routes
web/src/api/ai-resume.ts, web/src/api/paths.ts
The AI-resume API wrapper and route definitions are removed.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
participant AgentService
participant RetryHelper
participant LLM
participant Parser
AgentService->>RetryHelper: Submit generation request
RetryHelper->>LLM: Generate response
LLM-->>RetryHelper: Response and usage
RetryHelper->>Parser: Parse response
Parser-->>RetryHelper: Parsed output or error
RetryHelper->>LLM: Retry with feedback
LLM-->>RetryHelper: Retry response and usage
RetryHelper-->>AgentService: Output and aggregated usage
Loading

Possibly related PRs

Suggested labels:backend, web, test, agent, documentation

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 74.36% 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedPRの主目的であるBE/WEB/XRのリファクタリングレビューHigh指摘解消を端的に表しており、変更内容と整合しています。
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/all-skills-2026-07-28

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
backend/app/services/agent/resume_draft/draft_service.py (1)

21-21: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Shared types imported through ..chat_service instead of the canonical ..llm.base.llm/base.py is now documented as the source of truth for AgentResponseParseError / AgentUsage; the re-export in chat_service exists only for backward compatibility, so newly-migrated services needlessly depend on the chat module (including its import-time prompt file read).

  • backend/app/services/agent/resume_draft/draft_service.py#L21-L21: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/resume_import/import_service.py#L23-L23: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/skill_display/proposer.py#L20-L20: change to from ..llm.base import AgentResponseParseError, AgentUsage.
🤖 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 `@backend/app/services/agent/resume_draft/draft_service.py` at line 21, Update
the imports in draft_service.py (line 21), import_service.py (line 23), and
proposer.py (line 20) to source AgentResponseParseError and AgentUsage from the
canonical ..llm.base module instead of ..chat_service; no other changes are
needed.
backend/app/services/agent/_utils.py (1)

11-15: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Fence stripping only handles a lowercase json tag.

text.strip("")also removes any trailing backticks anywhere at the ends, andremoveprefix("json")missesJSON` / other language tags, leaving the tag in the payload and forcing an unnecessary retry. A regex-based fence strip would be more robust; behavior today still degrades safely via the parse-error retry path, so this is optional.

♻️ Optional: regex-based fence strip
+import re++_FENCE_RE = re.compile(r"^```[A-Za-z0-9_+-]*\s*\n?(.*?)\n?```$", re.DOTALL)+
def strip_code_fence(raw: str) -> str:
text = raw.strip()
- if text.startswith("```"):- text = text.strip("`")- text = text.removeprefix("json").strip()- return text+ match = _FENCE_RE.match(text)+ return match.group(1).strip() if match else text
🤖 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 `@backend/app/services/agent/_utils.py` around lines 11 - 15, Update
strip_code_fence to remove complete Markdown code fences without stripping
unrelated trailing backticks, and accept case-insensitive or arbitrary language
tags such as JSON. Use a compiled regex matching the opening fence, optional
language identifier, payload, and closing fence; return the trimmed captured
payload when matched, otherwise preserve the original trimmed text.
🤖 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.
Inline comments:
In `@backend/tests/test_routers_shared.py`:
- Around line 28-32: Update test_enforce_agent_daily_limit_allows_under_limit to
explicitly set AGENT_DAILY_LIMIT to 2 before calling enforce_agent_daily_limit,
using the test’s existing configuration/environment override mechanism so the
single request always remains under the limit.
---
Nitpick comments:
In `@backend/app/services/agent/_utils.py`:
- Around line 11-15: Update strip_code_fence to remove complete Markdown code
fences without stripping unrelated trailing backticks, and accept
case-insensitive or arbitrary language tags such as JSON. Use a compiled regex
matching the opening fence, optional language identifier, payload, and closing
fence; return the trimmed captured payload when matched, otherwise preserve the
original trimmed text.
In `@backend/app/services/agent/resume_draft/draft_service.py`:
- Line 21: Update the imports in draft_service.py (line 21), import_service.py
(line 23), and proposer.py (line 20) to source AgentResponseParseError and
AgentUsage from the canonical ..llm.base module instead of ..chat_service; no
other changes are needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c7e317f-2079-4b6e-87f8-94e785a2c554

📥 Commits

Reviewing files that changed from the base of the PR and between 6896b11 and 60ab364.

📒 Files selected for processing (23)
  • backend/app/repositories/resume.py
  • backend/app/routers/_shared.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/chat_service.py
  • backend/app/services/agent/llm/base.py
  • backend/app/services/agent/llm/retry.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/pdf/generators/intelligence_generator.py
  • backend/tests/test_resume_import_service.py
  • backend/tests/test_routers_shared.py
  • web/src/api/ai-resume.ts
  • web/src/api/paths.ts
  • web/src/hooks/career/useCareerExportActions.test.ts
  • web/src/hooks/useAuthSession.ts
  • web/src/hooks/useMasterData.ts
  • web/src/hooks/useNotifications.test.ts
  • web/src/hooks/useNotifications.ts
💤 Files with no reviewable changes (5)
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • web/src/api/ai-resume.ts
  • backend/app/services/pdf/generators/intelligence_generator.py
  • web/src/api/paths.ts

Comment threadbackend/tests/test_routers_shared.py Outdated
- draft_service.py / import_service.py / proposer.py の AgentResponseParseError /
AgentUsage の import を後方互換用の chat_service 経由から正本の llm.base に変更
- strip_code_fence を正規表現ベースに強化し、大文字小文字混在の言語タグや
無関係な末尾バッククォートの誤削除を防止
- test_enforce_agent_daily_limit_allows_under_limit で AGENT_DAILY_LIMIT を
明示的に設定し、環境依存で失敗しないよう決定論化
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit 6018f8c into mainJul 28, 2026
20 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge Agentbackendバックエンドrefactorリファクタリングtestテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消 - #554

Merged
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28
Jul 28, 2026
Merged

refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消#554
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

/goal によるリファクタリングスキル一括実行タスク。BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを並列実行してレビューし、検出された High 指摘全件と、関連する安全な Medium 項目を修正した。

Backend

  • services/agent/ 配下4モジュール(chat / resume_draft / resume_import / skill_display)に一言一句コピーされていた「LLM呼び出し→1回リトライ→トークン合算」ロジックを services/agent/llm/retry.py_utils.py(コードフェンス剥がし)に抽出(Rule of Three 到達済み)
  • 呼び出し元ゼロ・カバレッジ0%の死コード(intelligence_generator 系 PDF/Markdown、計約275行)を削除
  • routers/agent.pyrouters/github_link/endpoints.py に重複していた日次レート制限429変換ロジックを routers/_shared.py に抽出
  • resume.py の冗長なローカル import を解消
  • resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加(616 tests, 90% coverage)

Frontend

  • useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、失敗パスのテストを追加(CLAUDE.md「例外の握りつぶし禁止」ルール対応)
  • useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
  • useCareerExportActions.ts(認証ゲート・活性制御ロジック)のテストを新規追加(359 tests)

Cross-realm

  • 存在しない backend エンドポイントを参照していた死コード web/src/api/ai-resume.tsPATHS.aiResume を削除

見送った項目(レビュー自身が優先度低・時期尚早と判断したもの。過剰な抽象化を避けるため今回は対応しない)

  • Infra: cloud_run の secret_manager module 分割(Terraform state 影響あり)・CI matrix 化(挙動変更リスクあり)。HCL重複率は既に0%(過去のsymlink統合で解消済み)で緊急度なし
  • Backend Medium: routers/agent.py package化、resume_generator._build_html 分割、github_collector._collect_repo_signals 分割、_SequentialFakeLLM 統合
  • Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three 未達、2箇所のみ)、setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編

各レビューの詳細レポートは report/*.md(gitignore 対象のためリポジトリには含まれない)。

Test plan

  • make ci(lint-backend / typecheck-backend / test-backend / lint-web / test-web / build-web)全て green
  • backend: 616 passed, 90% coverage
  • web: 48 files / 359 tests passed
  • make codegen-types 差分なし確認済み(OpenAPI契約に影響する変更なし)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • AI-powered resume import, drafting, and skill suggestions now retry once when responses are invalid, improving successful completion and usage reporting.
    • Fenced or formatted AI responses are handled more reliably.
  • Bug Fixes

    • Agent-related actions now consistently enforce daily usage limits and return a clear rate-limit error when exceeded.
    • Authentication, master-data, and notification failures now provide warning feedback for improved troubleshooting.
  • Removed

    • Legacy AI resume snapshot and intelligence report generation capabilities were removed.

BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを実行し、
検出された High 指摘と関連する安全な Medium 項目を修正。
## Backend
- services/agent/ 配下4モジュール(chat/resume_draft/resume_import/skill_display)に
重複していた LLM リトライ+トークン集計ロジックを services/agent/llm/retry.py と
_utils.py(コードフェンス剥がし)に抽出
- 呼び出し元ゼロの死コード(intelligence_generator 系、PDF/Markdown 計約275行)を削除
- routers/agent.py と routers/github_link/endpoints.py に重複していた
日次レート制限429変換ロジックを routers/_shared.py に抽出
- resume.py の冗長なローカル import を解消
- resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加
## Frontend
- useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、
失敗パスのテストを追加(CLAUDE.md の例外握りつぶし禁止ルール対応)
- useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
- useCareerExportActions.ts のテストを新規追加(認証ゲート・活性制御の分岐)
## Cross-realm
- 存在しない backend エンドポイントを参照する死コード
web/src/api/ai-resume.ts と PATHS.aiResume を削除
## 見送った項目(レビュー自身が優先度低・時期尚早と判断)
- Infra: cloud_run の secret_manager 分割・CI matrix 化(state影響/挙動変更リスクに対し
実利小、HCL重複率は既に0%)
- Backend Medium: routers/agent.py package化、resume_generator._build_html分割、
github_collector._collect_repo_signals分割、_SequentialFakeLLM統合
- Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three未達)、
setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編
検証: make ci(lint / test-backend 616 passed / test-web 359 passed / build-web)全て green
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent refactor リファクタリング labels Jul 28, 2026
@coderabbitai

coderabbitaiBot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b8594c33-b945-48d4-a9dc-42af9491244d

📥 Commits

Reviewing files that changed from the base of the PR and between 60ab364 and 38efd10.

📒 Files selected for processing (5)
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/tests/test_routers_shared.py
📝 Walkthrough

Walkthrough

The PR centralizes agent LLM retry, parsing, usage accounting, and daily-limit handling; adds backend and frontend tests; removes obsolete intelligence-report and AI-resume API code; and adds frontend warning logs for caught errors.

Changes

Agent LLM orchestration

Layer / File(s)Summary
Shared parsing, usage, and retry contracts
backend/app/services/agent/_utils.py, backend/app/services/agent/llm/*
Shared code-fence parsing, AgentUsage, and single-retry orchestration are introduced.
Chat service integration
backend/app/services/agent/chat_service.py
Chat parsing, exports, retry handling, and usage accounting use the shared helpers.
Agent service migration and validation
backend/app/services/agent/resume_draft/*, backend/app/services/agent/resume_import/*, backend/app/services/agent/skill_display/*, backend/tests/test_resume_import_service.py
Agent services delegate parsing and retry behavior to the common helper, with resume-import retry and usage tests added.

Agent daily-limit routing

Layer / File(s)Summary
Shared daily-limit enforcement
backend/app/routers/_shared.py, backend/tests/test_routers_shared.py
Daily-limit checks, commits, and HTTP 429 conversion are extracted and tested.
Endpoint adoption
backend/app/routers/agent.py, backend/app/routers/github_link/endpoints.py
Agent-related endpoints call the shared enforcement helper.

Resume project sorting

Layer / File(s)Summary
Project period date parsing
backend/app/repositories/resume.py
Project sorting uses the module-level date type without changing parsing behavior.

Intelligence report removal

Layer / File(s)Summary
Remove intelligence report generators
backend/app/services/markdown/generators/..., backend/app/services/markdown/templates/..., backend/app/services/pdf/generators/...
Intelligence Markdown/PDF generators and template constants are removed.

Web API and error observability

Layer / File(s)Summary
Career export behavior coverage
web/src/hooks/career/useCareerExportActions.test.ts
Career export authentication, resume availability, actions, and disabled states are tested.
Frontend warning logging
web/src/hooks/useAuthSession.ts, web/src/hooks/useMasterData.ts, web/src/hooks/useNotifications.*
Caught frontend errors now emit warnings while existing fallback behavior remains.
Remove obsolete AI-resume routes
web/src/api/ai-resume.ts, web/src/api/paths.ts
The AI-resume API wrapper and route definitions are removed.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
participant AgentService
participant RetryHelper
participant LLM
participant Parser
AgentService->>RetryHelper: Submit generation request
RetryHelper->>LLM: Generate response
LLM-->>RetryHelper: Response and usage
RetryHelper->>Parser: Parse response
Parser-->>RetryHelper: Parsed output or error
RetryHelper->>LLM: Retry with feedback
LLM-->>RetryHelper: Retry response and usage
RetryHelper-->>AgentService: Output and aggregated usage
Loading

Possibly related PRs

Suggested labels:backend, web, test, agent, documentation

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 74.36% 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedPRの主目的であるBE/WEB/XRのリファクタリングレビューHigh指摘解消を端的に表しており、変更内容と整合しています。
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/all-skills-2026-07-28

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
backend/app/services/agent/resume_draft/draft_service.py (1)

21-21: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Shared types imported through ..chat_service instead of the canonical ..llm.base.llm/base.py is now documented as the source of truth for AgentResponseParseError / AgentUsage; the re-export in chat_service exists only for backward compatibility, so newly-migrated services needlessly depend on the chat module (including its import-time prompt file read).

  • backend/app/services/agent/resume_draft/draft_service.py#L21-L21: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/resume_import/import_service.py#L23-L23: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/skill_display/proposer.py#L20-L20: change to from ..llm.base import AgentResponseParseError, AgentUsage.
🤖 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 `@backend/app/services/agent/resume_draft/draft_service.py` at line 21, Update
the imports in draft_service.py (line 21), import_service.py (line 23), and
proposer.py (line 20) to source AgentResponseParseError and AgentUsage from the
canonical ..llm.base module instead of ..chat_service; no other changes are
needed.
backend/app/services/agent/_utils.py (1)

11-15: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Fence stripping only handles a lowercase json tag.

text.strip("")also removes any trailing backticks anywhere at the ends, andremoveprefix("json")missesJSON` / other language tags, leaving the tag in the payload and forcing an unnecessary retry. A regex-based fence strip would be more robust; behavior today still degrades safely via the parse-error retry path, so this is optional.

♻️ Optional: regex-based fence strip
+import re++_FENCE_RE = re.compile(r"^```[A-Za-z0-9_+-]*\s*\n?(.*?)\n?```$", re.DOTALL)+
def strip_code_fence(raw: str) -> str:
text = raw.strip()
- if text.startswith("```"):- text = text.strip("`")- text = text.removeprefix("json").strip()- return text+ match = _FENCE_RE.match(text)+ return match.group(1).strip() if match else text
🤖 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 `@backend/app/services/agent/_utils.py` around lines 11 - 15, Update
strip_code_fence to remove complete Markdown code fences without stripping
unrelated trailing backticks, and accept case-insensitive or arbitrary language
tags such as JSON. Use a compiled regex matching the opening fence, optional
language identifier, payload, and closing fence; return the trimmed captured
payload when matched, otherwise preserve the original trimmed text.
🤖 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.
Inline comments:
In `@backend/tests/test_routers_shared.py`:
- Around line 28-32: Update test_enforce_agent_daily_limit_allows_under_limit to
explicitly set AGENT_DAILY_LIMIT to 2 before calling enforce_agent_daily_limit,
using the test’s existing configuration/environment override mechanism so the
single request always remains under the limit.
---
Nitpick comments:
In `@backend/app/services/agent/_utils.py`:
- Around line 11-15: Update strip_code_fence to remove complete Markdown code
fences without stripping unrelated trailing backticks, and accept
case-insensitive or arbitrary language tags such as JSON. Use a compiled regex
matching the opening fence, optional language identifier, payload, and closing
fence; return the trimmed captured payload when matched, otherwise preserve the
original trimmed text.
In `@backend/app/services/agent/resume_draft/draft_service.py`:
- Line 21: Update the imports in draft_service.py (line 21), import_service.py
(line 23), and proposer.py (line 20) to source AgentResponseParseError and
AgentUsage from the canonical ..llm.base module instead of ..chat_service; no
other changes are needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c7e317f-2079-4b6e-87f8-94e785a2c554

📥 Commits

Reviewing files that changed from the base of the PR and between 6896b11 and 60ab364.

📒 Files selected for processing (23)
  • backend/app/repositories/resume.py
  • backend/app/routers/_shared.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/chat_service.py
  • backend/app/services/agent/llm/base.py
  • backend/app/services/agent/llm/retry.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/pdf/generators/intelligence_generator.py
  • backend/tests/test_resume_import_service.py
  • backend/tests/test_routers_shared.py
  • web/src/api/ai-resume.ts
  • web/src/api/paths.ts
  • web/src/hooks/career/useCareerExportActions.test.ts
  • web/src/hooks/useAuthSession.ts
  • web/src/hooks/useMasterData.ts
  • web/src/hooks/useNotifications.test.ts
  • web/src/hooks/useNotifications.ts
💤 Files with no reviewable changes (5)
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • web/src/api/ai-resume.ts
  • backend/app/services/pdf/generators/intelligence_generator.py
  • web/src/api/paths.ts

Comment threadbackend/tests/test_routers_shared.py Outdated
- draft_service.py / import_service.py / proposer.py の AgentResponseParseError /
AgentUsage の import を後方互換用の chat_service 経由から正本の llm.base に変更
- strip_code_fence を正規表現ベースに強化し、大文字小文字混在の言語タグや
無関係な末尾バッククォートの誤削除を防止
- test_enforce_agent_daily_limit_allows_under_limit で AGENT_DAILY_LIMIT を
明示的に設定し、環境依存で失敗しないよう決定論化
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit 6018f8c into mainJul 28, 2026
20 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge Agentbackendバックエンドrefactorリファクタリングtestテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消 - #554

Merged
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28
Jul 28, 2026
Merged

refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消#554
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

/goal によるリファクタリングスキル一括実行タスク。BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを並列実行してレビューし、検出された High 指摘全件と、関連する安全な Medium 項目を修正した。

Backend

  • services/agent/ 配下4モジュール(chat / resume_draft / resume_import / skill_display)に一言一句コピーされていた「LLM呼び出し→1回リトライ→トークン合算」ロジックを services/agent/llm/retry.py_utils.py(コードフェンス剥がし)に抽出(Rule of Three 到達済み)
  • 呼び出し元ゼロ・カバレッジ0%の死コード(intelligence_generator 系 PDF/Markdown、計約275行)を削除
  • routers/agent.pyrouters/github_link/endpoints.py に重複していた日次レート制限429変換ロジックを routers/_shared.py に抽出
  • resume.py の冗長なローカル import を解消
  • resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加(616 tests, 90% coverage)

Frontend

  • useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、失敗パスのテストを追加(CLAUDE.md「例外の握りつぶし禁止」ルール対応)
  • useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
  • useCareerExportActions.ts(認証ゲート・活性制御ロジック)のテストを新規追加(359 tests)

Cross-realm

  • 存在しない backend エンドポイントを参照していた死コード web/src/api/ai-resume.tsPATHS.aiResume を削除

見送った項目(レビュー自身が優先度低・時期尚早と判断したもの。過剰な抽象化を避けるため今回は対応しない)

  • Infra: cloud_run の secret_manager module 分割(Terraform state 影響あり)・CI matrix 化(挙動変更リスクあり)。HCL重複率は既に0%(過去のsymlink統合で解消済み)で緊急度なし
  • Backend Medium: routers/agent.py package化、resume_generator._build_html 分割、github_collector._collect_repo_signals 分割、_SequentialFakeLLM 統合
  • Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three 未達、2箇所のみ)、setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編

各レビューの詳細レポートは report/*.md(gitignore 対象のためリポジトリには含まれない)。

Test plan

  • make ci(lint-backend / typecheck-backend / test-backend / lint-web / test-web / build-web)全て green
  • backend: 616 passed, 90% coverage
  • web: 48 files / 359 tests passed
  • make codegen-types 差分なし確認済み(OpenAPI契約に影響する変更なし)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • AI-powered resume import, drafting, and skill suggestions now retry once when responses are invalid, improving successful completion and usage reporting.
    • Fenced or formatted AI responses are handled more reliably.
  • Bug Fixes

    • Agent-related actions now consistently enforce daily usage limits and return a clear rate-limit error when exceeded.
    • Authentication, master-data, and notification failures now provide warning feedback for improved troubleshooting.
  • Removed

    • Legacy AI resume snapshot and intelligence report generation capabilities were removed.

BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを実行し、
検出された High 指摘と関連する安全な Medium 項目を修正。
## Backend
- services/agent/ 配下4モジュール(chat/resume_draft/resume_import/skill_display)に
重複していた LLM リトライ+トークン集計ロジックを services/agent/llm/retry.py と
_utils.py(コードフェンス剥がし)に抽出
- 呼び出し元ゼロの死コード(intelligence_generator 系、PDF/Markdown 計約275行)を削除
- routers/agent.py と routers/github_link/endpoints.py に重複していた
日次レート制限429変換ロジックを routers/_shared.py に抽出
- resume.py の冗長なローカル import を解消
- resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加
## Frontend
- useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、
失敗パスのテストを追加(CLAUDE.md の例外握りつぶし禁止ルール対応)
- useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
- useCareerExportActions.ts のテストを新規追加(認証ゲート・活性制御の分岐)
## Cross-realm
- 存在しない backend エンドポイントを参照する死コード
web/src/api/ai-resume.ts と PATHS.aiResume を削除
## 見送った項目(レビュー自身が優先度低・時期尚早と判断)
- Infra: cloud_run の secret_manager 分割・CI matrix 化(state影響/挙動変更リスクに対し
実利小、HCL重複率は既に0%)
- Backend Medium: routers/agent.py package化、resume_generator._build_html分割、
github_collector._collect_repo_signals分割、_SequentialFakeLLM統合
- Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three未達)、
setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編
検証: make ci(lint / test-backend 616 passed / test-web 359 passed / build-web)全て green
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent refactor リファクタリング labels Jul 28, 2026
@coderabbitai

coderabbitaiBot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b8594c33-b945-48d4-a9dc-42af9491244d

📥 Commits

Reviewing files that changed from the base of the PR and between 60ab364 and 38efd10.

📒 Files selected for processing (5)
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/tests/test_routers_shared.py
📝 Walkthrough

Walkthrough

The PR centralizes agent LLM retry, parsing, usage accounting, and daily-limit handling; adds backend and frontend tests; removes obsolete intelligence-report and AI-resume API code; and adds frontend warning logs for caught errors.

Changes

Agent LLM orchestration

Layer / File(s)Summary
Shared parsing, usage, and retry contracts
backend/app/services/agent/_utils.py, backend/app/services/agent/llm/*
Shared code-fence parsing, AgentUsage, and single-retry orchestration are introduced.
Chat service integration
backend/app/services/agent/chat_service.py
Chat parsing, exports, retry handling, and usage accounting use the shared helpers.
Agent service migration and validation
backend/app/services/agent/resume_draft/*, backend/app/services/agent/resume_import/*, backend/app/services/agent/skill_display/*, backend/tests/test_resume_import_service.py
Agent services delegate parsing and retry behavior to the common helper, with resume-import retry and usage tests added.

Agent daily-limit routing

Layer / File(s)Summary
Shared daily-limit enforcement
backend/app/routers/_shared.py, backend/tests/test_routers_shared.py
Daily-limit checks, commits, and HTTP 429 conversion are extracted and tested.
Endpoint adoption
backend/app/routers/agent.py, backend/app/routers/github_link/endpoints.py
Agent-related endpoints call the shared enforcement helper.

Resume project sorting

Layer / File(s)Summary
Project period date parsing
backend/app/repositories/resume.py
Project sorting uses the module-level date type without changing parsing behavior.

Intelligence report removal

Layer / File(s)Summary
Remove intelligence report generators
backend/app/services/markdown/generators/..., backend/app/services/markdown/templates/..., backend/app/services/pdf/generators/...
Intelligence Markdown/PDF generators and template constants are removed.

Web API and error observability

Layer / File(s)Summary
Career export behavior coverage
web/src/hooks/career/useCareerExportActions.test.ts
Career export authentication, resume availability, actions, and disabled states are tested.
Frontend warning logging
web/src/hooks/useAuthSession.ts, web/src/hooks/useMasterData.ts, web/src/hooks/useNotifications.*
Caught frontend errors now emit warnings while existing fallback behavior remains.
Remove obsolete AI-resume routes
web/src/api/ai-resume.ts, web/src/api/paths.ts
The AI-resume API wrapper and route definitions are removed.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
participant AgentService
participant RetryHelper
participant LLM
participant Parser
AgentService->>RetryHelper: Submit generation request
RetryHelper->>LLM: Generate response
LLM-->>RetryHelper: Response and usage
RetryHelper->>Parser: Parse response
Parser-->>RetryHelper: Parsed output or error
RetryHelper->>LLM: Retry with feedback
LLM-->>RetryHelper: Retry response and usage
RetryHelper-->>AgentService: Output and aggregated usage
Loading

Possibly related PRs

Suggested labels:backend, web, test, agent, documentation

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 74.36% 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedPRの主目的であるBE/WEB/XRのリファクタリングレビューHigh指摘解消を端的に表しており、変更内容と整合しています。
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/all-skills-2026-07-28

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
backend/app/services/agent/resume_draft/draft_service.py (1)

21-21: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Shared types imported through ..chat_service instead of the canonical ..llm.base.llm/base.py is now documented as the source of truth for AgentResponseParseError / AgentUsage; the re-export in chat_service exists only for backward compatibility, so newly-migrated services needlessly depend on the chat module (including its import-time prompt file read).

  • backend/app/services/agent/resume_draft/draft_service.py#L21-L21: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/resume_import/import_service.py#L23-L23: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/skill_display/proposer.py#L20-L20: change to from ..llm.base import AgentResponseParseError, AgentUsage.
🤖 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 `@backend/app/services/agent/resume_draft/draft_service.py` at line 21, Update
the imports in draft_service.py (line 21), import_service.py (line 23), and
proposer.py (line 20) to source AgentResponseParseError and AgentUsage from the
canonical ..llm.base module instead of ..chat_service; no other changes are
needed.
backend/app/services/agent/_utils.py (1)

11-15: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Fence stripping only handles a lowercase json tag.

text.strip("")also removes any trailing backticks anywhere at the ends, andremoveprefix("json")missesJSON` / other language tags, leaving the tag in the payload and forcing an unnecessary retry. A regex-based fence strip would be more robust; behavior today still degrades safely via the parse-error retry path, so this is optional.

♻️ Optional: regex-based fence strip
+import re++_FENCE_RE = re.compile(r"^```[A-Za-z0-9_+-]*\s*\n?(.*?)\n?```$", re.DOTALL)+
def strip_code_fence(raw: str) -> str:
text = raw.strip()
- if text.startswith("```"):- text = text.strip("`")- text = text.removeprefix("json").strip()- return text+ match = _FENCE_RE.match(text)+ return match.group(1).strip() if match else text
🤖 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 `@backend/app/services/agent/_utils.py` around lines 11 - 15, Update
strip_code_fence to remove complete Markdown code fences without stripping
unrelated trailing backticks, and accept case-insensitive or arbitrary language
tags such as JSON. Use a compiled regex matching the opening fence, optional
language identifier, payload, and closing fence; return the trimmed captured
payload when matched, otherwise preserve the original trimmed text.
🤖 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.
Inline comments:
In `@backend/tests/test_routers_shared.py`:
- Around line 28-32: Update test_enforce_agent_daily_limit_allows_under_limit to
explicitly set AGENT_DAILY_LIMIT to 2 before calling enforce_agent_daily_limit,
using the test’s existing configuration/environment override mechanism so the
single request always remains under the limit.
---
Nitpick comments:
In `@backend/app/services/agent/_utils.py`:
- Around line 11-15: Update strip_code_fence to remove complete Markdown code
fences without stripping unrelated trailing backticks, and accept
case-insensitive or arbitrary language tags such as JSON. Use a compiled regex
matching the opening fence, optional language identifier, payload, and closing
fence; return the trimmed captured payload when matched, otherwise preserve the
original trimmed text.
In `@backend/app/services/agent/resume_draft/draft_service.py`:
- Line 21: Update the imports in draft_service.py (line 21), import_service.py
(line 23), and proposer.py (line 20) to source AgentResponseParseError and
AgentUsage from the canonical ..llm.base module instead of ..chat_service; no
other changes are needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c7e317f-2079-4b6e-87f8-94e785a2c554

📥 Commits

Reviewing files that changed from the base of the PR and between 6896b11 and 60ab364.

📒 Files selected for processing (23)
  • backend/app/repositories/resume.py
  • backend/app/routers/_shared.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/chat_service.py
  • backend/app/services/agent/llm/base.py
  • backend/app/services/agent/llm/retry.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/pdf/generators/intelligence_generator.py
  • backend/tests/test_resume_import_service.py
  • backend/tests/test_routers_shared.py
  • web/src/api/ai-resume.ts
  • web/src/api/paths.ts
  • web/src/hooks/career/useCareerExportActions.test.ts
  • web/src/hooks/useAuthSession.ts
  • web/src/hooks/useMasterData.ts
  • web/src/hooks/useNotifications.test.ts
  • web/src/hooks/useNotifications.ts
💤 Files with no reviewable changes (5)
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • web/src/api/ai-resume.ts
  • backend/app/services/pdf/generators/intelligence_generator.py
  • web/src/api/paths.ts

Comment threadbackend/tests/test_routers_shared.py Outdated
- draft_service.py / import_service.py / proposer.py の AgentResponseParseError /
AgentUsage の import を後方互換用の chat_service 経由から正本の llm.base に変更
- strip_code_fence を正規表現ベースに強化し、大文字小文字混在の言語タグや
無関係な末尾バッククォートの誤削除を防止
- test_enforce_agent_daily_limit_allows_under_limit で AGENT_DAILY_LIMIT を
明示的に設定し、環境依存で失敗しないよう決定論化
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit 6018f8c into mainJul 28, 2026
20 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge Agentbackendバックエンドrefactorリファクタリングtestテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消 - #554

Merged
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28
Jul 28, 2026
Merged

refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消#554
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

/goal によるリファクタリングスキル一括実行タスク。BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを並列実行してレビューし、検出された High 指摘全件と、関連する安全な Medium 項目を修正した。

Backend

  • services/agent/ 配下4モジュール(chat / resume_draft / resume_import / skill_display)に一言一句コピーされていた「LLM呼び出し→1回リトライ→トークン合算」ロジックを services/agent/llm/retry.py_utils.py(コードフェンス剥がし)に抽出(Rule of Three 到達済み)
  • 呼び出し元ゼロ・カバレッジ0%の死コード(intelligence_generator 系 PDF/Markdown、計約275行)を削除
  • routers/agent.pyrouters/github_link/endpoints.py に重複していた日次レート制限429変換ロジックを routers/_shared.py に抽出
  • resume.py の冗長なローカル import を解消
  • resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加(616 tests, 90% coverage)

Frontend

  • useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、失敗パスのテストを追加(CLAUDE.md「例外の握りつぶし禁止」ルール対応)
  • useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
  • useCareerExportActions.ts(認証ゲート・活性制御ロジック)のテストを新規追加(359 tests)

Cross-realm

  • 存在しない backend エンドポイントを参照していた死コード web/src/api/ai-resume.tsPATHS.aiResume を削除

見送った項目(レビュー自身が優先度低・時期尚早と判断したもの。過剰な抽象化を避けるため今回は対応しない)

  • Infra: cloud_run の secret_manager module 分割(Terraform state 影響あり)・CI matrix 化(挙動変更リスクあり)。HCL重複率は既に0%(過去のsymlink統合で解消済み)で緊急度なし
  • Backend Medium: routers/agent.py package化、resume_generator._build_html 分割、github_collector._collect_repo_signals 分割、_SequentialFakeLLM 統合
  • Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three 未達、2箇所のみ)、setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編

各レビューの詳細レポートは report/*.md(gitignore 対象のためリポジトリには含まれない)。

Test plan

  • make ci(lint-backend / typecheck-backend / test-backend / lint-web / test-web / build-web)全て green
  • backend: 616 passed, 90% coverage
  • web: 48 files / 359 tests passed
  • make codegen-types 差分なし確認済み(OpenAPI契約に影響する変更なし)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • AI-powered resume import, drafting, and skill suggestions now retry once when responses are invalid, improving successful completion and usage reporting.
    • Fenced or formatted AI responses are handled more reliably.
  • Bug Fixes

    • Agent-related actions now consistently enforce daily usage limits and return a clear rate-limit error when exceeded.
    • Authentication, master-data, and notification failures now provide warning feedback for improved troubleshooting.
  • Removed

    • Legacy AI resume snapshot and intelligence report generation capabilities were removed.

BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを実行し、
検出された High 指摘と関連する安全な Medium 項目を修正。
## Backend
- services/agent/ 配下4モジュール(chat/resume_draft/resume_import/skill_display)に
重複していた LLM リトライ+トークン集計ロジックを services/agent/llm/retry.py と
_utils.py(コードフェンス剥がし)に抽出
- 呼び出し元ゼロの死コード(intelligence_generator 系、PDF/Markdown 計約275行)を削除
- routers/agent.py と routers/github_link/endpoints.py に重複していた
日次レート制限429変換ロジックを routers/_shared.py に抽出
- resume.py の冗長なローカル import を解消
- resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加
## Frontend
- useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、
失敗パスのテストを追加(CLAUDE.md の例外握りつぶし禁止ルール対応)
- useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
- useCareerExportActions.ts のテストを新規追加(認証ゲート・活性制御の分岐)
## Cross-realm
- 存在しない backend エンドポイントを参照する死コード
web/src/api/ai-resume.ts と PATHS.aiResume を削除
## 見送った項目(レビュー自身が優先度低・時期尚早と判断)
- Infra: cloud_run の secret_manager 分割・CI matrix 化(state影響/挙動変更リスクに対し
実利小、HCL重複率は既に0%)
- Backend Medium: routers/agent.py package化、resume_generator._build_html分割、
github_collector._collect_repo_signals分割、_SequentialFakeLLM統合
- Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three未達)、
setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編
検証: make ci(lint / test-backend 616 passed / test-web 359 passed / build-web)全て green
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent refactor リファクタリング labels Jul 28, 2026
@coderabbitai

coderabbitaiBot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b8594c33-b945-48d4-a9dc-42af9491244d

📥 Commits

Reviewing files that changed from the base of the PR and between 60ab364 and 38efd10.

📒 Files selected for processing (5)
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/tests/test_routers_shared.py
📝 Walkthrough

Walkthrough

The PR centralizes agent LLM retry, parsing, usage accounting, and daily-limit handling; adds backend and frontend tests; removes obsolete intelligence-report and AI-resume API code; and adds frontend warning logs for caught errors.

Changes

Agent LLM orchestration

Layer / File(s)Summary
Shared parsing, usage, and retry contracts
backend/app/services/agent/_utils.py, backend/app/services/agent/llm/*
Shared code-fence parsing, AgentUsage, and single-retry orchestration are introduced.
Chat service integration
backend/app/services/agent/chat_service.py
Chat parsing, exports, retry handling, and usage accounting use the shared helpers.
Agent service migration and validation
backend/app/services/agent/resume_draft/*, backend/app/services/agent/resume_import/*, backend/app/services/agent/skill_display/*, backend/tests/test_resume_import_service.py
Agent services delegate parsing and retry behavior to the common helper, with resume-import retry and usage tests added.

Agent daily-limit routing

Layer / File(s)Summary
Shared daily-limit enforcement
backend/app/routers/_shared.py, backend/tests/test_routers_shared.py
Daily-limit checks, commits, and HTTP 429 conversion are extracted and tested.
Endpoint adoption
backend/app/routers/agent.py, backend/app/routers/github_link/endpoints.py
Agent-related endpoints call the shared enforcement helper.

Resume project sorting

Layer / File(s)Summary
Project period date parsing
backend/app/repositories/resume.py
Project sorting uses the module-level date type without changing parsing behavior.

Intelligence report removal

Layer / File(s)Summary
Remove intelligence report generators
backend/app/services/markdown/generators/..., backend/app/services/markdown/templates/..., backend/app/services/pdf/generators/...
Intelligence Markdown/PDF generators and template constants are removed.

Web API and error observability

Layer / File(s)Summary
Career export behavior coverage
web/src/hooks/career/useCareerExportActions.test.ts
Career export authentication, resume availability, actions, and disabled states are tested.
Frontend warning logging
web/src/hooks/useAuthSession.ts, web/src/hooks/useMasterData.ts, web/src/hooks/useNotifications.*
Caught frontend errors now emit warnings while existing fallback behavior remains.
Remove obsolete AI-resume routes
web/src/api/ai-resume.ts, web/src/api/paths.ts
The AI-resume API wrapper and route definitions are removed.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
participant AgentService
participant RetryHelper
participant LLM
participant Parser
AgentService->>RetryHelper: Submit generation request
RetryHelper->>LLM: Generate response
LLM-->>RetryHelper: Response and usage
RetryHelper->>Parser: Parse response
Parser-->>RetryHelper: Parsed output or error
RetryHelper->>LLM: Retry with feedback
LLM-->>RetryHelper: Retry response and usage
RetryHelper-->>AgentService: Output and aggregated usage
Loading

Possibly related PRs

Suggested labels:backend, web, test, agent, documentation

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 74.36% 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedPRの主目的であるBE/WEB/XRのリファクタリングレビューHigh指摘解消を端的に表しており、変更内容と整合しています。
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/all-skills-2026-07-28

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
backend/app/services/agent/resume_draft/draft_service.py (1)

21-21: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Shared types imported through ..chat_service instead of the canonical ..llm.base.llm/base.py is now documented as the source of truth for AgentResponseParseError / AgentUsage; the re-export in chat_service exists only for backward compatibility, so newly-migrated services needlessly depend on the chat module (including its import-time prompt file read).

  • backend/app/services/agent/resume_draft/draft_service.py#L21-L21: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/resume_import/import_service.py#L23-L23: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/skill_display/proposer.py#L20-L20: change to from ..llm.base import AgentResponseParseError, AgentUsage.
🤖 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 `@backend/app/services/agent/resume_draft/draft_service.py` at line 21, Update
the imports in draft_service.py (line 21), import_service.py (line 23), and
proposer.py (line 20) to source AgentResponseParseError and AgentUsage from the
canonical ..llm.base module instead of ..chat_service; no other changes are
needed.
backend/app/services/agent/_utils.py (1)

11-15: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Fence stripping only handles a lowercase json tag.

text.strip("")also removes any trailing backticks anywhere at the ends, andremoveprefix("json")missesJSON` / other language tags, leaving the tag in the payload and forcing an unnecessary retry. A regex-based fence strip would be more robust; behavior today still degrades safely via the parse-error retry path, so this is optional.

♻️ Optional: regex-based fence strip
+import re++_FENCE_RE = re.compile(r"^```[A-Za-z0-9_+-]*\s*\n?(.*?)\n?```$", re.DOTALL)+
def strip_code_fence(raw: str) -> str:
text = raw.strip()
- if text.startswith("```"):- text = text.strip("`")- text = text.removeprefix("json").strip()- return text+ match = _FENCE_RE.match(text)+ return match.group(1).strip() if match else text
🤖 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 `@backend/app/services/agent/_utils.py` around lines 11 - 15, Update
strip_code_fence to remove complete Markdown code fences without stripping
unrelated trailing backticks, and accept case-insensitive or arbitrary language
tags such as JSON. Use a compiled regex matching the opening fence, optional
language identifier, payload, and closing fence; return the trimmed captured
payload when matched, otherwise preserve the original trimmed text.
🤖 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.
Inline comments:
In `@backend/tests/test_routers_shared.py`:
- Around line 28-32: Update test_enforce_agent_daily_limit_allows_under_limit to
explicitly set AGENT_DAILY_LIMIT to 2 before calling enforce_agent_daily_limit,
using the test’s existing configuration/environment override mechanism so the
single request always remains under the limit.
---
Nitpick comments:
In `@backend/app/services/agent/_utils.py`:
- Around line 11-15: Update strip_code_fence to remove complete Markdown code
fences without stripping unrelated trailing backticks, and accept
case-insensitive or arbitrary language tags such as JSON. Use a compiled regex
matching the opening fence, optional language identifier, payload, and closing
fence; return the trimmed captured payload when matched, otherwise preserve the
original trimmed text.
In `@backend/app/services/agent/resume_draft/draft_service.py`:
- Line 21: Update the imports in draft_service.py (line 21), import_service.py
(line 23), and proposer.py (line 20) to source AgentResponseParseError and
AgentUsage from the canonical ..llm.base module instead of ..chat_service; no
other changes are needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c7e317f-2079-4b6e-87f8-94e785a2c554

📥 Commits

Reviewing files that changed from the base of the PR and between 6896b11 and 60ab364.

📒 Files selected for processing (23)
  • backend/app/repositories/resume.py
  • backend/app/routers/_shared.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/chat_service.py
  • backend/app/services/agent/llm/base.py
  • backend/app/services/agent/llm/retry.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/pdf/generators/intelligence_generator.py
  • backend/tests/test_resume_import_service.py
  • backend/tests/test_routers_shared.py
  • web/src/api/ai-resume.ts
  • web/src/api/paths.ts
  • web/src/hooks/career/useCareerExportActions.test.ts
  • web/src/hooks/useAuthSession.ts
  • web/src/hooks/useMasterData.ts
  • web/src/hooks/useNotifications.test.ts
  • web/src/hooks/useNotifications.ts
💤 Files with no reviewable changes (5)
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • web/src/api/ai-resume.ts
  • backend/app/services/pdf/generators/intelligence_generator.py
  • web/src/api/paths.ts

Comment threadbackend/tests/test_routers_shared.py Outdated
- draft_service.py / import_service.py / proposer.py の AgentResponseParseError /
AgentUsage の import を後方互換用の chat_service 経由から正本の llm.base に変更
- strip_code_fence を正規表現ベースに強化し、大文字小文字混在の言語タグや
無関係な末尾バッククォートの誤削除を防止
- test_enforce_agent_daily_limit_allows_under_limit で AGENT_DAILY_LIMIT を
明示的に設定し、環境依存で失敗しないよう決定論化
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit 6018f8c into mainJul 28, 2026
20 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge Agentbackendバックエンドrefactorリファクタリングtestテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消 - #554

Merged
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28
Jul 28, 2026
Merged

refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消#554
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

/goal によるリファクタリングスキル一括実行タスク。BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを並列実行してレビューし、検出された High 指摘全件と、関連する安全な Medium 項目を修正した。

Backend

  • services/agent/ 配下4モジュール(chat / resume_draft / resume_import / skill_display)に一言一句コピーされていた「LLM呼び出し→1回リトライ→トークン合算」ロジックを services/agent/llm/retry.py_utils.py(コードフェンス剥がし)に抽出(Rule of Three 到達済み)
  • 呼び出し元ゼロ・カバレッジ0%の死コード(intelligence_generator 系 PDF/Markdown、計約275行)を削除
  • routers/agent.pyrouters/github_link/endpoints.py に重複していた日次レート制限429変換ロジックを routers/_shared.py に抽出
  • resume.py の冗長なローカル import を解消
  • resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加(616 tests, 90% coverage)

Frontend

  • useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、失敗パスのテストを追加(CLAUDE.md「例外の握りつぶし禁止」ルール対応)
  • useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
  • useCareerExportActions.ts(認証ゲート・活性制御ロジック)のテストを新規追加(359 tests)

Cross-realm

  • 存在しない backend エンドポイントを参照していた死コード web/src/api/ai-resume.tsPATHS.aiResume を削除

見送った項目(レビュー自身が優先度低・時期尚早と判断したもの。過剰な抽象化を避けるため今回は対応しない)

  • Infra: cloud_run の secret_manager module 分割(Terraform state 影響あり)・CI matrix 化(挙動変更リスクあり)。HCL重複率は既に0%(過去のsymlink統合で解消済み)で緊急度なし
  • Backend Medium: routers/agent.py package化、resume_generator._build_html 分割、github_collector._collect_repo_signals 分割、_SequentialFakeLLM 統合
  • Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three 未達、2箇所のみ)、setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編

各レビューの詳細レポートは report/*.md(gitignore 対象のためリポジトリには含まれない)。

Test plan

  • make ci(lint-backend / typecheck-backend / test-backend / lint-web / test-web / build-web)全て green
  • backend: 616 passed, 90% coverage
  • web: 48 files / 359 tests passed
  • make codegen-types 差分なし確認済み(OpenAPI契約に影響する変更なし)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • AI-powered resume import, drafting, and skill suggestions now retry once when responses are invalid, improving successful completion and usage reporting.
    • Fenced or formatted AI responses are handled more reliably.
  • Bug Fixes

    • Agent-related actions now consistently enforce daily usage limits and return a clear rate-limit error when exceeded.
    • Authentication, master-data, and notification failures now provide warning feedback for improved troubleshooting.
  • Removed

    • Legacy AI resume snapshot and intelligence report generation capabilities were removed.

BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを実行し、
検出された High 指摘と関連する安全な Medium 項目を修正。
## Backend
- services/agent/ 配下4モジュール(chat/resume_draft/resume_import/skill_display)に
重複していた LLM リトライ+トークン集計ロジックを services/agent/llm/retry.py と
_utils.py(コードフェンス剥がし)に抽出
- 呼び出し元ゼロの死コード(intelligence_generator 系、PDF/Markdown 計約275行)を削除
- routers/agent.py と routers/github_link/endpoints.py に重複していた
日次レート制限429変換ロジックを routers/_shared.py に抽出
- resume.py の冗長なローカル import を解消
- resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加
## Frontend
- useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、
失敗パスのテストを追加(CLAUDE.md の例外握りつぶし禁止ルール対応)
- useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
- useCareerExportActions.ts のテストを新規追加(認証ゲート・活性制御の分岐)
## Cross-realm
- 存在しない backend エンドポイントを参照する死コード
web/src/api/ai-resume.ts と PATHS.aiResume を削除
## 見送った項目(レビュー自身が優先度低・時期尚早と判断)
- Infra: cloud_run の secret_manager 分割・CI matrix 化(state影響/挙動変更リスクに対し
実利小、HCL重複率は既に0%)
- Backend Medium: routers/agent.py package化、resume_generator._build_html分割、
github_collector._collect_repo_signals分割、_SequentialFakeLLM統合
- Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three未達)、
setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編
検証: make ci(lint / test-backend 616 passed / test-web 359 passed / build-web)全て green
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent refactor リファクタリング labels Jul 28, 2026
@coderabbitai

coderabbitaiBot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b8594c33-b945-48d4-a9dc-42af9491244d

📥 Commits

Reviewing files that changed from the base of the PR and between 60ab364 and 38efd10.

📒 Files selected for processing (5)
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/tests/test_routers_shared.py
📝 Walkthrough

Walkthrough

The PR centralizes agent LLM retry, parsing, usage accounting, and daily-limit handling; adds backend and frontend tests; removes obsolete intelligence-report and AI-resume API code; and adds frontend warning logs for caught errors.

Changes

Agent LLM orchestration

Layer / File(s)Summary
Shared parsing, usage, and retry contracts
backend/app/services/agent/_utils.py, backend/app/services/agent/llm/*
Shared code-fence parsing, AgentUsage, and single-retry orchestration are introduced.
Chat service integration
backend/app/services/agent/chat_service.py
Chat parsing, exports, retry handling, and usage accounting use the shared helpers.
Agent service migration and validation
backend/app/services/agent/resume_draft/*, backend/app/services/agent/resume_import/*, backend/app/services/agent/skill_display/*, backend/tests/test_resume_import_service.py
Agent services delegate parsing and retry behavior to the common helper, with resume-import retry and usage tests added.

Agent daily-limit routing

Layer / File(s)Summary
Shared daily-limit enforcement
backend/app/routers/_shared.py, backend/tests/test_routers_shared.py
Daily-limit checks, commits, and HTTP 429 conversion are extracted and tested.
Endpoint adoption
backend/app/routers/agent.py, backend/app/routers/github_link/endpoints.py
Agent-related endpoints call the shared enforcement helper.

Resume project sorting

Layer / File(s)Summary
Project period date parsing
backend/app/repositories/resume.py
Project sorting uses the module-level date type without changing parsing behavior.

Intelligence report removal

Layer / File(s)Summary
Remove intelligence report generators
backend/app/services/markdown/generators/..., backend/app/services/markdown/templates/..., backend/app/services/pdf/generators/...
Intelligence Markdown/PDF generators and template constants are removed.

Web API and error observability

Layer / File(s)Summary
Career export behavior coverage
web/src/hooks/career/useCareerExportActions.test.ts
Career export authentication, resume availability, actions, and disabled states are tested.
Frontend warning logging
web/src/hooks/useAuthSession.ts, web/src/hooks/useMasterData.ts, web/src/hooks/useNotifications.*
Caught frontend errors now emit warnings while existing fallback behavior remains.
Remove obsolete AI-resume routes
web/src/api/ai-resume.ts, web/src/api/paths.ts
The AI-resume API wrapper and route definitions are removed.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
participant AgentService
participant RetryHelper
participant LLM
participant Parser
AgentService->>RetryHelper: Submit generation request
RetryHelper->>LLM: Generate response
LLM-->>RetryHelper: Response and usage
RetryHelper->>Parser: Parse response
Parser-->>RetryHelper: Parsed output or error
RetryHelper->>LLM: Retry with feedback
LLM-->>RetryHelper: Retry response and usage
RetryHelper-->>AgentService: Output and aggregated usage
Loading

Possibly related PRs

Suggested labels:backend, web, test, agent, documentation

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 74.36% 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedPRの主目的であるBE/WEB/XRのリファクタリングレビューHigh指摘解消を端的に表しており、変更内容と整合しています。
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/all-skills-2026-07-28

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
backend/app/services/agent/resume_draft/draft_service.py (1)

21-21: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Shared types imported through ..chat_service instead of the canonical ..llm.base.llm/base.py is now documented as the source of truth for AgentResponseParseError / AgentUsage; the re-export in chat_service exists only for backward compatibility, so newly-migrated services needlessly depend on the chat module (including its import-time prompt file read).

  • backend/app/services/agent/resume_draft/draft_service.py#L21-L21: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/resume_import/import_service.py#L23-L23: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/skill_display/proposer.py#L20-L20: change to from ..llm.base import AgentResponseParseError, AgentUsage.
🤖 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 `@backend/app/services/agent/resume_draft/draft_service.py` at line 21, Update
the imports in draft_service.py (line 21), import_service.py (line 23), and
proposer.py (line 20) to source AgentResponseParseError and AgentUsage from the
canonical ..llm.base module instead of ..chat_service; no other changes are
needed.
backend/app/services/agent/_utils.py (1)

11-15: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Fence stripping only handles a lowercase json tag.

text.strip("")also removes any trailing backticks anywhere at the ends, andremoveprefix("json")missesJSON` / other language tags, leaving the tag in the payload and forcing an unnecessary retry. A regex-based fence strip would be more robust; behavior today still degrades safely via the parse-error retry path, so this is optional.

♻️ Optional: regex-based fence strip
+import re++_FENCE_RE = re.compile(r"^```[A-Za-z0-9_+-]*\s*\n?(.*?)\n?```$", re.DOTALL)+
def strip_code_fence(raw: str) -> str:
text = raw.strip()
- if text.startswith("```"):- text = text.strip("`")- text = text.removeprefix("json").strip()- return text+ match = _FENCE_RE.match(text)+ return match.group(1).strip() if match else text
🤖 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 `@backend/app/services/agent/_utils.py` around lines 11 - 15, Update
strip_code_fence to remove complete Markdown code fences without stripping
unrelated trailing backticks, and accept case-insensitive or arbitrary language
tags such as JSON. Use a compiled regex matching the opening fence, optional
language identifier, payload, and closing fence; return the trimmed captured
payload when matched, otherwise preserve the original trimmed text.
🤖 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.
Inline comments:
In `@backend/tests/test_routers_shared.py`:
- Around line 28-32: Update test_enforce_agent_daily_limit_allows_under_limit to
explicitly set AGENT_DAILY_LIMIT to 2 before calling enforce_agent_daily_limit,
using the test’s existing configuration/environment override mechanism so the
single request always remains under the limit.
---
Nitpick comments:
In `@backend/app/services/agent/_utils.py`:
- Around line 11-15: Update strip_code_fence to remove complete Markdown code
fences without stripping unrelated trailing backticks, and accept
case-insensitive or arbitrary language tags such as JSON. Use a compiled regex
matching the opening fence, optional language identifier, payload, and closing
fence; return the trimmed captured payload when matched, otherwise preserve the
original trimmed text.
In `@backend/app/services/agent/resume_draft/draft_service.py`:
- Line 21: Update the imports in draft_service.py (line 21), import_service.py
(line 23), and proposer.py (line 20) to source AgentResponseParseError and
AgentUsage from the canonical ..llm.base module instead of ..chat_service; no
other changes are needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c7e317f-2079-4b6e-87f8-94e785a2c554

📥 Commits

Reviewing files that changed from the base of the PR and between 6896b11 and 60ab364.

📒 Files selected for processing (23)
  • backend/app/repositories/resume.py
  • backend/app/routers/_shared.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/chat_service.py
  • backend/app/services/agent/llm/base.py
  • backend/app/services/agent/llm/retry.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/pdf/generators/intelligence_generator.py
  • backend/tests/test_resume_import_service.py
  • backend/tests/test_routers_shared.py
  • web/src/api/ai-resume.ts
  • web/src/api/paths.ts
  • web/src/hooks/career/useCareerExportActions.test.ts
  • web/src/hooks/useAuthSession.ts
  • web/src/hooks/useMasterData.ts
  • web/src/hooks/useNotifications.test.ts
  • web/src/hooks/useNotifications.ts
💤 Files with no reviewable changes (5)
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • web/src/api/ai-resume.ts
  • backend/app/services/pdf/generators/intelligence_generator.py
  • web/src/api/paths.ts

Comment threadbackend/tests/test_routers_shared.py Outdated
- draft_service.py / import_service.py / proposer.py の AgentResponseParseError /
AgentUsage の import を後方互換用の chat_service 経由から正本の llm.base に変更
- strip_code_fence を正規表現ベースに強化し、大文字小文字混在の言語タグや
無関係な末尾バッククォートの誤削除を防止
- test_enforce_agent_daily_limit_allows_under_limit で AGENT_DAILY_LIMIT を
明示的に設定し、環境依存で失敗しないよう決定論化
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit 6018f8c into mainJul 28, 2026
20 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge Agentbackendバックエンドrefactorリファクタリングtestテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消 - #554

Merged
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28
Jul 28, 2026
Merged

refactor: BE/WEB/XR リファクタリングレビューの High 指摘を解消#554
yusuke0610 merged 2 commits into
mainfrom
refactor/all-skills-2026-07-28

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

/goal によるリファクタリングスキル一括実行タスク。BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを並列実行してレビューし、検出された High 指摘全件と、関連する安全な Medium 項目を修正した。

Backend

  • services/agent/ 配下4モジュール(chat / resume_draft / resume_import / skill_display)に一言一句コピーされていた「LLM呼び出し→1回リトライ→トークン合算」ロジックを services/agent/llm/retry.py_utils.py(コードフェンス剥がし)に抽出(Rule of Three 到達済み)
  • 呼び出し元ゼロ・カバレッジ0%の死コード(intelligence_generator 系 PDF/Markdown、計約275行)を削除
  • routers/agent.pyrouters/github_link/endpoints.py に重複していた日次レート制限429変換ロジックを routers/_shared.py に抽出
  • resume.py の冗長なローカル import を解消
  • resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加(616 tests, 90% coverage)

Frontend

  • useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、失敗パスのテストを追加(CLAUDE.md「例外の握りつぶし禁止」ルール対応)
  • useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
  • useCareerExportActions.ts(認証ゲート・活性制御ロジック)のテストを新規追加(359 tests)

Cross-realm

  • 存在しない backend エンドポイントを参照していた死コード web/src/api/ai-resume.tsPATHS.aiResume を削除

見送った項目(レビュー自身が優先度低・時期尚早と判断したもの。過剰な抽象化を避けるため今回は対応しない)

  • Infra: cloud_run の secret_manager module 分割(Terraform state 影響あり)・CI matrix 化(挙動変更リスクあり)。HCL重複率は既に0%(過去のsymlink統合で解消済み)で緊急度なし
  • Backend Medium: routers/agent.py package化、resume_generator._build_html 分割、github_collector._collect_repo_signals 分割、_SequentialFakeLLM 統合
  • Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three 未達、2箇所のみ)、setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編

各レビューの詳細レポートは report/*.md(gitignore 対象のためリポジトリには含まれない)。

Test plan

  • make ci(lint-backend / typecheck-backend / test-backend / lint-web / test-web / build-web)全て green
  • backend: 616 passed, 90% coverage
  • web: 48 files / 359 tests passed
  • make codegen-types 差分なし確認済み(OpenAPI契約に影響する変更なし)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • AI-powered resume import, drafting, and skill suggestions now retry once when responses are invalid, improving successful completion and usage reporting.
    • Fenced or formatted AI responses are handled more reliably.
  • Bug Fixes

    • Agent-related actions now consistently enforce daily usage limits and return a clear rate-limit error when exceeded.
    • Authentication, master-data, and notification failures now provide warning feedback for improved troubleshooting.
  • Removed

    • Legacy AI resume snapshot and intelligence report generation capabilities were removed.

BE_refacter / WEB_refacter / INFRA_refacter / XR_refacter の4スキルを実行し、
検出された High 指摘と関連する安全な Medium 項目を修正。
## Backend
- services/agent/ 配下4モジュール(chat/resume_draft/resume_import/skill_display)に
重複していた LLM リトライ+トークン集計ロジックを services/agent/llm/retry.py と
_utils.py(コードフェンス剥がし)に抽出
- 呼び出し元ゼロの死コード(intelligence_generator 系、PDF/Markdown 計約275行)を削除
- routers/agent.py と routers/github_link/endpoints.py に重複していた
日次レート制限429変換ロジックを routers/_shared.py に抽出
- resume.py の冗長なローカル import を解消
- resume_import のリトライ回復パス・共通429ヘルパーの単体テストを追加
## Frontend
- useNotifications.ts の4箇所の catch {} 握りつぶしに logger.warn を追加し、
失敗パスのテストを追加(CLAUDE.md の例外握りつぶし禁止ルール対応)
- useMasterData.ts / useAuthSession.ts の同種の握りつぶしにも logger.warn を追加
- useCareerExportActions.ts のテストを新規追加(認証ゲート・活性制御の分岐)
## Cross-realm
- 存在しない backend エンドポイントを参照する死コード
web/src/api/ai-resume.ts と PATHS.aiResume を削除
## 見送った項目(レビュー自身が優先度低・時期尚早と判断)
- Infra: cloud_run の secret_manager 分割・CI matrix 化(state影響/挙動変更リスクに対し
実利小、HCL重複率は既に0%)
- Backend Medium: routers/agent.py package化、resume_generator._build_html分割、
github_collector._collect_repo_signals分割、_SequentialFakeLLM統合
- Web Medium/Low: AgentChatWidget のリサイズロジック重複(Rule of Three未達)、
setAtPath.ts の再帰共通化、hooks/ ディレクトリ再編
検証: make ci(lint / test-backend 616 passed / test-web 359 passed / build-web)全て green
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent refactor リファクタリング labels Jul 28, 2026
@coderabbitai

coderabbitaiBot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b8594c33-b945-48d4-a9dc-42af9491244d

📥 Commits

Reviewing files that changed from the base of the PR and between 60ab364 and 38efd10.

📒 Files selected for processing (5)
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/tests/test_routers_shared.py
📝 Walkthrough

Walkthrough

The PR centralizes agent LLM retry, parsing, usage accounting, and daily-limit handling; adds backend and frontend tests; removes obsolete intelligence-report and AI-resume API code; and adds frontend warning logs for caught errors.

Changes

Agent LLM orchestration

Layer / File(s)Summary
Shared parsing, usage, and retry contracts
backend/app/services/agent/_utils.py, backend/app/services/agent/llm/*
Shared code-fence parsing, AgentUsage, and single-retry orchestration are introduced.
Chat service integration
backend/app/services/agent/chat_service.py
Chat parsing, exports, retry handling, and usage accounting use the shared helpers.
Agent service migration and validation
backend/app/services/agent/resume_draft/*, backend/app/services/agent/resume_import/*, backend/app/services/agent/skill_display/*, backend/tests/test_resume_import_service.py
Agent services delegate parsing and retry behavior to the common helper, with resume-import retry and usage tests added.

Agent daily-limit routing

Layer / File(s)Summary
Shared daily-limit enforcement
backend/app/routers/_shared.py, backend/tests/test_routers_shared.py
Daily-limit checks, commits, and HTTP 429 conversion are extracted and tested.
Endpoint adoption
backend/app/routers/agent.py, backend/app/routers/github_link/endpoints.py
Agent-related endpoints call the shared enforcement helper.

Resume project sorting

Layer / File(s)Summary
Project period date parsing
backend/app/repositories/resume.py
Project sorting uses the module-level date type without changing parsing behavior.

Intelligence report removal

Layer / File(s)Summary
Remove intelligence report generators
backend/app/services/markdown/generators/..., backend/app/services/markdown/templates/..., backend/app/services/pdf/generators/...
Intelligence Markdown/PDF generators and template constants are removed.

Web API and error observability

Layer / File(s)Summary
Career export behavior coverage
web/src/hooks/career/useCareerExportActions.test.ts
Career export authentication, resume availability, actions, and disabled states are tested.
Frontend warning logging
web/src/hooks/useAuthSession.ts, web/src/hooks/useMasterData.ts, web/src/hooks/useNotifications.*
Caught frontend errors now emit warnings while existing fallback behavior remains.
Remove obsolete AI-resume routes
web/src/api/ai-resume.ts, web/src/api/paths.ts
The AI-resume API wrapper and route definitions are removed.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
participant AgentService
participant RetryHelper
participant LLM
participant Parser
AgentService->>RetryHelper: Submit generation request
RetryHelper->>LLM: Generate response
LLM-->>RetryHelper: Response and usage
RetryHelper->>Parser: Parse response
Parser-->>RetryHelper: Parsed output or error
RetryHelper->>LLM: Retry with feedback
LLM-->>RetryHelper: Retry response and usage
RetryHelper-->>AgentService: Output and aggregated usage
Loading

Possibly related PRs

Suggested labels:backend, web, test, agent, documentation

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 74.36% 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedPRの主目的であるBE/WEB/XRのリファクタリングレビューHigh指摘解消を端的に表しており、変更内容と整合しています。
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/all-skills-2026-07-28

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
backend/app/services/agent/resume_draft/draft_service.py (1)

21-21: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Shared types imported through ..chat_service instead of the canonical ..llm.base.llm/base.py is now documented as the source of truth for AgentResponseParseError / AgentUsage; the re-export in chat_service exists only for backward compatibility, so newly-migrated services needlessly depend on the chat module (including its import-time prompt file read).

  • backend/app/services/agent/resume_draft/draft_service.py#L21-L21: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/resume_import/import_service.py#L23-L23: change to from ..llm.base import AgentResponseParseError, AgentUsage.
  • backend/app/services/agent/skill_display/proposer.py#L20-L20: change to from ..llm.base import AgentResponseParseError, AgentUsage.
🤖 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 `@backend/app/services/agent/resume_draft/draft_service.py` at line 21, Update
the imports in draft_service.py (line 21), import_service.py (line 23), and
proposer.py (line 20) to source AgentResponseParseError and AgentUsage from the
canonical ..llm.base module instead of ..chat_service; no other changes are
needed.
backend/app/services/agent/_utils.py (1)

11-15: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Fence stripping only handles a lowercase json tag.

text.strip("")also removes any trailing backticks anywhere at the ends, andremoveprefix("json")missesJSON` / other language tags, leaving the tag in the payload and forcing an unnecessary retry. A regex-based fence strip would be more robust; behavior today still degrades safely via the parse-error retry path, so this is optional.

♻️ Optional: regex-based fence strip
+import re++_FENCE_RE = re.compile(r"^```[A-Za-z0-9_+-]*\s*\n?(.*?)\n?```$", re.DOTALL)+
def strip_code_fence(raw: str) -> str:
text = raw.strip()
- if text.startswith("```"):- text = text.strip("`")- text = text.removeprefix("json").strip()- return text+ match = _FENCE_RE.match(text)+ return match.group(1).strip() if match else text
🤖 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 `@backend/app/services/agent/_utils.py` around lines 11 - 15, Update
strip_code_fence to remove complete Markdown code fences without stripping
unrelated trailing backticks, and accept case-insensitive or arbitrary language
tags such as JSON. Use a compiled regex matching the opening fence, optional
language identifier, payload, and closing fence; return the trimmed captured
payload when matched, otherwise preserve the original trimmed text.
🤖 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.
Inline comments:
In `@backend/tests/test_routers_shared.py`:
- Around line 28-32: Update test_enforce_agent_daily_limit_allows_under_limit to
explicitly set AGENT_DAILY_LIMIT to 2 before calling enforce_agent_daily_limit,
using the test’s existing configuration/environment override mechanism so the
single request always remains under the limit.
---
Nitpick comments:
In `@backend/app/services/agent/_utils.py`:
- Around line 11-15: Update strip_code_fence to remove complete Markdown code
fences without stripping unrelated trailing backticks, and accept
case-insensitive or arbitrary language tags such as JSON. Use a compiled regex
matching the opening fence, optional language identifier, payload, and closing
fence; return the trimmed captured payload when matched, otherwise preserve the
original trimmed text.
In `@backend/app/services/agent/resume_draft/draft_service.py`:
- Line 21: Update the imports in draft_service.py (line 21), import_service.py
(line 23), and proposer.py (line 20) to source AgentResponseParseError and
AgentUsage from the canonical ..llm.base module instead of ..chat_service; no
other changes are needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c7e317f-2079-4b6e-87f8-94e785a2c554

📥 Commits

Reviewing files that changed from the base of the PR and between 6896b11 and 60ab364.

📒 Files selected for processing (23)
  • backend/app/repositories/resume.py
  • backend/app/routers/_shared.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/services/agent/_utils.py
  • backend/app/services/agent/chat_service.py
  • backend/app/services/agent/llm/base.py
  • backend/app/services/agent/llm/retry.py
  • backend/app/services/agent/resume_draft/draft_service.py
  • backend/app/services/agent/resume_import/import_service.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/pdf/generators/intelligence_generator.py
  • backend/tests/test_resume_import_service.py
  • backend/tests/test_routers_shared.py
  • web/src/api/ai-resume.ts
  • web/src/api/paths.ts
  • web/src/hooks/career/useCareerExportActions.test.ts
  • web/src/hooks/useAuthSession.ts
  • web/src/hooks/useMasterData.ts
  • web/src/hooks/useNotifications.test.ts
  • web/src/hooks/useNotifications.ts
💤 Files with no reviewable changes (5)
  • backend/app/services/markdown/templates/intelligence_template.py
  • backend/app/services/markdown/generators/intelligence_generator.py
  • web/src/api/ai-resume.ts
  • backend/app/services/pdf/generators/intelligence_generator.py
  • web/src/api/paths.ts

Comment threadbackend/tests/test_routers_shared.py Outdated
- draft_service.py / import_service.py / proposer.py の AgentResponseParseError /
AgentUsage の import を後方互換用の chat_service 経由から正本の llm.base に変更
- strip_code_fence を正規表現ベースに強化し、大文字小文字混在の言語タグや
無関係な末尾バッククォートの誤削除を防止
- test_enforce_agent_daily_limit_allows_under_limit で AGENT_DAILY_LIMIT を
明示的に設定し、環境依存で失敗しないよう決定論化
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit 6018f8c into mainJul 28, 2026
20 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge Agentbackendバックエンドrefactorリファクタリングtestテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610