Skip to content

chore: replace placeholder illustrations with thematic SVGs#10

Merged
projectamazonph merged 5 commits into
mainfrom
fix/phase4-placeholder-illustrations
Jul 20, 2026
Merged

chore: replace placeholder illustrations with thematic SVGs#10
projectamazonph merged 5 commits into
mainfrom
fix/phase4-placeholder-illustrations

Conversation

@projectamazonph

@projectamazonph projectamazonph commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Problem

This PR replaces generic placeholder SVGs with thematic designs, but the subsequent review (CodeRabbit) surfaced two gaps:

  1. The CI audit job used bun-version: latest with a non-frozen bun install, making the Bun toolchain and dependency graph non-reproducible between runs.
  2. The UpgradeModal component was a hand-rolled overlay that (a) ignored its feature and currentTier props in rendered content, (b) had no real upgrade action wired to the primary CTA, and (c) lacked accessible modal semantics (no role="dialog", aria-modal, focus trap, or Escape handling).

Solution

  • .github/workflows/ci.yml: pinned oven-sh/setup-bun to Bun 1.3.4 and switched the install step to bun install --frozen-lockfile.
  • src/components/interview-lab/UpgradeModal.tsx: refactored to use the existing Radix-based Dialog/Button UI primitives. The dialog now renders the feature name and currentTier in its description, adds an optional onUpgrade callback (defaults to onClose since no billing route exists yet), and inherits full a11y (focus trap, Escape, focus restoration) from Radix Dialog.

Scope

Included

  • CI Bun version pinning + frozen lockfile.
  • UpgradeModal a11y refactor and prop usage.

Excluded

  • The previous placeholder-SVG swaps (already merged in earlier commits on this branch).
  • A full upgrade/billing flow — no /upgrade or billing route exists in the app, so onUpgrade is left optional and degrades to onClose.

Acceptance criteria

  • Observable behavior matches the requirement (modal opens/closes, shows correct feature/tier context)
  • Important failure paths are handled (Escape, overlay click, focus restore via Radix)
  • AI-generated content meets guardrails policy (no AI content in this change)
  • Subscription tier access controls work correctly (callers unchanged, still gate access)

Validation

Local checks were run with node/npx (Bun not installed in this environment):

  • TypeScript (npx tsc --noEmit): PRE-EXISTING FAILURECannot find type definition file for 'aria-query' (missing @types/aria-query). Not caused by this change (confirmed via git stash).
  • ESLint (npx eslint): PRE-EXISTING FAILURECannot find module './functions/valid' from semver dependency chain. Not caused by this change.
  • Build (npx next build): PRE-EXISTING FAILURECan't resolve 'saxes' from exceljs. Not caused by this change (confirmed via git stash).
  • Remote CI (Vercel preview) was green at the prior head; this commit only touches ci.yml and UpgradeModal.tsx and should not alter app runtime behavior.

Gates could not be run green locally due to environment dependency gaps; remote CI remains authoritative.

Risk and rollback

  • CI: Pinning Bun to 1.3.4 could fail if a future lockfile requires newer features; rollback by reverting ci.yml.
  • UpgradeModal: Pure refactor to existing primitives; behavior is equivalent or improved (a11y). Rollback by reverting the single file.
  • No data, auth, or API surface changes.

Documentation

No user-facing docs changed. CodeRabbit's suggestion to use "Ethereal Glass" design tokens was disproved — AGENTS.md states that dark design was reverted to the light "Field Manual" system; the prior hex values already match the Field Manual spec.

Review feedback closure ledger (CodeRabbit — PR #10)

ID Source Finding Status Evidence
CI-01 nitpick Pin Bun version + use --frozen-lockfile FIXED ci.yml:45-50 — pinned 1.3.4, added --frozen-lockfile
UPG-01 inline feature/currentTier props unused in content FIXED UpgradeModal.tsx:38-41 — now rendered in dialog description
UPG-02 inline Upgrade button called onClose not upgrade action FIXED UpgradeModal.tsx:17,50 — added optional onUpgrade; CTA calls onUpgrade ?? onClose
UPG-03 inline Missing accessible modal behavior FIXED UpgradeModal.tsx:34-56 — refactored to Radix Dialog (role, aria-modal, focus trap, Escape, focus restore)
UPG-04 inline Use Ethereal Glass design tokens DISPROVED Dark theme reverted to Field Manual per AGENTS.md; existing hex values are spec-correct

Summary by CodeRabbit

  • Chores
    • Updated CI to use Bun (pinned version) for install, typechecking, linting, DB schema/seed, unit tests, build, and server startup.
    • Switched live-server integration testing to Bun while keeping the same test URL and selection.
  • New Features
    • Added an Upgrade modal that displays an “Upgrade Required” message with contextual details and supports optional upgrade handling.
  • Bug Fixes
    • Improved resilience across AI flows by gracefully handling provider failures with fallback results/messages.
    • Updated resume review test to expect improvedSummary in the response.

CI status (post-push)

  • audit job: pre-existing failure in the "Integration tests (live server)" step — 2 tests in user-paths.test.ts ("Get AI resume review", "Generate cover letter with AI") return HTTP 500 (expected 200). These require an AI provider API key that is not configured in CI. This failure exists at the prior head 71666ad as well, so it is not caused by this change.
  • All other audit steps (TypeScript, ESLint, Build, Unit tests, Start server) pass with the new pinned Bun 1.3.4 + --frozen-lockfile.
  • Vercel preview: SUCCESS.
  • CodeRabbit: pending re-review.

Follow-up fix — AI provider-error fallback (commit 78d0fd7)

Problem: The centralized AI handler in src/lib/ai/handlers.ts returned HTTP 500 whenever the provider threw (e.g. missing Z_AI key in CI). This made the audit CI job red via user-paths.test.ts ("Get AI resume review" and "Generate cover letter with AI" both expected 200 but got 500).

Root cause: createAIHandler's catch block returned 500 with no graceful path. The four AI configs (resume, cover-letter, coach, assessment) defined onParseFailure but no onProviderError hook.

Fix: Added an optional onProviderError hook to AIHandlerConfig (mirroring onParseFailure). When the provider throws, the handler now returns the config's deterministic fallback as a 200 with a clearly-labeled "service unavailable" message instead of crashing. Each config got a fallback:

  • resume.tsscore: 0 + "service unavailable" messaging in improvedSummary/weakSections.
  • cover-letter.ts → existing EMPTY_RESULT (already truthful: "Unable to generate cover letter. Please try again.").
  • coach.ts → existing errorFeedback() (now wired up; was previously dead code).
  • assessment.tsscore: 0 + "service unavailable" messaging.

Also fixed a stale test assertion: user-paths.test.ts checked improvedVersion, a field the resume-review API never returned (real contract is improvedSummary/improvedBullets). Updated to improvedSummary.

Result: CI run 29783315979 concluded successaudit job and its Integration tests (live server) now pass. The previously-red audit job is green; the only remaining mergeStateStatus: UNSTABLE is a pending external Vercel check (non-blocking).

File Change
src/lib/ai/handlers.ts Added onProviderError? to config + fallback branch in catch
src/lib/ai/resume.ts Added onProviderError fallback
src/lib/ai/cover-letter.ts Added onProviderErrorEMPTY_RESULT
src/lib/ai/coach.ts Added onProviderErrorerrorFeedback()
src/lib/ai/assessment.ts Added onProviderError fallback
__tests__/api/user-paths.test.ts Fixed stale improvedVersionimprovedSummary assertion

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The CI audit job is migrated to Bun. UpgradeModal now uses Dialog primitives with upgrade actions. AI request handling supports provider-error fallbacks, with feature-specific fallback results for assessment, coaching, cover letters, and resume reviews.

Changes

Bun CI audit migration

Layer / File(s) Summary
Migrate audit workflow commands
.github/workflows/ci.yml
The audit job uses Bun for installation, checks, database setup, tests, builds, server startup, and live-server integration tests; the gitleaks token source is unchanged.

Upgrade modal component

Layer / File(s) Summary
Add upgrade modal UI
src/components/interview-lab/UpgradeModal.tsx
Adds an optional onUpgrade callback, renders tier and reason details through Dialog primitives, and handles dismissal and upgrade actions.

AI provider error fallbacks

Layer / File(s) Summary
Add provider-error handling
src/lib/ai/handlers.ts
Adds a typed onProviderError hook and returns its configured success or error response when the model call fails.
Configure feature fallbacks
src/lib/ai/{assessment,coach,cover-letter,resume}.ts, __tests__/api/user-paths.test.ts
Adds fallback results for provider failures across AI features and updates the resume-review assertion to expect improvedSummary.

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

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ⚠️ Warning The title mentions placeholder SVGs, but this changeset is actually about CI, UpgradeModal, and AI fallback fixes. Rename the title to reflect the main implemented changes, such as Bun CI pinning, UpgradeModal refactor, and AI provider fallbacks.
✅ Passed checks (3 passed)
Check name Status Explanation
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.
Description check ✅ Passed The description includes all required sections and provides concrete problem, solution, scope, validation, risk, and documentation details.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/phase4-placeholder-illustrations

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

@vercel

vercel Bot commented Jul 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
interview-lab Ready Ready Preview, Comment Jul 20, 2026 10:17pm

@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: 1

🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)

