feat: add Markdown export for assessment reports - #26
Conversation
Adds a pure assessmentToMarkdown() helper (lib/exportMarkdown.ts) that serializes an AssessmentResult + the GitHub profile it was generated from into a clean, shareable Markdown report: profile header, executive summary, hirability verdict, career timeline, SWOT, metrics, advanced AI insights, per-repo assessments (including keyHighlights/redFlags, which existed on the type but weren't surfaced in the UI before), the full detailed report, and (developer mode only) the mentorship plan. Wires up a small 'Export as Markdown' button next to the existing 'Compare Candidates' button on the assessment page. It's visible in both Employer and Developer mode (unlike Compare, which is employer-only), since the issue calls out both audiences. Clicking it builds a Blob client-side and triggers a download -- no server involved, consistent with the app's 100%-client-side architecture. Filename pattern: gitdeep-<username>-<mode>-report.md.
|
@ishhwarrii is attempting to deploy a commit to the Yuvraj Sarathe's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
🧙 Sourcery has finished reviewing your pull request! Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe assessment page now exports current GitHub and AI assessment data as a mode-specific Markdown file, with formatted report sections, filename sanitization, browser download handling, completion feedback, error alerts, and Vitest coverage. ChangesMarkdown assessment export
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant AssessmentPage
participant assessmentToMarkdown
participant downloadMarkdown
participant Browser
AssessmentPage->>assessmentToMarkdown: generate Markdown from current assessment
assessmentToMarkdown-->>AssessmentPage: return report content
AssessmentPage->>downloadMarkdown: pass filename and content
downloadMarkdown->>Browser: trigger file download
Browser-->>AssessmentPage: complete export and show feedback
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
lib/exportMarkdown.test.tsOops! Something went wrong! :( ESLint: 9.39.1 TypeError: Converting circular structure to JSON package.jsonOops! Something went wrong! :( ESLint: 9.39.1 TypeError: Converting circular structure to JSON vitest.config.tsOops! Something went wrong! :( ESLint: 9.39.1 TypeError: Converting circular structure to JSON 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. Comment |
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The
assessmentToMarkdownhelper currently embedsnew Date().toLocaleString()directly, which makes output non-deterministic and harder to test; consider passing a generated timestamp into the function or allowing an optionalgeneratedAtoverride for stable fixture-based tests. - Using
alertinhandleExportMarkdownis a bit jarring relative to the rest of the UI; consider surfacing export errors via an inline toast or status message in the existing layout instead of a blocking browser alert.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `assessmentToMarkdown` helper currently embeds `new Date().toLocaleString()` directly, which makes output non-deterministic and harder to test; consider passing a generated timestamp into the function or allowing an optional `generatedAt` override for stable fixture-based tests.
- Using `alert` in `handleExportMarkdown` is a bit jarring relative to the rest of the UI; consider surfacing export errors via an inline toast or status message in the existing layout instead of a blocking browser alert.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
app/assessment/page.tsx (1)
432-448: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAnnounce the transient "Exported!" state to assistive tech.
The label swap is purely visual —
aria-labelstays constant, so screen reader users get no confirmation that the download fired. A small live region (or a dynamicaria-label) closes the gap.♻️ Proposed change
<button onClick={handleExportMarkdown} - aria-label="Export this assessment report as a Markdown file" + aria-label={exported ? 'Report exported as Markdown' : 'Export this assessment report as a Markdown file'} className="w-full flex items-center justify-center gap-2 bg-[`#21262D`] hover:bg-[`#30363D`] border border-[`#30363D`] text-[`#C9D1D9`] text-xs font-bold py-3 px-4 rounded-lg transition-colors uppercase tracking-widest" > @@ </button> + <span role="status" aria-live="polite" className="sr-only"> + {exported ? 'Report exported as Markdown' : ''} + </span>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/assessment/page.tsx` around lines 432 - 448, Update the export control around handleExportMarkdown so the transient exported state is announced to assistive technologies. Add a dynamically updated aria-label or a small polite live region tied to exported, while preserving the existing visual label swap and button behavior.lib/exportMarkdown.ts (1)
270-280: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winSchedule
revokeObjectURLfor the next tick.Revoking the blob URL immediately after
link.click()can cause Safari/WebKit downloads to fail because the browser may still need the object URL in the current tick. Move cleanup intosetTimeout(..., 0)so the download can start before revocation.♻️ Proposed change
document.body.appendChild(link); link.click(); document.body.removeChild(link); - URL.revokeObjectURL(url); + setTimeout(() => URL.revokeObjectURL(url), 0); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/exportMarkdown.ts` around lines 270 - 280, Update downloadMarkdown so URL.revokeObjectURL runs inside a zero-delay setTimeout after the link is clicked and removed, allowing the download to start before cleanup.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/exportMarkdown.ts`:
- Around line 45-48: Update formatAccountAge to detect an invalid parsed
createdAt date before calculating the year difference, and fall back to 0 years
for unparsable values while preserving the existing singular/plural formatting.
---
Nitpick comments:
In `@app/assessment/page.tsx`:
- Around line 432-448: Update the export control around handleExportMarkdown so
the transient exported state is announced to assistive technologies. Add a
dynamically updated aria-label or a small polite live region tied to exported,
while preserving the existing visual label swap and button behavior.
In `@lib/exportMarkdown.ts`:
- Around line 270-280: Update downloadMarkdown so URL.revokeObjectURL runs
inside a zero-delay setTimeout after the link is clicked and removed, allowing
the download to start before cleanup.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: ac27deeb-0ab7-4988-be94-41e5ec0afcc6
📒 Files selected for processing (2)
app/assessment/page.tsxlib/exportMarkdown.ts
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
|
@ishhwarrii please follow the given PR template and also link the issue this PR is for. |
|
@Yuvraj-Sarathe Done! I've updated the PR to follow the required template and linked the related issue. Thanks for the reminder! |
Yuvraj-Sarathe
left a comment
There was a problem hiding this comment.
Make sure linting tests are passed. You can check the exact logs from workflow in conversation tab or check the issue on exact code block in Files changed tab.
🔗 Related Issue
Closes #23
📝 Description of Changes
What's changed
assessmentToMarkdown()helper to serialize assessment data into a clean Markdown format.🏷️ Proposed Labels
📂 Core Files Changed
lib/exportMarkdown.ts📸 Verification & Screenshots
UI/UX (User Interface / User Experience — how it looks and feels):
.mdfile.CI/CD (Continuous Integration / Continuous Deployment — the automated build/test pipeline):
🤖 AI Assistance Declaration
Did you use an AI tool to write or assist with this code OR Pull Request?
Which AI Model did you use?
Which Platform/Tool?
What exactly did the AI do?
What exactly did YOU do?
What is the advantage of using this AI approach here?
✅ The "I Swear I Didn't Break Anything" Pledge
Summary by CodeRabbit
New Features
Tests