5.0 KiB
SLICE 4 — gtd-gantt data layer
State-saving rule: update this file immediately after EVERY completed task (tick the checkbox, update Status and Resume notes) and whenever pausing for input — automatically, without being asked. State on disk must always match reality.
Status
COMPLETE (2026-07-15). Pure data layer landed; 140/140 tests pass;
tsc --noEmit clean. No rendering/index wiring yet — that is SLICE5.
Resolved open question (2026-07-15): dateless/invalid-date gantt items are excluded with a warning (the recorded default) — no Unscheduled strip. If a strip is wanted later it's an additive change to collectGantt + the payload.
Goal
Pure data layer for the gantt: item opt-in parsing, project grouping, collection, config parsing. No rendering yet.
Design (agreed with user 2026-07-13)
- Items opt in with their own
gtd-gantt fenced block (separate fromgtd):- Notes (bars):
project: bluesky,begin-date: yyyy-mm-dd,end-date: yyyy-mm-dd(accept same date formats as resolveDate.ts). - To-dos (milestones):
project: bluesky; the milestone date is the to-do's native due date. begin/end on a to-do → warning, treated as milestone anyway.
- Notes (bars):
- Rows/swimlanes are grouped by
project:. - Chart block vs item block disambiguation (same fence name!): a
gtd-ganttblock containing aproject:key is an ITEM declaration; withoutproject:it is the CHART config block. The markdown-it renderer must apply the same rule (SLICE5). Item blocks render as a small inline badge ("gantt: bluesky"), not a chart. - Chart config keys:
title,notebook,scope,filter-project(optional; limit to one project),sort/sort-type(row order within project),card-detailsemantics for hover text. Defaults follow the existing parsers' conventions; invalid values warn + fall back. - Semantics: completed to-do milestones render checked/struck (consistent with calendar). Items with unparseable/missing dates → warning + excluded (a gantt has no Unscheduled section — confirm with user if one is wanted; see open questions).
- Reuse styling keys? Item gtd-gantt block also accepts
bg-colour,fg-colour,title,textmirroring the gtd block.
Open questions for user (non-blocking, defaults chosen)
- Dateless gantt items: currently planned as warn+exclude. Alternative: an "Unscheduled" strip like the calendar. DEFAULT: exclude with warning.
Tasks
src/Gtd/ganttBlock.ts—extractGanttBlockmirrors gtdBlock.ts (fence regex forgtd-gantt, same YAML/empty/malformed handling). Parses project / begin-date / end-date + styling keys (bg-colour/fg-colour/title/ text). Classification is the caller's job viablock.project(non-null ⇒ item, null ⇒ chart).src/Gtd/parseGanttConfig.ts— chart config: title, scope (+ scope: all + notebook conflict warning), notebook, filter-project, sort, sort-type (begin-date|title|modified-date), card-detail. Invalid → warn + default.src/Gtd/collectGantt.ts— scope (scopeAll-aware) → fetch (always with body) → item filter (project present, ≠ chart) → filter-project → bar vs milestone → group by project → sort → compute range. Returns typedGanttChart { projects, rangeStart, rangeEnd, warnings, scannedFolders, scannedNotes, itemCount }. Rules: notes → bars (begin+end required & valid, end≥begin else warn+exclude); to-dos → milestones on their due date (begin/end on a to-do → warning; no due date → warn+exclude); completed/recurring flags on milestones; projects merged case-insensitively, output alphabetical.- Types in
src/Gtd/types.ts— GanttSortType, GanttItemBlock, GanttBlockResult, GanttConfig, GanttBar, GanttMilestone, GanttProject, GanttChart. - Thorough unit tests —
src/tests/Gtd/gantt.test.ts(20 cases): block extraction (chart vs item, styling, Date coercion, malformed), config (defaults/full/conflict/invalid), collector (grouping+range, ignore chart/plain/host, bar bad/reversed dates, milestone due-date + begin/end warning, milestone no-due-date, completed+recurring, filter-project, begin-date sort + direction, case-insensitive project merge). - Full test run: 140 passed, 140 total (12 suites) on 2026-07-15.
tsc --noEmitclean for src/.
Resume notes
SLICE4 complete — pure data layer only. New files:
src/Gtd/ganttBlock.ts,parseGanttConfig.ts,collectGantt.ts- gantt types appended to
src/Gtd/types.ts src/tests/Gtd/gantt.test.ts
NOT done here (belongs to SLICE5): the markdown-it renderer's chart-vs-item
disambiguation, the getGantt message handler in src/index.ts, and any
webview rendering. collectGantt's signature mirrors the other collectors
(adapter, hostNoteId, hostFolderId, config) so index wiring will look like
handleGetKanban. Item blocks must render as a small inline badge (not a chart) —
that's a SLICE5 renderer concern. Next: SLICE5.