[READ-ONLY] Mirror of https://github.com/mrgnw/cv.
Content Optimization Fix - Summary#
Problem Statement#
The content optimization system was being too aggressive and removing content that should be displayed:
- Bitpanda route (
/bitpanda) was only showing 2 bullet points per experience item instead of the full content frombitpanda.json5 - No projects were showing on the bitpanda route
- Web pages were applying artificial limits even when they should show full content
- Content was being reduced unnecessarily instead of only when PDFs exceed one page
Root Cause Analysis#
Original Issues:#
- Default limits were too restrictive:
exp1: 5, exp2: 4, exp3: 4, exp4: 3, projects: 4 - Web pages were applying limits by default instead of showing all content
- PDF reduction steps were too aggressive and started cutting content immediately
- Bitpanda.json5 was missing projects array so no projects were being resolved
Solutions Implemented#
1. Fixed Web Content Display (CV.svelte)#
Before:
function getDefaultLimits() {
return { exp1: 5, exp2: 4, exp3: 4, exp4: 3, projects: 4, removeProjects: 0 };
}
After:
function getDefaultLimits() {
// Default is to show ALL content (no limits)
return { exp1: null, exp2: null, exp3: null, exp4: null, projects: null, removeProjects: 0 };
}
Key Changes:
- Web pages now show ALL content by default (
null= no limit) - Content limits only apply when explicitly set via searchParams
- This ensures
/bitpandashows all 5 CGI achievements, 4 NCD achievements, etc.
2. Updated Content Limiting Logic#
Before (Always Applied Limits):
const optimizedExperience = experience.map((exp, i) => ({
...exp,
achievements: exp.achievements.slice(0, getExpLimit(i))
}));
After (Only Apply When Set):
const optimizedExperience = experience.map((exp, i) => {
const limit = getExpLimit(i);
return {
...exp,
achievements: limit !== null ? exp.achievements.slice(0, limit) : exp.achievements
};
});
3. More Gradual PDF Optimization Steps#
Before (Too Aggressive):
this.reductionSteps = [
{},
{ removeProjects: 1 }, // Immediately remove projects
{ limitExp4: 2 }, // Heavily limit 4th experience
{ removeProjects: 2, limitExp3: 3 },
// ...more aggressive cuts
];
After (Gradual):
this.reductionSteps = [
{}, // Start with no reduction - full content
{ limitExp4: 4 }, // Reduce only the 4th experience slightly
{ limitExp4: 3 }, // Reduce 4th experience more
{ limitExp3: 4, limitExp4: 3 }, // Start limiting 3rd experience
{ limitExp3: 4, limitExp4: 3, removeProjects: 1 }, // Remove 1 project
// ...more gradual steps
];
4. Added Missing Projects to Bitpanda Version#
Added to bitpanda.json5:
"projects": [
"Resume",
"Multilingual translator",
"TextMe"
]
Results#
✅ Web Content (Full Display)#
| Route | Experience Entries | Achievements | Projects |
|---|---|---|---|
/ (main) |
4 | All (5,3,2,X) | All (3+) |
/bitpanda |
4 | All (5,4,4,4) | 3 |
✅ PDF Optimization (Only When Needed)#
- Step 1: Try full content first
- Step 2: Only reduce if content > 1 page
- Step 3: Make gradual reductions until it fits
- Step 4: Preserve as much high-priority content as possible
✅ Test Coverage#
All 52 tests still pass after the changes:
- ✅ 35 experience rendering tests
- ✅ 17 route integration tests
- ✅ 4 legacy MJS test suites
Usage Examples#
Web Pages (Full Content)#
# Shows ALL content from JSON5 files
curl http://localhost:4173/bitpanda
curl http://localhost:4173/main
PDF Generation (Optimized)#
# Automatically optimizes content to fit on one page
npm run pdf:local:force bitpanda
npm run pdf:local:force main
Manual Content Limiting (URL Parameters)#
# Only for testing - manually limit content
curl "http://localhost:4173/bitpanda?limitExp1=3&removeProjects=1"
Testing Commands#
Run All Tests#
npm run test:run # 52 Vitest tests
npm run test:all # 4 MJS test suites
npm run test:content-optimization # Content optimization verification
Generate PDFs#
npm run pdf:local:force bitpanda # Test bitpanda optimization
npm run pdf:local:force main # Test main optimization
Technical Details#
Content Limiting Flow#
- Web Request: No searchParams → Show all content
- PDF Generation: Adds searchParams with limits → Apply optimization
- Manual Testing: Can add searchParams → Apply specific limits
PDF Optimization Process#
- Try rendering with full content
- Check if it fits on one page using
checkPdfPageCount() - If > 1 page, apply next reduction step
- Repeat until content fits on one page
- Use the optimized parameters for final PDF generation
Data Flow#
JSON5 Files → versionReader → coalesceVersion → CV.svelte → Browser/PDF
↓ ↓ ↓ ↓
Raw Data Merge Versions Apply Limits Render
Key Improvements#
- 🎯 Fixed Core Issue: Web pages now show all content from JSON5 files
- 📄 Smarter PDF Optimization: Only reduces content when absolutely necessary
- 🔄 Gradual Reduction: Makes small incremental cuts rather than aggressive ones
- ✅ Maintained Test Coverage: All 52 tests still pass
- 📊 Better Content Preservation: Keeps more high-priority content in PDFs
Verification#
Bitpanda Route Now Shows:#
- ✅ 4 experience entries (CGI, National Care Dental, Persefoni, Zelis Healthcare)
- ✅ All achievements: CGI (5), NCD (4), Persefoni (4), Zelis (4)
- ✅ 3 projects: Resume, Multilingual translator, TextMe
- ✅ Full content from bitpanda.json5
PDF Generation:#
- ✅ Starts with full content
- ✅ Only reduces when needed
- ✅ Makes gradual cuts
- ✅ Fits on one page
Conclusion#
The content optimization system now works as intended:
- Web pages show ALL content from JSON5 files by default
- PDFs are optimized only when they exceed one page
- Optimization is gradual and preserves high-priority content
- Bitpanda route now displays complete experience data and projects
The fix ensures users see complete information on the web while maintaining clean, one-page PDFs for professional use.