Skip to content

refactor: resolve implicit any errors and improve fe type safety#3289

Closed
hussainjamal760 wants to merge 21 commits intoOWASP:mainfrom
hussainjamal760:refactor/fe-type-safety
Closed

refactor: resolve implicit any errors and improve fe type safety#3289
hussainjamal760 wants to merge 21 commits intoOWASP:mainfrom
hussainjamal760:refactor/fe-type-safety

Conversation

@hussainjamal760
Copy link
Copy Markdown
Contributor

Proposed change
Resolves #3285

This PR focuses on enhancing the frontend code quality by resolving multiple noImplicitAny errors across core components and utility functions. The goal is to move the project towards a stricter and more maintainable TypeScript configuration.

Key Improvements:

Type Refactoring: Converted implicit any types to explicit interfaces in major components.

Polymorphic Safety: Implemented Type Guards ('prop' in object) and keyof typeof patterns to safely handle complex Union types (Issues, Milestones, Releases, etc.).

Build Integrity: Verified that all refactored files pass strict type checks, reducing the risk of runtime property access errors.

Checklist
[x] Required: I read and followed the contributing guidelines

[x] Required: I ran make check-test locally and all tests passed
4th
5th

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 10, 2026

Summary by CodeRabbit

  • New Features

    • Per-suggestion items now render as interactive buttons for clearer selection.
  • Improvements / Bug Fixes

    • Titles without URLs no longer render as links; avatars are hidden when author data is missing.
    • Hover/highlight and suggestion selection behavior preserved with improved DOM structure.
    • Several components now have stricter typings, reducing runtime ambiguity.
  • Refactor

    • Metadata flows tightened: missing content now yields empty metadata objects.
    • Centralized dashboard filtering with URL sync.
  • Chores

    • Added/expanded TypeScript declarations for third‑party modules.
  • Tests

    • Updated unit tests and extended timeouts.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Widespread TypeScript typing additions and refactors across the frontend: added ambient module declarations, tightened component and GraphQL typings, refactored MultiSearch item rendering and ItemCardList shapes, strengthened Apollo client typings, introduced metrics filter helpers, and updated associated tests and small utilities.

Changes

Cohort / File(s) Summary
Type declarations
frontend/src/types/declarations.d.ts, frontend/src/types/markdown-it-task-lists.d.ts, frontend/src/types/react-leaflet-cluster.d.ts
Add ambient/module declarations for react-leaflet, markdown-it-task-lists, and react-leaflet-cluster (new types/interfaces only). Review for correctness vs. upstream types.
GraphQL query typing & layouts
frontend/src/app/**/layout.tsx (e.g., projects/[projectKey]/layout.tsx, chapters/[chapterKey]/layout.tsx, committees/[committeeKey]/layout.tsx, members/[memberKey]/layout.tsx, organizations/..., community/snapshots/[id]/layout.tsx, organizations/.../repositories/.../layout.tsx)
Import generated Get*Query types, use apolloClient.query<T> generics, add runtime guards (return data only if entity exists), and change missing-data metadata returns from null to {}. Check metadata behavior and downstream consumers.
Apollo client typings
frontend/src/server/apolloClient.ts
Strengthen client types (NormalizedCacheObject), declare global state, tighten authLink/noop client generics, change cache restore fallback, and export a constrained query/mutate surface. Verify runtime SSR toggle and type casts.
MultiSearch rendering
frontend/src/components/MultiSearch.tsx
Switch per-suggestion DOM to button-wrapped items, compute loginName display, preserve keys but change inner structure and event/hover logic binding. Verify keyboard/accessibility and test coverage.
Item card rendering & tests
frontend/src/components/ItemCardList.tsx, frontend/__tests__/unit/components/ItemCardList.test.tsx
Introduce BaseItem/RenderItem types, allow nullable data, unify card shape, always-wrap avatar link when author exists, conditionally omit Link when url is empty, and update tests accordingly. Review key generation and avatar/link behavior.
Metrics filtering refactor
frontend/src/app/projects/dashboard/metrics/page.tsx
Add Health/Level filter structures, mappings, and getFiltersFromParams; derive and sync filters from URL params and update action flows. Review URL sync and pagination reset logic.
Component type annotations & small refactors
frontend/src/components/* (e.g., ProgramCard.tsx, MarkdownWrapper.tsx, AutoScrollToTop.tsx, CardDetailsPage.tsx, ContributionHeatmap.tsx, BarChart.tsx, MultiSearch.tsx, ItemCardList.tsx)
Add explicit types (Record, Readonly props, React return types), refine inline function parameter typings, introduce TooltipContext/RawContribution, refactor leaders rendering and SocialLinks props. Spot-check JSX return types and prop immutability.
Utilities & types
frontend/src/utils/metaconfig.ts, frontend/src/types/healthMetrics.ts, frontend/src/app/about/page.tsx, frontend/src/utils/helpers/githubHeatmap.ts
Narrow getStaticMetadata key type, explicitly type ApexBarChartDataSeries fields, add leaders mapping typing and safe access, and add RawContribution interface with casts in heatmap helpers. Verify no behavioral regressions.
Tests: timeouts & query mocks
frontend/__tests__/unit/pages/CreateModule.test.tsx, frontend/__tests__/unit/pages/RepositoryDetails.test.tsx
Increase waitFor timeout to 15s and ensure useQuery mock includes loading: false. Confirm CI test stability expectations.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • arkid15r
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.64% 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
Title check ✅ Passed The title 'refactor: resolve implicit any errors and improve fe type safety' clearly and concisely describes the main objective of the PR, which is resolving noImplicitAny errors and improving TypeScript type safety across frontend components.
Description check ✅ Passed The description is directly related to the changeset, explaining the purpose of resolving noImplicitAny errors, listing key improvements (type refactoring, polymorphic safety, build integrity), and referencing the linked issue #3285.
Linked Issues check ✅ Passed The PR comprehensively addresses issue #3285 by converting implicit any types to explicit interfaces across 20+ files, implementing type guards and keyof patterns for union types, and ensuring strict TypeScript compliance as required.
Out of Scope Changes check ✅ Passed All changes are within scope of resolving noImplicitAny errors: type annotations on components/utilities, interface definitions, type guards, and test updates to validate type safety improvements. No unrelated refactoring detected.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
Contributor

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/src/utils/helpers/githubHeatmap.ts (1)

16-18: Fix the HeatmapData.contributions type.

The contributions property is typed as an empty array [] which doesn't accurately represent its structure. This should be a proper array type matching the actual data shape.

🔧 Proposed fix
 export interface HeatmapData {
   years: DataStructYear[]
-  contributions: []
+  contributions: Array<{ date: string; count: number }>
 }
🧹 Nitpick comments (5)
frontend/src/components/MultiSearch.tsx (1)

266-272: Consider using nullish coalescing (??) for more precise type-safe fallbacks.

The current implementation uses || which treats empty strings, 0, and false as falsy. For type-safe identifier and display name resolution, the nullish coalescing operator (??) would only fallback on null or undefined, preserving intentional empty strings.

♻️ Proposed refinement using nullish coalescing
                  {suggestion.hits.map((hit, subIndex) => {
                    const keyId =
-                     ('key' in hit && hit.key) ||
-                     ('login' in hit && hit.login) ||
-                     ('url' in hit && hit.url) ||
+                     ('key' in hit && hit.key) ??
+                     ('login' in hit && hit.login) ??
+                     ('url' in hit && hit.url) ??
                      subIndex

-                   const displayName = hit.name || ('login' in hit ? hit.login : '')
+                   const displayName = hit.name ?? ('login' in hit ? hit.login : '')
frontend/src/utils/helpers/githubHeatmap.ts (1)

54-69: Consider refactoring repeated type assertions.

The same type assertion { date: string; count: number }[] is repeated multiple times on lines 54-55, 57, 67-68. This approach works but creates maintenance overhead and verbosity.

♻️ Proposed refactor

Consider extracting and typing the contributions array once to improve readability:

     if (!heatmapData.contributions) {
       return {
         years: [],
         contributions: [],
       }
     }
-    heatmapData.contributions = (
-      heatmapData.contributions as { date: string; count: number }[]
-    ).filter(
-      (item: { date: string; count: number }) =>
-        new Date(item.date) <= endDate && new Date(item.date) >= startDate
-    )
+    
+    const typedContributions = heatmapData.contributions as { date: string; count: number }[]
+    heatmapData.contributions = typedContributions.filter(
+      (item) => new Date(item.date) <= endDate && new Date(item.date) >= startDate
+    )
 
     const allDates: string[] = []
     for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
       allDates.push(format(d, 'yyyy-MM-dd'))
     }
 
     const transformedContributions: HeatmapContribution[] = allDates.map((date) => {
-      const contribution = (heatmapData.contributions as { date: string; count: number }[]).find(
-        (c: { date: string; count: number }) => c.date === date
-      )
+      const contribution = typedContributions.find((c) => c.date === date)
       return contribution
         ? {
             date: contribution.date,
frontend/src/utils/metaconfig.ts (2)

77-77: Consider removing redundant String() conversion.

Since pageKey is typed as MetadataPageKey (a union of string literals from METADATA_CONFIG), it's already a string. The String() wrapper is unnecessary.

♻️ Simplified version
-    canonicalPath: canonicalPath || `/${String(pageKey).toLowerCase()}`,
+    canonicalPath: canonicalPath || `/${pageKey}`,

81-81: Type cast is safe but consider improving config typing.

The cast is currently valid since all METADATA_CONFIG entries have type: 'website'. However, this creates a maintenance risk if the config is later modified.

Consider defining the config type structure explicitly to avoid the need for type assertions:

type MetadataConfigEntry = {
  description: string
  keywords: string[]
  pageTitle: string
  type: 'website' | 'article' | 'profile'
}

Then use this type when defining METADATA_CONFIG in utils/metadata.ts.

frontend/src/components/AutoScrollToTop.tsx (1)

4-16: Type annotation added, though plain functions are preferred in React 19.

The conversion to FC adds explicit typing, which aligns with the PR's type safety goals. However, React 19 documentation recommends plain function declarations over FC for simplicity and better inference.

If you prefer following React 19 best practices, the plain function approach works equally well:

export default function AutoScrollToTop() {
  const pathname = usePathname()
  // ... rest of implementation
}

Both approaches are valid; this is a style preference.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d912c99 and 7d50c8b.

📒 Files selected for processing (10)
  • frontend/src/app/about/page.tsx
  • frontend/src/app/projects/dashboard/metrics/page.tsx
  • frontend/src/components/AutoScrollToTop.tsx
  • frontend/src/components/BarChart.tsx
  • frontend/src/components/CardDetailsPage.tsx
  • frontend/src/components/ContributionHeatmap.tsx
  • frontend/src/components/MultiSearch.tsx
  • frontend/src/components/ProgramCard.tsx
  • frontend/src/utils/helpers/githubHeatmap.ts
  • frontend/src/utils/metaconfig.ts
🧰 Additional context used
🧠 Learnings (11)
📓 Common learnings
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/app/snapshots/[id]/page.tsx:0-0
Timestamp: 2025-09-21T17:04:48.154Z
Learning: User rudransh-shrivastava confirmed that suggested type safety improvements during Apollo Client migration were no longer relevant, reinforcing their preference to keep migration PRs focused on core migration changes rather than additional improvements.
📚 Learning: 2025-07-12T17:14:28.536Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/mentorship/programs/[programKey]/edit/page.tsx:90-128
Timestamp: 2025-07-12T17:14:28.536Z
Learning: Both ProgramForm (programCard.tsx) and ModuleForm (mainmoduleCard.tsx) components already implement HTML validation using the `required` attribute on form fields. The browser's native validation prevents form submission and displays error messages when required fields are empty, eliminating the need for additional JavaScript validation before GraphQL mutations.

Applied to files:

  • frontend/src/components/ProgramCard.tsx
📚 Learning: 2025-07-13T11:29:25.245Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/mentorship/programs/page.tsx:59-61
Timestamp: 2025-07-13T11:29:25.245Z
Learning: In Next.js 13+ app router, components with the 'use client' directive run entirely on the client side and don't require window object existence checks or SSR hydration considerations. Direct access to window.location and other browser APIs is safe in client components.

Applied to files:

  • frontend/src/components/AutoScrollToTop.tsx
📚 Learning: 2025-07-13T07:31:06.511Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/components/ModuleCard.tsx:53-55
Timestamp: 2025-07-13T07:31:06.511Z
Learning: In Next.js 13+ app router, useRouter from 'next/navigation' does not provide asPath or query properties. Use useParams to extract route parameters and usePathname to get the current pathname instead.

Applied to files:

  • frontend/src/components/AutoScrollToTop.tsx
📚 Learning: 2025-07-03T03:08:03.290Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1703
File: frontend/src/components/BarChart.tsx:33-46
Timestamp: 2025-07-03T03:08:03.290Z
Learning: In the OWASP Nest project's BarChart component (frontend/src/components/BarChart.tsx), the days and requirements arrays are guaranteed to always have the same length in their use cases, so input validation for array length matching is not needed.

Applied to files:

  • frontend/src/components/BarChart.tsx
📚 Learning: 2025-09-17T02:42:41.928Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 2288
File: frontend/src/components/ActionButton.tsx:0-0
Timestamp: 2025-09-17T02:42:41.928Z
Learning: In frontend/src/components/ActionButton.tsx, the user Rajgupta36 intentionally changed text-blue-600 to text-[#1D7BD7] to align the text color with the border color (#1D7BD7) for visual consistency, prioritizing design alignment over theme tokens.

Applied to files:

  • frontend/src/components/BarChart.tsx
📚 Learning: 2025-12-29T22:01:53.874Z
Learnt from: ShashaankS
Repo: OWASP/Nest PR: 3086
File: frontend/src/components/SortBy.tsx:45-45
Timestamp: 2025-12-29T22:01:53.874Z
Learning: In frontend/src/components/SortBy.tsx, the SelectItem uses hover:bg-transparent intentionally for better visual appeal and theme consistency. This design choice prioritizes a cleaner aesthetic over hover background feedback.

Applied to files:

  • frontend/src/components/MultiSearch.tsx
📚 Learning: 2025-06-20T16:12:59.256Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/HealthMetrics.tsx:30-30
Timestamp: 2025-06-20T16:12:59.256Z
Learning: In the DetailsCard component (frontend/src/components/CardDetailsPage.tsx), there's a length check before rendering HealthMetrics: `healthMetricsData.length > 0`. This ensures that when HealthMetrics is rendered, the data array has at least one element, making accessing data[0] safe within the HealthMetrics component.

Applied to files:

  • frontend/src/app/projects/dashboard/metrics/page.tsx
📚 Learning: 2025-06-20T16:12:59.256Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/HealthMetrics.tsx:30-30
Timestamp: 2025-06-20T16:12:59.256Z
Learning: In the DetailsCard component (frontend/src/components/CardDetailsPage.tsx), there's a safety check that ensures HealthMetrics component is only rendered when healthMetricsData exists and has at least one element: `healthMetricsData && healthMetricsData.length > 0`. This makes accessing data[0] safe within the HealthMetrics component.

Applied to files:

  • frontend/src/app/projects/dashboard/metrics/page.tsx
📚 Learning: 2025-07-13T11:34:31.823Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/mentorship/programs/page.tsx:14-14
Timestamp: 2025-07-13T11:34:31.823Z
Learning: In the Next.js frontend mentorship application, there are two distinct types for authentication-related data: ExtendedSession for useSession hook (containing accessToken and user.login properties) and UserRolesData for useUserRoles hook (containing currentUserRoles.roles array). The correct access pattern for GitHub username is `(session as ExtendedSession)?.user?.login`.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
📚 Learning: 2025-06-21T12:21:32.372Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/GradientRadialChart.tsx:67-116
Timestamp: 2025-06-21T12:21:32.372Z
Learning: The react-apexcharts Chart component does not support ARIA attributes like aria-label and role as direct props. To add accessibility attributes to ApexCharts in React, wrap the Chart component in a container div with the appropriate ARIA attributes.

Applied to files:

  • frontend/src/components/ContributionHeatmap.tsx
🧬 Code graph analysis (2)
frontend/src/utils/metaconfig.ts (1)
frontend/src/utils/metadata.ts (1)
  • METADATA_CONFIG (1-57)
frontend/src/app/about/page.tsx (1)
backend/apps/owasp/api/internal/nodes/common.py (1)
  • leaders (19-21)
🔇 Additional comments (10)
frontend/src/components/MultiSearch.tsx (1)

274-295: LGTM! Excellent semantic HTML restructuring.

The refactored rendering structure correctly places the button inside the list item rather than wrapping the list item with a button, which improves semantic HTML and accessibility. The type-safe property access using type guards ('key' in hit, 'login' in hit) properly handles the polymorphic union types while maintaining all interactive behaviors and styling.

frontend/src/app/about/page.tsx (1)

324-328: LGTM! Good type-safety improvement.

The introduction of the LeaderUsername type alias and the safe access pattern with a fallback ensures type-safe lookups in the leaders dictionary while gracefully handling cases where a username might not be present.

frontend/src/components/ContributionHeatmap.tsx (1)

183-193: LGTM! Excellent type safety enhancement.

The explicit typing of the tooltip's custom function parameters and the typed access to series data significantly improves type safety while maintaining the existing functionality. The optional chaining on line 193 adds appropriate defensive programming.

frontend/src/components/ProgramCard.tsx (1)

38-42: LGTM! Clean type annotation.

The explicit Record<string, string> type annotation improves type safety for the role-to-CSS-class mapping, making the code more maintainable and self-documenting.

frontend/src/components/BarChart.tsx (1)

82-98: LGTM! Improved type safety for color callback.

The explicit parameter types for the colors callback function enhance type safety and code clarity. The destructured parameters with explicit types make the function's contract clear while maintaining the original coloring logic.

frontend/src/utils/metaconfig.ts (1)

68-70: LGTM! Excellent type safety improvement.

The MetadataPageKey type alias ensures compile-time validation of valid page keys, preventing runtime errors from invalid keys.

frontend/src/app/projects/dashboard/metrics/page.tsx (2)

165-189: Excellent type-safe filter validation pattern.

The typed filter keys combined with runtime validation using the in operator ensure both compile-time and runtime safety. The pattern correctly:

  • Derives types from the mapping objects
  • Validates raw query parameters before type assertion
  • Safely accesses mappings only with validated keys

This eliminates implicit any errors while preventing invalid property access.


292-299: Consistent type-safe handling in action handler.

The action handler correctly applies the same validation pattern used during initialization. The in operator checks combined with type assertions ensure safe mapping access.

frontend/src/components/CardDetailsPage.tsx (2)

106-106: LGTM! Appropriate use of Partial<Record<...>>.

The Partial<Record<CardType, string>> type correctly represents a mapping where only some CardType values have entries. The partial nature allows the fallback on line 111 to work as intended.


3-3: Good explicit typing for SocialLinks component.

The SocialLinksProps interface and React.FC typing improve type safety for this exported component. The import on line 3 supports this typing.

Similar to AutoScrollToTop, while React.FC is acceptable, React 19 documentation recommends plain function declarations for better type inference and simplicity.

Also applies to: 367-371

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 10, 2026
Copy link
Copy Markdown
Contributor

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/src/components/MultiSearch.tsx (1)

53-53: Use generic type parameter instead of type assertion for type-safe Algolia results.

The type assertion on line 53 is needed because fetchAlgoliaData is called without a type parameter, leaving data.hits as unknown[]. Instead of asserting the type, provide the proper generic type based on the index name:

// Current pattern (type-unsafe):
const data = await fetchAlgoliaData(index, query, pageCount, suggestionCount)
hits: data.hits as Chapter[] | Event[] | Organization[] | Project[] | User[],

// Better pattern (see useSearchPage.ts for reference):
const typeMap = {
  'chapters': /* Chapter[] */,
  'organizations': /* Organization[] */,
  'projects': /* Project[] */,
  'users': /* User[] */,
}
const data = await fetchAlgoliaData<TypeForIndex>(index, query, pageCount, suggestionCount)

This makes the type flow explicit and eliminates the need for assertions.

🧹 Nitpick comments (1)
frontend/src/components/MultiSearch.tsx (1)

266-272: Consider using nullish coalescing for more precise fallback logic.

The current implementation uses logical OR (||) which will fallback to the next option for any falsy value (empty string, 0, false, etc.). While unlikely in practice, if hit.key, hit.login, or hit.name could legitimately be empty strings, this logic would incorrectly skip them.

♻️ Use nullish coalescing (??) for more precise fallback
-                    const keyId =
-                      ('key' in hit && hit.key) ||
-                      ('login' in hit && hit.login) ||
-                      ('url' in hit && hit.url) ||
-                      subIndex
+                    const keyId =
+                      ('key' in hit && hit.key) ??
+                      ('login' in hit && hit.login) ??
+                      ('url' in hit && hit.url) ??
+                      subIndex

-                    const displayName = hit.name || ('login' in hit ? hit.login : '')
+                    const displayName = hit.name ?? ('login' in hit ? hit.login : '')

This ensures the fallback only occurs when the value is null or undefined, not when it's an empty string or other falsy value.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1032cdb and b48b2fd.

📒 Files selected for processing (2)
  • frontend/src/components/CardDetailsPage.tsx
  • frontend/src/components/MultiSearch.tsx
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/app/snapshots/[id]/page.tsx:0-0
Timestamp: 2025-09-21T17:04:48.154Z
Learning: User rudransh-shrivastava confirmed that suggested type safety improvements during Apollo Client migration were no longer relevant, reinforcing their preference to keep migration PRs focused on core migration changes rather than additional improvements.
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1714
File: frontend/src/components/ProjectTypeDashboardCard.tsx:8-12
Timestamp: 2025-07-08T17:07:50.988Z
Learning: In the OWASP/Nest project, union types for component props are not necessary when they would require creating separate type definitions. The project prefers inline prop type definitions even for props with specific string values, maintaining consistency with the single-use component prop pattern.
Learnt from: kasya
Repo: OWASP/Nest PR: 1680
File: frontend/src/components/SponsorCard.tsx:3-3
Timestamp: 2025-06-30T00:55:03.133Z
Learning: In the OWASP/Nest project, interfaces or types are not created for component props that are used only once. Inline prop type definitions are preferred for single-use cases.
📚 Learning: 2025-12-29T22:01:53.874Z
Learnt from: ShashaankS
Repo: OWASP/Nest PR: 3086
File: frontend/src/components/SortBy.tsx:45-45
Timestamp: 2025-12-29T22:01:53.874Z
Learning: In frontend/src/components/SortBy.tsx, the SelectItem uses hover:bg-transparent intentionally for better visual appeal and theme consistency. This design choice prioritizes a cleaner aesthetic over hover background feedback.

Applied to files:

  • frontend/src/components/MultiSearch.tsx
📚 Learning: 2025-07-13T11:34:31.823Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/mentorship/programs/page.tsx:14-14
Timestamp: 2025-07-13T11:34:31.823Z
Learning: In the Next.js frontend mentorship application, there are two distinct types for authentication-related data: ExtendedSession for useSession hook (containing accessToken and user.login properties) and UserRolesData for useUserRoles hook (containing currentUserRoles.roles array). The correct access pattern for GitHub username is `(session as ExtendedSession)?.user?.login`.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
🔇 Additional comments (5)
frontend/src/components/CardDetailsPage.tsx (4)

3-3: LGTM! React import enables explicit FC typing.

The React import is necessary for the React.FC<SocialLinksProps> typing used in the SocialLinks component (line 371). While React 19's JSX transform doesn't require importing React for JSX syntax, the import is still needed for TypeScript type references.


106-111: Excellent type safety improvement!

The explicit Partial<Record<CardType, string>> type annotation eliminates implicit any while correctly expressing that only a subset of CardType values need mappings. The fallback pattern on line 111 handles unmapped types safely.


367-369: Well-defined props interface for exported component.

The explicit SocialLinksProps interface appropriately types the component props with urls: string[], eliminating implicit any. Since SocialLinks is exported, defining a reusable interface is appropriate.


371-394: Strongly typed component with safe implementation.

The explicit React.FC<SocialLinksProps> typing eliminates implicit any and provides clear type contracts. The implementation safely guards against empty arrays (line 372) and correctly maps social URLs to icons using the getSocialIcon utility.

frontend/src/components/MultiSearch.tsx (1)

274-295: LGTM! Well-structured accessibility improvements.

