generated from coulomb/repo-seed
chore(workplan): archive obsolete IHUB-WP-0021 personal dashboard implementation
Obsolete after migration to core-hub; cancel all tasks and archive the file-backed workplan rather than pursue inter-hub implementation.
This commit is contained in:
@@ -0,0 +1,632 @@
|
||||
---
|
||||
id: IHUB-WP-0021
|
||||
type: workplan
|
||||
title: "Personal Dashboard Implementation"
|
||||
domain: infotech
|
||||
repo: inter-hub
|
||||
status: archived
|
||||
owner: codex
|
||||
topic_slug: inter_hub
|
||||
created: "2026-06-16"
|
||||
updated: "2026-07-03"
|
||||
phase: 13
|
||||
depends_on: IHUB-WP-0020
|
||||
related_docs:
|
||||
- docs/research/personal-dashboard-current-state.md
|
||||
- docs/prs/personal-dashboard-prs.md
|
||||
- docs/fdd/personal-dashboard-fdd.md
|
||||
state_hub_workstream_id: "79f72176-fb3f-4d59-9678-d42f5ff1e679"
|
||||
---
|
||||
|
||||
# Personal Dashboard Implementation
|
||||
|
||||
## Goal
|
||||
|
||||
Implement the personal dashboard framework designed in IHUB-WP-0020: a
|
||||
server-rendered authenticated landing page with persisted per-user panels,
|
||||
governed panel widget identity, default dashboard seeding, simple edit forms,
|
||||
and six first-slice panel renderers.
|
||||
|
||||
## Inputs
|
||||
|
||||
- `docs/research/personal-dashboard-current-state.md`
|
||||
- `docs/prs/personal-dashboard-prs.md`
|
||||
- `docs/fdd/personal-dashboard-fdd.md`
|
||||
- Existing dashboard surfaces in `Web/Controller/Hubs.hs`,
|
||||
`Web/Controller/LearningDashboard.hs`, `Web/Controller/ApiDashboard.hs`,
|
||||
`Web/Controller/MarketplaceDashboard.hs`, and federated governance
|
||||
controllers.
|
||||
|
||||
## Constraints
|
||||
|
||||
- Keep implementation additive.
|
||||
- Preserve public root/static routes.
|
||||
- Do not refactor all existing dashboards.
|
||||
- No client-side data fetching framework.
|
||||
- No drag-and-drop layout in this workplan.
|
||||
- Every saved dashboard panel must have stable `Widget` identity and render
|
||||
through `widgetEnvelope`.
|
||||
- Bound every panel query.
|
||||
- Cast aggregate `COUNT(*)` queries when decoding as `Int`, or decode as
|
||||
`Int64`.
|
||||
|
||||
## Tasks
|
||||
|
||||
### T01 - Add personal dashboard schema
|
||||
|
||||
```task
|
||||
id: IHUB-WP-0021-T01
|
||||
status: cancel
|
||||
priority: high
|
||||
state_hub_task_id: "bb7366a3-78ec-42d8-9f16-b7ed4979ec53"
|
||||
```
|
||||
|
||||
Add the schema from the FDD:
|
||||
|
||||
- `personal_dashboards`
|
||||
- `dashboard_panel_types`
|
||||
- `dashboard_panels`
|
||||
|
||||
Implementation notes:
|
||||
|
||||
- Add an `Application/Migration/<timestamp>-personal-dashboard-framework.sql`
|
||||
migration.
|
||||
- Update `Application/Schema.sql` consistently with the migration.
|
||||
- Use `panel_key`, not `key`, on `dashboard_panel_types`.
|
||||
- Include `removed_at` on `dashboard_panels`.
|
||||
- Include indexes and layout CHECK constraints from the FDD.
|
||||
|
||||
Entry criteria:
|
||||
|
||||
- IHUB-WP-0020 is done.
|
||||
- FDD exists and is reviewed enough for implementation.
|
||||
|
||||
Exit criteria:
|
||||
|
||||
- Schema files contain the three new tables and indexes.
|
||||
- `rg "personal_dashboards|dashboard_panel_types|dashboard_panels" Application`
|
||||
finds the expected migration/schema entries.
|
||||
- No existing table or route behavior is changed.
|
||||
|
||||
Verification:
|
||||
|
||||
- Run `git diff --check`.
|
||||
- If the IHP dev environment is available, run the repo compile/schema check
|
||||
used by prior inter-hub workplans.
|
||||
|
||||
Rollback notes:
|
||||
|
||||
- Before production data exists, rollback is removing the migration/schema
|
||||
additions.
|
||||
- After production data exists, rollback requires preserving linked `widgets`
|
||||
and `interaction_events`; do not delete panel widgets casually.
|
||||
|
||||
---
|
||||
|
||||
### T02 - Seed panel types and framework panel vocabulary
|
||||
|
||||
```task
|
||||
id: IHUB-WP-0021-T02
|
||||
status: cancel
|
||||
priority: high
|
||||
depends_on: T01
|
||||
state_hub_task_id: "d298eab2-736d-48ed-b6d4-84afa1604de9"
|
||||
```
|
||||
|
||||
Add idempotent seed data for:
|
||||
|
||||
- framework hub with slug `inter-hub` and `hub_kind = 'framework'` if absent;
|
||||
- active widget type `panel` if absent;
|
||||
- six first-slice `dashboard_panel_types`:
|
||||
- `watched-hubs`
|
||||
- `recent-interactions`
|
||||
- `triage-queue`
|
||||
- `recent-decisions`
|
||||
- `hub-health`
|
||||
- `learning-digest`
|
||||
|
||||
Entry criteria:
|
||||
|
||||
- T01 schema exists.
|
||||
|
||||
Exit criteria:
|
||||
|
||||
- Seed SQL or helper is idempotent.
|
||||
- Re-running seeds does not create duplicate framework hubs, widget types, or
|
||||
panel types.
|
||||
- Default configs match the FDD.
|
||||
|
||||
Verification:
|
||||
|
||||
- Inspect seed SQL for `ON CONFLICT DO NOTHING` or equivalent idempotency.
|
||||
- If DB is available, run a local seed twice and confirm row counts stay stable.
|
||||
|
||||
Rollback notes:
|
||||
|
||||
- Panel type seed rows are additive. If rollback is needed before use, remove
|
||||
only the new dashboard panel type rows and any framework hub created solely
|
||||
for this feature.
|
||||
|
||||
---
|
||||
|
||||
### T03 - Add controller skeleton, routes, and default dashboard helper
|
||||
|
||||
```task
|
||||
id: IHUB-WP-0021-T03
|
||||
status: cancel
|
||||
priority: high
|
||||
depends_on: T02
|
||||
state_hub_task_id: "8a171c71-3762-46c7-88d7-10ffb87fc78a"
|
||||
```
|
||||
|
||||
Add:
|
||||
|
||||
- `PersonalDashboardsController` to `Web/Types.hs`;
|
||||
- `Web/Controller/PersonalDashboards.hs`;
|
||||
- `Web/View/PersonalDashboards/Show.hs`;
|
||||
- `Web/View/PersonalDashboards/Edit.hs` placeholder or minimal views;
|
||||
- route registration in `Web/Routes.hs`;
|
||||
- controller import and parser registration in `Web/FrontController.hs`;
|
||||
- helper module `Application/Helper/PersonalDashboard.hs`.
|
||||
|
||||
Implement:
|
||||
|
||||
- `ensureDefaultDashboard :: User -> IO PersonalDashboard`;
|
||||
- dashboard lookup scoped to current user;
|
||||
- idempotent default seeding with six panel rows;
|
||||
- linked `Widget` creation for each seeded panel;
|
||||
- initial `WidgetVersion` creation for panel widgets.
|
||||
|
||||
Entry criteria:
|
||||
|
||||
- T01/T02 complete.
|
||||
|
||||
Exit criteria:
|
||||
|
||||
- Authenticated user can hit `PersonalDashboardAction`.
|
||||
- First visit creates a default dashboard with six active panels.
|
||||
- A second visit does not duplicate panels.
|
||||
- Controller denies unauthenticated access through `ensureIsUser`.
|
||||
|
||||
Verification:
|
||||
|
||||
- Compile if environment is available.
|
||||
- Add or run focused helper tests if existing test harness supports it.
|
||||
|
||||
Rollback notes:
|
||||
|
||||
- Remove route/controller/helper additions if skeleton must be reverted.
|
||||
- Keep seeded widgets/events if any user interactions already happened.
|
||||
|
||||
---
|
||||
|
||||
### T04 - Implement first three panel view models/renderers
|
||||
|
||||
```task
|
||||
id: IHUB-WP-0021-T04
|
||||
status: cancel
|
||||
priority: high
|
||||
depends_on: T03
|
||||
state_hub_task_id: "012dcd2a-d3e0-48ba-966b-f4c7afa51dad"
|
||||
```
|
||||
|
||||
Implement typed config decoding and view-model builders for:
|
||||
|
||||
- `watched-hubs`
|
||||
- `recent-interactions`
|
||||
- `triage-queue`
|
||||
|
||||
Requirements:
|
||||
|
||||
- Query from controller/helper, not from HSX views.
|
||||
- Clamp configured limits.
|
||||
- Apply optional hub filters.
|
||||
- Render empty states.
|
||||
- Include source links:
|
||||
- watched hub rows link to `ShowHubAction`;
|
||||
- recent interaction rows link to widget or hub context where available;
|
||||
- triage rows link to `ShowRequirementCandidateAction`.
|
||||
|
||||
Entry criteria:
|
||||
|
||||
- T03 controller/helper skeleton exists.
|
||||
|
||||
Exit criteria:
|
||||
|
||||
- The three panels render in the dashboard show action.
|
||||
- Invalid config falls back to defaults and records a warning in the panel view
|
||||
model.
|
||||
- Queries are bounded.
|
||||
|
||||
Verification:
|
||||
|
||||
- Compile if environment is available.
|
||||
- Manual smoke with empty DB and seeded fixture data if possible.
|
||||
|
||||
Rollback notes:
|
||||
|
||||
- Renderer additions are isolated to helper/view modules and can be reverted
|
||||
without dropping schema.
|
||||
|
||||
---
|
||||
|
||||
### T05 - Implement dashboard show view and responsive grid
|
||||
|
||||
```task
|
||||
id: IHUB-WP-0021-T05
|
||||
status: cancel
|
||||
priority: high
|
||||
depends_on: T04
|
||||
state_hub_task_id: "b4c4de39-147b-45a0-954d-9bafad4aafa1"
|
||||
```
|
||||
|
||||
Build the dashboard show view:
|
||||
|
||||
- title and edit link;
|
||||
- responsive grid;
|
||||
- panel cards using row/col/span config;
|
||||
- panel title fallback to panel type label;
|
||||
- warning display for invalid config or unsupported panel;
|
||||
- source link area;
|
||||
- `widgetEnvelope` around every panel.
|
||||
|
||||
Implementation notes:
|
||||
|
||||
- Use current Tailwind and HSX conventions.
|
||||
- Add a small CSS helper in `static/app.css` only if needed for responsive
|
||||
collapse.
|
||||
- Keep text compact and operational.
|
||||
|
||||
Entry criteria:
|
||||
|
||||
- At least three panel view models exist.
|
||||
|
||||
Exit criteria:
|
||||
|
||||
- Seeded dashboard is usable as an authenticated landing surface.
|
||||
- Panels do not overlap at desktop or narrow widths.
|
||||
- Panel layout persists in the order defined by `row`, `col`, and `sort_order`.
|
||||
|
||||
Verification:
|
||||
|
||||
- Compile if environment is available.
|
||||
- Browser/manual smoke if a dev server is running.
|
||||
|
||||
Rollback notes:
|
||||
|
||||
- Show view changes can be reverted independently of schema/controller work.
|
||||
|
||||
---
|
||||
|
||||
### T06 - Implement remaining first-slice panel view models/renderers
|
||||
|
||||
```task
|
||||
id: IHUB-WP-0021-T06
|
||||
status: cancel
|
||||
priority: high
|
||||
depends_on: T05
|
||||
state_hub_task_id: "8d0bd046-17b3-48d9-a945-8b2e9c001123"
|
||||
```
|
||||
|
||||
Implement:
|
||||
|
||||
- `recent-decisions`
|
||||
- `hub-health`
|
||||
- `learning-digest`
|
||||
|
||||
Requirements:
|
||||
|
||||
- Recent decisions: bounded by time range and limit; link to
|
||||
`ShowDecisionRecordAction`.
|
||||
- Hub health: latest snapshot per hub plus active bottleneck count; use
|
||||
aggregate count casting or `Int64`.
|
||||
- Learning digest: recent `learning_insights` and
|
||||
`institutional_knowledge_entries`; link to knowledge entries where possible.
|
||||
|
||||
Entry criteria:
|
||||
|
||||
- T05 show view can render panel view models.
|
||||
|
||||
Exit criteria:
|
||||
|
||||
- All six first-slice panels render.
|
||||
- All panel queries are bounded.
|
||||
- Empty states are sane for all six panels.
|
||||
|
||||
Verification:
|
||||
|
||||
- Compile if environment is available.
|
||||
- `git diff --check`.
|
||||
|
||||
Rollback notes:
|
||||
|
||||
- Each renderer should be separable so a single broken panel can be reverted
|
||||
without removing the framework.
|
||||
|
||||
---
|
||||
|
||||
### T07 - Implement edit flow
|
||||
|
||||
```task
|
||||
id: IHUB-WP-0021-T07
|
||||
status: cancel
|
||||
priority: high
|
||||
depends_on: T06
|
||||
state_hub_task_id: "51a72b56-5c23-4baa-892f-4ab89fd8495c"
|
||||
```
|
||||
|
||||
Implement:
|
||||
|
||||
- `EditPersonalDashboardAction`;
|
||||
- `UpdatePersonalDashboardAction`;
|
||||
- `AddDashboardPanelAction`;
|
||||
- `UpdateDashboardPanelAction`;
|
||||
- `RemoveDashboardPanelAction`.
|
||||
|
||||
Edit view capabilities:
|
||||
|
||||
- show existing panels in layout order;
|
||||
- edit row, col, col span, row span, title, and sort order;
|
||||
- edit supported config fields such as limit, time range, display mode, and
|
||||
hub filter;
|
||||
- add active panel type;
|
||||
- remove panel.
|
||||
|
||||
Entry criteria:
|
||||
|
||||
- All six panels render on show view.
|
||||
|
||||
Exit criteria:
|
||||
|
||||
- User can modify layout and config through server-rendered forms.
|
||||
- User can add a panel and remove a panel.
|
||||
- Invalid layout/config re-renders edit view with an error.
|
||||
- A user cannot edit another user's dashboard/panel.
|
||||
|
||||
Verification:
|
||||
|
||||
- Manual edit smoke.
|
||||
- Focused authorization/config tests if available.
|
||||
|
||||
Rollback notes:
|
||||
|
||||
- If edit flow is unstable, keep show-only dashboard and disable edit links
|
||||
until fixed.
|
||||
|
||||
---
|
||||
|
||||
### T08 - Complete governed panel widget lifecycle
|
||||
|
||||
```task
|
||||
id: IHUB-WP-0021-T08
|
||||
status: cancel
|
||||
priority: high
|
||||
depends_on: T07
|
||||
state_hub_task_id: "ca70b76d-766f-4e6e-84f1-19943c0a347c"
|
||||
```
|
||||
|
||||
Harden widget lifecycle behavior:
|
||||
|
||||
- create panel widget on panel add/seed;
|
||||
- create initial `WidgetVersion` snapshot;
|
||||
- create a new `WidgetVersion` snapshot when material panel config changes;
|
||||
- render every panel through `widgetEnvelope`;
|
||||
- preserve annotations/events when panels are removed;
|
||||
- archive/deprecate linked widget on panel removal.
|
||||
|
||||
Entry criteria:
|
||||
|
||||
- Edit flow can add/remove/update panels.
|
||||
|
||||
Exit criteria:
|
||||
|
||||
- Every active dashboard panel has a linked active `Widget`.
|
||||
- Every linked widget has non-empty `view_context`.
|
||||
- Annotate link opens the existing widget annotation flow.
|
||||
- Removing a panel does not delete widget history.
|
||||
|
||||
Verification:
|
||||
|
||||
- Manual smoke: add panel, annotate panel, remove panel, confirm widget/event
|
||||
history is not deleted.
|
||||
- Inspect generated HTML for expected `data-widget-*` attributes.
|
||||
|
||||
Rollback notes:
|
||||
|
||||
- Do not delete existing `widgets`, `annotations`, or `interaction_events`.
|
||||
Disable dashboard rendering if needed while preserving history.
|
||||
|
||||
---
|
||||
|
||||
### T09 - Redirect login and add navigation
|
||||
|
||||
```task
|
||||
id: IHUB-WP-0021-T09
|
||||
status: cancel
|
||||
priority: medium
|
||||
depends_on: T08
|
||||
state_hub_task_id: "2fd1041b-9135-49e4-a9d1-e5d0b67d8fd7"
|
||||
```
|
||||
|
||||
Update:
|
||||
|
||||
- `Web/Controller/Sessions.hs` to redirect successful login to
|
||||
`PersonalDashboardAction`;
|
||||
- `Web/FrontController.hs` sidebar to include `Dashboard`;
|
||||
- any relevant public page management links only if they should point to the
|
||||
dashboard rather than Hubs.
|
||||
|
||||
Do not change:
|
||||
|
||||
- public root route;
|
||||
- `LandingAction`;
|
||||
- capabilities/tutorial/extension guide pages;
|
||||
- `HubsAction` availability.
|
||||
|
||||
Entry criteria:
|
||||
|
||||
- Dashboard show route is stable and governed panel lifecycle is complete.
|
||||
|
||||
Exit criteria:
|
||||
|
||||
- Successful login lands on personal dashboard.
|
||||
- Hubs remain reachable from sidebar.
|
||||
- Public pages still render without login.
|
||||
|
||||
Verification:
|
||||
|
||||
- Manual login smoke.
|
||||
- Route smoke for `/`, Hubs, dashboard, Learning, API Dashboard, Marketplace.
|
||||
|
||||
Rollback notes:
|
||||
|
||||
- If dashboard redirect fails, revert only the login redirect and keep
|
||||
dashboard accessible from sidebar.
|
||||
|
||||
---
|
||||
|
||||
### T10 - Add AutoRefresh and query hardening pass
|
||||
|
||||
```task
|
||||
id: IHUB-WP-0021-T10
|
||||
status: cancel
|
||||
priority: medium
|
||||
depends_on: T09
|
||||
state_hub_task_id: "e19c06e7-ec95-40ca-8087-df669b575f86"
|
||||
```
|
||||
|
||||
Wrap `PersonalDashboardAction` in `autoRefresh do` and audit all six panel
|
||||
queries:
|
||||
|
||||
- every query is bounded;
|
||||
- optional hub filter is applied before broad fetches where practical;
|
||||
- aggregate counts decode safely;
|
||||
- no secrets are selected or displayed;
|
||||
- dashboard refresh remains acceptable with default seed data.
|
||||
|
||||
Entry criteria:
|
||||
|
||||
- Dashboard route, renderers, edit flow, and login redirect exist.
|
||||
|
||||
Exit criteria:
|
||||
|
||||
- Dashboard updates using existing IHP AutoRefresh behavior.
|
||||
- Query review notes are either captured in code comments or tests where useful.
|
||||
- No known `COUNT(*)` as `Int` decode hazard remains in dashboard code.
|
||||
|
||||
Verification:
|
||||
|
||||
- Compile if environment is available.
|
||||
- Manual refresh smoke by adding an interaction/candidate and observing the
|
||||
dashboard update, when a dev DB is available.
|
||||
|
||||
Rollback notes:
|
||||
|
||||
- Remove `autoRefresh` wrapper if it causes unacceptable behavior; keep static
|
||||
dashboard route.
|
||||
|
||||
---
|
||||
|
||||
### T11 - Add focused tests
|
||||
|
||||
```task
|
||||
id: IHUB-WP-0021-T11
|
||||
status: cancel
|
||||
priority: medium
|
||||
depends_on: T10
|
||||
state_hub_task_id: "32b4f55e-ede6-4830-a171-b0785afe88e1"
|
||||
```
|
||||
|
||||
Add focused tests where the current harness supports them:
|
||||
|
||||
- default dashboard seeding is idempotent;
|
||||
- seeded dashboard has six active panels;
|
||||
- each active panel has linked widget identity;
|
||||
- config decoder clamps limits and rejects unknown values safely;
|
||||
- remove action soft-removes panel and archives widget;
|
||||
- users cannot edit another user's dashboard;
|
||||
- aggregate counts in dashboard helpers decode safely.
|
||||
|
||||
Entry criteria:
|
||||
|
||||
- T10 implementation is stable enough to test.
|
||||
|
||||
Exit criteria:
|
||||
|
||||
- Relevant test files exist or a documented reason explains why the current
|
||||
harness cannot cover a case.
|
||||
- Tests pass where runnable in the local environment.
|
||||
|
||||
Verification:
|
||||
|
||||
- Run available test command.
|
||||
- If unavailable, record exact blocker in this workplan before closing T11.
|
||||
|
||||
Rollback notes:
|
||||
|
||||
- Do not weaken production behavior to satisfy a brittle test; adjust the test
|
||||
to match the intended FDD contract.
|
||||
|
||||
---
|
||||
|
||||
### T12 - Manual smoke and closeout
|
||||
|
||||
```task
|
||||
id: IHUB-WP-0021-T12
|
||||
status: cancel
|
||||
priority: high
|
||||
depends_on: T11
|
||||
state_hub_task_id: "8c6648ae-d33e-48f6-9d56-ee557f367d80"
|
||||
```
|
||||
|
||||
Run a manual smoke pass:
|
||||
|
||||
1. Log in as an existing admin user.
|
||||
2. Confirm redirect lands on personal dashboard.
|
||||
3. Confirm all six seeded panels render.
|
||||
4. Click source links from watched hubs, triage queue, and learning digest.
|
||||
5. Open Annotate for one panel.
|
||||
6. Edit layout and save.
|
||||
7. Sign out/in and confirm layout persists.
|
||||
8. Add and remove a panel.
|
||||
9. Confirm Hubs, Hub show, Ops Review, Federation, Learning, API Dashboard,
|
||||
Hub Registry, and Marketplace still load.
|
||||
10. Run `git diff --check`.
|
||||
|
||||
Entry criteria:
|
||||
|
||||
- T01 through T11 complete or have explicit accepted caveats.
|
||||
|
||||
Exit criteria:
|
||||
|
||||
- Smoke evidence is recorded in this workplan or a short docs/evidence note.
|
||||
- WP-0021 tasks reflect final status.
|
||||
- State Hub progress note is logged.
|
||||
- Operator is reminded to run `make fix-consistency REPO=inter-hub` from
|
||||
`~/state-hub` after workplan/status changes.
|
||||
|
||||
Rollback notes:
|
||||
|
||||
- If smoke fails after login redirect, first rollback is reverting the login
|
||||
redirect while keeping dashboard route available for debugging.
|
||||
|
||||
## Workplan Exit Criteria
|
||||
|
||||
- Personal dashboard schema, seeds, controller, views, helper, and route are
|
||||
implemented.
|
||||
- Successful login reaches the personal dashboard.
|
||||
- Default dashboard seeding is idempotent.
|
||||
- Six first-slice panels render with bounded queries.
|
||||
- Panel edit flow works.
|
||||
- Every panel has governed widget identity.
|
||||
- Existing source dashboards remain functional.
|
||||
- Checks/smoke evidence is recorded.
|
||||
|
||||
## Closure on 2026-07-03
|
||||
|
||||
- Obsolete after migration from inter-hub to core-hub; no further inter-hub
|
||||
personal-dashboard implementation is planned.
|
||||
- IHUB-WP-0020 design artefacts remain in-repo for reference; execution
|
||||
work in this workplan is cancelled rather than transferred.
|
||||
- Workstream archived and all tasks cancelled per operator direction.
|
||||
|
||||
Reference in New Issue
Block a user