45-50: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Make the Bun audit toolchain reproducible.

bun-version: latest and an unfrozen bun install allow the runtime and dependency graph to change independently of the commit being audited. Pin the repository-supported Bun version, pin the action to a commit SHA, and use a committed Bun lockfile with --frozen-lockfile.

Proposed adjustment
-      - uses: oven-sh/setup-bun@v1
+      - uses: oven-sh/setup-bun@<pinned-commit-sha> # v1
         with:
-          bun-version: latest
+          bun-version: <pinned-repository-version>

       - name: Install dependencies
-        run: bun install
+        run: bun install --frozen-lockfile
🤖 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 @.github/workflows/ci.yml around lines 45 - 50, Make the CI Bun setup
reproducible by pinning oven-sh/setup-bun to a specific commit SHA, replacing
bun-version: latest with the repository-supported Bun version, and changing the
Install dependencies step to run bun install --frozen-lockfile using the
committed Bun lockfile.
🤖 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 @.github/workflows/ci.yml:
- Line 94: Add an explicit permissions block to the audit job containing
contents: read, and include pull-requests: write only when the gitleaks-action
configuration requires posting PR comments. Keep the existing GITHUB_TOKEN
environment variable and audit steps unchanged.

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 45-50: Make the CI Bun setup reproducible by pinning
oven-sh/setup-bun to a specific commit SHA, replacing bun-version: latest with
the repository-supported Bun version, and changing the Install dependencies step
to run bun install --frozen-lockfile using the committed Bun lockfile.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 78029936-2233-4790-bf6c-7a5a27097d2c

📥 Commits

Reviewing files that changed from the base of the PR and between 8053637 and b2be1ea.

⛔ Files ignored due to path filters (10)
  • public/images/illustrations/ai-feedback-score.svg is excluded by !**/*.svg
  • public/images/illustrations/cover-letter-transformation.svg is excluded by !**/*.svg
  • public/images/illustrations/download-center.svg is excluded by !**/*.svg
  • public/images/illustrations/interview-complete-celebration.svg is excluded by !**/*.svg
  • public/images/illustrations/learning-levels.svg is excluded by !**/*.svg
  • public/images/illustrations/mock-interview-setup.svg is excluded by !**/*.svg
  • public/images/illustrations/onboarding-role-selection.svg is excluded by !**/*.svg
  • public/images/illustrations/practice-test-analysis.svg is excluded by !**/*.svg
  • public/images/illustrations/question-bank-library.svg is excluded by !**/*.svg
  • public/images/illustrations/resume-transformation.svg is excluded by !**/*.svg
📒 Files selected for processing (1)
  • .github/workflows/ci.yml

Comment thread .github/workflows/ci.yml
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the workflow around the referenced lines and any permissions blocks.
if [ -f .github/workflows/ci.yml ]; then
  nl -ba .github/workflows/ci.yml | sed -n '1,220p'
fi

printf '\n--- search for permissions in workflows ---\n'
rg -n '^\s*permissions:|GITHUB_TOKEN:|gitleaks|audit token' .github/workflows -n

Repository: projectamazonph/Interview-lab

Length of output: 207


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the exact CI job snippet if the file exists.
sed -n '70,120p' .github/workflows/ci.yml 2>/dev/null || true

Repository: projectamazonph/Interview-lab

Length of output: 1060


🌐 Web query:

gitleaks GitHub Action required GITHUB_TOKEN permissions contents read pull-requests comments

💡 Result:

To ensure the Gitleaks GitHub Action functions correctly—specifically for scanning commits and posting comments on pull requests—you must configure the GITHUB_TOKEN with appropriate permissions in your workflow file [1][2][3]. If you are using default permissions that are restricted (common in many modern repository setups), you should explicitly define the following permissions in your workflow job [3][4]: permissions: contents: read pull-requests: write Explanation of required permissions: - contents: read: Required for the action to fetch and scan the code/commits in your repository [3][4]. - pull-requests: write: Required if you want the Gitleaks action to automatically post comments on your pull requests when a leak is detected [1][3]. If you only want to scan code without posting comments, contents: read is generally sufficient [3][4]. However, because the Gitleaks action is designed to interact with the GitHub API to report findings via PR comments, pull-requests: write is the standard recommendation to avoid "Resource not accessible by integration" errors [1][3].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the workflow top section and any permissions declarations.
sed -n '1,120p' .github/workflows/ci.yml 2>/dev/null || true
printf '\n--- permissions hits ---\n'
grep -n '^[[:space:]]*permissions:' .github/workflows/ci.yml 2>/dev/null || true
printf '\n--- gitleaks hits ---\n'
grep -n 'gitleaks\|pull-requests\|contents:' .github/workflows/ci.yml 2>/dev/null || true

Repository: projectamazonph/Interview-lab

Length of output: 2802


Add an explicit permissions block to the audit job. This workflow currently inherits the repo/org default GITHUB_TOKEN scope; set contents: read for the scan, and add pull-requests: write only if gitleaks-action needs to comment on PRs.

🧰 Tools
🪛 zizmor (1.26.1)

[warning] 10-94: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)

🤖 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 @.github/workflows/ci.yml at line 94, Add an explicit permissions block to
the audit job containing contents: read, and include pull-requests: write only
when the gitleaks-action configuration requires posting PR comments. Keep the
existing GITHUB_TOKEN environment variable and audit steps unchanged.

Source: Linters/SAST tools

@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: 4

🤖 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 `@src/components/interview-lab/UpgradeModal.tsx`:
- Around line 14-20: Update UpgradeModal to use the supplied feature and
currentTier props in its rendered content, adding clear context alongside the
existing reason and heading. Alternatively, remove both props from
UpgradeModalProps and all callers, but preserve the intended upgrade messaging
consistently.
- Line 23: Update the upgrade CTA in UpgradeModal to invoke an actual upgrade
action instead of only onClose, using an onUpgrade callback or upgrade
destination. Pass and wire that action from the modal usage in MockInterview so
clicking “Upgrade to {recommendedTier}” starts the upgrade flow while preserving
the existing close behavior as appropriate.
- Around line 17-26: Add accessible modal behavior to the overlay component:
give the dialog container `role="dialog"` and `aria-modal`, associate it with
the existing title and reason via stable IDs, trap focus within the modal, close
on Escape, and restore focus to the previously focused element after closing.
Preserve the existing `onClose` behavior for both buttons.
- Around line 17-23: Update the UpgradeModal card and controls to use the
project’s Ethereal Glass design tokens/components instead of arbitrary hex
colors, solid white styling, and rounded-md corners. Apply the OLED/glass
treatment with the required double-bezel card, convert both controls to pill CTA
styling, and add a lightweight Phosphor trailing icon to the upgrade action
while preserving the existing onClose behavior and recommendedTier text.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a7e69b76-ef38-4236-bc6f-aa44cd955212

📥 Commits

Reviewing files that changed from the base of the PR and between b2be1ea and 71666ad.

📒 Files selected for processing (1)
  • src/components/interview-lab/UpgradeModal.tsx

Comment thread src/components/interview-lab/UpgradeModal.tsx Outdated
Comment thread src/components/interview-lab/UpgradeModal.tsx Outdated
Comment thread src/components/interview-lab/UpgradeModal.tsx Outdated
<p className="text-sm text-[#404040] break-words">{reason}</p>
<div className="flex gap-2">
<button onClick={onClose} className="flex-1 px-3 py-2 rounded-md border border-[#E5E5E0] text-sm font-medium text-[#171717]">Close</button>
<button onClick={onClose} className="flex-1 px-3 py-2 rounded-md bg-[#FF6B35] text-white text-sm font-medium">Upgrade to {recommendedTier}</button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Wire the upgrade CTA to an actual upgrade action.

The button is labeled “Upgrade” but only calls onClose, so users cannot start an upgrade flow. Add an onUpgrade callback or upgrade destination and update MockInterview.tsx:341-348 accordingly.

🤖 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 `@src/components/interview-lab/UpgradeModal.tsx` at line 23, Update the upgrade
CTA in UpgradeModal to invoke an actual upgrade action instead of only onClose,
using an onUpgrade callback or upgrade destination. Pass and wire that action
from the modal usage in MockInterview so clicking “Upgrade to {recommendedTier}”
starts the upgrade flow while preserving the existing close behavior as
appropriate.

- CI: pin Bun to 1.3.4 and use --frozen-lockfile for reproducible builds
- UpgradeModal: refactor to Radix Dialog for proper a11y (role, aria-modal, focus trap, Escape)
- Use feature/currentTier props in rendered content
- Add optional onUpgrade callback prop
Copilot AI review requested due to automatic review settings July 20, 2026 21:57

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

