From 1485d3de1b305d9862f724c662b5740ef9ae99db Mon Sep 17 00:00:00 2001 From: Dotta <34892728+cryppadotta@users.noreply.github.com> Date: Fri, 6 Nov 2026 12:00:50 -0600 Subject: [PATCH] fix(ui): hold announcements until the onboarding first task is finished (#19514) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - A new user's first session is the onboarding first task. The agent asks its onboarding questions in that task thread. > - The app also shows an optional in-app announcement. The live feed now serves "Introducing Connectors" (`2026-09-14-connectors`). > - The announcement well only waits while the onboarding wizard dialog is open. It shows 3 seconds after the user lands on the first task. > - In the Nov 5 cloud onboarding test (Claude API path), the tester said: "Don't show the connectors upsell until the second session. It's blocking the user flyout and potentially the onboarding questions." > - This pull request holds announcements until the company's onboarding first task is done or cancelled. > - The benefit is that a new user sees the onboarding questions and the account menu without an upsell on top of them. ## Linked Issues or Issue Description Refs #19511 (places the card in the desktop sidebar, above the account menu. That PR keeps the card off the account menu after onboarding. This PR adds the first-session gate that #19511 leaves open.) **What happened?** On a new company's onboarding first task, the "Introducing Connectors" card shows 3 seconds after the page loads. At 1440x900 the card (352x346 px, bottom-left, z-40) covers the sidebar account menu trigger and the left edge of the task composer. **Expected behavior** Optional announcements do not show in the first session, while the onboarding first task is open. **Steps to reproduce** 1. Create a new company through onboarding. The wizard creates the onboarding first task. 2. Open the first task at 1440x900 and wait 3 seconds. 3. See the announcement card on top of the account menu and the composer. **Paperclip version or commit** `master` at 819420a60a. ## What Changed - `AnnouncementWell` reads the company's onboarding first task (`originKind=onboarding_first_task`, `limit=1`) with React Query under `["issues", companyId, "onboarding-first-task"]`. Issue live-update invalidation of `["issues", companyId]` refreshes it. - The well stays disabled while that task is not `done` or `cancelled`. While the read is loading or after it fails, the optional card stays hidden. A company that never had an onboarding first task is not gated. - "First session" uses the existing `origin_kind` marker. There is no schema change. - New e2e spec `tests/e2e/announcement-first-session.spec.ts` with a mocked feed that copies the live connectors entry. It checks that the card is absent while the onboarding first task is open. Then it marks the task done on the same page and checks that the card appears without a reload (a positive control for the feed mock and the live refresh path). - New unit test `AnnouncementWell.onboarding.test.tsx`. It covers open, finished, no first task, read failure, and the open-to-done transition after `["issues", companyId]` is invalidated. `AnnouncementWell.test.tsx` now gives the well a `QueryClient` with a finished onboarding state. ## Verification Red on `master` (819420a60a), before the fix. Vitest: ``` cd ui && npx vitest run src/components/AnnouncementWell.onboarding.test.tsx × stays hidden while the onboarding first task is open × stays hidden when onboarding state cannot be read Tests 2 failed | 1 passed (3) AssertionError: expected true to be false ``` Red on `master`, Playwright at 1440x900 (an earlier draft of the spec also had a placement check, recorded here as evidence for the flyout part of the report): ``` ✘ announcement-first-session.spec.ts › a brand-new company with its onboarding task open does not show the upsell Error: expect(locator).toHaveCount(expected) failed Locator: getByRole('complementary', { name: 'Paperclip announcements' }) Expected: 0 Received: 1 ✘ … where the upsell shows, it does not cover the account menu or its flyout Error: well {"x":12,"y":542,"width":352,"height":346} covers account trigger {"x":20,"y":856,"width":166,"height":36} ``` Green after the fix, merged with current `master` (f7070d68b5), with the in-page positive control: ``` ✓ announcement-first-session.spec.ts › a brand-new company with its onboarding task open does not show the upsell (10.1s) 1 passed cd ui && npx vitest run src/components/AnnouncementWell.onboarding.test.tsx src/components/AnnouncementWell.test.tsx Tests 6 passed (6) cd ui && npx vitest run src/components/AnnouncementWell.onboarding.test.tsx src/components/AnnouncementWell.test.tsx \ src/components/AnnouncementCard.test.tsx src/hooks/useAnnouncement.test.tsx src/components/SidebarAccountMenu.test.tsx src/components/Layout.test.tsx Test Files 6 passed (6) Tests 95 passed (95) ``` - `pnpm check:token-gates`: All gates clean. - UI `tsc --noEmit`: no errors in app code. The only errors are the git-ignored, generated Storybook catalog files. - CI note: the first CI run had three jobs fail with "The self-hosted runner lost communication with the server" (server tests 12/12, Runner vitest package, e2e shard 5/8). These are infra flakes. I reran them. - Local e2e note: two runs could not start the server because embedded PostgreSQL ports were in use by parallel e2e runs on the same machine. A rerun passed. This is not related to the change. Before (master): the card covers the account menu and the composer on the onboarding first task. ![before: onboarding first task](https://raw.githubusercontent.com/paperclipai/paperclip/c97519868225b0c206cf95fa3fb7150287c88116/n13-before-onboarding-task.png) After: no card on the onboarding first task. The account menu and the composer are clear. ![after: onboarding first task](https://raw.githubusercontent.com/paperclipai/paperclip/c97519868225b0c206cf95fa3fb7150287c88116/n13-after-onboarding-task.png) ## Risks - Low risk. The change only hides optional content. - A user who never finishes or cancels the onboarding first task does not see announcements in that company. This is the intended trade-off for "not in the first session". Closing the task shows them again. - The well makes one extra small issues read (`limit=1`) per company. It is cached for 60 seconds. - `AnnouncementWell.tsx` also changes in #19511. Whichever PR lands second resolves a small conflict in the `enabled` condition and the `