Skip to content

fix(platform): show access denied for non-members and optimize execution query#578

Merged
larryro merged 3 commits into
mainfrom
fix/dashboard-access-denied-and-execution-query
Feb 26, 2026
Merged

fix(platform): show access denied for non-members and optimize execution query#578
larryro merged 3 commits into
mainfrom
fix/dashboard-access-denied-and-execution-query

Conversation

@larryro
Copy link
Copy Markdown
Collaborator

@larryro larryro commented Feb 26, 2026

Summary

  • Show an "access denied" message when authenticated users navigate to a workspace they're not a member of, instead of rendering nothing
  • Optimize hasRunningExecution query by using a compound by_definition_status index instead of filtering, enabling parallel lookups for running and pending statuses
  • Add tests for dashboard layout (loading, access denied, and role-based rendering states) and hasRunningExecution helper

Test plan

  • Dashboard shows spinner while auth or member context is loading
  • Dashboard shows access denied message for non-members
  • Dashboard renders child routes for members with a role
  • hasRunningExecution correctly detects running/pending executions via compound index
  • hasRunningExecutions returns correct map for multiple definitions

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Dashboard now displays proper access denial messaging when users lack required membership, replacing previous null fallback behavior.
  • Tests

    • Added comprehensive test suite for dashboard layout, covering authentication states, loading conditions, and access control scenarios.
    • Added test suite for workflow execution scheduling helpers, validating concurrent status queries.

…ion query

Show an AccessDenied screen when a user without membership navigates to a
workspace dashboard. Optimize hasRunningExecution to use a compound index
(by_definition_status) with parallel queries instead of a filter scan.
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Feb 26, 2026

Greptile Summary

Improved UX by displaying an access denied message when authenticated users navigate to workspaces they're not members of (previously showed nothing), and optimized workflow execution queries by replacing filtered scans with compound index lookups.

Key Changes:

  • Dashboard now properly handles non-member access with a clear "access denied" message instead of rendering nothing
  • Split loading states (isAuthLoading and isQueryLoading) to ensure spinner displays during both auth and member context loading
  • Optimized hasRunningExecution to use compound by_definition_status index with parallel Promise.all queries instead of filtering, enabling efficient status checks
  • Added comprehensive tests for both dashboard layout (6 test cases) and execution helpers (7 test cases)

Code Quality:

  • Well-structured tests with proper mocking and comprehensive coverage of edge cases
  • Clean separation of concerns with loading state management
  • Performance optimization follows database indexing best practices

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk - it improves UX and performance with thorough test coverage
  • All changes are well-tested with comprehensive test coverage (13 tests total), the optimization uses proper database indexing patterns, and the UX improvement addresses a real user-facing issue. No breaking changes or security concerns identified.
  • No files require special attention

Important Files Changed

Filename Overview
services/platform/app/routes/dashboard/$id.tsx Added access denied message for non-members and split loading states for better UX - shows spinner while auth or member query loads, then access denied if user lacks membership
services/platform/convex/workflow_engine/helpers/scheduler/has_running_execution.ts Optimized to use compound by_definition_status index with parallel queries instead of filtering, improving query performance
services/platform/convex/workflows/schema.ts Added compound index by_definition_status on wfExecutions table to support optimized execution status queries

Last reviewed commit: c39ee38

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 26, 2026

📝 Walkthrough

Walkthrough

This PR integrates authentication and internationalization handling into the dashboard route, replacing null membership fallbacks with an AccessDenied component. It introduces a new composite database index for workflow execution queries and refactors the query logic to perform concurrent lookups by status. The PR adds comprehensive test coverage for the dashboard layout component and workflow execution helpers, includes a new localization entry for membership denial messages, and updates the test configuration to include route-level tests.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • Israeltheminer
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main changes: showing access denied for non-members and optimizing the execution query with an index-based approach.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/dashboard-access-denied-and-execution-query

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@services/platform/convex/workflow_engine/helpers/scheduler/has_running_execution.test.ts`:
- Around line 19-21: The mock for query.withIndex in
has_running_execution.test.ts currently ignores the _indexName, allowing false
positives; update the withIndex mock (the vi.fn inside the query mock) to assert
that _indexName === 'by_definition_status' (or throw/fail the test if not)
before invoking the provided callback, so the test fails if hasRunningExecution
stops using the expected index; locate the query mock and its withIndex
implementation and add this explicit check/assertion.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c2b602f and c39ee38.

📒 Files selected for processing (7)
  • services/platform/app/routes/dashboard/$id.tsx
  • services/platform/app/routes/dashboard/__tests__/dashboard-layout.test.tsx
  • services/platform/convex/workflow_engine/helpers/scheduler/has_running_execution.test.ts
  • services/platform/convex/workflow_engine/helpers/scheduler/has_running_execution.ts
  • services/platform/convex/workflows/schema.ts
  • services/platform/messages/en.json
  • services/platform/vitest.ui.config.mjs

Comment on lines +19 to +21
query: vi.fn((_table: string) => ({
withIndex: vi.fn((_indexName: string, cb: (q: unknown) => unknown) => {
const filters: Record<string, string> = {};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Assert index usage in the mock to prevent false-positive regressions.

Right now _indexName is ignored, so tests can still pass even if hasRunningExecution stops using by_definition_status. That misses the exact optimization this PR introduces.

Suggested test hardening
 function createMockCtx(executions: MockExecution[]) {
   const db = {
-    query: vi.fn((_table: string) => ({
-      withIndex: vi.fn((_indexName: string, cb: (q: unknown) => unknown) => {
+    query: vi.fn((table: string) => ({
+      withIndex: vi.fn((indexName: string, cb: (q: unknown) => unknown) => {
+        expect(table).toBe('wfExecutions');
+        expect(indexName).toBe('by_definition_status');
         const filters: Record<string, string> = {};
         const q = {
           eq: (field: string, value: string) => {
             filters[field] = value;
             return q;
           },
         };
         cb(q);

         const match = executions.find(
           (e) =>
             e.wfDefinitionId === filters['wfDefinitionId'] &&
             e.status === filters['status'],
         );

         return {
           first: vi.fn(async () => match ?? null),
         };
       }),
     })),
   };

Also applies to: 30-38

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@services/platform/convex/workflow_engine/helpers/scheduler/has_running_execution.test.ts`
around lines 19 - 21, The mock for query.withIndex in
has_running_execution.test.ts currently ignores the _indexName, allowing false
positives; update the withIndex mock (the vi.fn inside the query mock) to assert
that _indexName === 'by_definition_status' (or throw/fail the test if not)
before invoking the provided callback, so the test fails if hasRunningExecution
stops using the expected index; locate the query mock and its withIndex
implementation and add this explicit check/assertion.

@larryro larryro merged commit d561dc5 into main Feb 26, 2026
18 checks passed
@larryro larryro deleted the fix/dashboard-access-denied-and-execution-query branch February 26, 2026 12:30
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.

1 participant