When the AI provider is unavailable (missing key / outage), the centralized
AI handler returned HTTP 500, failing the CI integration tests
(user-paths.test.ts: resume-review and cover-letter). Add an optional
onProviderError hook to AIHandlerConfig (mirroring onParseFailure) and wire
deterministic, clearly-labeled fallbacks into the resume, cover-letter,
coach, and assessment configs. Also fix the stale resume-review assertion
(improvedVersion -> improvedSummary), which the API never returned.

This makes AI outages degrade to a 200 with a 'service unavailable' message
instead of crashing, and turns the pre-existing red audit job green.

@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

🧹 Nitpick comments (1)
__tests__/api/user-paths.test.ts (1)

151-151: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Add coverage for provider-error fallbacks.

This assertion correctly matches the API contract, but it only validates the renamed field. Add route tests that simulate provider failures and verify the expected HTTP 200 fallback payloads for the affected AI flows.

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

In `@__tests__/api/user-paths.test.ts` at line 151, Add route-level tests in the
affected AI flow cases alongside the improvedSummary assertion to simulate
provider failures, then verify each request returns HTTP 200 and the documented
fallback payload. Preserve the existing renamed-field assertion while covering
every affected provider-error path.
🤖 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 `@src/lib/ai/coach.ts`:
- Around line 125-126: Update the onProviderError callback to return a dedicated
provider-unavailable coaching result instead of errorFeedback(). Include an
explicit truthfulness/availability warning and omit any score so unavailable AI
responses cannot be rendered as genuine evaluations.

In `@src/lib/ai/handlers.ts`:
- Around line 101-107: Restrict the provider-error handling around the handler
flow so only exceptions from the provider call completeJson are passed to
config.onProviderError. Keep buildUserPrompt, onParseFailure, and normalize
failures outside that catch, allowing them to propagate with their existing
error behavior rather than returning a fallback response or HTTP 200.

---

Nitpick comments:
In `@__tests__/api/user-paths.test.ts`:
- Line 151: Add route-level tests in the affected AI flow cases alongside the
improvedSummary assertion to simulate provider failures, then verify each
request returns HTTP 200 and the documented fallback payload. Preserve the
existing renamed-field assertion while covering every affected provider-error
path.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 79a3c587-c5d0-47a3-a0e6-1d10327ae662

📥 Commits

Reviewing files that changed from the base of the PR and between 91e1919 and 78d0fd7.

📒 Files selected for processing (6)
  • __tests__/api/user-paths.test.ts
  • src/lib/ai/assessment.ts
  • src/lib/ai/coach.ts
  • src/lib/ai/cover-letter.ts
  • src/lib/ai/handlers.ts
  • src/lib/ai/resume.ts

Comment thread src/lib/ai/coach.ts
Comment on lines +125 to +126
// Graceful degradation when the AI provider is unavailable (missing key, outage).
onProviderError: () => ({ ok: true, value: errorFeedback() }),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Return an explicit provider-unavailable coaching result.

errorFeedback() returns score: 5 and normal coaching text, so the HTTP 200 response can be rendered as a genuine evaluation even when no AI response exists. Use a dedicated unavailable result with an explicit truthfulness/availability warning and no misleading score.

🤖 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 `@src/lib/ai/coach.ts` around lines 125 - 126, Update the onProviderError
callback to return a dedicated provider-unavailable coaching result instead of
errorFeedback(). Include an explicit truthfulness/availability warning and omit
any score so unavailable AI responses cannot be rendered as genuine evaluations.

Source: Coding guidelines

Comment thread src/lib/ai/handlers.ts
Comment on lines +101 to +107
if (config.onProviderError) {
const fallback = config.onProviderError(body);
if (fallback.ok) {
return NextResponse.json(fallback.value);
}
return NextResponse.json({ error: fallback.error }, { status: fallback.status });
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not classify every handler exception as a provider outage.

This catch also covers errors from buildUserPrompt, onParseFailure, and normalize, not only completeJson. A bug in any of those paths will now return a successful fallback with HTTP 200, hiding the real failure from clients and monitoring. Narrow the try/catch to the provider call or classify the caught error before invoking onProviderError.

🤖 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 `@src/lib/ai/handlers.ts` around lines 101 - 107, Restrict the provider-error
handling around the handler flow so only exceptions from the provider call
completeJson are passed to config.onProviderError. Keep buildUserPrompt,
onParseFailure, and normalize failures outside that catch, allowing them to
propagate with their existing error behavior rather than returning a fallback
response or HTTP 200.

@projectamazonph
projectamazonph merged commit c7e9a07 into main Jul 20, 2026
4 checks passed
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.

2 participants