Finish IHUB-WP-0020 design work (status finished, all design tasks done) and add IHUB-WP-0021 with the 12-task implementation workplan plus research, PRs, and FDD deliverables produced during the 2026-06-16 review.
16 KiB
id, type, title, domain, repo, status, owner, topic_slug, created, updated, phase, depends_on, related_docs, state_hub_workstream_id
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | phase | depends_on | related_docs | state_hub_workstream_id | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| IHUB-WP-0021 | workplan | Personal Dashboard Implementation | inter_hub | inter-hub | ready | codex | inter_hub | 2026-06-16 | 2026-06-16 | 13 | IHUB-WP-0020 |
|
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.mddocs/prs/personal-dashboard-prs.mddocs/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
Widgetidentity and render throughwidgetEnvelope. - Bound every panel query.
- Cast aggregate
COUNT(*)queries when decoding asInt, or decode asInt64.
Tasks
T01 - Add personal dashboard schema
id: IHUB-WP-0021-T01
status: todo
priority: high
state_hub_task_id: "bb7366a3-78ec-42d8-9f16-b7ed4979ec53"
Add the schema from the FDD:
personal_dashboardsdashboard_panel_typesdashboard_panels
Implementation notes:
- Add an
Application/Migration/<timestamp>-personal-dashboard-framework.sqlmigration. - Update
Application/Schema.sqlconsistently with the migration. - Use
panel_key, notkey, ondashboard_panel_types. - Include
removed_atondashboard_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" Applicationfinds 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
widgetsandinteraction_events; do not delete panel widgets casually.
T02 - Seed panel types and framework panel vocabulary
id: IHUB-WP-0021-T02
status: todo
priority: high
depends_on: T01
state_hub_task_id: "d298eab2-736d-48ed-b6d4-84afa1604de9"
Add idempotent seed data for:
- framework hub with slug
inter-hubandhub_kind = 'framework'if absent; - active widget type
panelif absent; - six first-slice
dashboard_panel_types:watched-hubsrecent-interactionstriage-queuerecent-decisionshub-healthlearning-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 NOTHINGor 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
id: IHUB-WP-0021-T03
status: todo
priority: high
depends_on: T02
state_hub_task_id: "8a171c71-3762-46c7-88d7-10ffb87fc78a"
Add:
PersonalDashboardsControllertoWeb/Types.hs;Web/Controller/PersonalDashboards.hs;Web/View/PersonalDashboards/Show.hs;Web/View/PersonalDashboards/Edit.hsplaceholder 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
Widgetcreation for each seeded panel; - initial
WidgetVersioncreation 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
id: IHUB-WP-0021-T04
status: todo
priority: high
depends_on: T03
state_hub_task_id: "012dcd2a-d3e0-48ba-966b-f4c7afa51dad"
Implement typed config decoding and view-model builders for:
watched-hubsrecent-interactionstriage-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.
- watched hub rows link to
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
id: IHUB-WP-0021-T05
status: todo
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;
widgetEnvelopearound every panel.
Implementation notes:
- Use current Tailwind and HSX conventions.
- Add a small CSS helper in
static/app.cssonly 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, andsort_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
id: IHUB-WP-0021-T06
status: todo
priority: high
depends_on: T05
state_hub_task_id: "8d0bd046-17b3-48d9-a945-8b2e9c001123"
Implement:
recent-decisionshub-healthlearning-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_insightsandinstitutional_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
id: IHUB-WP-0021-T07
status: todo
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
id: IHUB-WP-0021-T08
status: todo
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
WidgetVersionsnapshot; - create a new
WidgetVersionsnapshot 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, orinteraction_events. Disable dashboard rendering if needed while preserving history.
T09 - Redirect login and add navigation
id: IHUB-WP-0021-T09
status: todo
priority: medium
depends_on: T08
state_hub_task_id: "2fd1041b-9135-49e4-a9d1-e5d0b67d8fd7"
Update:
Web/Controller/Sessions.hsto redirect successful login toPersonalDashboardAction;Web/FrontController.hssidebar to includeDashboard;- 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;
HubsActionavailability.
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
id: IHUB-WP-0021-T10
status: todo
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(*)asIntdecode 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
autoRefreshwrapper if it causes unacceptable behavior; keep static dashboard route.
T11 - Add focused tests
id: IHUB-WP-0021-T11
status: todo
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
id: IHUB-WP-0021-T12
status: todo
priority: high
depends_on: T11
state_hub_task_id: "8c6648ae-d33e-48f6-9d56-ee557f367d80"
Run a manual smoke pass:
- Log in as an existing admin user.
- Confirm redirect lands on personal dashboard.
- Confirm all six seeded panels render.
- Click source links from watched hubs, triage queue, and learning digest.
- Open Annotate for one panel.
- Edit layout and save.
- Sign out/in and confirm layout persists.
- Add and remove a panel.
- Confirm Hubs, Hub show, Ops Review, Federation, Learning, API Dashboard, Hub Registry, and Marketplace still load.
- 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-hubfrom~/state-hubafter 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.