Skip to content

fix(linear): unblock wizard Save + UX polish for Linear PM setup#1113

Merged
zbigniewsobiecki merged 10 commits intodevfrom
zs/002-linear-wizard-setup-ux
Apr 15, 2026
Merged

fix(linear): unblock wizard Save + UX polish for Linear PM setup#1113
zbigniewsobiecki merged 10 commits intodevfrom
zs/002-linear-wizard-setup-ux

Conversation

@zbigniewsobiecki
Copy link
Copy Markdown
Member

Summary

Fixes spec 002-linear-webhook-setup-ux end-to-end. Two plans landed:

  1. plan 002/1 — save-path-fix. Linear PM wizard Save was returning HTTP 500 on dev. Diagnosed as a 23514 check-constraint violation on chk_integration_category_provider (predates Linear support — Linear was never added to the allowed pm providers when feat(wizard): add Linear as PM provider option in dashboard wizard #1107 shipped). Fixed with migration 0049_allow_linear_pm_provider.sql. Also hardened the dashboard error path so future failures of this shape are immediately diagnosable from server logs (src/api/errorLogging.ts: formatters for Hono app.onError + tRPC errorFormatter that surface PG code, detail, constraint, table when present).

  2. plan 002/2 — wizard-webhooks-step. The Webhooks step of the Linear wizard now matches reality: the "Enable events" list recommends exactly the three event families CASCADE consumes (Issues, Comments, Issue Labels) with a one-line rationale each, and the previously missing signing-secret input is rendered inline via the existing ProjectSecretField component — no detour to the Credentials tab. PMWizard threads the masked LINEAR_WEBHOOK_SECRET credential from projects.credentials.list through WebhookStep, so the field reflects existing values on mount and stays in sync with the Credentials tab.

Also includes an unrelated CLAUDE.md rewrite (streamlined from ~820 to ~163 lines) that the author had in-flight; kept as its own commit.

User-visible

  • Linear PM wizard Save succeeds end-to-end on dev.
  • Webhooks step lists the three events CASCADE actually handles, not just "Issues".
  • Webhook signing secret is entered inline in the wizard, directly below the webhook URL.
  • Dashboard error logs now contain real DB error details on 500s; clients still receive a safe generic message.

Tests

  • 17 new SSR component tests (tests/unit/web/linear-webhook-info-panel.test.ts, pm-wizard-webhooks-step.test.ts) — render components via react-dom/server.renderToStaticMarkup and assert against the HTML string. No new test infrastructure added (web/ has no @testing-library/react, and it would be out-of-scope for a UX-polish plan). Interactive mutation firing is intentionally out of scope; ProjectSecretField's internals are untested today under the same constraint and spec non-goal forbids modifying it.
  • 15 new unit tests for error-logging formatters (tests/unit/api/error-logging.test.ts).
  • 2 new integration tests for upsertProjectIntegration with Linear provider.
  • 4 new log-hygiene integration tests (tests/integration/api/no-secret-leakage.test.ts) proving plaintext credentials never leak on credential-save, success, or failure paths.

Totals: 7585 unit + 522 integration — all green. Lint + typecheck (root + web) clean.

Migration note

0049_allow_linear_pm_provider.sql must run on dev before the Save step works for Linear. Drops and re-creates the chk_integration_category_provider CHECK with linear added to the pm branch; forward-only, no data migration.

Test plan

  • npm test — 7585 passing
  • TEST_DATABASE_URL=... npm run test:integration — 522 passing
  • npm run lint — clean
  • npm run typecheck (root) — clean
  • cd web && npx tsc -b — clean
  • On dev after deploy: complete the Linear wizard end-to-end on a fresh project, confirm the integration row is persisted and the signing secret appears masked in the Credentials tab.
  • On dev after deploy: re-open the wizard on an already-configured Linear project and confirm the masked-secret state is shown.
  • On dev after deploy: walk Trello + JIRA wizards end-to-end to confirm no regressions in their Webhooks steps.

🤖 Generated with Claude Code

zbigniewsobiecki and others added 10 commits April 15, 2026 19:05
Spec 002 (linear-webhook-setup-ux) introduces the Linear wizard UX
improvements and save-path fix. Plan 1 locked for execution.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds src/api/errorLogging.ts with formatters that surface pg driver
fields (code, detail, constraint, table) onto server-side logs for
both Hono app.onError and the tRPC errorFormatter. Client responses
for INTERNAL_SERVER_ERROR now carry a generic message; real details
remain in cascade-dashboard-* stdout for operators to grep.

plan 002/1 task 1.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… constraint

The chk_integration_category_provider check constraint (from
0047_add_alerting_integration.sql) only permitted trello/jira for
pm-category integrations. Linear support was introduced without a
matching constraint update, so every projects.integrations.upsert
for category=pm + provider=linear failed with SQLSTATE 23514 and
surfaced as HTTP 500 from the dashboard Linear wizard.

Migration 0049 drops and re-creates the constraint with linear added
to the pm branch. Forward-only, no data migration required.
Reproduced with two new integration tests against the test DB.

plan 002/1 tasks 2-3 (diagnose + fix).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Integration tests that spy on console.{log,error,warn} around
writeProjectCredential, upsertProjectIntegration (happy + FK-violation
paths), and the formatTRPCErrorLog formatter. Asserts the sentinel
credential value never appears in captured output, while confirming
the real PG error (SQLSTATE + constraint name) IS present on the
failure path — proving diagnosability without leakage.

plan 002/1 task 4.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…Save

All 11 per-plan ACs pass. Spec ACs #5-8 delivered:
- Linear upsert succeeds on fresh projects and re-configuration
- DB error diagnostics (SQLSTATE, constraint, detail) surface in server logs
- tRPC clients receive generic 'Internal server error' for unexpected throws
- Plaintext credentials never leak into captured stdout/stderr

Caveat: CLAUDE.md addition deferred to avoid conflicting with the
user's in-progress rewrite of that file. Doc impact met via CHANGELOG.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Plan 2 originally assumed @testing-library/react in web/; project has no
such infrastructure and the web/ package has no test script. Plan edited
in place to:
- use react-dom/server.renderToStaticMarkup (available; no new deps)
- test under the existing root unit-core project
- drop interactive-mutation tests (would need jsdom); ProjectSecretField
  internals are out-of-scope per spec non-goal

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…igning secret

Plan 002/2 (wizard-webhooks-step).

Linear PM wizard Webhooks step now:
- lists the three event families CASCADE consumes (Issues, Comments,
  Issue Labels), each with a one-line rationale tracing to
  src/triggers/linear/
- renders a ProjectSecretField bound to LINEAR_WEBHOOK_SECRET directly
  beneath the webhook URL, matching the Sentry alerting tab pattern
- drops the 'store as LINEAR_WEBHOOK_SECRET in project credentials'
  trailing bullet (replaced by the inline input)

PMWizard threads projectId + the masked LINEAR_WEBHOOK_SECRET credential
meta from projects.credentials.list through WebhookStep, so the field
reflects its own stored value on mount and stays in sync with the
Credentials tab.

Tests: 17 new SSR tests using react-dom/server — no React testing
library required. Interactive mutation firing is out of scope (would
need jsdom); ProjectSecretField itself is untested today under the
same constraint and is spec non-goal to modify.

vitest.config.ts gains @/components, @/lib, @/hooks aliases pointing at
web/src/ for test-time resolution.

src/integrations/README.md Linear section defers to the dashboard
wizard as the authoritative setup source.

Plan 2 closes out spec 002.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Compacts the project's CLAUDE.md from ~820 to ~163 lines by dropping
dated setup minutiae, duplicated process docs, and legacy sections.
Keeps the load-bearing context: architecture, PR checkout gotcha,
testing commands, Zod policy, migrations, GitHub dual-persona rules,
trigger system, engines, environment, and git hooks.

No code changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 15, 2026

Codecov Report

❌ Patch coverage is 77.31092% with 27 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/api/errorLogging.ts 83.80% 14 Missing and 3 partials ⚠️
src/dashboard.ts 0.00% 6 Missing ⚠️
src/api/trpc.ts 50.00% 4 Missing ⚠️

📢 Thoughts on this report? Let us know!

@zbigniewsobiecki zbigniewsobiecki merged commit ac6773a into dev Apr 15, 2026
8 of 9 checks passed
@zbigniewsobiecki zbigniewsobiecki deleted the zs/002-linear-wizard-setup-ux branch April 15, 2026 17:32
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