Application React + TypeScript + Vite permettant de générer des cartes de métro personnalisées selon le profil utilisateur. Intègre un backend Express + PostgreSQL + Prisma pour collecter les retours utilisateurs via un questionnaire de satisfaction.
- React 19 avec TypeScript
- Vite pour le build et le dev server
- TailwindCSS pour le styling
- D3.js pour le rendu des cartes schΓ©matiques
- Leaflet pour les cartes gΓ©ographiques
- Radix UI (shadcn/ui) pour les composants UI
- Express - API REST
- PostgreSQL 16 - Base de donnΓ©es
- Prisma - ORM avec migrations
- Zod - Validation des donnΓ©es
- TypeScript - Type safety cΓ΄tΓ© serveur
- Docker & Docker Compose - Containerisation
- Nginx - Serveur web statique et reverse proxy
- Node.js 24+
- npm ou yarn
- Docker & Docker Compose (pour la production)
- PostgreSQL 16 (pour le dΓ©veloppement local)
- Installer les dΓ©pendances
npm install- Configurer la base de donnΓ©es
CrΓ©ez une base PostgreSQL locale :
# Avec psql
createdb metrodb
# Ou via Docker
docker run -d \
--name metro-postgres \
-e POSTGRES_USER=metroadmin \
-e POSTGRES_PASSWORD=metropassword \
-e POSTGRES_DB=metrodb \
-p 5432:5432 \
postgres:16-alpine- Configurer les variables d'environnement
Le fichier .env est dΓ©jΓ configurΓ© pour le dΓ©veloppement local :
DATABASE_URL="postgresql://metroadmin:metropassword@localhost:5432/metrodb"
PORT=3001
NODE_ENV=development
CORS_ORIGIN=http://localhost:5173- Initialiser Prisma et crΓ©er les tables
npm run prisma:migrate- GΓ©nΓ©rer le Prisma Client
npm run prisma:generateTerminal 1 - Backend API :
npm run server:devLe serveur dΓ©marre sur http://localhost:3001
Terminal 2 - Frontend Vite :
npm run devL'application est accessible sur http://localhost:5173
Le proxy Vite redirige automatiquement /api vers le backend.
npm run prisma:studioOuvre une interface web sur http://localhost:5555 pour explorer la base de donnΓ©es.
docker-compose up --buildServices dΓ©marrΓ©s :
- Frontend (Nginx) :
http://localhost:3200 - Backend (Express) :
http://localhost:3001 - PostgreSQL :
localhost:5432
βββββββββββββββββββββββββββββββββββββββββββ
β Frontend (Nginx :80) β
β Serve static files + reverse proxy β
β Port exposΓ©: 3200 β
ββββββββββββββ¬βββββββββββββββββββββββββββββ
β Proxy /api β backend
β
βββββββββββββββββββββββββββββββββββββββββββ
β Backend (Express :3001) β
β API REST + Prisma Client β
β Port exposΓ©: 3001 β
ββββββββββββββ¬βββββββββββββββββββββββββββββ
β Connexion DATABASE_URL
β
βββββββββββββββββββββββββββββββββββββββββββ
β PostgreSQL 16 (:5432) β
β Volume persistant: postgres_data β
βββββββββββββββββββββββββββββββββββββββββββ
Soumet un questionnaire de satisfaction.
Body:
{
"question1": 4,
"question2": 5,
"question3": 3,
"question4": 4,
"question5": 5,
"openFeedback": "Super application !",
"userProfile": {
"profession": "etudiant",
"domicile": "vieux_lyon",
"travail": "cordeliers",
"mapType": "schematisee",
"geometry": "octilineaire",
"lineColor": "#e60042",
"colorMode": "custom",
"modeAffichage": "mobile",
"basemap": "cartodb-light"
},
"mapConfig": {
"basemap": "cartodb-light",
"colorMode": "custom",
"lineColor": "#e60042",
"geometry": "octilineaire",
"mapType": "schematisee"
}
}Response 201:
{
"success": true,
"id": 1,
"message": "Merci pour votre retour !"
}Récupère les statistiques agrégées des réponses.
Response 200:
{
"success": true,
"totalResponses": 42,
"averageRatings": {
"question1": 4.2,
"question2": 4.5,
"question3": 3.8,
"question4": 4.1,
"question5": 4.3
}
}Health check endpoint.
model SurveyResponse {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
question1 Int // 1-5
question2 Int // 1-5
question3 Int // 1-5
question4 Int // 1-5
question5 Int // 1-5
openFeedback String @db.Text
userProfile Json
mapConfig Json
@@map("survey_responses")
}| Script | Description |
|---|---|
npm run dev |
DΓ©marre Vite dev server (frontend) |
npm run build |
Build production du frontend |
npm run server:dev |
DΓ©marre le serveur Express en mode dev |
npm run server:build |
Compile le backend TypeScript |
npm run server:start |
Lance le serveur compilΓ© |
npm run prisma:generate |
Génère le Prisma Client |
npm run prisma:migrate |
CrΓ©e une nouvelle migration |
npm run prisma:migrate:deploy |
Applique les migrations en production |
npm run prisma:studio |
Ouvre Prisma Studio |
my-metro-app/
βββ server/ # Backend Express
β βββ index.ts # Point d'entrΓ©e serveur
β βββ routes/
β β βββ survey.ts # Routes API questionnaire
β βββ types.ts # Types TypeScript backend
β βββ prisma/
β βββ schema.prisma # SchΓ©ma base de donnΓ©es
βββ src/ # Frontend React
β βββ components/ # Composants React
β β βββ Header.tsx # Formulaire questionnaire
β β βββ RatingSlider.tsx
β β βββ ...
β βββ data/ # DonnΓ©es JSON des rΓ©seaux
β βββ types.ts # Types TypeScript frontend
β βββ App.tsx
βββ Dockerfile # Build frontend (Nginx)
βββ Dockerfile.backend # Build backend (Node)
βββ docker-compose.yml # Orchestration services
βββ nginx.conf # Config reverse proxy
βββ vite.config.ts # Config Vite avec proxy
βββ tsconfig.server.json # Config TypeScript backend
βββ package.json
DATABASE_URL=postgresql://user:password@host:port/db
PORT=3001
NODE_ENV=development|production
CORS_ORIGIN=http://localhost:5173VITE_API_URL=/apinpm run prisma:migrate
# Nom suggΓ©rΓ©: add_new_field, rename_table, etc.npx prisma migrate reset --schema=./server/prisma/schema.prisma- Logs backend : AffichΓ©s dans le terminal
npm run server:dev - Logs Docker :
docker-compose logs -f backend - Connexion PostgreSQL :
docker exec -it metro-postgres psql -U metroadmin -d metrodb - Inspect tables :
SELECT * FROM survey_responses ORDER BY "createdAt" DESC LIMIT 10;
Γ implΓ©menter : tests unitaires avec Vitest, tests d'intΓ©gration avec Playwright
Projet acadΓ©mique - Tous droits rΓ©servΓ©s