diff --git a/.github/README.md b/.github/README.md
index 2a6b238..3d1e429 100644
--- a/.github/README.md
+++ b/.github/README.md
@@ -1,191 +1,191 @@
-# GitHub Actions CI Pipeline
-
-Questo workflow automatizza la pipeline di **Continuous Integration** per il progetto HomeCloud.
-
-> **ℹ️ Build & Deploy**: Gestiti automaticamente da **AWS Amplify** ad ogni push su `main`
-> Questa pipeline CI si concentra su **qualità del codice** e **validazione**.
-
-## 🚀 Trigger
-
-La pipeline si attiva automaticamente per:
-
-- ✅ **Push** su branch `main`
-- ✅ **Pull Request** verso `main`
-
-## 🔧 Jobs della Pipeline
-
-### 1. **Setup & Install Dependencies**
-
-- Configura Node.js 18 e pnpm 8
-- Cache intelligente delle dipendenze
-- Installazione con `pnpm install --frozen-lockfile`
-
-### 2. **Lint Code**
-
-- ESLint per il controllo qualità del codice
-- Verifica formattazione Prettier (se configurato)
-- **Fallisce** se ci sono errori di linting
-
-### 3. **Test Frontend**
-
-- Esegue tutti i test React con Jest
-- Genera report di copertura del codice
-- Carica artifacts per analisi
-
-### 4. **Test Backend Functions**
-
-- Valida la struttura delle funzioni Lambda AWS
-- Prepara l'infrastruttura per test futuri
-- **Non fallisce** la pipeline (informativo)
-
-### 5. **Security Scan** (parallelo, solo per main/PR)
-
-- Audit delle dipendenze npm/pnpm
-- Scansione per secrets nel codice
-- **Solo** per PR e push su main
-
-### 6. **Amplify Validation** (parallelo, solo per main/PR)
-
-- Verifica configurazione AWS Amplify
-- Controlla sintassi file JSON
-- Lista funzioni Lambda disponibili
-
-### 7. **Pipeline Summary** (finale)
-
-- Genera report finale con stato di tutti i job
-- Visibile nella tab "Summary" di GitHub Actions
-
-## 📊 Status e Artifacts
-
-La pipeline genera:
-
-- **Coverage Report**: `coverage/` (7 giorni)
-- **Pipeline Summary**: Report finale con tutti gli stati
-
-> **ℹ️ Build & Deploy**: Gestiti automaticamente da AWS Amplify
-
-## 🔄 Flusso di Lavoro
-
-````mermaid
-graph TD
- A[Push/PR] --> B[Setup]
- B --> C[Lint]
- B --> D[Frontend Tests]
- B --> E[Backend Tests]
- B --> F[Security Scan]
- B --> G[Amplify Validation]
-
- C --> H[Summary]
- D --> H
- E --> H
- F --> H
- G --> H
-
- H --> I[AWS Amplify Auto-Deploy]
- I --> J[✅ Production]
-```## ⚡ Ottimizzazioni
-
-- **Cache pnpm**: Velocizza installazioni ripetute
-- **Jobs paralleli**: Setup, lint, test e security girano in parallelo
-- **Condizioni smart**: Build solo se lint/test passano
-- **Artifacts ottimizzati**: Retention di 7 giorni
-
-## 🛠 Estensioni Future
-
-### Backend Testing
-
-```bash
-# Aggiungere test per funzioni Lambda
-mkdir -p .github/tests/backend/unit
-# Esempio: createDeadline.test.js, readUsers.test.js, etc.
-````
-
-### Multi-Environment Deploy
-
-```yaml
-# Aggiungere job per deploy staging/production
-deploy-staging:
- if: github.ref == 'refs/heads/develop'
- # Deploy logic
-```
-
-### Performance Testing
-
-```yaml
-# Aggiungere Lighthouse CI
-lighthouse:
- needs: build
- # Performance analysis
-```
-
-## 🚨 Troubleshooting
-
-### Pipeline fallisce al Lint
-
-```bash
-# Locale: Fix errori ESLint
-npx eslint src/ --fix
-```
-
-### Test falliscono
-
-```bash
-# Locale: Run test in modalità interattiva
-pnpm test
-```
-
-### Build fallisce
-
-```bash
-# Locale: Test build
-pnpm run build
-```
-
-### Security scan rileva vulnerabilità
-
-```bash
-# Fix dipendenze vulnerabili
-pnpm audit --fix
-```
-
-## 📝 Configurazione Consigliata
-
-### ESLint (già configurato)
-
-Il progetto usa `eslint-config-react-app` - configurazione ottimale per React.
-
-### Prettier (opzionale)
-
-```json
-// .prettierrc
-{
- "semi": true,
- "trailingComma": "all",
- "singleQuote": true,
- "printWidth": 80,
- "tabWidth": 2
-}
-```
-
-### VS Code Settings
-
-```json
-// .vscode/settings.json
-{
- "editor.formatOnSave": true,
- "editor.codeActionsOnSave": {
- "source.fixAll.eslint": true
- }
-}
-```
-
-## 🎯 Next Steps
-
-1. **Commit** questo workflow
-2. **Crea una PR** per testare la pipeline
-3. **Verifica** che tutti i job passino
-4. **Estendi** con test backend quando necessario
-
----
-
-> **Nota**: La pipeline è progettata per essere **non-bloccante** per il workflow di sviluppo, ma **rigorosa** per la qualità del codice in produzione.
+# GitHub Actions CI Pipeline
+
+Questo workflow automatizza la pipeline di **Continuous Integration** per il progetto HomeCloud.
+
+> **ℹ️ Build & Deploy**: Gestiti automaticamente da **AWS Amplify** ad ogni push su `main`
+> Questa pipeline CI si concentra su **qualità del codice** e **validazione**.
+
+## 🚀 Trigger
+
+La pipeline si attiva automaticamente per:
+
+- ✅ **Push** su branch `main`
+- ✅ **Pull Request** verso `main`
+
+## 🔧 Jobs della Pipeline
+
+### 1. **Setup & Install Dependencies**
+
+- Configura Node.js 18 e pnpm 8
+- Cache intelligente delle dipendenze
+- Installazione con `pnpm install --frozen-lockfile`
+
+### 2. **Lint Code**
+
+- ESLint per il controllo qualità del codice
+- Verifica formattazione Prettier (se configurato)
+- **Fallisce** se ci sono errori di linting
+
+### 3. **Test Frontend**
+
+- Esegue tutti i test React con Jest
+- Genera report di copertura del codice
+- Carica artifacts per analisi
+
+### 4. **Test Backend Functions**
+
+- Valida la struttura delle funzioni Lambda AWS
+- Prepara l'infrastruttura per test futuri
+- **Non fallisce** la pipeline (informativo)
+
+### 5. **Security Scan** (parallelo, solo per main/PR)
+
+- Audit delle dipendenze npm/pnpm
+- Scansione per secrets nel codice
+- **Solo** per PR e push su main
+
+### 6. **Amplify Validation** (parallelo, solo per main/PR)
+
+- Verifica configurazione AWS Amplify
+- Controlla sintassi file JSON
+- Lista funzioni Lambda disponibili
+
+### 7. **Pipeline Summary** (finale)
+
+- Genera report finale con stato di tutti i job
+- Visibile nella tab "Summary" di GitHub Actions
+
+## 📊 Status e Artifacts
+
+La pipeline genera:
+
+- **Coverage Report**: `coverage/` (7 giorni)
+- **Pipeline Summary**: Report finale con tutti gli stati
+
+> **ℹ️ Build & Deploy**: Gestiti automaticamente da AWS Amplify
+
+## 🔄 Flusso di Lavoro
+
+````mermaid
+graph TD
+ A[Push/PR] --> B[Setup]
+ B --> C[Lint]
+ B --> D[Frontend Tests]
+ B --> E[Backend Tests]
+ B --> F[Security Scan]
+ B --> G[Amplify Validation]
+
+ C --> H[Summary]
+ D --> H
+ E --> H
+ F --> H
+ G --> H
+
+ H --> I[AWS Amplify Auto-Deploy]
+ I --> J[✅ Production]
+```## ⚡ Ottimizzazioni
+
+- **Cache pnpm**: Velocizza installazioni ripetute
+- **Jobs paralleli**: Setup, lint, test e security girano in parallelo
+- **Condizioni smart**: Build solo se lint/test passano
+- **Artifacts ottimizzati**: Retention di 7 giorni
+
+## 🛠 Estensioni Future
+
+### Backend Testing
+
+```bash
+# Aggiungere test per funzioni Lambda
+mkdir -p .github/tests/backend/unit
+# Esempio: createDeadline.test.js, readUsers.test.js, etc.
+````
+
+### Multi-Environment Deploy
+
+```yaml
+# Aggiungere job per deploy staging/production
+deploy-staging:
+ if: github.ref == 'refs/heads/develop'
+ # Deploy logic
+```
+
+### Performance Testing
+
+```yaml
+# Aggiungere Lighthouse CI
+lighthouse:
+ needs: build
+ # Performance analysis
+```
+
+## 🚨 Troubleshooting
+
+### Pipeline fallisce al Lint
+
+```bash
+# Locale: Fix errori ESLint
+npx eslint src/ --fix
+```
+
+### Test falliscono
+
+```bash
+# Locale: Run test in modalità interattiva
+pnpm test
+```
+
+### Build fallisce
+
+```bash
+# Locale: Test build
+pnpm run build
+```
+
+### Security scan rileva vulnerabilità
+
+```bash
+# Fix dipendenze vulnerabili
+pnpm audit --fix
+```
+
+## 📝 Configurazione Consigliata
+
+### ESLint (già configurato)
+
+Il progetto usa `eslint-config-react-app` - configurazione ottimale per React.
+
+### Prettier (opzionale)
+
+```json
+// .prettierrc
+{
+ "semi": true,
+ "trailingComma": "all",
+ "singleQuote": true,
+ "printWidth": 80,
+ "tabWidth": 2
+}
+```
+
+### VS Code Settings
+
+```json
+// .vscode/settings.json
+{
+ "editor.formatOnSave": true,
+ "editor.codeActionsOnSave": {
+ "source.fixAll.eslint": true
+ }
+}
+```
+
+## 🎯 Next Steps
+
+1. **Commit** questo workflow
+2. **Crea una PR** per testare la pipeline
+3. **Verifica** che tutti i job passino
+4. **Estendi** con test backend quando necessario
+
+---
+
+> **Nota**: La pipeline è progettata per essere **non-bloccante** per il workflow di sviluppo, ma **rigorosa** per la qualità del codice in produzione.
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f8dcdbf..84ff350 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,352 +1,374 @@
-name: CI Pipeline
-
-on:
- push:
- branches: [main]
- pull_request:
- branches: [main]
-
-env:
- NODE_VERSION: "18"
- PNPM_VERSION: "8"
-
-jobs:
- setup:
- name: Setup & Install Dependencies
- runs-on: ubuntu-latest
- outputs:
- cache-key: ${{ steps.cache-key.outputs.key }}
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
-
- - name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- node-version: ${{ env.NODE_VERSION }}
-
- - name: Setup pnpm
- uses: pnpm/action-setup@v2
- with:
- version: ${{ env.PNPM_VERSION }}
-
- - name: Get pnpm store directory
- id: pnpm-cache
- shell: bash
- run: |
- echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
-
- - name: Generate cache key
- id: cache-key
- run: |
- echo "key=pnpm-${{ hashFiles('**/package.json') }}" >> $GITHUB_OUTPUT
-
- - name: Cache pnpm dependencies
- uses: actions/cache@v3
- with:
- path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
- key: ${{ steps.cache-key.outputs.key }}
- restore-keys: |
- pnpm-
-
- - name: Install dependencies
- run: pnpm install
-
- lint:
- name: Lint Code
- runs-on: ubuntu-latest
- needs: setup
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
-
- - name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- node-version: ${{ env.NODE_VERSION }}
-
- - name: Setup pnpm
- uses: pnpm/action-setup@v2
- with:
- version: ${{ env.PNPM_VERSION }}
-
- - name: Get pnpm store directory
- id: pnpm-cache
- shell: bash
- run: |
- echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
-
- - name: Restore pnpm cache
- uses: actions/cache@v3
- with:
- path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
- key: ${{ needs.setup.outputs.cache-key }}
-
- - name: Install dependencies
- run: pnpm install
-
- - name: Run ESLint
- run: npx eslint src/ --ext .js,.jsx,.ts,.tsx --max-warnings 0
- continue-on-error: false
-
- - name: Check code formatting (if Prettier is configured)
- run: |
- if [ -f ".prettierrc" ] || [ -f ".prettierrc.json" ] || [ -f "prettier.config.js" ]; then
- echo "Prettier configuration found, checking formatting..."
- npx prettier --check "src/**/*.{js,jsx,ts,tsx,json,css,md}"
- else
- echo "No Prettier configuration found, skipping formatting check"
- fi
- continue-on-error: true
-
- test-frontend:
- name: Test Frontend
- runs-on: ubuntu-latest
- needs: setup
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
-
- - name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- node-version: ${{ env.NODE_VERSION }}
-
- - name: Setup pnpm
- uses: pnpm/action-setup@v2
- with:
- version: ${{ env.PNPM_VERSION }}
-
- - name: Get pnpm store directory
- id: pnpm-cache
- shell: bash
- run: |
- echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
-
- - name: Restore pnpm cache
- uses: actions/cache@v3
- with:
- path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
- key: ${{ needs.setup.outputs.cache-key }}
-
- - name: Install dependencies
- run: pnpm install
-
- - name: Run tests
- run: pnpm test -- --coverage --watchAll=false
- env:
- CI: true
-
- - name: Upload coverage reports
- if: always()
- uses: actions/upload-artifact@v3
- with:
- name: coverage-report
- path: coverage/
- retention-days: 7
-
- test-backend:
- name: Test Backend Functions
- runs-on: ubuntu-latest
- needs: setup
- if: always()
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
-
- - name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- node-version: ${{ env.NODE_VERSION }}
-
- - name: Setup pnpm
- uses: pnpm/action-setup@v2
- with:
- version: ${{ env.PNPM_VERSION }}
-
- - name: Test Lambda Functions Structure
- run: |
- echo "🔍 Checking Lambda functions structure..."
-
- # Check if Lambda functions exist
- if [ -d "amplify/backend/function" ]; then
- echo "✅ Lambda functions directory found"
-
- # List all Lambda functions
- echo "📋 Available Lambda functions:"
- find amplify/backend/function -maxdepth 1 -type d -not -path "amplify/backend/function" | while read dir; do
- func_name=$(basename "$dir")
- echo " - $func_name"
-
- # Check if package.json exists
- if [ -f "$dir/src/package.json" ]; then
- echo " ✅ package.json found"
- else
- echo " ⚠️ package.json not found"
- fi
-
- # Check if index.js exists
- if [ -f "$dir/src/index.js" ]; then
- echo " ✅ index.js found"
- else
- echo " ⚠️ index.js not found"
- fi
- done
- else
- echo "❌ No Lambda functions directory found"
- exit 1
- fi
-
- - name: Install Lambda Dependencies (Future Test Setup)
- run: |
- echo "🔧 Setting up future backend testing structure..."
-
- # Create a test structure for future backend tests
- mkdir -p .github/tests/backend
-
- cat > .github/tests/backend/README.md << 'EOF'
- # Backend Testing Setup
-
- This directory is prepared for future Lambda function tests.
-
- ## Structure
- ```
- .github/tests/backend/
- ├── unit/ # Unit tests for individual functions
- ├── integration/ # Integration tests
- └── utils/ # Test utilities and helpers
- ```
-
- ## Adding Tests
-
- 1. For each Lambda function in `amplify/backend/function/`, create corresponding test files
- 2. Use Jest or your preferred testing framework
- 3. Test both business logic and AWS integration points
-
- ## Example Test Structure
- ```javascript
- // .github/tests/backend/unit/createDeadline.test.js
- const { handler } = require('../../../amplify/backend/function/createDeadline/src/index');
-
- describe('createDeadline Lambda', () => {
- test('should validate input correctly', () => {
- // Test implementation
- });
- });
- ```
- EOF
-
- echo "📁 Backend test structure created for future use"
-
- security-scan:
- name: Security Scan
- runs-on: ubuntu-latest
- needs: setup
- if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main'
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
-
- - name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- node-version: ${{ env.NODE_VERSION }}
-
- - name: Setup pnpm
- uses: pnpm/action-setup@v2
- with:
- version: ${{ env.PNPM_VERSION }}
-
- - name: Run npm audit
- run: pnpm audit --audit-level moderate
- continue-on-error: true
-
- - name: Check for secrets
- uses: trufflesecurity/trufflehog@main
- with:
- path: ./
- base: main
- head: HEAD
- extra_args: --debug --only-verified
-
- amplify-validation:
- name: Validate Amplify Configuration
- runs-on: ubuntu-latest
- if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main'
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
-
- - name: Validate Amplify Structure
- run: |
- echo "🔍 Validating Amplify project structure..."
-
- # Check required Amplify files
- required_files=(
- "amplify/cli.json"
- "amplify/backend/backend-config.json"
- "amplify.yml"
- )
-
- for file in "${required_files[@]}"; do
- if [ -f "$file" ]; then
- echo "✅ $file exists"
- else
- echo "❌ $file is missing"
- exit 1
- fi
- done
-
- # Validate backend-config.json syntax
- if ! jq empty amplify/backend/backend-config.json; then
- echo "❌ Invalid JSON in backend-config.json"
- exit 1
- else
- echo "✅ backend-config.json is valid JSON"
- fi
-
- # Check Lambda functions
- echo "📋 Lambda functions found:"
- if [ -d "amplify/backend/function" ]; then
- find amplify/backend/function -maxdepth 1 -type d -not -path "amplify/backend/function" | while read dir; do
- echo " - $(basename "$dir")"
- done
- fi
-
- summary:
- name: Pipeline Summary
- runs-on: ubuntu-latest
- needs:
- [
- setup,
- lint,
- test-frontend,
- test-backend,
- security-scan,
- amplify-validation,
- ]
- if: always()
- steps:
- - name: Generate Summary
- run: |
- echo "## 🚀 Pipeline Results" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY
- echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY
- echo "| Setup | ${{ needs.setup.result }} |" >> $GITHUB_STEP_SUMMARY
- echo "| Lint | ${{ needs.lint.result }} |" >> $GITHUB_STEP_SUMMARY
- echo "| Frontend Tests | ${{ needs.test-frontend.result }} |" >> $GITHUB_STEP_SUMMARY
- echo "| Backend Tests | ${{ needs.test-backend.result }} |" >> $GITHUB_STEP_SUMMARY
- echo "| Security Scan | ${{ needs.security-scan.result }} |" >> $GITHUB_STEP_SUMMARY
- echo "| Amplify Validation | ${{ needs.amplify-validation.result }} |" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**ℹ️ Build & Deploy**: Automatically managed by AWS Amplify on every push to \`main\`" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- if [[ "${{ needs.lint.result }}" == "success" && "${{ needs.test-frontend.result }}" == "success" ]]; then
- echo "✅ **CI pipeline completed successfully!**" >> $GITHUB_STEP_SUMMARY
- echo "🚀 **Code is ready for automatic Amplify deploy**" >> $GITHUB_STEP_SUMMARY
- else
- echo "❌ **CI pipeline failed. Check the jobs above.**" >> $GITHUB_STEP_SUMMARY
- echo "⚠️ **Amplify deploy may fail if there are critical errors**" >> $GITHUB_STEP_SUMMARY
- fi
+name: CI Pipeline
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+env:
+ NODE_VERSION: "18"
+ PNPM_VERSION: "8"
+
+jobs:
+ setup:
+ name: Setup & Install Dependencies
+ runs-on: ubuntu-latest
+ outputs:
+ cache-key: ${{ steps.cache-key.outputs.key }}
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v2
+ with:
+ version: ${{ env.PNPM_VERSION }}
+
+ - name: Get pnpm store directory
+ id: pnpm-cache
+ shell: bash
+ run: |
+ echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
+
+ - name: Generate cache key
+ id: cache-key
+ run: |
+ echo "key=pnpm-${{ hashFiles('**/package.json') }}" >> $GITHUB_OUTPUT
+
+ - name: Cache pnpm dependencies
+ uses: actions/cache@v4
+ with:
+ path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
+ key: ${{ steps.cache-key.outputs.key }}
+ restore-keys: |
+ pnpm-
+
+ - name: Install dependencies
+ run: pnpm install
+
+ lint:
+ name: Lint Code
+ runs-on: ubuntu-latest
+ needs: setup
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v2
+ with:
+ version: ${{ env.PNPM_VERSION }}
+
+ - name: Get pnpm store directory
+ id: pnpm-cache
+ shell: bash
+ run: |
+ echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
+
+ - name: Restore pnpm cache
+ uses: actions/cache@v4
+ with:
+ path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
+ key: ${{ needs.setup.outputs.cache-key }}
+
+ - name: Install dependencies
+ run: pnpm install
+
+ - name: Run ESLint
+ run: npx eslint src/ --ext .js,.jsx,.ts,.tsx --max-warnings 0
+ continue-on-error: false
+
+ - name: Check code formatting (if Prettier is configured)
+ run: |
+ if [ -f ".prettierrc" ] || [ -f ".prettierrc.json" ] || [ -f "prettier.config.js" ]; then
+ echo "Prettier configuration found, checking formatting..."
+ npx prettier --check "src/**/*.{js,jsx,ts,tsx,json,css,md}"
+ else
+ echo "No Prettier configuration found, skipping formatting check"
+ fi
+ continue-on-error: true
+
+ test-frontend:
+ name: Test Frontend
+ runs-on: ubuntu-latest
+ needs: setup
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v2
+ with:
+ version: ${{ env.PNPM_VERSION }}
+
+ - name: Get pnpm store directory
+ id: pnpm-cache
+ shell: bash
+ run: |
+ echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
+
+ - name: Restore pnpm cache
+ uses: actions/cache@v4
+ with:
+ path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
+ key: ${{ needs.setup.outputs.cache-key }}
+
+ - name: Install dependencies
+ run: pnpm install
+
+ - name: Run tests
+ run: pnpm test -- --coverage --watchAll=false
+ env:
+ CI: true
+
+ - name: Upload coverage reports
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: coverage-report
+ path: coverage/
+ retention-days: 7
+
+ test-backend:
+ name: Test Backend Functions
+ runs-on: ubuntu-latest
+ needs: setup
+ if: always()
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v2
+ with:
+ version: ${{ env.PNPM_VERSION }}
+
+ - name: Test Lambda Functions Structure
+ run: |
+ echo "🔍 Checking Lambda functions structure..."
+
+ # Check if Lambda functions exist
+ if [ -d "amplify/backend/function" ]; then
+ echo "✅ Lambda functions directory found"
+
+ # List all Lambda functions
+ echo "📋 Available Lambda functions:"
+ find amplify/backend/function -maxdepth 1 -type d -not -path "amplify/backend/function" | while read dir; do
+ func_name=$(basename "$dir")
+ echo " - $func_name"
+
+ # Check if package.json exists
+ if [ -f "$dir/src/package.json" ]; then
+ echo " ✅ package.json found"
+ else
+ echo " ⚠️ package.json not found"
+ fi
+
+ # Check if index.js exists
+ if [ -f "$dir/src/index.js" ]; then
+ echo " ✅ index.js found"
+ else
+ echo " ⚠️ index.js not found"
+ fi
+ done
+ else
+ echo "❌ No Lambda functions directory found"
+ exit 1
+ fi
+
+ - name: Install Lambda Dependencies (Future Test Setup)
+ run: |
+ echo "🔧 Setting up future backend testing structure..."
+
+ # Create a test structure for future backend tests
+ mkdir -p .github/tests/backend
+
+ cat > .github/tests/backend/README.md << 'EOF'
+ # Backend Testing Setup
+
+ This directory is prepared for future Lambda function tests.
+
+ ## Structure
+ ```
+ .github/tests/backend/
+ ├── unit/ # Unit tests for individual functions
+ ├── integration/ # Integration tests
+ └── utils/ # Test utilities and helpers
+ ```
+
+ ## Adding Tests
+
+ 1. For each Lambda function in `amplify/backend/function/`, create corresponding test files
+ 2. Use Jest or your preferred testing framework
+ 3. Test both business logic and AWS integration points
+
+ ## Example Test Structure
+ ```javascript
+ // .github/tests/backend/unit/createDeadline.test.js
+ const { handler } = require('../../../amplify/backend/function/createDeadline/src/index');
+
+ describe('createDeadline Lambda', () => {
+ test('should validate input correctly', () => {
+ // Test implementation
+ });
+ });
+ ```
+ EOF
+
+ echo "📁 Backend test structure created for future use"
+
+ security-scan:
+ name: Security Scan
+ runs-on: ubuntu-latest
+ if: github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/main')
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v2
+ with:
+ version: 8
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: 18
+ cache: "pnpm"
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Run security audit
+ run: |
+ echo "Running pnpm audit..."
+ pnpm audit --audit-level moderate || {
+ echo "Security vulnerabilities found. Checking severity..."
+ if pnpm audit --audit-level high; then
+ echo "High severity vulnerabilities found!"
+ exit 1
+ else
+ echo "Only low/moderate vulnerabilities found - proceeding"
+ exit 0
+ fi
+ }
+
+ - name: Check for secrets (simple grep)
+ run: |
+ echo "Checking for potential secrets..."
+ # Verifica pattern comuni di secrets
+ if grep -r -i --exclude-dir=node_modules --exclude-dir=.git \
+ -E "(password|secret|key|token|api_key).*=.*['\"][^'\"]{10,}['\"]" . || \
+ grep -r --exclude-dir=node_modules --exclude-dir=.git \
+ -E "AKIA[0-9A-Z]{16}" . || \
+ grep -r --exclude-dir=node_modules --exclude-dir=.git \
+ -E "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" .; then
+ echo "⚠️ Potential secrets detected!"
+ echo "Please review the above matches and ensure no sensitive data is committed."
+ # Non facciamo fallire la pipeline, solo warning
+ else
+ echo "✅ No obvious secrets detected"
+ fi
+
+ amplify-validation:
+ name: Validate Amplify Configuration
+ runs-on: ubuntu-latest
+ if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main'
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Validate Amplify Structure
+ run: |
+ echo "🔍 Validating Amplify project structure..."
+
+ # Check required Amplify files
+ required_files=(
+ "amplify/cli.json"
+ "amplify/backend/backend-config.json"
+ "amplify.yml"
+ )
+
+ for file in "${required_files[@]}"; do
+ if [ -f "$file" ]; then
+ echo "✅ $file exists"
+ else
+ echo "❌ $file is missing"
+ exit 1
+ fi
+ done
+
+ # Validate backend-config.json syntax
+ if ! jq empty amplify/backend/backend-config.json; then
+ echo "❌ Invalid JSON in backend-config.json"
+ exit 1
+ else
+ echo "✅ backend-config.json is valid JSON"
+ fi
+
+ # Check Lambda functions
+ echo "📋 Lambda functions found:"
+ if [ -d "amplify/backend/function" ]; then
+ find amplify/backend/function -maxdepth 1 -type d -not -path "amplify/backend/function" | while read dir; do
+ echo " - $(basename "$dir")"
+ done
+ fi
+
+ summary:
+ name: Pipeline Summary
+ runs-on: ubuntu-latest
+ needs:
+ [
+ setup,
+ lint,
+ test-frontend,
+ test-backend,
+ security-scan,
+ amplify-validation,
+ ]
+ if: always()
+ steps:
+ - name: Generate Summary
+ run: |
+ echo "## 🚀 Pipeline Results" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY
+ echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY
+ echo "| Setup | ${{ needs.setup.result }} |" >> $GITHUB_STEP_SUMMARY
+ echo "| Lint | ${{ needs.lint.result }} |" >> $GITHUB_STEP_SUMMARY
+ echo "| Frontend Tests | ${{ needs.test-frontend.result }} |" >> $GITHUB_STEP_SUMMARY
+ echo "| Backend Tests | ${{ needs.test-backend.result }} |" >> $GITHUB_STEP_SUMMARY
+ echo "| Security Scan | ${{ needs.security-scan.result }} |" >> $GITHUB_STEP_SUMMARY
+ echo "| Amplify Validation | ${{ needs.amplify-validation.result }} |" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**ℹ️ Build & Deploy**: Automatically managed by AWS Amplify on every push to \`main\`" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [[ "${{ needs.lint.result }}" == "success" && "${{ needs.test-frontend.result }}" == "success" ]]; then
+ echo "✅ **CI pipeline completed successfully!**" >> $GITHUB_STEP_SUMMARY
+ echo "🚀 **Code is ready for automatic Amplify deploy**" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "❌ **CI pipeline failed. Check the jobs above.**" >> $GITHUB_STEP_SUMMARY
+ echo "⚠️ **Amplify deploy may fail if there are critical errors**" >> $GITHUB_STEP_SUMMARY
+ fi
diff --git a/src/components/RootRoute.js b/src/components/RootRoute.js
index d3e732c..7a1e9f4 100644
--- a/src/components/RootRoute.js
+++ b/src/components/RootRoute.js
@@ -1,24 +1,24 @@
-import React, { useEffect, useState } from "react";
-import { Navigate } from "react-router-dom";
-import { getLoggedUser } from "../helpers/authHelper";
-import Dashboard from "../pages/Dashboard";
-
-const RootRoute = () => {
- const [checking, setChecking] = useState(true);
- const [isAuthenticated, setIsAuthenticated] = useState(false);
-
- useEffect(() => {
- const checkAuth = async () => {
- const user = await getLoggedUser();
- setIsAuthenticated(!!user);
- setChecking(false);
- };
- checkAuth();
- }, []);
-
- if (checking) return null;
-
- return isAuthenticated ? : ;
-};
-
-export default RootRoute;
+import React, { useEffect, useState } from "react";
+import { Navigate } from "react-router-dom";
+import { getLoggedUser } from "../helpers/authHelper";
+import Dashboard from "../pages/Dashboard";
+
+const RootRoute = () => {
+ const [checking, setChecking] = useState(true);
+ const [isAuthenticated, setIsAuthenticated] = useState(false);
+
+ useEffect(() => {
+ const checkAuth = async () => {
+ const user = await getLoggedUser();
+ setIsAuthenticated(!!user);
+ setChecking(false);
+ };
+ checkAuth();
+ }, []);
+
+ if (checking) return null;
+
+ return isAuthenticated ? : ;
+};
+
+export default RootRoute;
diff --git a/src/components/UserProfileSection.js b/src/components/UserProfileSection.js
index aa2389a..7a661ea 100644
--- a/src/components/UserProfileSection.js
+++ b/src/components/UserProfileSection.js
@@ -18,7 +18,8 @@ const UserProfileSection = ({ user, loadingUser, onUserUpdate, onMessage }) => {
const value = e.target.value;
// Regex per permettere solo lettere, spazi, apostrofi e caratteri accentati
- const allowedCharsRegex = /^[a-zA-ZÀ-ÿ\u0100-\u017F\u0180-\u024F\u1E00-\u1EFF\s']*$/;
+ const allowedCharsRegex =
+ /^[a-zA-ZÀ-ÿ\u0100-\u017F\u0180-\u024F\u1E00-\u1EFF\s']*$/;
// Controlla se il valore contiene solo caratteri consentiti
if (allowedCharsRegex.test(value)) {
@@ -43,7 +44,7 @@ const UserProfileSection = ({ user, loadingUser, onUserUpdate, onMessage }) => {
// Previeni l'inserimento di numeri anche tramite tastiera
const char = e.key;
const isNumber = /[0-9]/.test(char);
- const isSpecialChar = /[!@#$%^&*()_+\-=\[\]{};:"\\|,.<>\/?]/.test(char);
+ const isSpecialChar = /[!@#$%^&*()_+=[\]{};:"\\|,.<>/?]/.test(char);
// Permettiamo solo: lettere, spazi, backspace, delete, tab, enter, escape
const allowedKeys = [
@@ -58,7 +59,13 @@ const UserProfileSection = ({ user, loadingUser, onUserUpdate, onMessage }) => {
"ArrowDown",
];
- if (isNumber || (isSpecialChar && !allowedKeys.includes(char) && char !== "'" && char !== ' ')) {
+ if (
+ isNumber ||
+ (isSpecialChar &&
+ !allowedKeys.includes(char) &&
+ char !== "'" &&
+ char !== " ")
+ ) {
e.preventDefault();
return;
}
@@ -111,6 +118,16 @@ const UserProfileSection = ({ user, loadingUser, onUserUpdate, onMessage }) => {
return;
}
+ // Controllo caratteri speciali (permettiamo solo lettere, spazi, apostrofi e trattini)
+ const validNameRegex = /^[a-zA-ZÀ-ÿ\s'-]+$/;
+ if (!validNameRegex.test(trimmedName)) {
+ onMessage({
+ type: "error",
+ text: "Il nome può contenere solo lettere, spazi, apostrofi e trattini.",
+ });
+ return;
+ }
+
if (trimmedName === user?.full_name) {
setIsEditingName(false);
return;
diff --git a/src/hooks/useKeyboardHeight.js b/src/hooks/useKeyboardHeight.js
index 4def89a..b14f155 100644
--- a/src/hooks/useKeyboardHeight.js
+++ b/src/hooks/useKeyboardHeight.js
@@ -1,27 +1,27 @@
-import { useState, useEffect } from "react";
-
-export const useKeyboardHeight = () => {
- const [keyboardHeight, setKeyboardHeight] = useState(0);
- const [isKeyboardVisible, setIsKeyboardVisible] = useState(false);
-
- useEffect(() => {
- if (typeof window === "undefined") return;
-
- const handleResize = () => {
- if (window.visualViewport) {
- const heightDiff = window.screen.height - window.visualViewport.height;
- setKeyboardHeight(heightDiff);
- setIsKeyboardVisible(heightDiff > 150);
- }
- };
-
- if (window.visualViewport) {
- window.visualViewport.addEventListener("resize", handleResize);
- return () => {
- window.visualViewport.removeEventListener("resize", handleResize);
- };
- }
- }, []);
-
- return { keyboardHeight, isKeyboardVisible };
-};
+import { useState, useEffect } from "react";
+
+export const useKeyboardHeight = () => {
+ const [keyboardHeight, setKeyboardHeight] = useState(0);
+ const [isKeyboardVisible, setIsKeyboardVisible] = useState(false);
+
+ useEffect(() => {
+ if (typeof window === "undefined") return;
+
+ const handleResize = () => {
+ if (window.visualViewport) {
+ const heightDiff = window.screen.height - window.visualViewport.height;
+ setKeyboardHeight(heightDiff);
+ setIsKeyboardVisible(heightDiff > 150);
+ }
+ };
+
+ if (window.visualViewport) {
+ window.visualViewport.addEventListener("resize", handleResize);
+ return () => {
+ window.visualViewport.removeEventListener("resize", handleResize);
+ };
+ }
+ }, []);
+
+ return { keyboardHeight, isKeyboardVisible };
+};