Skip to content

Conversation

@SethFalco
Copy link
Member

@SethFalco SethFalco commented Oct 18, 2025

In the resume.handlebars, we had a couple if if/else if blocks, where we were keeping support for some outdated property names.

For example, work.name used to be work.company. Some resumes in the wild still use the old name, so we've kept support.

However, it's a little messy and error-prone to maintain this in the view, this should probably be in a preprocessing step that runs before we start rendering the resume in the first place.

This introduces that preprocessing step, #upgradeOutdatedResume. This will rewrite outdated properties to whatever it should look like in the v1.0.0 specifications. Ofc, properties that are not known to use can not be acted on.

This should handle is gracefully, but does also log a warning guiding developers to read the schema.

Here is what I see when I build a resume that has work.company instead of work.name:

⚠️  Resume is written against an outdated version of the JSON Resume schema.
⚠️  This will still work, but you should consider updating your resume.
⚠️  See: https://jsonresume.org/schema

Done! Find your new .html resume at:
 /home/seth/Documents/repos/jsonresume/jsonresume-theme-class/resume.html

We originally only maintained 4 fallbacks, which happen to be the ones this resume was using by name before. However, I'd actually gone back in the release history and support for upgrading old property names.

I didn't add everything, but I'm prepared to add more if we encounter any other problems regarding compatibility.

Chores

  • Runs a formatter over some of the files.

Summary by CodeRabbit

  • New Features

    • Added support for upgrading legacy resume formats to the latest schema, enabling compatibility with older resume data with automatic conversion warnings.
    • Enhanced resume template rendering with improved metadata handling and better-structured sections for work, education, volunteer, and skills presentation.
  • Chores

    • Updated TypeScript configuration settings.

@coderabbitai
Copy link

coderabbitai bot commented Oct 18, 2025

Walkthrough

The PR modernizes the JSON Resume theme by introducing schema migration logic to automatically upgrade outdated resume formats, comprehensively refactoring the HTML template for consistency and clarity, updating test fixtures, and adjusting TypeScript configuration. No behavioral breaking changes; backward compatibility is maintained through the upgrade mechanism.

Changes

Cohort / File(s) Summary
Schema Migration & Rendering
index.js
Introduces upgradeOutdatedResume() internal function to migrate resume objects to latest JSON Resume schema (updating field names like companyname, pictureimage, mapping hobbiesinterests, etc.). Modified render() to invoke upgrade and log warnings. Refactored profile processing with guarded optional-chaining access.
Template Restructuring
resume.handlebars
Significant overhaul of resume HTML template: consolidated metadata handling in head, unified image/OG tag logic, modernized contact/website section structure, reorganized work/education/volunteer/profiles/skills sections with consistent nested-item rendering, improved markdown support, and flattened conditional nesting for clarity.
Documentation Formatting
README.md
Minor formatting: changed Markdown bullet list markers from - to + under Markdown section; removed trailing whitespace from Preview header. No semantic impact.
Test & Configuration Updates
test/fixture.resume.json
Changed work entry field from name to company to align with schema migration expectations.
TypeScript Config
tsconfig.json
Reformatted lib option to multiline array containing "es2021"; added noImplicitAny: false under compilerOptions.

Sequence Diagram

sequenceDiagram
    participant User
    participant render as render()
    participant upgrade as upgradeOutdatedResume()
    participant template as Handlebars Template
    
    User ->> render: render(outdatedResume)
    render ->> upgrade: upgradeOutdatedResume(resume)
    activate upgrade
    upgrade ->> upgrade: Migrate field names<br/>(company→name, picture→image, etc.)
    upgrade -->> render: returns boolean (upgraded?)
    deactivate upgrade
    
    alt Upgrade occurred
        render ->> render: log warning
    end
    
    render ->> template: pass upgraded resume
    template -->> render: HTML output
    render -->> User: rendered resume
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

The PR spans multiple file types with varying complexity: the schema migration logic is new and requires validation; the template restructuring is extensive but follows consistent patterns throughout sections; config and fixture changes are straightforward. The heterogeneous nature of edits (logic, template, config) demands separate reasoning per cohort, though individual changes within cohorts are largely repetitive or conventional.

Possibly related PRs

Poem

🐰 Hops through fields with names anew,
Company, image, hobbies too—
The schema blooms, the templates gleam,
Resumes now flow like carrot cream. 🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "chore: add upgrade step while processing resume" directly and accurately captures the primary change in the changeset. The core modification is the introduction of the upgradeOutdatedResume() function in index.js, which preprocesses resume objects to update legacy property names to match the current JSON Resume schema before rendering. The title precisely describes this—an upgrade step being added during resume processing. The title is concise, specific enough for context, uses the appropriate "chore:" prefix for maintenance work, and avoids vague terminology. While supporting changes exist (template restructuring, fixture updates, config adjustments), they all serve to integrate this upgrade step, making the title appropriately capture the main objective.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

❤️ Share

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

@SethFalco SethFalco merged commit 489df61 into jsonresume:main Oct 18, 2025
2 checks passed
@SethFalco SethFalco deleted the clean-up branch October 18, 2025 01:26
Copy link

@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

🧹 Nitpick comments (1)
tsconfig.json (1)

