Skip to content

fix(it3): address CodeRabbit review — double-submit guard, bounded loop, type annotation#72

Merged
EmiyaKiritsugu3 merged 3 commits into
mainfrom
fix/coderabbit-it3-followup
Apr 19, 2026
Merged

fix(it3): address CodeRabbit review — double-submit guard, bounded loop, type annotation#72
EmiyaKiritsugu3 merged 3 commits into
mainfrom
fix/coderabbit-it3-followup

Conversation

@EmiyaKiritsugu3

@EmiyaKiritsugu3 EmiyaKiritsugu3 commented Apr 19, 2026

Copy link
Copy Markdown
Owner

Summary

  • WorkoutSession.tsx: add isFinishing guard to handleFinalizarTreino; button disabled while in-flight to prevent duplicate saves/XP on rapid clicks (CodeRabbit critical)
  • workout-session.spec.ts: scope iniciarButton to 'Treino E2E' row via .filter(); add MAX_EXERCISES=20 guard to while loop for deterministic failure on regression
  • workout-feedback-flow.test.ts: type-annotate fallback shape as WorkoutFeedbackOutput so compiler validates the contract
  • CHANGELOG.md: consolidate dois [Unreleased] sections into one
  • CURRENT-STATE.md: fix version header inconsistency

Test plan

  • npm run typecheck → 0 errors
  • npm run lint → 0 errors
  • npm test → 22/22 passing
  • E2E CI runs green with scoped treinoRow locator

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • The "Finalizar Treino" flow now prevents duplicate completions (button disabled while finishing) to avoid double-saves/XP.
  • Tests

    • E2E tests made deterministic: workout row selection scoped, a max-step guard added to avoid infinite loops, and a feedback contract explicitly typed.
  • Documentation

    • Release/version and CI status updated; topmost Unreleased entry date updated and an Unreleased observability note removed.
  • Chores

    • Added project review/configuration settings for automated code review.

…op, type annotation

- WorkoutSession.tsx: add isFinishing guard to handleFinalizarTreino; button
  disabled while in-flight to prevent duplicate saves/XP on rapid clicks
- workout-session.spec.ts: scope iniciarButton to 'Treino E2E' row via filter;
  add MAX_EXERCISES=20 guard to while loop for deterministic failure on regression
- workout-feedback-flow.test.ts: type-annotate fallback shape as WorkoutFeedbackOutput
- CHANGELOG.md: consolidate two [Unreleased] sections into one
- CURRENT-STATE.md: fix version header to reflect completed state

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

vercel Bot commented Apr 19, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
smartmanagementsystem Ready Ready Preview, Comment Apr 19, 2026 2:32am

@coderabbitai

coderabbitai Bot commented Apr 19, 2026

Copy link
Copy Markdown

Warning

.coderabbit.yaml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
Validation error: Invalid enum value. Expected 'de' | 'de-DE' | 'de-AT' | 'de-CH' | 'en' | 'en-US' | 'en-AU' | 'en-GB' | 'en-CA' | 'en-NZ' | 'en-ZA' | 'es' | 'es-AR' | 'fr' | 'fr-CA' | 'fr-CH' | 'fr-BE' | 'nl' | 'nl-BE' | 'pt-AO' | 'pt' | 'pt-BR' | 'pt-MZ' | 'pt-PT' | 'ar' | 'ast-ES' | 'ast' | 'be-BY' | 'be' | 'br-FR' | 'br' | 'ca-ES' | 'ca' | 'ca-ES-valencia' | 'ca-ES-balear' | 'da-DK' | 'da' | 'de-DE-x-simple-language' | 'el-GR' | 'el' | 'eo' | 'fa' | 'ga-IE' | 'ga' | 'gl-ES' | 'gl' | 'it' | 'ja-JP' | 'ja' | 'km-KH' | 'km' | 'ko-KR' | 'ko' | 'pl-PL' | 'pl' | 'ro-RO' | 'ro' | 'ru-RU' | 'ru' | 'sk-SK' | 'sk' | 'sl-SI' | 'sl' | 'sv' | 'ta-IN' | 'ta' | 'tl-PH' | 'tl' | 'tr' | 'uk-UA' | 'uk' | 'zh-CN' | 'zh' | 'crh-UA' | 'crh' | 'cs-CZ' | 'cs' | 'nb' | 'no' | 'nl-NL' | 'de-DE-x-simple-language-DE' | 'es-ES' | 'it-IT' | 'fa-IR' | 'sv-SE' | 'de-LU' | 'fr-FR' | 'bg-BG' | 'bg' | 'he-IL' | 'he' | 'hi-IN' | 'hi' | 'vi-VN' | 'vi' | 'th-TH' | 'th' | 'bn-BD' | 'bn', received 'typescript' at "code_generation.docstrings.language"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 67762e41-ce20-4dd4-9145-d0d1cf7aa3f3

