Skip to content

Implement the presentation of dashboard metrics list with filters - #1718

Merged
arkid15r merged 54 commits into
OWASP:mainfrom
ahmedxgouda:dashboard/metrics-list-frontend
Jul 23, 2025
Merged

arkid15r merged 54 commits into
OWASP:mainfrom
ahmedxgouda:dashboard/metrics-list-frontend

Conversation

@ahmedxgouda

@ahmedxgouda ahmedxgouda commented Jul 7, 2025 •

Copy link
Copy Markdown
Collaborator

Resolves #1701

Screencast.from.2025-07-13.18-11-14.mp4

@coderabbitai

coderabbitai Bot commented Jul 7, 2025 •

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Introduced a metrics dashboard page displaying a paginated, filterable, and sortable list of project health metrics.
    • Added interactive dropdowns for filtering by project level or health status and sorting by score.
    • Implemented clickable metric cards linking to detailed project views.
    • Enabled navigation to filtered metrics dashboards from project type cards.
  • Bug Fixes

    • Improved UI elements for navigation and dark mode compatibility.
  • Tests

    • Added comprehensive end-to-end and unit tests for the metrics dashboard, including UI rendering, filtering, sorting, and pagination.
    • Introduced mock data and new test suites for backend ordering and query functionality.
  • Documentation

    • Updated custom dictionary for terminology consistency.
  • Chores

    • Added utility functions and new types to support dropdowns and metrics filtering.

Walkthrough

This change implements a new project health metrics dashboard list in the frontend, including a paginated, filterable, and sortable metrics page with supporting components, GraphQL queries, and types. Backend changes add ordering and filtering to the health metrics API, expose new fields, and update tests. New end-to-end and unit tests validate the dashboard's functionality.

Changes

Files / Areas Change Summary
frontend/src/app/projects/dashboard/metrics/page.tsx, frontend/src/components/MetricsCard.tsx, frontend/src/components/ProjectsDashboardDropDown.tsx, frontend/src/components/ProjectsDashboardNavBar.tsx, frontend/src/components/ProjectTypeDashboardCard.tsx Added new React components for the metrics dashboard page, metric cards, dropdown filters, and updated navigation and dashboard card linking for filtering and sorting.
frontend/src/server/queries/projectsHealthDashboardQueries.ts Added a new GraphQL query for paginated, filterable, and sortable project health metrics list.
frontend/src/types/healthMetrics.ts, frontend/src/types/DropDownSectionProps.ts Added/updated TypeScript types for health metrics, filters, and dropdown section props.
frontend/src/utils/getKeysLabels.ts Added utility function to map dropdown selection keys to their corresponding labels.
cspell/custom-dict.txt Added "lte" to the custom spelling dictionary.
frontend/__tests__/e2e/pages/ProjectsHealthDashboardMetrics.spec.ts Added end-to-end Playwright tests for the metrics dashboard page, including UI element presence and data rendering validation.
frontend/__tests__/unit/data/mockProjectsHealthMetricsData.ts, frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx Added mock data and unit tests for the metrics dashboard page and its components, covering loading, error, data rendering, and user interaction scenarios.
backend/apps/owasp/api/internal/nodes/project_health_metrics.py Updated ProjectHealthMetricsNode to inherit from strawberry.relay.Node, removed pagination from decorator, and added a project_key field resolver method.
backend/apps/owasp/api/internal/ordering/project_health_metrics.py Added new ordering type ProjectHealthMetricsOrder for project health metrics with a score field.
backend/apps/owasp/api/internal/queries/project_health_metrics.py Refactored health metrics query to support filters, pagination, and ordering; added a distinct length resolver for filtered metrics count.
backend/tests/apps/owasp/api/internal/nodes/project_health_metrics_test.py, backend/tests/apps/owasp/api/internal/ordering/project_health_metrics_test.py, backend/tests/apps/owasp/api/internal/queries/project_health_metrics_test.py Updated and added backend tests for new fields, ordering functionality, and query logic including filtering and pagination.

Estimated code review effort

3 (~45 minutes)

Possibly related PRs

Suggested reviewers

  • kasya

📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5a0e059 and aaf144c.

📒 Files selected for processing (3)
  • backend/apps/owasp/api/internal/queries/project_health_metrics.py (2 hunks)
  • frontend/src/types/DropDownSectionProps.ts (1 hunks)
  • frontend/src/types/healthMetrics.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • frontend/src/types/DropDownSectionProps.ts
  • frontend/src/types/healthMetrics.ts
  • backend/apps/owasp/api/internal/queries/project_health_metrics.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run backend tests
  • GitHub Check: Run frontend unit tests
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: CodeQL (javascript-typescript)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • 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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 10

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 022ec16 and a0ff4a4.

📒 Files selected for processing (9)
  • backend/apps/owasp/graphql/nodes/project_health_metrics.py (1 hunks)
  • backend/apps/owasp/graphql/queries/project_health_metrics.py (1 hunks)
  • frontend/src/app/projects/dashboard/layout.tsx (1 hunks)
  • frontend/src/app/projects/dashboard/metrics/page.tsx (1 hunks)
  • frontend/src/app/projects/dashboard/page.tsx (1 hunks)
  • frontend/src/components/MetricsCard.tsx (1 hunks)
  • frontend/src/components/ProjectsDashboardNavBar.tsx (1 hunks)
  • frontend/src/server/queries/projectsHealthDashboardQueries.ts (1 hunks)
  • frontend/src/types/healthMetrics.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
backend/apps/owasp/graphql/nodes/project_health_metrics.py (1)
Learnt from: ahmedxgouda
PR: OWASP/Nest#1676
File: backend/apps/owasp/graphql/filters/project_health_metrics.py:17-22
Timestamp: 2025-06-29T00:41:32.198Z
Learning: In the OWASP Nest codebase, when implementing GraphQL filters that convert string values to enums (like ProjectLevel), do not catch ValueError exceptions for invalid values. Let the errors propagate to provide proper error responses to GraphQL clients rather than silently ignoring invalid input.
frontend/src/app/projects/dashboard/layout.tsx (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/components/ProjectsDashboardNavBar.tsx (1)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/components/MetricsCard.tsx (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/app/projects/dashboard/metrics/page.tsx (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/types/healthMetrics.ts (3)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1633
File: frontend/src/components/GradientRadialChart.tsx:113-113
Timestamp: 2025-06-21T12:22:01.889Z
Learning: In the OWASP Nest project, health metrics requirements (like lastCommitDaysRequirement, lastReleaseDaysRequirement) should never be 0. A requirement value of 0 is considered invalid and should result in displaying 0 on the radial chart.
frontend/src/app/projects/dashboard/page.tsx (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/server/queries/projectsHealthDashboardQueries.ts (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
🧬 Code Graph Analysis (3)
frontend/src/components/MetricsCard.tsx (1)
frontend/src/types/healthMetrics.ts (1)
  • HealthMetricsProps (26-42)
frontend/src/app/projects/dashboard/metrics/page.tsx (2)
frontend/src/types/healthMetrics.ts (2)
  • HealthMetricsProps (26-42)
  • HealthMetricsFilter (44-52)
frontend/src/server/queries/projectsHealthDashboardQueries.ts (1)
  • GET_PROJECT_HEALTH_METRICS_LIST (20-35)
frontend/src/app/projects/dashboard/page.tsx (1)
frontend/src/server/queries/projectsHealthDashboardQueries.ts (1)
  • GET_PROJECT_HEALTH_STATS (3-19)
🪛 Biome (1.9.4)
frontend/src/app/projects/dashboard/layout.tsx

[error] 10-10: The elements with the following roles can be changed to the following elements:

For examples and more information, see WAI-ARIA Roles

(lint/a11y/useSemanticElements)


[error] 10-10: Using the role attribute 'main' on the 'main' element is redundant, because it is implied by the semantic 'main' element.

Unsafe fix: Remove the role attribute.

(lint/a11y/noRedundantRoles)

🪛 GitHub Actions: Run CI/CD
frontend/src/types/healthMetrics.ts

[error] 49-49: CSpell: Unknown word 'lte' detected during spelling check.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: CodeQL (javascript-typescript)
  • GitHub Check: CodeQL (python)
🔇 Additional comments (8)
frontend/src/components/ProjectsDashboardNavBar.tsx (1)

1-55: LGTM! Well-implemented navigation component.

The component follows React and Next.js best practices with proper TypeScript typing, accessibility attributes, and responsive design. The code is clean, maintainable, and includes appropriate client-side directive usage.

backend/apps/owasp/graphql/nodes/project_health_metrics.py (1)

29-29: LGTM! Proper relay node inheritance for pagination support.

The change to inherit from strawberry.relay.Node correctly enables GraphQL relay-style pagination, aligning with the corresponding query-level pagination changes.

backend/apps/owasp/graphql/queries/project_health_metrics.py (1)

19-19: LGTM! Pagination enabled at query level.

The addition of pagination=True to the field decorator correctly enables pagination support for the project health metrics query, complementing the node-level changes.

frontend/src/app/projects/dashboard/layout.tsx (1)

1-17: LGTM! Well-structured layout component.

The component provides a clean, responsive layout structure for the dashboard with proper semantic HTML and accessibility considerations.

frontend/src/server/queries/projectsHealthDashboardQueries.ts (2)

3-19: LGTM! Well-structured GraphQL query for aggregated statistics.

The query structure is clean and includes all necessary fields for displaying project health dashboard statistics.


20-35: LGTM! Proper use of variables for pagination and filtering.

The query correctly uses variables for filters and pagination, enabling flexible data fetching. The field selection matches the component requirements.

frontend/src/types/healthMetrics.ts (2)

26-42: LGTM! Type updates properly support the new dashboard functionality.

The additions of optional fields like id, contributorsCount, and projectName align well with the GraphQL queries and component requirements. Making several fields optional provides flexibility for different use cases.


44-52: LGTM! Well-structured filter type for GraphQL queries.

The HealthMetricsFilter type properly supports both score range filtering and level filtering, matching the GraphQL query structure and component filtering needs.

Comment thread frontend/src/components/MetricsCard.tsx Resolved
Comment thread frontend/src/components/MetricsCard.tsx Resolved
Comment thread frontend/src/components/MetricsCard.tsx Resolved
Comment thread frontend/src/types/healthMetrics.ts Resolved

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a0ff4a4 and bb843a5.

📒 Files selected for processing (1)
  • cspell/custom-dict.txt (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run CI Denendencies Scan
  • GitHub Check: Run Code Scan
  • GitHub Check: CodeQL (python)
  • GitHub Check: CodeQL (javascript-typescript)

Comment thread cspell/custom-dict.txt Resolved

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

♻️ Duplicate comments (6)
frontend/src/components/MetricsCard.tsx (3)

8-8: Handle optional id field to prevent navigation issues.

The id field is optional in HealthMetricsProps but used directly for navigation. This could cause issues if id is undefined.


13-13: Handle optional projectName field gracefully.

The projectName field is optional in HealthMetricsProps but used directly, which could display "undefined" text.


22-22: Handle optional contributorsCount field gracefully.

The contributorsCount field is optional in HealthMetricsProps but used directly, which could display "undefined" text.

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

25-25: Consider making pagination limit configurable.

The hard-coded pagination limit of 10 reduces flexibility. Consider making it configurable or using a constant.


53-59: Fix potential race condition in filter handling.

The refetch call uses the old filters state instead of the new value being set, which could lead to inconsistent filtering behavior due to React's asynchronous state updates.


76-80: Add handling for empty metrics state.

Consider adding a message or placeholder when no metrics are available to improve user experience.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dd94dfc and 234fb58.

📒 Files selected for processing (2)
  • frontend/src/app/projects/dashboard/metrics/page.tsx (1 hunks)
  • frontend/src/components/MetricsCard.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/app/projects/dashboard/metrics/page.tsx (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/components/MetricsCard.tsx (4)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: codic-yeeshu
PR: OWASP/Nest#1444
File: frontend/src/components/NavDropDown.tsx:0-0
Timestamp: 2025-04-30T13:41:20.846Z
Learning: Use React's useId() hook rather than manually generating random strings when creating accessibility identifiers for UI components. This creates stable, unique IDs without causing hydration mismatches.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1633
File: frontend/src/components/GradientRadialChart.tsx:113-113
Timestamp: 2025-06-21T12:22:01.889Z
Learning: In the OWASP Nest project, health metrics requirements (like lastCommitDaysRequirement, lastReleaseDaysRequirement) should never be 0. A requirement value of 0 is considered invalid and should result in displaying 0 on the radial chart.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run Code Scan
  • GitHub Check: Run CI Denendencies Scan
  • GitHub Check: CodeQL (javascript-typescript)
  • GitHub Check: CodeQL (python)
🔇 Additional comments (2)
frontend/src/components/MetricsCard.tsx (1)

31-34: Score color logic is well-implemented.

The conditional color coding for scores (green ≥75, orange 50-74, red <50) provides clear visual feedback and follows good UX practices for health metrics display.

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

68-75: Grid layout implementation is well-structured.

The grid headers match the layout used in MetricsCard, providing consistent column alignment. The responsive grid system with fractional units appropriately allocates space for different data types.

Comment thread frontend/src/components/MetricsCard.tsx Resolved

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

♻️ Duplicate comments (4)
frontend/src/app/projects/dashboard/metrics/page.tsx (4)

19-19: Remove redundant manual loading state management.

The manual isLoading state is unnecessary since Apollo Client's useQuery already provides a loading state. This creates redundant state management and potential inconsistencies.


30-39: Simplify useEffect by removing manual loading state updates.

The useEffect should focus only on data and error handling, not loading state management since Apollo Client handles this automatically.

  useEffect(() => {
    if (data) {
      setMetrics(data.projectHealthMetrics)
-     setIsLoading(false)
    }
    if (graphQLRequestError) {
      handleAppError(graphQLRequestError)
-     setIsLoading(false)
    }
  }, [data, graphQLRequestError])

40-42: Use Apollo Client's loading state instead of manual state.

Replace the manual isLoading state with Apollo Client's loading state for consistency and to eliminate redundancy.

- if (isLoading) {
+ if (loading) {
    return <LoadingSpinner />
  }

20-29: Missing loading state from useQuery destructuring.

The loading state should be destructured from useQuery to replace the manual loading state management.

  const {
    data,
+   loading,
    error: graphQLRequestError,
    refetch,
  } = useQuery(GET_PROJECT_HEALTH_METRICS_LIST, {
    variables: {
      filters,
      pagination: { offset: 0, limit: PAGINATION_LIMIT },
    },
  })
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 234fb58 and a237c4e.

📒 Files selected for processing (1)
  • frontend/src/app/projects/dashboard/metrics/page.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/app/projects/dashboard/metrics/page.tsx (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run frontend checks
  • GitHub Check: Run pre-commit checks
  • GitHub Check: CodeQL (javascript-typescript)
  • GitHub Check: CodeQL (python)

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

♻️ Duplicate comments (1)
frontend/src/types/healthMetrics.ts (1)

49-49: CSpell false positive for standard GraphQL term.

The lte (less than or equal) term is a standard GraphQL comparison operator and should be added to the CSpell dictionary to prevent false positives.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a237c4e and f92117d.

📒 Files selected for processing (6)
  • backend/apps/owasp/graphql/ordering/project_health_metrics.py (1 hunks)
  • backend/apps/owasp/graphql/queries/project_health_metrics.py (1 hunks)
  • backend/tests/apps/owasp/graphql/ordering/project_health_metrics_test.py (1 hunks)
  • frontend/src/app/projects/dashboard/metrics/page.tsx (1 hunks)
  • frontend/src/server/queries/projectsHealthDashboardQueries.ts (1 hunks)
  • frontend/src/types/healthMetrics.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/app/projects/dashboard/metrics/page.tsx (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/server/queries/projectsHealthDashboardQueries.ts (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/types/healthMetrics.ts (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
backend/apps/owasp/graphql/queries/project_health_metrics.py (1)
Learnt from: ahmedxgouda
PR: OWASP/Nest#1676
File: backend/apps/owasp/graphql/filters/project_health_metrics.py:17-22
Timestamp: 2025-06-29T00:41:32.198Z
Learning: In the OWASP Nest codebase, when implementing GraphQL filters that convert string values to enums (like ProjectLevel), do not catch ValueError exceptions for invalid values. Let the errors propagate to provide proper error responses to GraphQL clients rather than silently ignoring invalid input.
🧬 Code Graph Analysis (2)
backend/tests/apps/owasp/graphql/ordering/project_health_metrics_test.py (3)
backend/apps/owasp/graphql/queries/project_health_metrics.py (1)
  • project_health_metrics (23-40)
backend/apps/owasp/graphql/ordering/project_health_metrics.py (1)
  • ProjectHealthMetricsOrder (10-16)
backend/apps/owasp/graphql/nodes/committee.py (3)
  • forks_count (25-27)
  • stars_count (40-42)
  • contributors_count (15-17)
backend/apps/owasp/graphql/queries/project_health_metrics.py (3)
backend/apps/owasp/graphql/ordering/project_health_metrics.py (1)
  • ProjectHealthMetricsOrder (10-16)
backend/apps/owasp/models/project_health_metrics.py (2)
  • ProjectHealthMetrics (16-210)
  • get_latest_health_metrics (145-158)
backend/apps/owasp/graphql/filters/project_health_metrics.py (1)
  • ProjectHealthMetricsFilter (12-22)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: CodeQL (python)
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (9)
backend/tests/apps/owasp/graphql/ordering/project_health_metrics_test.py (1)

1-30: LGTM! Comprehensive test coverage for ordering functionality.

The test suite effectively validates the ProjectHealthMetricsOrder class with good coverage of:

  • Strawberry GraphQL definition verification
  • Field validation against expected ordering options
  • Instance creation with different ordering directions

The tests follow pytest best practices and provide confidence in the ordering implementation.

backend/apps/owasp/graphql/ordering/project_health_metrics.py (1)

1-17: LGTM! Clean ordering implementation following framework conventions.

The ordering class correctly:

  • Uses the @order_type decorator for automatic GraphQL type generation
  • Defines the expected fields for project health metrics ordering
  • Leverages auto type inference for proper GraphQL scalar types

This implementation aligns well with the test coverage and GraphQL query requirements.

frontend/src/server/queries/projectsHealthDashboardQueries.ts (1)

1-37: LGTM! Well-structured GraphQL queries supporting dashboard functionality.

The queries are properly implemented with:

  • Correct GraphQL syntax and variable definitions
  • Comprehensive field selection for both stats and metrics list
  • Proper support for filtering, pagination, and ordering parameters
  • Alignment with backend schema and frontend requirements

These queries effectively bridge the frontend dashboard components with the backend GraphQL API.

frontend/src/types/healthMetrics.ts (2)

26-42: LGTM! Enhanced type definitions support new dashboard features.

The additions to HealthMetricsProps correctly include the new fields (id, contributorsCount, projectName) that align with the backend GraphQL schema and dashboard requirements.


44-67: LGTM! Well-designed filter and ordering types.

The new HealthMetricsFilter and HealthMetricsOrdering types provide:

  • Comprehensive score filtering with standard comparison operators (gt, gte, lt, lte)
  • Level-based filtering support
  • Structured ordering options for all relevant metrics fields

These types effectively support the dashboard's filtering and sorting functionality.

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

17-47: LGTM! Well-structured component with proper state management.

The component correctly:

  • Uses Apollo Client's useQuery hook for data fetching
  • Implements proper error handling with handleAppError
  • Manages loading states appropriately
  • Uses a configurable pagination limit constant

The overall architecture is solid for a dashboard metrics page.


116-132: LGTM! Well-implemented grid layout with proper empty state handling.

The component correctly:

  • Uses a responsive grid layout for the metrics display
  • Provides clear column headers
  • Handles empty states with user-friendly messaging
  • Maps through metrics with proper key handling

The UI implementation is clean and user-friendly.

backend/apps/owasp/graphql/queries/project_health_metrics.py (2)

9-9: LGTM - Import addition aligns with new functionality.

The import for ProjectHealthMetricsOrder is correctly added to support the new ordering capabilities.


17-28: LGTM - Well-structured resolver method signature.

The decorator and method signature are properly implemented:

  • Correct use of @strawberry_django.field decorator with all necessary parameters
  • Proper parameter types and optional ordering
  • Good documentation format

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 4

♻️ Duplicate comments (2)
frontend/src/app/projects/dashboard/metrics/page.tsx (2)

30-30: Manual loading state management is still redundant.

This duplicates a previous review comment that hasn't been addressed. Apollo Client's useQuery already provides a loading state, making the manual isLoading state and useEffect unnecessary.

Apply this diff to use Apollo's loading state:

- const [isLoading, setIsLoading] = useState<boolean>(true)
  const {
    data,
+   loading,
    error: graphQLRequestError,
    refetch,
  } = useQuery(GET_PROJECT_HEALTH_METRICS_LIST, {
    variables: {
      filters,
      pagination: { offset: 0, limit: PAGINATION_LIMIT },
      ordering: Object.values(ordering),
    },
  })
  useEffect(() => {
    if (data) {
      setMetrics(data.projectHealthMetrics)
-     setIsLoading(false)
    }
    if (graphQLRequestError) {
      handleAppError(graphQLRequestError)
-     setIsLoading(false)
    }
  }, [data, graphQLRequestError])
- if (isLoading) {
+ if (loading) {
    return <LoadingSpinner />
  }

Also applies to: 42-54


103-115: Complex ordering logic still needs simplification.

This duplicates a previous review comment that hasn't been addressed. The dynamic property construction using string interpolation and bracket notation reduces type safety and maintainability.

Apply this diff to improve type safety:

onPress={() => {
  const [key, order] = option.key.split('_')
- const newOrdering: HealthMetricsOrdering = {
-   ...ordering,
- }
- newOrdering[`${key}Ordering`] = { [key]: order }
+ const orderingMap: Record<string, keyof HealthMetricsOrdering> = {
+   score: 'scoreOrdering',
+   starsCount: 'starsCountOrdering',
+   forksCount: 'forksCountOrdering',
+   contributorsCount: 'contributorsCountOrdering',
+ }
+ const newOrdering: HealthMetricsOrdering = {
+   ...ordering,
+   [orderingMap[key]]: { [key]: order as 'ASC' | 'DESC' }
+ }
  setOrdering(newOrdering)
  refetch({
    filters,
    pagination: { offset: 0, limit: PAGINATION_LIMIT },
    ordering: Object.values(newOrdering),
  })
}}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f92117d and 56a0e9d.

📒 Files selected for processing (1)
  • frontend/src/app/projects/dashboard/metrics/page.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/app/projects/dashboard/metrics/page.tsx (4)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1714
File: frontend/src/components/ProjectTypeDashboardCard.tsx:8-12
Timestamp: 2025-07-08T17:07:50.957Z
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.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: Run backend tests
  • GitHub Check: Run frontend unit tests
  • GitHub Check: CodeQL (javascript-typescript)

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 539f29b and df980df.

📒 Files selected for processing (6)
  • backend/apps/owasp/graphql/queries/project_health_metrics.py (2 hunks)
  • backend/tests/apps/owasp/graphql/queries/project_health_metrics_test.py (2 hunks)
  • frontend/src/app/projects/dashboard/metrics/page.tsx (1 hunks)
  • frontend/src/components/ProjectsDashboardDropDown.tsx (1 hunks)
  • frontend/src/server/queries/projectsHealthDashboardQueries.ts (1 hunks)
  • frontend/src/types/DropDownSectionProps.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/app/projects/dashboard/metrics/page.tsx (5)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1718
File: frontend/src/app/projects/dashboard/metrics/page.tsx:96-96
Timestamp: 2025-07-09T08:37:10.232Z
Learning: In the OWASP Nest project's MetricsPage component (frontend/src/app/projects/dashboard/metrics/page.tsx), the sorting dropdown intentionally uses selectionMode="multiple" to allow users to select multiple sorting criteria simultaneously. This enables complex sorting scenarios where users can sort by multiple fields in sequence.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1714
File: frontend/src/components/ProjectTypeDashboardCard.tsx:8-12
Timestamp: 2025-07-08T17:07:50.957Z
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.
backend/apps/owasp/graphql/queries/project_health_metrics.py (3)
Learnt from: ahmedxgouda
PR: OWASP/Nest#1718
File: backend/apps/owasp/graphql/queries/project_health_metrics.py:0-0
Timestamp: 2025-07-09T08:41:58.105Z
Learning: In strawberry_django, when using @strawberry_django.field decorator with filters, pagination, and ordering parameters, the framework automatically applies these to the QuerySet returned by the resolver method. Manual application using strawberry_django.filters.apply() is only needed for custom implementations, not when using the standard decorator approach.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1676
File: backend/apps/owasp/graphql/filters/project_health_metrics.py:17-22
Timestamp: 2025-06-29T00:41:32.198Z
Learning: In the OWASP Nest codebase, when implementing GraphQL filters that convert string values to enums (like ProjectLevel), do not catch ValueError exceptions for invalid values. Let the errors propagate to provide proper error responses to GraphQL clients rather than silently ignoring invalid input.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1675
File: backend/apps/owasp/graphql/queries/project_health_metrics.py:13-21
Timestamp: 2025-07-03T03:47:05.436Z
Learning: The OWASP Nest project does not use async operations anywhere in the codebase and doesn't have the required database driver for async operations. All database methods and GraphQL resolvers should remain synchronous to maintain consistency with the existing architecture.
frontend/src/server/queries/projectsHealthDashboardQueries.ts (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/components/ProjectsDashboardDropDown.tsx (1)
Learnt from: ahmedxgouda
PR: OWASP/Nest#1718
File: frontend/src/app/projects/dashboard/metrics/page.tsx:96-96
Timestamp: 2025-07-09T08:37:10.232Z
Learning: In the OWASP Nest project's MetricsPage component (frontend/src/app/projects/dashboard/metrics/page.tsx), the sorting dropdown intentionally uses selectionMode="multiple" to allow users to select multiple sorting criteria simultaneously. This enables complex sorting scenarios where users can sort by multiple fields in sequence.
🧬 Code Graph Analysis (3)
frontend/src/app/projects/dashboard/metrics/page.tsx (4)
frontend/src/types/healthMetrics.ts (3)
  • HealthMetricsProps (26-42)
  • HealthMetricsFilter (44-52)
  • HealthMetricsOrdering (54-67)
frontend/src/server/queries/projectsHealthDashboardQueries.ts (1)
  • GET_PROJECT_HEALTH_METRICS_LIST (20-37)
frontend/src/app/global-error.tsx (1)
  • handleAppError (66-86)
frontend/src/types/DropDownSectionProps.ts (1)
  • DropDownSectionProps (1-7)
frontend/src/components/ProjectsDashboardDropDown.tsx (1)
frontend/src/types/DropDownSectionProps.ts (1)
  • DropDownSectionProps (1-7)
backend/tests/apps/owasp/graphql/queries/project_health_metrics_test.py (2)
backend/apps/owasp/graphql/queries/project_health_metrics.py (4)
  • ProjectHealthMetricsQuery (14-60)
  • project_health_stats (43-50)
  • project_health_metrics (23-40)
  • project_health_metrics_distinct_length (53-60)
backend/apps/owasp/graphql/nodes/project_health_metrics.py (1)
  • ProjectHealthMetricsNode (29-75)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: Run frontend unit tests
  • GitHub Check: Run backend tests
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (14)
frontend/src/types/DropDownSectionProps.ts (1)

1-7: LGTM!

The type definition is well-structured and provides a clear interface for dropdown sections.

frontend/src/server/queries/projectsHealthDashboardQueries.ts (1)

1-37: Well-structured GraphQL queries!

The queries are properly defined with appropriate parameters and field selections that align with the backend schema changes.

backend/tests/apps/owasp/graphql/queries/project_health_metrics_test.py (3)

66-66: Test updates align well with the refactored query structure.

The removal of the empty list parameter correctly reflects the new query implementation.


71-99: Comprehensive test coverage for the enhanced resolver.

The test properly validates the new method signature with filters, pagination, and ordering parameters.


100-109: Good addition of distinct length test.

The test correctly verifies the new project_health_metrics_distinct_length resolver functionality.

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

14-41: Well-designed reusable dropdown component!

The component is properly structured with clear props interface and clean implementation. Good use of the @heroui/react library components.

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

1-37: Good setup with proper state management and Apollo Client usage.

Excellent use of a constant for pagination limit and proper destructuring of Apollo Client's query results including the loading state.


39-47: Proper data synchronization and error handling.

Good use of useEffect to sync Apollo query results with local state and appropriate error handling.


49-132: Well-organized configuration for dropdowns.

Good separation of dropdown sections and filter mappings. The inclusion of a reset option is a nice UX touch.


220-232: Excellent UI state handling.

Great implementation with proper loading state, empty state message, and data rendering. This addresses the UX concerns from previous reviews.


233-261: Well-implemented pagination with proper cache updates.

The pagination component correctly handles page changes and updates the Apollo cache appropriately through the updateQuery callback.

backend/apps/owasp/graphql/queries/project_health_metrics.py (3)

9-9: LGTM: Proper import for ordering support.

The import of ProjectHealthMetricsOrder is correctly added to support the new ordering functionality.


17-40: LGTM: Excellent refactor with proper pagination and ordering support.

The refactor from a simple field declaration to a method resolver with @strawberry_django.field decorator is well-implemented. The decorator correctly specifies pagination=True and ordering=ProjectHealthMetricsOrder, and the method signature includes all necessary parameters. Based on the strawberry_django framework behavior, the filters, pagination, and ordering will be automatically applied to the QuerySet returned by ProjectHealthMetrics.get_latest_health_metrics().

The docstring is comprehensive and follows good documentation practices.


52-60: LGTM: Clean implementation of distinct count field.

The new field provides a straightforward way to get the count of distinct project health metrics by calling .count() on the result of get_latest_health_metrics(). The implementation is clean and the docstring is well-written.

@arkid15r
arkid15r requested a review from aramattamara July 11, 2025 00:25

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between df980df and f2e4dfa.

📒 Files selected for processing (1)
  • frontend/src/app/projects/dashboard/metrics/page.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/app/projects/dashboard/metrics/page.tsx (4)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1718
File: frontend/src/app/projects/dashboard/metrics/page.tsx:96-96
Timestamp: 2025-07-09T08:37:10.241Z
Learning: In the OWASP Nest project's MetricsPage component (frontend/src/app/projects/dashboard/metrics/page.tsx), the sorting dropdown intentionally uses selectionMode="multiple" to allow users to select multiple sorting criteria simultaneously. This enables complex sorting scenarios where users can sort by multiple fields in sequence.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
🧬 Code Graph Analysis (1)
frontend/src/app/projects/dashboard/metrics/page.tsx (4)
frontend/src/types/healthMetrics.ts (3)
  • HealthMetricsProps (26-42)
  • HealthMetricsFilter (44-52)
  • HealthMetricsOrdering (54-67)
frontend/src/server/queries/projectsHealthDashboardQueries.ts (1)
  • GET_PROJECT_HEALTH_METRICS_LIST (20-37)
frontend/src/app/global-error.tsx (1)
  • handleAppError (66-86)
frontend/src/types/DropDownSectionProps.ts (1)
  • DropDownSectionProps (1-7)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run Code Scan
  • GitHub Check: Run CI Denendencies Scan
  • GitHub Check: CodeQL (python)
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (8)
frontend/src/app/projects/dashboard/metrics/page.tsx (8)

1-16: LGTM! Clean imports and setup.

The imports are well-organized and the PAGINATION_LIMIT constant extraction follows the feedback from previous reviews.


17-39: Good state management and Apollo integration.

The state management is comprehensive and the Apollo useQuery hook is properly configured with all necessary variables.


41-49: Proper data handling and error management.

The useEffect properly handles both successful data responses and GraphQL errors using the global error handler.


51-103: Well-structured dropdown configuration.

The sections are logically organized and provide a good user experience with clear categorization of filters and sorting options.


162-164: Simple and effective pagination helper.

The getCurrentPage calculation is straightforward and correctly handles the offset-to-page conversion.


166-211: Excellent header implementation with proper dropdown integration.

The header layout with filtering and sorting dropdowns is well-implemented, properly handling state updates and refetching data when selections change.


212-232: Good grid layout and empty state handling.

The grid headers provide clear context and the empty state message improves user experience when no metrics match the current filters.


233-264: Robust pagination implementation.

The pagination component properly handles page changes using fetchMore and maintains filters/ordering state correctly across page transitions.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f2e4dfa and 8e0c025.

📒 Files selected for processing (1)
  • frontend/src/app/projects/dashboard/metrics/page.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/app/projects/dashboard/metrics/page.tsx (4)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1718
File: frontend/src/app/projects/dashboard/metrics/page.tsx:96-96
Timestamp: 2025-07-09T08:37:10.241Z
Learning: In the OWASP Nest project's MetricsPage component (frontend/src/app/projects/dashboard/metrics/page.tsx), the sorting dropdown intentionally uses selectionMode="multiple" to allow users to select multiple sorting criteria simultaneously. This enables complex sorting scenarios where users can sort by multiple fields in sequence.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
🧬 Code Graph Analysis (1)
frontend/src/app/projects/dashboard/metrics/page.tsx (4)
frontend/src/types/healthMetrics.ts (3)
  • HealthMetricsProps (26-42)
  • HealthMetricsFilter (44-52)
  • HealthMetricsOrdering (54-67)
frontend/src/server/queries/projectsHealthDashboardQueries.ts (1)
  • GET_PROJECT_HEALTH_METRICS_LIST (20-37)
frontend/src/app/global-error.tsx (1)
  • handleAppError (66-86)
frontend/src/types/DropDownSectionProps.ts (1)
  • DropDownSectionProps (1-7)
🪛 Biome (1.9.4)
frontend/src/app/projects/dashboard/metrics/page.tsx

[error] 167-167: expected , but instead found const

Remove const

(parse)


[error] 167-167: expected : but instead found getCurrentPage

Remove getCurrentPage

(parse)


[error] 171-171: expected , but instead found return

Remove return

(parse)


[error] 172-172: Expected a parameter but instead found '<'.

Expected a parameter here.

(parse)


[error] 172-172: Expected a type parameter but instead found '>'.

Expected a type parameter here.

(parse)


[error] 173-173: Expected a parenthesis '(' but instead found '<'.

Expected a parenthesis '(' here.

(parse)


[error] 173-173: expected , but instead found className

Remove className

(parse)


[error] 174-174: Expected a parenthesis '(' but instead found '<'.

Expected a parenthesis '(' here.

(parse)


[error] 174-174: expected , but instead found className

Remove className

(parse)


[error] 174-174: Expected a parenthesis '(' but instead found 'Project'.

Expected a parenthesis '(' here.

(parse)


[error] 174-174: expected , but instead found Health

Remove Health

(parse)


[error] 174-174: expected , but instead found Metrics

Remove Metrics

(parse)


[error] 174-174: Expected a type parameter but instead found '/'.

Expected a type parameter here.

(parse)


[error] 174-174: expected , but instead found h1

Remove h1

(parse)


[error] 175-175: Expected a parenthesis '(' but instead found '<'.

Expected a parenthesis '(' here.

(parse)


[error] 175-175: expected , but instead found className

Remove className

(parse)


[error] 176-176: Expected a parenthesis '(' but instead found '<'.

Expected a parenthesis '(' here.

(parse)


[error] 177-177: expected , but instead found buttonDisplayName

Remove buttonDisplayName

(parse)


[error] 178-178: expected , but instead found icon

Remove icon

(parse)


[error] 179-179: expected , but instead found sections

Remove sections

(parse)


[error] 180-180: expected , but instead found selectionMode

Remove selectionMode

(parse)


[error] 181-181: expected , but instead found selectedKeys

Remove selectedKeys

(parse)


[error] 182-182: expected , but instead found onAction

Remove onAction

(parse)


[error] 182-182: ';' expected'

An explicit or implicit semicolon is expected here...

(parse)


[error] 184-184: ';' expected'

An explicit or implicit semicolon is expected here...

(parse)


[error] 184-184: ';' expected'

An explicit or implicit semicolon is expected here...

(parse)


[error] 184-184: Expected a property, or a signature but instead found ','.

Expected a property, or a signature here.

(parse)


[error] 184-184: expected , but instead found :

Remove :

(parse)


[error] 184-184: expected , but instead found PAGINATION_LIMIT

Remove PAGINATION_LIMIT

(parse)


[error] 184-184: expected , but instead found }

Remove }

(parse)


[error] 185-185: expected , but instead found setPagination

Remove setPagination

(parse)


[error] 185-185: expected , but instead found (

Remove (

(parse)


[error] 185-185: expected , but instead found newPagination

Remove newPagination

(parse)


[error] 185-185: expected , but instead found )

Remove )

(parse)


[error] 186-186: expected , but instead found setFilters

Remove setFilters

(parse)


[error] 186-186: expected , but instead found (

Remove (

(parse)


[error] 186-186: expected , but instead found filtersMapping

Remove filtersMapping

(parse)


[error] 186-186: expected , but instead found [

Remove [

(parse)


[error] 186-186: expected , but instead found key

Remove key

(parse)


[error] 186-186: expected , but instead found ]

Remove ]

(parse)


[error] 187-187: expected , but instead found setActiveFilterKey

Remove setActiveFilterKey

(parse)


[error] 187-187: expected , but instead found (

Remove (

(parse)


[error] 187-187: expected , but instead found key

Remove key

(parse)


[error] 187-187: expected , but instead found )

Remove )

(parse)


[error] 188-188: expected , but instead found await

Remove await

(parse)


[error] 188-188: expected , but instead found refetch

Remove refetch

(parse)


[error] 188-188: expected , but instead found (

Remove (

(parse)


[error] 189-189: expected , but instead found filters

Remove filters

(parse)


[error] 189-189: expected , but instead found :

Remove :

(parse)


[error] 189-189: expected , but instead found filtersMapping

Remove filtersMapping

(parse)


[error] 189-189: expected , but instead found [

Remove [

(parse)


[error] 189-189: expected , but instead found key

Remove key

(parse)


[error] 189-189: expected , but instead found ]

Remove ]

(parse)


[error] 190-190: expected , but instead found :

Remove :

(parse)


[error] 190-190: expected , but instead found newPagination

Remove newPagination

(parse)


[error] 191-191: expected , but instead found :

Remove :

(parse)


[error] 191-191: expected , but instead found Object

Remove Object

(parse)


[error] 191-191: expected , but instead found .

Remove .

(parse)


[error] 191-191: expected , but instead found values

Remove values

(parse)


[error] 191-191: expected , but instead found (

Remove (

(parse)


[error] 191-191: expected , but instead found ordering

Remove ordering

(parse)


[error] 191-191: expected , but instead found )

Remove )

(parse)


[error] 192-192: Expected a type parameter but instead found '}'.

Expected a type parameter here.

(parse)


[error] 192-192: Expected a semicolon or an implicit semicolon after a statement, but found none

An explicit or implicit semicolon is expected here...

...Which is required to end this statement

(parse)


[error] 193-198: Expected a statement but instead found '}
/>

      <ProjectsDashboardDropDown
        buttonDisplayName="Sort By"
        icon='.

Expected a statement here.

(parse)


[error] 201-201: expected : but instead found }

Remove }

(parse)


[error] 202-202: Expected a function body but instead found '=>'.

Expected a function body here.

(parse)


[error] 204-204: expected , but instead found const

Remove const

(parse)


[error] 204-204: expected : but instead found newPagination

Remove newPagination

(parse)


[error] 205-205: expected , but instead found setPagination

Remove setPagination

(parse)


[error] 206-206: Expected a function body but instead found 'setOrdering'.

Expected a function body here.

(parse)


[error] 206-206: expected , but instead found [

Remove [

(parse)


[error] 207-207: Expected a function body but instead found 'setActiveOrderingKey'.

Expected a function body here.

(parse)


[error] 208-208: Expected a function body but instead found 'await'.

Expected a function body here.

(parse)


[error] 208-208: expected , but instead found refetch

Remove refetch

(parse)


[error] 211-211: expected , but instead found .

Remove .

(parse)


[error] 211-211: expected , but instead found )

Remove )

(parse)


[error] 211-211: Expected a function body but instead found ','.

Expected a function body here.

(parse)


[error] 212-212: Expected a semicolon or an implicit semicolon after a statement, but found none

An explicit or implicit semicolon is expected here...

...Which is required to end this statement

(parse)


[error] 267-267: Expected an expression but instead found '<'.

Expected an expression here.

(parse)


[error] 211-211: Do not shadow the global "Object" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


[error] 187-187: Shouldn't redeclare 'key'. Consider to delete it or rename it.

'key' is defined here:

(lint/suspicious/noRedeclare)


[error] 189-189: Shouldn't redeclare 'key'. Consider to delete it or rename it.

'key' is defined here:

(lint/suspicious/noRedeclare)


[error] 190-190: Shouldn't redeclare 'newPagination'. Consider to delete it or rename it.

'newPagination' is defined here:

(lint/suspicious/noRedeclare)


[error] 198-198: This block statement doesn't serve any purpose and can be safely removed.

Standalone block statements without any block-level declarations are redundant in JavaScript and can be removed to simplify the code.

(lint/complexity/noUselessLoneBlockStatements)


[error] 225-237: This block statement doesn't serve any purpose and can be safely removed.

Standalone block statements without any block-level declarations are redundant in JavaScript and can be removed to simplify the code.

(lint/complexity/noUselessLoneBlockStatements)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run pre-commit checks
  • GitHub Check: Run frontend checks
  • GitHub Check: CodeQL (javascript-typescript)
  • GitHub Check: CodeQL (python)

@ahmedxgouda
ahmedxgouda force-pushed the dashboard/metrics-list-frontend branch from 8e0c025 to a15b0b0 Compare July 11, 2025 23:49

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e0c025 and a15b0b0.

📒 Files selected for processing (1)
  • frontend/src/app/projects/dashboard/metrics/page.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
frontend/src/app/projects/dashboard/metrics/page.tsx (4)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1718
File: frontend/src/app/projects/dashboard/metrics/page.tsx:96-96
Timestamp: 2025-07-09T08:37:10.241Z
Learning: In the OWASP Nest project's MetricsPage component (frontend/src/app/projects/dashboard/metrics/page.tsx), the sorting dropdown intentionally uses selectionMode="multiple" to allow users to select multiple sorting criteria simultaneously. This enables complex sorting scenarios where users can sort by multiple fields in sequence.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
🧬 Code Graph Analysis (1)
frontend/src/app/projects/dashboard/metrics/page.tsx (4)
frontend/src/types/healthMetrics.ts (3)
  • HealthMetricsProps (26-42)
  • HealthMetricsFilter (44-52)
  • HealthMetricsOrdering (54-67)
frontend/src/server/queries/projectsHealthDashboardQueries.ts (1)
  • GET_PROJECT_HEALTH_METRICS_LIST (20-37)
frontend/src/app/global-error.tsx (1)
  • handleAppError (66-86)
frontend/src/types/DropDownSectionProps.ts (1)
  • DropDownSectionProps (1-7)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run CI Denendencies Scan
  • GitHub Check: Run Code Scan
  • GitHub Check: CodeQL (python)
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (1)
frontend/src/app/projects/dashboard/metrics/page.tsx (1)

1-266: Excellent implementation of the metrics dashboard with comprehensive filtering and sorting!

The component is well-structured and follows React best practices. I can see that most issues from previous reviews have been addressed:

✅ Pagination limit is now properly extracted to a constant
✅ Apollo Client's loading state is used instead of manual state management
✅ Race conditions in filter handling have been resolved
✅ Empty state handling is implemented
✅ Visual indication of active filters and sorting is working
✅ Ordering property keys have been corrected

The current implementation provides a robust dashboard with:

  • Proper state management for metrics, filters, pagination, and ordering
  • Clean separation of configuration objects for dropdowns
  • Appropriate error handling using the global error handler
  • Efficient pagination using Apollo's fetchMore
  • Good user experience with loading states and empty state messages

The code is production-ready and handles all the key requirements for the metrics dashboard feature.

Comment on lines +104 to +160
const filtersMapping = {
incubator: {
level: 'incubator',
},
lab: {
level: 'lab',
},
production: {
level: 'production',
},
flagship: {
level: 'flagship',
},
healthy: {
score: {
gte: 75,
},
},
warning: {
score: {
gte: 50,
lt: 75,
},
},
critical: {
score: {
lt: 50,
},
},
reset: {},
}
const orderingMapping = {
scoreDESC: {
scoreOrdering: { score: 'DESC' },
},
scoreASC: {
scoreOrdering: { score: 'ASC' },
},
starsCountDESC: {
starsCountOrdering: { starsCount: 'DESC' },
},
starsCountASC: {
starsCountOrdering: { starsCount: 'ASC' },
},
forksCountDESC: {
forksCountOrdering: { forksCount: 'DESC' },
},
forksCountASC: {
forksCountOrdering: { forksCount: 'ASC' },
},
contributorsCountDESC: {
contributorsCountOrdering: { contributorsCount: 'DESC' },
},
contributorsCountASC: {
contributorsCountOrdering: { contributorsCount: 'ASC' },
},
}

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.

🧹 Nitpick (assertive)

Consider improving type safety for mapping objects.

While the current implementation works correctly, the filtersMapping and orderingMapping objects use string indexing which could be enhanced with proper TypeScript typing for better type safety and IDE support.

You could define types for the mapping keys:

type FilterKey = 'incubator' | 'lab' | 'production' | 'flagship' | 'healthy' | 'warning' | 'critical' | 'reset'
type OrderingKey = 'scoreDESC' | 'scoreASC' | 'starsCountDESC' | 'starsCountASC' | 'forksCountDESC' | 'forksCountASC' | 'contributorsCountDESC' | 'contributorsCountASC'

const filtersMapping: Record<FilterKey, HealthMetricsFilter> = {
  // ... existing mapping
}

const orderingMapping: Record<OrderingKey, HealthMetricsOrdering> = {
  // ... existing mapping  
}
🤖 Prompt for AI Agents
In frontend/src/app/projects/dashboard/metrics/page.tsx around lines 104 to 160,
the filtersMapping and orderingMapping objects currently use untyped string keys
which reduces type safety and IDE support. Define explicit TypeScript union
types for the keys of each mapping (e.g., FilterKey and OrderingKey) and then
type the mapping objects using Record with these key types and the appropriate
value types (HealthMetricsFilter and HealthMetricsOrdering). This will enforce
valid keys and improve code maintainability and autocompletion.

@ahmedxgouda

ahmedxgouda commented Jul 21, 2025 •

Copy link
Copy Markdown
Collaborator Author

I was resolving conflicts, of course I would not dismiss your approval :) @kasya

@arkid15r

Copy link
Copy Markdown
Collaborator

I was resolving conflicts, of course I would not dismiss your approval :) @kasya

It seems you overthink it a bit, the workflow is fine and all understand whats and whys, don't sweat it @ahmedxgouda it's all good 👍

@coderabbitai coderabbitai Bot mentioned this pull request Jul 21, 2025
2 tasks

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
backend/tests/apps/owasp/api/internal/ordering/project_health_metrics_test.py (1)

21-26: Consider testing both ASC and DESC ordering options.

The current test only validates DESC ordering. Consider adding a parameterized test or additional test case to verify ASC ordering as well to ensure complete coverage of the ordering functionality.

-    def test_order_by(self):
-        """Test ordering by score."""
-        order_instance = ProjectHealthMetricsOrder(
-            score="DESC",
-        )
-        assert order_instance.score == "DESC"
+    @pytest.mark.parametrize("order_direction", ["ASC", "DESC"])
+    def test_order_by(self, order_direction):
+        """Test ordering by score in both directions."""
+        order_instance = ProjectHealthMetricsOrder(
+            score=order_direction,
+        )
+        assert order_instance.score == order_direction
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 477ec5b and b87c634.

📒 Files selected for processing (6)
  • backend/apps/owasp/api/internal/nodes/project_health_metrics.py (2 hunks)
  • backend/apps/owasp/api/internal/ordering/project_health_metrics.py (1 hunks)
  • backend/apps/owasp/api/internal/queries/project_health_metrics.py (2 hunks)
  • backend/tests/apps/owasp/api/internal/nodes/project_health_metrics_test.py (2 hunks)
  • backend/tests/apps/owasp/api/internal/ordering/project_health_metrics_test.py (1 hunks)
  • backend/tests/apps/owasp/api/internal/queries/project_health_metrics_test.py (2 hunks)
🧠 Learnings (2)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1718
File: frontend/src/app/projects/dashboard/metrics/page.tsx:96-96
Timestamp: 2025-07-09T08:37:10.241Z
Learning: In the OWASP Nest project's MetricsPage component (frontend/src/app/projects/dashboard/metrics/page.tsx), the sorting dropdown intentionally uses selectionMode="multiple" to allow users to select multiple sorting criteria simultaneously. This enables complex sorting scenarios where users can sort by multiple fields in sequence.
backend/apps/owasp/api/internal/nodes/project_health_metrics.py (3)

Learnt from: Rajgupta36
PR: #1717
File: backend/apps/mentorship/graphql/queries/module.py:39-50
Timestamp: 2025-07-11T15:57:56.648Z
Learning: In the OWASP Nest mentorship GraphQL queries, Strawberry GraphQL automatically converts between Django Module instances and ModuleNode types, so methods can return Module instances directly without manual conversion even when typed as ModuleNode.

Learnt from: Rajgupta36
PR: #1717
File: backend/apps/mentorship/graphql/mutations/program.py:166-166
Timestamp: 2025-07-13T05:55:46.436Z
Learning: In the OWASP Nest mentorship GraphQL mutations, Strawberry GraphQL automatically converts between Django Program instances and ProgramNode types, so mutations can return Program instances directly without manual conversion even when typed as ProgramNode, similar to the Module/ModuleNode pattern.

Learnt from: ahmedxgouda
PR: #1676
File: backend/apps/owasp/graphql/filters/project_health_metrics.py:17-22
Timestamp: 2025-06-29T00:41:32.198Z
Learning: In the OWASP Nest codebase, when implementing GraphQL filters that convert string values to enums (like ProjectLevel), do not catch ValueError exceptions for invalid values. Let the errors propagate to provide proper error responses to GraphQL clients rather than silently ignoring invalid input.

🧬 Code Graph Analysis (2)
backend/tests/apps/owasp/api/internal/queries/project_health_metrics_test.py (2)
backend/apps/owasp/api/internal/queries/project_health_metrics.py (4)
  • ProjectHealthMetricsQuery (14-70)
  • project_health_stats (43-50)
  • project_health_metrics (23-40)
  • project_health_metrics_distinct_length (53-70)
backend/apps/owasp/api/internal/nodes/project_health_metrics.py (1)
  • ProjectHealthMetricsNode (31-97)
backend/tests/apps/owasp/api/internal/ordering/project_health_metrics_test.py (1)
backend/apps/owasp/api/internal/queries/project_health_metrics.py (1)
  • project_health_metrics (23-40)
✅ Files skipped from review due to trivial changes (1)
  • backend/apps/owasp/api/internal/ordering/project_health_metrics.py
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1718
File: frontend/src/app/projects/dashboard/metrics/page.tsx:96-96
Timestamp: 2025-07-09T08:37:10.241Z
Learning: In the OWASP Nest project's MetricsPage component (frontend/src/app/projects/dashboard/metrics/page.tsx), the sorting dropdown intentionally uses selectionMode="multiple" to allow users to select multiple sorting criteria simultaneously. This enables complex sorting scenarios where users can sort by multiple fields in sequence.
backend/apps/owasp/api/internal/nodes/project_health_metrics.py (3)

Learnt from: Rajgupta36
PR: #1717
File: backend/apps/mentorship/graphql/queries/module.py:39-50
Timestamp: 2025-07-11T15:57:56.648Z
Learning: In the OWASP Nest mentorship GraphQL queries, Strawberry GraphQL automatically converts between Django Module instances and ModuleNode types, so methods can return Module instances directly without manual conversion even when typed as ModuleNode.

Learnt from: Rajgupta36
PR: #1717
File: backend/apps/mentorship/graphql/mutations/program.py:166-166
Timestamp: 2025-07-13T05:55:46.436Z
Learning: In the OWASP Nest mentorship GraphQL mutations, Strawberry GraphQL automatically converts between Django Program instances and ProgramNode types, so mutations can return Program instances directly without manual conversion even when typed as ProgramNode, similar to the Module/ModuleNode pattern.

Learnt from: ahmedxgouda
PR: #1676
File: backend/apps/owasp/graphql/filters/project_health_metrics.py:17-22
Timestamp: 2025-06-29T00:41:32.198Z
Learning: In the OWASP Nest codebase, when implementing GraphQL filters that convert string values to enums (like ProjectLevel), do not catch ValueError exceptions for invalid values. Let the errors propagate to provide proper error responses to GraphQL clients rather than silently ignoring invalid input.

🧬 Code Graph Analysis (2)
backend/tests/apps/owasp/api/internal/queries/project_health_metrics_test.py (2)
backend/apps/owasp/api/internal/queries/project_health_metrics.py (4)
  • ProjectHealthMetricsQuery (14-70)
  • project_health_stats (43-50)
  • project_health_metrics (23-40)
  • project_health_metrics_distinct_length (53-70)
backend/apps/owasp/api/internal/nodes/project_health_metrics.py (1)
  • ProjectHealthMetricsNode (31-97)
backend/tests/apps/owasp/api/internal/ordering/project_health_metrics_test.py (1)
backend/apps/owasp/api/internal/queries/project_health_metrics.py (1)
  • project_health_metrics (23-40)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: Run backend tests
  • GitHub Check: Run frontend unit tests
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (7)
backend/tests/apps/owasp/api/internal/nodes/project_health_metrics_test.py (1)

33-33: LGTM! Test coverage updated correctly for the new field.

The addition of "project_key" to both the expected field names validation and the parameterized type test ensures proper coverage of the new field with the correct expected type (str).

Also applies to: 72-72

backend/apps/owasp/api/internal/nodes/project_health_metrics.py (1)

31-31: LGTM! Proper relay Node inheritance.

The change to inherit from strawberry.relay.Node is the correct approach for GraphQL relay-compliant nodes, replacing the previous pagination=True decorator argument.

backend/tests/apps/owasp/api/internal/queries/project_health_metrics_test.py (3)

67-67: LGTM! Correct instantiation update.

The removal of the empty list parameter in the ProjectHealthMetricsQuery() instantiation aligns with the updated constructor signature.


72-102: LGTM! Comprehensive test coverage for the updated method.

The test properly mocks the get_latest_health_metrics method and validates the new method signature with explicit filters=None, pagination=None, and ordering=None parameters. The assertions correctly verify both the return type and content.


103-112: No changes needed for get_latest_health_metrics mock
get_latest_health_metrics() returns a Django QuerySet with a .count() method, so

mock_get_latest_metrics.return_value.count.return_value = 42

already correctly stubs the count call. You can ignore the proposed diff.

Likely an incorrect or invalid review comment.

backend/apps/owasp/api/internal/queries/project_health_metrics.py (2)

52-70: LGTM! Proper implementation of distinct length with filter support.

The project_health_metrics_distinct_length method correctly applies filters when provided and returns the count. The implementation follows the expected pattern and properly handles the optional filters parameter.


17-40: No manual filter/ordering logic needed—strawberry_django handles it automatically.

The @strawberry_django.field decorator with filters=, pagination=, and ordering= will automatically apply those parameters to the QuerySet returned by the resolver. Since ProjectHealthMetrics.get_latest_health_metrics() returns a QuerySet, you don’t need to call strawberry_django.filters.apply() or manually handle ordering/pagination in your method.

No changes required here.

@coderabbitai coderabbitai Bot mentioned this pull request Jul 22, 2025
7 tasks done
@arkid15r
arkid15r enabled auto-merge July 23, 2025 16:48
@sonarqubecloud

Copy link
Copy Markdown

@arkid15r arkid15r left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM,
Thank you @ahmedxgouda

@arkid15r
arkid15r added this pull request to the merge queue Jul 23, 2025
Merged via the queue into OWASP:main with commit 8452a33 Jul 23, 2025
@ahmedxgouda
ahmedxgouda deleted the dashboard/metrics-list-frontend branch July 24, 2025 11:25
@coderabbitai coderabbitai Bot mentioned this pull request Aug 4, 2025
2 tasks done
@coderabbitai coderabbitai Bot mentioned this pull request Aug 31, 2025
2 tasks done
@coderabbitai coderabbitai Bot mentioned this pull request Sep 23, 2025
2 tasks done
@coderabbitai coderabbitai Bot mentioned this pull request Nov 2, 2025
2 tasks done
@coderabbitai coderabbitai Bot mentioned this pull request Dec 24, 2025
@coderabbitai coderabbitai Bot mentioned this pull request Jan 30, 2026
4 tasks done
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.

Implement the presentation of the project health metrics dashboard list

3 participants