fix(pm-discovery): promote JIRA baseUrl from config into discovery credentials#1184
Merged
zbigniewsobiecki merged 1 commit intodevfrom Apr 24, 2026
Merged
Conversation
…edentials
Edit-mode re-verification in the JIRA wizard's Select Project step was
returning "Internal server error" because `pm.discovery.discover({ projectId })`
resolved credentials only from `project_credentials` — where JIRA's `baseUrl`
does not live. The JIRA `createDiscoveryProvider` factory built
`new Version3Client({ host: '' })` and the underlying jira.js client threw
"Couldn't parse the host URL."
Regression from spec 010/2, which replaced per-provider discovery procedures
with the generic `pm.discovery.discover`. The legacy `jiraProjectsByProject`
read `baseUrl` off integration config directly.
Fix: add an optional `configToCredentials(config): Record<string, string>`
hook to `PMProviderManifest`. The resolver invokes it on the `projectId`
path to seed the credentials bag with non-secret connection fields promoted
from `project_integrations.config`. `project_credentials` values override
on key collisions — DB-scoped secrets always win over config-derived defaults.
JIRA declares the hook to promote `baseUrl` → `base_url`.
The hook is generic (no JIRA `if` in shared infra), defensive (bad hook
returns or throws are caught and logged, discovery stays up), and preserves
the spec-009 "new provider touches zero shared files" invariant.
Also: refactored `resolvePMCredentials` to stay under the biome cognitive-
complexity threshold by extracting `promoteConfigCredentials` +
`loadIntegrationAndManifest` helpers.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This was referenced Apr 24, 2026
zbigniewsobiecki
added a commit
that referenced
this pull request
Apr 24, 2026
…ntials refactor (#1187) #1184 extracted `promoteConfigCredentials` + `loadIntegrationAndManifest` helpers but added five guard branches none of the new tests exercised (codecov patch coverage on that PR was 58.33%, below the 80% target). This commit pins each branch directly so the patch is in the green: - UNAUTHORIZED when projectId is set but effectiveOrgId is null - NOT_FOUND when no PM integration is configured for the project - NOT_FOUND when the saved integration belongs to a different provider - configToCredentials returning a non-object (string/null/array) is silently coerced to empty — resolved bag ends up project_credentials-only - configToCredentials throwing is swallowed with a console.warn; discovery still returns project_credentials — a broken hook cannot brick the wizard All five are behavioural contracts the original `resolvePMCredentials` upheld through inline conditionals; the refactor preserved them but moved them into the helpers. These tests make the contract explicit. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ua-store).configToCredentials(config)manifest hook so providers can promote non-secret connection fields fromproject_integrations.configinto the discovery credentials bag — JIRA wires it to promotebaseUrl→base_url.new-provider-surface.test.tsstill green).Root cause
Regression from spec 010/2 (generic
pm.discovery.discover). JIRA'sbaseUrllives onproject_integrations.config, notproject_credentials. The resolver only iteratedcredentialRoles→ returned{email, api_token}with nobase_url.createDiscoveryProviderthen builtnew Version3Client({ host: '' })→ jira.js threw "Couldn't parse the host URL."Legacy
jiraProjectsByProject(deleted in 010/2) readbaseUrldirectly from integration config. The generic replacement lost that step.First-time wizard setup was unaffected (wizard passes
credentials: { email, api_token, base_url }explicitly). Edit-mode re-verification broke.Fix shape
New optional manifest field:
projectIdpath ofresolvePMCredentials, not on the explicit-credentials path.project_credentialsvalues win on key collision — DB secret always beats config-derived default.JIRA implementation:
Extracted helpers (
promoteConfigCredentials,loadIntegrationAndManifest) keepresolvePMCredentialsunder biome's cognitive-complexity threshold.Tests (11 new cases, all green)
tests/unit/api/pm-discovery.test.ts— 4 router cases: hook is merged, DB creds win on collision, no-hook providers still work, hook not invoked on explicit-credentials path.tests/unit/pm/jira/manifest-config-to-credentials.test.ts— 7 unit cases pinning the JIRA hook contract (missing / empty / non-string / null / nested / unrelated fields).Hygiene
configToCredentialsinsrc/integrations/README.md.npm run lint,npm run typecheck, andnpx vitest run --project unit-api --project unit-coreall clean (6398 tests pass).Test plan
ua-storeJIRA wizard → Select Project loads project list instead of "Internal server error"🤖 Generated with Claude Code