📥 Commits

Reviewing files that changed from the base of the PR and between 19788fe and 02ce627.

📒 Files selected for processing (1)
  • .coderabbit.yaml
✅ Files skipped from review due to trivial changes (1)
  • .coderabbit.yaml

📝 Walkthrough

Walkthrough

Replaced the topmost Unreleased changelog header and date, removed the Unreleased Sentry production wiring entry, updated CURRENT-STATE to v0.6.0/main, added an isFinishing guard and disabled button in the workout finish flow, tightened an E2E selector with a MAX_EXERCISES guard, added a type annotation to a workout feedback test fallback, and added a new .coderabbit.yaml config.

Changes

Cohort / File(s) Summary
Changelog & Docs
CHANGELOG.md, docs/CURRENT-STATE.md
Replaced Unreleased heading/date; removed Unreleased Sentry production wiring section; updated branch/version to main (v0.6.0 tagged) and CI/E2E status.
Workout Session UI
src/components/WorkoutSession.tsx
Added isFinishing state; handleFinalizarTreino short-circuits when finishing, sets/resets isFinishing, and disables the "Finalizar Treino" button while in-flight.
E2E Tests
tests/e2e/specs/workout-session.spec.ts
Scoped iniciar button selection to the div.rounded-lg row containing Treino E2E; added MAX_EXERCISES = 20 loop guard and error on exceeding it.
Test Type Safety
src/ai/flows/workout-feedback-flow.test.ts
Added a type-only import WorkoutFeedbackOutput and annotated the fallback fixture to enforce the expected contract at compile time.
Tooling Config
.coderabbit.yaml
Added repository configuration: language en-US, auto-review mode enabled (drafts disabled), review profile defaults and TypeScript docstring generation disabled.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I bounced through changelogs and tests tonight,
Guarded the finish with a soft, fluffy bite,
Scoped the buttons, capped the loop's spree,
Typed the fallback for certainty,
Hoppity—v0.6.0 lands just right! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main changes: adding a double-submit guard, implementing a bounded loop, and adding type annotation—all key fixes from the CodeRabbit review.
Description check ✅ Passed The description covers all required template sections: a clear summary of changes, proper categorization as a 'fix', and a test plan checklist aligned with the repository standards.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/coderabbit-it3-followup

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

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/WorkoutSession.tsx (1)

135-172: ⚠️ Potential issue | 🟠 Major

isFinishing can remain stuck if onFinish fails.

onFinish (Line 152) is outside the current try/finally, so a thrown/rejected call skips Line 171 and leaves the UI permanently locked in this session.

