Skip to content

fix(portal): address CodeRabbit review findings - #6

Merged
deckyfx merged 3 commits into
masterfrom
fix/portal-cr-fixes
Jul 27, 2026
Merged

fix(portal): address CodeRabbit review findings#6
deckyfx merged 3 commits into
masterfrom
fix/portal-cr-fixes

Conversation

@deckyfx

@deckyfx deckyfx commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Summary

  • TranslateRoutes: move readiness gate after engine resolution — DeepL requests no longer get 503 when local model is disabled; IsNullOrWhiteSpace fallback replaces ?? to reject empty-string engine values
  • ModelSettingsStore: PreferredTranslationEngine in Merge() now uses env-override + IsNullOrWhiteSpace fallback, consistent with all other fields
  • SettingsRoutes: add PATCH /api/settings/engine narrow endpoint — updates only the engine field without persisting env-derived repo/dir/files values to disk
  • Dashboard: switch to PATCH /api/settings/engine; surface save failures via setErr() instead of silent console.error; clear error on retry
  • JobsListPage: restructure JobCard as two sibling native <button> elements inside a <div> — eliminates nested interactive controls (div[role=button] inside <button>); add catch + deleteError signal so failed deletes show a dismissable banner

These are the 6 actionable findings from the CodeRabbit review of PR #5 that were fixed after the PR was merged.

Test plan

  • DeepL translation works when TRANSLATE_MODEL_ENABLED=false
  • Dashboard translation engine switch shows error banner on save failure
  • Job delete error shows banner in JobsListPage
  • Keyboard navigation on job cards works (Tab focuses delete button separately from nav button)
  • PATCH /api/settings/engine returns { preferred_translation_engine } and persists across restart

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a dedicated workflow to save the selected translation engine (updates only the engine setting).
  • Bug Fixes
    • Improved translation request validation to block empty text.
    • Refined translation engine selection and readiness behavior (including “auto” resolution and external-engine checks).
    • Updated engine preference precedence to prefer the configured environment value when set.
    • Added user-visible feedback for failed job deletions and cleared stale errors before health checks.
  • Accessibility & Style
    • Refined job card controls to use native buttons and updated focus/stacking styles.

- TranslateRoutes: move readiness gate after engine resolution so DeepL
  requests are not blocked by the local-model-not-ready check; use
  IsNullOrWhiteSpace instead of ?? to reject empty-string engine values
- ModelSettingsStore: apply env-override + NonEmpty fallback to
  PreferredTranslationEngine in Merge(), matching all other fields
- SettingsRoutes: add PATCH /api/settings/engine narrow endpoint so the
  dashboard can update only the engine without a read-modify-write cycle
  that would persist env-derived repo/dir/files values to disk
- Dashboard: use PATCH /api/settings/engine; surface save failures via
  setErr() instead of silent console.error; clear err on retry
- JobsListPage: restructure JobCard as sibling native <button> elements
  (no more div[role=button] inside <button>); add catch + deleteError
  signal to confirmDelete so failures are visible to the user
- Rebuild client bundle

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 12 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: 32a15daa-6473-4eb2-ac50-9850085d70fc

📥 Commits

Reviewing files that changed from the base of the PR and between 14d4be5 and 09b7575.

📒 Files selected for processing (2)
  • .coderabbit.yaml
  • server/src/ModelSettingsStore.cs
📝 Walkthrough

Walkthrough

The change adds a narrow translation-engine settings endpoint, updates engine precedence and translation readiness checks, and refactors job-card deletion controls with failure feedback. Bundled frontend assets reflect the client interaction and styling changes.

Changes

Translation engine flow

Layer / File(s) Summary
Engine settings API and persistence
server/src/Routes/SettingsRoutes.cs, server/src/ModelSettingsStore.cs
Adds PATCH /api/settings/engine and applies environment, persisted-file, and default precedence when merging the preferred engine.
Translation request selection
server/src/Routes/TranslateRoutes.cs
Validates text before readiness checks, selects the requested or preferred engine, and requires local readiness only for non-DeepL translation.
Translation settings client wiring
server/ClientApp/src/components/Dashboard.tsx
Saves only the selected engine through the PATCH endpoint and clears or reports request errors appropriately.

Job deletion interactions

Layer / File(s) Summary
Job card controls and deletion state
server/ClientApp/src/pages/JobsListPage.tsx
Separates navigation and deletion into sibling native buttons, captures deletion failures, and renders dismissible error feedback.
Bundled job interaction and styling
server/wwwroot/js/app.js, server/wwwroot/js/app.css
Updates bundled deletion wiring and adds stacking and focus styling utilities.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Dashboard
  participant SettingsRoutes
  participant ModelSettingsStore
  participant TranslateRoutes
  User->>Dashboard: Select translation engine
  Dashboard->>SettingsRoutes: PATCH /api/settings/engine
  SettingsRoutes->>ModelSettingsStore: Persist preferred engine
  ModelSettingsStore-->>SettingsRoutes: Updated settings
  SettingsRoutes-->>Dashboard: Updated engine
  User->>TranslateRoutes: Submit translation text and optional engine
  TranslateRoutes->>TranslateRoutes: Validate text and select engine
  TranslateRoutes-->>User: Continue or return readiness status
Loading

Possibly related PRs

  • deckyfx/web-ocr#3: Establishes the base /api/settings GET/PUT routes extended here with the engine-specific PATCH endpoint.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is generic and does not describe the specific changes in translation settings, job cards, or route handling. Rename it to mention the main change, such as adding the settings engine endpoint and related UI/route updates.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check 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 fix/portal-cr-fixes

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.

@coderabbitai coderabbitai Bot 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: 5

