Skip to content

schulzdimitri/portfolio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dimitri Schulz Amado — Full-Stack Portfolio

Go JavaScript SQLite Docker DigitalOcean GitHub Actions

A modernized, full-stack personal portfolio. What started as a static HTML/JS site has evolved into a robust decoupled application featuring a Vanilla JavaScript frontend and a resilient Golang backend powered by SQLite.

🏗️ Architecture & Stack

  • Frontend: Pure HTML5, CSS3, and Vanilla JavaScript. Deployed statically to GitHub Pages. Focuses on performance and SEO.
  • Backend: Go 1.26 API following Clean Architecture/DDD patterns.
  • Database: SQLite with automated initial seeding (embedded JSON data).
  • Security & Reliability: Built-in CORS configuration, IP-based Rate Limiting, and graceful failure handling.
  • CI/CD & DevOps: Automated via GitHub Actions. Tests are enforced (50%+ coverage required). Backend is packaged into a Docker container and deployed via SSH to a DigitalOcean Droplet.

✨ Key Features

  • Dynamic Content: Projects are served from a SQLite database rather than hardcoded static files.
  • Automated Seeding: If the database is empty, the backend automatically seeds initial data at runtime using Go's //go:embed directive.
  • Contact Form Integration: Includes an SMTP sender to natively dispatch emails when the contact form is submitted.
  • Resilient Infrastructure: Backend runs containerized with persistent volumes to ensure data survives across restarts.

📂 Project Structure

portfolio/
├── frontend/
│   ├── index.html          # Entry point
│   ├── css/                # Styling (CSS Modules)
│   ├── js/                 # Client logic and API fetching
│   └── package.json        # Test dependencies (Vitest)
│
├── backend/
│   ├── cmd/server/         # Entrypoint & Seeder logic
│   ├── internal/
│   │   ├── domain/         # Entities (Project, ContactMessage)
│   │   ├── handler/        # HTTP Controllers
│   │   ├── middleware/     # Security (CORS, Rate Limiter)
│   │   ├── repository/     # SQLite persistence layer
│   │   └── sender/         # External SMTP service
│   ├── Dockerfile          # Multi-stage build definition
│   └── go.mod
│
└── .github/workflows/      # Automated Deployment Pipelines

🚀 Getting Started (Local Development)

Prerequisites

  • Go 1.26+
  • Node.js & npm (for frontend tests)

Running the Backend

cd backend

# The backend will start on port 8080 and create portfolio.db automatically
go run cmd/server/main.go

Running the Frontend

The frontend points to http://localhost:8080 by default during local development. Simply open frontend/index.html in your browser, or use a local static server:

cd frontend
python3 -m http.server 3000
# Open http://localhost:3000

⚙️ Environment Variables

To fully run the backend in production (or locally with email capabilities), set the following environment variables:

Variable Description Default
PORT The port the HTTP server listens on. 8080
DB_PATH Path to the SQLite database file. portfolio.db
ALLOWED_ORIGIN CORS allowed origin (Frontend URL). *
ADMIN_TOKEN Token for securing POST /api/projects and /api/experiences. supersecret123
SMTP_HOST Hostname of your email provider (e.g., smtp.gmail.com). empty
SMTP_PORT Port for your SMTP server (e.g., 587). empty
SMTP_USER SMTP authentication username. empty
SMTP_PASSWORD SMTP authentication password/app token. empty
CONTACT_TO_EMAIL Destination email to receive contact form submissions. empty

(Note: If SMTP variables are missing, the backend will still run but will fallback to logging contact messages to the console).

🔐 Admin API (POST Data)

You can dynamically add new projects and experiences to your database without touching the code. Make a POST request to the API with the header Authorization: Bearer <ADMIN_TOKEN>.

Adding an Experience:

curl -X POST "https://jellyfish-app-ows8l.ondigitalocean.app/api/experiences" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "company": "Huawei",
    "role": "Backend Maintenance Engineer - Sistema Django em Produção",
    "period": "2024",
    "duties": [
      "Manutenção proativa e troubleshooting do principal sistema Django em produção",
      "Implementação de correções e otimizações de performance",
      "Suporte técnico a equipes de negócio e operações"
    ]
  }'

Experience Fields:

  • company (string): Company name
  • role (string): Job title/position
  • period (string): Employment period (e.g., "fev 2023 - ago 2024")
  • duties (array): List of responsibilities and accomplishments

Adding a Project:

curl -X POST "https://jellyfish-app-ows8l.ondigitalocean.app/api/projects" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Portfolio API",
    "description": "REST API desenvolvida em Go com SQLite para gerenciar experiências, projetos e contatos. Inclui autenticação por Bearer token, CORS e rate limiting.",
    "github": "https://github.com/schulzdimitri/portfolio",
    "tags": ["Go", "SQLite", "REST API", "Docker", "CI/CD", "GitHub Actions"]
  }'

Project Fields:

  • title (string): Project name
  • description (string): Detailed description of the project
  • github (string): GitHub repository URL
  • tags (array): Technologies and skills used

🔄 CI/CD Pipelines

This project utilizes two independent GitHub Actions workflows:

  1. Frontend Pipeline (frontend-ci.yml): Triggers on UI changes. Runs Vitest unit tests, injects the production BACKEND_URL, and deploys statically to GitHub Pages.
  2. Backend Pipeline (backend-ci.yml): Triggers on backend changes. Runs Go tests, enforces coverage, builds a Docker image to GitHub Container Registry (GHCR), and triggers a rolling update via SSH to the DigitalOcean Droplet.

About

Meu portfólio DEV

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors