Skip to content

fix(app-graphql-playground): store playground tabs and history per tenant again - #5984

Merged
adrians5j merged 1 commit into
nextfrom
claude/fix-playground-tenant-storage
Oct 13, 2026
Merged

adrians5j merged 1 commit into
nextfrom
claude/fix-playground-tenant-storage

Conversation

@adrians5j

@adrians5j adrians5j commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

The GraphQL playground's saved tabs and query history were shared across tenants, because both were written to the unprefixed root localStorage.

Cause

The tenancy provider gives each tenant a child container that registers its own LocalStorage, prefixed with the tenant (app-admin/src/features/tenancy/feature.ts). The playground's two repositories and the two presenters that read them were root singletons. Under @webiny/di 1.x, the first resolve came from the tenant container, so they used the tenant-prefixed storage. @webiny/di 2.0 (#5969) builds a singleton from the container that registers it, here the root. Tabs went to webiny/<id>:graphql-playground instead of webiny/<id>/<tenant>:graphql-playground, and the same happened to the history.

Fix

PlaygroundRepository, QueryHistoryRepository, PlaygroundPresenter and QueryHistoryPresenter are registered with inContainerScope(). Each tenant container builds its own instances against its own storage. Within one container, the two presenters still share the one QueryHistoryRepository. Nothing else depends on these four. The tab registry and the client factories don't touch storage, so they stay root singletons.

The other root singletons that use LocalStorage store global state: the current tenant, assumed permissions, the WCP licence cache, feature flags and the installed flag. They were resolved from the root under 1.x too, so nothing changed for them.

Anything saved since #5969 sits under the root key and won't appear after this change. Data saved before #5969 is under the tenant key and shows again.

Testing

  • The app-graphql-playground tests pass (6 files, 101 tests). yyb builds.
  • In the admin, the playground wrote webiny/<id>:graphql-playground before this change. After it, it writes webiny/<id>/root:graphql-playground and webiny/<id>/root:graphql-playground-history. An added tab survives a reload, and running a query saves history.

Workspace: wby-next2 · 🧹 MERGE 6.5.0 => NEXT

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Updates
    • Query history, playground data, and presentation components now use instances scoped to each playground container instead of shared singleton instances.
    • No changes to user-facing functionality are specified.

…nant again

The tenancy provider gives each tenant a child container with its own
LocalStorage, prefixed by the tenant. The playground's repositories and
presenters were root singletons. Under @webiny/di 1.x the first resolve
came from the tenant container, so they used the tenant-prefixed
storage. @webiny/di 2.0 (#5969) builds a singleton from its own
container, the root, so tabs and query history went to the unprefixed
root storage and were shared across tenants.

PlaygroundRepository, QueryHistoryRepository and the two presenters that
read them are now registered with inContainerScope(), so each tenant
container builds its own against its own storage.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🚓 Slop Cop

✅ Nothing worth flagging. The diff looks consistent with the PR's stated intent and the code-style rules.

Small, focused fix changing four feature registrations from singleton to container scope, matching the stated intent; no integrity or style issues found.

Automated, non-blocking heads-up from an LLM. It can be wrong — use your judgment. Regenerates on every push.

@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 46057ec6-643a-46ec-bbc9-5efec1fc3331
📥 Commits

Reviewing files that changed from the base of the PR and between 586764e and e9671bf.

📒 Files selected for processing (4)
  • packages/app-graphql-playground/src/features/queryHistory/feature.ts
  • packages/app-graphql-playground/src/features/repository/feature.ts
  • packages/app-graphql-playground/src/presentation/Playground/feature.ts
  • packages/app-graphql-playground/src/presentation/QueryHistory/feature.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 4 remain after this review.

📝 Walkthrough

Four GraphQL Playground service registrations now use container scope instead of singleton scope. These registrations cover the query history and playground repositories and presenters.

Changes: GraphQL Playground container scope

Layer / File(s) Summary
Container-scoped repositories and presenters
packages/app-graphql-playground/src/features/queryHistory/feature.ts, packages/app-graphql-playground/src/features/repository/feature.ts, packages/app-graphql-playground/src/presentation/Playground/feature.ts, packages/app-graphql-playground/src/presentation/QueryHistory/feature.ts
The query history and playground repositories and presenters change from singleton scope to container scope. The Playground presenter registration includes a comment stating that it reads per-tenant playground repositories.

Priority: ➖ Normal

Estimated code review effort: 1 (Trivial) | ~5 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to e9671

Playground tabs and history are now isolated by tenant. Older history in the former shared key may not appear, but assigning it to a tenant could expose another tenant’s data; no actionable merge blocker remains.

Pre-merge checks · Passed 5
Passed Passed checks (5 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly summarizes the main change: playground tabs and query history now use tenant-specific storage again. It is concise and directly matches the affected repositories and presenters.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 4…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@adrians5j
adrians5j merged commit 42eaee6 into next Oct 13, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant