You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-**US06 — AI Workout Feedback** (`src/components/WorkoutSession.tsx`): after completing a workout, the component calls `generateWorkoutFeedback` (Genkit + Gemini 2.5 Flash) inside a `try/catch`. On success, renders a feedback card (`data-testid="workout-feedback-card"`) with an AI-generated title and motivational message. On failure, falls back to `{ title: 'Treino Concluído!', message: 'Continue assim!' }`. The workout save (`onFinish`) is not gated on AI availability — Constitution Principle IV satisfied.
13
+
-**E2E: workout session completion** (`tests/e2e/specs/workout-session.spec.ts`): ALUNO logs in, starts the seeded "Treino E2E", marks series done, clicks "Finalizar Treino", waits for `[data-testid="workout-feedback-card"]`, then navigates to `/aluno/dashboard` and asserts `[data-testid="xp-display"]` is visible.
14
+
-**E2E: student enrollment** (`tests/e2e/specs/enrollment.spec.ts`): GERENTE opens the enrollment dialog, fills name/email/CPF (timestamp-based to avoid unique constraint collisions), submits, and asserts the new aluno appears in the list.
15
+
-**Unit tests** (`src/ai/flows/workout-feedback-flow.test.ts`): 4 tests covering AI feedback resolution, rejection propagation, empty-exercise fallback, and the fallback shape contract. 22/22 unit tests passing.
16
+
-**Seed extension** (`prisma/seed-e2e.ts`): seeded 1 `Treino` record (`id: 00000000-0000-0000-0000-000000000010`) with 2 `Exercicio` rows (Supino Reto 3×10-12, Crucifixo 3×12-15) linked to the ALUNO + INSTRUTOR fixed UUIDs.
17
+
-**`data-testid="xp-display"`**: added to XP paragraph in `dashboard-client.tsx` for stable E2E assertion.
18
+
-**`CRITICAL-PATHS.md`**: updated from 15 → 17 covered scenarios; moved "Workout session completion" and "Student enrollment flow" from Pending to Coverage Table.
19
+
20
+
### Fixed
21
+
22
+
-**`meus-treinos-client.tsx`**: removed `setTreinoEmSessao(null)` from `handleFinishWorkout` — it was unmounting `WorkoutSession` before the feedback screen could render. Session now stays mounted until the user clicks "Fechar Treino" (`onCancel`).
23
+
-**`seed-e2e.ts` CWE-798**: removed hardcoded `postgresql://postgres:postgres@...` fallback; replaced with explicit `if (!process.env.DATABASE_URL) throw new Error(...)` guard.
24
+
-**E2E strict mode** (`student-portal.spec.ts`): `getByRole('heading')` now targets `{ name: 'Meus Treinos' }` — the seed treino added a second `<h3>` heading, breaking the previously unambiguous selector.
25
+
-**E2E Tailwind selector** (`workout-session.spec.ts`): `.grid .grid-cols-4 button` (space = descendant) replaced with `div.grid-cols-4 button` — Tailwind applies both `grid` and `grid-cols-4` to the **same** element, so the descendant combinator never matched.
26
+
-**E2E dialog scoping** (`enrollment.spec.ts`): submit button now scoped to `page.getByRole('dialog')` to avoid fragile `.last()` ordering among all matching buttons on the page.
27
+
28
+
---
29
+
30
+
## [Unreleased] — 2026-04-18 — Observability: Sentry Production Wiring
31
+
32
+
### Added
33
+
34
+
-**`NEXT_PUBLIC_SENTRY_DSN`**: configured in Vercel Production via CLI — Sentry error tracking now active in production.
35
+
-**`SENTRY_AUTH_TOKEN`**: configured in Vercel Production — source maps (92 files) uploaded on every build, enabling readable stack traces in Sentry.
| Tailwind multi-class elements |`.grid .grid-cols-4 button`|`div.grid-cols-4 button`| Tailwind puts both classes on the **same** element — space selector requires nesting |
132
+
| Playwright strict mode |`getByRole('heading')`|`getByRole('heading', { name: 'X' })`| Adding seed data can create new headings, breaking previously unambiguous selectors |
133
+
| Dialog scoping |`page.getByRole('button', ...).last()`|`page.getByRole('dialog').getByRole('button', ...)`| Dialog renders after page buttons — scope to dialog to avoid fragile `.last()` ordering |
134
+
|`onFinish` vs `onCancel` separation | Call `setTreinoEmSessao(null)` in `onFinish`| Call it only in `onCancel`| Closing the session in `onFinish` unmounts the component before feedback state can render |
135
+
| CPF uniqueness in E2E | Hard-coded CPF |`timestamp`-derived CPF | Unique constraints fail on re-runs if the same CPF is always used |
136
+
111
137
## Update Protocol
112
138
113
139
Update this file at the start of every AI session and after every major phase completion.
0 commit comments