feat(phase 4f): per-item timeline_exclude flag (hide noise from /timeline)
m's stated use case: home VTODOs (shopping list) shouldn't pollute the
chronological /timeline by default, but they should stay visible on the
home detail page itself. This adds an item-level switch with four kinds
and a URL override to peek at everything when wanted.
## Schema (migration 0015)
- timeline_exclude text[] NOT NULL DEFAULT '{}'
- items_timeline_exclude_idx GIN
- items_unified view rebuilt to surface the new column
- Behaviour-neutral: empty array = unchanged from today. m flips the
toggle himself via /admin/bulk or the detail-page form.
## Aggregation
- web/timeline.go: pre-compute the per-kind keep-list via keepFor(kind)
before fanning out — items with the kind in their exclude array are
dropped entirely (no CalDAV call wasted on excluded sources). Doc and
creation rows check the per-item flag inline. `?include_excluded=1`
(URL) and `include_excluded:true` (MCP arg) override the filter.
- store.Item.ExcludesTimelineKind(kind) helper accepts either singular
("todo") or plural ("todos") to bridge the kind-constant / persisted-
value naming choice — see comment for the why.
## UI
- /i/{path} grows a "Timeline behaviour" collapsible section with four
checkboxes (todos / events / docs / creation) and helper text. Open by
default when any kind is excluded, so m can see at a glance what's
hidden for this item.
- /admin/bulk gains a "timeline todos" select with "Exclude from timeline"
and "Re-include on timeline" — the other three kinds stay editable
per-item only per the task brief (most common use case is just todos).
## MCP
- update_item accepts timeline_exclude as a partial-update field with an
enum-restricted whitelist; unknown values dropped silently.
- itemView always emits timeline_exclude (defaults to []) so consumers
can render the toggle state without a second round-trip.
## Tests
- Migration + GIN index landed
- Item with timeline_exclude=['todos'] hides the VTODO from /timeline
- ?include_excluded=1 brings it back
- Bulk action toggles the array idempotently in both directions
- Detail page renders all 4 checkbox affordances
## docs/design.md
§12 gains a "Per-item exclusion" subsection documenting semantics, the
URL override, the bulk action, and the "detail page still shows everything"
invariant.
## Out of scope (per task brief)
- Per-tag exclusion (per-item is clearer)
- Per-day exclusion (overkill)
- Dashboard exclusion (m only flagged timeline; dashboard's "today" view
should still show shopping today if it's due today)
- Auto-seeding home with timeline_exclude=['todos'] (m runs once himself
via /admin/bulk after the deploy — schema change stays behaviour-neutral)
This commit is contained in:
@@ -526,6 +526,16 @@ Items without a date never appear here — the tree/graph/dashboard cover the re
|
||||
|
||||
**Cache**: 90 s in-memory map keyed by `(filter, from, to, order, kinds)`. Looser than the dashboard's 60 s because timeline is browse-y, not action-y. The cache is invalidated wholesale on VTODO writeback (`/dashboard/task/*`, `/i/{path}/caldav/todo/*`) and on dated-link add/remove — any of those could move rows on or off the spine and the cost of a re-aggregation is cheap.
|
||||
|
||||
**Per-item exclusion (Phase 4f)**:
|
||||
|
||||
Each item carries a `timeline_exclude text[]` whose values name kinds to hide from the spine: `'todos'`, `'events'`, `'docs'`, `'creation'` (empty array = default = nothing hidden). The aggregator drops the matching source for each flagged item *before* fanning out — no CalDAV call is made for an item whose VTODOs are excluded, no creation marker is emitted for an item whose `'creation'` kind is excluded, and so on.
|
||||
|
||||
The detail page (`/i/{path}`) still surfaces everything regardless — exclusion is a render-time concern for the timeline view only, so m doesn't lose visibility into his data, he just stops seeing it braided into the chronological spine.
|
||||
|
||||
URL override: `?include_excluded=1` (and the MCP `include_excluded: true` arg) ignore the per-item arrays and surface everything — useful for "show me what I'm hiding" peek.
|
||||
|
||||
Bulk action: `/admin/bulk` offers an "Exclude todos from timeline" / "Re-include todos on timeline" pair (the most common use case — m's home shopping list). The other three kinds (events / docs / creation) are editable per-item only.
|
||||
|
||||
**Out of scope for 4a**:
|
||||
|
||||
- Drag-to-create-on-date (would require write paths from a non-detail page).
|
||||
|
||||
Reference in New Issue
Block a user