Bug: Completed (done) cards still flagged as overdue via API overdue field
Nextcloud Deck version: 1.17.1
Nextcloud version: 33.0.3
Description
When a card is marked as "done" (the done field set to a timestamp), the Nextcloud Deck API still returns overdue: 3 (the DUEDATE_OVERDUE constant) on that card if its original duedate is in the past. The overdue field computation does not check the done status of the card.
This causes third-party apps (e.g., Next Deck on iOS/Android) and API consumers to display completed tasks as overdue, even when they have a visible "done" checkmark.
Steps to Reproduce
- Create a card in Nextcloud Deck with a due date in the past (e.g., May 2)
- Mark the card as done (set the done checkbox)
- Query the card via the Deck API:
GET /index.php/apps/deck/api/v1.0/boards/{id}/stacks
Expected Behavior
The overdue field on a done card should return 0 (DUEDATE_FUTURE) or a new value indicating "completed" — not 3 (DUEDATE_OVERDUE). A card that has been completed should never be flagged as overdue regardless of its original due date.
Actual Behavior
The API returns overdue: 3 for done cards with past due dates:
{
"title": "Review ALL DNS configurations for jeepnet.tech",
"done": "2026-05-31T12:50:09+00:00",
"duedate": "2026-05-03T00:00:00+00:00",
"overdue": 3
}
Root Cause
In lib/Model/CardDetails.php, the getDueStatus() method computes the overdue state based solely on getDaysUntilDue(), which only compares the duedate to the current date. It does not check $this->getDone():
private function getDueStatus(): int {
$diffDays = $this->getDaysUntilDue();
if ($diffDays === null || $diffDays > 1) {
return static::DUEDATE_FUTURE; // 0
}
if ($diffDays === 1) {
return static::DUEDATE_NEXT; // 1
}
if ($diffDays === 0) {
return static::DUEDATE_NOW; // 2
}
return static::DUEDATE_OVERDUE; // 3 — reached even when done
}
And in lib/Db/Card.php, getDaysUntilDue() only checks duedate, not done:
public function getDaysUntilDue(): ?int {
if ($this->getDuedate() === null) {
return null;
}
// ... compares duedate to today, no done check
}
Notably, the database query layer in CardMapper.php does correctly exclude done cards from overdue queries (->andWhere($qb->expr()->isNull('done'))), but the per-card overdue field in API responses bypasses this.
Suggested Fix
Add a done check to getDueStatus():
private function getDueStatus(): int {
if ($this->getDone() !== null) {
return static::DUEDATE_FUTURE; // or a new DUEDATE_COMPLETED constant
}
$diffDays = $this->getDaysUntilDue();
// ... rest of existing logic
}
This would ensure that completed cards are never flagged as overdue in API responses, which would also fix the issue for all third-party apps consuming the API.
Impact
- Third-party apps (Next Deck, etc.) that rely on the
overdue field display completed tasks as overdue
- Any API consumer filtering by overdue status gets false positives
- The web UI may also be affected depending on which code paths it uses
Bug: Completed (done) cards still flagged as overdue via API
overduefieldNextcloud Deck version: 1.17.1
Nextcloud version: 33.0.3
Description
When a card is marked as "done" (the
donefield set to a timestamp), the Nextcloud Deck API still returnsoverdue: 3(theDUEDATE_OVERDUEconstant) on that card if its originalduedateis in the past. Theoverduefield computation does not check thedonestatus of the card.This causes third-party apps (e.g., Next Deck on iOS/Android) and API consumers to display completed tasks as overdue, even when they have a visible "done" checkmark.
Steps to Reproduce
GET /index.php/apps/deck/api/v1.0/boards/{id}/stacksExpected Behavior
The
overduefield on a done card should return0(DUEDATE_FUTURE) or a new value indicating "completed" — not3(DUEDATE_OVERDUE). A card that has been completed should never be flagged as overdue regardless of its original due date.Actual Behavior
The API returns
overdue: 3for done cards with past due dates:{ "title": "Review ALL DNS configurations for jeepnet.tech", "done": "2026-05-31T12:50:09+00:00", "duedate": "2026-05-03T00:00:00+00:00", "overdue": 3 }Root Cause
In
lib/Model/CardDetails.php, thegetDueStatus()method computes the overdue state based solely ongetDaysUntilDue(), which only compares theduedateto the current date. It does not check$this->getDone():And in
lib/Db/Card.php,getDaysUntilDue()only checksduedate, notdone:Notably, the database query layer in
CardMapper.phpdoes correctly exclude done cards from overdue queries (->andWhere($qb->expr()->isNull('done'))), but the per-cardoverduefield in API responses bypasses this.Suggested Fix
Add a
donecheck togetDueStatus():This would ensure that completed cards are never flagged as overdue in API responses, which would also fix the issue for all third-party apps consuming the API.
Impact
overduefield display completed tasks as overdue