🤖 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 `@server/ClientApp/src/pages/JobsListPage.tsx`:
- Around line 194-202: Add role="alert" to the dynamically rendered
deletion-error div containing msg() in JobsListPage so assistive technology
announces deletion failures, preserving the existing dismissal behavior and
styling.
- Around line 62-69: Update the delete button in JobsListPage so it remains
visible by default on touch devices while preserving the current hover/focus
reveal behavior for capable devices. Adjust the opacity utility classes on the
button containing Trash2, using responsive or device-appropriate variants rather
than relying solely on group-hover.

In `@server/src/ModelSettingsStore.cs`:
- Around line 196-202: Update the PreferredTranslationEngine selection to ignore
whitespace-only PREFERRED_TRANSLATION_ENGINE values by validating with
!string.IsNullOrWhiteSpace. Trim the accepted environment override before
assigning it, while preserving the existing file-value and env-derived default
fallback order.

In `@server/src/Routes/SettingsRoutes.cs`:
- Around line 33-35: Replace the read-modify-write sequence in the settings
route with a store method that clones the current settings, applies the
requested engine update, and persists it while holding _writeLock. Update the
route to call this atomic method instead of modifying store.Current and passing
the full object to UpdateAsync, preserving unrelated concurrent settings.

In `@server/src/Routes/TranslateRoutes.cs`:
- Around line 20-27: Update the engine-selection flow in the translation route
to resolve “auto” to DeepL when configured, otherwise to the local backend,
before evaluating needsLocal. Apply the readiness check against this resolved
backend and enqueue the same resolved engine, preserving explicit engine
selections.
🪄 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: 9f111dad-353b-4725-88c4-064eb9880b12

📥 Commits

Reviewing files that changed from the base of the PR and between 7da1899 and f38a9af.

📒 Files selected for processing (7)
  • server/ClientApp/src/components/Dashboard.tsx
  • server/ClientApp/src/pages/JobsListPage.tsx
  • server/src/ModelSettingsStore.cs
  • server/src/Routes/SettingsRoutes.cs
  • server/src/Routes/TranslateRoutes.cs
  • server/wwwroot/js/app.css
  • server/wwwroot/js/app.js

Comment thread server/ClientApp/src/pages/JobsListPage.tsx
Comment thread server/ClientApp/src/pages/JobsListPage.tsx Outdated
Comment thread server/src/ModelSettingsStore.cs
Comment thread server/src/Routes/SettingsRoutes.cs Outdated
Comment thread server/src/Routes/TranslateRoutes.cs Outdated
- JobsListPage: remove opacity-0/group-hover on delete button so it is
  always visible on touch devices (was undiscoverable without hover)
- JobsListPage: add role="alert" to delete-error banner for screen reader
  announcement
- ModelSettingsStore: add UpdateEngineAsync() that clones _current and
  persists atomically inside _writeLock, preventing a race between PATCH
  and concurrent PUT /api/settings
- SettingsRoutes: use UpdateEngineAsync() in PATCH /api/settings/engine
  instead of the racy read-modify-write on store.Current
- TranslateRoutes: resolve "auto" engine to deepl/local before needsLocal
  check so DeepL is used when configured and the local model is not ready
- ModelSettingsStore: guard PREFERRED_TRANSLATION_ENGINE env var with
  IsNullOrWhiteSpace + Trim() to reject whitespace-only values

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@deckyfx

deckyfx commented Jul 27, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

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

@coderabbitai coderabbitai Bot 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: 2

🤖 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 `@server/src/ModelSettingsStore.cs`:
- Around line 140-145: Update the persistence flow in the method containing
_current and _writeLock so the serialized updated settings are written
successfully, including directory creation, before assigning _current. Keep the
assignment inside the existing _writeLock scope, and only log and return the
committed value after persistence succeeds.
- Around line 126-138: Update UpdateEngineAsync to trim the engine value before
assigning PreferredTranslationEngine, then validate the normalized value at this
persistence boundary and reject it when it is empty or whitespace-only. Store
and propagate only the normalized, valid engine while preserving the existing
settings update flow.
🪄 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: 67fc1730-2834-4348-9b0a-7cd397f75c2d

📥 Commits

Reviewing files that changed from the base of the PR and between f38a9af and 14d4be5.

📒 Files selected for processing (5)
  • server/ClientApp/src/pages/JobsListPage.tsx
  • server/src/ModelSettingsStore.cs
  • server/src/Routes/SettingsRoutes.cs
  • server/src/Routes/TranslateRoutes.cs
  • server/wwwroot/js/app.js
🚧 Files skipped from review as they are similar to previous changes (3)
  • server/src/Routes/SettingsRoutes.cs
  • server/src/Routes/TranslateRoutes.cs
  • server/ClientApp/src/pages/JobsListPage.tsx

Comment thread server/src/ModelSettingsStore.cs
Comment thread server/src/ModelSettingsStore.cs Outdated
- Validate and trim engine before _writeLock in UpdateEngineAsync so
  whitespace-padded values are rejected at the persistence boundary
- Move _current assignment to after File.WriteAllTextAsync so in-memory
  state only reflects what was successfully persisted
- Add .coderabbit.yaml to exclude server/wwwroot/js/app.{js,css} from
  CodeRabbit reviews (generated Vite artifacts, not hand-written code)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@deckyfx
deckyfx force-pushed the fix/portal-cr-fixes branch from 73a1de0 to 09b7575 Compare July 27, 2026 11:43
@deckyfx

deckyfx commented Jul 27, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

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

@deckyfx
deckyfx merged commit a72fa61 into master Jul 27, 2026
1 check passed
@deckyfx
deckyfx deleted the fix/portal-cr-fixes branch July 27, 2026 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant