#91 — Work-management depth: subtasks, dependencies, board & calendar views
Subtasks, checklists, task dependencies, Kanban/board + calendar views, custom statuses, role-based assignment slots, task time estimates, bulk updates, teams/groups + custom roles. The atomic feature comparison shows Firmary partial/absent on most of this cluster while every major competitor has it natively; the requirements gap analysis flags the same gaps (no job object, milestones, blockers). Capacity/workload planning lands with Phase-3 analytics. Size: L. Source: product-roadmap.md §4 (2026-07-09 comparison fold-in).
14 Comments
·about 2 months agoReconciliation 2026-07-16 (agent): keeping in_progress, annotating reality — subtasks + dependencies (migration 0068), estimates (0069), kanban board-view and month calendar-view all SHIPPED via PR #30 (apps/web/app/staff/queue/board-view.tsx + calendar-view.tsx; modules/tasks subtasks/deps integration tests). Remaining epic scope = custom statuses, teams/groups + custom roles, and role-based assignment slots.
·about 2 months agoAgent B — final for tonight (04:15 CT). Claim on this card RELEASED. Third review wave (12 agents) confirmed 10 findings — all fixed or documented in 0a067af: contact unblock-nudges no longer leak staff-internal blocker titles (critical; regression-tested against the rendered email), freed dependents grouped per recipient (second nudge was silently swallowed by the (event,recipient) dedupe), manually-blocked dependents stay quiet, batched reads, client-side estimate validation, board double-drag fix. Documented-as-accepted: reopened→recompleted blockers never re-fire task.completed (producer once-per-task key), near-simultaneous blocker completions can double-nudge. Tonight's totals on PR #30 (13 commits): 5 slices + notify-on-unblock + 6 E2E journeys + 3 adversarial review waves (49 agents, 36 confirmed findings fixed/documented). Final gates: typecheck 9/9, lint 8/8, boundaries 0 errors, full suite 8/8 (web 1446, outbox 176, validators 154). Card stays In Progress: PR unmerged and the epic still has unclaimed sub-items (custom statuses, teams/groups + custom roles, role-based assignment slots) — free for any agent to claim.
·about 2 months agoAgent B — notify-on-unblock follow-up shipped (PR #30, commit 36fa199). When a blocker completes, the notification engine now nudges the assignee of every dependent task that just became fully unblocked (new kind task.unblocked, category tasks — existing preference opt-outs apply; email template default included; unassigned dependents stay quiet). Verified: outbox 173 tests (2 new: multi-dependent fan-out, still-gated/unassigned quiet, replay idempotent, second-blocker path), full gates green, 3x stable. This closes the last named follow-up from slice 1.
·about 2 months agoAgent B — slice 5 (task time estimates) complete & verified; PR #30 (commit 305d7aa). tasks.estimate_minutes (migration 0069, journal ordering handled): set from the create form + edit dialog (1..10,000 min), shown as an Nh Nm chip on queue rows, board cards, and the detail card. Display/planning only — actual time stays in the time-tracking module. Also aligned the detail page due-date to UTC formatting. Verification: full gates green (web 1446, validators 154), estimates E2E journey passed live. Tonight's epic total: 5 slices + 2 adversarial review waves (37 agents, 26 confirmed findings fixed) + 6 proven E2E journeys, all on PR #30. Still unclaimed in the epic: custom statuses, teams/groups + custom roles, role-based assignment slots.
·about 2 months agoAgent B claiming slice 5 of this epic: task time estimates — tasks.estimate_minutes (nullable), set at create/edit, shown on detail/queue/board, validators + migration 0069 + tests. Started: 2026-07-09 03:30 America/Chicago. This is the last slice I start tonight; teams/custom roles + custom statuses remain unclaimed.
·about 2 months agoAgent B — E2E specs authored AND proven (PR #30, commit 8cd6caf). apps/web/e2e/work-management.spec.ts: five journeys — subtask/dependency gate lifecycle with queue chips, board drag + blocked-reason dialog + done-gate snap-back, calendar UTC placement + month nav + junk-param fallback, bulk partial-failure with the gated task skipped, portal read-only surfacing. Ran green against a dev stack: 5/5 in 2.4m (this closes the earlier "E2E deferred" risk note for the work-management surfaces — the specs are CI-ready; the FULL e2e suite sweep across all of tonight's lanes remains the previously-flagged owner follow-up). Truth table already carries the slice evidence.
·about 2 months agoAgent B — second adversarial review wave (18 agents over slices 2-4) done; 12 confirmed findings fixed in 9c28d3e (PR #30). Highlights: bulk actions now act only on currently-visible selections (ghost off-screen mutations impossible), server rejects oversized batches instead of silently truncating, board optimistic overrides expire when server state moves, date-only due dates render/bucket in UTC on all new surfaces (off-by-one fixed), calendar month params validated, undated note is a real filtered COUNT, all views show truncation notices. Full gates re-green (web 1443) + live smoke drive. Follow-up filed: platform-wide date-only formatting on OLDER surfaces still local-TZ (new Improvements post). Accepted-as-documented: bulk runs N per-task transactions (pool of 5, max 100).
·about 2 months agoAgent B — slice 4 (bulk updates) complete & verified; PR #30 (commit 0d4533e). Queue table now has multi-select with a bulk bar: set status (open/in-progress/done; blocked stays per-row — needs a per-task reason) and assign-to-staff (contacts are client-specific, per-row control still handles them). Each batched task runs the same module action as a single change — authz, completion gates, audit all hold per task — and partial failures report as "N updated, M skipped" with the reason instead of aborting. Verification: typecheck 9/9, lint 8/8, boundaries 0 errors, web 1443 passed; live Playwright drive (bulk done skips the subtask-gated task with its message, bulk staff assign, select-all). Epic scorecard tonight: slices 1-4 done (subtasks+dependencies, board view, calendar view, bulk updates) — all in PR #30. Remaining unclaimed in this epic: custom statuses, task time estimates, teams/groups + custom roles, role-based assignment slots.
·about 2 months agoAgent B claiming slice 4 of this epic: bulk updates — multi-select rows in the queue table with a bulk action bar (status change + assign), per-task authz/audit preserved, partial-failure reporting (e.g. done-gate skips). Files: /staff/queue table extraction into a client component + actions.ts additions. Started: 2026-07-09 ~02:55 America/Chicago.
·about 2 months agoAgent B — slice 3 (calendar view) complete & verified; PR #30 (commit 04e1cae). /staff/queue?view=calendar: month grid over due dates with status-badged task chips, overdue highlight, today marker, prev/next month links preserving filters, and an undated-tasks count. Server: listQueue gained dueFrom/dueTo predicates so the month window is correct regardless of queue depth. Verification: typecheck 9/9, lint 8/8, full suite 8/8 pkgs (web 1443, incl. new window-filter integration test); live Playwright drive (dated chip on the right day, month nav excludes/returns it, undated note, table toggle). Epic status: slices 1-3 done (subtasks+dependencies, board, calendar). Remaining unclaimed in epic: custom statuses, estimates, bulk updates, teams/custom roles.
·about 2 months agoAgent B — slice 2 (Kanban board view) complete & verified; same PR #30 (commit 7394cda). /staff/queue now has a Table|Board toggle (?view=board, filters preserved). Four status columns; dragging a card runs the same gated updateTaskStatus action as the table — drop on Blocked collects the required reason in a dialog, the done-gate rejects and the card snaps back with the server message; cards show client/assignee, priority, due, subtask/checklist/waiting-on chips; readers get a read-only board. Verification: typecheck 9/9, lint 8/8, web 1442 passed; live Playwright drive (board renders, drag persists across reload, blocked dialog, done-gate snap-back, default table intact). Remaining in this epic (unclaimed, not started): calendar view, custom statuses, estimates, bulk updates, teams/custom roles — leaving the card In Progress since the epic is broader than tonight's two slices; slices 1+2 are done and merged into PR #30.
·about 2 months agoAgent B — slice 1 (subtasks + dependencies) complete & verified. PR #30. What changed: tasks.parent_task_id (subtasks: same-client, single-level, inline add from staff task detail) + task_dependencies table (waits-on edges: same-client, staff-managed, self/cross-client/cycle rejected — cycle guard covers explicit edges AND the implicit parent-gate; per-client advisory lock closes the concurrency races). A task cannot be completed with open subtasks or unfinished blockers (staff + contacts; contacts get a neutral message that leaks nothing). Deleting a parent cascade-archives subtasks and drops edges; re-delete is a self-healing repair pass. User-visible: staff task detail gains Subtasks + Dependencies cards and a Part-of link; queue rows show Subtask chip, n/m subtask progress, Waiting-on-N chip; portal to-do detail shows read-only subtasks + honest waiting-on count that never leaks staff-internal titles. Files: packages/database (schema/tasks.ts, migration 0068, repository.ts), packages/validators/tasks.ts, apps/web/modules/tasks/api/* (4 new actions + createTask/updateTaskStatus/deleteTask), staff queue + portal task pages. Verification: turbo typecheck 9/9, lint 8/8, boundaries 0 errors, full suite 8/8 pkgs (web 1442 passed incl. 17 new integration tests), migration proven fresh + upgrade-clone, live Playwright drive of staff flow (create→subtask→link→done-gate→chips→complete) and portal flow, plus a 19-agent adversarial review — all confirmed findings fixed and regression-tested. Notes/risks: drizzle journal timestamps are future-dated until ~11:00 CDT today — any migration generated before then must bump its journal when past 1783612800009 (details in PR #30); E2E specs deferred per tonight’s repo policy; notify-on-unblock when a blocker completes is a named follow-up. Keeping this card In Progress — Agent B continuing with slice 2: Kanban board view for the staff queue (view toggle, status columns, drag to change status; no schema changes). Board/calendar/custom-statuses remainder stays within this epic.
·about 2 months agoAgent B claiming this until completion or block. Scope: bounded slice 1 of this epic — subtasks (parent/child tasks) + task dependencies (blocks/blocked-by with blocking semantics), end-to-end: schema + migration, validators, tasks API actions, staff queue/detail UI, portal surfacing where relevant, unit/integration tests, tasks contract + truth-table updates. NOT in this slice (remain unclaimed): board/calendar views, custom statuses, estimates, bulk updates, teams/custom roles. Working on branch agent-b/tasks-subtasks-deps off origin/master (e445931); not touching CSV-import files (Agent A lane). Started: 2026-07-09 00:57 America/Chicago.
Closed during the 2026-08-23 GitHub migration: slices 1-5 shipped via PR #30 (subtasks+dependencies 0068, estimates 0069, board + calendar views, bulk updates, notify-on-unblock; 6 E2E journeys). The unshipped epic remainder (custom statuses, teams/groups + custom roles, assignment slots) was extracted to its own GitHub issue: https://github.com/Firmary/firmary-os/issues/337.