Add age calculation API endpoint#14
Conversation
This PR adds a new REST API endpoint at /api/age that calculates a person's age from their date of birth. Features: - Calculate current age or age at a specific date - Returns age in multiple formats (readable, decimal, detailed) - Proper input validation and error handling - RESTful design following existing API patterns Fixes #6 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Airyland <airyland@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting
| // Parse birthdate | ||
| const birthDate = new Date(birthDateParam) |
There was a problem hiding this comment.
Parse birth dates without pinning timezone
The handler builds birthDate with new Date(birthDateParam) and then feeds it into calculateAge, which uses getFullYear()/getMonth()/getDate() and therefore interprets the date in the server’s local timezone. When the runtime is not configured for UTC, a request such as birthdate=2000-01-01 will be parsed as midnight UTC and show up as Dec 31 in UTC−05:00, causing the reported age to be off by a day (and possibly the month). Consider parsing the incoming YYYY-MM-DD string with Date.UTC or appending a T00:00:00 offset so the calendar date is stable regardless of server timezone.
Useful? React with 👍 / 👎.
Code Review - PR #14: Add age calculation API endpointThank you for this contribution! This is a well-structured PR that adds a clean REST API endpoint. Here is my detailed review: StrengthsCode Quality
Error Handling
Issues and Recommendations1. Critical: Date Parsing Timezone IssueLocation: app/api/age/route.ts:22, 37 The current code uses new Date(dateString), which has timezone problems. new Date("2007-01-15") parses as midnight UTC, but then Date methods like .getMonth() and .getDate() use local timezone, causing off-by-one day errors for users in certain timezones. Example Bug:
Recommended Fix: Create a helper function that parses YYYY-MM-DD strings by splitting and using the Date constructor with individual components: new Date(year, month - 1, day, 0, 0, 0, 0). This ensures dates are interpreted as local midnight, avoiding timezone confusion. 2. Bug: Hours/Minutes/Seconds CalculationLocation: app/api/age/route.ts:66 When targetDateParam is not provided, targetDate is new Date() with the current time. The time component calculations will be inconsistent because birth dates are at midnight but "now" has a time. Recommendation: Since this is an age API, normalize both dates to midnight for consistency. The README examples show 0:00:00 for time, suggesting midnight normalization is intended. 3. Validation: Better Date Format CheckLocation: app/api/age/route.ts:25, 40 Current validation only checks if parsing succeeds, which accepts formats like "2007/01/15" or "Jan 15 2007". Recommendation: Add explicit YYYY-MM-DD format validation using a regex pattern to ensure consistent input format. 4. Code Duplication: DRY PrincipleLocation: app/api/age/route.ts:20-47 The date parsing and validation logic is duplicated for birthdate and targetDate. Extract this into a reusable helper function to reduce duplication and improve maintainability. 5. Decimal Age Calculation PrecisionLocation: lib/age-calculator.ts:56 Using 365.25 for decimal age is reasonable but approximate. The README should clarify that decimalAge uses an average year length (365.25 days) and is not exact for specific date ranges. 6. Security: Consider Rate LimitingFor production, consider adding rate limiting to prevent abuse. Use middleware or a library to limit requests per IP. This is standard practice for public APIs. Not blocking, but good practice for production. 7. Test Coverage - IMPORTANTMissing: No tests for this new functionality Recommendation: Add tests for:
This is important for ensuring correctness and preventing regressions. 8. Minor: Response ConsistencyLocation: app/api/age/route.ts:76 The formatted.readable field is computed inline in the route handler, while other formats come from age.formatted. Move all formatting to calculateAge function for consistency. 9. Documentation: API Response SchemaLocation: app/api/age/README.md Great documentation! Minor suggestions:
Performance and SecurityPerformance: No major concerns. Calculations are O(1), no database queries or external API calls, small response size. Security: Good security posture overall. No SQL injection, XSS, file system access, or code execution risks. Input validation is present. Summary and Action ItemsMust Fix (Blocking):
Should Fix (Recommended):
Nice to Have:
Overall AssessmentRating: 4/5 stars This is a solid, well-structured PR with good code quality and excellent documentation. The main concern is the timezone bug, which could cause incorrect results for users in certain timezones. Once that is fixed and tests are added, this will be production-ready. The code follows Next.js best practices and has good error handling. Great work overall! Let me know if you would like help with any of these items or have questions about the feedback! |
|
|
Summary
Testing
|
Pull Request Review: Age Calculation API EndpointThank you for this comprehensive PR! The implementation is well-structured and demonstrates strong attention to detail. Below is my detailed review covering code quality, potential issues, performance, security, and test coverage. ✅ Strengths1. Excellent Code Organization
2. Strong Input Validation
3. Good Documentation
4. Test Coverage
🐛 Potential Bugs & IssuesCritical: Redundant NaN Check (route.ts:73-80)After parsing targetDate with parseIsoDateWithOffset, there is an unreachable isNaN check. The function already validates the date and throws errors for invalid dates, so this check will never catch invalid dates. Location: app/api/age/route.ts:73-80 Recommendation: Remove this redundant check since it is dead code. Medium: Ambiguous UTC Offset Parsing (date-utils.ts:30-41)The logic that interprets numeric offsets is potentially confusing. Values ≤14 are treated as hours (e.g., -5 → -300 minutes) while values >14 are treated as minutes (e.g., 45 → 45 minutes). This creates ambiguity around the value 14. Users might expect 60 to mean 1 hour, but it means 60 minutes. Location: app/api/age/date-utils.ts:37-40 Recommendation: Document this behavior clearly in the API documentation, consider requiring the ±HH:MM format for clarity, or always treat numeric values as minutes only. Low: Year/Month Calculation Edge Case (age-calculator.ts:31-36)When targetDay < birthDay, the month is decremented. However, if this happens in January (month 0), the adjustment wraps to December (month 11) but does not decrement the year. This might be correct depending on the intended behavior, but it is worth verifying. Location: lib/age-calculator.ts:31-36 Example scenario: Birth 2020-02-29, Target 2021-01-15. Expected: 0 years, 10 months, 17 days (approximately) 🔒 Security ConsiderationsGood Security Practices:
Minor Concern: Error Logging (route.ts:114)The API logs errors to console, which is good for debugging but could expose sensitive information in production logs if unexpected errors occur. Recommendation: Ensure production logging is properly configured to sanitize error messages. |
⚡ Performance ConsiderationsExcellent Performance:
Minor Optimization Opportunity:The formattedCurl() function in api-tester-client.tsx is recalculated on every render. Consider memoizing it with useMemo hook. Location: app/[locale]/api/age/api-tester-client.tsx:73-83 🧪 Test CoverageStrong Test Foundation:
Missing Test Cases:
Recommendation: Add integration tests using Next.js testing utilities or a tool like Vitest/Jest with React Testing Library. 📝 Code Quality & Best PracticesExcellent:
Minor Suggestions:
🎨 UI/UX ObservationsExcellent UI Implementation:
Minor Enhancement:Consider adding client-side validation for the input fields (e.g., HTML5 type='date' or pattern validation) to provide immediate feedback before API calls. 📦 Dependencies & Build
|
🎯 Summary & RecommendationsPriority Fixes:
Recommended Enhancements:
Overall Assessment:This is a high-quality PR with well-structured code, comprehensive documentation, and good test coverage. The implementation is production-ready with minor improvements recommended. The UTC offset handling is particularly well-done, and the interactive API tester is an excellent addition for documentation. Recommendation: Approve with minor revisions ✅ Great work! 🎉 Code ReferencesIssues identified:
|
This PR adds a new REST API endpoint at /api/age that calculates a person's age from their date of birth.
Features
Fixes #6
Generated with Claude Code