Skip to content

fix(frontend): salvage dashboard server visibility stability - #173

Closed
LucasSantana-Dev wants to merge 9 commits into
mainfrom
fix/dashboard-visibility-salvage
Closed

LucasSantana-Dev wants to merge 9 commits into
mainfrom
fix/dashboard-visibility-salvage

Conversation

@LucasSantana-Dev

@LucasSantana-Dev LucasSantana-Dev commented Mar 12, 2026 •

Copy link
Copy Markdown
Owner

Summary

Validation

  • npm run test --workspace=packages/backend -- tests/unit/services/DiscordOAuthService.test.ts tests/unit/services/GuildAccessService.test.ts
  • npm run test --workspace=packages/frontend -- src/stores/guildStore.test.ts src/hooks/useGuildSelection.test.tsx src/App.authRoutes.test.tsx src/components/Layout/Sidebar.test.tsx src/pages/ServersPage.test.tsx src/pages/DashboardOverview.test.tsx
  • CI=1 npm run test:e2e --workspace=packages/frontend -- tests/e2e/dashboard-page.spec.ts tests/e2e/servers-page.spec.ts tests/e2e/layout-navigation.spec.ts
  • npm run lint --workspace=packages/frontend
  • npm run type:check --workspace=packages/frontend

Notes

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Fixed dashboard resilience when guild authorization fails; individual guild errors are now handled gracefully without dropping the entire server list.
    • Improved OAuth and session error handling with clearer actionable messages.
  • New Features

    • Automatic server selection now prioritizes servers where the bot is already installed.
    • Enhanced server selector with distinct error states and retry/re-authenticate options for authentication and network failures.
    • Added explicit guidance for users to add the bot to their server when none are available.
  • Improvements

    • Server selector now distinguishes between authorization failures, network issues, and fetch errors.
    • Enhanced permission validation to support dual Discord permission formats.

@netlify

netlify Bot commented Mar 12, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for regal-bunny-0c8efe ready!

Name Link
🔨 Latest commit 68172bb
🔍 Latest deploy log https://app.netlify.com/projects/regal-bunny-0c8efe/deploys/69b2365add8ee00008a33e55
😎 Deploy Preview https://deploy-preview-173--regal-bunny-0c8efe.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@vercel

vercel Bot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lucky Ready Ready Preview, Comment Mar 12, 2026 3:43am

Request Review

@coderabbitai

coderabbitai Bot commented Mar 12, 2026 •

Copy link
Copy Markdown

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

Backend adds per-guild authorization resilience and centralized error mapping (401/403/502); Discord permission parsing supports dual formats; frontend removes /servers route guard and auto-selects servers where bot is installed; server selector distinguishes auth failures from empty states with actionable CTAs.

Changes

Cohort / File(s) Summary
Documentation
CHANGELOG.md, README.md
Updated changelog and deployment notes documenting new authorization resilience, permission handling, OAuth error mapping, route accessibility changes, and guild auto-selection behavior.
Backend Guild Route Handlers
packages/backend/src/routes/guilds.ts
Added centralized error handling with getStatusCode, mapGuildAccessError, and runGuildAccessOperation wrapper; wrapped existing endpoints to map Discord API errors (401/403/429/5xx) to AppError variants and upstream outages to 502.
Backend OAuth & Permission Service
packages/backend/src/services/DiscordOAuthService.ts
Added DiscordApiError class with statusCode/endpoint metadata; extended DiscordGuild with optional permissions_new field; implemented permission normalization helpers (parsePermissionBits, normalizePermissionValue); updated hasAdminPermission to accept dual permission formats and filterAdminGuilds to consider both permission fields.
Backend Guild Access Service
packages/backend/src/services/GuildAccessService.ts
Enhanced error handling in fetchUserGuilds to map Discord errors to AppError variants; refactored buildContext to check permissions_new and added resilient bot-presence resolution; made listAuthorizedGuilds skip failing guilds (with logging) instead of failing entire response, throwing 502 only if all fail.
Backend Unit Tests
packages/backend/tests/unit/services/DiscordOAuthService.test.ts, packages/backend/tests/unit/services/GuildAccessService.test.ts
Added tests for invalid permission payloads, dual permission prioritization, error classification (401/403/502/unknown), and guild context resolution failure scenarios; updated hasAdminPermission mock signature to accept two optional parameters.
Frontend Route Guards
packages/frontend/src/App.tsx
Removed module access guard from /servers route, making it accessible for all authenticated users without overview module requirement.
Frontend Guild State Management
packages/frontend/src/stores/guildStore.ts
Major refactor introducing per-request tracking (currentGuildRequestId, currentGuildSelectionRequestId), error classification (GuildLoadErrorKind/GuildLoadErrorState), and resilient guild/member-context fetching with stale-response guards; auto-selects first botAdded guild on load or clears selection if none available; removed hasFetchedGuilds flag.
Frontend Guild Selection Hook
packages/frontend/src/hooks/useGuildSelection.ts
Added authentication-aware guild loading gated by isAuthenticated state; introduced request-suppression via hasRetriedAuthReadyFetch ref to prevent duplicate fetches; updated to auto-select first bot-enabled guild within auth-ready context.
Frontend Server Selector Component
packages/frontend/src/components/Layout/Sidebar.tsx
Extracted new ServerSelector component encapsulating server selection UI, dropdown behavior, loading/error states, and retry/re-authenticate actions; added getGuildLoadMessage helper to map error states to user-facing guidance.
Frontend Unit Tests
packages/frontend/src/App.authRoutes.test.tsx, packages/frontend/src/components/Layout/Sidebar.test.tsx, packages/frontend/src/hooks/useGuildSelection.test.tsx, packages/frontend/src/stores/guildStore.test.ts
Expanded test coverage for new error states (auth/forbidden/network), auto-selection logic, request tracking and stale-response handling, per-guild context resolution failures, and route access without module guards.
Frontend E2E Test Infrastructure
packages/frontend/tests/e2e/helpers/api-helpers.ts, packages/frontend/tests/e2e/helpers/page-helpers.ts, packages/frontend/tests/e2e/helpers/ui-helpers.ts
Replaced global guild mocks with per-guild variants (mockGuildMemberContext, mockServerListing, mockModerationStats, mockModerationCases); refactored setupMockApiResponses to iterate over guilds and register per-guild mocks; updated locator strategies for more robust element selection.
Frontend E2E Tests & Fixtures
packages/frontend/tests/e2e/dashboard-page.spec.ts, packages/frontend/tests/e2e/servers-page.spec.ts, packages/frontend/tests/e2e/layout-navigation.spec.ts, packages/frontend/tests/e2e/fixtures/test-data.ts
Updated test assertions to verify new server-state guidance ("No Server Selected" vs "Could not load servers" vs "Select a Server"), added botAdded flag to guild fixtures, introduced MANAGE_EFFECTIVE_ACCESS constant, replaced text-based selectors with more robust locator strategies.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant Frontend as Frontend Store
    participant Routes as /api/guilds Routes
    participant GuildAccessService
    participant OAuth as DiscordOAuthService
    participant API as Discord API

    Client->>Frontend: Trigger guild fetch (isAuthenticated)
    Frontend->>Routes: GET /api/guilds (with requestId)
    Routes->>GuildAccessService: listAuthorizedGuilds(sessionData)
    
    loop For each guild
        GuildAccessService->>OAuth: resolveGuildContext(sessionData, guildId)
        
        par Bot presence check
            OAuth->>API: GET /users/@me/guilds
        and Member context fetch
            OAuth->>API: GET /guilds/{id}/members/@me
        end
        
        alt API returns 401/403/429/5xx
            OAuth-->>GuildAccessService: Error with statusCode
            GuildAccessService->>GuildAccessService: mapGuildAccessError (classify)
            GuildAccessService->>GuildAccessService: Log failure, continue to next
        else API succeeds
            OAuth-->>GuildAccessService: Guild context
            GuildAccessService->>GuildAccessService: Add to results
        end
    end
    
    alt All guilds failed
        GuildAccessService-->>Routes: AppError 502
        Routes-->>Frontend: 502 (Upstream unavailable)
        Frontend->>Frontend: Set guildLoadError.kind='upstream'
    else Some guilds succeeded
        GuildAccessService-->>Routes: List of guild contexts
        Routes-->>Frontend: 200 with partial results
        Frontend->>Frontend: Auto-select first botAdded guild
    end
    
    Frontend->>Client: Update UI with server list or error state
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

size/xl

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 'fix(frontend): salvage dashboard server visibility stability' is directly related to the main changes involving dashboard server selection, visibility, and resilience improvements.
Linked Issues check ✅ Passed The PR addresses all primary objectives from #169: /servers accessible for authenticated users [App.tsx, README], bot-first guild auto-selection [useGuildSelection.ts, guildStore.ts], guild-load error classification [guildStore.ts, Sidebar.tsx], and E2E contract alignment [dashboard-page.spec.ts, servers-page.spec.ts, layout-navigation.spec.ts].
Out of Scope Changes check ✅ Passed All code changes are within scope. Backend resilience updates (DiscordOAuthService, GuildAccessService, guilds routes) support frontend visibility and error handling. Frontend changes implement server selection, routing, and sidebar logic. E2E and test updates validate the new behavior.

✏️ 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-visibility-salvage

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot added the size/xl label Mar 12, 2026
@LucasSantana-Dev

Copy link
Copy Markdown
Owner Author

Closing this salvage PR because #169 merged directly before salvage merge. Diff is now redundant against main (only changelog line drift).

@LucasSantana-Dev
LucasSantana-Dev deleted the fix/dashboard-visibility-salvage branch March 12, 2026 03:46
LucasSantana-Dev added a commit that referenced this pull request May 31, 2026
## Problem
`lucky-frontend` reports a permanent **false-positive `unhealthy`** (the
app serves fine). Its `Dockerfile` HEALTHCHECK (production-frontend
stage, `nginx-unprivileged:1.31-alpine`) uses `sh -c 'exec
3<>/dev/tcp/127.0.0.1/8080 …'` — but `/dev/tcp` is a **bash builtin**,
and alpine's `sh` is busybox `ash`, which has no `/dev/tcp`. So the
probe could never run.

## Fix
Use busybox `wget` (present at `/usr/bin/wget`) against the unprivileged
`:8080` listener: `wget -q --spider http://127.0.0.1:8080/`. **Validated
live** in the running container (`WGET_SPIDER_OK`).

Part of the same healthcheck-probe-mismatch class as homelab PR #173 +
ADR-0018 and the lucky-bot fix #1105.

This branch was successfully deployed

1 active deployment
Preview — 68172bbf Deployed Mar 12, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant