diff --git a/README.md b/README.md index f8ed218..514c120 100644 --- a/README.md +++ b/README.md @@ -1,263 +1,279 @@ -# OrticelloAPI -Express API system for Orticello, a web application for Gardening management in community gardens. - -## Presentazione del Team -Ali Raja Faizan, Caria Antonio, Pedron Federico - -### TO DO - -#### Testing -- [x] Test classes for all working modules -- [ ] Integration tests for authentication flows -- [ ] E2E tests for main user stories - -#### User Story 2 - Search & Map (RF2) -- [ ] **Search filters implementation**: - - [ ] Filter by zone/area - - [ ] Filter by availability status - - [ ] Filter by sensor presence - - [ ] Filter by plot size -- [ ] Backend API for filtered search with multiple criteria - -#### User Story 4 - Plot Request (RF6.3) -- [ ] **Request submission system**: - - [ ] Validation: user must not have existing assignments - - [ ] Request status: "pending" -- [ ] **Notification system** for request confirmation -- [ ] Backend API for creating and managing plot requests -- [ ] Request model/schema in database - -#### User Story 6 - Notice Management (RF19, RF27) -- [ ] **Notice visibility system**: - - [ ] Municipality: "Public" and "Associations Only" options - - [ ] Association: auto-targeting to their citizens - -#### User Story 7 - Notice Consultation (RF3) -- [ ] **Notice filtering** by: - - [ ] Issuing entity (Municipality/Association) - - [ ] Date range - - [ ] Category -- [ ] **Read/Unread status tracking**: - - [ ] Mark as read functionality - - [ ] Visual indicators for unread notices - - [ ] User-notice read status model -- [ ] **Notice history** preservation -- [ ] Backend logic for user-specific notice visibility -- [ ] API endpoint for filtered notices by authenticated user - -#### User Story 8 - Competition Announcements (RF15.1) -- [ ] **PDF file upload** for bando documents -- [ ] **File validation** (PDF format, size limits) -- [ ] **File storage system** (local/cloud) -- [ ] **Mandatory field validation** (name, deadline, PDF) - -#### User Story 9 - Bando Consultation (RF26) -- [ ] **Active bando filtering** (future deadline only) -- [ ] **PDF download functionality** for each bando - -#### User Story 10 - Citizen Registration (RF5) -- [ ] **Email confirmation system**: - - [ ] Email service configuration - - [ ] Confirmation email template - - [ ] Email sending after registration -- [ ] **Enhanced duplicate checking**: - - [ ] Codice Fiscale uniqueness validation -- [ ] Registration success feedback - -#### User Story 11 - Request Management (RF25) -- [ ] **Request management dashboard** for associations: - - [ ] List of pending requests - - [ ] Request filtering (zone, priority, date) - - [ ] Citizen details display -- [ ] **Approval workflow**: - - [ ] Assignment duration input - - [ ] Plot status update to "occupied" - - [ ] Create affidaLotto record - - [ ] Citizen notification of approval -- [ ] **Rejection workflow**: - - [ ] Rejection reason field - - [ ] Citizen notification with reason -- [ ] Backend API for request approval/rejection -- [ ] Notification system (email/in-app) - -#### Advanced Features -- [ ] **Geospatial queries**: - - [ ] Query by distance from coordinates - - [ ] Query by geographic boundaries - - [ ] Optimize 2dsphere indexes usage -- [ ] **Sensor data management**: - - [ ] Date range queries for sensor readings - - [ ] Location-based sensor queries - - [ ] Latest reading optimization - - [ ] Data aggregation and statistics -- [ ] **Weather data management**: - - [ ] Date range queries for weather data - - [ ] Location-based weather queries - - [ ] Latest reading optimization -- [ ] **Role-based access control**: - - [ ] Apply checkRole middleware to protected routes - - [ ] Define permissions matrix for each endpoint - - [ ] Admin-specific functionalities -- [ ] **Audit logging** for critical operations -- [ ] **Email notification system** (SendGrid/Nodemailer) -- [ ] **In-app notification system** +
+ + +Orticello Logo + +**Sistema di gestione intelligente per orti urbani comunitari** + +[![Node.js](https://img.shields.io/badge/Node.js->=20.19.0-green.svg)](https://nodejs.org/) +[![MongoDB](https://img.shields.io/badge/MongoDB-Database-brightgreen.svg)](https://www.mongodb.com/) +[![Express](https://img.shields.io/badge/Express-4.16.3-blue.svg)](https://expressjs.com/) + +[Documentazione API](#-documentazione-api) โ€ข [Caratteristiche](#-caratteristiche-principali) โ€ข [Installazione](#-installazione) โ€ข [Team](#-team) + +
--- -## API Endpoints Implementation Status - -### 1. affidaLottoController.js ๐Ÿ“ฆ (Plot Assignment & Requests) -| Method | Verb | Role | Status | Description / Requirements | -|--------|------|------|--------|---------------------------| -| `addColtura` | POST | `citt` | โœ… DONE | **RF7**: Citizen adds what they're cultivating | -| `removeColtura` | DELETE | `citt` | โœ… DONE | **RF7**: Citizen removes a crop | -| `getAllAffidaLotti` | GET | `asso, comu` | โœ… DONE | **RF100**: Assignment history | -| `getAffidaLottoById` | GET | `All` | โœ… DONE | Assignment details | -| `createAffidaLotto` | POST | `comu, asso` | โœ… DONE | Manual assignment (bypass request) | -| `updateAffidaLotto` | PUT | `comu, asso` | โœ… DONE | Update assignment details | -| `deleteAffidaLotto` | DELETE | `comu, asso` | โœ… DONE | Revoke assignment / End mandate | - -**Priority Tasks:** -- [ ] Implement `richiediLotto` endpoint for citizen plot requests -- [ ] Implement `getRichiestePendenti` to list pending requests for associations -- [ ] Implement `gestisciRichiesta` with approval/rejection logic -- [ ] Create `Richiesta` model/schema for plot requests -- [ ] Add role-based access control middleware to all endpoints - -### 2. bandoController.js ๐Ÿ“œ (Competition Announcements) -| Method | Verb | Role | Status | Description / Requirements | -|--------|------|------|--------|---------------------------| -| `createBando` | POST | `comu` | โœ… DONE | **RF15**: Municipality publishes new bando | -| `deleteBando` | DELETE | `comu` | โœ… DONE | **RF15**: Municipality removes bando | -| `getAllBandi` | GET | `All` | โœ… DONE | **RF26**: List of bandi visible to all (or logged users) | -| `getBandoById` | GET | `All` | โœ… DONE | **RF26.2**: Bando details for application | -| `updateBando` | PUT | `comu` | โœ… DONE | Correction of errors in bando | -| `getActiveBandi` | GET | `Comu, Asso` | โœ… DONE | **RF26**: Only active bandi (deadline not passed) | - -**Priority Tasks:** -- [ ] Implement `getActiveBandi` to filter bandi with future deadlines -- [ ] Add PDF file upload functionality to `createBando` -- [ ] Add file storage system (local/cloud) -- [ ] Add file validation (PDF only, size limits) -- [ ] Add role-based access control middleware - -### 3. avvisoController.js ๐Ÿ“ข (Notices & Communications) -| Method | Verb | Role | Status | Description / Requirements | -|--------|------|------|--------|---------------------------| -| `createAvviso` | POST | `comu, asso` | โœ… DONE | **RF19, RF27**: Municipality or Association creates notices | -| `getAllAvvisi` | GET | `All` | โœ… DONE | **RF3**: Notice board view (filtered by relevance) | -| `getAvvisoById` | GET | `All` | โœ… DONE | Notice details | -| `updateAvviso` | PUT | `comu, asso` | โœ… DONE | Update own notice | -| `deleteAvviso` | DELETE | `comu, asso` | โœ… DONE | Delete notice (only own) | -| `getAvvisiFiltered` | GET | `All` | โœ… DONE | **RF3.4**: Filtered notices (entity, date, category) | -| `markAsRead` | PUT | `All` | โœ… DONE | **RF3**: Mark notice as read | - -**Priority Tasks:** -- [ ] Implement notice visibility system (Public, Associations Only, Association-specific) -- [ ] Add `target` field validation in `createAvviso` -- [x] Implement `getAvvisiFiltered` with filtering by entity, date, category -- [x] Implement `markAsRead` endpoint -- [x] Create `AvvisoLetto` model for read/unread tracking -- [x] Add role-based access control middleware - -### 4. ortoController.js ๐Ÿก (Garden Management) -| Method | Verb | Role | Status | Description / Requirements | -|--------|------|------|--------|---------------------------| -| `createOrto` | POST | `comu` | โœ… DONE | **RF16**: Municipality registers new garden space | -| `updateOrto` | PUT | `comu` | โœ… DONE | Modify data (e.g., address, number of plots) | -| `getAllOrtos` | GET | `All` | โœ… DONE | **RF2**: Map/List of city gardens | -| `getOrtoById` | GET | `All` | โœ… DONE | Single garden details | -| `deleteOrto` | DELETE | `comu` | โœ… DONE | Remove garden (with integrity check) | -| `getOrtosFiltrati` | GET | `All` | โœ… DONE | **RF2.2**: Gardens filtered by zone, availability, sensors, size | - -**Priority Tasks:** -- [x] Implement `getOrtosFiltrati` with multiple filter criteria -- [ ] Add geospatial query support for location-based filtering -- [x] Add role-based access control middleware to protected endpoints - -### 5. affidaOrtoController.js ๐Ÿค (Garden-Association Assignment) -| Method | Verb | Role | Status | Description / Requirements | -|--------|------|------|--------|---------------------------| -| `assignOrto` (createAffidaOrto) | POST | `comu` | โœ… DONE | **RF18**: Municipality assigns garden management to Association | -| `revokeOrto` (deleteAffidaOrto) | DELETE | `comu` | โœ… DONE | **RF18**: Municipality revokes management | -| `getAllAssignments` (getAllAffidaOrti) | GET | `comu` | โœ… DONE | List of who manages what | -| `getAffidaOrtoById` | GET | `All` | โœ… DONE | Assignment details | -| `updateAffidaOrto` | PUT | `comu` | โœ… DONE | Update assignment details | -| `getActiveAffidaOrti` | GET | `All` | โœ… DONE | Active garden assignments only | - -**Priority Tasks:** -- [ ] Add role-based access control middleware to all endpoints -- [ ] Add validation to prevent assignment conflicts - -### 6. associazioneController.js ๐Ÿ‘ฅ (Association Member Management) -| Method | Verb | Role | Status | Description / Requirements | -|--------|------|------|--------|---------------------------| -| `addMembro` | POST | `asso (Admin)` | โœ… DONE | **RF22**: Association Admin adds collaborator | -| `removeMembro` | DELETE | `asso (Admin)` | โœ… DONE | **RF22**: Association Admin removes collaborator | -| `getMembri` | GET | `asso` | โœ… DONE | List of association staff | -| `createAssociazione` | POST | `comu` | โœ… DONE | Create new association | -| `getAllAssociazioni` | GET | `All` | โœ… DONE | List all associations | -| `getAssociazioneById` | GET | `All` | โœ… DONE | Association details | -| `updateAssociazione` | PUT | `asso (Admin), comu` | โœ… DONE | Update association info | -| `deleteAssociazione` | DELETE | `comu` | โœ… DONE | Remove association | - -**Priority Tasks:** -- [x] Implement `addMembro` to add association collaborators -- [x] Implement `removeMembro` to remove collaborators -- [x] Implement `getMembri` to list association members -- [ ] Create member relationship model (utente-associazione) -- [x] Add admin-only access control for member management - -### 7. utenteController.js ๐Ÿ‘ค (User Profile Management) -| Method | Verb | Role | Status | Description / Requirements | -|--------|------|------|--------|---------------------------| -| `updateProfile` (updateUtente) | PUT | `Owner` | โœ… DONE | **RF4**: User modifies own data (phone, address) | -| `deleteProfile` (deleteUtente) | DELETE | `Owner` | โœ… DONE | **RF5**: Account deletion (GDPR) | -| `getProfile` (getUtenteById) | GET | `Owner, comu` | โœ… DONE | View own data | -| `getAllUtenti` | GET | `comu (Admin)` | โœ… DONE | Global monitoring (optional but useful) | -| `createUtente` | POST | `Public` | โœ… DONE | **RF5**: Self-registration | -| `updatePassword` | PUT | `Owner` | โœ… DONE | Change password | - -**Priority Tasks:** -- [ ] Add email confirmation system for registration -- [ ] Implement email service integration -- [ ] Add ownership validation (users can only modify their own data) -- [ ] Add role-based access control for `getAllUtenti` - -### 8. comuneController.js ๐Ÿ›๏ธ (Municipality Advanced Administration) -| Method | Verb | Role | Status | Description / Requirements | -|--------|------|------|--------|---------------------------| -| `createUtenteComune` | POST | `comu (Admin)` | โŒ TODO | **RF12**: Create municipal employee profiles | -| `createAssociazioneAdmin` | POST | `comu` | โŒ TODO | **RF14**: Create first Admin profile for new Association | -| `createComune` | POST | `System` | โœ… DONE | Create municipality record | -| `getAllComuni` | GET | `All` | โœ… DONE | List all municipalities | -| `getComuneById` | GET | `All` | โœ… DONE | Municipality details | -| `updateComune` | PUT | `comu (Admin)` | โœ… DONE | Update municipality info | -| `deleteComune` | DELETE | `System` | โœ… DONE | Remove municipality | - -**Priority Tasks:** -- [ ] Implement `createUtenteComune` for creating municipal employees -- [ ] Implement `createAssociazioneAdmin` for association initialization -- [ ] Add validation to ensure first association admin creation -- [ ] Add admin-only access control +## ๐Ÿ“– Descrizione + +**Orticello** รจ una piattaforma RESTful API completa per la gestione degli orti urbani comunitari della cittร  di Trento. L'applicazione facilita l'amministrazione dei terreni coltivabili, la gestione delle assegnazioni ai cittadini, il monitoraggio ambientale e la comunicazione tra comuni, associazioni e utenti. + +### ๐ŸŽฏ Obiettivi + +- ๐Ÿก Semplificare la gestione degli orti urbani +- ๐Ÿ‘ฅ Connettere cittadini, associazioni e amministrazioni comunali +- ๐Ÿ“Š Monitorare le condizioni ambientali con sensori IoT +- ๐Ÿ“ข Facilitare la comunicazione attraverso avvisi e bandi +- ๐ŸŒ Supportare la sostenibilitร  urbana e l'agricoltura locale --- -### Implementation Priority +## โœจ Caratteristiche Principali + +### ๐Ÿ” Autenticazione e Autorizzazione +- Sistema JWT per autenticazione sicura +- Gestione ruoli multi-livello (Cittadini, Associazioni, Comuni) +- Controllo accessi basato su permessi granulari + +### ๐Ÿ—บ๏ธ Gestione Geospaziale +- Localizzazione orti e lotti con coordinate GeoJSON +- Query geospaziali avanzate (ricerca per distanza e area) +- Indicizzazione MongoDB 2dsphere per performance ottimali + +### ๐ŸŒฟ Amministrazione Orti e Lotti +- Gestione completa di orti urbani e singoli lotti +- Sistema di assegnazione e affidamento terreni +- Tracciamento stato e disponibilitร  lotti + +### ๐Ÿ“ก Monitoraggio Ambientale +- Integrazione dati sensori IoT in tempo reale +- Raccolta dati meteorologici +- Storico condizioni ambientali + +### ๐Ÿ“ฃ Comunicazione +- Sistema avvisi per comuni e associazioni +- Gestione bandi di concorso +- Notifiche mirate agli utenti + +### ๐ŸŒ Internazionalizzazione +- Supporto multilingua (๐Ÿ‡ฎ๐Ÿ‡น Italiano, ๐Ÿ‡ฌ๐Ÿ‡ง Inglese, ๐Ÿ‡ฉ๐Ÿ‡ช Tedesco) +- Rilevamento automatico lingua preferita +- Messaggi di errore localizzati + +### ๐Ÿค– AI Integration +- Integrazione Google Generative AI +- Consigli personalizzati per la coltivazione + +--- + +## ๐Ÿ—๏ธ Architettura + +### Stack Tecnologico + +``` +Backend Framework: Express.js 4.16.3 +Database: MongoDB 9.0.0 con Mongoose ODM +Autenticazione: JWT + bcrypt +Documentazione: OpenAPI 3.0 / Swagger +Testing: Jest + Supertest +Security: Helmet, CORS, Validator +``` + +### Struttura Moduli + +``` +๐Ÿ“ฆ Orticello API +โ”œโ”€โ”€ ๐Ÿก Orti (Gardens) - Gestione orti urbani +โ”œโ”€โ”€ ๐Ÿ“ Lotti (Plots) - Gestione singoli lotti coltivabili +โ”œโ”€โ”€ ๐Ÿ‘ค Utenti (Users) - Gestione utenti (cittadini, admin) +โ”œโ”€โ”€ ๐Ÿข Associazioni - Gestione associazioni di quartiere +โ”œโ”€โ”€ ๐Ÿ›๏ธ Comune (Municipality) - Gestione enti comunali +โ”œโ”€โ”€ ๐Ÿค Affidamenti - Assegnazioni orti e lotti +โ”œโ”€โ”€ ๐Ÿ“ข Avvisi (Notices) - Comunicazioni pubbliche +โ”œโ”€โ”€ ๐Ÿ“‹ Bandi (Competitions) - Bandi di assegnazione +โ”œโ”€โ”€ ๐ŸŒค๏ธ Meteo (Weather) - Dati meteorologici +โ””โ”€โ”€ ๐Ÿ“ก Sensori (Sensors) - Dati sensori ambientali +``` + +--- + +## ๐Ÿš€ Installazione + +### Prerequisiti + +- Node.js >= 20.19.0 +- npm >= 10.0.0 +- MongoDB (locale o cloud) + +### Setup + +```bash +# Clona il repository +git clone https://github.com/your-repo/orticello.git + +# Entra nella directory +cd orticello + +# Installa le dipendenze +npm install + +# Configura le variabili d'ambiente +cp .env.example .env +# Modifica .env con le tue configurazioni + +# Avvia l'applicazione +npm start + +# Oppure in modalitร  sviluppo +npm run dev +``` + +### Variabili d'Ambiente + +Crea un file `.env` nella root del progetto: + +```env +# Database +MONGODB_URI=mongodb://localhost:27017/orticello + +# Server +PORT=8080 + +# JWT +JWT_SECRET=your-secret-key-here + +# Google AI (opzionale) +GOOGLE_API_KEY=your-google-api-key +``` + +--- + +## ๐Ÿ“š Documentazione API + +La documentazione interattiva completa รจ disponibile tramite Swagger UI: + +``` +http://localhost:8080/api-docs +``` + +### Endpoints Principali + +| Risorsa | Endpoint | Descrizione | +|---------|----------|-------------| +| ๐Ÿ” Auth | `/api/v1/authentication` | Login e registrazione | +| ๐Ÿก Orti | `/api/v1/orti` | CRUD orti urbani | +| ๐Ÿ“ Lotti | `/api/v1/lotti` | CRUD lotti coltivabili | +| ๐Ÿ‘ค Utenti | `/api/v1/utenti` | Gestione utenti | +| ๐Ÿข Associazioni | `/api/v1/associazioni` | Gestione associazioni | +| ๐Ÿ“ข Avvisi | `/api/v1/avvisi` | Gestione comunicazioni | +| ๐Ÿ“‹ Bandi | `/api/v1/bandi` | Gestione bandi | +| ๐ŸŒค๏ธ Meteo | `/api/v1/meteo` | Dati meteorologici | +| ๐Ÿ“ก Sensori | `/api/v1/sensor` | Dati sensori IoT | + +### Esempio Richiesta + +```javascript +// Autenticazione +const response = await fetch('http://localhost:8080/api/v1/authentication/login', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + email: 'user@example.com', + password: 'password123' + }) +}); + +const { token } = await response.json(); + +// Richiesta autenticata +const orti = await fetch('http://localhost:8080/api/v1/orti', { + headers: { + 'Authorization': `Bearer ${token}`, + 'X-Language': 'it' + } +}); +``` + +--- + +## ๐Ÿงช Testing + +```bash +# Esegui tutti i test +npm test + +# Test con coverage +npm test -- --coverage + +# Test specifici +npm test -- controllers/ortoController.test.js +``` + +### Copertura Test + +- โœ… Controller tests +- โœ… Utility middleware tests +- โœ… Authentication tests + +--- + +## ๐ŸŒ Internazionalizzazione + +L'API supporta richieste multilingua: + +```bash +# Query parameter +GET /api/v1/orti?lang=en + +# Header personalizzato +X-Language: de + +# Accept-Language (automatico) +Accept-Language: en-US,en;q=0.9 +``` + +--- + +## ๐Ÿ”’ Sicurezza + +- ๐Ÿ” Autenticazione JWT con token expiration +- ๐Ÿ”‘ Password hashing con bcrypt +- โœ… Validazione input con validator.js +- ๐Ÿ›ก๏ธ CORS configurato +- ๐Ÿ” Sanitizzazione dati +- ๐Ÿ“ Logging completo richieste ed errori + +--- + +## ๐Ÿ“Š Logging + +Sistema di logging strutturato per: +- โœ… Richieste HTTP +- โŒ Errori applicativi +- ๐Ÿ”Œ Connessioni database +- โš ๏ธ Avvisi di sistema + +--- + +## ๐Ÿ‘ฅ Team + +Sviluppato con โค๏ธ da: + +- **Ali Raja Faizan** +- **Antonio Caria** +- **Federico Pedron** + +--- + +## ๐Ÿ“ž Contatti + +Per domande o supporto, apri una issue su GitHub. + +--- -**High Priority (Core User Stories):** -1. Plot request system (`richiediLotto`, `getRichiestePendenti`, `gestisciRichiesta`) -2. Notice visibility and filtering system -3. Active bandi filtering with PDF support -4. Role-based access control on all endpoints +
-**Medium Priority (Enhanced Features):** -1. Association member management -2. Email confirmation system -3. Municipal employee management -4. Read/unread notice tracking +**Coltiva il futuro verde delle cittร ! ๐ŸŒฑ๐Ÿ™๏ธ** -**Low Priority (Nice to Have):** -1. Advanced filtering for gardens -2. Geospatial queries optimization -3. Audit logging implementation +
\ No newline at end of file diff --git a/doc/I18N.md b/doc/I18N.md deleted file mode 100644 index 54bb4fb..0000000 --- a/doc/I18N.md +++ /dev/null @@ -1,184 +0,0 @@ -# Sistema di Internazionalizzazione (i18n) - Orticello API - -## Lingue Supportate -- ๐Ÿ‡ฎ๐Ÿ‡น Italiano (it) - Default -- ๐Ÿ‡ฌ๐Ÿ‡ง Inglese (en) -- ๐Ÿ‡ฉ๐Ÿ‡ช Tedesco (de) - -## Come Funziona - -Il sistema rileva automaticamente la lingua preferita dell'utente in questo ordine di prioritร : - -1. **Query Parameter** - `?lang=en` -2. **Header Personalizzato** - `X-Language: de` -3. **Header Accept-Language** - Rilevamento automatico dal browser -4. **Lingua Default** - Italiano (it) - -## Esempi di Utilizzo - -### 1. Tramite Query Parameter -```bash -GET /api/v1/orti?lang=en -GET /api/v1/utenti?lang=de -``` - -### 2. Tramite Header Personalizzato -```bash -curl -H "X-Language: en" http://localhost:8080/api/v1/orti -``` - -### 3. Tramite Accept-Language (automatico dal browser) -```bash -curl -H "Accept-Language: de-DE,de;q=0.9,en;q=0.8" http://localhost:8080/api/v1/orti -``` - -### 4. Fetch API (JavaScript) -```javascript -// Con query parameter -fetch('/api/v1/orti?lang=en') - -// Con header personalizzato -fetch('/api/v1/orti', { - headers: { - 'X-Language': 'de' - } -}) - -// Automatico (usa Accept-Language del browser) -fetch('/api/v1/orti') -``` - -### 5. Axios (JavaScript) -```javascript -// Con header personalizzato -axios.get('/api/v1/orti', { - headers: { - 'X-Language': 'en' - } -}) - -// Con query parameter -axios.get('/api/v1/orti', { - params: { - lang: 'de' - } -}) -``` - -## Esempi di Risposte - -### Italiano (Default) -```json -{ - "message": "Orto non trovato" -} -``` - -### Inglese -```json -{ - "message": "Garden not found" -} -``` - -### Tedesco -```json -{ - "message": "Garten nicht gefunden" -} -``` - -## Struttura File di Traduzione - -Le traduzioni sono organizzate in `/src/locales/`: - -``` -src/locales/ -โ”œโ”€โ”€ it.json (Italiano) -โ”œโ”€โ”€ en.json (Inglese) -โ””โ”€โ”€ de.json (Tedesco) -``` - -### Categorie di Messaggi - -- `errors.*` - Messaggi di errore -- `success.*` - Messaggi di successo -- `notFound.*` - Messaggi per risorse non trovate -- `validation.*` - Messaggi di validazione -- `auth.*` - Messaggi di autenticazione - -## Aggiungere Nuove Traduzioni - -### 1. Nei Controller -```javascript -// Invece di: -res.status(404).json({ message: 'Orto non trovato' }); - -// Usa: -res.status(404).json({ message: req.t('notFound.orto') }); -``` - -### 2. Nei File di Traduzione -Aggiungi la chiave in tutti i file lingua: - -**it.json** -```json -{ - "notFound": { - "orto": "Orto non trovato" - } -} -``` - -**en.json** -```json -{ - "notFound": { - "orto": "Garden not found" - } -} -``` - -**de.json** -```json -{ - "notFound": { - "orto": "Garten nicht gefunden" - } -} -``` - -## Testing - -### Test con cURL -```bash -# Italiano (default) -curl http://localhost:8080/api/v1/orti/invalid-id - -# Inglese -curl http://localhost:8080/api/v1/orti/invalid-id?lang=en - -# Tedesco -curl -H "X-Language: de" http://localhost:8080/api/v1/orti/invalid-id -``` - -## Best Practices - -1. **Usa sempre chiavi di traduzione** invece di testo hardcoded -2. **Organizza le chiavi** per categoria (errors, success, etc.) -3. **Mantieni consistenza** nei nomi delle chiavi tra tutte le lingue -4. **Testa tutte le lingue** dopo aver aggiunto nuove traduzioni -5. **Documenta** nuove chiavi di traduzione aggiunte - -## Note per gli Sviluppatori - -- Il middleware `detectLanguage` รจ applicato globalmente in `app.js` -- La funzione `req.t()` รจ disponibile in tutti i controller -- Usa la notazione punto per chiavi annidate: `req.t('errors.retrieving_ortos')` -- Le traduzioni mancanti torneranno alla chiave stessa come fallback - -## Roadmap - -- [ ] Aggiungere traduzioni per tutti i controller -- [ ] Implementare traduzioni per messaggi di validazione Mongoose -- [ ] Aggiungere supporto per parametri dinamici nelle traduzioni diff --git a/doc/LOGGING.md b/doc/LOGGING.md deleted file mode 100644 index 93d6684..0000000 --- a/doc/LOGGING.md +++ /dev/null @@ -1,339 +0,0 @@ -# Sistema di Logging - Orticello API - -## Panoramica - -Sistema di logging completo e configurabile per tracciare tutte le operazioni importanti dell'API. - -## Caratteristiche - -โœ… **Completamente configurabile** tramite variabili d'ambiente -โœ… **4 livelli di log**: error, warn, info, debug -โœ… **Output flessibile**: console, file, o entrambi -โœ… **Formato strutturato** con timestamp e contesto -โœ… **Logging specializzato** per HTTP, DB, Auth -โœ… **Rotazione automatica** dei file di log -โœ… **Possibilitร  di disabilitare** completamente - -## Configurazione - -### Variabili d'Ambiente - -Tutte le configurazioni sono gestite tramite variabili d'ambiente nel file `.env`: - -```bash -# Abilita/disabilita logging -LOG_ENABLED=true - -# Livello di log (error | warn | info | debug) -LOG_LEVEL=info - -# Output su console -LOG_TO_CONSOLE=true - -# Output su file -LOG_TO_FILE=false - -# Percorso file di log -LOG_FILE_PATH=logs/app.log -``` - -### Livelli di Log - -| Livello | Descrizione | Quando usare | -|---------|-------------|--------------| -| `error` | Solo errori critici | Produzione | -| `warn` | Errori + warnings | Produzione | -| `info` | Informazioni generali + errori + warnings | Staging/Produzione | -| `debug` | Tutti i dettagli inclusi debug | Sviluppo | - -### Configurazioni Consigliate - -#### Sviluppo Locale -```bash -LOG_ENABLED=true -LOG_LEVEL=debug -LOG_TO_CONSOLE=true -LOG_TO_FILE=false -``` - -#### Produzione -```bash -LOG_ENABLED=true -LOG_LEVEL=warn -LOG_TO_CONSOLE=true -LOG_TO_FILE=true -LOG_FILE_PATH=/var/log/orticello/app.log -``` - -#### Testing -```bash -LOG_ENABLED=false -``` - -## Utilizzo - -### Nel Codice - -```javascript -const logger = require('./config/logger'); - -// Log generale -logger.info('Operazione completata'); -logger.error('Errore critico', { error: err.message }); -logger.warn('Attenzione', { details: 'qualcosa da notare' }); -logger.debug('Debug info', { data: someData }); - -// Log HTTP (automatico tramite middleware) -logger.http(req, 200, 'Request processed'); - -// Log Database -logger.db('INSERT', 'Orto', true, { id: orto._id }); -logger.db('UPDATE', 'Utente', false, { error: 'Validation failed' }); - -// Log Autenticazione -logger.auth('LOGIN', userId, true, { method: 'email' }); -logger.auth('REGISTER', email, false, { reason: 'Email exists' }); -``` - -### Middleware Automatici - -Il sistema include middleware che loggano automaticamente: - -#### 1. Request Logger -Logga tutte le richieste HTTP in arrivo e le risposte: -``` -[2024-12-17T10:30:45.123Z] [INFO] | {"method":"GET","url":"/api/v1/orti","statusCode":200} - Request completed in 145ms -``` - -#### 2. Error Logger -Logga tutti gli errori non gestiti con stack trace completo: -``` -[2024-12-17T10:30:45.123Z] [ERROR] | {"error":"ValidationError","stack":"..."} - Unhandled error -``` - -## Formato dei Log - -### Console (con colori) -``` -[2024-12-17T10:30:45.123Z] [INFO] | {"userId":"123","action":"login"} - User authenticated -``` - -### File (JSON-like) -``` -[2024-12-17T10:30:45.123Z] [ERROR] | {"method":"POST","url":"/api/v1/orti","error":"Validation failed"} - Error creating orto -``` - -## Rotazione dei Log - -I file di log vengono automaticamente ruotati quando superano **10MB**: - -``` -logs/app.log # File corrente -logs/app_2024-12-17.log # File rotato -logs/app_2024-12-16.log # File rotato precedente -``` - -## Esempi di Log per Operazione - -### 1. Operazioni CRUD - -```javascript -// GET /api/v1/orti -[INFO] DB SELECT on Orto: SUCCESS | {"count":15} - -// POST /api/v1/orti -[INFO] DB INSERT on Orto: SUCCESS | {"id":"674...","nome":"Orto Nord"} - -// PUT /api/v1/orti/:id -[INFO] DB UPDATE on Orto: SUCCESS | {"id":"674..."} - -// DELETE /api/v1/orti/:id -[WARN] Orto not found | {"id":"invalid-id"} -[INFO] DB DELETE on Orto: SUCCESS | {"id":"674..."} -``` - -### 2. Autenticazione - -```javascript -// Login riuscito -[INFO] Auth LOGIN for user mario@example.com: SUCCESS | {"userId":"123"} - -// Login fallito -[WARN] Auth LOGIN for user mario@example.com: FAILED | {"reason":"Wrong password"} - -// Registrazione Google -[INFO] Auth GOOGLE_REGISTER for user nuovo@gmail.com: SUCCESS | {"userId":"456"} -``` - -### 3. Errori - -```javascript -// Errore database -[ERROR] DB SELECT on Orto: FAILED | {"error":"Connection timeout"} - -// Errore validazione -[ERROR] DB INSERT on Utente: FAILED | {"error":"Email already exists"} - -// Errore non gestito -[ERROR] Unhandled error: Cannot read property 'id' of undefined | {"stack":"..."} -``` - -### 4. Richieste HTTP - -```javascript -// Richiesta normale -[INFO] | {"method":"GET","url":"/api/v1/orti","statusCode":200} - Request completed in 45ms - -// Richiesta non trovata -[WARN] 404 - Route not found | {"method":"GET","url":"/api/v1/nonexistent"} - -// Richiesta con errore -[ERROR] | {"method":"POST","url":"/api/v1/orti","statusCode":500} - Request completed in 120ms -``` - -## Best Practices - -### 1. Usa il Livello Appropriato - -```javascript -// โŒ Non fare -logger.info('Database connection failed'); - -// โœ… Fare -logger.error('Database connection failed', { error: err.message }); -``` - -### 2. Includi Sempre il Contesto - -```javascript -// โŒ Non fare -logger.info('Orto created'); - -// โœ… Fare -logger.db('INSERT', 'Orto', true, { id: orto._id, nome: orto.nome }); -``` - -### 3. Non Loggare Dati Sensibili - -```javascript -// โŒ Non fare -logger.debug('User login', { password: req.body.password }); - -// โœ… Fare -logger.debug('User login attempt', { email: req.body.email }); -``` - -### 4. Usa Debug per Dettagli di Sviluppo - -```javascript -// Durante sviluppo -logger.debug('Processing request', { body: req.body, params: req.params }); - -// In produzione (LOG_LEVEL=info) questo non verrร  registrato -``` - -## Monitoraggio e Analisi - -### Trovare Errori - -```bash -# Cerca errori nei log -grep "ERROR" logs/app.log - -# Conta gli errori -grep -c "ERROR" logs/app.log - -# Ultimi 50 errori -grep "ERROR" logs/app.log | tail -n 50 -``` - -### Analisi Performance - -```bash -# Richieste lente (>1000ms) -grep "Request completed" logs/app.log | grep -E "[0-9]{4,}ms" - -# Conta richieste per endpoint -grep "Request completed" logs/app.log | grep -oP '"/api/v1/\w+"' | sort | uniq -c -``` - -### Audit di Sicurezza - -```bash -# Login falliti -grep "Auth LOGIN.*FAILED" logs/app.log - -# Tentativi di accesso 404 -grep "404" logs/app.log -``` - -## Disabilitare il Logging - -### Temporaneamente (per test) -```bash -LOG_ENABLED=false npm test -``` - -### Permanentemente -Nel file `.env`: -```bash -LOG_ENABLED=false -``` - -## Struttura File - -``` -src/ -โ”œโ”€โ”€ config/ -โ”‚ โ””โ”€โ”€ logger.js # Sistema di logging principale -โ”œโ”€โ”€ middleware/ -โ”‚ โ”œโ”€โ”€ requestLogger.js # Middleware per richieste HTTP -โ”‚ โ””โ”€โ”€ errorLogger.js # Middleware per errori -โ””โ”€โ”€ controllers/ - โ””โ”€โ”€ ortoController.js # Esempio di utilizzo nei controller - -logs/ # Directory log (auto-creata) -โ””โ”€โ”€ app.log # File di log principale -``` - -## Integrazione con Servizi Esterni - -Il sistema puรฒ essere facilmente esteso per integrare servizi di logging cloud: - -- **Sentry**: per error tracking -- **LogDNA/Datadog**: per log management -- **ELK Stack**: per analisi avanzata -- **CloudWatch**: per AWS deployment - -## Troubleshooting - -### I log non appaiono - -1. Verifica che `LOG_ENABLED=true` -2. Controlla il livello: `LOG_LEVEL` deve includere il livello che vuoi vedere -3. Se usi file, verifica i permessi di scrittura su `LOG_FILE_PATH` - -### File di log troppo grandi - -Il sistema ruota automaticamente i file >10MB. Per modificare: - -```javascript -// In src/config/logger.js -const maxSize = 5 * 1024 * 1024; // 5MB invece di 10MB -``` - -### Prestazioni degradate - -Se i log rallentano l'applicazione: -- Aumenta `LOG_LEVEL` (es. da debug a info) -- Disabilita `LOG_TO_FILE` in produzione -- Usa servizi esterni di logging asincroni - -## Roadmap - -- [ ] Integrazione con Sentry -- [ ] Log rotation basato su tempo (daily, weekly) -- [ ] Compressione file di log rotati -- [ ] Export log in formato JSON strutturato -- [ ] Dashboard web per visualizzazione log -- [ ] Alerts automatici per errori critici diff --git a/doc/logo.png b/doc/logo.png new file mode 100644 index 0000000..f068bc8 Binary files /dev/null and b/doc/logo.png differ diff --git a/src/controllers/consigliController.js b/src/controllers/consigliController.js index 815a9d6..cd924fe 100644 --- a/src/controllers/consigliController.js +++ b/src/controllers/consigliController.js @@ -31,7 +31,7 @@ exports.getConsigli = async (req, res) => { // Build weather context let weatherContext = ''; if (weather) { - weatherContext = `\nCurrent weather: temperature ${weather.temperature}ยฐC, humidity ${weather.humidity}%, wind ${weather.windSpeed} km/h, condition: ${weather.condition}.`; + weatherContext = `\nCurrent weather: temperature ${weather.temperature}ยฐC, humidity ${weather.humidity}%, wind ${weather.windSpeed} km/h, condition: ${weather.condition}, date: ${weather.date}.`; } const prompt = `You are an expert agronomist. Give exactly 4 practical tips for a citizen growing these ${lang.crops} in their ${lang.garden}: ${colture.join(', ')}.${weatherContext}