Skip to content

fix(task-delivery): surface Jira work from emailless assignees via accountId fallback (#1776) - #1827

Closed
cyberantonz wants to merge 1 commit into
constructorfabric:mainfrom
cyberantonz:fix/jira-emailless-assignee-fallback
Closed

fix(task-delivery): surface Jira work from emailless assignees via accountId fallback (#1776)#1827
cyberantonz wants to merge 1 commit into
constructorfabric:mainfrom
cyberantonz:fix/jira-emailless-assignee-fallback

Conversation

@cyberantonz

@cyberantonz cyberantonz commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Closes #1776.

Problem

Per-person Task Delivery metrics key each Jira issue by resolving the assignee's accountId to an email. When the account exposes no email (on a realistic dataset only ~31% of Jira accounts carry one), assignee_email was left empty in insight.task_issue_current_state, and every downstream metric dropped the row via its assignee_email != '' guard.

Result: ~17% of all assigned issues silently vanished from every per-person metric (Tasks Completed, MTTR, Dev Time, Estimation Accuracy, Bugs Fixed, Reopen Rate, …), and team/manager rollups undercounted. The person read as "did nothing" rather than "couldn't attribute" — absent from gold, not present-but-null.

Root cause

assignee_email = lower(u.email) with no fallback (task_issue_current_state, migration 20260708000000_task-delivery-status-category.sql). Emailless assignees survive the LEFT JOIN with an empty assignee_email, then get filtered out by the assignee_email IS NOT NULL AND assignee_email != '' guards on every metric CTE. jira_closed_tasks even writes coalesce(assignee_email,'') AS person_id, but the != '' filter makes that fallback dead code.

Fix

Derive the person key with a fallback in the one view every per-person metric reads assignee_email from:

multiIf(
    u.email != '',               lower(u.email),
    s.assignee_account_id != '', concat('jira-account:', s.assignee_account_id),
    ''
) AS assignee_email
  • Emailless-but-assigned work is surfaced under a stable jira-account:<accountId> key (the issue's pre-approved "accountId-based fallback" outcome) instead of being discarded.
  • Truly unassigned issues (no accountId) keep an empty key and stay excluded — no false "unassigned person".
  • The jira-account: prefix can't collide with an email (no @) and never matches insight.people, so org_unit_id stays NULL: the person is honestly unattributed (peer stats render as "No peer data") rather than folded into a wrong cohort.
  • The emailed path is byte-identical to before (u.email != ''lower(u.email)), so existing behavior and all existing e2e specs are unaffected.

Because task_issue_current_state is a plain view read at query time by jira_closed_tasks, task_dev_seconds_per_issue, task_close_events_daily, task_reopen_events_daily, etc., the single change propagates to all Task Delivery metrics.

Test

Adds an e2e regression fixture (task_delivery_tasks_completed_emailless_assignee_jira.test.yaml): an assignee whose jira_user.email is empty and who has no org-chart identity closes 2 tasks; querying his jira-account:<id> key must return tasks_completed = 2. Pre-fix that person produced no rows at all. Asserted via CEL on items (not find), since an unattributed person legitimately has null peer stats.

Note

This surfaces the work and stops the silent drop; full attribution of emailless accounts to org teams remains the domain of the identity-resolution effort (#1765/#1766). The chosen fallback is deliberately compatible with that direction — it's a distinct, greppable key namespace, not a guessed email.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved task assignment tracking for Jira issues where the assignee has no email address.
    • Preserved metric visibility by using a Jira account identifier when email data is unavailable.
    • Correctly excludes unassigned issues from assignee-based results.
  • Tests

    • Added coverage confirming completed-task metrics work with email-less Jira assignees and date filters.

…countId fallback (constructorfabric#1776)

Per-person Task Delivery metrics key each Jira issue by resolving the
assignee's accountId to an email. When the account exposes no email (only
~31% do), `assignee_email` was left empty in `task_issue_current_state` and
every downstream metric dropped the row via its `assignee_email != ''`
guard — so ~17% of assigned issues silently vanished from all per-person
metrics and every team/manager rollup undercounted. The person read as
"did nothing" rather than "couldn't attribute".

Derive the person key with a fallback: prefer the email; when it's empty,
use a namespaced `jira-account:<accountId>` key so the work is surfaced as
an unattributed-but-present person instead of discarded. Truly unassigned
issues (no accountId) keep an empty key and stay excluded. The prefix can't
collide with an email (no '@') and never matches insight.people, so
org_unit_id stays NULL (honestly unattributed — peer stats show "No peer
data" rather than a wrong cohort).

The fix is a single expression in `task_issue_current_state`, the one view
every per-person Task Delivery metric reads `assignee_email` from, so it
propagates to tasks_completed, MTTR, dev time, estimation accuracy, bugs
fixed, reopen rate, etc. The emailed path is byte-identical to before.

Adds an e2e regression test: an emailless assignee who closes 2 tasks must
appear under the accountId fallback key (pre-fix: no rows at all).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Anton Zelenov <antonz@constructor.tech>
@cyberantonz
cyberantonz requested a review from a team as a code owner July 20, 2026 06:39
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9dd38276-df93-41b0-981c-167d8dab100e

📥 Commits

Reviewing files that changed from the base of the PR and between 5fd666d and 8ed3a79.

📒 Files selected for processing (2)
  • src/ingestion/scripts/migrations/20260708000000_task-delivery-status-category.sql
  • src/ingestion/tests/e2e/metrics/task_delivery_tasks_completed_emailless_assignee_jira.test.yaml

📝 Walkthrough

Walkthrough

The task delivery materialized view now falls back to jira-account:<accountId> when a Jira assignee lacks an email. A new E2E fixture verifies tasks_completed attribution and date filtering for that case.

Changes

Jira assignee fallback attribution

Layer / File(s) Summary
Assignee key derivation
src/ingestion/scripts/migrations/20260708000000_task-delivery-status-category.sql
The view now uses a lowercased email when available, otherwise jira-account:<accountId>, and returns an empty value for unassigned issues.
Tasks completed regression coverage
src/ingestion/tests/e2e/metrics/task_delivery_tasks_completed_emailless_assignee_jira.test.yaml
The E2E fixture seeds two closed issues for an emailless Jira account and verifies tasks_completed = 2.0 for the fallback person key, with no results in an unrelated date range.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers: ktursunov

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding an accountId fallback for Jira assignees without email in Task Delivery.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cyberantonz

Copy link
Copy Markdown
Contributor Author

Ready for review. All substantive lanes are green — including the e2e metrics lane (bronze→dbt→gold→API, 12m14s) that runs the edited migration and the new emailless-assignee regression test.

The only red check is K3s GitOps Deploy, which is the known-flaky lane (it failed on a pre-existing DROP VIEW IF EXISTS insight.task_status_intervals under ClickHouse 25.7 — unrelated to this change; my only edit is the assignee_email expression). Safe to disregard for this PR.

@cyberantonz

Copy link
Copy Markdown
Contributor Author

Closing: this accountId-fallback keys emailless assignees under a synthetic jira-account:<id> identity, which surfaces the work but does not actually attribute it (org_unit stays NULL, no team rollup). The correct fix is to resolve these accounts through the identity-resolution service (#1765/#1766) so they map to real persons/teams — that's a substantial effort, not a quick win. Declining #1776 here in favor of that path.

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.

Jira work assigned to accounts with no email is silently dropped from all per-person Task Delivery metrics

1 participant