Skip to content

Feat/newlogos#73

Merged
SimonBurmer merged 6 commits intomainfrom
feat/newlogos
Apr 5, 2026
Merged

Feat/newlogos#73
SimonBurmer merged 6 commits intomainfrom
feat/newlogos

Conversation

@SimonBurmer
Copy link
Copy Markdown
Collaborator

@SimonBurmer SimonBurmer commented Apr 5, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Added LinkedIn profile links for team members
  • UI/Style Updates

    • Enhanced partner logo carousel with improved visibility, hover effects, and responsive sizing
    • Improved team member profile card styling and avatar display
    • Updated board image handling for better visual presentation
  • Content Updates

    • Refined partnership descriptions
    • Updated team demographic information
    • Improved homepage navigation flow

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 5, 2026

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

Project Deployment Actions Updated (UTC)
start-munich Ready Ready Preview, Comment Apr 5, 2026 4:36pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 5, 2026

📝 Walkthrough

Walkthrough

The PR consolidates partner data fetching into a new utility (lib/partners.ts), removes the admin UI and associated startup API routes, updates multiple pages to use centralized partner retrieval, and applies styling/content updates including LinkedIn profile integration for board members and a root route redirect to /home.

Changes

Cohort / File(s) Summary
Partner data layer refactoring
lib/partners.ts, app/api/partners/route.ts, app/for-partners/page.tsx, app/home/page.tsx
Introduced new lib/partners.ts utility with Partner interface and getAllPartners() function; replaced inline NocoDB fetching in /api/partners and page-level fetchPartners() with centralized utility; updated logo selection logic to use last uploaded image instead of first.
Admin and startup API removal
app/admin/page.tsx, app/api/startups/[id]/route.ts, app/api/startups/add/route.ts
Removed entire admin page UI (1145 lines), dynamic startup GET/PUT/DELETE route handler (355 lines), and POST handler for adding startups (266 lines); eliminated client-side admin state management, form validation, and NocoDB integration logic.
UI and styling updates
app/home/HomeClient.tsx, app/members/page.tsx, app/page.tsx
Updated partner logo carousel styling with opacity/hover transitions; modified board member rendering with LinkedIn URL integration and adjusted placeholder image detection; changed root page to redirect to /home; updated member gender distribution percentages and board image fallback rendering.
Content updates
app/about-us/page.tsx
Revised mission partner (CDTM/Manage & More) description text in two descriptionParts entries.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • CFO fix #24: Modifies app/members/page.tsx placeholder UI and name-rendering logic for member cards.
  • Feat/UI improvements #10: Removes admin UI and startup API code with overlapping file changes and deletions.
  • Fix: Ali Changes #48: Updates app/about-us/page.tsx mission partner description rendering with optional chaining safety improvements.

Poem

🐰 Partners tucked neatly in a utility so fine,
Admin and startups packed away—no more design!
Pages now dance with getAllPartners() calls,
Members linked to LinkedIn within our halls.
Root redirects home, cleaner paths we take,
A refactored foundation for the web we make! 🎉

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Feat/newlogos' is vague and does not clearly describe the main changes in the pull request. While logos are modified, the PR involves significant refactoring including removing admin UI, migrating to a new partners library, and updating multiple page components. Use a more descriptive title that captures the primary objective, such as 'Refactor: migrate partner data fetching to shared library and update logo handling' or 'Feat: restructure admin and partner data management with new logo selection logic'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/newlogos

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.

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: 5

🧹 Nitpick comments (3)
lib/partners.ts (1)

32-66: Error handling silently returns empty array for all failure modes.

getAllPartners() returns [] for config errors, HTTP errors, and exceptions alike. Consumers (like app/api/partners/route.ts) cannot distinguish between "NocoDB returned zero partners" and "NocoDB is down." The route handler's check on lines 16-21 only catches the missing config case, not runtime failures.

Consider returning a result object or throwing for actual errors so callers can respond appropriately (e.g., return 500 vs 200 with empty data).

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

In `@lib/partners.ts` around lines 32 - 66, getAllPartners currently swallows all
failures and returns [] so callers can't differentiate "no partners" from
runtime/config errors; change getAllPartners to surface errors instead of always
returning an empty array—either by throwing on config checks, non-2xx HTTP
responses, and caught exceptions (e.g., throw new Error with the status/details)
or by returning a discriminated result object like { success: boolean, data?:
Partner[], error?: string } so callers (e.g., app/api/partners/route.ts) can map
config errors to 400/500 and runtime failures to 500 while still returning 200
for an actual empty data array; implement the chosen approach in getAllPartners
and update any callers to handle the thrown errors or inspect the result object
accordingly.
app/members/page.tsx (1)

540-555: Consider using a non-navigating element when no LinkedIn URL exists.

Using href="#" when linkedinUrl is falsy will scroll the page to the top on click, despite the cursor-default styling. Consider using a <div> or <span> instead of <a> when there's no link, or use href="javascript:void(0)" / add onClick={(e) => e.preventDefault()}.

🔧 Alternative approach using conditional element
{member.linkedinUrl ? (
  <a href={member.linkedinUrl} target="_blank" rel="noopener noreferrer" className="relative cursor-pointer">
    {/* card content */}
  </a>
) : (
  <div className="relative cursor-default">
    {/* card content */}
  </div>
)}

Or extract the card content to avoid duplication.

Also applies to: 568-583

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

In `@app/members/page.tsx` around lines 540 - 555, The anchor uses href="#" when
member.linkedinUrl is falsy causing unintended navigation; update the JSX around
member.linkedinUrl (the element wrapping the card that currently uses <a key={i}
href={member.linkedinUrl || '#'} …>) to conditionally render an <a> only when
member.linkedinUrl exists and otherwise render a non-navigating element (e.g.,
<div> or <span>) with the same class names and content (the card including the
Image, getInitials fallback, and the name/role blocks) to avoid page scroll;
alternatively, if you prefer one element, remove href="#" and add onClick={(e)
=> e.preventDefault()} when member.linkedinUrl is falsy, and keep target/rel
only when linkedinUrl is present.
app/api/partners/route.ts (1)

7-12: Consider removing or reducing verbose debug logging in production.

These console logs expose partial API tokens and configuration details. While the token is truncated, logging this on every request could clutter production logs and potentially leak sensitive information.

🔧 Suggested improvement
 export async function GET() {
-    console.log('========== FETCHING ALL PARTNERS ==========');
-    console.log('🔍 Environment Variables:');
-    const token = process.env.NOCODB_API_TOKEN;
-    console.log('NOCODB_API_TOKEN:', token ? `${token.substring(0, 10)}... (${token.length} chars)` : 'NOT SET');
-    console.log('NOCODB_BASE_URL:', process.env.NOCODB_BASE_URL || 'https://ndb.startmunich.de');
-    console.log('NOCODB_PARTNERS_TABLE_ID:', process.env.NOCODB_PARTNERS_TABLE_ID);
-
     const partners = await getAllPartners();

If debugging is needed, consider using a debug flag or NODE_ENV check.

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

In `@app/api/partners/route.ts` around lines 7 - 12, The console.log statements in
app/api/partners/route.ts (the "========== FETCHING ALL PARTNERS =========="
block) emit sensitive/config data on every request; update that block to remove
or gate verbose logging behind a debug flag or NODE_ENV check (e.g., only log
when process.env.DEBUG_PARTNERS === 'true' or process.env.NODE_ENV !==
'production'), stop printing any API token fragments, and replace with minimal
safe logs (like "Fetching partners" and conditional detailed debug info) so that
normal production requests do not leak or clutter logs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/about-us/page.tsx`:
- Around line 38-39: Replace the abrupt sentence "However START Munich and CDTM
/ M&M differ." with a smoother connective and adjust the following sentence for
flow; for example, change it to "However, START Munich differs from CDTM and
M&M: we're a community that emphasizes learning by doing, while those are
structured educational programs." Update the array entry containing that text
(the object with pink: true) and ensure the next object remains a separate
sentence about members joining both programs.

In `@app/api/partners/route.ts`:
- Around line 14-24: The endpoint in app/api/partners/route.ts currently treats
an empty partners array as success and only errors when env vars are missing;
change the flow so you first validate NOCODB_API_TOKEN and
NOCODB_PARTNERS_TABLE_ID and return 500 if missing, then call getAllPartners(),
and if getAllPartners() returns an empty array while config is present, log an
error and return a 500 (or propagate the actual error). Also update
lib/partners.ts to stop swallowing upstream errors from the NocoDB call (let
exceptions bubble or return error details) so the route can respond with proper
non-200 status when NocoDB fails; reference getAllPartners and the handler in
app/api/partners/route.ts.

In `@app/home/page.tsx`:
- Around line 45-51: The partner logo selection is inconsistent:
app/home/page.tsx chooses the last uploaded logo (logos[logos.length - 1]) while
lib/partners.ts currently uses the first (Logo[0]); update lib/partners.ts to
mirror app/home/page.tsx by selecting the last element of the Logo array (use
Logo[Logo.length - 1] or equivalent) and guard for empty/null Logo arrays so the
fallback avatar logic remains used—ensure the same signedPath/URL construction
logic is applied so both endpoints return the same logo for a partner.

In `@lib/partners.ts`:
- Around line 18-20: The code hardcodes "https://ndb.startmunich.de/" when
constructing logoUrl instead of using the existing NOCODB_BASE_URL constant;
update the assignment that sets logoUrl (the block using logo.signedPath) to
build the URL from NOCODB_BASE_URL and the signedPath (e.g., join
NOCODB_BASE_URL and logo.signedPath while avoiding duplicate slashes or using
the URL constructor) so logoUrl uses NOCODB_BASE_URL consistently.
- Around line 23-26: The mapping in lib/partners.ts uses the misspelled field
record.Categrory and a non-deterministic fallback id String(Math.random());
first verify the NocoDB table schema and correct the field access to the actual
column name (change record.Categrory to record.Category if the schema uses
"Category", or defensively read both record.Category || record.Categrory to
handle a misspelling at source), and second replace the unstable id fallback in
the partner mapping (and the similar use in app/home/page.tsx) with a stable
value — prefer record.Id when present, otherwise derive a deterministic hash
from record.Name (or another stable field) instead of Math.random() so
server/client renders remain consistent.

---

Nitpick comments:
In `@app/api/partners/route.ts`:
- Around line 7-12: The console.log statements in app/api/partners/route.ts (the
"========== FETCHING ALL PARTNERS ==========" block) emit sensitive/config data
on every request; update that block to remove or gate verbose logging behind a
debug flag or NODE_ENV check (e.g., only log when process.env.DEBUG_PARTNERS ===
'true' or process.env.NODE_ENV !== 'production'), stop printing any API token
fragments, and replace with minimal safe logs (like "Fetching partners" and
conditional detailed debug info) so that normal production requests do not leak
or clutter logs.

In `@app/members/page.tsx`:
- Around line 540-555: The anchor uses href="#" when member.linkedinUrl is falsy
causing unintended navigation; update the JSX around member.linkedinUrl (the
element wrapping the card that currently uses <a key={i}
href={member.linkedinUrl || '#'} …>) to conditionally render an <a> only when
member.linkedinUrl exists and otherwise render a non-navigating element (e.g.,
<div> or <span>) with the same class names and content (the card including the
Image, getInitials fallback, and the name/role blocks) to avoid page scroll;
alternatively, if you prefer one element, remove href="#" and add onClick={(e)
=> e.preventDefault()} when member.linkedinUrl is falsy, and keep target/rel
only when linkedinUrl is present.

In `@lib/partners.ts`:
- Around line 32-66: getAllPartners currently swallows all failures and returns
[] so callers can't differentiate "no partners" from runtime/config errors;
change getAllPartners to surface errors instead of always returning an empty
array—either by throwing on config checks, non-2xx HTTP responses, and caught
exceptions (e.g., throw new Error with the status/details) or by returning a
discriminated result object like { success: boolean, data?: Partner[], error?:
string } so callers (e.g., app/api/partners/route.ts) can map config errors to
400/500 and runtime failures to 500 while still returning 200 for an actual
empty data array; implement the chosen approach in getAllPartners and update any
callers to handle the thrown errors or inspect the result object accordingly.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9fc0bd3e-ed52-48f8-8466-0b6bf79cff1f

📥 Commits

Reviewing files that changed from the base of the PR and between fc38772 and c2f1197.

⛔ Files ignored due to path filters (1)
  • public/ourMembers/boads/boad26.jpeg is excluded by !**/*.jpeg
📒 Files selected for processing (13)
  • app/about-us/page.tsx
  • app/admin/page.tsx
  • app/api/partners/route.ts
  • app/api/startups/[id]/route.ts
  • app/api/startups/add/route.ts
  • app/for-partners/page.tsx
  • app/home/HomeClient.tsx
  • app/home/page.tsx
  • app/members/page.tsx
  • app/page.tsx
  • lib/partners.ts
  • scripts/landing_page_proposal.html
  • tsconfig.tsbuildinfo
💤 Files with no reviewable changes (3)
  • app/api/startups/add/route.ts
  • app/admin/page.tsx
  • app/api/startups/[id]/route.ts

Comment thread app/about-us/page.tsx
Comment on lines +38 to +39
{ text: "However START Munich and CDTM / M&M differ. We are a community that encourages learning by doing, while they are educational programs that provide structured curriculum. ", pink: true },
{ text: "Some of our members also join CDTM or M&M, but handling the intensive time commitment for both is challenging." },
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 | 🟡 Minor

Polish wording for readability and tone consistency.

The new copy is clear in intent, but “However START Munich and CDTM / M&M differ.” reads a bit abrupt. Consider tightening the phrasing to improve flow.

Suggested copy tweak
-    { text: "However START Munich and CDTM / M&M differ. We are a community that encourages learning by doing, while they are educational programs that provide structured curriculum. ", pink: true },
-    { text: "Some of our members also join CDTM or M&M, but handling the intensive time commitment for both is challenging." },
+    { text: "However, START Munich and CDTM / M&M differ in format: we are a community that encourages learning by doing, while they are educational programs with a structured curriculum. ", pink: true },
+    { text: "Some of our members also join CDTM or M&M, but balancing the intensive time commitment of both is challenging." },
📝 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
{ text: "However START Munich and CDTM / M&M differ. We are a community that encourages learning by doing, while they are educational programs that provide structured curriculum. ", pink: true },
{ text: "Some of our members also join CDTM or M&M, but handling the intensive time commitment for both is challenging." },
{ text: "However, START Munich and CDTM / M&M differ in format: we are a community that encourages learning by doing, while they are educational programs with a structured curriculum. ", pink: true },
{ text: "Some of our members also join CDTM or M&M, but balancing the intensive time commitment of both is challenging." },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/about-us/page.tsx` around lines 38 - 39, Replace the abrupt sentence
"However START Munich and CDTM / M&M differ." with a smoother connective and
adjust the following sentence for flow; for example, change it to "However,
START Munich differs from CDTM and M&M: we're a community that emphasizes
learning by doing, while those are structured educational programs." Update the
array entry containing that text (the object with pink: true) and ensure the
next object remains a separate sentence about members joining both programs.

Comment thread app/api/partners/route.ts
Comment on lines +14 to +24
const partners = await getAllPartners();

// Check if NocoDB is configured
if (!NOCODB_API_TOKEN || !NOCODB_PARTNERS_TABLE_ID) {
console.error('NocoDB not configured - missing API token or partners table ID');
if (partners.length === 0 && (!process.env.NOCODB_API_TOKEN || !process.env.NOCODB_PARTNERS_TABLE_ID)) {
return NextResponse.json(
{ error: 'NocoDB not configured for partners' },
{ status: 500 }
);
}

try {
console.log('Fetching partners from NocoDB...');

const response = await fetch(
`${NOCODB_BASE_URL}/api/v2/tables/${NOCODB_PARTNERS_TABLE_ID}/records?limit=1000&offset=0`,
{
headers: {
'xc-token': NOCODB_API_TOKEN,
'Content-Type': 'application/json',
},
next: { revalidate: 3600 },
}
);

if (!response.ok) {
const errorText = await response.text();
console.error(`NocoDB API error: ${response.status} ${response.statusText}`, errorText);
throw new Error(`NocoDB API error: ${response.status} ${response.statusText}`);
}

const data = await response.json();

// Debug: Log the first raw record to see actual column names
if (data.list && data.list[0]) {
console.log('📋 Sample raw record from NocoDB:', JSON.stringify(data.list[0], null, 2));
}

const partners = (data.list || [])
.filter((record: any) => {
// Check if 'Show' column is true, 1, or 'true' (case-insensitive)
const show = record.Show;
return show === true || show === 1 || String(show).toLowerCase() === 'true';
})
.map(transformNocoDBRecord);

console.log(`Successfully fetched ${partners.length} partners from NocoDB`);
return NextResponse.json(partners);

} catch (error) {
console.error('Error fetching from NocoDB:', error);
return NextResponse.json(
{ error: 'Failed to fetch partners from database' },
{ status: 500 }
);
}
console.log(`Successfully fetched ${partners.length} partners from NocoDB`);
return NextResponse.json(partners);
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

Error detection logic may mask upstream failures.

The current check only returns a 500 error when partners.length === 0 AND environment variables are missing. If NocoDB is configured but fails (network error, API error), getAllPartners() returns [] and this route returns 200 with an empty array—masking the actual failure from clients.

This ties back to the error-swallowing behavior in lib/partners.ts. If that's not addressed, consider at minimum logging when an empty result is returned despite valid config.

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

In `@app/api/partners/route.ts` around lines 14 - 24, The endpoint in
app/api/partners/route.ts currently treats an empty partners array as success
and only errors when env vars are missing; change the flow so you first validate
NOCODB_API_TOKEN and NOCODB_PARTNERS_TABLE_ID and return 500 if missing, then
call getAllPartners(), and if getAllPartners() returns an empty array while
config is present, log an error and return a 500 (or propagate the actual
error). Also update lib/partners.ts to stop swallowing upstream errors from the
NocoDB call (let exceptions bubble or return error details) so the route can
respond with proper non-200 status when NocoDB fails; reference getAllPartners
and the handler in app/api/partners/route.ts.

Comment thread app/home/page.tsx
Comment on lines +45 to +51
const logos: any[] = r.Logo || []
// Some partners have two images uploaded; always use the last one so that
// a newer/preferred logo can be added as a second upload without removing the original.
const logo = logos.length > 0 ? logos[logos.length - 1] : null
const logoUrl = logo?.signedPath
? `${NOCODB_BASE_URL}/${logo.signedPath}`
: `https://ui-avatars.com/api/?name=${encodeURIComponent(r.Name || 'Partner')}&size=300&background=4f46e5&color=fff&bold=true&font-size=0.4`
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

Inconsistent logo selection logic across codebase.

This function picks the last logo (logos[logos.length - 1]) with the rationale that newer uploads should take precedence. However, lib/partners.ts:16-20 picks the first logo (Logo[0]). This divergence means the same partner could display different logos on /home vs /for-partners or the API.

Consider aligning both implementations to use the same selection strategy.

🔧 Option: Update lib/partners.ts to match this behavior

In lib/partners.ts:

     if (record.Logo && Array.isArray(record.Logo) && record.Logo[0]) {
-        const logo = record.Logo[0];
+        const logo = record.Logo[record.Logo.length - 1];
         if (logo.signedPath) {
             logoUrl = `${NOCODB_BASE_URL}/${logo.signedPath}`;
         }
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/home/page.tsx` around lines 45 - 51, The partner logo selection is
inconsistent: app/home/page.tsx chooses the last uploaded logo
(logos[logos.length - 1]) while lib/partners.ts currently uses the first
(Logo[0]); update lib/partners.ts to mirror app/home/page.tsx by selecting the
last element of the Logo array (use Logo[Logo.length - 1] or equivalent) and
guard for empty/null Logo arrays so the fallback avatar logic remains
used—ensure the same signedPath/URL construction logic is applied so both
endpoints return the same logo for a partner.

Comment thread lib/partners.ts
Comment on lines +18 to +20
if (logo.signedPath) {
logoUrl = `https://ndb.startmunich.de/${logo.signedPath}`;
}
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 | 🟡 Minor

Hardcoded base URL instead of using environment variable.

Line 19 hardcodes https://ndb.startmunich.de/ but NOCODB_BASE_URL is defined at the top of the file (line 2). This creates an inconsistency if the base URL ever changes.

🔧 Proposed fix
     if (record.Logo && Array.isArray(record.Logo) && record.Logo[0]) {
         const logo = record.Logo[0];
         if (logo.signedPath) {
-            logoUrl = `https://ndb.startmunich.de/${logo.signedPath}`;
+            logoUrl = `${NOCODB_BASE_URL}/${logo.signedPath}`;
         }
     }
📝 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
if (logo.signedPath) {
logoUrl = `https://ndb.startmunich.de/${logo.signedPath}`;
}
if (logo.signedPath) {
logoUrl = `${NOCODB_BASE_URL}/${logo.signedPath}`;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/partners.ts` around lines 18 - 20, The code hardcodes
"https://ndb.startmunich.de/" when constructing logoUrl instead of using the
existing NOCODB_BASE_URL constant; update the assignment that sets logoUrl (the
block using logo.signedPath) to build the URL from NOCODB_BASE_URL and the
signedPath (e.g., join NOCODB_BASE_URL and logo.signedPath while avoiding
duplicate slashes or using the URL constructor) so logoUrl uses NOCODB_BASE_URL
consistently.

Comment thread lib/partners.ts
Comment on lines +23 to +26
return {
id: record.Id || String(Math.random()),
name: record.Name || 'Unnamed Partner',
category: record.Categrory || 'Other',
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 | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for other usages of Categrory vs Category in the codebase
rg -n 'Categrory|Category' --type ts --type tsx

Repository: startmunich/website-special-pages

Length of output: 104


🏁 Script executed:

#!/bin/bash
# Search for Categrory and Category usage without problematic file type
rg -n 'Categrory|Category' lib/

Repository: startmunich/website-special-pages

Length of output: 142


🏁 Script executed:

#!/bin/bash
# Also check the full context of lib/partners.ts around lines 23-26
wc -l lib/partners.ts

Repository: startmunich/website-special-pages

Length of output: 95


🏁 Script executed:

#!/bin/bash
# Read the relevant portion of lib/partners.ts
head -40 lib/partners.ts | tail -20

Repository: startmunich/website-special-pages

Length of output: 773


🏁 Script executed:

#!/bin/bash
# Search entire codebase for Categrory
rg -n 'Categrory' .

Repository: startmunich/website-special-pages

Length of output: 306


🏁 Script executed:

#!/bin/bash
# Check for any Partner type/interface definitions
rg -n 'interface Partner|type Partner|category' lib/partners.ts | head -20

Repository: startmunich/website-special-pages

Length of output: 179


🏁 Script executed:

#!/bin/bash
# Look for NocoDB-related configuration or field mappings
rg -n 'NOCODB|field|Field' lib/partners.ts

Repository: startmunich/website-special-pages

Length of output: 514


🏁 Script executed:

#!/bin/bash
# Check if there's any documentation about NocoDB field names
find . -type f \( -name "README*" -o -name "*.md" -o -name ".env*" \) | xargs grep -l "Categrory\|partner" 2>/dev/null | head -10

Repository: startmunich/website-special-pages

Length of output: 59


🏁 Script executed:

#!/bin/bash
# Look for the Partner interface definition to see full context
sed -n '5,12p' lib/partners.ts

Repository: startmunich/website-special-pages

Length of output: 207


Verify NocoDB field name and address non-deterministic ID generation.

Two concerns:

  1. Field name mismatch: The code accesses record.Categrory while the Partner interface property is category. This pattern appears consistently across the codebase (also in app/home/page.tsx:52), suggesting Categrory may match the actual NocoDB field name. Verify this against the NocoDB table schema to confirm the field is indeed misspelled at the source or if it should be corrected to Category.

  2. String(Math.random()) produces non-deterministic IDs that could cause React hydration mismatches between server and client renders. This issue also appears in app/home/page.tsx:52. Use a stable identifier such as a hash of the record's name or the record's ID value if available.

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

In `@lib/partners.ts` around lines 23 - 26, The mapping in lib/partners.ts uses
the misspelled field record.Categrory and a non-deterministic fallback id
String(Math.random()); first verify the NocoDB table schema and correct the
field access to the actual column name (change record.Categrory to
record.Category if the schema uses "Category", or defensively read both
record.Category || record.Categrory to handle a misspelling at source), and
second replace the unstable id fallback in the partner mapping (and the similar
use in app/home/page.tsx) with a stable value — prefer record.Id when present,
otherwise derive a deterministic hash from record.Name (or another stable field)
instead of Math.random() so server/client renders remain consistent.

@SimonBurmer SimonBurmer merged commit 943c996 into main Apr 5, 2026
3 checks passed
@SimonBurmer SimonBurmer deleted the feat/newlogos branch April 5, 2026 22:20
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