fix(task-delivery): surface Jira work from emailless assignees via accountId fallback (#1776) - #1827
Conversation
…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>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe task delivery materialized view now falls back to ChangesJira assignee fallback attribution
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
Ready for review. All substantive lanes are green — including the e2e The only red check is K3s GitOps Deploy, which is the known-flaky lane (it failed on a pre-existing |
|
Closing: this accountId-fallback keys emailless assignees under a synthetic |
Closes #1776.
Problem
Per-person Task Delivery metrics key each Jira issue by resolving the assignee's
accountIdto an email. When the account exposes no email (on a realistic dataset only ~31% of Jira accounts carry one),assignee_emailwas left empty ininsight.task_issue_current_state, and every downstream metric dropped the row via itsassignee_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, migration20260708000000_task-delivery-status-category.sql). Emailless assignees survive the LEFT JOIN with an emptyassignee_email, then get filtered out by theassignee_email IS NOT NULL AND assignee_email != ''guards on every metric CTE.jira_closed_taskseven writescoalesce(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_emailfrom:multiIf( u.email != '', lower(u.email), s.assignee_account_id != '', concat('jira-account:', s.assignee_account_id), '' ) AS assignee_emailjira-account:<accountId>key (the issue's pre-approved "accountId-based fallback" outcome) instead of being discarded.jira-account:prefix can't collide with an email (no@) and never matchesinsight.people, soorg_unit_idstays NULL: the person is honestly unattributed (peer stats render as "No peer data") rather than folded into a wrong cohort.u.email != ''→lower(u.email)), so existing behavior and all existing e2e specs are unaffected.Because
task_issue_current_stateis a plain view read at query time byjira_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 whosejira_user.emailis empty and who has no org-chart identity closes 2 tasks; querying hisjira-account:<id>key must returntasks_completed = 2. Pre-fix that person produced no rows at all. Asserted via CEL onitems(notfind), 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
Tests