feat: add Figma design previews and plugin issue linking#718
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 08b0ec54ae
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| _, err = tx.Exec(ctx, ` | ||
| insert into provider_job (workspace_id, workspace_integration_id, provider, kind, status, payload, scheduled_at, updated_at) | ||
| values ($1::uuid, (select id from workspace_integration where workspace_id=$1::uuid and provider='figma' and status in ('connected','degraded') limit 1), 'figma', 'metadata_refresh', 'queued', $2::jsonb, now(), now())`, workspaceID, raw) |
There was a problem hiding this comment.
Add the metadata_refresh job kind before enqueueing
When an issue description or comment contains a Figma URL, this enqueue path inserts provider_job.kind='metadata_refresh', but packages/proto/migrations/0007_integration_provider_lifecycle.sql still constrains kind to webhook_ingestion, outbound_delivery, backfill, or sync, and this commit does not alter that check. In those inputs the insert returns a constraint violation, SyncSources returns an error, and the surrounding issue/comment create or update rolls back instead of saving.
Useful? React with 👍 / 👎.
| if got := setupRequirement("figma"); got != nil { | ||
| t.Fatalf("configured figma requirement = %#v", got) | ||
| t.Setenv("AUTH_INTERCOM_ID", "") |
There was a problem hiding this comment.
Close the Figma setupRequirement assertion
This if got := setupRequirement("figma"); got != nil { block is missing its closing brace before the Intercom setup checks, so the rest of TestSetupRequirement remains nested in the if and the following func TestCanManage is parsed inside the function body. As a result, the integrations test package will not compile once the Go toolchain parses this file.
Useful? React with 👍 / 👎.
08b0ec5 to
0f66c68
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0f66c683b4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| _, err = tx.Exec(ctx, ` | ||
| insert into provider_job (workspace_id, workspace_integration_id, provider, kind, status, payload, scheduled_at, updated_at) | ||
| values ($1::uuid, (select id from workspace_integration where workspace_id=$1::uuid and provider='figma' and status in ('connected','degraded') limit 1), 'figma', 'metadata_refresh', 'queued', $2::jsonb, now(), now())`, workspaceID, raw) |
There was a problem hiding this comment.
Add a worker to process Figma metadata jobs
When a source is linked/created or the user clicks Refresh, this enqueue succeeds but nothing ever claims provider='figma'/kind='metadata_refresh': apps/api/cmd/api/main.go only starts Slack, MicrosoftTeams, Sentry, Salesforce, Front, Intercom, and Zendesk workers, and a repo-wide search for metadata_refresh only finds these enqueue sites. As a result, linked Figma cards never get refreshed name/thumbnail/error metadata even though the UI reports a refresh; add a Figma worker/claim loop or fetch the metadata synchronously before returning success.
Useful? React with 👍 / 👎.
| result, err := h.DB.Exec(r.Context(), ` | ||
| delete from figma_source | ||
| where workspace_id=$1::uuid and issue_id=$2::uuid and container_type='plugin' | ||
| and (($3 <> '' and id=$3::uuid) or ($4 <> '' and normalized_url=$4))`, p.WorkspaceID, issue.ID, strings.TrimSpace(input.SourceID), normalizedURL) |
There was a problem hiding this comment.
Broadcast Figma unlink mutations to sync clients
When the plugin unlinks a Figma source while another client has the issue open, this delete is returned as successful without adding an operation entry, unlike the link path above which calls syncapi.InsertOperation after mutating figma_source. WebSocket/offline-sync clients therefore keep the stale preview card until a full issue refetch; wrap the delete in a transaction and insert an issue updated operation when rows are removed.
Useful? React with 👍 / 👎.
|
Controller disposition for current head Evidence:
Required before merge: rebase onto current |
…pair # Conflicts: # apps/web/src/components/issue-detail-view.tsx # packages/proto/openapi.yaml # packages/sdk/src/generated.ts
|
Controller update: conflict repaired on current head a878ddb. PR is now MERGEABLE/CLEAN and origin/staging is an ancestor of the PR head. Focused checks passed: OpenAPI coverage, web SDK guard, SDK typecheck/test/build, issue-detail Vitest, and Go tests for internal/figma + internal/integrations. Remaining blocker is broad make check baseline syntax errors outside this PR diff in apps/web/src/app/(app)/settings/integrations/page.tsx and apps/web/tests/integrations-view.test.tsx. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a878ddb4f2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| problem.Write(w, http.StatusInternalServerError, "Create Figma issue failed", err.Error()) | ||
| return | ||
| } | ||
| if _, err := syncapi.InsertOperation(r.Context(), tx, p.WorkspaceID, "issue", issue.ID, "created", issue, p.UserID); err != nil { |
There was a problem hiding this comment.
Publish Figma plugin issue operations
When the Figma plugin creates an issue, this inserts an operation but discards it and returns without calling syncapi.PublishOperations after the commit; the link handler below does the same. I checked apps/api/internal/sync/handler.go: connected WebSocket clients only receive live updates from the Redis publish path, and DB rows are only replayed when they reconnect. Thus a user with the team list or issue open won't see plugin-created issues/links until a reconnect or manual refresh, unlike the normal issue create path which publishes the inserted op.
Useful? React with 👍 / 👎.
| properties: | ||
| issueId: { type: string, format: uuid } | ||
| identifier: { type: string } | ||
| sourceId: { type: string, format: uuid } | ||
| source: { $ref: '#/components/schemas/FigmaPluginSourceInput' } |
There was a problem hiding this comment.
Require the source for Figma link requests
For POST /integrations/figma/plugin/links, the handler immediately calls normalizeFigmaPluginSource(input.Source), so a request that follows this schema with only issueId/identifier or sourceId compiles in the generated SDK but reaches the server with an empty source.url and is rejected as 400. Since DELETE can use sourceId but POST cannot, split the schemas or mark source required for the link operation so plugin clients don't generate invalid link calls.
Useful? React with 👍 / 👎.
|
Controller disposition for current head Current blocker:
Required before merge: rebase or rebuild on fresh |
Summary
Verification
node scripts/check-openapi-coverage.mjspassed.node scripts/check-web-sdk-usage.mjspassed.pnpm --filter @namuh-eng/expn-sdk typecheckpassed.pnpm --filter @namuh-eng/expn-sdk testpassed.pnpm --filter @exponential/web exec vitest run tests/issue-detail-view.test.tsxpassed.cd apps/api && PATH="/home/jaeyunha/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.25.10.linux-amd64/bin:$PATH" go test ./internal/figma ./internal/integrationspassed.make checkis blocked by baseline syntax errors outside this PR's diff inapps/web/src/app/(app)/settings/integrations/page.tsxandapps/web/tests/integrations-view.test.tsx.