14-14: Consider re-enabling noImplicitAny for better type safety.

Setting noImplicitAny: false allows implicit any types, which can mask type errors and reduce the benefits of TypeScript's type checking. Unless there's a specific reason for disabling this (e.g., gradual migration), consider keeping it enabled or adding a comment explaining the rationale.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fb4446e and fdd638c.

📒 Files selected for processing (5)
  • README.md (2 hunks)
  • index.js (3 hunks)
  • resume.handlebars (1 hunks)
  • test/fixture.resume.json (1 hunks)
  • tsconfig.json (1 hunks)
🔇 Additional comments (12)
tsconfig.json (1)

6-8: LGTM!

Formatting change to multiline array is consistent and improves readability.

README.md (1)

46-47: LGTM!

These are trivial Markdown formatting changes (list marker style and trailing whitespace) with no semantic impact.

Also applies to: 61-61

index.js (6)

78-92: Well-documented upgrade function.

The JSDoc clearly explains the purpose, parameters, return value, and mutation behavior. The references to specific schema releases are helpful for understanding the migration history.


95-128: LGTM: Basics-level migrations look correct.

The migration logic properly:

  • Preserves existing new-format fields with !resume.basics.field checks
  • Handles the firstName/lastNamename concatenation gracefully
  • Maps all the common legacy field names to their v1.0.0 equivalents

The logic is defensive and won't overwrite manually migrated fields.


130-160: LGTM: Array entry migrations are well-structured.

The migrations for work, volunteer, and publications entries:

  • Properly iterate arrays with guards (Array.isArray())
  • Use safe property access with optional chaining (work?.company)
  • Preserve existing new-format fields
  • Track upgrades correctly

194-196: LGTM: Clean integration with helpful warning.

The upgrade is performed early (before any template processing), and the warning message is clear and actionable, directing users to the schema documentation.


198-224: LGTM: Improved profile processing with proper guards.

The refactored profile processing:

  • Uses defensive checks with Array.isArray(resume.basics?.profiles)
  • Properly scopes the profiles destructuring
  • Maintains the existing xTwitter handle extraction logic

This prevents potential runtime errors when basics or profiles is undefined or not an array.


167-179: The review comment is based on incorrect assumptions about the schema history and should be disregarded.

v0.0.12 schema for languages already uses "language" and "fluency" fields, not "name" and "level". The migration code correctly maps namelanguage and levelfluency to upgrade from even older pre-v0.0.12 versions to the v0.0.12+ format. The mappings are not backwards—they represent a forward upgrade to the current schema standard.

Likely an incorrect or invalid review comment.

resume.handlebars (4)

8-45: LGTM: Well-structured head metadata.

The head section properly:

  • Provides fallback title when basics.name is missing
  • Populates Open Graph and Twitter Card metadata
  • Guards all optional fields with conditionals
  • Includes proper charset, viewport, and accessibility attributes

49-116: LGTM: Basics section aligned with v1.0.0 schema.

The basics section correctly:

  • Uses name and label fields (lines 51-54)
  • References url instead of legacy website (line 62)
  • Guards the profiles section with profiles.length (line 89)
  • Provides fallback rendering (e.g., URL shown when username missing, lines 101-105)

118-164: LGTM: Work section uses correct v1.0.0 schema fields.

The work section correctly uses:

  • name field for the company/organization name (lines 123-127)
  • url instead of legacy website (lines 142-146)
  • Proper guards for all optional fields
  • Markdown rendering for summary and highlights

This aligns with the upgrade logic in index.js that converts legacy companyname.


166-359: LGTM: Remaining sections well-structured and schema-compliant.

All remaining sections (volunteer, education, skills, languages, interests, references):

  • Use proper v1.0.0 schema field names (e.g., language/fluency on lines 306-312 instead of legacy alternatives)
  • Include appropriate guards for optional content
  • Follow consistent rendering patterns
  • Properly use the markdown helper for rich text fields

The template comprehensively covers all JSON Resume sections with clean, maintainable markup.

"work": [
{
"name": "JSON Resume",
"company": "JSON Resume",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Test fixture uses outdated schema format.

This change introduces an inconsistency. The fixture is being changed to use the OLD schema field "company" instead of the NEW v1.0.0 schema field "name". This is backwards because:

  1. Line 2 explicitly references the v1.0.0 schema: "$schema": "https://raw.githubusercontent.com/jsonresume/resume-schema/v1.0.0/schema.json"
  2. The upgrade logic in index.js (lines 132-135) converts companyname (treating company as legacy)
  3. The template resume.handlebars (lines 123-127) expects the name field

Test fixtures should demonstrate the current/correct schema format, not legacy formats that require upgrading.

Apply this diff to use the correct v1.0.0 schema field:

-      "company": "JSON Resume",
+      "name": "JSON Resume",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"company": "JSON Resume",
"name": "JSON Resume",
🤖 Prompt for AI Agents
In test/fixture.resume.json around line 30, the fixture uses the legacy field
"company" instead of the v1.0.0 schema field "name"; update the JSON fixture to
replace the "company" key with "name" (preserve the same value "JSON Resume") so
the fixture matches the declared schema and the template/upgrade logic
expectations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant