# CV Project - Developer Memory ## ⚠️ CRITICAL: Read This Before Any Changes This document contains **non-negotiable rules** and **hard-learned lessons** from this project's development. Violating these causes bugs, breaks features, and wastes time. --- ## 🔴 ABSOLUTE RULES - NEVER VIOLATE ### 1. Icon Naming Convention (CRITICAL) **ALWAYS use "icons" - NEVER "logos"** ```javascript // ✅ CORRECT .show-icons localStorage.getItem('cv-icons') const showIcons = ... // ❌ WRONG - WILL BREAK ICON TOGGLE .show-logos localStorage.getItem('cv-logos') const showLogos = ... ``` **Why:** Icon toggle had critical bug (commit 3f77fed) because JavaScript used `.show-logos` but CSS checked for `.show-icons`. This caused toggles to only work after page refresh. **Test that enforces this:** `tests/mjs/1-toggles.test.mjs` **Memory file:** `~/.claude/cv-icons-migration.md` --- ### 2. Hyperscript Parser Limit (NEEDS RETESTING) **⚠️ TO VERIFY: Maximum 3 `def` statements limit with latest hyperscript version** **Status:** We upgraded to the LATEST hyperscript version. This limit may no longer exist. **TODO:** Test if the 3 `def` statement limit still applies with current version **Current solution (still recommended):** Move complex logic to JavaScript functions ```javascript // ✅ CORRECT - JavaScript functions function toggleIcons(showIcons) { ... } function toggleCVLength(isLong) { ... } function toggleTheme(isClean) { ... } // Call from hyperscript _="on change call toggleIcons(my.checked)" // ❌ WRONG - Too many def statements _="def toggleIcons(show) if show then add .show-icons... end" ``` **Why:** Parser crashes/fails silently when limit exceeded. **Test that enforces this:** `tests/mjs/3-hyperscript.test.mjs` **Reference:** `HYPERSCRIPT-RULES.md` --- ### 3. Toggle Synchronization (WORKING) + Hover Sync (BROKEN) **Toggle checkboxes WORK perfectly ✅** Every toggle checkbox exists in TWO places and stays synchronized: 1. Action bar (desktop) - `#lengthToggle`, `#iconToggle`, `#themeToggle` 2. Hamburger menu (mobile) - `#lengthToggleMenu`, `#iconToggleMenu`, `#themeToggleMenu` **Toggle behavior (WORKING):** - ✅ Clicking either toggle updates BOTH - ✅ Changes are real-time (no page refresh) - ✅ localStorage persists the state - ✅ Page load reads from localStorage and applies to both ```javascript // ✅ CORRECT - Update both toggles function toggleIcons(showIcons) { const paper = document.querySelector('.cv-paper'); const otherToggle = document.querySelector('#iconToggle') || document.querySelector('#iconToggleMenu'); if (showIcons) { paper?.classList.add('show-icons'); localStorage.setItem('cv-icons', 'true'); if (otherToggle) otherToggle.checked = true; } else { paper?.classList.remove('show-icons'); localStorage.setItem('cv-icons', 'false'); if (otherToggle) otherToggle.checked = false; } } ``` **⚠️ HOVER SYNC BUG - PDF/Print buttons NOT synchronized** **Action buttons that SHOULD sync hover states:** 1. Action bar (desktop): - `#action-bar-pdf-btn` - Download PDF button - `.action-bar-print-btn` - Print Friendly button 2. Hamburger menu (mobile): - PDF button (templates/partials/navigation/hamburger-menu.html:178) - `.menu-print-btn` (templates/partials/navigation/hamburger-menu.html:183) **Current hover sync functions exist but DON'T WORK:** - `syncPdfHover(isHovering)` - SHOULD sync PDF button hover between locations - `syncPrintHover(isHovering)` - SHOULD sync Print button hover between locations **THE BUG:** Hovering action bar buttons DOES NOT highlight menu buttons **Files affected:** - `templates/partials/navigation/action-buttons.html` (lines 9-10, 18-19) - `templates/partials/navigation/hamburger-menu.html` (lines 185-186) - `static/js/cv-functions.js` - hover sync functions incomplete/broken **Test coverage:** `tests/mjs/1-toggles.test.mjs` doesn't verify hover states (NEEDS test case) **Test that enforces toggle sync:** `tests/mjs/1-toggles.test.mjs` ✅ --- ### 4. Real-Time Rendering + Persistence (CRITICAL) **ALL UI changes MUST happen in BOTH DOM and localStorage** **BOTH are required - not mutually exclusive:** ```javascript // ✅ CORRECT - DOM update AND localStorage paper.classList.add('show-icons'); // Visual change (instant feedback) localStorage.setItem('cv-icons', 'true'); // Persistence (survives reload) // ❌ WRONG - Only DOM (lost on page reload) paper.classList.add('show-icons'); // ❌ WRONG - Only storage (no visual feedback) localStorage.setItem('cv-icons', 'true'); ``` **Why both are needed:** - **DOM changes** = instant visual feedback (users see it immediately) - **localStorage** = state persists across page reloads (users don't lose their preferences) - Users need BOTH: instant feedback + remembered preferences **Test that enforces this:** `tests/mjs/1-toggles.test.mjs` (verifies both DOM and localStorage) --- ### 5. Test Suite as Single Source of Truth **If a test passes, the feature MUST work. If a feature works, the test MUST pass.** ``` tests/mjs/ ├── 0-zoom.test.mjs # Zoom functionality ├── 1-toggles.test.mjs # ALL toggles + sync + persistence ├── 2-keyboard-shortcuts.test.mjs # L, I, V, ? keys ├── 3-hyperscript.test.mjs # Parse errors + def limit ├── 4-htmx.test.mjs # HTMX integration ├── 5-language.test.mjs # EN/ES switching ├── 6-modals.test.mjs # Modal functionality └── 7-mobile-responsive.test.mjs # Mobile viewports ``` **Non-negotiable:** - ❌ NO code changes without test validation - ❌ NO bug fixes without regression test - ❌ NO features without test coverage - ❌ NO deployment if tests fail **Run before every commit:** ```bash bun tests/run-all.mjs ``` **Reference:** `tests/README.md`, `tests/TEST-SUMMARY.md` --- ## 📋 Architecture Decisions ### Tech Stack **Backend:** - ✅ Go 1.21+ (Backend server) - ✅ Standard library `net/http` (HTTP server) - ✅ Go templates (Server-side rendering) **Frontend:** - ✅ HTMX (Hypermedia-driven interactions) - ✅ Hyperscript (Latest version - event handling) - ✅ Vanilla JavaScript (cv-functions.js - toggles, keyboard shortcuts) - ✅ Iconify (Icon system) **Testing:** - ✅ Playwright (E2E browser automation) - ✅ Bun (Test runner ONLY - NOT the runtime!) **Why Go:** - Fast compilation - Single binary deployment - Built-in templating - Excellent standard library - Strong typing - Cross-platform **Why HTMX + Hyperscript:** - Server-driven UI (hypermedia pattern) - Minimal JavaScript - Progressive enhancement - Real-time updates capabilities ### File Organization ``` cv/ ├── main.go # Server entry point (v1.1.0) ├── go.mod, go.sum # Go dependencies ├── internal/ │ ├── config/ # Configuration │ ├── handlers/ # HTTP handlers │ ├── middleware/ # HTTP middleware │ ├── models/ # Data models │ ├── routes/ # Route definitions │ └── templates/ # Template utilities ├── static/ │ ├── js/ │ │ └── cv-functions.js # Global functions (toggles, keyboard, hover sync) │ ├── css/ # Stylesheets │ ├── hyperscript/ │ │ └── functions._hs # Hyperscript functions (if any) │ ├── images/ # Static images │ └── pdf/ # PDF files ├── templates/ │ ├── index.html # Main page template │ ├── cv-content.html # CV content │ ├── language-switch.html # Language switcher │ └── partials/ │ ├── navigation/ │ │ ├── action-bar.html # Desktop action bar │ │ ├── action-buttons.html # PDF + Print buttons │ │ └── hamburger-menu.html # Mobile menu (ALL controls + buttons) │ ├── widgets/ # Reusable UI components │ └── modals/ # Modal dialogs └── tests/ └── mjs/ # Systematic test suite (Playwright + Bun runner) ``` **Critical files:** - `main.go` - Server entry point - `static/js/cv-functions.js` - Toggle, keyboard, and hover sync functions - `templates/partials/navigation/action-buttons.html` - PDF + Print buttons (action bar) - `templates/partials/navigation/hamburger-menu.html` - Complete mobile menu with toggles + buttons - `templates/index.html` - Main template structure --- ## 🐛 Historical Bugs (Learn From These) ### Bug 1: Icon Toggle Required Refresh **Commit:** 3f77fed **Date:** 2025-11-17 **Symptom:** Icon toggle only worked after page refresh **Root cause:** Class name mismatch - JavaScript: `classList.add('show-logos')` - CSS: `.cv-paper:not(.show-icons)` **Fix:** Changed all references from "logos" to "icons" **Test added:** Screenshot verification in `1-toggles.test.mjs` **Memory:** `~/.claude/cv-icons-migration.md` ### Bug 2: Hyperscript Parser Crash **Date:** 2025-11-16 **Symptom:** Silent failures, toggles stopped working **Root cause:** Exceeded 3 `def` statement limit **Fix:** Moved toggle logic to JavaScript (`cv-functions.js`) **Test added:** Def statement counter in `3-hyperscript.test.mjs` **Reference:** `HYPERSCRIPT-RULES.md` ### Bug 3: Toggle Desynchronization **Date:** 2025-11-15 **Symptom:** Action bar and menu toggles out of sync **Root cause:** Only updating one toggle, not both **Fix:** Every toggle function now updates both locations **Test added:** Sync verification in `1-toggles.test.mjs` --- ## 🎯 Development Workflow ### Before Making Changes 1. **Read relevant test:** Understand what's being tested 2. **Run the test:** See current behavior 3. **Make changes:** Code + test updates together 4. **Run test again:** Verify it passes 5. **Run ALL tests:** `bun tests/run-all.mjs` 6. **Manual verification:** Browser stays open - check it yourself 7. **Commit:** With clear description ### When Adding a Feature 1. **Write test FIRST** (test what you want to build) 2. **Implement feature** 3. **Test passes** (feature works) 4. **Update documentation** (TEST-SUMMARY.md) 5. **Commit both** (code + test together) ### When Fixing a Bug 1. **Write regression test** (reproduces the bug) 2. **Test FAILS** (proves bug exists) 3. **Fix the bug** 4. **Test PASSES** (proves fix works) 5. **Commit both** (fix + test together) --- ## 📝 Key Patterns ### Toggle Pattern (Standard) ```javascript function toggleX(enabled) { const target = document.querySelector('.target'); const otherToggle = document.querySelector('#xToggle') || document.querySelector('#xToggleMenu'); if (enabled) { target?.classList.add('state-class'); localStorage.setItem('cv-x', 'true'); if (otherToggle) otherToggle.checked = true; } else { target?.classList.remove('state-class'); localStorage.setItem('cv-x', 'false'); if (otherToggle) otherToggle.checked = false; } } ``` **Must have:** - ✅ Real-time DOM update - ✅ localStorage persistence - ✅ Sync both toggle locations - ✅ Safe navigation (`?.`) ### Hyperscript Pattern (LIMITED USE) ```html