Skip to content

feat: save variable and style references for Studio projects#3867

Open
six7 wants to merge 6 commits into
mainfrom
six7/plugin-theme-refs-round-trip
Open

feat: save variable and style references for Studio projects#3867
six7 wants to merge 6 commits into
mainfrom
six7/plugin-theme-refs-round-trip

Conversation

@six7

@six7 six7 commented May 12, 2026

Copy link
Copy Markdown
Collaborator

Why does this PR exist?

When using the REST/OAuth path to sync with Studio projects (Studio-on-Rails), variable references ($figmaVariableReferences) and style references ($figmaStyleReferences) were read-only -- changes made in the plugin were never written back to the server. This PR adds round-trip support so these maps are persisted when users update them.

Related backend PR: https://github.com/The-Phoenix-Will-Fly/studio-on-rails/pull/2396

What does this pull request do?

Adds write support for Figma variable/style references on the REST/OAuth path:

  • Fixes the read path: Variable refs are sourced from the theme group (where the API stores them) rather than incorrectly reading from the theme option.
  • Adds PATCH helpers: Two functions that write variable refs to theme groups and style refs to theme options via the Rails API.
  • Wires the middleware: When using TOKENS_STUDIO_OAUTH, ref-mutation actions (assign/unassign variable refs, update style refs) now trigger a REST PATCH to persist changes.
  • Caches server IDs: $themeGroupId and $themeOptionId are stored on each ThemeObject after the initial fetch so we can target the correct API endpoints on write.
  • Re-resolves branch: The change_set_id is re-resolved before each write to handle branch switches between fetch and mutation.

Key design decisions:

  • Only the GQL path is untouched (it talks to the original TS backend which uses a different data model).
  • Omitting a key preserves existing refs; sending {} explicitly clears them; null is never sent.
  • Style refs are sent verbatim ("S:key," form) -- no stripping/re-adding prefixes.

Testing this change

Unit tests added (14 new tests):

yarn jest --no-coverage --testPathPattern="pushThemeRefsRest.test|updateThemeRefsViaRestApi.test"

All existing tokensStudio tests (55) and middleware tests (36) continue to pass.

Manual testing against the preview API (studio-on-rails-web-5s4z-pr-2396.onrender.com) has not been done yet -- this needs a live Studio project with OAuth configured.

Additional Notes (if any)

This is scoped to refs-only sync (Option B). Full OAuth write parity (theme CRUD) is out of scope and can be a follow-up.

- Extend ThemeObject with $themeGroupId and $themeOptionId for server-side UUID caching
- Fix REST read: source figma_variable_references from theme group (not option)
- Add PATCH helpers for variable refs (group) and style refs (option)
- Add resolveChangeSetId helper for branch-aware writes
- Wire tokenState middleware for TOKENS_STUDIO_OAUTH provider (refs-only actions)
- Add unit tests for PATCH helpers and orchestrator (14 tests)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@changeset-bot

changeset-bot Bot commented May 12, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 57cc01d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@tokens-studio/figma-plugin Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

github-actions Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

⤵️ 📦 ✨ The artifact was successfully created! Want to test it? Download it here 👀 🎁

@github-actions

github-actions Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

Commit SHA:eb7e63bae81daadffb986da3064cce7d2371985c

Test coverage results 🧪

Code coverage diff between base branch:main and head branch: six7/plugin-theme-refs-round-trip 
Status File % Stmts % Branch % Funcs % Lines
🟢 total 61.57 (0.07) 53.11 (0.1) 59.2 (-0.02) 61.99 (0.08)
🔴 packages/tokens-studio-for-figma/src/app/store/middlewares/tokenState.ts 86.66 (-13.34) 70 (-30) 75 (-25) 84.61 (-15.39)
✨ 🆕 packages/tokens-studio-for-figma/src/utils/tokensStudio/pushThemeRefsRest.ts 88.88 100 50 100
✨ 🆕 packages/tokens-studio-for-figma/src/utils/tokensStudio/updateThemeRefsViaRestApi.ts 92 81.57 100 95.45

@github-actions

github-actions Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

Commit SHA:eb7e63bae81daadffb986da3064cce7d2371985c
Current PR reduces the test coverage percentage by 1 for some tests

Copilot AI 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.

Pull request overview

Adds REST/OAuth round-trip persistence for Figma variable/style reference maps when syncing against Studio-on-Rails projects, aligning REST behavior with the existing GQL sync path.

Changes:

  • Fetches variable references from theme groups (REST model) and stores REST server IDs on ThemeObject for targeted writes.
  • Introduces REST PATCH helpers plus middleware wiring to persist ref mutations back to the server.
  • Adds unit tests for the new REST PATCH helpers and the ref-update orchestration.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/tokens-studio-for-figma/src/utils/tokensStudio/updateThemeRefsViaRestApi.ts Diffs theme refs and PATCHes variable/style refs over REST for OAuth projects.
packages/tokens-studio-for-figma/src/utils/tokensStudio/updateThemeRefsViaRestApi.test.ts Unit tests for the diff-and-patch orchestration.
packages/tokens-studio-for-figma/src/utils/tokensStudio/pushThemeRefsRest.ts REST PATCH helpers for theme group/option ref persistence.
packages/tokens-studio-for-figma/src/utils/tokensStudio/pushThemeRefsRest.test.ts Unit tests for the REST PATCH helpers.
packages/tokens-studio-for-figma/src/utils/tokensStudio/fetchProjectDataRest.ts Fixes REST read path: variable refs come from theme groups; stores $themeGroupId/$themeOptionId.
packages/tokens-studio-for-figma/src/utils/tokensStudio/fetchBranchesListRest.ts Adds resolveChangeSetId helper for re-resolving branch change set before writes.
packages/tokens-studio-for-figma/src/types/ThemeObject.ts Adds optional REST server ID fields to ThemeObject.
packages/tokens-studio-for-figma/src/storage/schemas/themeObjectSchema.ts Extends theme schema to allow the new REST server ID fields.
packages/tokens-studio-for-figma/src/app/store/middlewares/tokenState.ts Triggers REST ref persistence for OAuth provider ref-mutation actions.
.changeset/theme-refs-round-trip.md Changeset for releasing the feature.

Comment thread packages/tokens-studio-for-figma/src/utils/tokensStudio/fetchProjectDataRest.ts Outdated
@anathaniel-TS

Copy link
Copy Markdown

🛡️ Hyma Compliance Check

⚠️ 1 finding(s) across 3 file(s)

Severity Category File Headline
🔵 LOW ROPA src/utils/tokensStudio/pushThemeRefsRest.ts + 2 others New REST API calls from Figma plugin to Studio-on-Rails backend introduce a direct client→server data flow not previously in ROPA
Full finding details

[ROPA] New REST API calls from Figma plugin to Studio-on-Rails backend

  • Files: src/utils/tokensStudio/pushThemeRefsRest.ts (new), src/utils/tokensStudio/updateThemeRefsViaRestApi.ts (new), src/app/store/middlewares/tokenState.ts (modified)
  • Implication: This PR introduces two new REST endpoints called from the Figma plugin client directly to Studio-on-Rails:
    • PATCH /api/v1/projects/{projectId}/theme_groups/{id}?change_set_id=... — sends figma_variable_references
    • PATCH /api/v1/projects/{projectId}/theme_options/{id}?change_set_id=... — sends figma_style_references
      These calls are authenticated via oauthTokens.accessToken from useAuthStore. The data transferred (figma_variable_references, figma_style_references) is design-system metadata rather than personal data. However, the Figma plugin is a client-side application running in Figma's sandbox, and these calls represent a new direct data flow from that context to the Studio backend that may not be reflected in the current ROPA entry for the Figma integration. GDPR Art. 30 requires recording all processing activities.
  • Recommended action: Review ROPA entry for the Figma plugin / design system sync processing activity. If this call pattern isn't yet documented, add a note describing the new bidirectional theme-ref sync flow. Low severity — no personal data transmitted, but ROPA completeness requires it.

ℹ️ This check is informational — findings do not block merging.
🛡️ Hyma Compliance Check · automated

@anathaniel-TS

Copy link
Copy Markdown

🛡️ Hyma Compliance Check — 2026-06-22

Automated review against GDPR, SOC 2, and Hyma internal policy.


🟡 MEDIUM — ROPA: New data flow — Figma plugin sends variable/style references to Studio backend

Files: src/utils/tokensStudio/pushThemeRefsRest.ts (new), src/utils/tokensStudio/updateThemeRefsViaRestApi.ts (new), src/app/store/middlewares/tokenState.ts

This PR establishes a new authenticated REST data flow: the Figma plugin now sends figmaVariableReferences and figmaStyleReferences back to the Studio-on-Rails backend via PATCH /api/v1/projects/{projectId}/theme_groups/{themeGroupId} and PATCH /api/v1/projects/{projectId}/theme_options/{themeOptionId}.

Data transferred:

  • Figma Variable IDs (internal Figma references, format: VariableID:xxx)
  • Figma Style IDs
  • Token names mapped to Figma Variable/Style IDs
  • Project ID, theme group ID, theme option ID

Authentication: OAuth Bearer token from the Figma plugin's Studio connection.

Risk:

  1. ROPA Art. 30: This is a new data transfer path from the Figma client to the Studio backend. If Hyma's ROPA documents the Figma plugin's data processing activities, this new sync path must be added.
  2. Figma as data source: Figma Variable IDs and Style IDs are Figma-internal identifiers. If the user's Figma files are under an enterprise Figma plan, this sync constitutes a new data export from Figma to Studio — confirm this aligns with any enterprise Figma DPA/ToS obligations.
  3. Error handling: pushThemeRefsRest.ts makes REST calls on every middleware trigger — confirm failure modes don't silently drop sync data or expose token details in error logs.

Recommended action:

  • Update ROPA to document the new Figma → Studio variable/style reference sync data flow.
  • Confirm Figma Variable IDs are not considered personal data under applicable agreements.

Taxonomy: ROPA | Severity: MEDIUM
Posted by the Hyma Compliance Agent · Notion PR Review

@anathaniel-TS

Copy link
Copy Markdown

🛡️ Hyma Compliance Check

⚠️ 2 finding(s) across 2 file(s)

Severity Category File Headline
🟡 MEDIUM Subprocessor packages/tokens-studio-for-figma/src/utils/tokensStudio/pushThemeRefsRest.ts New outbound PATCH write-path expands data sent to the Studio-on-Rails backend (previously read-only)
🟢 LOW Access Control packages/tokens-studio-for-figma/src/utils/tokensStudio/updateThemeRefsViaRestApi.ts OAuth bearer token sent on new write endpoints with per-write change_set_id (branch) re-resolution
Full finding details

[Subprocessor] New outbound PATCH write-path expands data sent to the Studio-on-Rails backend (previously read-only)

  • File: packages/tokens-studio-for-figma/src/utils/tokensStudio/pushThemeRefsRest.ts (lines 11-73; related: fetchBranchesListRest.ts ~28-54, updateThemeRefsViaRestApi.ts ~52-136, app/store/middlewares/tokenState.ts ~18-65)
  • Implication: This adds new fetch PATCH calls that write Figma variable/style reference maps back to the Tokens Studio Studio-on-Rails API (/api/v1/projects/.../theme_groups and /theme_options) on the OAuth sync path. The reference maps are design metadata (token-name → Figma variable/style ID) rather than personal data, but this materially expands the data flow to an existing subprocessor from read-only to read-write.
  • Recommended action: Before/after merging, confirm the Tokens Studio (Studio-on-Rails) subprocessor entry and DPA cover write-back of variable/style reference data, and update the ROPA data-flow record to reflect that this path now sends (not just receives) data; verify the target host is the production Studio API and not the preview/render.com host referenced in the PR description.

[Access Control] OAuth bearer token sent on new write endpoints with per-write change_set_id (branch) re-resolution

  • File: packages/tokens-studio-for-figma/src/utils/tokensStudio/updateThemeRefsViaRestApi.ts (lines 52-136; token usage in pushThemeRefsRest.ts ~28-40, 60-72)
  • Implication: The user's OAuth access token is read from the auth store and attached as an Authorization: Bearer header on the new write endpoints, and the change_set_id (branch/tenancy context) is re-resolved before each write. This is standard handling but constitutes new use of the credential against new mutating endpoints with tenancy-scoping logic.
  • Recommended action: Before/after merging, confirm write requests are scoped to the authenticated user's project/branch (no cross-tenant write), the bearer token is only sent over HTTPS to the trusted Studio host, and that failed writes (caught/logged) cannot silently desync access-controlled state.

ℹ️ This check is informational — findings do not block merging.
🛡️ Hyma Compliance Check · automated

@anathaniel-TS

Copy link
Copy Markdown

🛡️ Hyma Compliance Check

⚠️ 1 finding(s) across 3 file(s)

Severity Category File Headline
🟡 MEDIUM ROPA src/utils/tokensStudio/pushThemeRefsRest.ts New REST PATCH calls send Figma variable and style references to Studio-on-Rails backend
Full finding details

[ROPA] New REST API calls sync Figma variable/style references to Studio-on-Rails

  • File: src/utils/tokensStudio/pushThemeRefsRest.ts (lines 1–73), src/utils/tokensStudio/updateThemeRefsViaRestApi.ts, src/app/store/middlewares/tokenState.ts
  • Implication: When users modify $figmaVariableReferences or $figmaStyleReferences on themes in the Figma plugin (while using the TOKENS_STUDIO_OAUTH provider), the plugin now sends PATCH requests to [apiBaseUrl]/api/v1/projects/{projectId}/theme_groups/{id} and theme_options/{id} with the updated reference maps. This is a new data flow from the Figma plugin → Studio-on-Rails API. The data sent includes Figma variable IDs (e.g. VariableID:123:456) and style IDs (e.g. S:abc,) mapped to token names. These are Figma-internal identifiers, not personal data per se, but they constitute design asset data being synced to the Studio platform.
  • Recommended action: Confirm the ROPA "Figma Plugin → Studio Platform Sync" processing activity is updated to note that variable and style reference IDs from Figma are now synced (in addition to token sets and theme structures already covered). Verify the Studio-on-Rails API endpoints (/theme_groups/:id PATCH, /theme_options/:id PATCH) enforce the existing project authorization checks before accepting these writes.

ℹ️ This check is informational — findings do not block merging.
🛡️ Hyma Compliance Check · automated

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.

4 participants