Completed (done) cards still flagged as overdue — getDueStatus() ignores done field
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 1.4k
- Forks
- 354
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 43
Description
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
overduefield 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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with lib/Model/CardDetails.php and its getDueStatus() method, then compare lib/Db/Card.php with the done-card exclusion in CardMapper.php. Verify the Deck API card response from GET /index.php/apps/deck/api/v1.0/boards/{id}/stacks so a completed card with a past duedate is no longer reported as overdue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100