Skip to content

feat(tasks): readable task numbers and a calendar view (spec 214) - #64

Merged
HecFranco merged 8 commits into
mainfrom
feat/214-task-number-calendar
Nov 7, 2026
Merged

HecFranco merged 8 commits into
mainfrom
feat/214-task-number-calendar

Conversation

@HecFranco

Copy link
Copy Markdown
Contributor

Spec 214 (Beacon specs/214-readable-task-id-and-calendar), the TaskBoard part. Audit status: pending batch audit.

Both features are opt-in. With task_numbers.enabled and calendar.enabled off, no route, service, table or output changes. The one exception: every host adds the nullable column task_board_tasks.number (DDL for MySQL, PostgreSQL and SQLite in UPGRADING).

Numbers

  • A #123 per tenant or per board, assigned at persistence, so all four creation paths get one.
  • The counter reserves in a short transaction of its own, on a second connection when the caller is in a transaction. It falls back to the caller's transaction after a 2-second lock wait.
  • The ledger keeps retired numbers and aliases.
  • nowo:task-board:numbers-backfill, TaskNumberLedger, route task_by_number, and the number on the card, panel, list, subtask tree and Gantt tooltip.

Calendar

  • Month, week and list modes, with filters in the URL and a query bounded by the visible days.
  • Route task_schedule and TaskManager::reschedule().
  • Body drag through UiKit's sortable, edge drag, a Reschedule dialog, grid keyboard, and Undo through the kit's toast. No drag on phones.

Tests

  • PHPUnit 100% statements (SQLite), PHPStan, cs, rector, twig lint, translations, Igor, Vitest.
  • demo/symfony8/e2e/tests/calendar.spec.ts in Chromium, Firefox, WebKit and the phone profile.

Task numbers (task_numbers.enabled): a #123 per tenant or per board, assigned
at persistence by a Doctrine listener, with a counter and a ledger, so numbers
are never reused and a task moved to another scope keeps the old one as an
alias. The route task_by_number answers the same 404 for unknown, retired and
unreadable numbers. A backfill command numbers older tasks.

Calendar (calendar.enabled): month, week and list modes with server filters in
the URL, a query bounded by the visible days, and the route task_schedule with
TaskManager::reschedule(). Drag uses UiKit's sortable, with keyboard and dialog
routes that need no pointer. No drag on phones.

Both are opt-in. Every host adds the nullable column task_board_tasks.number.
Audit status: pending batch audit.
…tarts

HY-L1: task_schedule accepts only the years the calendar shows.
HY-L2: purgeScope() refuses while a task still carries a number in the scope.
HY-L3: a synced task with no start date keeps none, instead of the creation
date. The Gantt still falls back to it through getPlannedStart().

Also: a task moved to a scope where its new number equals its old one now gets
its ledger row there. The listener looked at the number's change, not the board.
… on mobile

The ClickUp checklist parent check reads the id from the item instead of casting
the array key: rector process removed that cast as useless, which brought the bug
back. New test and fixture for an all-digit item that names itself as parent.

A bad date on task_schedule says the dates could not be changed, instead of
blaming the due date when the start was wrong. Rector's non-static failure().

The drag part of the board e2e is skipped on isMobile: a real device test decides it.
@HecFranco
HecFranco merged commit 2eb14bd into main Nov 7, 2026
17 checks passed
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.

1 participant