Skip to content

console: accept-invitation page names neither the organization nor the role — the routed implementation is the thin duplicate, while the detailed one ships unrouted #8282

Description

@baozhoutao

The invitation-accept screen tells the invitee nothing about what they are accepting. Observed page (zh), in full:

接受组织邀请
您受邀加入一个组织。
[ 接受邀请 ] [ 拒绝 ]

No organization name, no inviter, no role being granted, no expiry. The user is asked to join "an organization" and cannot tell which one, from whom, or as what — a decision they have no basis to make, and a soft phishing surface (anyone who can send an invite can get a click on an anonymous "join" button).

The twist: a page that shows all of it already exists and is not routed

Two implementations of the same route live in the tree:

file fetches invitation? shows
apps/console/src/pages/auth/AcceptInvitationPage.tsx no accept / decline only — this is the one mounted
packages/app-shell/src/console/organizations/manage/AcceptInvitationPage.tsx yes (getInvitation) org name, role, expiry, plus a proper error state

The router mounts the thin one:

// apps/console/src/App.tsx:65,188
import { AcceptInvitationPage } from './pages/auth/AcceptInvitationPage';
…
<Route path="/accept-invitation/:invitationId" element={<AcceptInvitationPage />} />

while the richer one renders exactly the missing block:

{t('organization.accept.description', {
  defaultValue: 'You have been invited to join {{orgName}} as {{role}}.',
  orgName: invitation.organizationName ?? invitation.organizationId,
  role: invitation.role,
})}
…
Organization / Role / Expires rows

It is exported (DefaultAcceptInvitationPage from packages/app-shell/src/index.ts:199, and from console/organizations/index.ts) but nothing in apps/console imports it. The locale files carry both key families and the comment in every locale already notes the split:

// Distinct from organization.accept.* (app-shell's richer page, same route).

So the strings for the good page are translated in 10+ locales and shipped, for a page the console never renders.

Expected

The invitee sees at least the organization name and the role being granted before accepting. Inviter would be a further improvement.

Suggested fix

Route the app-shell page (DefaultAcceptInvitationPage) and delete the thin duplicate, or port the detail block into the routed one and retire the unused export + its translation keys. Either way one implementation should survive — two pages for one route with different information density is how this drifted.

Environment

objectos-ee-deploy on http://localhost:8080, zh locale, invitee lisi@acme-test.com accepting an invitation to 测试组织甲, observed 2026-08-12. Source references are the current objectui main checkout, where the routing above still stands — this is not a stale-image artifact.

Related: #8090 (the link that reaches this page is itself broken), #8094 (untranslated strings in the same flow).

Activity

  1. added theissue type on Aug 13, 2026
  2. hotlong commented on Aug 13, 2026

    @hotlong
    Contributor

    Triage: pm:queue, repo:objectui, type Bug. Two label corrections: removed domain:identity (domain:* labels are objectstack package lanes; cards whose fix lands wholly in objectui carry repo:objectui only — same shape as #8096/#8018) and the filer's priority:p2 (p1–p5 ladder retired, no reader). Card stays in this repo's backlog for the repo:objectui seat, per the established shape for objectui-landing cards filed here.

    The fix surface is entirely objectui: apps/console/src/App.tsx routing + the two AcceptInvitationPage implementations (apps/console/src/pages/auth/ thin vs packages/app-shell/src/console/organizations/manage/ rich). The card's "one implementation should survive" framing is right; note the rich page already has translated strings in 10+ locales, which weighs toward routing it and retiring the thin one rather than porting blocks.

    Cross-links for whoever dispatches: #8090 (the link reaching this page is broken — fix order matters: landing this first changes what #8090 verifies against) and #8094 (untranslated strings, same flow). #8092's affordance bug pairs with objectstack-side #8289 (wrong denial answer) — same end-user journey, different repos; do not batch them together.


    Generated by Claude Code

  3. hotlong commented on Aug 14, 2026

    @hotlong
    Contributor

    Maintainer ruling (2026-08-14, verbatim: 「同意」, approving item 1 of the six-item ruling list: 「#8282 修-17.x?」): fix in 17.x, per the remedy already on this card — route the rich DefaultAcceptInvitationPage (already localized in 10+ locales) and delete the thin routed duplicate; one implementation survives. target:v17 applied; enters Seat B (#8668) first batch.


    Generated by Claude Code

  4. self-assigned this
    on Aug 14, 2026
  5. yinlianghui commented on Aug 14, 2026

    @yinlianghui
    Collaborator

    Claim: PM loop round 2
    Session: session_01RnQd8iMMUwXQEV1crFmQiQ
    Branch: claude/issue-8282-invitation-page
    Worktree: objectui-issue-8282
    Domain: repo:objectui
    File surface: apps/console/src/App.tsx (route swap) + apps/console/src/pages/auth/AcceptInvitationPage.tsx (delete thin page) + locale resources for the retired thin-key family + tests (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: opus
    Serial constraints cleared: #8096/PR #4638 (AppHeader + OrganizationsPage) is MERGED — no longer in flight; sibling #8270 shares locale surfaces and stays HELD until this lands (serial); in-flight #4649 declares types/react/plugin-list/plugin-view/app-shell(views/ObjectView.tsx)+components metadata, #4650 declares plugin-calendar/form/grid/kanban props + app-shell(views/metadata-admin) — no overlap with this card's surface; no open dev PR touches apps/console (checked this round).


    Generated by Claude Code

  6. yinlianghui commented on Aug 14, 2026

    @yinlianghui
    Collaborator

    Premise falsified — no PR. The prescribed remedy was already merged three days before this card was filed.

    objectui PR #4168 — "fix(console): route /accept-invitation to DefaultAcceptInvitationPage, retire the duplicate acceptInvitation. namespace (#3811)"* — merged 2026-08-10T15:28:20Z (merged: true). It is Option A: the exact remedy the 2026-08-13 triage and the 2026-08-14 maintainer ruling independently prescribed.

    Verified on origin/main @ a99233fff

    Card claim State on main Verdict
    Thin page apps/console/src/pages/auth/AcceptInvitationPage.tsx is mounted git cat-file -e origin/main:<path> → "does not exist in 'origin/main'" deleted
    App.tsx:65,188 imports/routes the thin page App.tsx:36 imports DefaultAcceptInvitationPage; App.tsx:172-173 routes /accept-invitation/:invitationId to it already the rich page
    Rich page ships unrouted routed, and renders org name / role / expiry via organization.accept.description routed
    Thin acceptInvitation.* keys still shipped zero hits in all ten packs (packages/i18n/src/locales/{ar,de,en,es,fr,ja,ko,pt,ru,zh}.ts) retired
    No routing-level test apps/console/src/pages/auth/__tests__/AcceptInvitationRoute.test.tsx exists already pinned

    Surviving acceptInvitation grep hits are the auth client method acceptInvitation(invitationId) (packages/auth) and prose comments naming the retired namespace — not the locale family.

    The test the PM asked me to add already exists and is green

    pnpm exec vitest run apps/console/src/pages/auth/__tests__/AcceptInvitationRoute.test.tsx at a99233fff — 8 passed (8), including verbatim:

    ✓ the two capabilities the thin console page did not have
        > shows which organization, which role and when the invitation expires
    ✓ takes its copy from `organization.accept.*` — the surviving namespace
    ✓ anonymous visitors still bounce to /login with a return path
        > does NOT carry the console mount prefix when served under a basename
    

    That third-from-last case asserts builtInLocales.zh.acceptInvitation is undefined, so the locale retirement is pinned negatively — a partial revert fails it.

    What was actually wrong: the card's one explicitly-defended claim

    The body states "Source references are the current objectui main checkout, where the routing above still stands — this is not a stale-image artifact." That is the claim that is false, in both halves:

    This is a cluster, not a one-off. Sibling #8090 — same reporter, same 2026-08-12 walkthrough, same "the source quoted above is the current objectui main checkout" framing — is likewise already fixed: buildAcceptUrl is gone from both sites, replaced by resolveConsoleUrl (InvitationsPage.tsx:30,106, InviteMemberDialog.tsx:31,151). It was moved to objectui#4472 and closed 2026-08-12. Worth re-checking the rest of that walkthrough batch (#8091, #8092, #8093, #8094, #8095, #8096) against current main before dispatching any of them.

    Fix-order note (#8090) is moot

    #8090 is closed (not_planned, moved to objectui#4472, itself closed 2026-08-12), so nothing downstream is waiting on this card. For the record, the routed page's path contract — the stable target that note wanted:

    • route pattern "/accept-invitation/:invitationId", mounted bare (no AuthLayout); the page paints its own min-h-svh shell.
    • invitationId is read with useParams() and is required — absent, the page never fetches.
    • link producers must use resolveConsoleUrl(\accept-invitation/${id}`)(mount-aware), notimport.meta.env.BASE_URL`.
    • the anonymous bounce emits a basename-stripped ?redirect= from useLocation(), never window.location.pathname.

    No gates owed

    Zero files changed, so no changeset and no gate farm applies. The one targeted run above is the evidence that adjudicates the premise. Worktree objectui-issue-8282 and branch claude/issue-8282-invitation-page were created, used read-only, and removed unforced (clean git status, no commits).

    Recommended disposition: close #8282 as already-fixed by objectui#4168, or keep it open only as a deployment-refresh task — the objectos-ee-deploy instance at localhost:8080 is serving a pre-2026-08-10 build, which is the actual live defect and is not an objectui code change.


    Generated by Claude Code


    Generated by Claude Code

  7. yinlianghui commented on Aug 14, 2026

    @yinlianghui
    Collaborator

    ACCEPT (premise-falsified) + closing as already fixed — reviewer of record: seat session session_01RnQd8iMMUwXQEV1crFmQiQ.

    The dev's adjudication run (report above) establishes on origin/main @ a99233fff: the thin apps/console/src/pages/auth/AcceptInvitationPage.tsx does not exist, the router mounts the rich DefaultAcceptInvitationPage at /accept-invitation/:invitationId, the invitee sees organization / role / expiry, the dead locale family is gone, and a routing test pins all of it (8/8 green, run on an unbuilt fresh worktree so it cannot be a stale-dist false green). The prescribed remedy merged as objectui#4168 on 2026-08-10 — before this card was filed. No PR from this dispatch: there was nothing left to implement.

    @baozhoutao — the defect you saw is real on your instance, but its cause is deployment staleness, not objectui main: the objectos-ee-deploy at localhost:8080 observed on 2026-08-12 predates the 2026-08-10 fixes. Two of this walkthrough batch are now confirmed already-fixed-before-filing (this card, and #8090's remedy objectui#4472). Please refresh the deployed image before further walkthroughs, and treat "the source quoted is the current main checkout" as needing a git log timestamp check against the image's build date — that clause is exactly what failed here, twice.

    Seat process note: remaining open cards from the same 2026-08-12 batch get a premise re-verification against current main before any future dispatch (adopting the dev's recommendation; already applied to the next candidate this round).


    Generated by Claude Code

  8. removed their assignment
    on Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority:p0Critical: blocker, must ship before MVPrepo:objectui

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions