Skip to content

Refactor dateFormatter to use ISO date strings as timestamps#3857

Merged
kasya merged 33 commits intoOWASP:mainfrom
Mr-Rahul-Paul:fix#3371
Mar 8, 2026
Merged

Refactor dateFormatter to use ISO date strings as timestamps#3857
kasya merged 33 commits intoOWASP:mainfrom
Mr-Rahul-Paul:fix#3371

Conversation

@Mr-Rahul-Paul
Copy link
Contributor

@Mr-Rahul-Paul Mr-Rahul-Paul commented Feb 8, 2026

Resolves #3371

Proposed change

Refactored the dateFormatter utility to exclusively accept numeric Unix timestamps (in seconds) instead of the previous string | number union type. This PR also fixes the affected 50+ files which are other utilities, methods, jest tests and e2e tests.

My approach to fix the issue

  • changed the date format utilities in dateFormatter.ts to take numbers only
  • ran cd frontend && npx tsc to get a list of affected files
       3  __tests__/a11y/components/ActionButton.a11y.test.tsx:11
     1  __tests__/a11y/components/AnchorTitle.a11y.test.tsx:11
     1  __tests__/a11y/components/AutoScrollToTop.a11y.test.tsx:23
     2  __tests__/a11y/components/Badges.a11y.test.tsx:16
     1  __tests__/a11y/components/BarChart.a11y.test.tsx:79
     1  __tests__/a11y/components/BreadCrumbs.a11y.test.tsx:11
     1  __tests__/a11y/components/BreadCrumbsWrapper.a11y.test.tsx:30
     3  __tests__/a11y/components/CalendarButton.a11y.test.tsx:20
     4  __tests__/a11y/components/Card.a11y.test.tsx:49
     4  __tests__/a11y/components/CardDetailsPage.a11y.test.tsx:149
     3  __tests__/a11y/components/ChapterMap.a11y.test.tsx:161
     2  __tests__/a11y/components/ContributionHeatmap.a11y.test.tsx:82
     1  __tests__/a11y/components/ContributorAvatar.a11y.test.tsx:54
     1  __tests__/a11y/components/ContributorsList.a11y.test.tsx:63
     1  __tests__/a11y/components/DashboardCard.a11y.test.tsx:19
     1  __tests__/a11y/components/DisplayIcon.a11y.test.tsx:21
     1  __tests__/a11y/components/DonutBarChart.a11y.test.tsx:34
     2  __tests__/a11y/components/EntityActions.a11y.test.tsx:20
     2  __tests__/a11y/components/Footer.a11y.test.tsx:11
     1  __tests__/a11y/components/GeneralCompliantComponent.a11y.test.tsx:25
     1  __tests__/a11y/components/HealthMetrics.a11y.test.tsx:62
     2  __tests__/a11y/components/InfoBlock.a11y.test.tsx:21
     1  __tests__/a11y/components/InfoItem.a11y.test.tsx:12
     1  __tests__/a11y/components/ItemCardList.a11y.test.tsx:76
     1  __tests__/a11y/components/Leaders.a11y.test.tsx:12
     2  __tests__/a11y/components/LeadersList.a11y.test.tsx:36
     1  __tests__/a11y/components/LineChart.a11y.test.tsx:48
     1  __tests__/a11y/components/LoadingSpinner.a11y.test.tsx:11
     4  __tests__/a11y/components/LoginPageContent.a11y.test.tsx:28
     1  __tests__/a11y/components/LogoCarousel.a11y.test.tsx:59
     1  __tests__/a11y/components/MarkdownWrapper.a11y.test.tsx:21
     1  __tests__/a11y/components/MetricsCard.a11y.test.tsx:43
     2  __tests__/a11y/components/MetricsScoreCircle.a11y.test.tsx:11
     1  __tests__/a11y/components/Milestones.a11y.test.tsx:47
     1  __tests__/a11y/components/Modal.a11y.test.tsx:40
     1  __tests__/a11y/components/ModeToggle.a11y.test.tsx:17
     1  __tests__/a11y/components/MultiSearch.a11y.test.tsx:19
     1  __tests__/a11y/components/NavButton.a11y.test.tsx:23
     2  __tests__/a11y/components/NavDropDown.a11y.test.tsx:27
     1  __tests__/a11y/components/PageLayout.a11y.test.tsx:15
     1  __tests__/a11y/components/Pagination.a11y.test.tsx:18
     1  __tests__/a11y/components/ProgramCard.a11y.test.tsx:31
     1  __tests__/a11y/components/ProjectTypeDashboardCard.a11y.test.tsx:18
     1  __tests__/a11y/components/ProjectsDashboardDropDown.a11y.test.tsx:38
     1  __tests__/a11y/components/ProjectsDashboardNavBar.a11y.test.tsx:18
     1  __tests__/a11y/components/RecentIssues.a11y.test.tsx:38
     1  __tests__/a11y/components/RecentPullRequests.a11y.test.tsx:66
     3  __tests__/a11y/components/RecentRelease.a11y.test.tsx:7
     2  __tests__/a11y/components/Release.a11y.test.tsx:6
     3  __tests__/a11y/components/RepositoryCard.a11y.test.tsx:39
     1  __tests__/a11y/components/ScrollToTop.a11y.test.tsx:11
     3  __tests__/a11y/components/Search.a11y.test.tsx:19
     4  __tests__/a11y/components/SearchPageLayout.a11y.test.tsx:26
     1  __tests__/a11y/components/SecondaryCard.a11y.test.tsx:18
     1  __tests__/a11y/components/SingleModuleCard.a11y.test.tsx:72
     9  __tests__/a11y/components/SkeletonBase.a11y.test.tsx:19
     1  __tests__/a11y/components/SnapshotCard.a11y.test.tsx:19
     1  __tests__/a11y/components/SortBy.a11y.test.tsx:26
     1  __tests__/a11y/components/SponsorCard.a11y.test.tsx:16
     2  __tests__/a11y/components/StatusBadge.a11y.test.tsx:11
     2  __tests__/a11y/components/ToggleableList.a11y.test.tsx:8
     1  __tests__/a11y/components/TruncatedText.a11y.test.tsx:12
     1  __tests__/a11y/components/UserCard.a11y.test.tsx:29
     4  __tests__/a11y/components/UserMenu.a11y.test.tsx:51
     3  __tests__/a11y/pages/About.a11y.test.tsx:157
     5  __tests__/a11y/pages/ApiKeysPage.a11y.test.tsx:26
     4  __tests__/a11y/pages/ChapterDetails.a11y.test.tsx:39
     1  __tests__/a11y/pages/Chapters.a11y.test.tsx:36
     4  __tests__/a11y/pages/CommitteeDetails.a11y.test.tsx:32
     1  __tests__/a11y/pages/Committees.a11y.test.tsx:35
     1  __tests__/a11y/pages/Contribute.a11y.test.tsx:25
     1  __tests__/a11y/pages/CreateModule.a11y.test.tsx:45
     1  __tests__/a11y/pages/CreateProgram.a11y.test.tsx:48
     1  __tests__/a11y/pages/EditModule.a11y.test.tsx:32
     1  __tests__/a11y/pages/EditProgram.a11y.test.tsx:40
     1  __tests__/a11y/pages/Home.a11y.test.tsx:63
     1  __tests__/a11y/pages/IssuesPage.a11y.test.tsx:57
     1  __tests__/a11y/pages/MenteeProfilePage.a11y.test.tsx:188
     4  __tests__/a11y/pages/ModuleDetails.a11y.test.tsx:39
     4  __tests__/a11y/pages/ModuleDetailsPage.a11y.test.tsx:37
     4  __tests__/a11y/pages/ModuleIssueDetailsPage.a11y.test.tsx:102
     1  __tests__/a11y/pages/MyMentorship.a11y.test.tsx:44
     1  __tests__/a11y/pages/Organization.a11y.test.tsx:26
     1  __tests__/a11y/pages/OrganizationDetails.a11y.test.tsx:21
     1  __tests__/a11y/pages/Program.a11y.test.tsx:30
     1  __tests__/a11y/pages/ProgramDetails.a11y.test.tsx:33
     1  __tests__/a11y/pages/ProgramDetailsMentorship.a11y.test.tsx:28
     1  __tests__/a11y/pages/ProjectDetails.a11y.test.tsx:42
     1  __tests__/a11y/pages/ProjectHealthDashboardMetricsDetails.a11y.test.tsx:57
     1  __tests__/a11y/pages/Projects.a11y.test.tsx:50
     1  __tests__/a11y/pages/ProjectsHealthDashboardMetrics.a11y.test.tsx:40
     2  __tests__/a11y/pages/ProjectsHealthDashboardOverview.a11y.test.tsx:45
     1  __tests__/a11y/pages/RepositoryDetails.a11y.test.tsx:35
     1  __tests__/a11y/pages/SnapshotDetails.a11y.test.tsx:38
     1  __tests__/a11y/pages/Snapshots.a11y.test.tsx:21
     1  __tests__/a11y/pages/UserDetails.a11y.test.tsx:71
     1  __tests__/a11y/pages/Users.a11y.test.tsx:26
     1  __tests__/unit/components/ProgramCard.test.tsx:344
     4  __tests__/unit/components/SnapshotCard.test.tsx:27
    16  __tests__/unit/utils/dateFormatter.test.ts:9
     1  src/components/Card.tsx:86
     1  src/components/CardDetailsPage.tsx:463
     2  src/components/MenteeIssues.tsx:86
     1  src/components/Milestones.tsx:44
     1  src/components/ModuleCard.tsx:106
     3  src/components/ProgramCard.tsx:42
     1  src/components/RecentIssues.tsx:32
     1  src/components/RecentPullRequests.tsx:32
     2  src/components/SingleModuleCard.tsx:45
     2  src/components/SnapshotCard.tsx:22
  • all the listed files + other dependent methods and tests we addressed
  • Timestamps were converted using https://www.epochconverter.com/ from string to Unix time stamps
  • Existing tests using ISO stamps or strings were converted to Unix timestamps by AI tools but were individually checked by me afterwards .
  • make check-test works, All backend ,jest and e2e tests pass and warnings addressed.

Checklist

  • Required: I followed the contributing workflow
  • Required: I verified that my code works as intended and resolves the issue as described
  • Required: I ran make check-test locally: all warnings addressed, tests passed
  • I used AI for code, documentation, tests, or communication related to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 8, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

This pull request unifies timestamp handling across the application by transitioning from mixed formats (numeric Unix timestamps and various string representations) to standardized ISO 8601 strings. Changes affect type definitions, utility functions, test fixtures, and both frontend and backend components.

Changes

Cohort / File(s) Summary
Frontend Type Definitions
frontend/src/types/{calendar, issue, mentorship, milestone, chapter, committee, project, pullRequest, release, user}.ts
Type narrowing/updates to restrict timestamp fields (createdAt, updatedAt, startDate, endDate, publishedAt, etc.) from mixed types (number | string) or numeric to string-only representations.
Frontend Date Utilities
frontend/src/utils/{dateFormatter, getGoogleCalendarUrl, getIcsFileUrl}.ts
Refactored to accept only string inputs instead of mixed number/string types. Function signatures updated: formatDate(input: string | null), formatDateRange(startDate: string, endDate: string), formatDateForInput(input: string). Removed Unix timestamp parsing; added null-coalescing and ISO string handling.
Frontend Test Data — Mock Objects
frontend/__tests__/mockData/{mockHomeData, mockModuleData, mockOrganizationData, mockProgramData, mockProjectDetailsData, mockRepositoryData, mockSnapshotData, mockUserDetails, mockChapterData, mockChapterDetailsData, mockCommitteeData, mockCommitteeDetailsData, mockContributeData}.ts
Timestamp fields updated from numeric epochs or inconsistent string formats to standardized ISO 8601 strings with millisecond precision (e.g., "2025-01-01T00:00:00.000Z").
Frontend Unit Tests — Component/Page
frontend/__tests__/unit/{components, pages}/*.test.tsx
Test fixtures and mock data updated to use ISO string timestamps; date formatter mocks refactored to accept string inputs and handle null cases; test expectations aligned with new string-based date formats.
Frontend A11y Tests
frontend/__tests__/a11y/{components, pages, mockData}/*.test.tsx
Test data timestamps converted from numeric epochs or date-only strings to ISO 8601 format; test fixtures aligned with string-based timestamp expectations.
Frontend E2E Test Data
frontend/__tests__/e2e/data/mockHomeData.ts
Multiple timestamp fields normalized from "+00:00" offset notation to standardized ".000Z" UTC format with millisecond precision.
Frontend Components/Pages
frontend/src/{components, app}/*.tsx, frontend/src/app/board/[year]/candidates/page.tsx, frontend/src/app/organizations/[organizationKey]/page.tsx
Updated to handle string-based timestamps; removed numeric Unix timestamp multiplication (e.g., \* 1000); component type signatures adjusted for publishedAt (number → string) and member date fields.
Frontend Utility Helpers
frontend/src/utils/utility.ts
Updated getFilteredIcons to treat project.createdAt as string instead of numeric value; adjusted dayjs parsing accordingly.
Backend GraphQL Node Resolvers
backend/apps/{github, owasp}/api/internal/nodes/{user, chapter, committee, common}.py
Return type annotations updated from float to str for date resolver fields (created_at, updated_at, first_owasp_contribution_at) without changing resolver logic (still delegates to model properties).
Backend Model Index Mixins
backend/apps/{github, owasp}/models/mixins/{user, chapter, committee, project}.py
Index property methods changed from returning Unix timestamps (timestamp()) to ISO format strings (isoformat()); return type annotations updated from float to str.
Backend Tests
backend/tests/apps/{github, owasp}/{api, models}/...test.py
Test expectations updated to compare against .isoformat() results instead of .timestamp() values; test assertions align with new string-based date representations.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Rationale: This PR spans 80+ files across frontend and backend with changes to type definitions, utility function signatures, test data normalization, and model/resolver implementations. While individual changes follow consistent patterns (timestamp format updates, type narrowing), the breadth of affected areas (types, utilities, components, tests, backend models/resolvers) and the need to verify consistency across multiple layers demand thorough, context-aware review. The refactoring touches core date handling infrastructure, requiring attention to backward compatibility and data flow across the full stack.

Possibly related PRs

Suggested reviewers

  • kasya
  • arkid15r
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The changeset contains some changes that extend beyond the core objective of enforcing numeric types. Backend changes (converting GraphQL fields from float to string) and type narrowing in multiple type files suggest scope creep. Additionally, some test refactoring (like reorganizing test structure in CalendarButton.test.tsx) goes beyond simple data format conversion. Review and clarify backend GraphQL field changes (user.py, chapter.py, committee.py, project.py) and assess whether these represent necessary alignment or scope creep. Consider whether type narrowing in issue.ts, calendar.ts, and mentorship.ts align with the stated numeric-timestamps-only objective.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The PR description provides comprehensive context about the refactoring effort, including the proposed changes, approach, affected files count, testing methodology, and checklist completion. It clearly relates to the code changes in the changeset.
Linked Issues check ✅ Passed The PR addresses the coding requirements from issue #3371: refactored dateFormatter.ts to enforce number type, updated dependent interfaces/types, and converted 50+ files to use numeric Unix timestamps. All core objectives from the linked issue are substantially met with type signatures changed and test files updated accordingly.
Docstring Coverage ✅ Passed Docstring coverage is 93.88% which is sufficient. The required threshold is 80.00%.
Title check ✅ Passed The PR title 'Refactor dateFormatter to use ISO date strings as timestamps' accurately describes the primary change: updating the dateFormatter utility to work with a standardized date/timestamp format, with widespread updates across frontend test files and type definitions.

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

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

Caution

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

⚠️ Outside diff range comments (6)
frontend/__tests__/unit/components/SingleModuleCard.test.tsx (2)

53-55: ⚠️ Potential issue | 🟡 Minor

Mock formatDate produces incorrect dates with numeric timestamps.

The mock uses new Date(date) which interprets the numeric Unix timestamp (seconds) as milliseconds, yielding dates in 1970 instead of 2024. The real formatDate does new Date(input * 1000). While current tests don't assert on specific formatted date strings, this will silently produce wrong output.

Proposed fix
 jest.mock('utils/dateFormatter', () => ({
-  formatDate: jest.fn((date: string) => new Date(date).toLocaleDateString()),
+  formatDate: jest.fn((date: number) => new Date(date * 1000).toLocaleDateString()),
 }))

62-69: ⚠️ Potential issue | 🟡 Minor

Mock getSimpleDuration has the same seconds-vs-milliseconds issue.

new Date(start) on a Unix-seconds value gives a 1970 date. The diff calculation will be wrong. Should multiply by 1000.

Proposed fix
 jest.mock('components/ModuleCard', () => ({
-  getSimpleDuration: jest.fn((start: string, end: string) => {
-    const startDate = new Date(start)
-    const endDate = new Date(end)
+  getSimpleDuration: jest.fn((start: number, end: number) => {
+    const startDate = new Date(start * 1000)
+    const endDate = new Date(end * 1000)
     const diffTime = Math.abs(endDate.getTime() - startDate.getTime())
     const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
     return `${diffDays} days`
   }),
 }))
frontend/src/components/ModuleCard.tsx (1)

189-203: ⚠️ Potential issue | 🟡 Minor

getSimpleDuration should accept only number parameters to match the Module type.

The Module type defines startedAt and endedAt as number, yet getSimpleDuration accepts string | number. All production callers pass numeric values from Module objects, making the string-handling branch dead code.

♻️ Suggested change
-export const getSimpleDuration = (start: string | number, end: string | number): string => {
+export const getSimpleDuration = (start: number, end: number): string => {
   if (!start || !end) return 'N/A'
 
-  const startDate = typeof start === 'number' ? new Date(start * 1000) : new Date(start)
-  const endDate = typeof end === 'number' ? new Date(end * 1000) : new Date(end)
+  const startDate = new Date(start * 1000)
+  const endDate = new Date(end * 1000)
frontend/__tests__/unit/utils/getIcsFileUrl.test.ts (1)

40-78: ⚠️ Potential issue | 🟡 Minor

Duplicate test: Lines 40–58 and 60–78 are identical in setup, input, and assertions.

Both tests spread mockEvent with the same startDate/endDate values it already contains, mock createEvent identically, and assert the same start/end arrays. One of these should be removed to avoid dead test weight.

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

6-11: ⚠️ Potential issue | 🔴 Critical

Bug: formatLocalDate uses local-timezone accessors on UTC-midnight timestamps, producing wrong dates in non-UTC timezones.

formatLocalDate calls getFullYear(), getMonth(), getDate() — all local-time methods. When a user's browser is in a timezone behind UTC (e.g., UTC−5), a midnight-UTC timestamp like 1764547200 (2025-12-01T00:00:00Z) resolves to Nov 30 locally, so the all-day event date will be off by a day.

Since these timestamps are defined as UTC (line 23–24 comment confirms this), the all-day branch should use UTC accessors, consistent with formatUTCDateTime.

Proposed fix
 function formatLocalDate(date: Date) {
-  const year = date.getFullYear()
-  const month = pad(date.getMonth() + 1)
-  const day = pad(date.getDate())
+  const year = date.getUTCFullYear()
+  const month = pad(date.getUTCMonth() + 1)
+  const day = pad(date.getUTCDate())
   return `${year}${month}${day}`
 }

You may also want to rename it to formatUTCDate for clarity.

Also applies to: 44-48

frontend/__tests__/unit/components/Milestones.test.tsx (1)

126-127: ⚠️ Potential issue | 🟡 Minor

The test mock User values use milliseconds instead of seconds.

The values 1640995200000 in createMockUser are milliseconds (Jan 1, 2022), but given that this PR standardizes on Unix timestamps in seconds, these should be 1640995200. This matters because user.createdAt is used with formatDate in production code (e.g., frontend/src/app/members/[memberKey]/page.tsx:114), which expects seconds. The test currently passes only because the Milestones component doesn't display author.createdAt, but the mock data is incorrect and should match the pattern in mockUserDetails.ts, which correctly uses seconds.

🤖 Fix all issues with AI agents
In `@frontend/__tests__/mockData/mockRepositoryData.ts`:
- Line 58: The createdAt timestamp in mockRepositoryData (createdAt: 1740826800)
is off by one hour relative to the comment and other mocks; update the createdAt
value in mockRepositoryData to 1740823200 so it matches 2025-03-01T10:00:00Z and
stays consistent with mockUserDetails and e2e/mockHomeData entries.

In `@frontend/__tests__/unit/components/CardDetailsPage.test.tsx`:
- Line 555: The test uses numeric epoch seconds for Milestone.createdAt but the
createMilestones helper still sets createdAt to a string via new
Date(...).toISOString(); update the createMilestones function to return a
numeric timestamp (matching Milestone.createdAt?: number) — e.g. replace the
toISOString() usage with a numeric epoch seconds value (compute from Date using
getTime()/1000 or Math.floor) so createdAt is a number like 1672531200.

In
`@frontend/src/app/my/mentorship/programs/`[programKey]/modules/[moduleKey]/page.tsx:
- Around line 52-56: The current code double-converts timestamps by calling new
Date(...).getTime()/1000 before passing to formatDate; instead pass the
Unix-second timestamp directly from mentorshipModule.startedAt and
mentorshipModule.endedAt to formatDate (or coerce them to number if they may be
strings) because formatDate expects seconds and performs its own new Date(input
* 1000); update the objects where label: 'Start Date' and 'End Date' are
constructed to use mentorshipModule.startedAt and mentorshipModule.endedAt
directly.

In `@frontend/src/app/page.tsx`:
- Line 190: The call passes label={formatDateRange(event.startDate as number,
event.endDate as number)} which hides a real type mismatch: event.startDate is
already number but event.endDate is number | undefined, and the unnecessary "as
number" casts suppress the compiler; remove the casts and either (A) update the
Event type to make endDate required, or (B) change formatDateRange (or the call
site) to accept/handle endDate?: number (e.g., provide a fallback or overload)
so the parameter types align—locate formatDateRange, the Event type, and this
usage (event.startDate/event.endDate) and make one of those two fixes so
TypeScript type checking is preserved.

In `@frontend/src/components/CardDetailsPage.tsx`:
- Around line 463-465: The code double-converts milestone.createdAt before
calling formatDate, causing incorrect dates; instead pass the numeric Unix
seconds directly. In CardDetailsPage replace the expression formatDate(new
Date(milestone.createdAt).getTime() / 1000) with formatDate(milestone.createdAt)
(use the milestone.createdAt value as-is) so formatDate receives seconds as
expected.

In `@frontend/src/components/MenteeIssues.tsx`:
- Around line 86-89: In MenteeIssues.tsx the timestamps are being
double-converted before formatting: remove the unnecessary new
Date(...).getTime() / 1000 wrapper and pass issue.createdAt and issue.updatedAt
(when present) directly to formatDate, e.g. replace formatDate(new
Date(issue.createdAt).getTime() / 1000) with formatDate(issue.createdAt); keep
the conditional for issue.updatedAt as-is and mirror the pattern used in
RecentIssues.tsx so formatDate receives the original Unix seconds number.

In `@frontend/src/components/ModuleCard.tsx`:
- Around line 106-110: The displayed start date is wrong because ModuleCard's
TextInfoItem passes formatDate(new Date(module.startedAt).getTime() / 1000)
which treats an already-second Unix timestamp as milliseconds; update the call
to pass the seconds value directly (use formatDate(module.startedAt)) in the
ModuleCard component where TextInfoItem is rendered so formatDate (which expects
seconds) receives the correct input; ensure you adjust only the expression
around module.startedAt and leave TextInfoItem and formatDate implementations
unchanged.

In `@frontend/src/components/RecentPullRequests.tsx`:
- Line 32: RecentPullRequests.tsx is double-converting createdAt which breaks
numeric Unix timestamps; update the span rendering to check typeof
item.createdAt: if it's a number pass item.createdAt directly to formatDate
(since formatDate expects seconds), otherwise convert the string via new
Date(item.createdAt).getTime() / 1000 and pass that; reference the JSX span
using item.createdAt and the formatDate call so you only divide by 1000 for
string dates and avoid double-conversion for numeric timestamps.

In `@frontend/src/components/SingleModuleCard.tsx`:
- Around line 45-46: The current code double-converts timestamps by calling new
Date(module.startedAt).getTime()/1000 and new
Date(module.endedAt).getTime()/1000 before passing to formatDate; instead, pass
the Unix-second values directly (module.startedAt and module.endedAt) to
formatDate. Locate the entries where the labels 'Start Date' and 'End Date' are
formed in the SingleModuleCard component and replace the new
Date(...).getTime()/1000 expressions with module.startedAt and module.endedAt
respectively so formatDate receives the correct seconds-based timestamps.
🧹 Nitpick comments (5)
frontend/__tests__/unit/components/ProgramCard.test.tsx (1)

364-364: Using 0 as a sentinel for "no date" relies on JS falsiness.

This works because 0 is falsy, so if (startedAt) guards in the component correctly fall through to "No dates set". However, 0 is technically a valid Unix timestamp (epoch). If the type were number | null, intent would be clearer and less prone to accidental misuse in arithmetic paths. This is a broader design choice for the PR though, not specific to these tests.

Also applies to: 378-378, 393-393

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

86-91: Conversion is correct here, but CardProps.timeline types are still string.

Unlike the Module case, timeline.start and timeline.end are still typed as string in CardProps (see frontend/src/types/card.ts, lines 33-34), so the new Date(string).getTime() / 1000 conversion is valid. However, for consistency with the PR's goal of enforcing numeric timestamps everywhere, consider updating CardProps.timeline to use number as well and moving the conversion upstream to the call sites.

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

62-69: Parameter name dateStr is now misleading — it's a number, not a string.

A small rename to timestamp or date would improve clarity.

Suggested rename
-export const formatDateForInput = (dateStr: number) => {
-  if (!dateStr) return ''
-  const date = new Date(dateStr * 1000)
+export const formatDateForInput = (timestamp: number) => {
+  if (!timestamp) return ''
+  const date = new Date(timestamp * 1000)
frontend/__tests__/unit/utils/dateFormatter.test.ts (1)

3-23: Consider adding edge-case tests for the 0 and invalid inputs.

The formatDate implementation has two distinct code paths not covered here: formatDate(0) returns '' (falsy guard), and formatDate(NaN) throws 'Invalid date'. Adding a test for at least the 0'' case would improve coverage of the guard clause, and a test for the error path would document the contract.

frontend/__tests__/unit/components/Milestones.test.tsx (1)

14-31: The mock duplicates the real formatDate implementation.

This mock reimplements the exact same logic as the production formatDate (multiply by 1000, toLocaleDateString with identical options). If the real formatter's behavior changes, this mock won't detect regressions. Consider either:

  • Using a trivial mock (jest.fn(() => 'Jan 1, 2023')) and asserting the mock was called with the expected timestamp, or
  • Not mocking dateFormatter at all, letting the real implementation run.
♻️ Simpler mock approach
 jest.mock('utils/dateFormatter', () => {
-  const mockFormatDate = jest.fn((timestamp: number) => {
-    if (!timestamp) return ''
-    const date = new Date(timestamp * 1000)
-    return date.toLocaleDateString('en-US', {
-      year: 'numeric',
-      month: 'short',
-      day: 'numeric',
-      timeZone: 'UTC',
-    })
-  })
+  const mockFormatDate = jest.fn((timestamp: number) =>
+    timestamp ? `formatted-${timestamp}` : ''
+  )
 
   return {
     __esModule: true,
     formatDate: mockFormatDate,
     default: mockFormatDate,
   }
 })

Then update assertions to match on the stub output (e.g., 'formatted-1672531200') or verify .toHaveBeenCalledWith(1672531200).

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

16 issues found across 52 files

Confidence score: 3/5

  • Several date fields are double-converted to epoch seconds (e.g., formatDate fed new Date(...).getTime()/1000 on values already in seconds) causing incorrect dates (often around 1970) in frontend/src/components/MenteeIssues.tsx, frontend/src/components/SingleModuleCard.tsx, frontend/src/components/ModuleCard.tsx, frontend/src/components/CardDetailsPage.tsx, and frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx.
  • frontend/src/app/page.tsx casts optional event.endDate to number, which can yield an Invalid date at runtime when the value is missing.
  • These are user-facing date display issues with concrete impact, so there’s some merge risk despite the fixes being straightforward.
  • Pay close attention to frontend/src/components/MenteeIssues.tsx, frontend/src/components/SingleModuleCard.tsx, frontend/src/components/ModuleCard.tsx, frontend/src/components/CardDetailsPage.tsx, frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx, frontend/src/app/page.tsx - ensure epoch seconds aren’t scaled twice and optional dates are guarded.
Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="frontend/__tests__/mockData/mockRepositoryData.ts">

<violation number="1" location="frontend/__tests__/mockData/mockRepositoryData.ts:58">
P2: The Unix timestamp does not match the ISO comment; `2025-03-01T10:00:00Z` should be 1740823200, not 1740826800. This makes the mock data inconsistent and can cause time-based tests to drift by an hour.</violation>
</file>

<file name="frontend/src/components/MenteeIssues.tsx">

<violation number="1" location="frontend/src/components/MenteeIssues.tsx:86">
P2: `formatDate` already expects a Unix-seconds number. Wrapping `issue.createdAt` in `new Date(...).getTime() / 1000` will shrink already-seconds values by 1000 and render incorrect dates. Use the numeric timestamp directly.</violation>

<violation number="2" location="frontend/src/components/MenteeIssues.tsx:88">
P2: Same issue for `updatedAt`: `formatDate` expects a Unix-seconds number, so the extra `new Date(...).getTime() / 1000` will mis-scale seconds-based values.</violation>
</file>

<file name="frontend/src/components/SingleModuleCard.tsx">

<violation number="1" location="frontend/src/components/SingleModuleCard.tsx:45">
P2: `module.startedAt` is already a Unix-seconds number; converting it through `new Date(...).getTime()/1000` divides it by 1000 and produces an incorrect timestamp. Pass the seconds value directly to `formatDate` to avoid shifting dates to 1970.</violation>

<violation number="2" location="frontend/src/components/SingleModuleCard.tsx:46">
P2: `module.endedAt` is already a Unix-seconds number; converting it via `new Date(...).getTime()/1000` shrinks the timestamp and produces wrong dates. Pass the seconds value directly to `formatDate`.</violation>
</file>

<file name="frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx">

<violation number="1" location="frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx:54">
P2: `formatDate` already expects a seconds timestamp; wrapping `mentorshipModule.startedAt` in `new Date(...).getTime() / 1000` will turn a seconds value into a much smaller timestamp (dates around 1970). Pass the numeric timestamp directly.</violation>

<violation number="2" location="frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx:56">
P2: `formatDate` already expects a seconds timestamp; wrapping `mentorshipModule.endedAt` in `new Date(...).getTime() / 1000` will turn a seconds value into a much smaller timestamp (dates around 1970). Pass the numeric timestamp directly.</violation>
</file>

<file name="frontend/src/app/page.tsx">

<violation number="1" location="frontend/src/app/page.tsx:190">
P2: Casting `event.endDate` to `number` hides the fact that `endDate` is optional and can be `undefined`, which can trigger an Invalid date error at runtime. Guard or fall back when `endDate` is missing instead of asserting.</violation>
</file>

<file name="frontend/src/components/ModuleCard.tsx">

<violation number="1" location="frontend/src/components/ModuleCard.tsx:109">
P2: Module.startedAt is already a numeric Unix timestamp (seconds). Wrapping it in `new Date(...).getTime() / 1000` converts seconds as if they were milliseconds and then divides again, yielding a timestamp 1000× too small. This will render incorrect start dates. Pass the seconds value directly to `formatDate` (or explicitly multiply by 1000 only if `startedAt` is in ms).</violation>
</file>

<file name="frontend/src/components/RecentPullRequests.tsx">

<violation number="1" location="frontend/src/components/RecentPullRequests.tsx:32">
P2: This conversion double-scales numeric Unix seconds. Since `formatDate` already expects seconds, only convert ISO strings and pass numeric timestamps through unchanged to avoid incorrect dates.</violation>
</file>

<file name="frontend/src/components/CardDetailsPage.tsx">

<violation number="1" location="frontend/src/components/CardDetailsPage.tsx:464">
P2: `milestone.createdAt` is already a numeric Unix timestamp; wrapping it in `new Date(...).getTime() / 1000` scales it down by 1000, yielding incorrect dates. Pass the numeric value directly (and optionally guard for undefined) instead of re-converting it.</violation>
</file>

<file name="frontend/src/utils/getIcsFileUrl.ts">

<violation number="1" location="frontend/src/utils/getIcsFileUrl.ts:13">
P2: DateArray values are now derived with UTC getters, but `createEvent` treats DateArray inputs as local time by default. This can shift the calendar date in non‑UTC timezones. Use local getters or set `startInputType/endInputType` to `utc` when passing UTC timestamps.</violation>
</file>

<file name="frontend/__tests__/mockData/mockHomeData.ts">

<violation number="1" location="frontend/__tests__/mockData/mockHomeData.ts:4">
P2: The recentProjects createdAt timestamps don’t match the original ISO dates. These should be converted to the correct epoch for 2024-12-06T20:46:54Z (1733518014) to avoid changing the mock timeline.</violation>

<violation number="2" location="frontend/__tests__/mockData/mockHomeData.ts:97">
P2: The publishedAt timestamp doesn’t match the original ISO value; it’s off by ~40 minutes. Convert 2024-12-13T14:43:46Z to its correct epoch value.</violation>

<violation number="3" location="frontend/__tests__/mockData/mockHomeData.ts:128">
P2: endDate conversion doesn’t match the original date-only value; use the midnight UTC epoch for 2025-02-28 to keep the mock date consistent.</violation>

<violation number="4" location="frontend/__tests__/mockData/mockHomeData.ts:130">
P2: startDate conversion doesn’t match the original date-only value; use the midnight UTC epoch for 2025-02-27 to keep the mock date consistent.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@Mr-Rahul-Paul
Copy link
Contributor Author

Mr-Rahul-Paul commented Feb 8, 2026

closing the PR because of conversions errors

@arkid15r
Copy link
Collaborator

arkid15r commented Feb 8, 2026

closing the PR because of conversions errors

Please don't create multiple PRs if you need to improve your code. It's okay to close it if you won't create new PRs related to this issue.

@Mr-Rahul-Paul
Copy link
Contributor Author

Thanks for the feedback, I'll reopen the PR when I address the bot comments

coderabbitai[bot]
coderabbitai bot previously approved these changes Feb 8, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (2)
frontend/src/utils/getIcsFileUrl.ts (1)

16-23: ⚠️ Potential issue | 🟠 Major

Same local-vs-UTC issue in getEndDate.

getEndDate constructs a new Date(y, m - 1, d + 1) which interprets values in local time and then extracts components with local-time getters. If parseDate is fixed to return UTC components, this function should also use Date.UTC(...) and UTC getters to stay consistent; otherwise the "+1 day" rollover logic may still drift across timezone boundaries.

Proposed fix
     const getEndDate = (start: DateArray, end: DateArray): DateArray => {
       if (start.join('-') === end.join('-')) {
         const [y, m, d] = end
-        const nextDay = new Date(y, m - 1, d + 1)
-        return [nextDay.getFullYear(), nextDay.getMonth() + 1, nextDay.getDate()]
+        const nextDay = new Date(Date.UTC(y, m - 1, d + 1))
+        return [nextDay.getUTCFullYear(), nextDay.getUTCMonth() + 1, nextDay.getUTCDate()]
       }
       return end
     }
frontend/__tests__/a11y/components/RecentPullRequests.a11y.test.tsx (1)

34-34: ⚠️ Potential issue | 🟠 Major

Convert mockUser.createdAt from milliseconds to seconds.

The formatDate function expects Unix timestamps in seconds and multiplies by 1000 to convert to milliseconds (line 6 of frontend/src/utils/dateFormatter.ts). The value 1577836800000 is in milliseconds; it should be 1577836800 in seconds. This is inconsistent with all other test mocks in the codebase (mockUserDetails, mockRepositoryData, mockOrganizationData, etc.), which correctly use seconds. Without this fix, the component will render an incorrect date.

Proposed fix
-  createdAt: 1577836800000,
+  createdAt: 1577836800,
🤖 Fix all issues with AI agents
In `@frontend/src/utils/getIcsFileUrl.ts`:
- Around line 10-14: The parseDate function uses local-time getters which can
shift the calendar day across timezones; change parseDate to use UTC getters:
create the Date from the timestamp*1000 as before, then use d.getUTCFullYear(),
d.getUTCMonth() + 1, and d.getUTCDate() to populate the DateArray so the
date-only value reflects the absolute UTC calendar day (keep the month +1
adjustment).

@Mr-Rahul-Paul
Copy link
Contributor Author

@coderabbitai review changes

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 1, 2026

@Mr-Rahul-Paul: I'll review the changes in this PR right away.


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

Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/app/about/page.tsx:47-53
Timestamp: 2025-09-21T11:34:33.377Z
Learning: User rudransh-shrivastava prefers to keep Apollo Client migration PRs focused solely on migration-related changes and not include additional bug fixes or improvements that aren't directly related to the migration itself.
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (5)
frontend/__tests__/a11y/components/Release.a11y.test.tsx (1)

6-19: ⚠️ Potential issue | 🟡 Minor

Update publishedAt to ISO string in test fixture.

The Release.publishedAt type is defined as string in frontend/src/types/release.ts, but the test fixture uses Date.now() which returns a number. This creates a type mismatch. Line 8 should be updated to match the corrected author.createdAt format on line 19.

🔧 Proposed fix
 const release: ReleaseType = {
   name: 'v1.0 The First Release',
-  publishedAt: Date.now(),
+  publishedAt: new Date().toISOString(),
   repositoryName: 'our-awesome-project',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/__tests__/a11y/components/Release.a11y.test.tsx` around lines 6 -
19, The test fixture uses a numeric timestamp for Release.publishedAt but the
ReleaseType defines publishedAt as a string; update the publishedAt field in the
Release fixture (in the Release.a11y.test.tsx file) to an ISO string (e.g. new
Date().toISOString() or a hard-coded ISO date) so it matches the string type
like author.createdAt and satisfies the ReleaseType; ensure the field name
publishedAt in the ReleaseType fixture is the only change.
frontend/__tests__/unit/components/Release.test.tsx (1)

71-76: ⚠️ Potential issue | 🟠 Major

Type mismatch: publishedAt should be a string, not a number.

Date.now() returns a number, but Release.publishedAt is now typed as string per the changes in frontend/src/types/release.ts. This will cause TypeScript compilation errors.

🐛 Proposed fix
-const now = Date.now()
+const now = new Date().toISOString()
 const mockReleases: ReleaseType[] = [
   {
     id: 'release-test-1',
     name: 'v1.0 The First Release',
     publishedAt: now,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/__tests__/unit/components/Release.test.tsx` around lines 71 - 76,
The test uses Date.now() (a number) for publishedAt but Release.publishedAt is
typed as string; update the mock in Release.test.tsx by changing the now
variable or the publishedAt value in the mockReleases entry (referencing the
mockReleases array and the now constant) to a string representation (e.g., ISO
string or String(now)) so the publishedAt field matches the ReleaseType string
type.
backend/tests/apps/github/api/internal/nodes/user_test.py (2)

80-87: ⚠️ Potential issue | 🟠 Major

Test expects float but implementation returns string.

Same issue as test_created_at_field: the test sets mock_user.idx_updated_at = 1234567890.0 and uses math.isclose(), but the resolver now returns a string.

Proposed fix
     def test_updated_at_field(self):
-        """Test updated_at field resolution."""
+        """Test updated_at field resolution returns ISO string."""
         mock_user = Mock()
-        mock_user.idx_updated_at = 1234567890.0
+        mock_user.idx_updated_at = "2009-02-13T23:31:30+00:00"
 
         field = self._get_field_by_name("updated_at", UserNode)
         result = field.base_resolver.wrapped_func(None, mock_user)
-        assert math.isclose(result, 1234567890.0)
+        assert result == "2009-02-13T23:31:30+00:00"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tests/apps/github/api/internal/nodes/user_test.py` around lines 80 -
87, The test fails because UserNode's updated_at resolver (accessed in the test
via field = self._get_field_by_name("updated_at", UserNode) and
field.base_resolver.wrapped_func) is returning a string instead of a numeric
float; update the resolver implementation for updated_at to return the original
numeric value (cast/parse idx_updated_at to float if necessary) so that calling
field.base_resolver.wrapped_func(None, mock_user) yields a float comparable with
math.isclose instead of a string.

53-60: ⚠️ Potential issue | 🟠 Major

Test expects float but implementation returns string.

The test sets mock_user.idx_created_at = 1234567890.0 and asserts with math.isclose(result, 1234567890.0). However, the created_at resolver now returns root.idx_created_at which is expected to be an ISO format string (based on changes in UserIndexMixin.idx_created_at).

This test will fail because the resolver's return type is now str, not float.

Proposed fix
     def test_created_at_field(self):
-        """Test created_at field resolution."""
+        """Test created_at field resolution returns ISO string."""
         mock_user = Mock()
-        mock_user.idx_created_at = 1234567890.0
+        mock_user.idx_created_at = "2009-02-13T23:31:30+00:00"
 
         field = self._get_field_by_name("created_at", UserNode)
         result = field.base_resolver.wrapped_func(None, mock_user)
-        assert math.isclose(result, 1234567890.0)
+        assert result == "2009-02-13T23:31:30+00:00"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tests/apps/github/api/internal/nodes/user_test.py` around lines 53 -
60, Test assumes created_at is a float but the resolver now returns whatever
root.idx_created_at holds (an ISO string from UserIndexMixin.idx_created_at);
update test_created_at_field to set mock_user.idx_created_at to the ISO-format
string you expect and assert equality (e.g., result == mock_user.idx_created_at)
instead of using math.isclose, locating the field via
_get_field_by_name("created_at", UserNode) and calling
field.base_resolver.wrapped_func as before.
frontend/__tests__/mockData/mockHomeData.ts (1)

40-40: ⚠️ Potential issue | 🟡 Minor

The type field change removes test coverage for the 'Other' project type.

The type field for owasp-project-5 was changed from 'Other' to an empty string ''. While the empty string is handled by the getProjectIcon() default case (which returns the file code icon), this change affects the UI display: with an empty type, no label text is shown (only the icon); with 'Other', both the icon and "Other" label are displayed.

Since project type is rendered on the home page and the 'Other' type is a valid option in the codebase, restoring it to 'Other' would maintain test coverage of that project type variant.

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

In `@frontend/__tests__/mockData/mockHomeData.ts` at line 40, Restore the project
type for the mock entry with id 'owasp-project-5' by changing its type field
back from an empty string to 'Other' so the UI test covers the 'Other' project
type variant; update the object in mockHomeData.ts (the entry containing id
'owasp-project-5' and the property type) so getProjectIcon() still falls through
to the correct icon while the label text "Other" is rendered in tests.
♻️ Duplicate comments (2)
frontend/__tests__/unit/components/CardDetailsPage.test.tsx (1)

1905-1922: ⚠️ Potential issue | 🟡 Minor

Inconsistent timestamp format in createMilestones helper.

The mockRecentMilestones fixture at line 714 uses an ISO string for createdAt, but this createMilestones helper generates a numeric Unix timestamp. If Milestone.createdAt is being migrated to string, this helper should produce ISO strings for consistency.

🔧 Proposed fix
       milestones.push({
         author: mockUser,
         body: `Milestone description ${i + 1}`,
         closedIssuesCount: 5,
-        createdAt: Math.floor((Date.now() - 10000000) / 1000),
+        createdAt: new Date(Date.now() - 10000000).toISOString(),
         openIssuesCount: 2,
#!/bin/bash
# Verify the Milestone.createdAt type definition
rg -n "createdAt" frontend/src/types/milestone.ts -A2 -B2
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/__tests__/unit/components/CardDetailsPage.test.tsx` around lines
1905 - 1922, The createMilestones helper generates numeric Unix timestamps for
Milestone.createdAt but other fixtures like mockRecentMilestones use ISO
strings; update createMilestones to produce ISO-formatted strings (e.g., new
Date(...).toISOString()) for createdAt so the type matches Milestone.createdAt
and tests stay consistent; locate the helper function createMilestones in the
test file and replace the numeric timestamp generation with ISO string
generation, ensuring all createdAt usages across tests (including
mockRecentMilestones) are consistent.
frontend/src/utils/getIcsFileUrl.ts (1)

10-14: ⚠️ Potential issue | 🟠 Major

ICS date extraction is timezone-unsafe and missing UTC input type flags.

parseDate and getEndDate use local-time APIs, which can shift calendar days. Also, ics should be told these arrays are UTC to avoid reinterpretation as local time.

💡 Proposed fix
-    const parseDate = (date: string): DateArray => {
-      // ISO date string
-      const d = new Date(date)
-      return [d.getFullYear(), d.getMonth() + 1, d.getDate()]
-    }
+    const parseDate = (date: string): DateArray => {
+      const d = new Date(date)
+      return [d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate()]
+    }

@@
-        const nextDay = new Date(y, m - 1, d + 1)
-        return [nextDay.getFullYear(), nextDay.getMonth() + 1, nextDay.getDate()]
+        const nextDay = new Date(Date.UTC(y, m - 1, d + 1))
+        return [nextDay.getUTCFullYear(), nextDay.getUTCMonth() + 1, nextDay.getUTCDate()]
@@
     const eventAttributes: EventAttributes = {
       start: startArray,
+      startInputType: 'utc',
       end: finalEndArray,
+      endInputType: 'utc',
       title: event.title,
#!/bin/bash
# Verify timezone-sensitive APIs and UTC input flags in ICS utility
rg -n -C2 "parseDate|getFullYear|getMonth|getDate|getUTCFullYear|getUTCMonth|getUTCDate|startInputType|endInputType" frontend/src/utils/getIcsFileUrl.ts

Based on learnings, in frontend/src/utils/getIcsFileUrl.ts UTC getters plus startInputType: 'utc' and endInputType: 'utc' are required to preserve correct UTC dates with the ics library.

Also applies to: 16-21, 29-32

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

In `@frontend/src/utils/getIcsFileUrl.ts` around lines 10 - 14, parseDate and
getEndDate currently use local-time getters which can shift calendar days;
update parseDate to use UTC getters (getUTCFullYear, getUTCMonth + 1,
getUTCDate) and adjust getEndDate similarly so both build DateArray in UTC, and
when creating the ics event ensure you pass startInputType: 'utc' and
endInputType: 'utc' so the ics library treats those arrays as UTC. Locate the
functions parseDate and getEndDate and the place where the ics event/options are
constructed and apply these changes.
🧹 Nitpick comments (5)
backend/apps/owasp/models/mixins/committee.py (2)

12-15: Consider adding type annotations for consistency.

The implementation correctly returns ISO strings. For consistency with other mixins (e.g., ProjectIndexMixin.idx_updated_at which has -> str), consider adding type annotations:

♻️ Optional: Add type hints
     `@property`
-    def idx_created_at(self):
+    def idx_created_at(self) -> str | None:
         """Return created at for indexing."""
         return self.created_at.isoformat() if self.created_at else None
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/apps/owasp/models/mixins/committee.py` around lines 12 - 15, The
idx_created_at property lacks a type annotation; update the signature of
idx_created_at to include a return type (use -> Optional[str]) and ensure
Optional is imported from typing if not already present so the method signature
reads idx_created_at(self) -> Optional[str]; keep the implementation returning
self.created_at.isoformat() if present else None and leave the docstring as-is.

32-35: Implementation correctly returns ISO string.

Same suggestion for type annotation consistency:

♻️ Optional: Add type hint
     `@property`
-    def idx_updated_at(self):
+    def idx_updated_at(self) -> str | None:
         """Return updated at for indexing."""
         return self.updated_at.isoformat() if self.updated_at else None
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/apps/owasp/models/mixins/committee.py` around lines 32 - 35, Add a
return type annotation to the idx_updated_at property so its signature
explicitly indicates it returns an optional string (e.g., Optional[str] or str |
None) and import Optional from typing if not already present; update the
property signature def idx_updated_at(self) -> Optional[str]: and keep the
implementation using self.updated_at.isoformat() if self.updated_at else None,
referencing idx_updated_at and updated_at to locate the change.
backend/apps/github/models/mixins/user.py (1)

225-241: Date format inconsistency in nested fields.

idx_issues returns created_at as a Unix timestamp (.timestamp()), while idx_created_at and idx_updated_at return ISO strings (.isoformat()). The same pattern appears in idx_releases with published_at. Consider standardizing nested date fields to ISO format for consistency across the indexing layer.

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

In `@backend/apps/github/models/mixins/user.py` around lines 225 - 241, The nested
date in the issues index is rendered as a Unix timestamp
(created_at.timestamp()) causing inconsistency with other indexers that use ISO
strings; update the code in the idx_issues logic (the list comprehension
returning dicts for self.issues) to use ISO format (created_at.isoformat()) and
mirror this standard for nested date fields elsewhere (e.g., idx_releases
published_at) so that idx_issues, idx_created_at, idx_updated_at and
idx_releases consistently emit ISO8601 strings.
frontend/__tests__/unit/utils/getIcsFileUrl.test.ts (2)

42-45: Keep test fixtures aligned with CalendarEvent required fields.

These fixtures omit title, which weakens contract-level confidence for getIcsFileUrl(event: CalendarEvent).

💡 Minimal fixture alignment
     const eventWithTimestamps = {
+      title: 'Event',
       startDate: '2025-01-01T00:00:00Z',
       endDate: '2025-01-03T00:00:00Z',
     }
@@
     const singleDayEvent = {
+      title: 'Single Day Event',
       startDate: '2025-01-01T00:00:00Z',
       endDate: '2025-01-01T00:00:00Z',
     }

Also applies to: 61-64, 80-83

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

In `@frontend/__tests__/unit/utils/getIcsFileUrl.test.ts` around lines 42 - 45,
The test fixtures for getIcsFileUrl(event: CalendarEvent) are missing the
required title field, weakening the contract coverage; update each fixture
object (e.g., eventWithTimestamps and the other event* variables used in this
test file) to include a valid title string so they conform to CalendarEvent
shape and exercise real inputs for getIcsFileUrl.

39-75: Two UTC/date-array tests are duplicates.

Both tests use identical payloads and assertions, so the second one doesn’t add coverage. Consider merging into one case or changing one input to exercise a distinct timezone scenario.

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

In `@frontend/__tests__/unit/utils/getIcsFileUrl.test.ts` around lines 39 - 75,
The two tests in frontend/__tests__/unit/utils/getIcsFileUrl.test.ts are
duplicates; update the tests that call getIcsFileUrl (and mock createEvent) so
they cover distinct scenarios: either remove the second identical "should
correctly format Unix timestamps into DateArray (UTC conversion)" test and keep
a single UTC-case, or change the second test's eventWithTimestamps to a
non-UTC/timezone-offset input (e.g., '2025-01-01T00:00:00-05:00') and adjust the
expected createEvent DateArray values accordingly; locate the tests by the it
blocks that call getIcsFileUrl and reference the mocked createEvent to implement
the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/__tests__/unit/utils/getGoogleCalendarUrl.test.ts`:
- Around line 26-31: The test case name in the getGoogleCalendarUrl unit test is
misleading—it's labeled "handles Unix timestamps correctly" but passes ISO
string inputs; rename the test description to reflect ISO string handling (e.g.,
"handles ISO timestamp strings correctly" or similar) so it matches the fixture
values used in the getGoogleCalendarUrl test; locate the it(...) block inside
the 'timestamp handling' describe and update the string only.

In `@frontend/src/app/board/`[year]/candidates/page.tsx:
- Around line 36-37: The createdAt/firstOwaspContributionAt handling is
inconsistent with formatDate(string|null): change both field types to string |
null (update the interface/type that declares createdAt and
firstOwaspContributionAt) and remove the runtime numeric-branch (typeof ... ===
'number' and any *1000 logic) from the rendering; instead ensure any incoming
numeric timestamps are converted to ISO strings at the data parsing layer so
render code simply calls formatDate(createdAt) and
formatDate(firstOwaspContributionAt) without number guards.

In `@frontend/src/app/organizations/`[organizationKey]/page.tsx:
- Around line 121-126: The mapped recentReleases currently force-casts
release.publishedAt to string which hides a real GraphQL type (DateTime | null);
update the mapping in the recentReleases transform to explicitly handle
DateTime|null by converting a non-null value to an ISO string (e.g., via new
Date(release.publishedAt).toISOString()) and providing a safe fallback (e.g.,
empty string or null) so the Release type and runtime values align, or
alternatively adjust the Release type to accept DateTime | null and propagate
that change where Release is consumed.

In `@frontend/src/utils/getGoogleCalendarUrl.ts`:
- Around line 23-29: isAllDayEvent uses UTC checks but formatLocalDate uses
local getters, causing date shifts for UTC midnight timestamps; rename
formatLocalDate to formatUTCDate and update its implementation (and all call
sites in this file) to use getUTCFullYear(), getUTCMonth(), and getUTCDate() so
formatting is done in UTC and matches isAllDayEvent (ensure getUTC* getters
replace local getters wherever formatLocalDate was used).

---

Outside diff comments:
In `@backend/tests/apps/github/api/internal/nodes/user_test.py`:
- Around line 80-87: The test fails because UserNode's updated_at resolver
(accessed in the test via field = self._get_field_by_name("updated_at",
UserNode) and field.base_resolver.wrapped_func) is returning a string instead of
a numeric float; update the resolver implementation for updated_at to return the
original numeric value (cast/parse idx_updated_at to float if necessary) so that
calling field.base_resolver.wrapped_func(None, mock_user) yields a float
comparable with math.isclose instead of a string.
- Around line 53-60: Test assumes created_at is a float but the resolver now
returns whatever root.idx_created_at holds (an ISO string from
UserIndexMixin.idx_created_at); update test_created_at_field to set
mock_user.idx_created_at to the ISO-format string you expect and assert equality
(e.g., result == mock_user.idx_created_at) instead of using math.isclose,
locating the field via _get_field_by_name("created_at", UserNode) and calling
field.base_resolver.wrapped_func as before.

In `@frontend/__tests__/a11y/components/Release.a11y.test.tsx`:
- Around line 6-19: The test fixture uses a numeric timestamp for
Release.publishedAt but the ReleaseType defines publishedAt as a string; update
the publishedAt field in the Release fixture (in the Release.a11y.test.tsx file)
to an ISO string (e.g. new Date().toISOString() or a hard-coded ISO date) so it
matches the string type like author.createdAt and satisfies the ReleaseType;
ensure the field name publishedAt in the ReleaseType fixture is the only change.

In `@frontend/__tests__/mockData/mockHomeData.ts`:
- Line 40: Restore the project type for the mock entry with id 'owasp-project-5'
by changing its type field back from an empty string to 'Other' so the UI test
covers the 'Other' project type variant; update the object in mockHomeData.ts
(the entry containing id 'owasp-project-5' and the property type) so
getProjectIcon() still falls through to the correct icon while the label text
"Other" is rendered in tests.

In `@frontend/__tests__/unit/components/Release.test.tsx`:
- Around line 71-76: The test uses Date.now() (a number) for publishedAt but
Release.publishedAt is typed as string; update the mock in Release.test.tsx by
changing the now variable or the publishedAt value in the mockReleases entry
(referencing the mockReleases array and the now constant) to a string
representation (e.g., ISO string or String(now)) so the publishedAt field
matches the ReleaseType string type.

---

Duplicate comments:
In `@frontend/__tests__/unit/components/CardDetailsPage.test.tsx`:
- Around line 1905-1922: The createMilestones helper generates numeric Unix
timestamps for Milestone.createdAt but other fixtures like mockRecentMilestones
use ISO strings; update createMilestones to produce ISO-formatted strings (e.g.,
new Date(...).toISOString()) for createdAt so the type matches
Milestone.createdAt and tests stay consistent; locate the helper function
createMilestones in the test file and replace the numeric timestamp generation
with ISO string generation, ensuring all createdAt usages across tests
(including mockRecentMilestones) are consistent.

In `@frontend/src/utils/getIcsFileUrl.ts`:
- Around line 10-14: parseDate and getEndDate currently use local-time getters
which can shift calendar days; update parseDate to use UTC getters
(getUTCFullYear, getUTCMonth + 1, getUTCDate) and adjust getEndDate similarly so
both build DateArray in UTC, and when creating the ics event ensure you pass
startInputType: 'utc' and endInputType: 'utc' so the ics library treats those
arrays as UTC. Locate the functions parseDate and getEndDate and the place where
the ics event/options are constructed and apply these changes.

---

Nitpick comments:
In `@backend/apps/github/models/mixins/user.py`:
- Around line 225-241: The nested date in the issues index is rendered as a Unix
timestamp (created_at.timestamp()) causing inconsistency with other indexers
that use ISO strings; update the code in the idx_issues logic (the list
comprehension returning dicts for self.issues) to use ISO format
(created_at.isoformat()) and mirror this standard for nested date fields
elsewhere (e.g., idx_releases published_at) so that idx_issues, idx_created_at,
idx_updated_at and idx_releases consistently emit ISO8601 strings.

In `@backend/apps/owasp/models/mixins/committee.py`:
- Around line 12-15: The idx_created_at property lacks a type annotation; update
the signature of idx_created_at to include a return type (use -> Optional[str])
and ensure Optional is imported from typing if not already present so the method
signature reads idx_created_at(self) -> Optional[str]; keep the implementation
returning self.created_at.isoformat() if present else None and leave the
docstring as-is.
- Around line 32-35: Add a return type annotation to the idx_updated_at property
so its signature explicitly indicates it returns an optional string (e.g.,
Optional[str] or str | None) and import Optional from typing if not already
present; update the property signature def idx_updated_at(self) ->
Optional[str]: and keep the implementation using self.updated_at.isoformat() if
self.updated_at else None, referencing idx_updated_at and updated_at to locate
the change.

In `@frontend/__tests__/unit/utils/getIcsFileUrl.test.ts`:
- Around line 42-45: The test fixtures for getIcsFileUrl(event: CalendarEvent)
are missing the required title field, weakening the contract coverage; update
each fixture object (e.g., eventWithTimestamps and the other event* variables
used in this test file) to include a valid title string so they conform to
CalendarEvent shape and exercise real inputs for getIcsFileUrl.
- Around line 39-75: The two tests in
frontend/__tests__/unit/utils/getIcsFileUrl.test.ts are duplicates; update the
tests that call getIcsFileUrl (and mock createEvent) so they cover distinct
scenarios: either remove the second identical "should correctly format Unix
timestamps into DateArray (UTC conversion)" test and keep a single UTC-case, or
change the second test's eventWithTimestamps to a non-UTC/timezone-offset input
(e.g., '2025-01-01T00:00:00-05:00') and adjust the expected createEvent
DateArray values accordingly; locate the tests by the it blocks that call
getIcsFileUrl and reference the mocked createEvent to implement the change.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4882665 and 5169ded.

⛔ Files ignored due to path filters (8)
  • frontend/src/types/__generated__/boardQueries.generated.ts is excluded by !**/__generated__/**
  • frontend/src/types/__generated__/chapterQueries.generated.ts is excluded by !**/__generated__/**
  • frontend/src/types/__generated__/committeeQueries.generated.ts is excluded by !**/__generated__/**
  • frontend/src/types/__generated__/graphql.ts is excluded by !**/__generated__/**
  • frontend/src/types/__generated__/homeQueries.generated.ts is excluded by !**/__generated__/**
  • frontend/src/types/__generated__/projectQueries.generated.ts is excluded by !**/__generated__/**
  • frontend/src/types/__generated__/snapshotQueries.generated.ts is excluded by !**/__generated__/**
  • frontend/src/types/__generated__/userQueries.generated.ts is excluded by !**/__generated__/**
📒 Files selected for processing (72)
  • backend/apps/github/api/internal/nodes/user.py
  • backend/apps/github/models/mixins/user.py
  • backend/apps/owasp/api/internal/nodes/chapter.py
  • backend/apps/owasp/api/internal/nodes/committee.py
  • backend/apps/owasp/api/internal/nodes/common.py
  • backend/apps/owasp/models/mixins/chapter.py
  • backend/apps/owasp/models/mixins/committee.py
  • backend/apps/owasp/models/mixins/project.py
  • backend/tests/apps/github/api/internal/nodes/user_test.py
  • backend/tests/apps/github/models/mixins/user_test.py
  • backend/tests/apps/owasp/models/mixins/chapter_test.py
  • backend/tests/apps/owasp/models/mixins/committee_test.py
  • backend/tests/apps/owasp/models/mixins/project_test.py
  • frontend/__tests__/a11y/components/CalendarButton.a11y.test.tsx
  • frontend/__tests__/a11y/components/ItemCardList.a11y.test.tsx
  • frontend/__tests__/a11y/components/Milestones.a11y.test.tsx
  • frontend/__tests__/a11y/components/RecentIssues.a11y.test.tsx
  • frontend/__tests__/a11y/components/RecentPullRequests.a11y.test.tsx
  • frontend/__tests__/a11y/components/RecentRelease.a11y.test.tsx
  • frontend/__tests__/a11y/components/Release.a11y.test.tsx
  • frontend/__tests__/a11y/components/SnapshotCard.a11y.test.tsx
  • frontend/__tests__/e2e/data/mockHomeData.ts
  • frontend/__tests__/mockData/mockChapterData.ts
  • frontend/__tests__/mockData/mockChapterDetailsData.ts
  • frontend/__tests__/mockData/mockCommitteeData.ts
  • frontend/__tests__/mockData/mockCommitteeDetailsData.ts
  • frontend/__tests__/mockData/mockContributeData.ts
  • frontend/__tests__/mockData/mockHomeData.ts
  • frontend/__tests__/mockData/mockOrganizationData.ts
  • frontend/__tests__/mockData/mockProgramData.ts
  • frontend/__tests__/mockData/mockProjectDetailsData.ts
  • frontend/__tests__/mockData/mockRepositoryData.ts
  • frontend/__tests__/mockData/mockSnapshotData.ts
  • frontend/__tests__/mockData/mockUserDetails.ts
  • frontend/__tests__/unit/components/CalendarButton.test.tsx
  • frontend/__tests__/unit/components/CardDetailsPage.test.tsx
  • frontend/__tests__/unit/components/ItemCardList.test.tsx
  • frontend/__tests__/unit/components/Milestones.test.tsx
  • frontend/__tests__/unit/components/MultiSearch.test.tsx
  • frontend/__tests__/unit/components/ProgramCard.test.tsx
  • frontend/__tests__/unit/components/RecentIssues.test.tsx
  • frontend/__tests__/unit/components/RecentPullRequests.test.tsx
  • frontend/__tests__/unit/components/RecentRelease.test.tsx
  • frontend/__tests__/unit/components/Release.test.tsx
  • frontend/__tests__/unit/components/SingleModuleCard.test.tsx
  • frontend/__tests__/unit/components/SnapshotCard.test.tsx
  • frontend/__tests__/unit/pages/EditModule.test.tsx
  • frontend/__tests__/unit/pages/EditProgram.test.tsx
  • frontend/__tests__/unit/pages/MyMentorship.test.tsx
  • frontend/__tests__/unit/pages/Organization.test.tsx
  • frontend/__tests__/unit/pages/Snapshots.test.tsx
  • frontend/__tests__/unit/utils/dateFormatter.test.ts
  • frontend/__tests__/unit/utils/getGoogleCalendarUrl.test.ts
  • frontend/__tests__/unit/utils/getIcsFileUrl.test.ts
  • frontend/src/app/board/[year]/candidates/page.tsx
  • frontend/src/app/organizations/[organizationKey]/page.tsx
  • frontend/src/components/ItemCardList.tsx
  • frontend/src/components/Milestones.tsx
  • frontend/src/types/calendar.ts
  • frontend/src/types/chapter.ts
  • frontend/src/types/committee.ts
  • frontend/src/types/issue.ts
  • frontend/src/types/mentorship.ts
  • frontend/src/types/milestone.ts
  • frontend/src/types/project.ts
  • frontend/src/types/pullRequest.ts
  • frontend/src/types/release.ts
  • frontend/src/types/user.ts
  • frontend/src/utils/dateFormatter.ts
  • frontend/src/utils/getGoogleCalendarUrl.ts
  • frontend/src/utils/getIcsFileUrl.ts
  • frontend/src/utils/utility.ts
💤 Files with no reviewable changes (1)
  • frontend/src/types/milestone.ts
✅ Files skipped from review due to trivial changes (1)
  • frontend/tests/unit/components/RecentRelease.test.tsx
🚧 Files skipped from review as they are similar to previous changes (17)
  • frontend/tests/unit/pages/MyMentorship.test.tsx
  • frontend/src/components/ItemCardList.tsx
  • frontend/tests/a11y/components/RecentPullRequests.a11y.test.tsx
  • frontend/src/components/Milestones.tsx
  • frontend/tests/unit/components/SnapshotCard.test.tsx
  • frontend/tests/unit/components/SingleModuleCard.test.tsx
  • frontend/tests/unit/pages/EditProgram.test.tsx
  • frontend/tests/unit/components/MultiSearch.test.tsx
  • frontend/tests/unit/components/ItemCardList.test.tsx
  • frontend/tests/mockData/mockSnapshotData.ts
  • frontend/tests/a11y/components/Milestones.a11y.test.tsx
  • frontend/src/types/issue.ts
  • frontend/src/utils/dateFormatter.ts
  • frontend/src/types/calendar.ts
  • frontend/tests/mockData/mockProgramData.ts
  • frontend/tests/unit/components/ProgramCard.test.tsx
  • frontend/tests/mockData/mockUserDetails.ts

@Mr-Rahul-Paul Mr-Rahul-Paul marked this pull request as draft March 1, 2026 14:28
coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 1, 2026
@Mr-Rahul-Paul Mr-Rahul-Paul marked this pull request as ready for review March 1, 2026 15:01
@Mr-Rahul-Paul Mr-Rahul-Paul changed the title Refactor dateFormatter to strictly accept numeric Unix timestamps Refactor dateFormatter to use ISO date strings as timestamps Mar 1, 2026
@Mr-Rahul-Paul Mr-Rahul-Paul marked this pull request as draft March 1, 2026 20:42
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="frontend/src/app/board/[year]/candidates/page.tsx">

<violation number="1" location="frontend/src/app/board/[year]/candidates/page.tsx:216">
P2: Repository list is no longer limited to 5 items; `.slice(1)` now renders all remaining repos while the header still says "Top 5 Active Repositories".</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 1, 2026
@Mr-Rahul-Paul Mr-Rahul-Paul marked this pull request as ready for review March 1, 2026 21:46
@Mr-Rahul-Paul
Copy link
Contributor Author

@kasya PR is ready for review

Changes

  • Backend: Those 8 backend functions now also return ISO date strings instead of numeric Unix timestamps
  • Frontend: dateFormatter.ts now strictly accepts string | null instead of numeric Unix timestamps
  • Tests: Updated both backend and frontend tests to account for the ISO string format
  • E2E tests also changed
  • ran make check-test , works.

Copy link
Collaborator

@kasya kasya left a comment

Choose a reason for hiding this comment

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

@Mr-Rahul-Paul Hi! Thank you so much for working on this! Great job 👍🏼

I pushed a small update to resolve a conflict in one of the test files.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 8, 2026

@kasya kasya enabled auto-merge March 8, 2026 01:09
@codecov
Copy link

codecov bot commented Mar 8, 2026

Codecov Report

❌ Patch coverage is 94.73684% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 99.43%. Comparing base (ac5e42d) to head (6421187).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
frontend/src/components/Milestones.tsx 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3857      +/-   ##
==========================================
- Coverage   99.43%   99.43%   -0.01%     
==========================================
  Files         519      519              
  Lines       16145    16146       +1     
  Branches     2206     2207       +1     
==========================================
  Hits        16054    16054              
  Misses         69       69              
- Partials       22       23       +1     
Flag Coverage Δ
backend 99.70% <100.00%> (ø)
frontend 98.61% <0.00%> (-0.03%) ⬇️

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

Files with missing lines Coverage Δ
backend/apps/github/api/internal/nodes/user.py 100.00% <100.00%> (ø)
backend/apps/github/models/mixins/user.py 100.00% <100.00%> (ø)
backend/apps/owasp/api/internal/nodes/chapter.py 100.00% <100.00%> (ø)
backend/apps/owasp/api/internal/nodes/committee.py 100.00% <100.00%> (ø)
backend/apps/owasp/api/internal/nodes/common.py 100.00% <100.00%> (ø)
backend/apps/owasp/models/mixins/chapter.py 100.00% <100.00%> (ø)
backend/apps/owasp/models/mixins/committee.py 100.00% <100.00%> (ø)
backend/apps/owasp/models/mixins/project.py 100.00% <100.00%> (ø)
...d/src/app/organizations/[organizationKey]/page.tsx 100.00% <ø> (ø)
frontend/src/components/ItemCardList.tsx 100.00% <ø> (ø)
... and 1 more

Continue to review full report in Codecov by Sentry.

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

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

@kasya kasya added this pull request to the merge queue Mar 8, 2026
Merged via the queue into OWASP:main with commit 70a5053 Mar 8, 2026
36 of 38 checks passed
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.

Enforce number type for date formatter utilities

3 participants