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.
17 KiB
id, type, title, domain, repo, status, owner, topic_slug, created, updated, phase, state_hub_workstream_id
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | phase | state_hub_workstream_id |
|---|---|---|---|---|---|---|---|---|---|---|---|
| IHUB-WP-0020 | workplan | Personal Dashboard Framework | inter_hub | inter-hub | finished | tegwick | inter_hub | 2026-05-03 | 2026-06-16 | 13 | 72fc022b-0196-492a-aaba-3475f8768f06 |
Personal Dashboard Framework
Goal
Design the first personal dashboard layer for inter-hub: an authenticated, per-user landing surface that composes the most important existing hub, governance, API, marketplace, and learning signals into a configurable daily operator view.
This workplan is now a design and implementation-planning workplan. It should produce the current-state audit, product requirements, functional design, and follow-on implementation workplan needed to build the feature safely.
Review Update: 2026-06-15
This workplan was reviewed against the current repository state and updated
from backlog to ready.
The original version assumed inter-hub mainly had a raw Hubs list and needed a greenfield dashboard framework. That assumption is outdated. The repo now has many dashboard-like surfaces and governed interaction primitives that should be reused instead of bypassed:
- Public root/intro pages exist from IHUB-WP-0015; the authenticated login flow
still redirects to
HubsAction. - Hub-level dashboard actions already exist in
Web.Controller.Hubs, including hub show, triage, governance, antifragility, agent audit, adapter compatibility, friction heatmap, bottleneck, hub health history, and the operational review board. - Cross-hub and platform dashboards already exist: federated governance, policy compliance, API usage, marketplace, and learning dashboard.
- The governed interaction substrate is mature:
widgets,widget_versions,interaction_events,annotations, type registries, hub manifests, ownership/routing, API request logs, hub health snapshots, learning insights, and institutional knowledge are all present. - There is no personal dashboard schema, controller, saved panel catalogue, user preference model, or role-aware default layout yet.
- Existing dashboards are mostly hard-coded controller queries plus HSX view fragments. They are useful source material, but they are not yet reusable panel renderers.
- The
userstable has no role column.stewardship_roles.assigned_tois text and hub-scoped, so role-aware defaults must be designed carefully instead of assuming a user-role foreign key exists.
The updated scope is therefore integration-first: define a personal dashboard contract that reuses existing data sources and view patterns, then introduce a small panel renderer abstraction only where it removes real duplication.
Scope
In Scope
- Authenticated personal dashboard route and post-login redirect design.
- Per-user saved dashboard record with ordered panel instances.
- A server-rendered panel catalogue backed by existing inter-hub models.
- Simple layout editing through IHP forms; no drag-and-drop in the first slice.
- Hub/time filters for panels where the underlying queries already support bounded data.
- Panel-level governance: each rendered saved panel must be annotatable and
event-capturable through the existing
widgetEnvelopeconvention. - A migration path that reuses current dashboard queries before attempting broad refactors.
Out of Scope for the First Implementation Workplan
- Client-side dashboard frameworks or client-side data fetching.
- External datasource connectors.
- Shared/team dashboards.
- Mobile-native layout editing.
- Drag-and-drop layout editing.
- A general purpose report builder.
- Rewriting every existing dashboard into panel renderers.
Current Design Constraints
- Server-rendered IHP views remain the default.
autoRefreshis acceptable for panels that already use live refresh patterns. - Tailwind and existing HSX view conventions should be reused.
- Runtime panel config may be stored as JSONB, but renderer code should decode into explicit Haskell config types before use.
- Do not create an ungoverned visual component layer. A saved dashboard panel
must either reference or create a
Widgetrow, most likely using the existing framework-levelpanelwidget type, so annotations and interaction events remain first-class IHF artifacts. - Avoid adding a
users.rolecolumn unless the PRS/FDD proves it is needed. Prefer defaults derived from current user identity, stewardship assignments, selected watched hubs, or explicit dashboard template choice.
Proposed First-Slice Panel Catalogue
The initial catalogue should be limited to panels that can be built from existing tables and controllers:
| Panel key | Label | Source surface/data | Live? |
|---|---|---|---|
watched-hubs |
Watched Hubs | hubs, hub_health_snapshots, optional saved hub filter |
No |
recent-interactions |
Recent Activity | interaction_events plus widgets and hubs |
Yes |
triage-queue |
Triage Queue | open requirement_candidates |
Yes |
recent-decisions |
Recent Decisions | decision_records, requirements, candidates |
No |
hub-health |
Hub Health | latest hub_health_snapshots, bottlenecks |
Yes |
agent-proposals |
Agent Proposals | agent_proposals, agent_review_records |
No |
api-usage |
API Usage | api_consumers, api_request_log |
Yes |
marketplace-trending |
Marketplace Trending | widget_patterns, adoptions, templates |
No |
learning-digest |
Learning Digest | learning_insights, institutional_knowledge_entries |
Yes |
my-annotations |
My Annotations | annotations filtered by current user when available |
No |
The implementation workplan should start with a smaller subset if needed:
watched-hubs, recent-interactions, triage-queue, recent-decisions,
hub-health, and learning-digest are enough to prove the framework.
Tasks
T01 - Current-state audit and dashboard pattern research
id: IHUB-WP-0020-T01
status: done
priority: high
state_hub_task_id: "6074f195-636b-4517-b6d1-eb3c57394a82"
Produce a short research note that starts with the current inter-hub codebase, then uses external dashboard systems only for secondary inspiration.
Required current-state inventory:
- Existing routes and views that behave like dashboards.
- Existing
autoRefreshusage and query patterns that are safe to reuse. - Existing type registry,
Widget,widgetEnvelope, annotation, and event capture constraints. - Existing tables that can power first-slice personal panels.
- Gaps: personal dashboard persistence, panel catalogue, saved filters, layout model, and user preference/defaulting model.
External systems may still be sampled, but the output should focus on patterns that are practical in IHP/HSX/Tailwind:
| System | What to extract |
|---|---|
| Grafana | Panel/grid layout model, dashboard variables, bounded refresh |
| Kibana dashboards | Saved-search panels, time range filters, role visibility |
| Retool/Appsmith | Widget catalogue and data binding concepts, not their client runtime |
| Linear home view | Flat "my work" aggregation across entities |
| Notion linked databases | Saved filters/sorts as user-facing views |
| Metabase | Question-as-unit model and governed saved queries |
| Streamlit | Declarative layout vocabulary suitable for server rendering |
Questions to answer:
- Which existing inter-hub dashboard fragments can become first-slice panel renderers without broad refactoring?
- Which panel configs must exist on day one: hub filter, time range, limit, display mode, or sort order?
- Which panels need live refresh, and which should stay static per request?
- How should each saved panel map to a governed
Widgetrow? - What should be explicitly deferred to avoid building a report builder?
Exit criteria: docs/research/personal-dashboard-current-state.md exists and
has enough evidence to drive the PRS.
Completion note (2026-06-16): added
docs/research/personal-dashboard-current-state.md, covering the current
dashboard inventory, AutoRefresh/query patterns, governed widget constraints,
first-slice panel candidates, external pattern extraction, and T02/T03
recommendations.
T02 - Product Requirements Specification
id: IHUB-WP-0020-T02
status: done
priority: high
depends_on: T01
state_hub_task_id: "698304bc-b91a-42e2-a617-b3ddbf749174"
Produce a formal PRS based on T01 and the current implementation.
Required sections:
- Problem statement: authenticated users currently land on the Hubs list and must manually navigate to specialized dashboards to answer daily operating questions.
- Personas:
- Hub operator: watches hub health, recent events, candidates, and bottlenecks.
- Governance reviewer: triages candidates, decisions, policy coverage, and annotations.
- AI orchestrator: watches agent proposals, review outcomes, and learning signals.
- Platform admin: watches API usage, hub registry health, manifests, and cross-hub propagation.
- Core requirements using MoSCoW:
- Must: per-user saved dashboard, seeded default dashboard, panel catalogue, server-rendered panels, persisted layout, governed panel widget identity, post-login route design, bounded panel queries.
- Should: hub/time filters, simple edit mode, live refresh on selected panels, keyboard-accessible forms, link-outs to existing source dashboards.
- Could: dashboard templates, saved watched-hub sets, shared dashboards, richer display modes.
- Won't: drag-and-drop, external datasources, client-side fetching, mobile layout editor, complete refactor of existing dashboards.
- Non-functional requirements:
- First paint target remains sub-second for seeded dashboards with bounded panel queries.
- Panel queries must use limits and existing indexes or propose new indexes.
- Dashboard save/load must be simple transactional IHP controller work.
- No new JS framework.
- Governance fit:
- Saved panel instances are governed IHF widgets or reference governed widgets.
- Panel views use
widgetEnvelope. - Panel interactions emit existing event types where possible.
- Annotations attach to the panel widget identity, not to a transient DOM block.
Exit criteria: docs/prs/personal-dashboard-prs.md exists and is ready for
FDD work.
Completion note (2026-06-16): added
docs/prs/personal-dashboard-prs.md, defining the problem statement,
personas, MoSCoW requirements, first-slice panel catalogue, governance
requirements, acceptance criteria, risks, and FDD open questions.
T03 - Functional Design Document
id: IHUB-WP-0020-T03
status: done
priority: high
depends_on: T02
state_hub_task_id: "438e5771-a043-4f26-a1ce-994ed478a760"
Translate the PRS into a concrete FDD covering schema, controller actions, panel renderer contract, layout, seed/default behavior, and migration strategy.
The FDD must update the old greenfield schema sketch. A likely shape is:
CREATE TABLE personal_dashboards (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,
user_id UUID NOT NULL REFERENCES users(id),
name TEXT NOT NULL,
is_default BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE dashboard_panel_types (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,
key TEXT NOT NULL UNIQUE,
label TEXT NOT NULL,
description TEXT,
default_config JSONB NOT NULL DEFAULT '{}',
default_col_span INT NOT NULL DEFAULT 4,
default_row_span INT NOT NULL DEFAULT 1,
live_update BOOLEAN NOT NULL DEFAULT FALSE,
status TEXT NOT NULL DEFAULT 'active'
);
CREATE TABLE dashboard_panels (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,
dashboard_id UUID NOT NULL REFERENCES personal_dashboards(id) ON DELETE CASCADE,
panel_type_id UUID NOT NULL REFERENCES dashboard_panel_types(id),
widget_id UUID NOT NULL REFERENCES widgets(id),
config JSONB NOT NULL DEFAULT '{}',
col INT NOT NULL DEFAULT 0,
row INT NOT NULL DEFAULT 0,
col_span INT NOT NULL DEFAULT 4,
row_span INT NOT NULL DEFAULT 1,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
The FDD must also resolve:
- Naming: whether tables should use
personal_dashboardsor another prefix to avoid confusing them with existing dashboard actions. - Panel config: JSONB storage plus explicit Haskell ADT decoding and validation.
- Governance identity: how
dashboard_panels.widget_idis created, versioned, and named. - Renderer contract:
data DashboardPanelConfig
= WatchedHubsConfig WatchedHubsOptions
| RecentInteractionsConfig RecentInteractionsOptions
| TriageQueueConfig TriageQueueOptions
| RecentDecisionsConfig RecentDecisionsOptions
| HubHealthConfig HubHealthOptions
| LearningDigestConfig LearningDigestOptions
renderDashboardPanel
:: DashboardPanelType
-> DashboardPanel
-> DashboardPanelConfig
-> ModelContext
-> IO Html
- Layout: 12-column grid on desktop, single-column below the existing Tailwind breakpoint, stable row/span constraints, no drag-and-drop in the first slice.
- Routes/actions:
PersonalDashboardActionEditPersonalDashboardActionUpdatePersonalDashboardActionAddDashboardPanelActionUpdateDashboardPanelActionRemoveDashboardPanelAction
- Login behavior:
CreateSessionActionshould redirect to the personal dashboard after authentication, while public root pages remain unchanged. - Defaulting model: seed a default dashboard on first visit without requiring a
users.rolecolumn. - Query safety: each panel query must be bounded, indexed, and compatible with
current PostgreSQL type decoding practices such as casting
COUNT(*)to integer when read asInt. - Tests and smoke checks needed for the follow-on implementation workplan.
Exit criteria: docs/fdd/personal-dashboard-fdd.md exists, schema decisions
are concrete enough to implement, and open questions are explicitly listed.
Completion note (2026-06-16): added
docs/fdd/personal-dashboard-fdd.md, resolving schema names, panel config
typing, renderer/view-model shape, default seeding, governed panel widget
lifecycle, query constraints, routes, layout, tests, and handoff shape for
IHUB-WP-0021.
T04 - Implementation workplan
id: IHUB-WP-0020-T04
status: done
priority: medium
depends_on: T03
state_hub_task_id: "970aa221-7e17-4500-8b37-9c98676280b1"
Create the execution workplan for implementation as IHUB-WP-0021.
Expected task structure for IHUB-WP-0021:
| Task | Focus |
|---|---|
| T01 | Schema migration for personal dashboards, panel types, and panel instances |
| T02 | Seed dashboard panel types and any required framework panel widgets/type vocabulary |
| T03 | Add controller/action/route skeleton and default dashboard lookup/seed helper |
| T04 | Implement first three renderers: watched hubs, recent interactions, triage queue |
| T05 | Implement dashboard show view and responsive CSS grid |
| T06 | Implement remaining first-slice renderers: recent decisions, hub health, learning digest |
| T07 | Implement edit flow: reorder/update layout, add/remove panels, validate config |
| T08 | Add governed widget identity creation and widgetEnvelope wrapping for panels |
| T09 | Redirect successful login to the personal dashboard |
| T10 | Add autoRefresh only around selected live panels or the whole page if finer wrapping is not practical |
| T11 | Add focused tests for seeding, panel config validation, route access, and bounded queries |
| T12 | Manual smoke: login, seeded dashboard, edit layout, annotate a panel, verify source dashboards still load |
Each task must have entry criteria, exit criteria, rollback notes, and the smallest reasonable test/smoke requirement. Keep implementation slices small enough for Codex sessions to finish without broad refactors.
Exit criteria: workplans/IHUB-WP-0021-personal-dashboard-implementation.md
exists with all tasks in todo state and enough detail to start implementation.
Completion note (2026-06-16): added
workplans/IHUB-WP-0021-personal-dashboard-implementation.md with twelve
sequenced implementation tasks covering schema, seeds, controller skeleton,
panel renderers, show/edit views, governed panel widget lifecycle, login
redirect, AutoRefresh/query hardening, tests, and manual smoke.
Exit Criteria Summary
| Task | Deliverable | Status |
|---|---|---|
| T01 | docs/research/personal-dashboard-current-state.md |
done |
| T02 | docs/prs/personal-dashboard-prs.md |
done |
| T03 | docs/fdd/personal-dashboard-fdd.md |
done |
| T04 | workplans/IHUB-WP-0021-personal-dashboard-implementation.md |
done |
Binding Design Principles
- Server-first: every panel renders on the server in the normal IHP request lifecycle.
- Integration-first: reuse current dashboard query patterns before extracting shared abstractions.
- Governed panels: saved panel instances have stable IHF widget identity and
use
widgetEnvelope. - Type-safe runtime config: JSONB is storage, not the unchecked runtime API.
- Bounded queries: every panel limits rows and uses existing indexes or proposes a specific migration.
- Minimal JS: no framework and no client-side data fetch loop.
- Tailwind only: use existing view style and responsive grid conventions.