Skip to content

feat(command): Command Center page, activity feed + nav#122

Merged
apps3000 merged 2 commits into
mainfrom
feature/command-center
Jul 9, 2026
Merged

feat(command): Command Center page, activity feed + nav#122
apps3000 merged 2 commits into
mainfrom
feature/command-center

Conversation

@apps3000

@apps3000 apps3000 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Closes #117

Final increment of Phase A (epic #110): the Command Center UI on top of the event spine (#118) + decision-queue backend (#119).

What

  • New /command page (force-dynamic, requireUser): the Decision Queue rendered as prioritized cards (kind badge · repo · age · title · optional detail) with per-item open (internal route or external GitHub link) and dismiss (a small client island calling the dismissDecision server action), a count badge, and an empty state.
  • Activity feed: latest Signal rows via the shadcn timeline, severity-badged.
  • Navigation: "Command Center" is now the first VIEWS entry (Inbox icon) and the post-login landing/login (already-signed-in) and the OAuth callback redirect to /command; /dashboard stays reachable via the nav.
  • Pure helpers src/lib/decision-ui.ts (decisionKindStyle, isInternalUrl, relativeAge) with unit tests.

Verification

  • pnpm check / pnpm test (177) / docstring gate — all green.
  • Live smoke test: dev server up, /command → 307 → /login (auth guard; compiles with no 500), /dashboard still 307/reachable; the worker registered the ingest:github task. Logged-in browser render check to follow.
  • UI uses shadcn/shadcnstudio primitives only (Card/Badge/Button/Timeline); no custom CSS.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a new Command Center page showing a decision queue and recent activity in a more focused view.
    • Added a dismiss action for individual decision items.
    • Updated navigation and post-login flows to open the Command Center by default.
  • Bug Fixes

    • Improved link handling so internal links stay in-app while external links open in a new tab.
    • Added clearer relative time labels and empty states for empty lists.
  • Tests

    • Added coverage for decision styling, link detection, and relative time formatting.

New /command home: the Decision Queue (getDecisionQueue) rendered as prioritized cards with per-item open + dismiss (client island calling the dismiss server action), a count badge, and empty state; an Activity feed from the latest Signal rows via the shadcn timeline. Command Center is the first VIEWS entry and the post-login landing (login + OAuth callback redirect to /command; /dashboard stays reachable). Pure presentation helpers (decisionKindStyle/isInternalUrl/relativeAge) in src/lib/decision-ui.ts with tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 42 minutes

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: eafce1b6-5883-4961-807d-97e78e84c1c2

📥 Commits

Reviewing files that changed from the base of the PR and between 5fa1732 and 09dc3a7.

📒 Files selected for processing (2)
  • src/app/(app)/command/page.tsx
  • src/components/decision-dismiss-button.tsx
📝 Walkthrough

Walkthrough

This PR adds a new server-rendered /command "Command Center" page displaying a decision queue and activity timeline, along with supporting UI helper functions (with tests), a client-side dismiss button component, a new sidebar navigation entry, and updates to post-login/OAuth redirects from /dashboard to /command.

Changes

Command Center feature

Layer / File(s) Summary
Decision UI helpers and tests
src/lib/decision-ui.ts, src/lib/decision-ui.test.ts
Adds decisionKindStyle, isInternalUrl, and relativeAge pure helper functions with a DecisionKindStyle interface, plus Vitest coverage for badge mapping, internal/external URL classification, and time bucketing.
Command Center page
src/app/(app)/command/page.tsx
Adds a force-dynamic server page that calls requireUser(), fetches the decision queue and up to 15 recent signals via Prisma, and renders a "Decision queue" list card and an "Activity" timeline card with empty states, severity styling, and relative ages.
Decision dismiss action
src/components/decision-dismiss-button.tsx
Adds a client component with a useTransition-driven click handler that calls dismissDecision(dedupeKey) and disables the button while pending.
Navigation and redirects
src/components/app-sidebar.tsx, src/app/login/page.tsx, src/app/api/auth/callback/route.ts
Adds a "Command Center" sidebar entry with Inbox icon, updates the sidebar header link, and changes login-page and OAuth callback redirect targets from /dashboard to /command.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant CommandCenterPage
  participant requireUser
  participant getDecisionQueue
  participant PrismaSignal

  Browser->>CommandCenterPage: GET /command
  CommandCenterPage->>requireUser: requireUser()
  requireUser-->>CommandCenterPage: authenticated user
  CommandCenterPage->>getDecisionQueue: getDecisionQueue()
  getDecisionQueue-->>CommandCenterPage: decisions
  CommandCenterPage->>PrismaSignal: findMany(orderBy occurredAt, take 15)
  PrismaSignal-->>CommandCenterPage: signals
  CommandCenterPage-->>Browser: Decision queue + Activity timeline
Loading

Possibly related issues

Possibly related PRs

  • apps3k-com/orchid-dev-dashboard#119: The /command page and DecisionDismissButton consume the Decision Queue backend and dismissDecision/undismissDecision server actions introduced there.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR covers the Command Center page, activity feed, and nav updates, but the linked issue also requires a header inbox dropdown and priority grouping that are not shown. Add the inbox dropdown/count badge in the header and ensure queue items are grouped by priority, with the installed empty-state block used for empty queues.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the Command Center page and navigation changes.
Out of Scope Changes check ✅ Passed The changes appear aligned with the Command Center feature and supporting UI helpers, with no obvious unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/command-center

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/components/app-sidebar.tsx (1)

101-104: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Logo icon still LayoutDashboard despite link now pointing to /command.

Minor inconsistency: the header link now navigates to /command, but the icon next to "Orchid" remains LayoutDashboard, which visually still implies "dashboard".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/app-sidebar.tsx` around lines 101 - 104, The header link in
app-sidebar still uses LayoutDashboard even though it now points to /command, so
update the icon in the Link block near the Orchid brand to match the new
command-style navigation. Replace the current LayoutDashboard reference with the
appropriate icon used elsewhere for command/terminal semantics, keeping the Link
structure and styling intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/`(app)/command/page.tsx:
- Around line 67-70: The two inline empty-state placeholders in the command page
should use the shared EmptyState block instead of plain <p> text. Update the
empty branches in the page component to render the existing empty-state block
used elsewhere in the app, following the same pattern as audits, and keep the
messaging/content consistent for both cases.

In `@src/components/decision-dismiss-button.tsx`:
- Around line 12-22: The dismiss button’s transition callback is synchronous, so
`pending` can reset before `dismissDecision` finishes and its result may be
ignored. Update `DecisionDismissButton` to pass an async callback to
`startTransition`, await `dismissDecision(dedupeKey)` inside it, and handle any
failure or result state there so the button remains disabled while the action is
in flight.

---

Nitpick comments:
In `@src/components/app-sidebar.tsx`:
- Around line 101-104: The header link in app-sidebar still uses LayoutDashboard
even though it now points to /command, so update the icon in the Link block near
the Orchid brand to match the new command-style navigation. Replace the current
LayoutDashboard reference with the appropriate icon used elsewhere for
command/terminal semantics, keeping the Link structure and styling intact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e3ec4a56-ff25-4ea7-8b02-b1306ba82361

📥 Commits

Reviewing files that changed from the base of the PR and between d1f41bc and 5fa1732.

📒 Files selected for processing (7)
  • src/app/(app)/command/page.tsx
  • src/app/api/auth/callback/route.ts
  • src/app/login/page.tsx
  • src/components/app-sidebar.tsx
  • src/components/decision-dismiss-button.tsx
  • src/lib/decision-ui.test.ts
  • src/lib/decision-ui.ts

Comment thread src/app/(app)/command/page.tsx Outdated
Comment thread src/components/decision-dismiss-button.tsx
)

Both empty states (decision queue, activity) now render the shared shadcnstudio empty-state-02 block at the column level (no card nesting) for UI consistency with /audits. The dismiss button's startTransition callback is now async and awaits dismissDecision, so the button stays disabled until the action settles and a failure message surfaces via the button title instead of being dropped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@apps3000

apps3000 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@CodeRabbit any more findings? if not, please approve

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check existing review comments made by coderabbitai on this PR to see if there are open/unresolved findings
gh pr view 122 --repo apps3k-com/orchid-dev-dashboard --json reviews,comments -q '.reviews[] | {author: .author.login, body: .body, state: .state}' | head -100
echo "---review comments---"
gh api repos/apps3k-com/orchid-dev-dashboard/pulls/122/comments --paginate | jq -r '.[] | "\(.user.login): \(.path)#\(.line // .original_line) :: \(.body[0:200])"'

Length of output: 7687


🏁 Script executed:

#!/bin/bash
sed -n '1,90p' "src/app/(app)/command/page.tsx"
echo "---"
cat -n src/components/decision-dismiss-button.tsx
echo "---sidebar icon check---"
sed -n '1,20p;95,110p' src/components/app-sidebar.tsx

Length of output: 6261


Both prior findings are confirmed fixed in commit 09dc3a7 (the dismiss button now awaits dismissDecision inside the transition and surfaces failures, and both empty states use the shared empty-state-02 block). The remaining LayoutDashboard icon nitpick was trivial/low-value and doesn't block anything. I don't see any new issues in the current diff.

@apps3000 confirmed, no further findings from me — nice work wiring up the Command Center, the async dismiss transition, and the shared empty-state block. Approving now.

[approve]

ヽ(•‿•)ノ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(command): Command Center page, feed + nav

1 participant