Conversation
Deploying modl-panel with
|
| Latest commit: |
c6443c8
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://90949bca.staging-panel.pages.dev |
| Branch Preview URL: | https://dev.staging-panel.pages.dev |
| const res = await apiFetch('/v1/panel/dashboard/alerts'); | ||
| if (!res.ok) { | ||
| throw new Error('Failed to fetch dashboard alerts'); | ||
| } |
There was a problem hiding this comment.
This throws for every non-OK alerts response, including permission or rollout failures. The dashboard does not read or display the alerts error, so a user whose account cannot access the new endpoint gets no alert section and a manual refresh can fail with only the generic dashboard refresh error.
Prompt To Fix With AI
This is a comment left during a code review.
Path: client/src/hooks/use-data.tsx
Line: 1275-1278
Comment:
**Alerts errors are unhandled**
This throws for every non-OK alerts response, including permission or rollout failures. The dashboard does not read or display the alerts error, so a user whose account cannot access the new endpoint gets no alert section and a manual refresh can fail with only the generic dashboard refresh error.
How can I resolve this? If you propose a fix, please make it concise.|
|
||
| // Recovery/verification flows that must stay reachable even when the tenant is not fully | ||
| // provisioned (serverExists===false) or the platform is in maintenance mode. | ||
| const ALWAYS_REACHABLE_PATHS = ['/verify-email', '/verify/', '/replay']; |
There was a problem hiding this comment.
The
/rate-limit page was added to the router but not to ALWAYS_REACHABLE_PATHS. When a user is being rate-limited, the /v1/public/settings request will also fail, so isSettingsError is true and publicSettings is undefined (no prior cache). The guard on the next line then fires and replaces the rate-limit page with "Unable to reach the server" — the exact screen this page is meant to replace.
| const ALWAYS_REACHABLE_PATHS = ['/verify-email', '/verify/', '/replay']; | |
| const ALWAYS_REACHABLE_PATHS = ['/verify-email', '/verify/', '/replay', '/rate-limit']; |
Prompt To Fix With AI
This is a comment left during a code review.
Path: client/src/App.tsx
Line: 194
Comment:
The `/rate-limit` page was added to the router but not to `ALWAYS_REACHABLE_PATHS`. When a user is being rate-limited, the `/v1/public/settings` request will also fail, so `isSettingsError` is `true` and `publicSettings` is `undefined` (no prior cache). The guard on the next line then fires and replaces the rate-limit page with "Unable to reach the server" — the exact screen this page is meant to replace.
```suggestion
const ALWAYS_REACHABLE_PATHS = ['/verify-email', '/verify/', '/replay', '/rate-limit'];
```
How can I resolve this? If you propose a fix, please make it concise.| } catch (error) { | ||
| try { | ||
| if (isPublic) { | ||
| const decoded = await protoFetch(GeneralSettingsEnvelopeSchema, '/v1/panel/settings/general'); | ||
| const general = decoded.data || {}; | ||
| return { | ||
| settings: { | ||
| ...general, | ||
| general, | ||
| generalMeta: metaToShape(decoded.meta), | ||
| } | ||
| }; | ||
| } | ||
| return await fetchPublic(); | ||
| } catch { | ||
| return { | ||
| settings: { | ||
| general: { | ||
| serverDisplayName: 'modl', | ||
| panelIconUrl: null, | ||
| homepageIconUrl: null | ||
| }, | ||
| ticketForms: {} | ||
| } | ||
| }; | ||
| } | ||
| } |
There was a problem hiding this comment.
Swapped fallback branches silently serve wrong settings shape
The outer catch reverses the intended fallbacks: when isPublic === false (a panel user) and the panel endpoint throws a non-auth error (e.g. a 500), the catch calls fetchPublic(), which returns only { serverDisplayName, panelIconUrl, homepageIconUrl, ticketForms }. That stripped shape is then cached for 5 minutes (staleTime: 300000, refetchOnWindowFocus: false), so every panel settings component that expects webhook settings, label settings, or the full general envelope silently reads undefined fields with no error state surfaced to the user.
The if (isPublic) branch (line 120) also tries the authenticated panel endpoint as a fallback when the public endpoint has failed for an unauthenticated visitor — this will always throw a 401, wasting a round-trip before falling through to the hardcoded defaults.
The two branches appear to need swapping: !isPublic → try the panel endpoint, else → try the public endpoint.
Rule Used: This is a React frontend project on React 19 with ... (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: client/src/hooks/data/settings.ts
Line: 118-144
Comment:
**Swapped fallback branches silently serve wrong settings shape**
The outer `catch` reverses the intended fallbacks: when `isPublic === false` (a panel user) and the panel endpoint throws a non-auth error (e.g. a 500), the catch calls `fetchPublic()`, which returns only `{ serverDisplayName, panelIconUrl, homepageIconUrl, ticketForms }`. That stripped shape is then cached for 5 minutes (`staleTime: 300000`, `refetchOnWindowFocus: false`), so every panel settings component that expects webhook settings, label settings, or the full `general` envelope silently reads `undefined` fields with no error state surfaced to the user.
The `if (isPublic)` branch (line 120) also tries the authenticated panel endpoint as a fallback when the public endpoint has failed for an unauthenticated visitor — this will always throw a 401, wasting a round-trip before falling through to the hardcoded defaults.
The two branches appear to need swapping: `!isPublic` → try the panel endpoint, else → try the public endpoint.
**Rule Used:** This is a React frontend project on React 19 with ... ([source](https://app.greptile.com/modl-gg/-/custom-context?memory=b7532101-0c9e-4ab6-b168-353a105ba593))
How can I resolve this? If you propose a fix, please make it concise.
Confidence Score: 4/5
Safe to merge with the settings fallback fix applied; all other changes are well-scoped refactors or additive features.
The auth handler for panel settings silently swallows non-auth errors and serves a stripped public-only settings shape for up to 5 minutes, meaning panel settings components receive undefined fields with no error surfaced. The realtime layer and proto migration are otherwise solid.
client/src/hooks/data/settings.ts — the outer catch fallback branches (lines 118–144) need to be swapped so a panel-page error falls back to the public endpoint and vice versa.
Important Files Changed
Comments Outside Diff (3)
client/src/pages/HomePage.tsx, line 108-109 (link)This page still stores the public knowledgebase response as if it were the category array, but the sibling fixes in this PR now unwrap the same endpoint family from envelope fields like
data.categories,data.cards, anddata.articles. When the backend returns{ categories: [...] }, this setscategoriesto an object, and the render path later callscategories.map, which crashes the public homepage instead of showing the category cards.Rule Used: This is a React frontend project on React 19 with ... (source)
Prompt To Fix With AI
client/src/pages/HomePage.tsx, line 128-129 (link)The homepage cards endpoint was migrated elsewhere in this PR to read
data.cards, but this public homepage path still stores the full response object. With an envelope response like{ cards: [...] },homepageCardsbecomes an object and the card rendering path calls.mapon it, so the homepage can crash before rendering its configured cards.Rule Used: This is a React frontend project on React 19 with ... (source)
Prompt To Fix With AI
client/src/pages/HomePage.tsx, line 156-157 (link)The matching knowledgebase search page now unwraps search results from
data.articles, but this homepage search path still assigns the whole response object. When search returns{ articles: [...] },searchResultsis no longer an array and the search-results render path calls.map, which breaks homepage search instead of showing results.Rule Used: This is a React frontend project on React 19 with ... (source)
Prompt To Fix With AI
Prompt To Fix All With AI
Reviews (10): Last reviewed commit: "fixes" | Re-trigger Greptile