Mobile fixes: - Add click toggle handler for hamburger menu (was hover-only) - Menu now opens/closes on tap and closes when clicking outside - Keep hover support for desktop iPad fixes: - Sidebar content now visible on touch devices (901-1280px) - Added (hover: hover) media query to prevent hide-on-hover on tablets Security improvements: - Replace exec.CommandContext with go-git library for git operations - Add path traversal and command injection prevention - Fix race condition in template hot reload - Add environment-based cookie Secure flag Code quality: - Add constants.go for magic numbers - Remove unused code (ParsePreferenceToggleRequest, DomainError) - Add FOUC prevention with inline critical CSS - Add Makefile dev/run/clean targets - Fix README git clone URL - Add doc/DECISIONS.md for architectural decisions Tests: - Add hamburger menu click toggle tests - Add iPad sidebar visibility tests - Update security tests for go-git implementation - Add cookie Secure flag tests
4.3 KiB
Architectural Decisions
This document records key architectural decisions made for this project.
Table of Contents
- ADR-001: No Data Caching
- ADR-002: Static Dates Instead of Git Integration
- ADR-003: CI/CD with GitHub Actions
ADR-001: No Data Caching
Status: Accepted Date: 2025-11-30
Context
The CV data (JSON files) is loaded from disk on every request. A caching layer could reduce disk I/O and improve response times.
Decision
No caching will be implemented for CV data.
Rationale
- Project Size: This is a small, personal CV website with minimal traffic
- Simplicity: Caching adds complexity (cache invalidation, memory management, TTL configuration)
- Performance is Already Good: JSON file loading takes <10ms, which is acceptable
- Hot Reload: In development, we want fresh data on every request for testing
- YAGNI: We don't need caching until we have evidence of performance issues
Consequences
- Simple, maintainable code
- No cache invalidation bugs
- Slightly higher disk I/O (negligible for this scale)
- If traffic increases significantly, this decision can be revisited
ADR-002: Static Dates Instead of Git Integration
Status: Accepted Date: 2025-11-30
Context
Previously, the project had a feature to dynamically fetch project start dates from git repository first commit dates using exec.CommandContext to run git log commands.
Decision
Git command execution has been removed. Use static dates in JSON files instead.
Rationale
- Security Risk: Executing shell commands (even with path validation) poses injection risks
- Symlink Bypass: Path validation can be bypassed with symbolic links
- Unnecessary Complexity: Static dates in JSON are simpler and more maintainable
- Control: Static dates give full control over what's displayed
- Performance: No external process spawning
Implementation
Instead of gitRepoUrl in project data, use startDate directly:
{
"title": "My Project",
"startDate": "2024-06",
"current": true
}
Consequences
- More secure codebase
- Simpler implementation
- Manual date updates required when adding new projects
- No external dependencies on git binary
ADR-003: CI/CD with GitHub Actions
Status: Implemented Date: 2025-11-30
Context
The project needs automated testing, linting, and deployment.
Decision
GitHub Actions is used for CI/CD with two workflows:
- test.yml - Runs on PRs and pushes to main/develop
- deploy.yml - Deploys to production on push to main
Workflows
Test Workflow (.github/workflows/test.yml)
Triggers: push and pull_request to main and develop branches
Steps:
- Checkout code
- Setup Go 1.25.1
- Install and verify dependencies
- Run golangci-lint
- Run unit tests with coverage
- Generate coverage report
- Check coverage threshold (target: 70%)
- Upload coverage to Codecov
- Run benchmarks
- Build binary
- Upload artifacts
Deploy Workflow (.github/workflows/deploy.yml)
Triggers: push to main branch or manual dispatch
Steps:
- SSH into production server
- Fix repository permissions
- Stash any local changes
- Pull latest changes
- Restart systemd service
- Verify health check
Required Secrets
SSH_PRIVATE_KEY- SSH private key for server accessSSH_HOST- Server IP or domainSSH_USER- SSH usernameSSH_PORT(optional, default: 22)SERVICE_NAME(optional, default: cv)REPO_PATH(optional, default: /home/txeo/Git/yo/cv)
Consequences
- Automated quality checks on every PR
- Consistent deployment process
- Health check verification after deployment
- Coverage tracking with Codecov
- Binary artifacts available for download
How to Add New Decisions
When making significant architectural decisions, add a new section following this template:
## ADR-XXX: Title
**Status:** Proposed | Accepted | Deprecated | Superseded
**Date:** YYYY-MM-DD
### Context
What is the issue that we're seeing that is motivating this decision?
### Decision
What is the change that we're proposing?
### Rationale
Why is this the best choice?
### Consequences
What are the results of this decision?