ubiquitous-invention/plans/Plan-daily-driver-finish/Epic-shipping-the-shell/Task-wire-workspace-home-dashboard.md

76 lines
4.2 KiB
Markdown
Raw Permalink Normal View History

plans: scaffold daily-driver-finish, saas-hardening, agent-coordination Three new plan trees that fill in the gaps surfaced during repo review. Together they map out what remains between the current scaffold-with-stubs state and a daily-usable, multitenant, agent-coordinated app. * Plan-daily-driver-finish (P0): turn stubs into real data. Five tasks covering the lint/shared-types breakage, hardcoded dashboard mocks, AI-page setTimeout placeholder, post-signin landing decision, and a cross-browser collab smoke test against the deployed Hocuspocus instance. * Plan-multitenant-saas-hardening (P1): everything multitenant needs beyond what Plan-multitenant-cursor-sync already covers. Invites and role management, soft-delete + append-only audit log, rate limits on the auth + mutation hot paths, and a Vitest + GitHub Actions test foundation so PRs can't ship red. * Plan-agent-coordination (P2): the layer that makes a Task-*.md runnable, not just readable. Adds workflow_prompt with task -> epic -> plan inheritance, an agent_runs table for auditable sessions, and two new MCP tools (claim_task / complete_task) that replace the freeform update_object composition agents do today. Includes an intentionally-deferred Epic-optional-orchestrator that captures the Symphony-shaped runner as a decision point rather than an immediate build. Each task is bead-scale (one focused Cursor session) with explicit in-scope, out-of-scope, and anti-goal sections so a future agent can pick up a single Task-*.md and start without scrollback context. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 00:52:22 -04:00
---
kind: task
slug: wire-workspace-home-dashboard
title: Replace hardcoded dashboard mocks with real tRPC queries
plan_slug: daily-driver-finish
epic_slug: shipping-the-shell
feat(web): wire workspace-home dashboard to real tRPC queries Path-A task 2/5. Replaces the hardcoded `stats` (24/8/12) and hardcoded `recent` list on the workspace-home page with real workspace-scoped data. * server/routers/objects.ts: add two new procedures. - `objects.stats` returns { openTasks, containers }. Open-task count treats null status as open; only `done` and `closed` (per packages/shared object-statuses) are terminal. Container count aggregates project + space + group rows. - `objects.listRecent({ limit })` returns the N most-recently-updated rows, descending by updated_at. Excludes archived and excludes `workspace`/`group` from the activity feed (containers clutter "what did I just touch" recency). Both go through workspaceProcedure, so the workspace_id filter comes from the middleware-resolved ctx.workspace.id rather than any user input. * app/(app)/[workspaceSlug]/page.tsx: rewrite to consume the new procedures via @trpc/react-query. Adds: - Skeleton loading state (no flash of zeros). - Empty state with a "New task" CTA on workspaces with no objects. - Real "X ago" labels on the recent feed. - Click-through links from recent rows to /{slug}/{id}. - A locally-mounted CreateObjectDialog instance independent of the global one in AppShell so the empty-state CTA can pre-seed defaultType="task" without coordinating shared state. * components/ui/skeleton.tsx: new (standard shadcn pulse skeleton). Used by the dashboard but reusable across the app. The scaffolded "Due this week" stat is dropped: `objects` has no due_at column and the task explicitly preferred dropping a card to schema-creep. `pnpm lint && pnpm type-check` clean. Closes plans/Plan-daily-driver-finish/Epic-shipping-the-shell/ Task-wire-workspace-home-dashboard.md. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 01:17:29 -04:00
status: done
plans: scaffold daily-driver-finish, saas-hardening, agent-coordination Three new plan trees that fill in the gaps surfaced during repo review. Together they map out what remains between the current scaffold-with-stubs state and a daily-usable, multitenant, agent-coordinated app. * Plan-daily-driver-finish (P0): turn stubs into real data. Five tasks covering the lint/shared-types breakage, hardcoded dashboard mocks, AI-page setTimeout placeholder, post-signin landing decision, and a cross-browser collab smoke test against the deployed Hocuspocus instance. * Plan-multitenant-saas-hardening (P1): everything multitenant needs beyond what Plan-multitenant-cursor-sync already covers. Invites and role management, soft-delete + append-only audit log, rate limits on the auth + mutation hot paths, and a Vitest + GitHub Actions test foundation so PRs can't ship red. * Plan-agent-coordination (P2): the layer that makes a Task-*.md runnable, not just readable. Adds workflow_prompt with task -> epic -> plan inheritance, an agent_runs table for auditable sessions, and two new MCP tools (claim_task / complete_task) that replace the freeform update_object composition agents do today. Includes an intentionally-deferred Epic-optional-orchestrator that captures the Symphony-shaped runner as a decision point rather than an immediate build. Each task is bead-scale (one focused Cursor session) with explicit in-scope, out-of-scope, and anti-goal sections so a future agent can pick up a single Task-*.md and start without scrollback context. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 00:52:22 -04:00
priority: P0
tenant_id: global
owner: unassigned
cursor_todo_id: null
feat(web): wire workspace-home dashboard to real tRPC queries Path-A task 2/5. Replaces the hardcoded `stats` (24/8/12) and hardcoded `recent` list on the workspace-home page with real workspace-scoped data. * server/routers/objects.ts: add two new procedures. - `objects.stats` returns { openTasks, containers }. Open-task count treats null status as open; only `done` and `closed` (per packages/shared object-statuses) are terminal. Container count aggregates project + space + group rows. - `objects.listRecent({ limit })` returns the N most-recently-updated rows, descending by updated_at. Excludes archived and excludes `workspace`/`group` from the activity feed (containers clutter "what did I just touch" recency). Both go through workspaceProcedure, so the workspace_id filter comes from the middleware-resolved ctx.workspace.id rather than any user input. * app/(app)/[workspaceSlug]/page.tsx: rewrite to consume the new procedures via @trpc/react-query. Adds: - Skeleton loading state (no flash of zeros). - Empty state with a "New task" CTA on workspaces with no objects. - Real "X ago" labels on the recent feed. - Click-through links from recent rows to /{slug}/{id}. - A locally-mounted CreateObjectDialog instance independent of the global one in AppShell so the empty-state CTA can pre-seed defaultType="task" without coordinating shared state. * components/ui/skeleton.tsx: new (standard shadcn pulse skeleton). Used by the dashboard but reusable across the app. The scaffolded "Due this week" stat is dropped: `objects` has no due_at column and the task explicitly preferred dropping a card to schema-creep. `pnpm lint && pnpm type-check` clean. Closes plans/Plan-daily-driver-finish/Epic-shipping-the-shell/ Task-wire-workspace-home-dashboard.md. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 01:17:29 -04:00
updated_at: "2026-06-02"
plans: scaffold daily-driver-finish, saas-hardening, agent-coordination Three new plan trees that fill in the gaps surfaced during repo review. Together they map out what remains between the current scaffold-with-stubs state and a daily-usable, multitenant, agent-coordinated app. * Plan-daily-driver-finish (P0): turn stubs into real data. Five tasks covering the lint/shared-types breakage, hardcoded dashboard mocks, AI-page setTimeout placeholder, post-signin landing decision, and a cross-browser collab smoke test against the deployed Hocuspocus instance. * Plan-multitenant-saas-hardening (P1): everything multitenant needs beyond what Plan-multitenant-cursor-sync already covers. Invites and role management, soft-delete + append-only audit log, rate limits on the auth + mutation hot paths, and a Vitest + GitHub Actions test foundation so PRs can't ship red. * Plan-agent-coordination (P2): the layer that makes a Task-*.md runnable, not just readable. Adds workflow_prompt with task -> epic -> plan inheritance, an agent_runs table for auditable sessions, and two new MCP tools (claim_task / complete_task) that replace the freeform update_object composition agents do today. Includes an intentionally-deferred Epic-optional-orchestrator that captures the Symphony-shaped runner as a decision point rather than an immediate build. Each task is bead-scale (one focused Cursor session) with explicit in-scope, out-of-scope, and anti-goal sections so a future agent can pick up a single Task-*.md and start without scrollback context. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 00:52:22 -04:00
---
# Task summary
`apps/web/app/(app)/[workspaceSlug]/page.tsx` currently renders a hardcoded `stats` array (`"24"`, `"8"`, `"12"`) and a hardcoded `recent` list. Replace both with real tRPC calls so the home page reflects actual workspace state.
## Description
The page is a Client Component (`"use client"`). It already pulls `currentWorkspace` from `useWorkspaceStore`. What it needs:
1. **Stats card**: replace the three `stats` entries with counts derived from `objects` filtered by workspace. Suggested:
- "Open tasks" — count of `objects` where `type = 'task'` and `status` is not in a "done" set, scoped by workspace_id.
- "Due this week" — same scope, additionally filtered by `due_at <= now + 7 days`. If `objects` doesn't have a due-date column yet, drop this card rather than fake it.
- "Lists" / "Projects" — count of `objects` where `type` is in `('project', 'space', 'group')`.
2. **Recent list**: replace the static `recent` array with the 5 most-recently-updated objects in the workspace. Use the existing `objects` router. If no suitable procedure exists, add one as `objects.listRecent({ limit: 5 })` — workspace-scoped via `workspaceProcedure` in `apps/web/server/trpc.ts`.
3. **Loading + empty states**: use the same `Card` skeleton pattern already in `apps/web/app/(app)/[workspaceSlug]/teams/page.tsx` (`MemberCardSkeleton`). When the workspace has no objects, render a friendly empty state with a "Create your first project" CTA that opens the existing `CreateObjectDialog`.
### Constraints
- Don't add a new column to `objects` unless you also add a Drizzle migration. Prefer to drop a card rather than schema-creep this task.
- All queries MUST filter by `workspace_id`. Use `workspaceProcedure`, never a raw procedure that pulls the slug from the URL without re-checking.
- No raw `fetch` against `/api/trpc` — use `api.objects.<...>.useQuery()` via `@trpc/react-query`.
## Subtasks
feat(web): wire workspace-home dashboard to real tRPC queries Path-A task 2/5. Replaces the hardcoded `stats` (24/8/12) and hardcoded `recent` list on the workspace-home page with real workspace-scoped data. * server/routers/objects.ts: add two new procedures. - `objects.stats` returns { openTasks, containers }. Open-task count treats null status as open; only `done` and `closed` (per packages/shared object-statuses) are terminal. Container count aggregates project + space + group rows. - `objects.listRecent({ limit })` returns the N most-recently-updated rows, descending by updated_at. Excludes archived and excludes `workspace`/`group` from the activity feed (containers clutter "what did I just touch" recency). Both go through workspaceProcedure, so the workspace_id filter comes from the middleware-resolved ctx.workspace.id rather than any user input. * app/(app)/[workspaceSlug]/page.tsx: rewrite to consume the new procedures via @trpc/react-query. Adds: - Skeleton loading state (no flash of zeros). - Empty state with a "New task" CTA on workspaces with no objects. - Real "X ago" labels on the recent feed. - Click-through links from recent rows to /{slug}/{id}. - A locally-mounted CreateObjectDialog instance independent of the global one in AppShell so the empty-state CTA can pre-seed defaultType="task" without coordinating shared state. * components/ui/skeleton.tsx: new (standard shadcn pulse skeleton). Used by the dashboard but reusable across the app. The scaffolded "Due this week" stat is dropped: `objects` has no due_at column and the task explicitly preferred dropping a card to schema-creep. `pnpm lint && pnpm type-check` clean. Closes plans/Plan-daily-driver-finish/Epic-shipping-the-shell/ Task-wire-workspace-home-dashboard.md. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 01:17:29 -04:00
- [x] Audit `apps/web/server/routers/objects.ts` — no `stats` or `listRecent` existed.
- [x] Added `objects.stats` (open-tasks count + container-types count) and `objects.listRecent({ limit })`. Both go through `workspaceProcedure`, so the `workspace_id` filter is enforced by the middleware, not just by the query body.
- [x] Replaced `stats` and `recent` arrays in `[workspaceSlug]/page.tsx` with real queries.
- [x] Added skeleton states (`apps/web/components/ui/skeleton.tsx`, new) and an empty state with a CTA.
- [x] Wired the empty-state CTA to a locally-mounted `CreateObjectDialog` instance with `defaultType: "task"`. The page-level dialog is independent of the global `AppShell` create dialog so it can pre-seed its `defaultType` without coordinating shared state.
### Decisions made vs. the scaffold
- **"Due this week" card dropped.** `objects` has no `due_at` column. Per the task's own constraint ("drop a card rather than schema-creep this task") it's gone, leaving a 2-up grid: open tasks + projects/spaces/groups.
- **Recent feed excludes `workspace` and `group` rows.** Container objects clutter a "what did I touch lately" view; the user wants to see the tasks/docs/whiteboards they actually edited.
- **Status "done" semantics** match `packages/shared/src/types/objects.ts`: `done` and `closed` are terminal. Null status is treated as open (a fresh task with no explicit status isn't done).
- **Time-ago helper inlined.** Single use site; not worth pulling in `date-fns` or building a shared hook.
plans: scaffold daily-driver-finish, saas-hardening, agent-coordination Three new plan trees that fill in the gaps surfaced during repo review. Together they map out what remains between the current scaffold-with-stubs state and a daily-usable, multitenant, agent-coordinated app. * Plan-daily-driver-finish (P0): turn stubs into real data. Five tasks covering the lint/shared-types breakage, hardcoded dashboard mocks, AI-page setTimeout placeholder, post-signin landing decision, and a cross-browser collab smoke test against the deployed Hocuspocus instance. * Plan-multitenant-saas-hardening (P1): everything multitenant needs beyond what Plan-multitenant-cursor-sync already covers. Invites and role management, soft-delete + append-only audit log, rate limits on the auth + mutation hot paths, and a Vitest + GitHub Actions test foundation so PRs can't ship red. * Plan-agent-coordination (P2): the layer that makes a Task-*.md runnable, not just readable. Adds workflow_prompt with task -> epic -> plan inheritance, an agent_runs table for auditable sessions, and two new MCP tools (claim_task / complete_task) that replace the freeform update_object composition agents do today. Includes an intentionally-deferred Epic-optional-orchestrator that captures the Symphony-shaped runner as a decision point rather than an immediate build. Each task is bead-scale (one focused Cursor session) with explicit in-scope, out-of-scope, and anti-goal sections so a future agent can pick up a single Task-*.md and start without scrollback context. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 00:52:22 -04:00
## Owner or assignee
Unassigned
## Status
feat(web): wire workspace-home dashboard to real tRPC queries Path-A task 2/5. Replaces the hardcoded `stats` (24/8/12) and hardcoded `recent` list on the workspace-home page with real workspace-scoped data. * server/routers/objects.ts: add two new procedures. - `objects.stats` returns { openTasks, containers }. Open-task count treats null status as open; only `done` and `closed` (per packages/shared object-statuses) are terminal. Container count aggregates project + space + group rows. - `objects.listRecent({ limit })` returns the N most-recently-updated rows, descending by updated_at. Excludes archived and excludes `workspace`/`group` from the activity feed (containers clutter "what did I just touch" recency). Both go through workspaceProcedure, so the workspace_id filter comes from the middleware-resolved ctx.workspace.id rather than any user input. * app/(app)/[workspaceSlug]/page.tsx: rewrite to consume the new procedures via @trpc/react-query. Adds: - Skeleton loading state (no flash of zeros). - Empty state with a "New task" CTA on workspaces with no objects. - Real "X ago" labels on the recent feed. - Click-through links from recent rows to /{slug}/{id}. - A locally-mounted CreateObjectDialog instance independent of the global one in AppShell so the empty-state CTA can pre-seed defaultType="task" without coordinating shared state. * components/ui/skeleton.tsx: new (standard shadcn pulse skeleton). Used by the dashboard but reusable across the app. The scaffolded "Due this week" stat is dropped: `objects` has no due_at column and the task explicitly preferred dropping a card to schema-creep. `pnpm lint && pnpm type-check` clean. Closes plans/Plan-daily-driver-finish/Epic-shipping-the-shell/ Task-wire-workspace-home-dashboard.md. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 01:17:29 -04:00
done
plans: scaffold daily-driver-finish, saas-hardening, agent-coordination Three new plan trees that fill in the gaps surfaced during repo review. Together they map out what remains between the current scaffold-with-stubs state and a daily-usable, multitenant, agent-coordinated app. * Plan-daily-driver-finish (P0): turn stubs into real data. Five tasks covering the lint/shared-types breakage, hardcoded dashboard mocks, AI-page setTimeout placeholder, post-signin landing decision, and a cross-browser collab smoke test against the deployed Hocuspocus instance. * Plan-multitenant-saas-hardening (P1): everything multitenant needs beyond what Plan-multitenant-cursor-sync already covers. Invites and role management, soft-delete + append-only audit log, rate limits on the auth + mutation hot paths, and a Vitest + GitHub Actions test foundation so PRs can't ship red. * Plan-agent-coordination (P2): the layer that makes a Task-*.md runnable, not just readable. Adds workflow_prompt with task -> epic -> plan inheritance, an agent_runs table for auditable sessions, and two new MCP tools (claim_task / complete_task) that replace the freeform update_object composition agents do today. Includes an intentionally-deferred Epic-optional-orchestrator that captures the Symphony-shaped runner as a decision point rather than an immediate build. Each task is bead-scale (one focused Cursor session) with explicit in-scope, out-of-scope, and anti-goal sections so a future agent can pick up a single Task-*.md and start without scrollback context. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 00:52:22 -04:00
## Estimation
M
## Acceptance criteria
feat(web): wire workspace-home dashboard to real tRPC queries Path-A task 2/5. Replaces the hardcoded `stats` (24/8/12) and hardcoded `recent` list on the workspace-home page with real workspace-scoped data. * server/routers/objects.ts: add two new procedures. - `objects.stats` returns { openTasks, containers }. Open-task count treats null status as open; only `done` and `closed` (per packages/shared object-statuses) are terminal. Container count aggregates project + space + group rows. - `objects.listRecent({ limit })` returns the N most-recently-updated rows, descending by updated_at. Excludes archived and excludes `workspace`/`group` from the activity feed (containers clutter "what did I just touch" recency). Both go through workspaceProcedure, so the workspace_id filter comes from the middleware-resolved ctx.workspace.id rather than any user input. * app/(app)/[workspaceSlug]/page.tsx: rewrite to consume the new procedures via @trpc/react-query. Adds: - Skeleton loading state (no flash of zeros). - Empty state with a "New task" CTA on workspaces with no objects. - Real "X ago" labels on the recent feed. - Click-through links from recent rows to /{slug}/{id}. - A locally-mounted CreateObjectDialog instance independent of the global one in AppShell so the empty-state CTA can pre-seed defaultType="task" without coordinating shared state. * components/ui/skeleton.tsx: new (standard shadcn pulse skeleton). Used by the dashboard but reusable across the app. The scaffolded "Due this week" stat is dropped: `objects` has no due_at column and the task explicitly preferred dropping a card to schema-creep. `pnpm lint && pnpm type-check` clean. Closes plans/Plan-daily-driver-finish/Epic-shipping-the-shell/ Task-wire-workspace-home-dashboard.md. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 01:17:29 -04:00
- [x] No hardcoded numbers or hardcoded titles remain in `apps/web/app/(app)/[workspaceSlug]/page.tsx`.
- [x] Loading state renders skeletons rather than a flash of zeros.
- [x] Empty state for a brand-new workspace renders a "New task" CTA wired to `CreateObjectDialog`.
- [x] All queries filter by `workspace_id` (enforced through `workspaceProcedure`).
plans: scaffold daily-driver-finish, saas-hardening, agent-coordination Three new plan trees that fill in the gaps surfaced during repo review. Together they map out what remains between the current scaffold-with-stubs state and a daily-usable, multitenant, agent-coordinated app. * Plan-daily-driver-finish (P0): turn stubs into real data. Five tasks covering the lint/shared-types breakage, hardcoded dashboard mocks, AI-page setTimeout placeholder, post-signin landing decision, and a cross-browser collab smoke test against the deployed Hocuspocus instance. * Plan-multitenant-saas-hardening (P1): everything multitenant needs beyond what Plan-multitenant-cursor-sync already covers. Invites and role management, soft-delete + append-only audit log, rate limits on the auth + mutation hot paths, and a Vitest + GitHub Actions test foundation so PRs can't ship red. * Plan-agent-coordination (P2): the layer that makes a Task-*.md runnable, not just readable. Adds workflow_prompt with task -> epic -> plan inheritance, an agent_runs table for auditable sessions, and two new MCP tools (claim_task / complete_task) that replace the freeform update_object composition agents do today. Includes an intentionally-deferred Epic-optional-orchestrator that captures the Symphony-shaped runner as a decision point rather than an immediate build. Each task is bead-scale (one focused Cursor session) with explicit in-scope, out-of-scope, and anti-goal sections so a future agent can pick up a single Task-*.md and start without scrollback context. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 00:52:22 -04:00
## Links to related Epic / Plan
- Epic: `./Epic-shipping-the-shell.md`
- Plan: `../Plan-daily-driver-finish.md`