fix: Mobile hamburger menu and iPad sidebar visibility
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
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
# Architectural Decisions
|
||||
|
||||
This document records key architectural decisions made for this project.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [ADR-001: No Data Caching](#adr-001-no-data-caching)
|
||||
- [ADR-002: Static Dates Instead of Git Integration](#adr-002-static-dates-instead-of-git-integration)
|
||||
- [ADR-003: CI/CD with GitHub Actions](#adr-003-cicd-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
|
||||
|
||||
1. **Project Size**: This is a small, personal CV website with minimal traffic
|
||||
2. **Simplicity**: Caching adds complexity (cache invalidation, memory management, TTL configuration)
|
||||
3. **Performance is Already Good**: JSON file loading takes <10ms, which is acceptable
|
||||
4. **Hot Reload**: In development, we want fresh data on every request for testing
|
||||
5. **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
|
||||
|
||||
1. **Security Risk**: Executing shell commands (even with path validation) poses injection risks
|
||||
2. **Symlink Bypass**: Path validation can be bypassed with symbolic links
|
||||
3. **Unnecessary Complexity**: Static dates in JSON are simpler and more maintainable
|
||||
4. **Control**: Static dates give full control over what's displayed
|
||||
5. **Performance**: No external process spawning
|
||||
|
||||
### Implementation
|
||||
|
||||
Instead of `gitRepoUrl` in project data, use `startDate` directly:
|
||||
|
||||
```json
|
||||
{
|
||||
"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:**
|
||||
|
||||
1. **test.yml** - Runs on PRs and pushes to main/develop
|
||||
2. **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:
|
||||
1. Checkout code
|
||||
2. Setup Go 1.25.1
|
||||
3. Install and verify dependencies
|
||||
4. Run golangci-lint
|
||||
5. Run unit tests with coverage
|
||||
6. Generate coverage report
|
||||
7. Check coverage threshold (target: 70%)
|
||||
8. Upload coverage to Codecov
|
||||
9. Run benchmarks
|
||||
10. Build binary
|
||||
11. Upload artifacts
|
||||
|
||||
#### Deploy Workflow (`.github/workflows/deploy.yml`)
|
||||
|
||||
Triggers: `push` to `main` branch or manual dispatch
|
||||
|
||||
Steps:
|
||||
1. SSH into production server
|
||||
2. Fix repository permissions
|
||||
3. Stash any local changes
|
||||
4. Pull latest changes
|
||||
5. Restart systemd service
|
||||
6. Verify health check
|
||||
|
||||
### Required Secrets
|
||||
|
||||
- `SSH_PRIVATE_KEY` - SSH private key for server access
|
||||
- `SSH_HOST` - Server IP or domain
|
||||
- `SSH_USER` - SSH username
|
||||
- `SSH_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:
|
||||
|
||||
```markdown
|
||||
## 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?
|
||||
```
|
||||
Reference in New Issue
Block a user