Skip to content

ENG-3464: Configurable Jira completion status#8046

Merged
JadeCara merged 29 commits into
mainfrom
eng-3464/configurable-jira-completion-status
May 5, 2026
Merged

ENG-3464: Configurable Jira completion status#8046
JadeCara merged 29 commits into
mainfrom
eng-3464/configurable-jira-completion-status

Conversation

@JadeCara
Copy link
Copy Markdown
Contributor

@JadeCara JadeCara commented Apr 28, 2026

Ticket ENG-3464

Description Of Changes

Allows admins to configure which exact Jira status triggers Fides completion, instead of relying on the entire "done" category. This addresses clients like Toast who use multiple statuses within the done category (e.g., "Done" = privacy work finished, "Complete" = all departments done).

Key changes:

  • New needs_polling boolean column on JiraTicketTask — terminal flag that decouples the Fides completion decision from Jira's status category
  • New completion_status field in connection secrets — when set, only that exact Jira status name triggers completion
  • Frontend "Completion trigger" dropdown in the Jira config tab, scoped to the selected issue type
  • Hardened expired token handling — refresh_token_if_needed returns the DB-fresh ConnectionConfig so build_jira_client always uses the latest access token
  • Polling interval default reduced from 10 to 3 minutes
  • Backward compatible: completion_status = null preserves current behavior

Companion PR: fidesplus#3477

Code Changes

  • Add needs_polling column to JiraTicketTask model with partial index
  • Add completion_status: str | None to JiraTicketSchema connection secrets
  • Migration: add column, backfill existing done/deleted rows, replace partial index
  • Frontend: add "Completion trigger" <Select> to JiraConfigTab, scoped to selected issue type; cascading clear on project/issue type change
  • RTK Query: getJiraStatuses with required projectKey + issueType params
  • Fix stale OAuth token bug: refresh_token_if_needed now returns the fresh ConnectionConfig
  • Reduce default polling interval from 10 → 3 minutes
  • Fix: seed.py mailgun secrets type error (pass dict instead of Pydantic model)

Steps to Confirm

  1. Create a jira_ticket connection via API
  2. PATCH secrets with completion_status: "Complete" — verify it saves and reads back
  3. PATCH secrets with completion_status: null — verify it clears
  4. Verify needs_polling column exists in DB with default false
  5. Verify migration downgrade removes the column and restores old index
  6. Navigate to Jira integration config in admin UI — verify "Completion trigger" dropdown appears after issue type is selected
  7. Dropdown should show statuses for the selected issue type only
Screenshot 2026-04-28 at 9 29 02 AM
  1. Changing the issue type should clear the completion trigger selection
  2. Approve a privacy request with Jira configured — verify ticket creation succeeds (hardened token handling)

Pre-Merge Checklist

  • Issue requirements met
  • All CI pipelines succeeded
  • CHANGELOG.md updated
    • Add a db-migration This indicates that a change includes a database migration label to the entry if your change includes a DB migration
    • Updates unreleased work already in Changelog, no new entry necessary

Add `is_fides_complete` column to JiraTicketTask to decouple the Fides
completion decision from Jira's status category. Add `completion_status`
field to JiraTicketSchema so admins can select which exact Jira status
triggers completion instead of the entire "done" category.

- Model: add `is_fides_complete` boolean column with partial index
- Schema: add `completion_status: str | None` to connection secrets
- Migration: add column, backfill existing done rows, replace index
- Frontend: add "Completion trigger" dropdown to JiraConfigTab
- Fix: seed.py mailgun secrets dict, remove --webpack flag from package.json
- Tests: updated get_open_tasks tests for new is_fides_complete filter

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

vercel Bot commented Apr 28, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
fides-plus-nightly Ready Ready Preview, Comment May 5, 2026 5:57pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
fides-privacy-center Ignored Ignored May 5, 2026 5:57pm

Request Review

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 28, 2026

Dependency Review

✅ No vulnerabilities found.

Scanned Files

  • docs/fides/requirements.txt

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 28, 2026

Title Lines Statements Branches Functions
admin-ui Coverage: 8%
6.64% (3008/45280) 5.96% (1554/26044) 4.65% (622/13351)
fides-js Coverage: 78%
79.43% (2013/2534) 66.13% (1244/1881) 73.09% (345/472)
privacy-center Coverage: 88%
85.97% (331/385) 81.36% (179/220) 78.87% (56/71)

JadeCara and others added 2 commits April 28, 2026 09:14
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 28, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.14%. Comparing base (37ecd60) to head (f8dab0c).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8046   +/-   ##
=======================================
  Coverage   85.14%   85.14%           
=======================================
  Files         637      637           
  Lines       41936    41937    +1     
  Branches     4927     4927           
=======================================
+ Hits        35707    35708    +1     
  Misses       5121     5121           
  Partials     1108     1108           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- Fix stale OAuth token bug: refresh_token_if_needed now returns the
  DB-fresh ConnectionConfig so build_jira_client always uses the latest
  access_token (previously the caller's detached copy was used)
- Reduce Jira polling interval default from 10 to 3 minutes
- Require issue_type when fetching statuses (frontend skip + backend
  validation) so completion trigger only shows relevant statuses
- Fix mypy error in seed.py for MessagingConfig.set_secrets

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
JadeCara and others added 4 commits April 28, 2026 13:26
…n on issue type change

- Rename is_fides_complete to is_resolved across model, migration, and tests
  for clarity (flag means "terminal", not "succeeded")
- Rename migration file to match column name
- Backfill deleted tickets as resolved in migration
- Clear completion_status when issue type changes (handleIssueTypeChange)
- Make RTK query params required (skip guard ensures presence)
- Add inline comment on seed.py type ignore
- Fix test assertion for polling interval default (10 → 3)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The boolean flag controls whether the poller checks a ticket, not
whether the ticket "resolved" (which was ambiguous about success vs
failure). needs_polling = True (default) means the poller should
check it; False means it reached a terminal state.

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

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@JadeCara JadeCara marked this pull request as ready for review April 28, 2026 20:10
@JadeCara JadeCara requested review from a team as code owners April 28, 2026 20:10
@JadeCara JadeCara requested review from kruulik and thabofletcher and removed request for a team April 28, 2026 20:10
@JadeCara
Copy link
Copy Markdown
Contributor Author

/code-review

Copy link
Copy Markdown
Contributor

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Code Review: ENG-3464 — Configurable Jira completion status

Overall this is a clean, well-scoped change. The core design decision — decoupling the polling flag (needs_polling) from Jira's status category — is the right abstraction. It makes future completion-trigger variations easy to add and avoids re-querying solely based on Jira's opinionated categories. The backward-compat default (completion_status = null → any done-category status) is correct.

What's working well

  • Migration is safe: server_default=true for the new column, followed by a targeted backfill for terminal rows — correct ordering, no data loss risk.
  • Partial index: replacing external_status_category IS NULL OR external_status_category != 'done' with needs_polling = true is cleaner and more direct.
  • Frontend cascading: clearing completion_status when project or issue type changes is handled correctly at both levels.
  • allowClear + showSearch on the completion status <Select> are the right UX choices for an optional field over a potentially long list of statuses.
  • Test coverage: the new test_get_open_tasks_includes_done_category_still_needing_polling test captures the key behavioral change precisely.

Notable observations

  • Core logic is in the companion PR: The fides side adds the schema field and DB column; the actual logic that reads completion_status and sets needs_polling = false when the status matches lives in fidesplus#3477. Reviewers should confirm the two PRs are reviewed together so the full flow is validated end-to-end.
  • PR description step 4 says "Verify needs_polling column exists in DB with default false" — the migration/model actually set the default to true. Minor doc issue in the checklist.

Inline comments

Six inline comments attached covering: stale class docstring, polling interval impact, inline response type, migration backfill clarification, seed.py type-ignore, and || vs ?? in the save handler.


🔬 Codegraph: connected (47570 nodes)


💡 Write /code-review in a comment to re-run this review.

Comment thread src/fides/config/execution_settings.py
Comment thread clients/admin-ui/src/features/plus/plus.slice.ts
Comment thread src/fides/api/db/seed.py
Comment thread clients/admin-ui/src/features/integrations/configure-jira/JiraConfigTab.tsx Outdated
logger.info("Initiating scheduler for Jira ticket polling")
scheduler.add_job(
func=poll_jira_tickets,
func=poll_jira_tickets.delay,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this pattern something we've done before? it feels a bit weird to me -- have we tested this works as expected?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, this pattern exists in fidesplus already (poll_query_log_task.delay and digest tasks via .apply_async()), but is new for fides OSS. The rationale is better isolation — the polling task makes external HTTP calls to Jira, so running it on a worker avoids blocking an APScheduler thread slot on the webserver.

Verified locally with task_always_eager=False: the worker picks up the task, acquires the Redis lock, queries Jira, and completes in ~1.3s. No queue contention risk since it goes to the default fides queue, not the DSR queue.

Move our migration to the end of the chain so it depends on
3a91e5d4f7b2 instead of d71c7d274c04, which now has two children.

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

@jpople jpople left a comment

Choose a reason for hiding this comment

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

Frontend code looks good to me!

When a Jira OAuth token expires, both the Connection tab and Ticket Setup
tab now surface the issue clearly with a Re-authorize button that triggers
the existing OAuth flow. Previously, users saw empty dropdowns and a
failed test with no path to fix the connection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Only show the re-authorize alert on the Ticket Setup tab when the error
is specifically a token refresh failure (401 or detail contains "token
refresh failed"), not for any 400 error which could be a validation issue.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Plumb failureReason from test connection response through to
ConnectionStatusData so the Connection tab can distinguish token
failures from other errors. Add unit tests for JiraConfigTab auth
error detection covering: token refresh failure, 401, non-auth 400,
and missing onReauthorize prop.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Auto-trigger test connection after successful OAuth re-authorization
  using a ref flag + effect to avoid closure staleness
- Show "Testing connection…" spinner in status bar while test runs
- Use broader check for Connection tab re-authorize button (any failed
  test on OAuth Jira) since failure_reason isn't available on page load
- Plumb failureReason through ConnectionStatusData for future use

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Cast action and label to ReactNode instead of unknown
- Use AccessLevel.WRITE enum instead of string literal

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
JadeCara and others added 2 commits May 5, 2026 11:53
Use typed props instead of Record<string, unknown> to avoid
unknown-to-ReactNode cast that strict tsc rejects.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@JadeCara JadeCara added this pull request to the merge queue May 5, 2026
Merged via the queue into main with commit 328c5ef May 5, 2026
74 of 75 checks passed
@JadeCara JadeCara deleted the eng-3464/configurable-jira-completion-status branch May 5, 2026 18:15
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.

3 participants