The refactored rendering correctly places the icon and text inside a single button element, improving both semantic correctness and keyboard navigation. The implementation includes:

  • Proper type guards for safe property access
  • Comprehensive keyboard handling (Enter, Space)
  • Appropriate focus styles with outline
  • Full-width clickable area for better UX
  • Text truncation to prevent overflow

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 10, 2026
Copy link
Copy Markdown
Contributor

@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

🤖 Fix all issues with AI agents
In @frontend/src/components/MultiSearch.tsx:
- Around line 267-271: The fallback chain computing keyId is broken because
expressions like ('key' in hit && hit.key) yield false when the property is
absent, and false is not nullish so the ?? chain never advances; replace each
('prop' in hit && hit.prop) piece with a null-returning conditional such as
('prop' in hit ? hit.prop : null) so that keyId = ( 'key' in hit ? hit.key :
null ) ?? ( 'login' in hit ? hit.login : null ) ?? ( 'url' in hit ? hit.url :
null ) ?? subIndex, ensuring the chain properly falls back; update the
expression around keyId, hit, and subIndex accordingly.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b48b2fd and 0ab0c90.

📒 Files selected for processing (1)
  • frontend/src/components/MultiSearch.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/app/snapshots/[id]/page.tsx:0-0
Timestamp: 2025-09-21T17:04:48.154Z
Learning: User rudransh-shrivastava confirmed that suggested type safety improvements during Apollo Client migration were no longer relevant, reinforcing their preference to keep migration PRs focused on core migration changes rather than additional improvements.
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1714
File: frontend/src/components/ProjectTypeDashboardCard.tsx:8-12
Timestamp: 2025-07-08T17:07:50.988Z
Learning: In the OWASP/Nest project, union types for component props are not necessary when they would require creating separate type definitions. The project prefers inline prop type definitions even for props with specific string values, maintaining consistency with the single-use component prop pattern.
🧬 Code graph analysis (1)
frontend/src/components/MultiSearch.tsx (6)
frontend/src/types/chapter.ts (1)
  • Chapter (4-29)
frontend/src/types/event.ts (1)
  • Event (1-10)
frontend/src/types/organization.ts (1)
  • Organization (1-17)
frontend/src/types/project.ts (1)
  • Project (20-57)
frontend/src/types/user.ts (1)
  • User (11-35)
frontend/src/server/fetchAlgoliaData.ts (1)
  • fetchAlgoliaData (6-59)
🔇 Additional comments (4)
frontend/src/components/MultiSearch.tsx (4)

16-16: LGTM! Clean type alias for Algolia hits.

The AlgoliaHit union type clearly captures all possible search result types and improves type safety throughout the component.


51-51: LGTM! Explicit generic parameter improves type safety.

Adding the <AlgoliaHit> type parameter eliminates implicit any and ensures type-safe access to the returned hits.


52-56: LGTM! Nullish coalescing is more semantically correct.

The change from || 0 to ?? 0 on line 55 is a better choice for numeric defaults, as it only treats null and undefined as triggers rather than all falsy values.


266-296: LGTM! Rendering refactor improves accessibility and type safety.

The structural changes are excellent:

  • The displayName computation correctly handles both name and login properties
  • Wrapping content in a <button> inside <li> improves accessibility and keyboard navigation
  • Moving the icon inside the button makes the entire area properly clickable
  • Focus styling and keyboard handlers are appropriate

Once the keyId computation bug is fixed (see previous comment), this rendering logic will be solid.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 10, 2026
coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 10, 2026
Copy link
Copy Markdown
Contributor

@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: 0

🧹 Nitpick comments (1)
frontend/src/components/MultiSearch.tsx (1)

267-271: Type guard logic is sound but consider simplification.

The keyId derivation correctly uses type guards with nullish coalescing to safely access properties across the union type. The ?? operator properly handles undefined values from optional properties.

However, note that when all property checks fail and keyId becomes subIndex, the React key on Line 277 becomes ${subIndex}-${subIndex}, which is redundant but harmless. Consider simplifying the key to just String(keyId) since the keyId fallback already includes subIndex when needed.

♻️ Optional: simplify React key generation

Since keyId already falls back to subIndex, the key can be simplified:

-                        key={`${keyId}-${subIndex}`}
+                        key={String(keyId)}

This avoids the redundant ${subIndex}-${subIndex} pattern when keyId defaults to subIndex.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0ab0c90 and 39b4c5a.

📒 Files selected for processing (2)
  • frontend/src/app/about/page.tsx
  • frontend/src/components/MultiSearch.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/app/about/page.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/app/snapshots/[id]/page.tsx:0-0
Timestamp: 2025-09-21T17:04:48.154Z
Learning: User rudransh-shrivastava confirmed that suggested type safety improvements during Apollo Client migration were no longer relevant, reinforcing their preference to keep migration PRs focused on core migration changes rather than additional improvements.
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1714
File: frontend/src/components/ProjectTypeDashboardCard.tsx:8-12
Timestamp: 2025-07-08T17:07:50.988Z
Learning: In the OWASP/Nest project, union types for component props are not necessary when they would require creating separate type definitions. The project prefers inline prop type definitions even for props with specific string values, maintaining consistency with the single-use component prop pattern.
🧬 Code graph analysis (1)
frontend/src/components/MultiSearch.tsx (6)
frontend/src/types/chapter.ts (1)
  • Chapter (4-29)
frontend/src/types/event.ts (1)
  • Event (1-10)
frontend/src/types/organization.ts (1)
  • Organization (1-17)
frontend/src/types/project.ts (1)
  • Project (20-57)
frontend/src/types/user.ts (1)
  • User (11-35)
frontend/src/server/fetchAlgoliaData.ts (1)
  • fetchAlgoliaData (6-59)
🔇 Additional comments (5)
frontend/src/components/MultiSearch.tsx (5)

16-16: LGTM! Type alias improves clarity.

The AlgoliaHit type alias clearly defines all possible search result types and eliminates implicit any issues when handling search results.


51-51: LGTM! Generic type parameter enhances type safety.

Adding the generic type parameter ensures that data.hits is correctly typed as AlgoliaHit[], eliminating implicit any and improving IntelliSense support.


52-56: Excellent fix: ?? is more appropriate than || for numeric defaults.

The change from || 0 to ?? 0 on Line 55 correctly handles the case where totalPages is legitimately 0, since ?? only treats null and undefined as nullish, whereas || treats all falsy values (including 0) as requiring the default.


273-273: Display name logic is sound with expected behavior.

The displayName derivation correctly falls back from name to login for Organization and User types. Note that the ?? operator means an empty string '' for name will be used rather than falling back to login. This is likely the intended behavior, but verify that empty names are acceptable in your UI.


275-296: Excellent accessibility improvements with button structure.

The refactored rendering structure wraps each suggestion in a proper <button> element with:

  • Correct semantic HTML (<li> containing <button>)
  • Proper keyboard event handling for Enter and Space keys
  • Focus management with visible outline styles
  • Full-width clickable area for better UX

This significantly improves accessibility for keyboard and screen reader users.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 11, 2026
@hussainjamal760
Copy link
Copy Markdown
Contributor Author

Hi @rudransh-shrivastava ,
Waiting for your review. Let me know if any changes are required.

Copy link
Copy Markdown
Collaborator

@rudransh-shrivastava rudransh-shrivastava left a comment

Choose a reason for hiding this comment

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

Nice work, this resolves many implicit any conversions. However, a few still exist.

If you enable noImplicitAny in tsconfig.json, you'll be able to identify other instances of implicit any conversions. I'm not suggesting that we should enable it, but just for identification. I think ignoring the ones in test files should be okay for this PR.

If possible, we might be able to enable it just for the src/ directory using the extends property: https://www.typescriptlang.org/tsconfig/extends.html

Also, separate out type/const definitions as suggested by Ark. I have unresolved that comment.

@hussainjamal760
Copy link
Copy Markdown
Contributor Author

@rudransh-shrivastava Yes, I usually work in the same way. I make all the changes using noimplictany, but I remove it before pushing the code. I will implement the changes you suggested and will verify them using make check-test. I will send it back to you for review. Thank you very much for your valuable feedback.

@hussainjamal760
Copy link
Copy Markdown
Contributor Author

@rudransh-shrivastava @arkid15r

I have made the requested changes. Please review them.
If any further changes or improvements are needed, kindly let me know , I’ll be happy to update them.
Thank you.

Copy link
Copy Markdown
Contributor

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/src/components/CardDetailsPage.tsx (1)

164-184: leadersValue is computed but never used; JSX.Element stringification bug persists.

The leadersValue variable (lines 167-172) correctly handles the case where detail.value might be a JSX.Element, but line 177 still uses String(detail.value) which will render as [object Object] for JSX elements.

🐛 Proposed fix: Use the computed leadersValue
             return isLeaders ? (
               <div key={detail.label} className="flex flex-row gap-1 pb-1">
                 <strong>{detail.label}:</strong>{' '}
-                <LeadersList leaders={detail?.value == null ? 'Unknown' : String(detail.value)} />
+                <LeadersList leaders={leadersValue} />
               </div>
             ) : (
🤖 Fix all issues with AI agents
In `@frontend/src/components/CardDetailsPage.tsx`:
- Line 116: The declared variable userLogin (const userLogin = (data as
ExtendedSession)?.user?.login) is referencing undefined data and is unused;
either remove that declaration from CardDetailsPage.tsx, or change it to use the
existing session variable (const userLogin = (session as
ExtendedSession)?.user?.login) and then replace occurrences of
session?.user?.login with userLogin; update or remove the unused ExtendedSession
cast accordingly so there are no reference errors or unused variables.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 41b8ceb and 411b3c5.

📒 Files selected for processing (3)
  • frontend/src/app/about/page.tsx
  • frontend/src/components/CardDetailsPage.tsx
  • frontend/src/components/ProgramCard.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/src/components/ProgramCard.tsx
  • frontend/src/app/about/page.tsx
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/app/snapshots/[id]/page.tsx:0-0
Timestamp: 2025-09-21T17:04:48.154Z
Learning: User rudransh-shrivastava confirmed that suggested type safety improvements during Apollo Client migration were no longer relevant, reinforcing their preference to keep migration PRs focused on core migration changes rather than additional improvements.
📚 Learning: 2025-06-20T16:12:59.256Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/HealthMetrics.tsx:30-30
Timestamp: 2025-06-20T16:12:59.256Z
Learning: In the DetailsCard component (frontend/src/components/CardDetailsPage.tsx), there's a length check before rendering HealthMetrics: `healthMetricsData.length > 0`. This ensures that when HealthMetrics is rendered, the data array has at least one element, making accessing data[0] safe within the HealthMetrics component.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
📚 Learning: 2025-06-20T16:12:59.256Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/HealthMetrics.tsx:30-30
Timestamp: 2025-06-20T16:12:59.256Z
Learning: In the DetailsCard component (frontend/src/components/CardDetailsPage.tsx), there's a safety check that ensures HealthMetrics component is only rendered when healthMetricsData exists and has at least one element: `healthMetricsData && healthMetricsData.length > 0`. This makes accessing data[0] safe within the HealthMetrics component.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
📚 Learning: 2025-07-03T03:08:03.290Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1703
File: frontend/src/components/BarChart.tsx:33-46
Timestamp: 2025-07-03T03:08:03.290Z
Learning: In the OWASP Nest project's BarChart component (frontend/src/components/BarChart.tsx), the days and requirements arrays are guaranteed to always have the same length in their use cases, so input validation for array length matching is not needed.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
📚 Learning: 2025-07-13T11:34:31.823Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/mentorship/programs/page.tsx:14-14
Timestamp: 2025-07-13T11:34:31.823Z
Learning: In the Next.js frontend mentorship application, there are two distinct types for authentication-related data: ExtendedSession for useSession hook (containing accessToken and user.login properties) and UserRolesData for useUserRoles hook (containing currentUserRoles.roles array). The correct access pattern for GitHub username is `(session as ExtendedSession)?.user?.login`.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
📚 Learning: 2025-09-21T17:04:48.154Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/app/snapshots/[id]/page.tsx:0-0
Timestamp: 2025-09-21T17:04:48.154Z
Learning: User rudransh-shrivastava confirmed that suggested type safety improvements during Apollo Client migration were no longer relevant, reinforcing their preference to keep migration PRs focused on core migration changes rather than additional improvements.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
📚 Learning: 2025-08-10T11:08:47.258Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/api/auth/[...nextauth]/route.ts:13-25
Timestamp: 2025-08-10T11:08:47.258Z
Learning: In the OWASP Nest codebase (frontend/src/app/api/auth/[...nextauth]/route.ts), input validation and string trimming for authentication-related queries like `isProjectLeader` and `isMentor` are handled in the backend rather than the frontend. The backend is responsible for sanitizing and validating input parameters.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
🧬 Code graph analysis (1)
frontend/src/components/CardDetailsPage.tsx (1)
frontend/src/types/auth.ts (1)
  • ExtendedSession (8-20)
🔇 Additional comments (2)
frontend/src/components/CardDetailsPage.tsx (2)

105-109: LGTM!

The explicit Partial<Record<CardType, string>> type annotation correctly represents the map structure and improves type safety.


381-381: LGTM!

Adding explicit prop types to SocialLinks improves type safety and aligns with the PR's objective of eliminating implicit any types.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@hussainjamal760
Copy link
Copy Markdown
Contributor Author

@rudransh-shrivastava Kindly review this and let me know if there are any issues, so I can fix them.

Copy link
Copy Markdown
Collaborator

@rudransh-shrivastava rudransh-shrivastava left a comment

Choose a reason for hiding this comment

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

Hey, I updated apolloClient.ts to return a typed data object. Please update any instances of data as <Query> type assertions that may not be needed anymore. I updated frontend/src/app/api/auth/[...nextauth]/route.ts for reference.

Note: I have not reviewed the following files yet. I will when I get a chance:

  • frontend/src/app/projects/dashboard/metrics/page.tsx
  • frontend/src/components/ItemCardList.tsx
  • frontend/src/components/MultiSearch.tsx
  • frontend/src/server/apolloClient.ts

Also, please run make check-test locally and make sure everything passes:

Copy link
Copy Markdown
Contributor

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/src/app/committees/[committeeKey]/layout.tsx (1)

38-45: Inconsistent metadata fallback: returns null instead of {}.

The projects layout (line 41) returns {} when no project is found, but this committee layout returns null. For consistency and type correctness with Promise<Metadata>, consider returning an empty object:

Suggested fix for consistency
   return committee
     ? generateSeoMetadata({
         canonicalPath: `/committees/${committeeKey}`,
         description: committee.summary ?? `${committee.name} details`,
         keywords: ['owasp', 'security', 'committee', committeeKey, committee.name],
         title: committee.name,
       })
-    : null
+    : {}
🤖 Fix all issues with AI agents
In `@frontend/src/components/ItemCardList.tsx`:
- Around line 45-50: The prop typing for the ItemCardList component is too
narrow: change the `data` prop declaration on the ItemCardList props to allow
null/undefined (e.g. make it `data?: (Issue | Milestone | PullRequest |
Release)[] | null | undefined`) so it matches guards (`data && data.length > 0`)
and callsites that pass `data?.recentIssues`; update the prop signature where
`data: (Issue | Milestone | PullRequest | Release)[]` is declared (alongside
`icon`, `showAvatar`, `showSingleColumn`, and `renderDetails`) to the widened
nullable/optional form. Ensure no other code relies on non-null `data` without
checking first.
♻️ Duplicate comments (3)
frontend/src/app/chapters/[chapterKey]/layout.tsx (1)

11-27: Consider whether explicit typing is necessary here.

The GetChapterMetadataDocument is already typed as DocumentNode<GetChapterMetadataQuery, GetChapterMetadataQueryVariables> (per the generated types), which allows Apollo to infer the query result type automatically. The explicit generic parameter and return type annotation are technically redundant.

A previous reviewer noted these changes may not be required. If the team prefers relying on TypeScript's inference from the typed DocumentNode, you could simplify to:

const getChapterMetadata = cache(async (chapterKey: string) => {
  try {
    const { data } = await apolloClient.query({
      query: GetChapterMetadataDocument,
      variables: { key: chapterKey },
    })
    return data?.chapter ? data : null
  } catch {
    return null
  }
})

That said, explicit annotations can aid readability and provide clearer error messages when types drift. Either approach is valid—defer to team preference.

frontend/src/types/declarations.d.ts (1)

1-38: Avoid shadowing react-leaflet’s bundled typings.

If the installed react-leaflet version already ships official TypeScript definitions, this ambient module can mask/duplicate them and narrows the prop surface, which runs counter to the type-safety goals of this PR. Prefer removing this block and rely on the package-provided types; if you must add missing pieces, use augmentation that only adds new types rather than redefining exports.

♻️ Proposed removal (use bundled react-leaflet types)
-declare module 'react-leaflet' {
-  import * as L from 'leaflet'
-  import * as React from 'react'
-
-  interface MapContainerProps {
-    center?: L.LatLngExpression
-    zoom?: number
-    scrollWheelZoom?: boolean
-    style?: React.CSSProperties
-    zoomControl?: boolean
-    maxBounds?: L.LatLngBoundsExpression
-    maxBoundsViscosity?: number
-    children?: React.ReactNode
-  }
-
-  interface TileLayerProps {
-    attribution?: string
-    url: string
-    className?: string
-  }
-
-  interface MarkerProps {
-    position: L.LatLngExpression
-    icon?: L.Icon | L.DivIcon
-    title?: string
-    children?: React.ReactNode
-  }
-
-  interface PopupProps {
-    children?: React.ReactNode
-  }
-
-  export const MapContainer: React.FC<MapContainerProps>
-  export const TileLayer: React.FC<TileLayerProps>
-  export const Marker: React.FC<MarkerProps>
-  export const Popup: React.FC<PopupProps>
-  export function useMap(): L.Map
-}
Does the current react-leaflet version used in OWASP/Nest ship built-in TypeScript definitions, and if so should local ambient module declarations be removed?
frontend/src/components/ItemCardList.tsx (1)

86-88: Add rel="noopener noreferrer" to the external link with target="_blank".

Opening external URLs in a new tab without rel="noopener noreferrer" exposes the page to security and privacy risks: the opened page can access window.opener to manipulate the original tab, and the referrer is leaked. This attribute should be added to the Link component.

🔧 Suggested fix
-                      <Link href={cardItem.url} target="_blank">
+                      <Link href={cardItem.url} target="_blank" rel="noopener noreferrer">
🧹 Nitpick comments (3)
frontend/src/app/organizations/[organizationKey]/repositories/[repositoryKey]/layout.tsx (1)

36-44: Consider aligning return value with organization layout for consistency.

This returns null when no repository is found, while the organization layout (frontend/src/app/organizations/[organizationKey]/layout.tsx line 35) returns {} in the same scenario. Both are valid for Next.js Metadata, but using a consistent approach across layouts improves maintainability.

♻️ Suggested change for consistency
   return repository
     ? generateSeoMetadata({
         canonicalPath: `/organizations/${organizationKey}/repositories/${repositoryKey}`,
         description: repository.description ?? `${repository.name} repository details`,
         keywords: ['owasp', 'repository', repositoryKey, repository.name],
         title: repository.name,
       })
-    : null
+    : {}
frontend/src/app/organizations/[organizationKey]/layout.tsx (1)

105-110: Type annotation is correct; consider caching for deduplication.

The generic type is properly applied. Note that this query duplicates the fetch in generateMetadata (line 20). While outside the scope of this type-safety PR, wrapping in a cache function (like the repository layout does) would deduplicate these calls during a single render.

frontend/src/server/apolloClient.ts (1)

37-38: Unsafe type assertion: null as T is a type lie.

The no-op client returns { data: null as T } but the return type claims Promise<{ data: T }>. This is unsafe because callers expect data to be of type T, not null. While this is intended for E2E tests, consuming code may encounter runtime errors when accessing properties on data.

Consider making the return type honest:

Suggested fix
 const noopApolloClient = {
-  mutate: async <T>(_options?: unknown): Promise<{ data: T }> => ({ data: null as T }),
-  query: async <T>(_options?: unknown): Promise<{ data: T }> => ({ data: null as T }),
+  mutate: async <T>(_options?: unknown): Promise<{ data: T | null }> => ({ data: null }),
+  query: async <T>(_options?: unknown): Promise<{ data: T | null }> => ({ data: null }),
 }

Copy link
Copy Markdown
Contributor

@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

🤖 Fix all issues with AI agents
In `@frontend/src/components/ItemCardList.tsx`:
- Around line 26-31: Update the RenderItem type so its date fields match the
source models instead of forcing strings: change createdAt to a union using
Issue['createdAt'] | Milestone['createdAt'] | PullRequest['createdAt'], change
publishedAt to Release['publishedAt'], and add openIssuesCount and
closedIssuesCount as optional numbers; remove the runtime/type cast that masks
these mismatches (the cast currently used where RenderItem instances are
produced) so TypeScript will enforce the correct union types from the source
models.
🧹 Nitpick comments (2)
frontend/src/components/ItemCardList.tsx (2)

56-57: Avoid the broad as RenderItem & BaseItem assertion.

After aligning RenderItem with the source types, you can drop this cast so TypeScript enforces the shape instead of bypassing it.

♻️ Suggested tweak
-          const cardItem = item as RenderItem & BaseItem
+          const cardItem: RenderItem = item

68-83: Default avatar fallback is currently unreachable.

Rendering is gated on author?.avatarUrl, so '/images/default-avatar.png' is never used. If you want a placeholder, gate on author instead; otherwise drop the fallback.

🧹 Optional cleanup
-                  {showAvatar && cardItem?.author?.avatarUrl && (
+                  {showAvatar && cardItem?.author && (
...
-                          src={cardItem?.author?.avatarUrl || '/images/default-avatar.png'}
+                          src={cardItem.author.avatarUrl || '/images/default-avatar.png'}

fix(types): add minZoom, maxZoom, worldCopyJump to MapContainerProps
@kasya
Copy link
Copy Markdown
Collaborator

kasya commented Jan 23, 2026

@hussainjamal760 could you resolve conflicts on this one?

@hussainjamal760
Copy link
Copy Markdown
Contributor Author

@hussainjamal760 could you resolve conflicts on this one?

@kasya resolved

@sonarqubecloud
Copy link
Copy Markdown

@codecov
Copy link
Copy Markdown

codecov bot commented Jan 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.60%. Comparing base (7484604) to head (b2efd97).
⚠️ Report is 217 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3289      +/-   ##
==========================================
- Coverage   85.60%   85.60%   -0.01%     
==========================================
  Files         461      461              
  Lines       14222    14173      -49     
  Branches     1894     1879      -15     
==========================================
- Hits        12175    12133      -42     
+ Misses       1678     1674       -4     
+ Partials      369      366       -3     
Flag Coverage Δ
backend 84.47% <ø> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
frontend/src/app/about/page.tsx 88.46% <ø> (-0.11%) ⬇️
...ontend/src/app/projects/dashboard/metrics/page.tsx 93.45% <ø> (+3.45%) ⬆️
frontend/src/components/AutoScrollToTop.tsx 100.00% <ø> (ø)
frontend/src/components/BarChart.tsx 94.44% <ø> (-0.16%) ⬇️
frontend/src/components/CardDetailsPage.tsx 88.42% <ø> (+0.42%) ⬆️
frontend/src/components/ContributionHeatmap.tsx 80.21% <ø> (-0.22%) ⬇️
frontend/src/components/ItemCardList.tsx 100.00% <ø> (ø)
frontend/src/components/MarkdownWrapper.tsx 100.00% <ø> (ø)
frontend/src/components/MultiSearch.tsx 92.56% <ø> (+0.37%) ⬆️
frontend/src/components/ProgramCard.tsx 95.23% <ø> (-0.22%) ⬇️

... and 6 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7484604...b2efd97. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hussainjamal760
Copy link
Copy Markdown
Contributor Author

Hi, @rudransh-shrivastava I’ve noticed that the CI/CD pipeline has failed. I’d appreciate your help in analyzing the issue so we can fix it and close this matter.

@arkid15r
Copy link
Copy Markdown
Collaborator

@hussainjamal760 do you plan to address those or I can close the PR?

@arkid15r arkid15r marked this pull request as draft February 16, 2026 23:32
@arkid15r arkid15r closed this Feb 21, 2026
@arkid15r
Copy link
Copy Markdown
Collaborator

Closing as abandoned.

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.

[Cleanup] Resolve Implicit Any Errors and Improve Frontend Type Safety

4 participants