Skip to content
18 changes: 5 additions & 13 deletions frontend/app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { CookieBanner } from '@/components/shared/CookieBanner';
import Footer from '@/components/shared/Footer';
import { ScrollWatcher } from '@/components/shared/ScrollWatcher';
import { ThemeProvider } from '@/components/theme/ThemeProvider';
// import { getCachedBlogCategories } from '@/db/queries/blog/blog-categories';
import { getCachedBlogCategories } from '@/db/queries/blog/blog-categories';
import { AuthProvider } from '@/hooks/useAuth';
import { locales } from '@/i18n/config';

Expand All @@ -25,18 +25,10 @@ export default async function LocaleLayout({

if (!locales.includes(locale as any)) notFound();

// const [messages, blogCategories] = await Promise.all([
// getMessages({ locale }),
// getCachedBlogCategories(locale),
// ]);

const messages = await getMessages({ locale });
const blogCategories: Array<{
id: string;
slug: string;
title: string;
}> = [];

const [messages, blogCategories] = await Promise.all([
getMessages({ locale }),
getCachedBlogCategories(locale),
]);
Comment on lines +28 to +31
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.

⚠️ Potential issue | 🟠 Major

Don't let blog-category lookup reintroduce global 500s.

getCachedBlogCategories() is just a cached DB wrapper with no fallback, so one rejection here aborts the entire locale layout again. Since blogCategories is optional in AppChrome, this should degrade to [] instead of taking down dashboard/auth/leaderboard pages that don't need blog nav data to render.

💡 Suggested fix
-  const [messages, blogCategories] = await Promise.all([
-    getMessages({ locale }),
-    getCachedBlogCategories(locale),
-  ]);
+  const [messagesResult, blogCategoriesResult] = await Promise.allSettled([
+    getMessages({ locale }),
+    getCachedBlogCategories(locale),
+  ]);
+
+  if (messagesResult.status === 'rejected') throw messagesResult.reason;
+
+  const messages = messagesResult.value;
+  const blogCategories =
+    blogCategoriesResult.status === 'fulfilled'
+      ? blogCategoriesResult.value
+      : [];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/app/`[locale]/layout.tsx around lines 28 - 31, The parallel fetch
currently uses Promise.all so a rejection from getCachedBlogCategories aborts
the whole layout; change the logic to treat blogCategories as optional by
catching errors from getCachedBlogCategories (or using Promise.allSettled) and
defaulting blogCategories to [] on failure while still throwing or propagating
errors from getMessages, and log the error; update the code around the
Promise.all call that assigns [messages, blogCategories] so AppChrome always
receives an array (possibly empty) for blogCategories instead of letting a DB
rejection bubble up.


const enableAdmin =
(
Expand Down
2 changes: 1 addition & 1 deletion frontend/db/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ if (process.env.NODE_ENV !== 'test') {

const IS_LOCAL_ENV = APP_ENV === 'local';

const STRICT_LOCAL_DB_GUARD = process.env.SHOP_STRICT_LOCAL_DB === '1';
0const STRICT_LOCAL_DB_GUARD = process.env.SHOP_STRICT_LOCAL_DB === '1';
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.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Show the malformed declaration in context and scan for similar accidental prefixes.
sed -n '24,32p' frontend/db/index.ts
rg -nP '^\s*\d+const\b' --type ts

Repository: DevLoversTeam/devlovers.net

Length of output: 398


Remove the stray 0 before const.

Line 29 is a hard syntax error (0const), so frontend/db/index.ts will not parse. This prevents the DB module from loading before the Netlify env fallback or the SHOP_STRICT_LOCAL_DB guard can run, which can bring back SSR 500s across DB-backed pages and also bypass the local-test safety check used by frontend/playwright.config.ts:27 and frontend/lib/tests/shop/setup.ts:39.

Suggested fix
-0const STRICT_LOCAL_DB_GUARD = process.env.SHOP_STRICT_LOCAL_DB === '1';
+const STRICT_LOCAL_DB_GUARD = process.env.SHOP_STRICT_LOCAL_DB === '1';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
0const STRICT_LOCAL_DB_GUARD = process.env.SHOP_STRICT_LOCAL_DB === '1';
const STRICT_LOCAL_DB_GUARD = process.env.SHOP_STRICT_LOCAL_DB === '1';
🧰 Tools
🪛 Biome (2.4.9)

[error] 29-29: Expected a statement but instead found '0const STRICT_LOCAL_DB_GUARD = process.env.SHOP_STRICT_LOCAL_DB === '1''.

(parse)


[error] 29-29: numbers cannot be followed by identifiers directly after

(parse)

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

In `@frontend/db/index.ts` at line 29, Remove the stray leading character before
the declaration: change the malformed token "0const STRICT_LOCAL_DB_GUARD =
process.env.SHOP_STRICT_LOCAL_DB === '1';" to a valid const declaration "const
STRICT_LOCAL_DB_GUARD = process.env.SHOP_STRICT_LOCAL_DB === '1';" so the module
parses and the SHOP_STRICT_LOCAL_DB guard (STRICT_LOCAL_DB_GUARD) can run; after
fixing, run TypeScript/ESLint or a quick build to confirm no other syntax errors
remain.

const REQUIRED_LOCAL_DB_URL = process.env.SHOP_REQUIRED_DATABASE_URL_LOCAL;

if (STRICT_LOCAL_DB_GUARD) {
Expand Down
4 changes: 0 additions & 4 deletions frontend/next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ import createNextIntlPlugin from 'next-intl/plugin';
const withNextIntl = createNextIntlPlugin('./i18n/request.ts');

const nextConfig: NextConfig = {
env: {
APP_ENV: process.env.APP_ENV,
DATABASE_URL: process.env.DATABASE_URL,
},
images: {
remotePatterns: [
{
Expand Down
3 changes: 3 additions & 0 deletions netlify.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@

[[plugins]]
package = "@netlify/plugin-nextjs"

[[plugins]]
package = "netlify-plugin-bundle-env"
Loading