@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Pile more atrocities onto the Maniphest burnup report

Summary:
See PHI273. Ref T13020. After D18777, tasks created directly into the default status (which is common) via the web UI no longer write a "status" transaction.

This is consistent with other applications, and consistent with the API/email behavior for tasks since early 2016. It also improves the consistency of //reading// tasks via the API.

However, it impacted the "Burnup Report" which relies on directly reading these rows to detect task creation. Until this is fixed properly (T1562), synthetically generate the "missing" transactions which this page expects by looking at task creation dates instead.

Specifically, we:

- Generate a fake `status: null -> "open"` transaction for every task by looking at the Task table.
- Go through the transaction list and remove all the legacy `status: null -> "any open status"` transactions. These will only exist for older tasks.
- Merge all our new fake transactions into the list of transactions.
- Continue on as though nothing happened, letting the rendering code continue to operate on legacy-looking data.

I think this will slightly miscount tasks which were created directly into a closed status, but this is very rare, and does not significantly impact the accuracy of this report relative to other known issues (notably, merging closed tasks).

This will also get the wrong result if the default status has changed from an "open" status to a "closed" status at any point, but this is exceptionally bizarre/rare.

Ultimately, T1562 will let us delete all this stuff and disavow its existence.

Test Plan:
- Created some tasks, loaded burnup before/after this patch.
- My local chart looks more accurate afterwards, but the data is super weird (I used `bin/lipsum` to create a huge number of tasks a couple months ago). I'll vet this on `secure`, which has more reasonable data.

Here's my local chart:

{F5356499}

That's what it //should// look like, it's just hard to be confident that nothing else is hiding there.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13020

Differential Revision: https://secure.phabricator.com/D18853

+55 -2
+55 -2
src/applications/maniphest/controller/ManiphestReportController.php
··· 99 99 ManiphestTaskMergedIntoTransaction::TRANSACTIONTYPE, 100 100 )); 101 101 102 + // See PHI273. After the move to EditEngine, we no longer create a 103 + // "status" transaction if a task is created directly into the default 104 + // status. This likely impacted API/email tasks after 2016 and all other 105 + // tasks after late 2017. Until Facts can fix this properly, use the 106 + // task creation dates to generate synthetic transactions which look like 107 + // the older transactions that this page expects. 108 + 109 + $default_status = ManiphestTaskStatus::getDefaultStatus(); 110 + $duplicate_status = ManiphestTaskStatus::getDuplicateStatus(); 111 + 112 + // Build synthetic transactions which take status from `null` to the 113 + // default value. 114 + $create_rows = queryfx_all( 115 + $conn, 116 + 'SELECT dateCreated FROM %T', 117 + id(new ManiphestTask())->getTableName()); 118 + foreach ($create_rows as $key => $create_row) { 119 + $create_rows[$key] = array( 120 + 'transactionType' => 'status', 121 + 'oldValue' => null, 122 + 'newValue' => $default_status, 123 + 'dateCreated' => $create_row['dateCreated'], 124 + ); 125 + } 126 + 127 + // Remove any actual legacy status transactions which take status from 128 + // `null` to any open status. 129 + foreach ($data as $key => $row) { 130 + if ($row['transactionType'] != 'status') { 131 + continue; 132 + } 133 + 134 + $oldv = trim($row['oldValue'], '"'); 135 + $newv = trim($row['oldValue'], '"'); 136 + 137 + // If this is a status change, preserve it. 138 + if ($oldv != 'null') { 139 + continue; 140 + } 141 + 142 + // If this task was created directly into a closed status, preserve 143 + // the transaction. 144 + if (!ManiphestTaskStatus::isOpenStatus($newv)) { 145 + continue; 146 + } 147 + 148 + // If this is a legacy "create" transaction, discard it in favor of the 149 + // synthetic one. 150 + unset($data[$key]); 151 + } 152 + 153 + // Merge the synthetic rows into the real transactions. 154 + $data = array_merge($create_rows, $data); 155 + $data = array_values($data); 156 + 102 157 $stats = array(); 103 158 $day_buckets = array(); 104 159 105 160 $open_tasks = array(); 106 161 107 - $default_status = ManiphestTaskStatus::getDefaultStatus(); 108 - $duplicate_status = ManiphestTaskStatus::getDuplicateStatus(); 109 162 foreach ($data as $key => $row) { 110 163 switch ($row['transactionType']) { 111 164 case ManiphestTaskStatusTransaction::TRANSACTIONTYPE: