Skip to content

Fix/canned story data - #561

Open
Sam Beveridge (00salmon) wants to merge 10 commits into
masterfrom
fix/canned-story-data
Open

Sam Beveridge (00salmon) wants to merge 10 commits into
masterfrom
fix/canned-story-data

Conversation

@00salmon

Copy link
Copy Markdown
Contributor

Description of the change

Description here

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation or Development tools (readme, specs, tests, code formatting)

Links

  • Jira issue number: (PUT IT HERE)
  • Process.st launch checklist: (PUT IT HERE)

Checklists

Development

  • Prettier was run (if applicable)
  • The behaviour changes in the pull request are covered by specs
  • All tests related to the changed code pass in development

Paperwork

  • This pull request has a descriptive title and information useful to a reviewer
  • This pull request has a Jira number
  • This pull request has a Process.st launch checklist

Code review

  • Changes have been reviewed by at least one other engineer
  • Security impacts of this change have been considered

`@saasquatch/component-boilerplate/canned` answers any query valid against a
snapshot of the SaaSquatch schema (saasquatch-core SaaSquatch.graphql) with
realistic, deterministic data, so stories no longer need a real tenant and a
real, signed user JWT.

- CannedGraphQLClient: graphql-tools mocks over the real schema; per-field
  realism (personas, pretty money values, epoch-ms dates, list sizes that match
  totalCount, inline images), Viewer/WidgetConfig pinned to the types a
  logged-in widget user gets, and a seeded PRNG so every response is stable.
- provideCannedGraphQL: supplies it through the existing `sq:graphql-client`
  DOM context, so components need no changes (works across bundles).
- interceptCannedFetch: answers direct `fetch`es to the canned endpoint only
  (component-environment's locale lookup bypasses the GraphQL client).
- useCannedEnvironment: one-call story setup with cleanup on unmount.
- fakeJwt: unsigned token, also exported from the main entry for demos.

The canned entry is separate so production consumers of the main entry never
load the 204 KB schema or graphql-tools (main entry size unchanged).
GRAPHQL_CONTEXT moves to its own module so the canned bundle doesn't inline a
second BatchedGraphQLClient or useHost.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Stories, e2e tests and two demo registration flows embedded 14 HS256 user
tokens with no expiry for real test tenants. They shipped in dist/ (31 mint
and 8 bedrock files) to npm and the CDN.

- 16 story setups use useCannedEnvironment instead of a real tenant + token.
  Locale stories set the locale explicitly instead of relying on the real
  users' stored locales.
- PortalFrame keeps the Android SDK identity path, now with a fakeJwt, and its
  full-stack stories become hook stories so their setup is cleaned up.
- Bedrock widget stories render mint's official ReferralWidget and
  CashPayoutsReferralWidget templates as the canned renderWidget response.
- Instant-access and referred registration demos use fakeJwt.
- The auth-template-switch e2e tests use an unsigned token.
- A spec in each package fails if a signed-looking JWT appears in src/.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Without an explicit bundle, Stencil merged sqb-stencilbook and the hook story
container into the lazy chunk customer pages load for sqb-widget, so story
code (and the tokens it contained) shipped to every page using the widget.
That chunk was 170 KB; sqb-widget is now 6 KB and story code lives in its own
chunk that only stencilbook loads.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 30, 2026 22:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Clean builds cannot resolve the new boilerplate imports, and unresolved identity lifecycle, Request-body handling, widget selection, and leaderboard mock issues break story behavior.

5 open issues
What changed in this PR

This PR replaces signed credentials and live-tenant data in Mint and Bedrock stories with shared canned GraphQL data, while switching registration demos to unsigned tokens.

Changes:

  • Adds a canned GraphQL client, environment helpers, configurable mocks, and schema-sync tooling.
  • Migrates stories and demos away from signed JWTs and separates Bedrock story bundles.
  • Adds canned-client tests and source checks for signed JWTs.
File Description
packages/​mint-components/​src/​utils/​noSignedJwts.spec.ts Adds a signed-JWT source check.
packages/​mint-components/​src/​components/​sqm-task-card/​UseTaskCard.stories.tsx Uses canned task-card data.
packages/​mint-components/​src/​components/​sqm-share-link/​UseShareLink.stories.tsx Uses canned share-link data.
packages/​mint-components/​src/​components/​sqm-share-button/​UseShareButton.stories.tsx Uses canned share-button data.
packages/​mint-components/​src/​components/​sqm-rewards-table/​UseRewardsTable.stories.tsx Uses canned rewards and explicit locales.
packages/​mint-components/​src/​components/​sqm-reward-exchange-list/​UseRewardExchangeList.stories.tsx Uses canned reward-exchange data.
packages/​mint-components/​src/​components/​sqm-referred-registration/​sqm-referred-registration.tsx Generates an unsigned demo token.
packages/​mint-components/​src/​components/​sqm-referral-table/​UseReferralTable.stories.tsx Uses canned referrals and explicit locales.
packages/​mint-components/​src/​components/​sqm-portal-frame/​PortalFrame.stories.tsx Uses canned environments in hook-backed stories.
packages/​mint-components/​src/​components/​sqm-leaderboard/​UseLeaderboard.stories.tsx Uses canned leaderboard data.
packages/​mint-components/​src/​components/​sqm-invoice-table/​UseInvoiceTable.stories.tsx Uses canned invoice data.
packages/​mint-components/​src/​components/​sqm-instant-access-registration/​sqm-instant-access-registration.tsx Generates an unsigned demo token.
packages/​mint-components/​src/​components/​sqm-input-field/​UseInputField.stories.tsx Uses canned input-field setup.
packages/​mint-components/​src/​components/​sqm-edit-profile/​UseEditProfile.stories.tsx Uses canned profile data.
packages/​mint-components/​src/​components/​sqm-dropdown-field/​UseDropdownField.stories.tsx Uses canned dropdown setup.
packages/​mint-components/​src/​components/​sqm-checkbox-field/​UseCheckboxField.stories.tsx Uses canned checkbox setup.
packages/​mint-components/​src/​components/​sqm-big-stat/​UseBigStat.stories.tsx Uses canned statistics data.
packages/​mint-components/​src/​components/​sqm-big-stat/​sqm-big-stat.e2e.ts Removes a token from commented-out code.
packages/​mint-components/​.changeset/​canned-story-data.md Records the Mint patch changes.
packages/​component-boilerplate/​test/​canned.test.ts Tests tokens, mocks, interception, and component queries.
packages/​component-boilerplate/​src/​index.ts Exports fakeJwt.
packages/​component-boilerplate/​src/​hooks/​graphql/​useGraphQLClient.ts Imports and re-exports the shared context name.
packages/​component-boilerplate/​src/​hooks/​graphql/​context.ts Defines the shared GraphQL context name.
packages/​component-boilerplate/​src/​fakeJwt.ts Adds unsigned JWT generation.
packages/​component-boilerplate/​src/​canned/​mocks.ts Adds seeded mock-data generators.
packages/​component-boilerplate/​src/​canned/​index.ts Implements the canned client and environment helpers.
packages/​component-boilerplate/​src/​canned.ts Exposes the canned entry point.
packages/​component-boilerplate/​scripts/​sync-canned-schema.js Adds schema-snapshot refresh tooling.
packages/​component-boilerplate/​README.md Documents canned story setup.
packages/​component-boilerplate/​package.json Configures canned exports, dependencies, and scripts.
packages/​component-boilerplate/​jest.config.ts Includes canned-client tests.
packages/​component-boilerplate/​CHANGELOG.md Documents the new APIs.
packages/​component-boilerplate/​canned/​package.json Provides canned subpath entry metadata.
packages/​bedrock-components/​stencil.config.ts Groups story components into a separate lazy bundle.
packages/​bedrock-components/​src/​utils/​noSignedJwts.spec.ts Adds a signed-JWT source check.
packages/​bedrock-components/​src/​components/​sqb-widget/​Widget.stories.tsx Uses canned widget data and explicit locales.
packages/​bedrock-components/​src/​components/​sqb-widget/​cannedWidgetTemplates.ts Adds referral and partner template mocks.
packages/​bedrock-components/​src/​components/​sqb-program-switch/​ProgramSwitch.stories.tsx Uses canned environments and unsigned identity.
packages/​bedrock-components/​src/​components/​sqb-auth-template-switch/​sqb-auth-template-switch.e2e.ts Replaces signed test credentials with an unsigned token.
packages/​bedrock-components/​src/​components/​sqb-auth-template-switch/​AuthTemplateSwitch.stories.tsx Uses canned authentication setup.
packages/​bedrock-components/​CHANGELOG.md Documents credential removal and bundle separation.

Review effort: Balanced

- useCannedEnvironment sets identity on every mount: an explicit user, else
  widgetIdent credentials (userId/accountId/token), else logged out. The
  global identity provider outlives stories and reads widgetIdent only when
  first created, so revisiting a widgetIdent-authenticated story (Auth
  Template Switch, Program Switch, Full Stack Frame) after any other story
  rendered it logged out. Reproduced in stencilbook before the fix.
- interceptCannedFetch reads the body from a Request when init.body is
  absent, matching fetch, so fetch(new Request(...)) gets data, not errors.
- EmptyLeaderboard returns no rows, as the real tenant did for its 2021
  interval, so the story shows the empty state again.
- Test pinning that graphql-tools v7 passes query arguments first to root
  field mocks, which bedrock's cannedWidgetMocks relies on.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings November 2, 2026 17:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Mint and Bedrock import new boilerplate APIs absent from their locked dependency release, so their independent CI builds cannot resolve those imports.

2 open issues
4 previously missed issues

In code that hasn't changed since last review

Medium severity Use locale-specific canned templates

packages/​bedrock-components/​src/​components/​sqb-widget/​cannedWidgetTemplates.ts:17

This resolver discards the requested locale and always returns an English template. Consequently, WidgetWithLocaleTr and WidgetWithLocaleFr now render the same English widget as the English story, losing the translated-widget behavior described in sqb-widget.feature:25-41. Select a locale-specific canned template using the resolver's locale argument so these stories still exercise translation loading without contacting a tenant.

Medium severity Add a types condition for the canned export

packages/​component-boilerplate/​package.json:13

TypeScript's node16, nodenext, and bundler resolution follow this export target rather than the types field in canned/package.json. They look for canned.modern.d.ts, but the declaration output is dist/canned.d.ts, leaving the new entry untyped or producing TS7016. Add a types condition while retaining the JavaScript target.

Medium severity Reset the program ID when setting up canned stories

packages/​component-boilerplate/​src/​canned/​index.ts:175

lazilyStartProgramContext() reads widgetIdent.programId only when creating the global provider, so later canned stories can inherit the previous story's program, including stories without a program. Initialize that provider with setProgramId during canned setup and clear it on cleanup. Apply initialization before any story-specific setProgramId override, so the table stories retain their chosen program.

Medium severity Return a decodable JWT from the canned registration response

packages/​component-boilerplate/​src/​canned/​mocks.ts:130

The canned registration response returns Example token, which useRegisterWithEmailAndPasswordMutation immediately tries to JWT-decode. Submitting a valid form in the input, checkbox, or dropdown stories therefore shows a network error instead of completing registration. Add a ManagedIdentityAuthenticationResult mock whose token comes from fakeJwt with a user payload containing id and accountId.

4 resolved since last review

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings November 3, 2026 17:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot AI balanced review requested due to automatic review settings November 3, 2026 21:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved defects leave stories using stale program context, break translated-widget and missing-locale scenarios, and return invalid registration tokens that cause valid submissions to fail.

10 open issues
3 files not reviewed
  • packages/bedrock-components/package-lock.json: Generated file
  • packages/component-boilerplate/package-lock.json: Generated file
  • packages/mint-components/package-lock.json: Generated file

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings November 5, 2026 22:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved issues leave stories using stale program context, allow VAT to exceed invoice totals, misrepresent pagination, and prevent locale stories from exercising translation and fallback behavior.

11 open issues
3 files not reviewed
  • packages/bedrock-components/package-lock.json: Generated file
  • packages/component-boilerplate/package-lock.json: Generated file
  • packages/mint-components/package-lock.json: Generated file

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings November 5, 2026 22:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new Object.fromEntries call is incompatible with the package’s ES2017 TypeScript libraries, causing TS2550 in the declaration build and blocking build/prepack.

5 open issues
7 resolved since last review
3 files not reviewed
  • packages/bedrock-components/package-lock.json: Generated file
  • packages/component-boilerplate/package-lock.json: Generated file
  • packages/mint-components/package-lock.json: Generated file

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings November 5, 2026 23:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The change introduces a declaration-build failure by using Object.fromEntries with ES2017 libraries, and stale story cleanup can erase the next story’s tenant settings or log it out.

6 open issues
3 files not reviewed
  • packages/bedrock-components/package-lock.json: Generated file
  • packages/component-boilerplate/package-lock.json: Generated file
  • packages/mint-components/package-lock.json: Generated file

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings November 6, 2026 00:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Human review is needed to evaluate overlapping story lifecycles that can overwrite shared program or locale state and fixtures that fail to reflect successful link updates.

No open issues 🎉

6 resolved since last review
3 files not reviewed
  • packages/bedrock-components/package-lock.json: Generated file
  • packages/component-boilerplate/package-lock.json: Generated file
  • packages/mint-components/package-lock.json: Generated file

Review effort: Balanced

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants