modifica e deploy.yml, correzione in cors.ts, creazione file Readme.md
This commit is contained in:
parent
9253e52bfd
commit
38c945f31d
4 changed files with 212 additions and 21 deletions
24
.env.example
Normal file
24
.env.example
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
# MySQL (docker-compose)
|
||||||
|
MYSQL_ROOT_PASSWORD=rootpassword
|
||||||
|
MYSQL_DATABASE=esameits24-26
|
||||||
|
MYSQL_USER=esameits
|
||||||
|
MYSQL_PASSWORD=esameits_password
|
||||||
|
|
||||||
|
# Server
|
||||||
|
PORT=3011
|
||||||
|
NODE_ENV=development
|
||||||
|
|
||||||
|
# Database (sviluppo locale senza Docker: usa localhost)
|
||||||
|
DB_HOST=localhost
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_NAME=esameits24-26
|
||||||
|
DB_USER=esameits
|
||||||
|
DB_PASSWORD=esameits_password
|
||||||
|
|
||||||
|
# Auth.js
|
||||||
|
AUTH_SECRET=cambia-con-stringa-casuale-lunga
|
||||||
|
AUTH_URL=http://localhost:3011
|
||||||
|
AUTH_TRUST_HOST=true
|
||||||
|
|
||||||
|
# CORS — origine del frontend
|
||||||
|
FRONTEND_URL=http://localhost:5173
|
||||||
34
.github/workflows/deploy.yml
vendored
34
.github/workflows/deploy.yml
vendored
|
|
@ -9,38 +9,32 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- uses: https://github.com/actions/checkout@v4
|
||||||
uses: https://github.com/actions/checkout@v4
|
- uses: https://github.com/actions/setup-node@v4
|
||||||
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: https://github.com/actions/setup-node@v4
|
|
||||||
with:
|
with:
|
||||||
node-version: "20"
|
node-version: "20"
|
||||||
|
- run: npm ci --prefer-offline
|
||||||
- name: Install dependencies
|
- run: npm run build
|
||||||
run: npm ci --prefer-offline
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: npm run build
|
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- uses: https://github.com/actions/checkout@v4
|
||||||
uses: https://github.com/actions/checkout@v4
|
- uses: https://github.com/appleboy/ssh-action@v1.0.3
|
||||||
|
|
||||||
- name: Deploy via SSH
|
|
||||||
uses: https://github.com/appleboy/ssh-action@v1.0.3
|
|
||||||
with:
|
with:
|
||||||
host: ${{ secrets.VPS_HOST }}
|
host: ${{ secrets.VPS_HOST }}
|
||||||
username: ${{ secrets.VPS_USER }}
|
username: ${{ secrets.VPS_USER }}
|
||||||
key: ${{ secrets.VPS_SSH_KEY }}
|
key: ${{ secrets.VPS_SSH_KEY }}
|
||||||
|
command_timeout: 30m
|
||||||
script: |
|
script: |
|
||||||
echo "START DEPLOY"
|
echo "=== START $(date -Iseconds) ==="
|
||||||
cd /root/esameits24-26backend
|
cd /root/esameits24-26backend
|
||||||
git pull --ff-only
|
git pull --ff-only
|
||||||
docker compose up -d --build
|
echo "=== DOCKER BUILD $(date -Iseconds) ==="
|
||||||
|
docker compose --progress plain up -d --build
|
||||||
|
echo "=== END $(date -Iseconds) ==="
|
||||||
|
docker compose ps
|
||||||
|
echo "DEPLOY COMPLETE"
|
||||||
|
|
|
||||||
173
README.md
Normal file
173
README.md
Normal file
|
|
@ -0,0 +1,173 @@
|
||||||
|
# Academy Aziendale — Backend
|
||||||
|
|
||||||
|
API REST per la piattaforma formativa interna (esame ITS Web Developer Full Stack 24-26, Prova C).
|
||||||
|
|
||||||
|
Gestisce autenticazione, catalogo corsi, assegnazioni ai dipendenti e statistiche per il Referente Academy.
|
||||||
|
|
||||||
|
## URL produzione
|
||||||
|
|
||||||
|
| Risorsa | URL |
|
||||||
|
|---------|-----|
|
||||||
|
| API | https://esameits24-26backend.andreavillari.it |
|
||||||
|
| Swagger UI | https://esameits24-26backend.andreavillari.it/api/docs |
|
||||||
|
| OpenAPI JSON | https://esameits24-26backend.andreavillari.it/api/docs.json |
|
||||||
|
| Health check | https://esameits24-26backend.andreavillari.it/api/health |
|
||||||
|
| Frontend | https://esameits24-26frontend.andreavillari.it |
|
||||||
|
|
||||||
|
## Stack tecnologico
|
||||||
|
|
||||||
|
- Node.js 20 + TypeScript (ESM)
|
||||||
|
- Express 5
|
||||||
|
- MySQL 8
|
||||||
|
- Auth.js (`@auth/express`) con sessione JWT e cookie
|
||||||
|
- Swagger UI per la documentazione API
|
||||||
|
|
||||||
|
## Credenziali di test
|
||||||
|
|
||||||
|
Password per tutti gli utenti: `Password123!`
|
||||||
|
|
||||||
|
| Email | Ruolo |
|
||||||
|
|-------|-------|
|
||||||
|
| `admin@academy.it` | Referente Academy |
|
||||||
|
| `maria.bianchi@academy.it` | Dipendente |
|
||||||
|
| `luca.conti@academy.it` | Dipendente |
|
||||||
|
| `elena.rossi@academy.it` | Dipendente |
|
||||||
|
|
||||||
|
## Ruoli e permessi
|
||||||
|
|
||||||
|
| Ruolo | Accesso API |
|
||||||
|
|-------|-------------|
|
||||||
|
| **Dipendente** | Profilo, corsi (lettura), proprie assegnazioni, completamento corso |
|
||||||
|
| **Referente Academy** | Tutto il precedente + CRUD utenti/corsi/assegnazioni, statistiche |
|
||||||
|
|
||||||
|
## Avvio con Docker (consigliato)
|
||||||
|
|
||||||
|
### Prerequisiti
|
||||||
|
|
||||||
|
- Docker e Docker Compose
|
||||||
|
|
||||||
|
### Configurazione
|
||||||
|
|
||||||
|
Crea un file `.env` nella root del backend (non committare):
|
||||||
|
|
||||||
|
```env
|
||||||
|
MYSQL_ROOT_PASSWORD=rootpassword
|
||||||
|
MYSQL_DATABASE=esameits24-26
|
||||||
|
MYSQL_USER=esameits
|
||||||
|
MYSQL_PASSWORD=esameits_password
|
||||||
|
|
||||||
|
AUTH_SECRET=genera-un-segreto-lungo-e-casuale
|
||||||
|
FRONTEND_URL=http://localhost:5173
|
||||||
|
AUTH_URL=http://localhost:3011
|
||||||
|
AUTH_TRUST_HOST=true
|
||||||
|
```
|
||||||
|
|
||||||
|
### Comandi
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
Servizi avviati:
|
||||||
|
|
||||||
|
| Servizio | Porta locale |
|
||||||
|
|----------|--------------|
|
||||||
|
| API | http://127.0.0.1:3011 |
|
||||||
|
| MySQL | 127.0.0.1:3311 |
|
||||||
|
| phpMyAdmin | http://127.0.0.1:8086 |
|
||||||
|
|
||||||
|
Al primo avvio, gli script in `initdb/` creano schema e dati di test.
|
||||||
|
|
||||||
|
## Avvio in sviluppo (senza Docker)
|
||||||
|
|
||||||
|
### Prerequisiti
|
||||||
|
|
||||||
|
- Node.js 20+
|
||||||
|
- MySQL 8 con database `esameits24-26` inizializzato (`initdb/01_schema.sql` e `02_seed.sql`)
|
||||||
|
|
||||||
|
### Comandi
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm ci
|
||||||
|
cp .env.example .env
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Il server di default ascolta su `http://localhost:3001` (o la porta impostata in `PORT`).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
## Variabili d'ambiente
|
||||||
|
|
||||||
|
| Variabile | Descrizione | Esempio |
|
||||||
|
|-----------|-------------|---------|
|
||||||
|
| `PORT` | Porta HTTP del server | `3011` |
|
||||||
|
| `DB_HOST` | Host MySQL | `localhost` / `mysql` |
|
||||||
|
| `DB_PORT` | Porta MySQL | `3306` |
|
||||||
|
| `DB_NAME` | Nome database | `esameits24-26` |
|
||||||
|
| `DB_USER` | Utente MySQL | `esameits` |
|
||||||
|
| `DB_PASSWORD` | Password MySQL | — |
|
||||||
|
| `AUTH_SECRET` | Segreto per JWT Auth.js | stringa casuale lunga |
|
||||||
|
| `AUTH_URL` | URL pubblico del backend | `https://esameits24-26backend.andreavillari.it` |
|
||||||
|
| `AUTH_TRUST_HOST` | Trust proxy/host header | `true` |
|
||||||
|
| `FRONTEND_URL` | Origine CORS del frontend | `https://esameits24-26frontend.andreavillari.it` |
|
||||||
|
| `NODE_ENV` | Ambiente | `development` / `production` |
|
||||||
|
|
||||||
|
## Endpoint principali
|
||||||
|
|
||||||
|
| Metodo | Percorso | Note |
|
||||||
|
|--------|----------|------|
|
||||||
|
| GET | `/api/health` | Stato servizio |
|
||||||
|
| GET | `/api/docs` | Swagger UI |
|
||||||
|
| POST | `/api/auth/callback/credentials` | Login |
|
||||||
|
| POST | `/api/auth/signout` | Logout |
|
||||||
|
| GET | `/api/me` | Profilo utente autenticato |
|
||||||
|
| CRUD | `/api/utenti` | Solo Referente Academy |
|
||||||
|
| CRUD | `/api/corsi` | Lettura: tutti; scrittura: Referente |
|
||||||
|
| CRUD | `/api/assegnazioni-corsi` | Dipendente vede solo le proprie |
|
||||||
|
| PUT | `/api/assegnazioni-corsi/:id/completa` | Solo il dipendente assegnatario |
|
||||||
|
| GET | `/api/statistiche/academy` | Solo Referente Academy |
|
||||||
|
|
||||||
|
Documentazione completa e parametri di query in Swagger.
|
||||||
|
|
||||||
|
## Struttura progetto
|
||||||
|
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
auth/ Configurazione Auth.js
|
||||||
|
config/ CORS, OpenAPI, Swagger
|
||||||
|
db/ Pool MySQL
|
||||||
|
middleware/ Autenticazione e autorizzazione
|
||||||
|
routes/ Router Express
|
||||||
|
validation/ Validazione input
|
||||||
|
initdb/ Schema e seed SQL
|
||||||
|
scripts/ Script di migrazione manuale
|
||||||
|
dockerfile/ Dockerfile produzione
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validazione errori
|
||||||
|
|
||||||
|
Il backend restituisce errori in JSON, ad esempio:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"error": "Data di scadenza non valida",
|
||||||
|
"fields": {
|
||||||
|
"dataScadenza": "La data di scadenza non può essere precedente alla data di assegnazione"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deploy
|
||||||
|
|
||||||
|
Il deploy su VPS è automatizzato tramite Forgejo Actions (`.github/workflows/deploy.yml`):
|
||||||
|
|
||||||
|
1. Build TypeScript su runner CI
|
||||||
|
2. SSH sul VPS → `git pull` → `docker compose up -d --build`
|
||||||
|
|
||||||
|
## Autore
|
||||||
|
|
||||||
|
Andrea Villari — esame ITS 24-26
|
||||||
|
|
@ -3,7 +3,7 @@ import cors from "cors";
|
||||||
const allowedOrigins = [
|
const allowedOrigins = [
|
||||||
"http://localhost:5173",
|
"http://localhost:5173",
|
||||||
"http://127.0.0.1:5173",
|
"http://127.0.0.1:5173",
|
||||||
"https://corrierifrontend.andreavillari.it",
|
"https://esameits24-26frontend.andreavillari.it",
|
||||||
process.env.FRONTEND_URL,
|
process.env.FRONTEND_URL,
|
||||||
].filter(Boolean) as string[];
|
].filter(Boolean) as string[];
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue