Skip to content

feat(jira-wizard): add API-token-with-scopes auth-type selector (MNG-1744)#1491

Merged
aaight merged 1 commit into
devfrom
feature/mng-1744-jira-wizard-auth-type-selector
Jul 10, 2026
Merged

feat(jira-wizard): add API-token-with-scopes auth-type selector (MNG-1744)#1491
aaight merged 1 commit into
devfrom
feature/mng-1744-jira-wizard-auth-type-selector

Conversation

@aaight

@aaight aaight commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds the API-token vs API-token-with-scopes selector to the JIRA setup wizard (MNG-1744). Operators can now pick the JIRA auth mode in the wizard; the choice is persisted to integration config, hydrated in edit mode, and threaded into the discovery/verification credential bags as auth_type.

This is a frontend-only story. The backend already persists (jiraConfigSchema.authType — MNG-1736) and consumes (auth_type / authType in discovery + verification — MNG-1743) the value; both dependencies are merged.

Issue: https://linear.app/issue/MNG-1744

What changed

web/src/components/projects/pm-providers/jira/state.ts

  • New JiraWizardAuthType = 'basic' | 'scoped' union (single source of truth to prevent drift with the aggregate state type).
  • jiraAuthType field added to JiraWizardStateSlice (default 'basic').
  • New SET_JIRA_AUTH_TYPE action + reducer case that sets the value and clears verificationResult / verifyError (auth mode changes the host verification runs against, so a prior "Verified as …" result is stale).

web/src/components/projects/pm-wizard-state.ts

  • Composes jiraAuthType into the aggregate WizardState. The action is auto-composed via the existing JiraWizardAction union; initial state flows through createInitialJiraState(); reducer routing already delegates JIRA actions.

web/src/components/projects/pm-providers/jira/wizard.ts

  • JiraCredentialsAdapter now renders a basic / scoped segmented control (shadcn Button primitives, SSR-safe — no raw radio/select) above the credential inputs, with per-option helper text (scoped ⇒ api.atlassian.com gateway + granular scopes; basic ⇒ classic site-URL REST API). Wired to SET_JIRA_AUTH_TYPE.
  • buildIntegrationConfig persists authType.
  • buildEditState hydrates jiraAuthType from initialConfig.authType ?? 'basic' (legacy configs without the field default to basic).

web/src/components/projects/pm-providers/jira/auth.ts

  • Adds { role: 'auth_type', stateField: 'jiraAuthType' } to jiraAuthMetadata.rawCredentials. Because jiraAuthType always has a value, areCredentialsReadyFromMetadata still enables the Verify button and buildProviderAuthArgFromMetadata auto-includes auth_type in the verify credential bag.

web/src/components/projects/pm-providers/jira/hooks.ts

  • Threads auth_type: state.jiraAuthType into the jiraProjectsMutation credentials bag and authType: state.jiraAuthType into the jiraProjectDetails discovery call, so project/detail discovery routes through the correct host.

UX wording

Presented as a host-routing / security-scope choice, not a different auth protocol (per MNG-1735 research). Both modes still authenticate via email:api_token; the helper text avoids implying Bearer/OAuth setup.

Tests

  • pm-wizard-state.test.tsjiraAuthType default (basic), SET_JIRA_AUTH_TYPE action (sets value + clears verification, via both the slice reducer and the aggregate reducer), edit-mode hydration (scoped from config; basic fallback for legacy config).
  • pm-wizard-hooks.test.tsauth_type present in the verify / discovery credential bags for both basic (default) and scoped; rawCredentials role list includes auth_typejiraAuthType; buildIntegrationConfig persists authType.
  • jira-credentials-auth-type.test.ts (new) — renders the selector + helper text (basic ⇒ "site URL"; scoped ⇒ "api.atlassian.com"), credential inputs still present, selected state reflects jiraAuthType, and the control dispatches SET_JIRA_AUTH_TYPE.

All tests/unit/web (724 tests), PM conformance, and JIRA provider tests pass. biome check and web tsc --noEmit are clean.

Out of scope

Backend routing / discovery threading (MNG-1743) and config/credential persistence shape (MNG-1736) — both already merged.

🤖 Generated with Claude Code

🕵️ claude-code · claude-opus-4-8 · run details

@nhopeatall nhopeatall left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

APPROVE — clean, tightly-scoped frontend-only change that implements all seven MNG-1744 acceptance criteria and is correctly wired end-to-end. Verified the two "already merged" backend dependencies actually accept what this PR sends, ran the affected tests (126 pass), and confirmed CI is 7/7 green.

Verification performed

  • State/reducerjiraAuthType defaults to 'basic'; SET_JIRA_AUTH_TYPE sets the value and clears verificationResult/verifyError. Aggregate createInitialState() picks it up via createInitialJiraState(), and isJiraWizardAction (type.includes('JIRA')) routes the new action to the JIRA slice reducer.
  • Metadata path — adding { role: 'auth_type', stateField: 'jiraAuthType' } to rawCredentials does not regress areCredentialsReadyFromMetadata (field always non-empty) and makes buildProviderAuthArgFromMetadata auto-include auth_type in the verify/mutation bags.
  • Backend contracts confirmed present (not just assumed):
    • pm.discovery.discover credentials schema is z.record(z.string(), z.string()) — the extra auth_type key is accepted, and jiraManifest.createDiscoveryProvider reads creds.auth_type via coerceJiraAuthType.
    • integrationsDiscovery.jiraProjectDetails extends jiraCredsInput, which declares authType: z.enum(['basic','scoped']).optional() and threads it into withJiraCredentials.
    • jiraManifest.createCustomField reads credentials.auth_type, so the mutation bag that now carries auth_type still routes correctly.
    • jiraConfigSchema.authType exists, so buildIntegrationConfig persisting authType round-trips.
  • Persistence boundaryjiraAuthType is correctly kept out of jiraCredentialPersistence (non-secret; persisted through config authType, mirroring base_url).
  • Pattern consistency — the React.ComponentProps<typeof Button> & DataProps cast and Button-based segmented control match existing shared step components (label-mapping.tsx, trello/webhook-step.tsx); buildEditState correctly returns no raw credential values.

Minor (optional, non-blocking)

  • SET_JIRA_AUTH_TYPE clears the verification result but leaves jiraProjects/jiraProjectDetails populated. If an operator verifies under one host, then switches token type and re-verifies, the auto-fetch useEffect only refetches when jiraProjects.length === 0, so a stale project list from the prior host can persist. This is identical to the existing SET_JIRA_BASE_URL/SET_JIRA_EMAIL behavior (both also change the host and don't reset the project list), so it's consistent rather than a new regression — noting only because auth_type is explicitly a host-routing switch. Not a merge blocker.

🕵️ claude-code · claude-opus-4-8 · run details

@aaight aaight merged commit e779941 into dev Jul 10, 2026
9 checks passed
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.

2 participants