Description
When the new dashboard creates a Plain support ticket via support.createTicket (tRPC), it calls plain.createThread() without the channel parameter. Plain's GraphQL API defaults channel to API in that case, so the resulting thread carries messageSource: "API".
Plain workflow conditions that filter on support channel = chat then skip these tickets silently — they never trigger the expected routing, auto-replies, or notifications.
The old frontend (/workspace/frontend/apps/web/app/api/support/tickets/route.ts:280) already sets channel: "CHAT" explicitly, so tickets opened through the legacy dashboard work correctly. This PR brings the new dashboard in line.
ThreadChannel is declared in @team-plain/typescript-sdk's .d.ts but not re-exported, so a @ts-expect-error directive is required — same pattern the old frontend uses. The literal "CHAT" matches the underlying enum value.
Diff:
const threadResult = await plain.createThread({
customerIdentifier: { customerId },
title: input.title,
tenantIdentifier: { externalId: tenantExternalId },
priority: severityToPriority[input.severity] ?? 2,
labelTypeIds: [labelTypeId],
+ // @ts-expect-error - ThreadChannel enum not exported from SDK but "CHAT" is valid.
+ // Without this, threads default to messageSource: "API", which causes Plain
+ // workflow conditions filtering on support channel = chat to skip silently.
+ channel: "CHAT",
});
How did I test this PR
pnpm typecheck — passes (exit 0). The @ts-expect-error is consumed by the channel: "CHAT" line; removing the comment would reintroduce the type error, confirming the directive is load-bearing.
pnpm lint — no new errors. The 5 pre-existing lint errors are in unrelated files (auth-error-toast.tsx, error-boundary.tsx, copyable-text.tsx).
- Verified against Plain SDK enum:
ThreadChannel.Chat = "CHAT" (node_modules/@team-plain/typescript-sdk/dist/index.d.ts), so the literal "CHAT" is the correct wire value.
- End-to-end runtime verification (open a ticket from the dashboard and confirm
messageSource: "CHAT" in Plain) is not feasible from this sandbox — Plain has no staging environment and the dashboard tRPC route requires an authenticated org session. Recommend confirming on the Vercel preview by creating one test ticket and checking the thread metadata in Plain.