Skip to content

feat(console): the screen of an invitation: who invites, the role, « Join », then « You are in » (FRU-241) - #270

Merged
sakuga-agent[bot] merged 2 commits into
mainfrom
mathieu/fru-241-console-lecran-dune-invitation-join-puis-you-are-in
Oct 13, 2026
Merged

sakuga-agent[bot] merged 2 commits into
mainfrom
mathieu/fru-241-console-lecran-dune-invitation-join-puis-you-are-in

Conversation

@sakuga-agent

@sakuga-agent sakuga-agent Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Not critical: no safeguard changes, and the link of an invitation still signs nobody in. Review balanced asked below. The orchestrator may merge it.

Base main: the stack under it is merged (#254, #255, #259, #260, #267), and the branch is one commit on main. FRU-242 (#271) comes after it.

Closes FRU-241. Parent: FRU-230 (« Simpler flow »). Screen 03 of the mockup of 2026-10-13.

Arbitrations that apply (orchestrator, 2026-10-13, on delegation from Mathieu). Q2: the link of an invitation stays neutral, only the sentence changes. Waiting for Mathieu, so not built: Q3 (a guest of one site) and Q8 (the extension signed in from the console).

What changes

/invitations was a list. It is now the screen of one invitation, the most recent of the address that is signed in:

  • who invites (« {workspace} invited you », with the initial of the workspace);
  • « Join {workspace} on Fruitback », and what the role lets its person do;
  • « Signed in as » and « Role »;
  • « Join {workspace} », over the column, and « Decline » under it;
  • « Not {email}? Use another address », which ends the session and leads to the sign-in page.

Joined, the screen stays: « You are in », what comes next (the extension), the first site of the workspace when it has one, and the way to the console. Before, joining went straight to the Sites screen.

What the mockup has and this screen does not, and why

On the mockup Here Why
« Mathieu from Sakuga invited you » « {workspace} invited you » The worker lists the workspace of an invitation, not who sent it. The ticket allows either a small worker change or this line; this pull request is the console only.
« Review staging.acme.dev with … », « You join as a guest: … », the row « Site » « Join {workspace} on Fruitback », the sentence of a member or of an admin, no row « Site » The guest of one site does not exist (Q3). The title is the <title> of the mockup, as the ticket says.
« The link in the invitation signed you in. Not …? » « Not {email}? Use another address » Q2: the link signs nobody in.
« … It signs in with this account. » Not said Q8: a browser is still connected from the console, with a code. « Go to the console » is there in its place: without it the screen has no way on for somebody whose extension is not installed.
« Add to Chrome » → the Chrome Web Store, « Get the Firefox add-on » → the add-on site Both → https://fruitback.com/reviewing.html#1-install-it The extension is in no store (FRU-130). The ticket says so for the button. To decide when reading this: the button still reads « Add to Chrome », and leads to a page that says how to build the extension. A sentence that says it is not in a store yet would be more honest than the mockup's words.

States the mockup does not draw, and what was chosen

State Choice
Several invitations The most recent on the screen; the others under « One more invitation » / « {count} more invitations », each with its role, « Decline » and « Join {workspace} ».
« Decline » A link button, at the end of the line under « Join » (the main button keeps the width of the mockup).
Joining « Joining… », every button disabled.
An invitation that ended or was cancelled The sentence of today, under the button; the screen stays.
« Use another address » when the session did not end « You are still signed in: Fruitback did not confirm the sign-out. Try again. », and the screen stays: somebody who reads « signed out » leaves the browser to the next person (FRU-204).
Nobody signed in, no invitation, a worker that did not answer The sentences of today, in the frame of the sign-in page.
Joined a workspace with no site, or whose sites could not be read « … on the sites of {workspace} … », and no « Open … ».
The date an invitation ends (« Until {date} » today) Not shown: the mockup has no place for it.

Against the mockup

Built at 1440 × 900 and 390 × 844, system font, with « Havane » for the workspace (as wide as the mockup's name) and the mockup's own example address, which is on main already. Boxes of the mockup from its measures.json.

Element, at 1440 Mockup x, y, w, h Built x, y, w, h
logo 80, 21, 113, 22 80, 21, 113, 22
avatar 500, 155, 28, 28 500, 155, 28, 28
h1 500, 203, 440, 64.4 (two lines) 500, 203, 440, 32.2 (one line)
« Join … » 500, 507, 440, 44 500, 432.2, 440, 44
joined: success mark 504, 155, 40, 40 504, 155, 40, 40
joined: h1 500, 219, 440, 32.2 500, 219, 440, 32.2
joined: confirmation 500, 261, 440, 72 (three lines) 500, 261.2, 440, 48 (two lines)
joined: « Add to Chrome » 500, 361, 167.1, 44 500, 337.2, 166, 44
joined: « Open staging.acme.dev » 687, 363, 159.9, 41 686, 338.7, 159.9, 41
joined: « Get the Firefox add-on » 595, 454, 151.8, 17 595.3, 430.2, 151.8, 17

What differs, and why. « Join » is 74.8 px higher: the title has one line and not two (32.2 px), and the list two rows and not three (43 px), both for the guest of one site that is not built. In the joined state everything under the confirmation is 24 px higher: one line less, for the sentence that is not said. The spec holds the mockup's positions less these amounts, within 2 px. « Add to Chrome » is 1.1 px narrower: it has the letter spacing of every main button, which the mockup forgets on this one.

Captures cannot be uploaded from the agent. They are on the machine sakuga-mini: built, ~/.claude/agent-coord/scratch/fru-sf-entree/fru-241/built-03-invitation-<invitation|joined>-<1440|390>.png with every box in built-boxes.json; mockup, ~/.claude/agent-coord/maquettes/simpler-flow/shots/03-invitation-<state>-<1440|390>.png.

Found while testing, and fixed in the kit (#260)

A wide button whose words are a name somebody typed (« Join {a very long workspace name} ») made the page scroll sideways by 44 px at 390. A wide button and a link now wrap their words; the kit's spec measures it.

French, sentence by sentence (the mockup has none)

English French
{workspace} invited you {workspace} vous a invité
Join {workspace} on Fruitback Rejoignez {workspace} sur Fruitback
You join as an admin: you manage the sites, the connectors and the members of {workspace}. Vous rejoignez en tant qu’admin : vous gérez les sites, les connecteurs et les membres de {workspace}.
You join as a member: you see and leave notes on every site of {workspace}. Vous rejoignez en tant que membre : vous voyez et laissez des notes sur tous les sites de {workspace}.
Signed in as Connecté en tant que
Not {email}? Vous n’êtes pas {email} ?
One more invitation Une autre invitation
{count} more invitations {count} autres invitations
You are in Vous y êtes
One more thing: the extension shows the notes on the sites of {workspace} and lets you leave yours. Une dernière chose : l’extension affiche les notes sur les sites de {workspace} et vous permet de laisser les vôtres.
One more thing: the extension shows the notes on {site} and lets you leave yours. Une dernière chose : l’extension affiche les notes sur {site} et vous permet de laisser les vôtres.
Add to Chrome Ajouter à Chrome
Open {site} Ouvrir {site}
Using Firefox? Vous utilisez Firefox ?
Get the Firefox add-on Obtenir le module pour Firefox

The two sentences of the roles are new English too (the ticket wrote them, on the legend of the Members screen): to check when reading. Removed: « For {email}. », « Until {date} ».

Tests

e2e/console-invitation.spec.ts, 11 tests. The two of FRU-104 and FRU-209 against a worker on PGlite still pass; the first now reads the new screen, joins, reads « You are in » with the site of the workspace, and goes to the console from there. Its assertions of security did not change: the link alone opens nothing, and only a session of the address joins. Nine new ones with stubs: the boxes of the two states at 1440 (on macOS: see #267 for why), axe on both and on the signed-out state (no violation), role="status" on « You are in », a workspace with no site, several invitations with one declined, an invitation that ended, « Use another address » when the session ends and when it does not, the three states with nothing to join, 390 and 320 px in English and French with a long workspace name and a long host.

Ran locally

pnpm format, pnpm lint, pnpm typecheck, console test (93) pass. Console specs against this branch: console-invitation 11, console-setup 16, console-sign-in 20, console-cookie-session 8: all pass.

Not verified

Firefox, Safari, a screen reader. The two sentences of the roles with a person who reads them for the first time.

🤖 Generated with Claude Code


Sakuga Review · Score de confiance : 4/5

Fusion possible : écran d'invitation propre, un seul défaut mineur de cas limite (invitations simultanées).

Constats

  1. P2 Invitation traitée mais la lecture des sites peut rester en attente apps/console/app/routes/invitations.tsx:104
    Après l'acceptation, l'appel GET des sites est attendu avant d'afficher « Vous y êtes ». Si ce GET est lent, le bouton reste « Arrivée… » alors que l'invitation est déjà acceptée ; un rechargement de page montrerait alors une liste sans cette invitation. Correction : Passer à l'état joined immédiatement, puis compléter le site quand la lecture revient.
Résumé

La PR refait l'écran /invitations (invitation la plus récente, rôle, « Rejoindre », puis « Vous y êtes » avec le premier site). Les chemins d'erreur sont traités : lecture des sites en échec, déconnexion non confirmée, invitation expirée. Les textes français et la doc sont cohérents ; les tests e2e couvrent les états principaux. Je n'ai pas pu vérifier les composants du kit (Button, LinkButton, EntryPage) ni les guards messages.test.ts.

Diagramme
%%{init: {'theme': 'neutral'}}%%
flowchart LR
A["invitations.tsx"] --> B["myInvitations"]
A --> C["accept-invitation"]
C --> D["GET workspaces sites"]
D --> E["Joined screen"]
A --> F["signOut"]
Loading
Non relu
  • Composants du kit (ui.tsx) et gardes messages.test.ts non fournis

Revues (4) · Dernier commit relu : test(console): « You are in » when the sites of... · Niveau balanced · anthropic/claude-sonnet-5.5 · 0,107 $

@sakuga-review sakuga-review 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.

Score de confiance : 4/5 · ✅ Rien de bloquant · Mergeable en l'état : je n'ai relevé aucun défaut de niveau majeur ou critique dans le diff. Le point restant est la suppression des clés « Until {date} » et « For {email} » du dictionnaire français, à vérifier ailleurs dans la console.

Niveau lite · anthropic/claude-haiku-5.5 · 0,006 $ · Le résumé, le diagramme et la liste des constats sont à la fin de la description de la PR.

@sakuga-review sakuga-review Bot added the review: 4/5 Score de confiance de Sakuga Review (5 : prête à merger) label Oct 13, 2026
@sakuga-agent
sakuga-agent Bot force-pushed the mathieu/fru-241-console-lecran-dune-invitation-join-puis-you-are-in branch from d74962a to 8e2af9a Compare October 13, 2026 15:20

@sakuga-review sakuga-review 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.

Score de confiance : 3/5 · ⚠️ Rien de bloquant · Ne pas fusionner en l'état : le rôle « guest » d'une invitation s'affiche comme « Membre », avec une description de droits fausse. Le reste du changement est cohérent avec le contrat décrit dans CLAUDE.md et les appels visibles.

Niveau lite · anthropic/claude-haiku-5.5 · 0,007 $ · Le résumé, le diagramme et la liste des constats sont à la fin de la description de la PR.

@sakuga-review sakuga-review Bot added review: 3/5 Score de confiance de Sakuga Review (5 : prête à merger) and removed review: 4/5 Score de confiance de Sakuga Review (5 : prête à merger) labels Oct 13, 2026
sakuga-agent Bot pushed a commit that referenced this pull request Oct 13, 2026
…page in the preview (FRU-242)

The commits of the branch as one, on the branch of #270 after the rebase of the stack on main.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@sakuga-agent
sakuga-agent Bot force-pushed the mathieu/fru-241-console-lecran-dune-invitation-join-puis-you-are-in branch from 8e2af9a to c1d10b9 Compare October 13, 2026 15:37

@sakuga-review sakuga-review 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.

Score de confiance : 4/5 · ✅ Rien de bloquant · Mergeable en l'état : aucun défaut certain dans le code lu. Le point à vérifier est la suppression de la clé « Fruitback » de messages.fr.ts, que d'autres écrans pourraient encore appeler.

Niveau lite · anthropic/claude-haiku-5.5 · 0,007 $ · Le résumé, le diagramme et la liste des constats sont à la fin de la description de la PR.

@sakuga-review sakuga-review Bot added review: 4/5 Score de confiance de Sakuga Review (5 : prête à merger) and removed review: 3/5 Score de confiance de Sakuga Review (5 : prête à merger) labels Oct 13, 2026
sakuga-agent Bot pushed a commit that referenced this pull request Oct 13, 2026
…page in the preview (FRU-242)

The commits of the branch as one, on the branch of #270 after the rebase of the stack on main.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Base automatically changed from mathieu/fru-239-console-la-mise-en-place-en-un-ecran-your-account-et-your to main October 13, 2026 16:03
…Join », then « You are in » (FRU-241)

The commits of the branch as one, on the branch of #267 after its rebase on main.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@sakuga-agent
sakuga-agent Bot force-pushed the mathieu/fru-241-console-lecran-dune-invitation-join-puis-you-are-in branch from c1d10b9 to c43a272 Compare October 13, 2026 16:06

@sakuga-review sakuga-review 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.

Score de confiance : 4/5 · ✅ Rien de bloquant · Le changement peut être fusionné : je n'ai trouvé aucun défaut confirmé dans le diff. Les points restants tiennent à des fichiers ou des appelants que le message ne montre pas.

Niveau lite · anthropic/claude-haiku-5.5 · 0,007 $ · Le résumé, le diagramme et la liste des constats sont à la fin de la description de la PR.

@sakuga-agent

sakuga-agent Bot commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

@sakuga-review review balanced

Asked now that its diff is its own: the stack under it is merged, and the branch is one commit on main. The lite of c43a272 gives 4/5 with no finding.

@sakuga-review sakuga-review 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.

Score de confiance : 3/5 · ⚠️ Rien de bloquant · Fusion possible après correction : un échec d'« Use another address » ne s'affiche pas sur l'écran « joined » et un état de « Join » peut rester incohérent ; peu de défauts bloquants.

Niveau balanced · anthropic/claude-sonnet-5.5 · 0,107 $ · Le résumé, le diagramme et la liste des constats sont à la fin de la description de la PR.

@sakuga-review sakuga-review Bot added review: 3/5 Score de confiance de Sakuga Review (5 : prête à merger) and removed review: 4/5 Score de confiance de Sakuga Review (5 : prête à merger) labels Oct 13, 2026
@sakuga-agent

sakuga-agent Bot commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

On the balanced review of c43a272:

P2, « Join » stays busy if the read of the sites throws. A call of the console does not throw. That is the contract of transport.ts (reach: « this must not reject », with a try/catch around fetch and a timeout of 15 s), and call answers an Answer in every case. The line after the read handles the failure: sites.ok ? … : undefined, then setBusy(undefined) and the « joined » screen, which then speaks of the sites of the workspace without naming one. The case « You are in, when the sites cannot be read » in e2e/console-invitation.spec.ts covers it. Nothing to change.

The summary, « a failure of “Use another address” does not show on the “joined” screen ». That action is only on the screen of an invitation, not on « joined ». Its failure is said there (STILL_SIGNED_IN), and the spec covers it.

…be read (FRU-241)

After « Join », the console reads the sites of the workspace to name the first one. Two cases hold
what happens when it cannot: the worker refuses the list, or the request does not arrive. The
invitation is accepted, the screen says « You are in » and names no site, and nothing stays busy.
Answers the balanced review of c43a272.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@sakuga-agent

sakuga-agent Bot commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

A correction to my answer above: the case I named did not exist. The spec had « joined a workspace with no site », and nothing for sites that cannot be read. 2ec3acc adds it, twice: the worker refuses the list (503), and the request does not arrive (route.abort). In both the invitation is accepted, the screen says « You are in » with the sentence that names no site, « Go to the console » is there, and nothing stays busy. The code is unchanged: these cases pass on c43a272 as it was, which is the proof asked for by the finding.

@sakuga-review sakuga-review 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.

Score de confiance : 4/5 · ✅ Rien de bloquant · Fusion envisageable : le diff ne montre pas de défaut certain. Le point à vérifier avant fusion est la route GET /console/workspaces//sites appelée par un membre invité, que le diff ne montre pas.

Niveau lite · anthropic/claude-haiku-5.5 · 0,006 $ · Le résumé, le diagramme et la liste des constats sont à la fin de la description de la PR.

@sakuga-review sakuga-review Bot removed the review: 3/5 Score de confiance de Sakuga Review (5 : prête à merger) label Oct 13, 2026
@sakuga-review sakuga-review Bot added the review: 4/5 Score de confiance de Sakuga Review (5 : prête à merger) label Oct 13, 2026
@sakuga-agent

sakuga-agent Bot commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

@sakuga-review review balanced

Since the balanced of c43a272, 2ec3acc adds the two cases its finding asked proof for: after « Join », the sites cannot be read (a refusal, and a request that does not arrive). The code is unchanged.

@sakuga-review sakuga-review 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.

Score de confiance : 4/5 · ⚠️ Rien de bloquant · Fusion possible : écran d'invitation propre, un seul défaut mineur de cas limite (invitations simultanées).

Niveau balanced · anthropic/claude-sonnet-5.5 · 0,107 $ · Le résumé, le diagramme et la liste des constats sont à la fin de la description de la PR.

@Mheaus
Mheaus added this pull request to stack #289 October 13, 2026 16:26
@sakuga-agent

sakuga-agent Bot commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

On the P2 of the balanced review of 2ec3acc, « the read of the sites can stay pending after the invitation is accepted »: the wait is bounded and deliberate. The read is one call, cut at 15 s by transport.ts, and « Joining… » stays during it. The screen « You are in » then shows once, with its final sentence. Showing it first and filling in the site after would change a sentence and add a link under the eyes, and under a screen reader that is reading the role="status". A reload in that window leads to the console of the workspace the person is now in, by the front door. No change.

@sakuga-agent
sakuga-agent Bot merged commit 30c62f8 into main Oct 13, 2026
13 checks passed
@sakuga-agent
sakuga-agent Bot deleted the mathieu/fru-241-console-lecran-dune-invitation-join-puis-you-are-in branch October 13, 2026 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review: 4/5 Score de confiance de Sakuga Review (5 : prête à merger)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant