# Fresh frontend code review

Status: DONE

## Result

**VERDICT: NEEDS CHANGES.** The participant/day storage boundaries, video-type validation, local-only labels, checkout state wording, and canvas interaction are broadly sound. Three medium defects let a review flow claim an expert response without its prerequisite, derive consent eligibility from page navigation, or claim a local change after storage failed.

## Issues

- **[severity: medium] Correctness and source-flow alignment** — [`site/app/app.js:93`](/Users/agency/Documents/Agty/KomplexLogopédia/outputs/rita-journey-20261002/site/app/app.js:93) renders the Rita editor whether or not `r.submitted` is true, and [`site/app/app.js:99-102`](/Users/agency/Documents/Agty/KomplexLogopédia/outputs/rita-journey-20261002/site/app/app.js:99) only require non-empty text. A fresh `rita-01.html` can therefore mark feedback sent while its own status says “Mintaadat, még nincs beküldés”; `day-01.html` then shows it as participant feedback. This makes the day/send/readback state machine contradict its stated video-review prerequisite. Disable or replace the editor until `r.submitted` is true, and have the send handler defensively reject a non-submitted record as well. If direct exploration is needed, keep the existing sample feedback visible but do not persist it as a participant readback.

- **[severity: medium] Correctness and consent eligibility** — [`site/flow/flow.js:33`](/Users/agency/Documents/Agty/KomplexLogopédia/outputs/rita-journey-20261002/site/flow/flow.js:33) sets `state.feedbackAvailable=true` whenever `free-feedback.html` renders. Direct navigation, with no local video selection or simulated submission, consequently makes the consent page say that a sample response arrived. The integration check only exercises the normal submission path, so it misses this bypass. Model receipt as a separate local transition that requires `freeSubmission?.simulated`, or derive eligibility from that state and an explicit “sample response received” action. Do not mutate eligibility merely by displaying a page.

- **[severity: medium] Error handling and truthful local state** — [`site/app/app.js:62`](/Users/agency/Documents/Agty/KomplexLogopédia/outputs/rita-journey-20261002/site/app/app.js:62), [`site/app/app.js:87`](/Users/agency/Documents/Agty/KomplexLogopédia/outputs/rita-journey-20261002/site/app/app.js:87), and [`site/app/app.js:88`](/Users/agency/Documents/Agty/KomplexLogopédia/outputs/rita-journey-20261002/site/app/app.js:88) ignore `saveState()` for fixture selection and removal. Under a quota/storage failure, removal deletes the IndexedDB video and reports success in the current UI, while a reload restores the old `videoMeta` from localStorage. Fixture selection has the symmetric misleading persistence claim. Check the return value on every state-changing branch, retain or explicitly mark any in-memory-only result, and show the existing storage-failure wording rather than a success message. Add these fixture/remove paths to the failure simulation already used for normal file selection and reflections.

## Deliverables and checks

| Deliverable | Requirement or verification | Result | Evidence |
|---|---|---|---|
| [`site/app/app.js`](/Users/agency/Documents/Agty/KomplexLogopédia/outputs/rita-journey-20261002/site/app/app.js:1) | Participant/day isolation, local draft/send/readback, video handling and storage failures | NEEDS CHANGES | `sample-b` has separate record, initial and consultation scopes plus IndexedDB keys. Direct Rita send bypasses the submission prerequisite; unhandled fixture/remove persistence failures remain. |
| [`site/flow/flow.js`](/Users/agency/Documents/Agty/KomplexLogopédia/outputs/rita-journey-20261002/site/flow/flow.js:1) | Local draft state, consent eligibility, unsupported video and checkout honesty | NEEDS CHANGES | Unsupported/zero-duration selections are rejected and checkout is explicitly simulated. Direct `free-feedback.html` visit changes eligibility state. |
| [`site/canvas.js`](/Users/agency/Documents/Agty/KomplexLogopédia/outputs/rita-journey-20261002/site/canvas.js:1) and [`site/canvas.css`](/Users/agency/Documents/Agty/KomplexLogopédia/outputs/rita-journey-20261002/site/canvas.css:1) | Canvas controls, review interaction and 390px frames | PASS | Mounting, zoom, panning, A/B inspector, review pointer suppression and 390px iframe sizing are internally consistent. |
| [`site/app/lessons.json`](/Users/agency/Documents/Agty/KomplexLogopédia/outputs/rita-journey-20261002/site/app/lessons.json:1) | Task data alignment and schema sanity | PASS | Valid JSON, 14 ordered days, six module keys and non-empty focus arrays. |
| Scoped source syntax | JavaScript and JSON parse | PASS | `node --check` passed for `canvas.js`, `flow.js`, and `app.js`; `jq empty` passed for `lessons.json`. |
| Headless state probes | Reproduce prerequisite, eligibility and failure-mode defects | PASS | Fresh profiles confirmed the three issues described above. Existing automated journeys cover normal loops and participant switching, but not these direct/broken prerequisite branches. |

## Limits or consequential decisions

This was a read-only review. No source files, state, deployment, or hosted artifacts were changed. The three findings are confined to prototype-state truthfulness, not real authentication, uploads, payments, messages, or booking.
