Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
0319ca5
docs: design Together flow improvements
cursoragent Sep 8, 2026
d4224d1
docs: plan Together flow improvements
cursoragent Sep 8, 2026
c686190
test(together): define four-person room behavior
cursoragent Sep 8, 2026
ccadad3
test(together): cover concurrent room joins
cursoragent Sep 8, 2026
b1c8dfd
feat(together): support rooms of up to four
cursoragent Sep 8, 2026
072b9c4
chore(together): satisfy checks for capacity changes
cursoragent Sep 8, 2026
cde7836
test(together): require atomic room host creation
cursoragent Sep 8, 2026
a01f222
fix(together): create rooms with hosts atomically
cursoragent Sep 8, 2026
ab96dcb
feat(together): share locale-neutral invite links
cursoragent Sep 8, 2026
bcd35de
style(together): format invite helpers
cursoragent Sep 8, 2026
b302405
fix(together): reject invalid locale quality values
cursoragent Sep 8, 2026
e9a9205
style(together): format locale regression
cursoragent Sep 8, 2026
2cfdb9a
docs: assign provider copy to setup task
cursoragent Sep 8, 2026
24925c4
test(together): cover provider setup and deck filters
cursoragent Sep 8, 2026
a5cc10d
feat(together): filter choices by host providers
cursoragent Sep 8, 2026
f1c9c26
style(together): format provider flow tests
cursoragent Sep 8, 2026
5b2a8f8
docs: report Together provider flow task
cursoragent Sep 8, 2026
3f86a06
test(together): cover provider reset on region change
cursoragent Sep 8, 2026
3941025
fix(together): clear providers when region changes
cursoragent Sep 8, 2026
ed3265c
docs: record provider region review fix
cursoragent Sep 8, 2026
30191f5
docs: assign match copy to celebration task
cursoragent Sep 8, 2026
c2caeeb
feat(together): celebrate matches while discovering
cursoragent Sep 8, 2026
5799e38
test(together): type stable match key fixture
cursoragent Sep 8, 2026
90ccc15
fix(together): normalize polled match interest
cursoragent Sep 8, 2026
e31329c
docs: report Together match celebration task
cursoragent Sep 8, 2026
5b95494
fix(together): harden live match celebrations
cursoragent Sep 8, 2026
d314df8
docs: record Task 4 review fixes
cursoragent Sep 8, 2026
6de3dc2
feat(together): guide guests and show room capacity
cursoragent Sep 8, 2026
9c5c266
fix(together): satisfy capacity verification
cursoragent Sep 8, 2026
840d48f
docs: report Together guest capacity task
cursoragent Sep 8, 2026
5fe449a
fix(auth): validate localized sign-in redirects
cursoragent Sep 8, 2026
e382026
fix(together): hydrate member token before room query
cursoragent Sep 8, 2026
a4589c1
fix(together): localize concurrent room capacity errors
cursoragent Sep 8, 2026
3ca13fe
fix(auth): enforce redirect safety at sign-in action
cursoragent Sep 8, 2026
c2bdb4d
fix(auth): preserve sign-up locale redirect
cursoragent Sep 8, 2026
920ccec
chore(web): restore generated typecheck cache
cursoragent Sep 8, 2026
55247ed
fix(auth): preserve sign-up checkout continuation
cursoragent Sep 8, 2026
3c9400c
docs: record Task 5 blocking review fixes
cursoragent Sep 8, 2026
ccb56a6
fix(auth): preserve checkout through onboarding check
cursoragent Sep 8, 2026
100397a
docs: record checkout onboarding blocker fix
cursoragent Sep 8, 2026
2833523
test(together): cover final review regressions
cursoragent Sep 8, 2026
413cb7f
fix(together): aggregate matches by media identity
cursoragent Sep 8, 2026
e8c9b1f
fix(together): expose consistent match metadata
cursoragent Sep 8, 2026
58323c0
fix(together): make group setup neutral and accessible
cursoragent Sep 8, 2026
558687d
feat(together): show localized match posters
cursoragent Sep 8, 2026
53452f6
fix(together): label selected providers clearly
cursoragent Sep 8, 2026
90a4166
style(together): format final review fixes
cursoragent Sep 8, 2026
1eaeb15
test(together): clarify localized match metadata
cursoragent Sep 8, 2026
033d708
docs: record Together final review fixes
cursoragent Sep 8, 2026
949ca96
test(together): cover final hardening cases
cursoragent Sep 8, 2026
6880d95
fix(together): select metadata from one swipe
cursoragent Sep 8, 2026
4b53f16
fix(together): focus provider heading only on return
cursoragent Sep 8, 2026
d327846
docs: record Together hardening verification
cursoragent Sep 8, 2026
fb4679c
fix(together): hide expanded room capacity
cursoragent Sep 8, 2026
af0470b
style(together): format capacity tests
cursoragent Sep 8, 2026
fb6d556
fix(together): use count-neutral room labels
cursoragent Sep 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 189 additions & 0 deletions .superpowers/sdd/final-fix-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
# Together PR #519 final-fix report

## Status

All seven final review findings are fixed on
`cursor/together-flow-improvements-08b6` and pushed.

## Changes

1. Match aggregation now groups only by `tmdbId` and `mediaType`. PostgreSQL
`min` aggregates select every metadata field deterministically, while
like, maybe, and distinct-interest counts retain their existing ordering.
Direct swipe matches use the same aggregate query as polled matches and
expose the same metadata/count contract.
2. Provider load failures retain Retry, explicit Any service, and Continue.
3. Together copy and rendered UI are group-neutral for 2–4 participants in
all seven locales. Waiting and voting headings use neutral group copy and
participant counts rather than the first two names.
4. Match celebrations render the TMDB poster with `next/image`, or the
existing `PosterFallback` when no poster exists.
5. Provider/name step transitions focus their focusable headings. Selected
providers and Any service show a visible Check indicator, localized
screen-reader text, and retain `aria-pressed`.
6. Proxy integration tests exercise locale-less path/query redirect
preservation and already-localized pass-through.
7. Shared `DialogContent` accepts an optional `closeLabel`, defaults to
`Close`, and MatchCelebration supplies localized Together copy.

No dependency was added.

## TDD evidence

The regression commit was run before implementation:

- Backend mixed-locale regression failed because polling returned zero
matches and direct counts did not distinguish LIKE from MAYBE.
- Web regressions failed for absent poster/fallback and localized close
behavior, missing heading focus, provider failure controls/selection
indicator, pair-specific headings, participant-count voting copy, and
missing dictionary keys.
- The new proxy integration tests passed immediately because current proxy
behavior already preserves the path/query and passes localized requests;
they replace the previous parser-only coverage gap with integration
protection.

After implementation, every focused regression passed. A follow-up test run
found concatenated accessible text (`NetflixSelected`); explicit localized
`aria-label` values corrected it to `Netflix, Selected`.

## Final verification

```text
Backend Together services:
pnpm --filter plotwist-api test --run src/domain/services/together
4 files passed, 20 tests passed

Web Together/auth/locale/dictionary:
pnpm --filter web test --run \
'src/app/[lang]/together/_components' \
src/services/together-invite.test.ts \
src/actions/auth \
src/utils/auth-redirect.test.ts \
'src/app/[lang]/sign-in' \
src/lib/request-locale.test.ts \
src/proxy.test.ts \
src/utils/dictionaries/get-dictionaries.test.ts
19 files passed, 95 tests passed

Backend build:
pnpm --filter plotwist-api run build
ESM, CJS, and DTS builds passed

Web typecheck:
pnpm --filter web run typecheck
passed

Changed-file Biome:
58 files checked, no fixes required
```

`apps/web/tsconfig.tsbuildinfo` was restored after typechecking.

## Commits