Proposed fix
   const handleFinalizarTreino = async () => {
     if (isFinishing) return;
     setIsFinishing(true);
-    const endTime = new Date();
-    const duracaoMinutos = Math.round((endTime.getTime() - startTime.getTime()) / 60000);
-
-    const historico: Omit<HistoricoTreino, 'id' | 'alunoId'> = {
-      treinoId: treino.id,
-      dataExecucao: startTime.toISOString(),
-      duracaoMinutos,
-      exercicios: exerciciosEmSessao.map((ex) => ({
-        exercicioId: ex.exercicioOriginal.id,
-        nomeExercicio: ex.exercicioOriginal.nomeExercicio,
-        seriesExecutadas: ex.seriesExecutadas,
-      })),
-    };
-
-    await onFinish(historico);
-    setCompleted(true);
-
-    const completedExercises = exerciciosEmSessao
-      .filter((ex) => ex.seriesExecutadas.some((s) => s.concluido))
-      .map((ex) => ex.exercicioOriginal.nomeExercicio);
-
-    setIsLoadingFeedback(true);
     try {
+      const endTime = new Date();
+      const duracaoMinutos = Math.round((endTime.getTime() - startTime.getTime()) / 60000);
+
+      const historico: Omit<HistoricoTreino, 'id' | 'alunoId'> = {
+        treinoId: treino.id,
+        dataExecucao: startTime.toISOString(),
+        duracaoMinutos,
+        exercicios: exerciciosEmSessao.map((ex) => ({
+          exercicioId: ex.exercicioOriginal.id,
+          nomeExercicio: ex.exercicioOriginal.nomeExercicio,
+          seriesExecutadas: ex.seriesExecutadas,
+        })),
+      };
+
+      await onFinish(historico);
+      setCompleted(true);
+
+      const completedExercises = exerciciosEmSessao
+        .filter((ex) => ex.seriesExecutadas.some((s) => s.concluido))
+        .map((ex) => ex.exercicioOriginal.nomeExercicio);
+
+      setIsLoadingFeedback(true);
+      try {
         const result = await generateWorkoutFeedback({
           goal: treino.objetivo,
           completedExercises,
           totalExercises: exerciciosEmSessao.length,
         });
         setFeedback(result);
-    } catch {
-      setFeedback({ title: 'Treino Concluído!', message: 'Continue assim!' });
-    } finally {
-      setIsLoadingFeedback(false);
+      } catch {
+        setFeedback({ title: 'Treino Concluído!', message: 'Continue assim!' });
+      } finally {
+        setIsLoadingFeedback(false);
+      }
+    } finally {
       setIsFinishing(false);
     }
   };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/WorkoutSession.tsx` around lines 135 - 172, The onFinish call
inside handleFinalizarTreino can throw and leave isFinishing true; wrap the
await onFinish(...) so setIsFinishing(false) always runs (e.g., move onFinish
into a try/catch/finally or add a surrounding try/finally) and only call
setCompleted(true) and start the feedback flow (setIsLoadingFeedback and
generateWorkoutFeedback) after onFinish succeeds; ensure any error from onFinish
is handled (log or set fallback state) so the UI is never permanently locked by
isFinishing remaining true.
🧹 Nitpick comments (1)
CHANGELOG.md (1)

8-8: Consider fully normalizing to a single [Unreleased] section.

This header cleanup is good, but there are still multiple later [Unreleased] blocks. Converting older ones to versioned entries (or merging intentfully) will keep release history clearer.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CHANGELOG.md` at line 8, The changelog contains multiple "[Unreleased]"
headings; keep a single canonical "[Unreleased]" section (the one at the top)
and locate any other occurrences of the marker ("[Unreleased]") elsewhere in
CHANGELOG.md, then either convert those later "[Unreleased]" blocks into proper
versioned entries with their release version/date or merge their contents into
the single top "[Unreleased]" section so history remains consistent and
unambiguous.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/CURRENT-STATE.md`:
- Line 5: The document's high-level status line "Version: 0.6.0 (It3 complete —
all quality gates green, 17/17 E2E passing)" is inconsistent with later lines
that state CI/merge is pending; update the file so all status statements match:
either change the header status to indicate CI/merge is pending or update the
later lines (the lines referencing CI/merge pending) to reflect completion,
ensuring the phrases "It3 complete", "all quality gates green", and "CI/merge
pending" are reconciled across the file so the document presents one clear,
consistent state.

---

Outside diff comments:
In `@src/components/WorkoutSession.tsx`:
- Around line 135-172: The onFinish call inside handleFinalizarTreino can throw
and leave isFinishing true; wrap the await onFinish(...) so
setIsFinishing(false) always runs (e.g., move onFinish into a try/catch/finally
or add a surrounding try/finally) and only call setCompleted(true) and start the
feedback flow (setIsLoadingFeedback and generateWorkoutFeedback) after onFinish
succeeds; ensure any error from onFinish is handled (log or set fallback state)
so the UI is never permanently locked by isFinishing remaining true.

---

Nitpick comments:
In `@CHANGELOG.md`:
- Line 8: The changelog contains multiple "[Unreleased]" headings; keep a single
canonical "[Unreleased]" section (the one at the top) and locate any other
occurrences of the marker ("[Unreleased]") elsewhere in CHANGELOG.md, then
either convert those later "[Unreleased]" blocks into proper versioned entries
with their release version/date or merge their contents into the single top
"[Unreleased]" section so history remains consistent and unambiguous.
🪄 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

Run ID: b92ba349-950d-42e2-8971-d50ecf29df41

📥 Commits

Reviewing files that changed from the base of the PR and between eedbf82 and f1f511f.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • docs/CURRENT-STATE.md
  • src/ai/flows/workout-feedback-flow.test.ts
  • src/components/WorkoutSession.tsx
  • tests/e2e/specs/workout-session.spec.ts

Comment thread docs/CURRENT-STATE.md Outdated
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…peScript

TypeScript types serve as documentation; JSDoc coverage metrics are
Python-specific and not applicable to this Next.js/React codebase.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@EmiyaKiritsugu3 EmiyaKiritsugu3 merged commit a0a8236 into main Apr 19, 2026
10 checks passed
@EmiyaKiritsugu3 EmiyaKiritsugu3 deleted the fix/coderabbit-it3-followup branch April 19, 2026 02:50
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