From ba28cbbe2df31e0730d4bbba643bbce5c9d3857a Mon Sep 17 00:00:00 2001 From: Frank Li Date: Tue, 5 May 2026 12:08:34 +0800 Subject: [PATCH 1/7] fix(builder): allow empty lines in Additional Info textareas (#763) --- apps/frontend/components/builder/forms/additional-form.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/components/builder/forms/additional-form.tsx b/apps/frontend/components/builder/forms/additional-form.tsx index 8e9398e80..37f2726da 100644 --- a/apps/frontend/components/builder/forms/additional-form.tsx +++ b/apps/frontend/components/builder/forms/additional-form.tsx @@ -17,7 +17,7 @@ export const AdditionalForm: React.FC = ({ data, onChange } // Helper to handle array conversions (text -> string[]) const handleArrayChange = (field: keyof AdditionalInfo, value: string) => { // Split by newlines only (preserving spaces within items) - const items = value.split('\n').filter((item) => item.trim() !== ''); + const items = value.split('\n'); onChange({ ...data, [field]: items, From 0ec0655e4c48cad893bed51dc9af034d29eaf17b Mon Sep 17 00:00:00 2001 From: Frank Li Date: Tue, 5 May 2026 12:09:50 +0800 Subject: [PATCH 2/7] fix(resume): filter empty strings in single-column additional section (#763) --- apps/frontend/components/resume/resume-single-column.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/frontend/components/resume/resume-single-column.tsx b/apps/frontend/components/resume/resume-single-column.tsx index 39a7f5bc9..567d49411 100644 --- a/apps/frontend/components/resume/resume-single-column.tsx +++ b/apps/frontend/components/resume/resume-single-column.tsx @@ -394,25 +394,25 @@ const AdditionalSection: React.FC<{ {technicalSkills.length > 0 && (
{mergedLabels.technicalSkills} - {technicalSkills.join(', ')} + {technicalSkills.filter((s) => s.trim()).join(', ')}
)} {languages.length > 0 && (
{mergedLabels.languages} - {languages.join(', ')} + {languages.filter((s) => s.trim()).join(', ')}
)} {certificationsTraining.length > 0 && (
{mergedLabels.certifications} - {certificationsTraining.join(', ')} + {certificationsTraining.filter((s) => s.trim()).join(', ')}
)} {awards.length > 0 && (
{mergedLabels.awards} - {awards.join(', ')} + {awards.filter((s) => s.trim()).join(', ')}
)} From 214c78c19469cb8930d8962fc1d317bef720327d Mon Sep 17 00:00:00 2001 From: Frank Li Date: Tue, 5 May 2026 12:09:53 +0800 Subject: [PATCH 3/7] fix(resume): filter empty strings in modern template additional section (#763) --- apps/frontend/components/resume/resume-modern.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/frontend/components/resume/resume-modern.tsx b/apps/frontend/components/resume/resume-modern.tsx index 33be6e532..31180c6ab 100644 --- a/apps/frontend/components/resume/resume-modern.tsx +++ b/apps/frontend/components/resume/resume-modern.tsx @@ -396,25 +396,25 @@ const AdditionalSection: React.FC<{ {technicalSkills.length > 0 && (
{mergedLabels.technicalSkills} - {technicalSkills.join(', ')} + {technicalSkills.filter((s) => s.trim()).join(', ')}
)} {languages.length > 0 && (
{mergedLabels.languages} - {languages.join(', ')} + {languages.filter((s) => s.trim()).join(', ')}
)} {certificationsTraining.length > 0 && (
{mergedLabels.certifications} - {certificationsTraining.join(', ')} + {certificationsTraining.filter((s) => s.trim()).join(', ')}
)} {awards.length > 0 && (
{mergedLabels.awards} - {awards.join(', ')} + {awards.filter((s) => s.trim()).join(', ')}
)} From 81e6f5655baff309dd70891b058b0c230e04e1c9 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Tue, 5 May 2026 12:09:55 +0800 Subject: [PATCH 4/7] fix(resume): filter empty strings in two-column additional section (#763) --- apps/frontend/components/resume/resume-two-column.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/frontend/components/resume/resume-two-column.tsx b/apps/frontend/components/resume/resume-two-column.tsx index d7e37d145..61edcf1e0 100644 --- a/apps/frontend/components/resume/resume-two-column.tsx +++ b/apps/frontend/components/resume/resume-two-column.tsx @@ -343,7 +343,7 @@ export const ResumeTwoColumn: React.FC = ({ {headingFallbacks.certifications}
    - {additional.certificationsTraining.map((cert, index) => ( + {additional.certificationsTraining.filter((s) => s.trim()).map((cert, index) => (
  • •  {cert} @@ -402,7 +402,7 @@ export const ResumeTwoColumn: React.FC = ({

    {headingFallbacks.skills}

    - {additional.technicalSkills.map((skill, index) => ( + {additional.technicalSkills.filter((s) => s.trim()).map((skill, index) => ( {skill} @@ -419,7 +419,7 @@ export const ResumeTwoColumn: React.FC = ({

    {headingFallbacks.languages}

    -

    {additional.languages.join(' • ')}

    +

    {additional.languages.filter((s) => s.trim()).join(' • ')}

    )} @@ -428,7 +428,7 @@ export const ResumeTwoColumn: React.FC = ({

    {headingFallbacks.awards}

      - {additional.awards.map((award, index) => ( + {additional.awards.filter((s) => s.trim()).map((award, index) => (
    • {award}
    • From b94811daa34ae50273f905bb8a94068375ed4371 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Tue, 5 May 2026 12:09:58 +0800 Subject: [PATCH 5/7] fix(resume): filter empty strings in modern-two-column additional section (#763) --- .../components/resume/resume-modern-two-column.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/frontend/components/resume/resume-modern-two-column.tsx b/apps/frontend/components/resume/resume-modern-two-column.tsx index 030cb09a8..f6981e237 100644 --- a/apps/frontend/components/resume/resume-modern-two-column.tsx +++ b/apps/frontend/components/resume/resume-modern-two-column.tsx @@ -306,7 +306,7 @@ export const ResumeModernTwoColumn: React.FC = ({

      {headingFallbacks.certifications}

        - {additional.certificationsTraining.map((cert, index) => ( + {additional.certificationsTraining.filter((s) => s.trim()).map((cert, index) => (
      • •  {cert} @@ -371,7 +371,7 @@ export const ResumeModernTwoColumn: React.FC = ({ {headingFallbacks.skills}
        - {additional.technicalSkills.map((skill, index) => ( + {additional.technicalSkills.filter((s) => s.trim()).map((skill, index) => ( {skill} @@ -390,7 +390,7 @@ export const ResumeModernTwoColumn: React.FC = ({ > {headingFallbacks.languages} -

        {additional.languages.join(' • ')}

        +

        {additional.languages.filter((s) => s.trim()).join(' • ')}

        )} @@ -403,7 +403,7 @@ export const ResumeModernTwoColumn: React.FC = ({ {headingFallbacks.awards}
          - {additional.awards.map((award, index) => ( + {additional.awards.filter((s) => s.trim()).map((award, index) => (
        • {award}
        • From 44640dfa49ca556487dbc4218d46a06c5456c03b Mon Sep 17 00:00:00 2001 From: Frank Li Date: Sat, 9 May 2026 09:23:52 +0800 Subject: [PATCH 6/7] fix(resume,llm): address cubic review feedback on PR #788 - Filter whitespace-only items in section visibility checks (two-column & single-column) - Restore deepseek 1.3x timeout multiplier in llm.py --- apps/backend/app/llm.py | 1 + .../components/resume/resume-single-column.tsx | 16 ++++++++-------- .../components/resume/resume-two-column.tsx | 8 ++++---- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/apps/backend/app/llm.py b/apps/backend/app/llm.py index 81f48f64a..51a5648af 100644 --- a/apps/backend/app/llm.py +++ b/apps/backend/app/llm.py @@ -917,6 +917,7 @@ def _calculate_timeout( "openai": 1.0, "anthropic": 1.2, "openrouter": 1.5, # More variable latency + "deepseek": 1.3, # DeepSeek API can be slower than OpenAI "groq": 1.0, "ollama": 2.0, # Local models can be slower } diff --git a/apps/frontend/components/resume/resume-single-column.tsx b/apps/frontend/components/resume/resume-single-column.tsx index 567d49411..9f4785cc4 100644 --- a/apps/frontend/components/resume/resume-single-column.tsx +++ b/apps/frontend/components/resume/resume-single-column.tsx @@ -380,10 +380,10 @@ const AdditionalSection: React.FC<{ }; const hasContent = - technicalSkills.length > 0 || - languages.length > 0 || - certificationsTraining.length > 0 || - awards.length > 0; + technicalSkills.filter((s) => s.trim()).length > 0 || + languages.filter((s) => s.trim()).length > 0 || + certificationsTraining.filter((s) => s.trim()).length > 0 || + awards.filter((s) => s.trim()).length > 0; if (!hasContent) return null; @@ -391,25 +391,25 @@ const AdditionalSection: React.FC<{

          {displayName}

          - {technicalSkills.length > 0 && ( + {technicalSkills.filter((s) => s.trim()).length > 0 && (
          {mergedLabels.technicalSkills} {technicalSkills.filter((s) => s.trim()).join(', ')}
          )} - {languages.length > 0 && ( + {languages.filter((s) => s.trim()).length > 0 && (
          {mergedLabels.languages} {languages.filter((s) => s.trim()).join(', ')}
          )} - {certificationsTraining.length > 0 && ( + {certificationsTraining.filter((s) => s.trim()).length > 0 && (
          {mergedLabels.certifications} {certificationsTraining.filter((s) => s.trim()).join(', ')}
          )} - {awards.length > 0 && ( + {awards.filter((s) => s.trim()).length > 0 && (
          {mergedLabels.awards} {awards.filter((s) => s.trim()).join(', ')} diff --git a/apps/frontend/components/resume/resume-two-column.tsx b/apps/frontend/components/resume/resume-two-column.tsx index 61edcf1e0..2e392212f 100644 --- a/apps/frontend/components/resume/resume-two-column.tsx +++ b/apps/frontend/components/resume/resume-two-column.tsx @@ -337,7 +337,7 @@ export const ResumeTwoColumn: React.FC = ({ {/* Certifications/Training - Main column */} {isSectionVisible('additional') && additional?.certificationsTraining && - additional.certificationsTraining.length > 0 && ( + additional.certificationsTraining.filter((s) => s.trim()).length > 0 && (

          {headingFallbacks.certifications} @@ -398,7 +398,7 @@ export const ResumeTwoColumn: React.FC = ({ {/* Skills Section */} {isSectionVisible('additional') && additional?.technicalSkills && - additional.technicalSkills.length > 0 && ( + additional.technicalSkills.filter((s) => s.trim()).length > 0 && (

          {headingFallbacks.skills}

          @@ -414,7 +414,7 @@ export const ResumeTwoColumn: React.FC = ({ {/* Languages Section */} {isSectionVisible('additional') && additional?.languages && - additional.languages.length > 0 && ( + additional.languages.filter((s) => s.trim()).length > 0 && (

          {headingFallbacks.languages} @@ -424,7 +424,7 @@ export const ResumeTwoColumn: React.FC = ({ )} {/* Awards Section */} - {isSectionVisible('additional') && additional?.awards && additional.awards.length > 0 && ( + {isSectionVisible('additional') && additional?.awards && additional.awards.filter((s) => s.trim()).length > 0 && (

          {headingFallbacks.awards}

            From fc5bfefe1c0db4aebd27f4aef4d337e6ca63a431 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Thu, 28 May 2026 11:45:14 +0800 Subject: [PATCH 7/7] fix(tailor): expand diff scope and preserve casing (fixes #805) Allow AI Tailor to modify more resume sections while preserving original capitalization: Backend: - improver.py: extend _ALLOWED_PATH_PATTERNS with education.description, additional.languages, certificationsTraining, awards - improver.py: refine _is_path_blocked to allow education[i].description while keeping degree/institution/years blocked - improver.py: extend calculate_resume_diff to compare education descriptions, languages, and awards - templates.py: add new PATHS to DIFF_IMPROVE_PROMPT + casing rule - test_apply_diffs.py: add tests for new allowed/blocked paths Frontend: - resume_previewer_context.tsx: expand field_type union with 'language' | 'award' - diff-preview-modal.tsx: add ChangeSection rendering for languages and awards - i18n: add translation keys for languageChanges and awardChanges (en/es/ja/pt-BR/zh) Co-Authored-By: Claude --- apps/backend/app/prompts/templates.py | 10 +- apps/backend/app/services/improver.py | 104 +++++++++++++++++- apps/backend/tests/unit/test_apply_diffs.py | 97 ++++++++++++++++ .../common/resume_previewer_context.tsx | 4 +- .../components/tailor/diff-preview-modal.tsx | 30 +++++ apps/frontend/messages/en.json | 2 + apps/frontend/messages/es.json | 2 + apps/frontend/messages/ja.json | 2 + apps/frontend/messages/pt-BR.json | 2 + apps/frontend/messages/zh.json | 2 + 10 files changed, 249 insertions(+), 6 deletions(-) diff --git a/apps/backend/app/prompts/templates.py b/apps/backend/app/prompts/templates.py index 636be1a34..ab80b7378 100644 --- a/apps/backend/app/prompts/templates.py +++ b/apps/backend/app/prompts/templates.py @@ -431,16 +431,22 @@ def _build_truthfulness_rules(rule_7: str) -> str: 7. Generate all new text in {output_language} 8. Do not use em dash characters 9. Keep changes minimal and targeted — do not rewrite content that already aligns well +10. Preserve original capitalization, especially for proper nouns, technical terms (e.g., REST, API, AWS), and acronyms. Do not change the casing of words that were capitalized in the original. PATHS you can target: - "summary" — the resume summary text - "workExperience[i].description[j]" — a specific bullet (i = entry index, j = bullet index) - "workExperience[i].description" — append a new bullet (action: "append") - "personalProjects[i].description[j]" — a specific project bullet -- "personalProjects[i].description" — append a new project bullet +- "personalProjects[i].description" — append a new project bullet (action: "append") +- "education[i].description[j]" — a specific education description bullet +- "education[i].description" — append a new education bullet (action: "append") - "additional.technicalSkills" — reorder the skills list (action: "reorder") +- "additional.languages" — reorder the languages list (action: "reorder") +- "additional.certificationsTraining" — reorder the certifications list (action: "reorder") +- "additional.awards" — reorder the awards list (action: "reorder") -Do NOT target: personalInfo, dates/years, company names, education, customSections. +Do NOT target: personalInfo, dates/years, company names, education degree/institution/years, customSections. Keywords to emphasize (only if already supported by resume content): {job_keywords} diff --git a/apps/backend/app/services/improver.py b/apps/backend/app/services/improver.py index 95c9a05c2..64196dcb1 100644 --- a/apps/backend/app/services/improver.py +++ b/apps/backend/app/services/improver.py @@ -80,7 +80,11 @@ def _check_for_truncation(data: dict[str, Any]) -> None: re.compile(r"^summary$"), re.compile(r"^workExperience\[\d+\]\.description(\[\d+\])?$"), re.compile(r"^personalProjects\[\d+\]\.description(\[\d+\])?$"), + re.compile(r"^education\[\d+\]\.description(\[\d+\])?$"), re.compile(r"^additional\.technicalSkills$"), + re.compile(r"^additional\.languages$"), + re.compile(r"^additional\.certificationsTraining$"), + re.compile(r"^additional\.awards$"), ] # Blocked path prefixes — always rejected @@ -129,6 +133,9 @@ def _is_path_blocked(path: str) -> bool: return True if path.startswith("education"): + # Allow education description modifications; block all other education fields + if re.match(r"^education\[\d+\]\.description(\[\d+\])?$", path): + return False return True return False @@ -995,7 +1002,40 @@ def calculate_resume_diff( confidences=confidences, ) - # 4. Compare certifications (order changes are intentionally ignored) + # 4. Compare education descriptions (string, not list) + original_education = original.get("education", []) + improved_education = improved.get("education", []) + max_education_len = max(len(original_education), len(improved_education)) + for idx in range(max_education_len): + original_entry = ( + original_education[idx] if idx < len(original_education) else None + ) + improved_entry = ( + improved_education[idx] if idx < len(improved_education) else None + ) + if not isinstance(original_entry, dict) and not isinstance(improved_entry, dict): + continue + orig_desc = str(original_entry.get("description", "")).strip() if isinstance(original_entry, dict) else "" + impr_desc = str(improved_entry.get("description", "")).strip() if isinstance(improved_entry, dict) else "" + if orig_desc != impr_desc: + if orig_desc and not impr_desc: + change_type = "removed" + elif impr_desc and not orig_desc: + change_type = "added" + else: + change_type = "modified" + changes.append( + ResumeFieldDiff( + field_path=f"education[{idx}].description", + field_type="description", + change_type=change_type, + original_value=orig_desc or None, + new_value=impr_desc or None, + confidence="medium", + ) + ) + + # 5. Compare certifications (order changes are intentionally ignored) orig_certs = _build_string_index( original.get("additional", {}).get("certificationsTraining", []), "additional.certificationsTraining", @@ -1024,7 +1064,65 @@ def calculate_resume_diff( confidence="medium" )) - # 5. Compare added/removed/modified entries + # 6. Compare languages (order changes are intentionally ignored) + orig_langs = _build_string_index( + original.get("additional", {}).get("languages", []), + "additional.languages", + ) + new_langs = _build_string_index( + improved.get("additional", {}).get("languages", []), + "additional.languages", + ) + orig_lang_keys = set(orig_langs) + new_lang_keys = set(new_langs) + for lang_key in new_lang_keys - orig_lang_keys: + changes.append(ResumeFieldDiff( + field_path="additional.languages", + field_type="language", + change_type="added", + new_value=new_langs[lang_key], + confidence="high" + )) + + for lang_key in orig_lang_keys - new_lang_keys: + changes.append(ResumeFieldDiff( + field_path="additional.languages", + field_type="language", + change_type="removed", + original_value=orig_langs[lang_key], + confidence="medium" + )) + + # 7. Compare awards (order changes are intentionally ignored) + orig_awards = _build_string_index( + original.get("additional", {}).get("awards", []), + "additional.awards", + ) + new_awards = _build_string_index( + improved.get("additional", {}).get("awards", []), + "additional.awards", + ) + orig_award_keys = set(orig_awards) + new_award_keys = set(new_awards) + for award_key in new_award_keys - orig_award_keys: + changes.append(ResumeFieldDiff( + field_path="additional.awards", + field_type="award", + change_type="added", + new_value=new_awards[award_key], + confidence="high" + )) + + for award_key in orig_award_keys - new_award_keys: + changes.append(ResumeFieldDiff( + field_path="additional.awards", + field_type="award", + change_type="removed", + original_value=orig_awards[award_key], + confidence="medium" + )) + + # 8. Compare added/removed/modified entries # Descriptions are diffed separately; ignore them when detecting entry-level changes. _append_entry_changes( changes, @@ -1052,7 +1150,7 @@ def calculate_resume_diff( _format_project_entry, ) - # 6. Build summary + # 9. Build summary summary = ResumeDiffSummary( total_changes=len(changes), skills_added=len([c for c in changes if c.field_type == "skill" and c.change_type == "added"]), diff --git a/apps/backend/tests/unit/test_apply_diffs.py b/apps/backend/tests/unit/test_apply_diffs.py index 8c15de61b..669b37028 100644 --- a/apps/backend/tests/unit/test_apply_diffs.py +++ b/apps/backend/tests/unit/test_apply_diffs.py @@ -483,3 +483,100 @@ def test_second_experience_entry(self, sample_resume): assert result["workExperience"][1]["description"][0] == "Updated payment system description" # First entry unchanged assert result["workExperience"][0]["description"][0] == sample_resume["workExperience"][0]["description"][0] + + +class TestApplyDiffsNewPaths: + """Tests for newly allowed paths (Issue #805 fix).""" + + def test_replace_education_description(self, sample_resume): + """Education description should be replaceable.""" + original_desc = sample_resume["education"][0]["description"] + changes = [ + ResumeChange( + path="education[0].description", + action="replace", + original=original_desc, + value="Graduated with honors, focused on distributed systems", + reason="test", + ) + ] + result, applied, rejected = apply_diffs(sample_resume, changes) + assert len(applied) == 1 + assert len(rejected) == 0 + assert result["education"][0]["description"] == changes[0].value + + def test_reorder_languages(self, sample_resume): + """Languages list should be reorderable.""" + original_langs = sample_resume["additional"]["languages"] + changes = [ + ResumeChange( + path="additional.languages", + action="reorder", + original=None, + value=list(reversed(original_langs)), + reason="Prioritize Spanish for this role", + ) + ] + result, applied, rejected = apply_diffs(sample_resume, changes) + assert len(applied) == 1 + assert len(rejected) == 0 + assert result["additional"]["languages"] == list(reversed(original_langs)) + + def test_reorder_awards(self, sample_resume): + """Awards list should be reorderable.""" + original_awards = sample_resume["additional"]["awards"] + changes = [ + ResumeChange( + path="additional.awards", + action="reorder", + original=None, + value=original_awards, + reason="No change needed", + ) + ] + result, applied, rejected = apply_diffs(sample_resume, changes) + assert len(applied) == 1 + assert len(rejected) == 0 + assert result["additional"]["awards"] == original_awards + + def test_reject_education_degree(self, sample_resume): + """Education degree should still be blocked.""" + changes = [ + ResumeChange( + path="education[0].degree", + action="replace", + original="B.S. Computer Science", + value="M.S. Computer Science", + reason="test", + ) + ] + result, applied, rejected = apply_diffs(sample_resume, changes) + assert len(rejected) == 1 + + def test_reject_education_institution(self, sample_resume): + """Education institution should still be blocked.""" + changes = [ + ResumeChange( + path="education[0].institution", + action="replace", + original="MIT", + value="Stanford", + reason="test", + ) + ] + result, applied, rejected = apply_diffs(sample_resume, changes) + assert len(rejected) == 1 + + def test_reject_education_years(self, sample_resume): + """Education years should still be blocked.""" + changes = [ + ResumeChange( + path="education[0].years", + action="replace", + original="2014 - 2018", + value="2014 - 2020", + reason="test", + ) + ] + result, applied, rejected = apply_diffs(sample_resume, changes) + assert len(rejected) == 1 diff --git a/apps/frontend/components/common/resume_previewer_context.tsx b/apps/frontend/components/common/resume_previewer_context.tsx index 85a478abd..cf3bffad9 100644 --- a/apps/frontend/components/common/resume_previewer_context.tsx +++ b/apps/frontend/components/common/resume_previewer_context.tsx @@ -63,7 +63,9 @@ export interface ResumeFieldDiff { | 'certification' | 'experience' | 'education' - | 'project'; + | 'project' + | 'language' + | 'award'; change_type: 'added' | 'removed' | 'modified'; original_value?: string; new_value?: string; diff --git a/apps/frontend/components/tailor/diff-preview-modal.tsx b/apps/frontend/components/tailor/diff-preview-modal.tsx index 4bc53c048..3ac69d928 100644 --- a/apps/frontend/components/tailor/diff-preview-modal.tsx +++ b/apps/frontend/components/tailor/diff-preview-modal.tsx @@ -116,6 +116,8 @@ export function DiffPreviewModal({ const experienceChanges = detailedChanges.filter((c) => c.field_type === 'experience'); const educationChanges = detailedChanges.filter((c) => c.field_type === 'education'); const projectChanges = detailedChanges.filter((c) => c.field_type === 'project'); + const languageChanges = detailedChanges.filter((c) => c.field_type === 'language'); + const awardChanges = detailedChanges.filter((c) => c.field_type === 'award'); return ( )} + + {/* Language changes */} + {languageChanges.length > 0 && ( + toggleSection('languages')} + > + {languageChanges.map((change, idx) => ( + + ))} + + )} + + {/* Award changes */} + {awardChanges.length > 0 && ( + toggleSection('awards')} + > + {awardChanges.map((change, idx) => ( + + ))} + + )}
          {/* Action buttons */} diff --git a/apps/frontend/messages/en.json b/apps/frontend/messages/en.json index c60ac0215..6090e31fb 100644 --- a/apps/frontend/messages/en.json +++ b/apps/frontend/messages/en.json @@ -546,6 +546,8 @@ "educationChanges": "Education Changes", "projectChanges": "Project Changes", "certificationChanges": "Certification Changes", + "languageChanges": "Language Changes", + "awardChanges": "Award Changes", "rejectButton": "Reject & Regenerate", "confirmButton": "Confirm & Save" }, diff --git a/apps/frontend/messages/es.json b/apps/frontend/messages/es.json index 6c4dae0e4..bd8d3e896 100644 --- a/apps/frontend/messages/es.json +++ b/apps/frontend/messages/es.json @@ -546,6 +546,8 @@ "educationChanges": "Cambios en educación", "projectChanges": "Cambios en proyectos", "certificationChanges": "Cambios en certificaciones", + "languageChanges": "Cambios en idiomas", + "awardChanges": "Cambios en premios", "rejectButton": "Rechazar y regenerar", "confirmButton": "Confirmar y guardar" }, diff --git a/apps/frontend/messages/ja.json b/apps/frontend/messages/ja.json index 7ec30c4d5..0217f6f63 100644 --- a/apps/frontend/messages/ja.json +++ b/apps/frontend/messages/ja.json @@ -546,6 +546,8 @@ "educationChanges": "学歴の変更", "projectChanges": "プロジェクトの変更", "certificationChanges": "資格の変更", + "languageChanges": "言語の変更", + "awardChanges": "賞の変更", "rejectButton": "拒否して再生成", "confirmButton": "確認して保存" }, diff --git a/apps/frontend/messages/pt-BR.json b/apps/frontend/messages/pt-BR.json index a9f81d457..c0c5d4530 100644 --- a/apps/frontend/messages/pt-BR.json +++ b/apps/frontend/messages/pt-BR.json @@ -546,6 +546,8 @@ "educationChanges": "Alterações de educação", "projectChanges": "Alterações de projetos", "certificationChanges": "Alterações de certificações", + "languageChanges": "Alterações de idiomas", + "awardChanges": "Alterações de prêmios", "rejectButton": "Rejeitar e regenerar", "confirmButton": "Confirmar e salvar" }, diff --git a/apps/frontend/messages/zh.json b/apps/frontend/messages/zh.json index b06860f7d..7ea2455ec 100644 --- a/apps/frontend/messages/zh.json +++ b/apps/frontend/messages/zh.json @@ -546,6 +546,8 @@ "educationChanges": "教育变更", "projectChanges": "项目变更", "certificationChanges": "认证变更", + "languageChanges": "语言变更", + "awardChanges": "奖项变更", "rejectButton": "拒绝并重新生成", "confirmButton": "确认并保存" },