Plan — BJ-3: JiraOAuthAuthProvider#
Summary#
Create a concrete JiraOAuthAuthProvider that extends the Atlassian OAuth base class, and wire it into a new JiraModule using the same useFactory + PLATFORM_AUTH_PROVIDER pattern as GitHubModule. Registration is gated on JIRA_OAUTH_CLIENT_ID so the app still boots when Jira is unconfigured.
Files#
| Path | Action | Purpose |
|---|---|---|
src/atlassian/jira-oauth-auth.provider.ts | create | Concrete provider, platform = 'jira', token endpoint https://auth.atlassian.com/oauth/token, getBotUsername() returns JIRA_BOT_USERNAME. |
src/atlassian/jira-oauth-auth.provider.spec.ts | create | Unit tests: platform id, bot username, missing-config error path, token endpoint passed to base. |
src/atlassian/jira.module.ts | create | NestJS module with useFactory for PLATFORM_AUTH_PROVIDER; registers provider only when JIRA_OAUTH_CLIENT_ID is set. |
src/config/config.schema.ts | modify | Add optional Joi entries: JIRA_OAUTH_CLIENT_ID, JIRA_OAUTH_CLIENT_SECRET, JIRA_OAUTH_REFRESH_TOKEN, JIRA_SITE_URL, JIRA_CLOUD_ID, JIRA_PROJECT_KEY, JIRA_BOT_USERNAME. |
.env.example | modify | Document the seven JIRA_* env vars under a # Jira (optional) section. |
CLAUDE.md | modify | Add atlassian to the Key modules list with a one-line description. |
Steps#
- Add the seven
JIRA_*keys toconfigValidationSchemaasJoi.string().optional();JIRA_OAUTH_CLIENT_IDalso.optional()— it is the feature gate. - Document the same seven vars in
.env.examplewith placeholder values. - Create
JiraOAuthAuthProviderextendingAtlassianOAuthAuthProvider, settingreadonly platform = 'jira', passinghttps://auth.atlassian.com/oauth/tokento the base, and implementinggetBotUsername()fromJIRA_BOT_USERNAME(throw a descriptive error if missing). - Add unit tests covering:
platform === 'jira',getBotUsername()returns the configured value,getBotUsername()throws when unset, and the token endpoint is forwarded to the base constructor. - Create
JiraModulemirroringGitHubModuleshape:useFactorygated onconfig.get('JIRA_OAUTH_CLIENT_ID')returning aJiraOAuthAuthProvider(or undefined when unset); exportPLATFORM_AUTH_PROVIDER. - Update
CLAUDE.mdKey modules list to mentionatlassian — Atlassian (Jira/Confluence) OAuth providers.
Verification#
npm run lintandnpm run testpass with zero warnings; new spec file covers the four cases above.- App boots cleanly with no
JIRA_*env vars set (provider not registered; no throw). - With
JIRA_OAUTH_CLIENT_IDset,PLATFORM_AUTH_PROVIDERresolves to aJiraOAuthAuthProviderinstance whoseplatformis'jira'.
Risks#
- Base class not yet merged (#541 BJ-1 is OPEN). If
AtlassianOAuthAuthProviderdoes not exist at implementation time, follow the AGENTS.md "Wave N stub" guidance: add a minimal localatlassian-oauth-auth.provider.tsstub that satisfies thePlatformAuthProvidercontract, and remove it once #541 lands. - Two modules binding
PLATFORM_AUTH_PROVIDER.JiraModulemust not be imported globally alongsideGitHubModulein the same consumer scope — that would cause a duplicate-token conflict. KeepJiraModuleimport local to Jira-only consumers until Wave 2 resolves multi-platform routing.
Assumptions#
- Base class
AtlassianOAuthAuthProvideraccepts a token endpoint URL via constructor (mirrors typical OAuth base patterns); if its shape differs once #541 merges, adjust the subclass accordingly in this same PR. JIRA_BOT_USERNAMEis the authoritative identity string; no derivation fromJIRA_CLOUD_IDis required.