API backend pour l'application Absolument G - Node.js 20 + TypeScript 5 + TypeORM 0.3
- Runtime: Node.js 20.x LTS
- Language: TypeScript 5.x
- Framework: Express 4.19.x
- ORM: TypeORM 0.3.x (DataSource API)
- Database: PostgreSQL 16.x + PostGIS 3.4.x
- Authentication: JWT (jsonwebtoken 9.x) + bcrypt 5.x
- Security: helmet, express-rate-limit, CORS
- WebSocket: ws 8.18.x
- Logging: winston 3.x
- Testing: Vitest 4.x
- Node.js 20.x LTS
- PostgreSQL 16.x avec extension PostGIS 3.4.x
- npm ou yarn
# Installer les dépendances
npm install
# Copier et configurer l'environnement
cp .env.example .env
# Éditer .env avec vos paramètres
# Créer la base de données
createdb -U postgres absg5
psql -U postgres -d absg5 -c "CREATE EXTENSION postgis;"
# Lancer les migrations
npm run migration:run# Database
DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=your_password
DB_DATABASE=absg5
# Server
PORT=3000
NODE_ENV=development
# Security
JWT_SECRET=your_jwt_secret_here
BCRYPT_ROUNDS=10
# CORS (IMPORTANT: Required when using credentials: true)
# Must match the exact origin of the frontend (scheme + host + port)
CORS_ORIGIN=http://localhost:8080
# Files
PATH_FILES=./data/files
# Email (optional)
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your_email
SMTP_PASS=your_passwordnpm run dev # Serveur avec hot-reload (nodemon)
npm run build # Compile TypeScript
npm start # Serveur de productionnpm test # Tests en mode watch
npm run test:run # Tests en mode single run
npm run test:ui # Interface UI pour les tests
npm run test:coverage # Tests avec coveragenpm run migration:generate -- -n MigrationName # Génère une migration
npm run migration:run # Exécute les migrations
npm run migration:revert # Annule la dernière migrationabsg-core/
├── src/
│ ├── controllers/ # API endpoints (routing-controllers)
│ │ ├── AuthController.ts
│ │ ├── UserController.ts
│ │ ├── PhotoController.ts
│ │ ├── ForumController.ts
│ │ ├── AgpaController.ts
│ │ └── ...
│ ├── entities/ # TypeORM entities
│ │ ├── User.ts
│ │ ├── Photo.ts
│ │ ├── Forum.ts
│ │ └── ...
│ ├── services/ # Business logic
│ │ ├── UserService.ts
│ │ ├── PhotoService.ts
│ │ └── ...
│ ├── middleware/ # Express middleware
│ │ ├── auth.ts
│ │ ├── logger.ts
│ │ └── ...
│ ├── data-source.ts # TypeORM DataSource configuration
│ └── api.ts # Main entry point
├── test/
│ ├── setup.ts # Test configuration
│ ├── example.test.ts # Example tests
│ ├── integration/ # Integration tests
│ └── helpers/ # Test helpers
├── data/ # Data files (uploads, etc.)
├── .env # Environment variables
├── tsconfig.json # TypeScript configuration
└── package.json
POST /api/auth/login- LoginGET /api/auth/check- Check sessionPOST /api/auth/logout- LogoutPOST /api/auth/reset-password- Reset password
GET /api/users- List usersGET /api/users/:id- Get userPUT /api/users/profile- Update profilePOST /api/users/change-pwd- Change password
GET /api/photos- List photosPOST /api/photos/upload- Upload photoGET /api/photos/:id- Get photoPUT /api/photos/:id- Update photoDELETE /api/photos/:id- Delete photo
GET /api/forum/topics- List topicsPOST /api/forum/topics- Create topicGET /api/forum/topics/:id- Get topicPOST /api/forum/topics/:id/reply- Reply to topic
GET /api/agpa- Get AGPA metadataGET /api/agpa/edition/:year- Get editionPOST /api/agpa/submit- Submit photoPOST /api/agpa/vote- Submit votes
Voir les contrôleurs pour la liste complète des endpoints.
- JWT tokens avec expiration
- Refresh tokens
- Password hashing avec bcrypt (10 rounds)
- Session management
- Helmet (security headers)
- Rate limiting (100 req/15min)
- CORS configuré
- Input validation
- SQL injection protection (TypeORM)
- XSS protection
Voir SECURITY_AUDIT.md
test/
├── setup.ts # Configuration Vitest
├── example.test.ts # Tests d'exemple
├── integration/ # Tests d'intégration
│ └── auth.test.ts
└── helpers/ # Helpers de test
└── testApp.ts
import { describe, it, expect } from 'vitest'
describe('Example Test', () => {
it('should pass', () => {
expect(1 + 1).toBe(2)
})
})npm test # Watch mode
npm run test:run # Single run
npm run test:coverage # Avec coverage# Build
npm run build
# Démarrer avec PM2
pm2 start npm --name "absg-api" -- start
# Logs
pm2 logs absg-api
# Monitoring
pm2 monit# Build image
docker build -t absg-core .
# Run container
docker run -p 3000:3000 --env-file .env absg-coreNODE_ENV=production
PORT=3000
DB_HOST=your_db_host
DB_PORT=5432
DB_USERNAME=your_db_user
DB_PASSWORD=your_secure_password
DB_DATABASE=absg5
JWT_SECRET=your_very_secure_jwt_secret
CORS_ORIGIN=https://absolumentg.frLes logs sont gérés par Winston et stockés dans :
logs/error.log- Erreurs uniquementlogs/combined.log- Tous les logs- Console - En développement
Configuration dans src/middleware/logger.ts
npm run migration:generate -- -n AddUserRolenpm run migration:runnpm run migration:revertexpress- HTTP servertypeorm- ORMpg- PostgreSQL clientreflect-metadata- Decorators supportrouting-controllers- Controller-based routingbcrypt- Password hashingjsonwebtoken- JWT authenticationhelmet- Security headersexpress-rate-limit- Rate limitingwinston- Loggingaxios- HTTP clientdate-fns- Date manipulationws- WebSocket
typescript- TypeScript compilervitest- Testing frameworknodemon- Auto-reloadeslint- Linting
# Vérifier que PostgreSQL est démarré
sudo systemctl status postgresql
# Vérifier les credentials dans .env
# Vérifier que la base existe
psql -U postgres -l# Synchroniser le schéma (dev only)
# Ajouter dans data-source.ts: synchronize: true
# Ou recréer la base
dropdb -U postgres absg5
createdb -U postgres absg5
psql -U postgres -d absg5 -c "CREATE EXTENSION postgis;"
npm run migration:run# Trouver le processus
lsof -i :3000
# Tuer le processus
kill -9 <PID>- Migration Guide
- Security Audit
- Performance Testing
- Family Relations in AGPA Badges - Intégration des relations familiales (spouse/children) dans le calcul des badges
- Love Badges System - Système de badges amoureux (L'Amoureux Transi, Le Chéri(e) de Mon Cœur, Le Couple Parfait)
- Le Mécène Badge Update - Modification du badge "Le Mécène" pour distribuer TOUS les points disponibles avec max 1 vote à 2pts/catégorie
- Le Modéré Badge Update - Transformation de "Le Modéré" en badge critérié (valeur moyenne ±5pts + max 50% votes 2pts) + suppression des badges par défaut
Privé - Tous droits réservés
Olivier Gueudelot - ikit
Important: La variable URL_FILES doit avoir un slash final / pour que les URLs des images soient correctement formées.
Exemple pour le développement:
URL_FILES=/files/
Exemple pour la production:
URL_FILES=https://absolumentg.fr/files/
Si le slash final est manquant, les URLs seront incorrectement formées:
- ❌
/filesagpa/2025/...(sans slash) - ✅
/files/agpa/2025/...(avec slash)
Usage: Forcer l'édition courante des AGPA pour le développement et les tests.
Par défaut, l'édition courante est calculée automatiquement en fonction de la date :
- Du 1er février au 30 septembre : édition de l'année en cours
- Du 1er octobre au 31 janvier : édition de l'année en cours (qui se termine en janvier suivant)
Pour tester des fonctionnalités d'une édition spécifique (par exemple, les archives ou la cérémonie d'une année passée), vous pouvez forcer l'édition :
# Forcer l'édition 2024 (utile pour tester les archives, le palmares, etc.)
AGPA_FORCE_EDITION=2024
# Laisser vide pour le comportement normal (calculé automatiquement)
AGPA_FORCE_EDITION=Attention: Cette variable ne doit être utilisée qu'en développement. En production, laissez-la vide pour que l'édition soit calculée automatiquement.