Files
pad/internal
xarmian 5afacaf478 feat(web): Insights analytics page (TASK-1633) (#643)
* feat(web): Insights analytics page (TASK-1633)

Add /[username]/[workspace]/insights — the Reports surface consuming
GET /workspaces/{ws}/report via api.report.get + the LayerCake chart library:
- window segmented control (day/week/2wk/month) + collection filter chips,
  both driving refetch via a single $effect
- totals (created/completed/net flow), throughput BarChart (created vs
  completed per bucket), cycle-time (median/p90 + per-collection), WIP
  (open count, median age, aging-band BarChart, per-collection), completed-
  by-collection BarChart, status-distribution bar rows
- loading/error/empty states; responsive grid; titleStore "Insights"

Route is /insights (owner directive); sidebar link is TASK-1636. Card
toggling + saved layouts are TASK-1634. Svelte 5 runes; MCP-validated;
npm run check 0 errors. Parent: PLAN-1628.

* fix(web): reset insights collection filter on workspace change per Codex review (round 1)

SvelteKit reuses the route component across workspace param changes, so a
collection filter selected in workspace A leaked into B — sending A's slugs to
B's /report, which the server scopes to an empty set (no match) → empty report
for a non-empty workspace. Track the previous wsSlug in a plain (non-reactive)
var and clear selectedCollections on an actual workspace change before
snapshotting, so the new workspace starts unfiltered. Loop-safe.

* fix(web): guard insights report fetch against stale/out-of-order responses per Codex review (round 2)

loadReport left the previous report visible during an in-flight fetch and wrote
responses unconditionally, so switching workspace A→B showed A's data under B's
URL, and a slow older request could overwrite a newer selection. Add a plain
request-sequence counter: capture seq at fetch start, commit report/error only
when seq is still the latest, and only the latest request clears `loading`.
Also clear report/collections on an actual workspace change so A's data doesn't
linger under B while B loads.

* fix: reserve 'insights' collection slug to avoid route shadowing per Codex review (round 3)

The static /[username]/[workspace]/insights route shadows the dynamic
/{collection} route, so an 'insights'-slugged collection would be unreachable.
Add 'insights' to reservedCollectionSlugs (server, blocks creation) and to the
Sidebar's reserved-slug filter, matching the existing activity/starred/library/
ref precedent (which likewise reserve UI routes without migrating pre-existing
data — an 'insights' collection on this new feature is not expected).
2026-05-29 10:56:21 -04:00
..
2026-03-26 01:52:36 +00:00