Same records, more ways in. Cheap to add on this platform and the thing evaluators reach for first.
Files you own
src/views/task.view.ts — extend listViews (grid, calendar, my_week, late, stalled already exist there)src/views/duty.view.ts — one tree lenstest/views.test.ts (new)
Nothing else in the M2 batch touches these files.
Views to add
board — kanban, columns by status. inlineEdit on, so dragging a card to Done issues the same status write the completion action does. Card face: subject, due date, owner, source badge.
schedule — gantt over visible_from → due_date, grouped by owner. This is the view that makes an overloaded period obvious before it arrives — the whole argument for lead_days is visible here as bar length.
recent — timeline ordered by last_update_at descending. The "what has actually been happening" lens, and the visual companion to the stagnation number.
by_unit — grid grouped by business_unit, for a manager scanning across teams.
catalog_tree in duly.view.ts — tree over duties grouped by business_unit then owner, so "what does this team owe" is one click.
Add each as a nav entry in the appropriate group of src/apps/duly.app.ts.
Rules
- A
calendar view needs its calendar: { startDateField, titleField, colorField } block, and a gantt view its equivalent. Without it the renderer falls back to literal default field names and the view renders empty while authoring reports success — the existing calendar view in task.view.ts shows the correct shape. - Filters use stored columns. Late is
due_date < {today} AND status IN (open, in_progress) — there is no is_late field and there will not be one. - Date macros only:
{today}, {week_start}, {14_days_ago}, {N_days_ago}, {N_weeks_from_now}. An unresolvable placeholder is sent to the engine as a literal string, matches nothing, and renders empty. pnpm validate catches it. - Colour by
status consistently across every lens — the same state must be the same colour in board, gantt and grid, or the views stop reading as one system. - No view sorts people by a count.
Acceptance
- every non-grid view declares its binding block;
pnpm validate clean with no warnings - dragging a card between board columns writes
status and nothing else - the gantt bar starts at
visible_from, not at due_date — a zero-length bar means lead time was dropped - every new view is reachable from app navigation
- status colours match across all lenses
Gates
pnpm validate && pnpm typecheck && pnpm test && pnpm build.
Same records, more ways in. Cheap to add on this platform and the thing evaluators reach for first.
Files you own
src/views/task.view.ts— extendlistViews(grid, calendar,my_week,late,stalledalready exist there)src/views/duty.view.ts— one tree lenstest/views.test.ts(new)Nothing else in the M2 batch touches these files.
Views to add
board— kanban, columns bystatus.inlineEditon, so dragging a card to Done issues the samestatuswrite the completion action does. Card face: subject, due date, owner, source badge.schedule— gantt overvisible_from→due_date, grouped by owner. This is the view that makes an overloaded period obvious before it arrives — the whole argument forlead_daysis visible here as bar length.recent— timeline ordered bylast_update_atdescending. The "what has actually been happening" lens, and the visual companion to the stagnation number.by_unit— grid grouped bybusiness_unit, for a manager scanning across teams.catalog_treeinduly.view.ts— tree over duties grouped bybusiness_unitthenowner, so "what does this team owe" is one click.Add each as a nav entry in the appropriate group of
src/apps/duly.app.ts.Rules
calendarview needs itscalendar: { startDateField, titleField, colorField }block, and aganttview its equivalent. Without it the renderer falls back to literal default field names and the view renders empty while authoring reports success — the existingcalendarview intask.view.tsshows the correct shape.due_date < {today} AND status IN (open, in_progress)— there is nois_latefield and there will not be one.{today},{week_start},{14_days_ago},{N_days_ago},{N_weeks_from_now}. An unresolvable placeholder is sent to the engine as a literal string, matches nothing, and renders empty.pnpm validatecatches it.statusconsistently across every lens — the same state must be the same colour in board, gantt and grid, or the views stop reading as one system.Acceptance
pnpm validateclean with no warningsstatusand nothing elsevisible_from, not atdue_date— a zero-length bar means lead time was droppedGates
pnpm validate && pnpm typecheck && pnpm test && pnpm build.