- `28335232` — `test(together): cover final review regressions`
- `413cb7fd` — `fix(together): aggregate matches by media identity`
- `e8c9b1ff` — `fix(together): expose consistent match metadata`
- `58323c0c` — `fix(together): make group setup neutral and accessible`
- `558687d4` — `feat(together): show localized match posters`
- `53452f60` — `fix(together): label selected providers clearly`
- `90a41661` — `style(together): format final review fixes`
- `1eaeb158` — `test(together): clarify localized match metadata`

## Concerns

- The repository declares Node 23+, while this environment runs Node
22.14.0. Every requested command passed despite the existing engine
warning.
- All seven locale dictionaries satisfy the structural contract and no
pair-specific Together terms remain in the audited copy. Native-speaker
review is still advisable for editorial nuance.

---

## Hardening follow-up (three desired fixes)

Inspected `HEAD` `4b53f169` on `cursor/together-flow-improvements-08b6`.
The three requested hardening items were already implemented and pushed
by earlier commits on this branch (`949ca969`, `6880d95b`, `4b53f169`).
This pass re-verified those commits against the review text, ran the
requested suites, and recorded evidence. No additional production change
was required.

### 1) Match metadata from one representative swipe

`selectTogetherMatchesWhere` no longer uses independent `min()` on each
display field. Every metadata column is taken from
`(array_agg(column ORDER BY title, id))[1]`, so title, poster, vote,
release date, and overview come from the same swipe row. Match list
order is LIKE count, then MAYBE count, then `mediaType`, then `tmdbId`.

Real Postgres fixtures in `create-swipe.spec.ts`:

- Mixed-locale Dune/Duna swipes assert every metadata field stays on
the title-ordered representative row (`Duna` / `/zulu.jpg` / `9.1` /
`2030-01-01` / Portuguese overview), not a mix of `min()` values.
- Three equal LIKE matches assert stable order
`MOVIE/10`, `MOVIE/20`, `TV_SHOW/1`.

### 2) Provider heading focus

`TogetherProviderStep` focuses its heading only when `focusHeading` is
true. `CreateInviteForm` keeps that flag false on first paint so the
guest prompt stays first in tab order, focuses the name heading on the
name step, and sets the flag only when leaving providers so Back
returns focus to the provider heading.

Regression tests:

- Initial render: `document.activeElement` stays `document.body`.
- Name step focuses `Create your invite`, not the name input.
- Back sets `focusHeading` true; provider heading receives focus.

### 3) Provider outage harness

`ControlledProviderHarness` owns `providerIds` in React state. The
outage test rejects the first provider list, clicks Retry, asserts the
query refetches (`list` called twice) and Netflix is selected again,
then clicks Any service and Continue and asserts `onContinue([])`.

### Hardening verification

```text
Backend Together services:
pnpm --filter plotwist-api test --run src/domain/services/together
4 files passed, 21 tests passed

Web Together components:
pnpm --filter web test --run 'src/app/[lang]/together/_components'
10 files passed, 47 tests passed

Backend build:
pnpm --filter plotwist-api run build
ESM, CJS, and DTS builds passed

Web typecheck:
pnpm --filter web run typecheck
passed

Changed-file Biome:
7 files checked, no fixes applied
```

`apps/web/tsconfig.tsbuildinfo` was restored after typechecking.

### Hardening commits

- `949ca969` — `test(together): cover final hardening cases`
- `6880d95b` — `fix(together): select metadata from one swipe`
- `4b53f169` — `fix(together): focus provider heading only on return`

### Hardening concerns

- Representative metadata still uses five `array_agg(...)[1]` expressions
that share one `ORDER BY title, id`. That is a consistent ordered
aggregate and the mixed-field fixture fails under independent `min()`,
but a single subquery/`json` row pick would be harder to drift.
- The repository still declares Node 23+; this environment is Node
22.14.0. Requested commands passed with the existing engine warning.
Loading
Loading