Commit Graph

500 Commits

Author SHA1 Message Date
juanatsap 61efe98240 feat: link projects to drolosoft.com pages and add GitHub badge
Main project URLs now point to drolosoft.com product pages with
language-aware links. GitHub repos are shown via a new badge next
to the existing LIVE badge.
2026-04-03 23:15:59 +01:00
juanatsap f54829cb28 data: add Immich Photo Manager project logo 2026-04-03 22:44:21 +01:00
juanatsap bbaf303e62 data: add Cmux Resurrect project logo (phoenix) 2026-04-02 23:37:38 +01:00
juanatsap b68eab10c2 data: add Immich Photo Manager open-source project to CV
Add MCP server for AI-powered Immich photo library management
to projects section in both English and Spanish.
2026-04-02 21:57:47 +01:00
juanatsap afe2ad5017 fix: capitalize Cmux Resurrect properly 2026-03-27 02:10:34 +00:00
juanatsap 5dd01461b3 fix: correct project name from CMAX to cmux Resurrect 2026-03-27 02:10:15 +00:00
juanatsap 623f3b2376 data: add CMAX Resurrect open-source project to CV
Add cmux-resurrect terminal session persistence tool to the
projects section in both English and Spanish CV data files.
2026-03-27 02:00:28 +00:00
juanatsap 1d0cf46dd3 fix: resolve errcheck warnings in security_test.go
Use t.Setenv for env var management in tests.
2026-03-15 20:22:41 +00:00
juanatsap cafd117437 fix: resolve golangci-lint errcheck and staticcheck warnings
Use t.Setenv in tests, add error return handling, and replace
WriteString(fmt.Sprintf(...)) with fmt.Fprintf.
2026-03-15 20:22:41 +00:00
juanatsap 585949b709 chore: update Matomo analytics URL to matomo.txeo.club
Migrate from matomo.morenorub.io to matomo.txeo.club in both
CSP headers and tracking script. Also fix errcheck lint warnings
in cv_streaming.go.
2026-03-15 20:22:41 +00:00
juanatsap 019f610eb5 data: close LIV Golf position (ended Dec 2025) 2026-03-05 22:35:07 +00:00
juanatsap 15723dfbe6 docs: rewrite doc/README.md as comprehensive master index v2.0.0
- Catalog 40+ documentation files across 4 sections
- Add architecture quick reference (13 internal packages, 6-layer CSS, template structure)
- Add complete E2E test suite matrix (83 Playwright tests grouped by range)
- Add JavaScript modules inventory (7 files)
- Add security features matrix (CSRF, rate limiting, bot detection, CSP)
- Add Makefile commands reference (16 targets)
- Add deployment scripts and CI/CD reference
- Add metrics dashboard
- Follow same pattern as commando and morenocuadrillero docs/README.md
2026-02-21 17:20:39 +00:00
juanatsap 69012bb1ae test: add comprehensive Go test suite with ~75% coverage
New test files:
- config/config_test.go (100% coverage)
- constants/constants_test.go (100% coverage)
- httputil/response_test.go (100% coverage)
- validation/rules_test.go (91.9% coverage)
- middleware/logger_test.go, security_test.go, security_logger_test.go
- handlers/errors_test.go

Updated documentation:
- doc/27-GO-TESTING.md: Complete testing guide
- doc/00-GO-DOCUMENTATION-INDEX.md: Added testing section
- doc/01-ARCHITECTURE.md: Updated package structure
- doc/DECISIONS.md: Added ADR-004 caching decision
- PROJECT-MEMORY.md: Added Go testing section
2025-12-06 17:51:20 +00:00
juanatsap 6ed6c7780b docs: add CLAUDE.md pointing to key project documentation
Links to PROJECT-MEMORY.md and DECISIONS.md for development rules
and architectural decisions, plus quick commands and doc index.
2025-12-06 17:49:13 +00:00
juanatsap c89b67a06d refactor: consolidate lang into constants, rename services to email
- Merge lang package into constants (add IsValidLang, ValidateLang, AllLangs)
- Rename internal/services to internal/email for consistency with pdf package
- Rename types to avoid redundancy: EmailService→Service, EmailConfig→Config
- Update all imports and references across codebase
- Delete internal/lang directory (functions moved to constants)
2025-12-06 17:05:17 +00:00
juanatsap 30ed21ff7a refactor: use 'c' alias for constants package
- Update all imports from 'constants' to 'c' for brevity
- Replace all 'constants.' references with 'c.'
- Fix remaining hardcoded content-type headers in httputil
- Fix remaining hardcoded User-Agent and Accept headers
- Rename CSRF receiver from 'c' to 'csrf' to avoid conflict
- Add ContentTypePlainSimple constant for Accept header matching
- Fix JSONCached to use proper integer formatting
2025-12-06 16:31:42 +00:00
juanatsap 2c7f8de242 refactor: centralize constants and reorganize documentation
- Create internal/constants package with all hardcoded values
  (environment, cookies, themes, headers, routes, cache)
