358 lines
9.5 KiB
Markdown
358 lines
9.5 KiB
Markdown
|
|
# go-first — URPI Web Application
|
||
|
|
|
||
|
|
[](https://golang.org)
|
||
|
|
[](https://react.dev)
|
||
|
|
[](https://typescriptlang.org)
|
||
|
|
[](https://tailwindcss.com)
|
||
|
|
[](https://docker.com)
|
||
|
|
[](LICENSE)
|
||
|
|
|
||
|
|
> **URPI** — Web Application & Backend Development Experts
|
||
|
|
> Live at: [https://www.urpi.be](https://www.urpi.be)
|
||
|
|
|
||
|
|
A modern, full-stack web application showcasing URPI's expertise in web application and backend development. Built with Go, React, TypeScript, and deployed on cloud-native infrastructure.
|
||
|
|
|
||
|
|
## ✨ Features
|
||
|
|
|
||
|
|
- **Modern Go Backend** — Clean architecture with Gin, structured logging, and middleware
|
||
|
|
- **React + TypeScript Frontend** — Vite, Tailwind CSS, and component-driven development
|
||
|
|
- **RESTful API** — Versioned endpoints for skills, projects, experience, services, and contact
|
||
|
|
- **Responsive Design** — Mobile-first, accessible, with "go-bananas" inspired bold styling
|
||
|
|
- **Docker Ready** — Multi-stage builds, docker-compose for local dev and production
|
||
|
|
- **CI/CD Friendly** — Makefile with all common tasks, GitHub Actions ready
|
||
|
|
- **Production Hardened** — Security headers, rate limiting, health checks, SSL termination
|
||
|
|
|
||
|
|
## 🚀 Quick Start
|
||
|
|
|
||
|
|
### Prerequisites
|
||
|
|
|
||
|
|
- Go 1.23+
|
||
|
|
- Node.js 20+
|
||
|
|
- Docker & Docker Compose (for containerized deployment)
|
||
|
|
- PostgreSQL 16+ & Redis 7+ (or use Docker)
|
||
|
|
|
||
|
|
### Development
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Clone and enter
|
||
|
|
git clone https://github.com/dnoulet/go-first.git
|
||
|
|
cd go-first
|
||
|
|
|
||
|
|
# Install dependencies
|
||
|
|
make install
|
||
|
|
|
||
|
|
# Start development servers (backend + frontend)
|
||
|
|
make dev
|
||
|
|
|
||
|
|
# Or run separately:
|
||
|
|
make dev-backend # Go backend on :8080 with hot reload
|
||
|
|
make dev-frontend # Vite frontend on :5173 with HMR
|
||
|
|
```
|
||
|
|
|
||
|
|
Visit:
|
||
|
|
- Frontend: http://localhost:5173
|
||
|
|
- Backend API: http://localhost:8080/api/v1
|
||
|
|
- Health check: http://localhost:8080/api/v1/health
|
||
|
|
|
||
|
|
### Environment Setup
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Copy example env files
|
||
|
|
cp .env.local.example .env.local
|
||
|
|
cp .env.production.example .env.production
|
||
|
|
|
||
|
|
# Edit with your values
|
||
|
|
vim .env.local
|
||
|
|
```
|
||
|
|
|
||
|
|
### Database (Docker)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Start only PostgreSQL and Redis
|
||
|
|
docker-compose up -d postgres redis
|
||
|
|
|
||
|
|
# Run migrations (when implemented)
|
||
|
|
make db-migrate-up
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🏗️ Project Structure
|
||
|
|
|
||
|
|
```
|
||
|
|
go-first/
|
||
|
|
├── cmd/server/ # Go application entry point
|
||
|
|
├── internal/
|
||
|
|
│ ├── config/ # Configuration loading (YAML + env)
|
||
|
|
│ ├── handler/ # HTTP handlers (Gin)
|
||
|
|
│ ├── middleware/ # Custom middleware (logging, CORS, security)
|
||
|
|
│ ├── model/ # Data models & API responses
|
||
|
|
│ └── service/ # Business logic (in-memory, swappable for DB)
|
||
|
|
├── web/ # React frontend
|
||
|
|
│ ├── src/
|
||
|
|
│ │ ├── components/ # UI, layout, sections, forms
|
||
|
|
│ │ ├── hooks/ # Custom React hooks
|
||
|
|
│ │ ├── services/ # API client
|
||
|
|
│ │ ├── types/ # TypeScript types
|
||
|
|
│ │ └── utils/ # Helpers
|
||
|
|
│ └── public/ # Static assets
|
||
|
|
├── deploy/ # Deployment configs
|
||
|
|
│ ├── nginx.conf # NGINX reverse proxy
|
||
|
|
│ └── deploy.sh # Deployment script
|
||
|
|
├── docs/ # Documentation
|
||
|
|
├── Dockerfile # Multi-stage Docker build
|
||
|
|
├── docker-compose.yml # Local/production stack
|
||
|
|
├── Makefile # Build, test, deploy commands
|
||
|
|
├── config.yaml # Application configuration
|
||
|
|
└── go.mod # Go dependencies
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🛠️ Makefile Commands
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Development
|
||
|
|
make dev # Run both backend & frontend
|
||
|
|
make dev-backend # Backend only (with air hot reload)
|
||
|
|
make dev-frontend # Frontend only (Vite)
|
||
|
|
make install # Install all dependencies
|
||
|
|
|
||
|
|
# Building
|
||
|
|
make build # Build everything for production
|
||
|
|
make build-backend # Build Go binary
|
||
|
|
make build-frontend # Build React app
|
||
|
|
|
||
|
|
# Testing & Quality
|
||
|
|
make test # Run all tests
|
||
|
|
make test-backend # Go tests with coverage
|
||
|
|
make test-frontend # Frontend tests (Vitest)
|
||
|
|
make lint # Run all linters
|
||
|
|
make lint-backend # golangci-lint
|
||
|
|
make lint-frontend # ESLint + Prettier
|
||
|
|
make fmt # Format all code
|
||
|
|
make vet # go vet
|
||
|
|
make tidy # go mod tidy
|
||
|
|
|
||
|
|
# Docker
|
||
|
|
make docker-build # Build Docker image
|
||
|
|
make docker-run # Run container locally
|
||
|
|
make docker-push # Push to registry
|
||
|
|
|
||
|
|
# Deployment
|
||
|
|
make deploy # Deploy to production
|
||
|
|
make deploy-staging # Deploy to staging
|
||
|
|
|
||
|
|
# Maintenance
|
||
|
|
make clean # Clean build artifacts
|
||
|
|
make clean-all # Clean everything (including node_modules)
|
||
|
|
make generate # Generate mocks/code
|
||
|
|
```
|
||
|
|
|
||
|
|
## 📡 API Endpoints
|
||
|
|
|
||
|
|
All endpoints prefixed with `/api/v1`
|
||
|
|
|
||
|
|
| Method | Endpoint | Description |
|
||
|
|
|--------|----------|-------------|
|
||
|
|
| GET | `/health` | Health check |
|
||
|
|
| GET | `/skills` | List all skills (query: `category`) |
|
||
|
|
| GET | `/skills/:id` | Get single skill |
|
||
|
|
| GET | `/projects` | List projects (query: `category`, `featured`) |
|
||
|
|
| GET | `/projects/featured` | Get featured projects |
|
||
|
|
| GET | `/projects/:id` | Get single project |
|
||
|
|
| GET | `/experience` | List work experience |
|
||
|
|
| GET | `/services` | List services offered |
|
||
|
|
| POST | `/contact` | Submit contact form |
|
||
|
|
|
||
|
|
### Example Responses
|
||
|
|
|
||
|
|
**GET /api/v1/skills**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"success": true,
|
||
|
|
"data": [
|
||
|
|
{
|
||
|
|
"id": "uuid",
|
||
|
|
"name": "Go",
|
||
|
|
"category": "Backend",
|
||
|
|
"proficiency": 5,
|
||
|
|
"icon": "go",
|
||
|
|
"order": 1
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**POST /api/v1/contact**
|
||
|
|
```json
|
||
|
|
// Request
|
||
|
|
{
|
||
|
|
"name": "John Doe",
|
||
|
|
"email": "john@example.com",
|
||
|
|
"subject": "Project Inquiry",
|
||
|
|
"message": "Hello, I'd like to discuss..."
|
||
|
|
}
|
||
|
|
|
||
|
|
// Response (201)
|
||
|
|
{
|
||
|
|
"success": true,
|
||
|
|
"data": {
|
||
|
|
"id": "uuid",
|
||
|
|
"name": "John Doe",
|
||
|
|
"email": "john@example.com",
|
||
|
|
"subject": "Project Inquiry",
|
||
|
|
"message": "Hello, I'd like to discuss...",
|
||
|
|
"status": "new",
|
||
|
|
"created_at": "2024-01-15T10:30:00Z"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🎨 Styling — "go-bananas" Design System
|
||
|
|
|
||
|
|
The frontend uses a custom design system inspired by the **go-bananas** aesthetic:
|
||
|
|
|
||
|
|
- **Brand Color**: Vibrant orange (`#ed7315`) — energetic, technical, approachable
|
||
|
|
- **Typography**: Inter (UI) + Cal Sans (display) + JetBrains Mono (code)
|
||
|
|
- **Components**: Card-based, subtle animations, glass morphism accents
|
||
|
|
- **Dark Mode**: Ready (CSS variables, Tailwind dark:)
|
||
|
|
- **Accessibility**: WCAG AA, focus states, semantic HTML, ARIA labels
|
||
|
|
|
||
|
|
### Tailwind Customization
|
||
|
|
|
||
|
|
```js
|
||
|
|
// tailwind.config.js - key extensions
|
||
|
|
colors: {
|
||
|
|
brand: { 500: '#ed7315', ... }, // Primary orange
|
||
|
|
dark: { 900: '#0f172a', ... } // Slate dark mode
|
||
|
|
},
|
||
|
|
fontFamily: {
|
||
|
|
sans: ['Inter', ...],
|
||
|
|
display: ['Cal Sans', 'Inter', ...],
|
||
|
|
mono: ['JetBrains Mono', ...]
|
||
|
|
},
|
||
|
|
animation: {
|
||
|
|
'fade-in': 'fadeIn 0.5s ease-out',
|
||
|
|
'slide-up': 'slideUp 0.6s ease-out',
|
||
|
|
'float': 'float 6s ease-in-out infinite',
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🐳 Docker Deployment
|
||
|
|
|
||
|
|
### Local Production Stack
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Build and start all services
|
||
|
|
docker-compose up -d --build
|
||
|
|
|
||
|
|
# View logs
|
||
|
|
docker-compose logs -f app
|
||
|
|
|
||
|
|
# Stop
|
||
|
|
docker-compose down
|
||
|
|
```
|
||
|
|
|
||
|
|
### Production Deployment
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Configure environment
|
||
|
|
cp .env.production.example .env.production
|
||
|
|
# Edit with production values
|
||
|
|
|
||
|
|
# Deploy
|
||
|
|
make deploy
|
||
|
|
# Or manually:
|
||
|
|
./deploy/deploy.sh production
|
||
|
|
```
|
||
|
|
|
||
|
|
### Kubernetes (Optional)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Apply manifests
|
||
|
|
kubectl apply -k deploy/kubernetes/overlays/production
|
||
|
|
|
||
|
|
# Check status
|
||
|
|
kubectl get pods -n go-first-production
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🔧 Configuration
|
||
|
|
|
||
|
|
### config.yaml
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
server:
|
||
|
|
host: "0.0.0.0"
|
||
|
|
port: 8080
|
||
|
|
mode: "debug" # debug | release
|
||
|
|
read_timeout: 10
|
||
|
|
write_timeout: 10
|
||
|
|
|
||
|
|
database:
|
||
|
|
host: "localhost"
|
||
|
|
port: 5432
|
||
|
|
# ...
|
||
|
|
|
||
|
|
jwt:
|
||
|
|
secret: "your-secret"
|
||
|
|
expires_in: 24 # hours
|
||
|
|
|
||
|
|
cors:
|
||
|
|
allowed_origins:
|
||
|
|
- "https://www.urpi.be"
|
||
|
|
# ...
|
||
|
|
```
|
||
|
|
|
||
|
|
Environment variables override YAML config.
|
||
|
|
|
||
|
|
## 🧪 Testing
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Backend tests
|
||
|
|
go test -v -race -coverprofile=coverage.out ./...
|
||
|
|
go tool cover -html=coverage.out
|
||
|
|
|
||
|
|
# Frontend tests
|
||
|
|
cd web && npm test -- --run --coverage
|
||
|
|
```
|
||
|
|
|
||
|
|
## 📦 Dependencies
|
||
|
|
|
||
|
|
### Backend (Go)
|
||
|
|
- `gin-gonic/gin` — HTTP framework
|
||
|
|
- `rs/zerolog` — Structured logging
|
||
|
|
- `joho/godotenv` — Environment loading
|
||
|
|
- `gopkg.in/yaml.v3` — YAML config
|
||
|
|
|
||
|
|
### Frontend (React)
|
||
|
|
- `react`, `react-dom`, `react-router-dom`
|
||
|
|
- `lucide-react` — Icons
|
||
|
|
- `clsx`, `tailwind-merge` — Class utilities
|
||
|
|
- `vite` — Build tool
|
||
|
|
- `typescript`, `eslint`, `prettier`
|
||
|
|
|
||
|
|
## 🤝 Contributing
|
||
|
|
|
||
|
|
1. Fork the repository
|
||
|
|
2. Create a feature branch: `git checkout -b feature/amazing-feature`
|
||
|
|
3. Commit changes: `git commit -m 'Add amazing feature'`
|
||
|
|
4. Push to branch: `git push origin feature/amazing-feature`
|
||
|
|
5. Open a Pull Request
|
||
|
|
|
||
|
|
### Code Style
|
||
|
|
|
||
|
|
- Go: `gofmt`, `golangci-lint`
|
||
|
|
- TypeScript: `eslint`, `prettier` (with Tailwind plugin)
|
||
|
|
- Conventional commits: `feat:`, `fix:`, `docs:`, `refactor:`
|
||
|
|
|
||
|
|
## 📄 License
|
||
|
|
|
||
|
|
MIT License — see [LICENSE](LICENSE) for details.
|
||
|
|
|
||
|
|
## 🌐 URPI
|
||
|
|
|
||
|
|
**URPI** — Web Application & Backend Development
|
||
|
|
Belgium | [https://www.urpi.be](https://www.urpi.be) | contact@urpi.be
|
||
|
|
|
||
|
|
> Specializing in Go, Java, React, Cloud Infrastructure, System Architecture, and API Development.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
Built with ❤️ and lots of ☕ by the URPI team.
|