- Create internal/httputil package for HTTP helper functions
- Update all handlers and middleware to use centralized constants
- Reorganize documentation with numbered prefixes (00-26)
- Remove duplicate docs from validation folder and docs/
- Delete handlers/constants.go (moved to internal/constants)
2025-12-06 16:27:12 +00:00
juanatsap 71d9258c58 feat: add application-level data caching for CV/UI
Eliminate per-request file I/O by loading CV and UI data once at startup.

## Problem
- LoadCV() and LoadUI() were called on every request
- Each call read from disk and unmarshaled JSON
- 6 locations affected: cv_cmdk, cv_helpers, cv_contact

## Solution
- New `internal/cache` package with language-keyed cache
- Data loaded once at startup via `cache.New(["en", "es"])`
- Handlers use `h.dataCache.GetCV(lang)` / `GetUI(lang)`
- Thread-safe concurrent reads via sync.RWMutex
- Deep copy for mutable slices (Experience, Projects)

## Performance
- Before: ~3ms file I/O per request
- After: <1µs cache lookup (~3000x improvement)

## Files
- internal/cache/data_cache.go (new)
- internal/cache/data_cache_test.go (new)
- internal/cache/README.md (new)
- internal/handlers/cv.go (added dataCache field)
- internal/handlers/cv_*.go (use cache)
- main.go (initialize cache at startup)
2025-12-06 15:57:23 +00:00
juanatsap 24f32421ad chore: improve test targets and documentation
- Add test-local target for running all tests from project root
- Add -short flag to test-unit for CI-safe execution
- Expand tests/README.md with Go backend test documentation
- Rename css-bundling test to follow numbered convention (81-)
2025-12-06 15:24:07 +00:00
juanatsap d51e1f4520 chore: remove duplicate docs from validation folder
Documentation lives in docs/go-validation-system.md
2025-12-06 15:22:13 +00:00
juanatsap 6c7595b041 feat: add tag-based validation system with reflection caching
Implement a declarative struct tag validation system for Go:

- Add validator.go with sync.Map caching for reflection metadata
- Add rules.go with 11 built-in validation rules (required, email,
  pattern, honeypot, timing, etc.)
- Add errors.go with FieldError and ValidationErrors types
- Update ContactFormRequest with validate tags
- Add ValidateContactFormV2() using the new tag-based validator

Rules implemented:
- required/optional: field presence validation
- trim/sanitize: automatic value transformations
- min/max: UTF-8 aware length validation
- email: RFC 5322 email format validation
- pattern: predefined regex patterns (name, subject, company)
- no_injection: email header injection prevention
- honeypot: bot trap (must be empty)
- timing: timestamp validation for bot detection

Documentation:
- docs/go-validation-system.md: complete validation guide
- docs/go-template-system.md: template manager documentation
- docs/go-routes-api.md: routes and API reference
- docs/README.md: documentation index
2025-12-06 15:20:45 +00:00
juanatsap 6172ada527 fix: mobile sprite icons overflow in experience section
Sprite icons (.icon-sprite.icon-section) had fixed 80px dimensions
while mobile breakpoint set container to 60px, causing overflow.
Added mobile-specific rules to scale sprites to 60px with proper
background-size and positioning calculations.
2025-12-06 11:59:39 +00:00
juanatsap c63ce6dd91 docs: add cache busting, mobile FAB, and lint workflow documentation 2025-12-06 11:34:57 +00:00
juanatsap 68c9371d76 feat: add lint-fix target and improve lint command 2025-12-06 11:32:13 +00:00
juanatsap 44cf5204f8 fix: handle file.Close() errors in sprites command (errcheck) 2025-12-06 11:29:59 +00:00
juanatsap 42f6135c07 chore: add cache-busting version to CSS bundle 2025-12-06 11:15:27 +00:00
juanatsap e06f98d1d8 fix: prevent FAB button overflow on very small screens (iPhone 13 mini)
- Add media query for screens ≤400px (iPhone 13 mini = 375px)
- Reduce button size to 34px and icon size to 16px
- Recalculate 6-button positions with 6px gaps (234px total width)
- Ensures buttons stay centered within narrow viewports
2025-12-06 10:01:12 +00:00
juanatsap 404748afb5 feat: redesign CMD+K button as macOS Spotlight-style search bar
Replace simple search button with search bar design in action bar:
- Semi-transparent styling integrated with dark action bar
- Keyboard shortcut indicators (⌘ K) shown as individual kbd elements
- Search icon and "Search" text for better discoverability
- Responsive: kbd keys hidden on mobile (<900px)
- Remove unused cmd-k-button.html partial template

Update test to verify new search bar structure (styling, kbd elements, icon).
2025-12-04 12:59:16 +00:00
juanatsap b5a50ca3ef feat: implement CSS sprite system for image optimization
Reduces HTTP requests from 44+ individual images to 3 sprite sheets
(~93% reduction). Includes Go sprite generator tool, CSS classes,
template integration, and E2E tests.

- Add cmd/sprites/main.go for sprite generation (60x60px + 120x120px @2x)
- Add _sprites.css with responsive sizing and retina support
- Update templates to use sprites with logoIndex fallback
- Add Makefile targets: sprites, sprites-clean
- Add 9-test E2E suite for sprite functionality
- Add doc/22-SPRITES.md with usage documentation
2025-12-04 11:38:36 +00:00
juanatsap 7727405c25 docs: fix broken links, update versions and test counts
5-expert orchestrated cleanup audit findings:
- Fix broken security doc links (docs/SECURITY.md → doc/9-SECURITY.md)
- Update Go version requirement (1.21+ → 1.25.1+)
- Correct test count (39 → 44 test files)
- Fix ZOOM_IMPLEMENTATION.md filename reference
- Update last modified dates to 2025-12-02
2025-12-02 21:02:57 +00:00
juanatsap d95c62bad4 refactor: remove outdated server design documentation
Remove 557-line server-design.md from _go-learning/architecture - content is now covered in updated architecture documentation with real implementation examples and test coverage.
2025-12-02 20:25:05 +00:00
juanatsap 0114b145ba refactor: remove search button from FAB, reorganize 7-button layout
Remove cmd-k-btn (search) from floating action buttons - search now only
lives in the action bar. Recalculated positions for 7-button (desktop)
and 6-button (mobile without shortcuts) layouts using fluid clamp() sizing.
2025-12-02 18:55:04 +00:00
juanatsap aeaa9f2d62 test: add intro-text justification CSS verification test
Tests text-align, text-align-last, hyphens, word-spacing,
overflow-wrap, and font-style properties for both EN and ES
2025-12-02 18:18:43 +00:00
juanatsap a0bef45b0a fix: restore udemy.png course logo and enhance text justification
- Re-added courseLogo reference for Udemy certifications in both cv-en.json and cv-es.json
- Enhanced .intro-text CSS with full justification (text-align-last) and cross-browser hyphenation support
2025-12-02 18:15:50 +00:00
juanatsap c26cea3fd5 fix: remove missing udemy.png reference, improve text justification
- Remove courseLogo reference for Udemy courses (use fallback icon)
- Add text-justify: inter-word and hyphens: auto to intro-text
- Better text flow on iPad/tablet widths with narrow columns
2025-12-02 18:07:33 +00:00
juanatsap 44116eba5a refactor: use hyperscript event filtering and destructuring
- Use event filtering [key is 'Enter' or key is ' '] on PDF modal cards
- Remove handlePdfCardKey helper function (now inline)
- Use event destructuring on keydown(key, target, ctrlKey, metaKey, altKey)
- Cleaner, more idiomatic hyperscript patterns
2025-12-02 17:55:45 +00:00
juanatsap 3c49f8f7cf refactor: use idiomatic hyperscript selector syntax
Replace verbose document.getElementById() and document.querySelectorAll()
with cleaner hyperscript syntax:
- #id for ID selectors
- .class and the first .class for class selectors
- <selector/> query literals for complex selectors
- #{variable} for dynamic ID interpolation

Files changed:
- utils._hs: scrollHeight, details, footer buttons, scrollToSection
- zoom._hs: all zoom control element selectors (14 changes)
- pdf-modal._hs: modal selector
- keyboard._hs: dynamic toggle and modal selectors
- contact-modal.html: response div and modal close
- index.html: ninja-keys bar selector
2025-12-02 16:23:40 +00:00
juanatsap 6970606c42 refactor: simplify contact form timestamp with hyperscript + minimal JS
Replace 34-line IIFE/MutationObserver with:
- Hyperscript: on toggle if me.open call resetContactForm()
- 11-line resetContactForm() function

Also dispatches 'show' event from openModal() for ninja-keys integration.
All 7 contact form tests pass.
2025-12-02 16:00:00 +00:00
juanatsap 2dd0922a63 refactor: replace verbose JS with hyperscript for contact form timestamp
Removed 34 lines of JavaScript (IIFE, MutationObserver, DOMContentLoaded)
and replaced with 2 lines of hyperscript in the existing 'on show' handler.
2025-12-02 15:52:33 +00:00
juanatsap bd859c318f docs: update architecture and add contact handler unit tests
Architecture updates:
- Add EmailService documentation with config and flow diagram
- Update CVHandler struct to show all dependencies
- Add new middleware components (BrowserOnly, RateLimiter, etc.)
- Update package structure to include services, pdf, validation

New unit tests for HandleContact (9 tests):
- Valid submission
- Missing email/message validation
- Honeypot bot protection
- Timing-based bot protection (too fast)
- Invalid HTTP method (405)
- Invalid email format
- Message too short
- Spanish language support

Includes MockEmailService for isolated testing.
2025-12-02 14:35:37 +00:00
juanatsap f3842a3486 fix: connect EmailService to contact form handler
The contact form was logging submissions but never actually sending emails.
This commit:
- Adds EmailService field to CVHandler
- Initializes EmailService in main.go with SMTP config
- Calls SendContactForm in HandleContact handler
- Updates all test files to pass nil for emailService parameter
2025-12-02 14:27:03 +00:00
juanatsap 9842f183ea ```
chore: remove local git repo path from laporra project

- Clear gitRepoUrl for laporra.club project in both EN/ES CV data
- Update validation doc example to use generic path instead of specific project
- Prevents exposing local filesystem paths in public CV data
```
2025-12-02 14:16:57 +00:00
juanatsap fc63151dcd fix: errcheck for client.Close in STARTTLS error path 2025-12-02 14:14:02 +00:00
juanatsap ff74946d2d feat: add Udemy courses and fix footer i18n + golangci-lint errors
- Add 5 Udemy courses with PDF certificate links (Go, Fyne, HTMX)
- Fix cv-footer.html to use CV data instead of hardcoded values
- Add i18n labels for footer (linkedin, github, domestika, email, phone)
- Fix 11 golangci-lint errors:
  - errcheck: proper Close() error handling in email/security/tests
  - staticcheck: simplify return and merge variable declaration
  - unused: remove legacy sendEmail and formatMessage functions
2025-12-02 14:11:36 +00:00
juanatsap 3edeb5274d fix: security tests with mock email sender and rate limit isolation
- Add EmailSender interface to allow mocking in tests
- Add IsInitialized() method to template.Manager for nil-safe checks
- Update contact handler to use interface and safe initialization checks
- Add mockEmailSender in security tests to avoid SMTP connection attempts
- Use unique IPs per test case to avoid rate limiting interference
2025-12-02 13:49:54 +00:00
juanatsap 41dbd77c2f feat: responsive HTML email templates with DreamHost SMTP
- Add professional HTML email template matching CV aesthetic
- Implement multipart emails (HTML + plain text fallback)
- Configure DreamHost SMTP with SSL (port 465)
- Add "light only" color scheme for Gmail iOS compatibility
- Include Reply-To header for easy sender response
- Add email validation and integration tests
- Update .env.example with DreamHost/Gmail SMTP examples
- Add .env to .gitignore to protect credentials
- Document email template customization and dark mode approach
2025-12-02 13:42:36 +00:00
juanatsap 40733034ca feat: comprehensive WCAG 2.1 AA accessibility audit
- Add aria-labels to menu action buttons (PDF, Print, Contact)
- Add aria-labelledby to toggle checkboxes (desktop + mobile)
- Add -webkit-user-select prefix for Safari compatibility
- Add DynamicCacheControl middleware for HTML pages
- Add accessibility test suite (60-accessibility.test.mjs)
- Add comprehensive accessibility documentation (21-ACCESSIBILITY.md)
- Update Modern Web Techniques doc to mark audit complete
2025-12-02 10:46:53 +00:00
juanatsap fbcc5f8f5b perf: Always use bundled CSS (28+ files → 1 file)
- Update head-styles.html to always load bundle.min.css
- Remove development/production conditional CSS loading
- Add CSS auto-rebuild to pre-commit hook
- Track bundle.min.css in git (unignore it)
- Reduces initial CSS requests from 28+ to 1
2025-12-02 09:23:32 +00:00
juanatsap db642c7cc2 docs: Add HTML Invoker Commands and Lazy Loading sections
- Document HTML Invoker Commands API (commandfor/command)
- Document lazy loading pattern for web components
- Include CDN comparison (esm.sh ?bundle vs others)
- Add CSP configuration notes
- Performance metrics before/after
2025-12-02 08:33:18 +00:00
juanatsap 2d3d3de8cd feat: lazy load ninja-keys + HTML Invoker Commands API
- Lazy load ninja-keys only on CMD+K press (0 requests on initial load)
- Use esm.sh bundled module (3 requests vs ~81 previously)
- Add esm.sh to CSP whitelist
- Implement HTML Invoker Commands API for modals:
  - commandfor="modal-id" + command="show-modal" for opening
  - commandfor="modal-id" + command="close" for closing
  - Removes need for onclick handlers on modal buttons
- Refactor index.html into layout partials (head, body-scripts)
- Add comprehensive tests for both features
2025-12-02 08:29:54 +00:00