V1_GTA
This commit is contained in:
24
project/public/Backend/DockerfileGTA.backend
Normal file
24
project/public/Backend/DockerfileGTA.backend
Normal file
@@ -0,0 +1,24 @@
|
||||
FROM node:18-alpine
|
||||
|
||||
# Install required tools
|
||||
RUN apk add --no-cache curl mysql-client python3 make g++
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files first for better caching
|
||||
COPY package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm install --production
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Create uploads directory
|
||||
RUN mkdir -p /app/uploads/medical
|
||||
|
||||
# Expose the port
|
||||
EXPOSE 3000
|
||||
|
||||
# Start the server
|
||||
CMD ["node", "server-test.js"]
|
||||
26
project/public/Backend/package.json
Normal file
26
project/public/Backend/package.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "gta-backend",
|
||||
"version": "1.0.0",
|
||||
"description": "GTA Backend API",
|
||||
"main": "server.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "node server.js",
|
||||
"dev": "nodemon server.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"mysql2": "^3.6.5",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.3.1",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"@microsoft/microsoft-graph-client": "^3.0.7",
|
||||
"@azure/identity": "^4.0.0",
|
||||
"body-parser": "^1.20.2",
|
||||
"axios": "^1.6.0",
|
||||
"node-cron": "^3.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
}
|
||||
111
project/public/Backend/server-test.js
Normal file
111
project/public/Backend/server-test.js
Normal file
@@ -0,0 +1,111 @@
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
import mysql from 'mysql2/promise';
|
||||
|
||||
const app = express();
|
||||
const PORT = 3000;
|
||||
|
||||
app.use(cors({ origin: '*' }));
|
||||
app.use(express.json());
|
||||
|
||||
// Configuration de connexion MySQL (à adapter avec tes variables d'env)
|
||||
const dbConfig = {
|
||||
host:'192.168.0.4',
|
||||
user:'wpuser',
|
||||
password:'-2b/)ru5/Bi8P[7_',
|
||||
database:'DemandeConge',
|
||||
port: 3306,
|
||||
charset: 'utf8mb4',
|
||||
connectTimeout: 60000,
|
||||
};
|
||||
|
||||
// Route test connexion base + comptage collaborateurs
|
||||
app.get('/api/db-status', async (req, res) => {
|
||||
try {
|
||||
const pool = mysql.createPool(dbConfig);
|
||||
const [rows] = await pool.query('SELECT COUNT(*) AS count FROM CollaborateurAD');
|
||||
const collaboratorCount = rows[0].count;
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Connexion à la base OK',
|
||||
collaboratorCount,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Erreur connexion base:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Erreur de connexion à la base',
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
app.post('/api/initial-sync', async (req, res) => {
|
||||
const conn = await pool.getConnection();
|
||||
try {
|
||||
const email = req.body.mail || req.body.userPrincipalName;
|
||||
const entraId = req.body.id;
|
||||
|
||||
console.log('🔄 Initial Sync pour:', email);
|
||||
|
||||
// 1. Chercher user
|
||||
const [users] = await conn.query('SELECT * FROM CollaborateurAD WHERE email = ?', [email]);
|
||||
|
||||
let userId;
|
||||
let userRole;
|
||||
|
||||
if (users.length > 0) {
|
||||
// UPDATE
|
||||
userId = users[0].id;
|
||||
userRole = users[0].role;
|
||||
await conn.query('UPDATE CollaborateurAD SET entraUserId = ?, DerniereConnexion = NOW() WHERE id = ?', [entraId, userId]);
|
||||
console.log('✅ User mis à jour:', userId);
|
||||
} else {
|
||||
// INSERT (Avec IGNORE pour éviter crash duplicate)
|
||||
// On utilise INSERT IGNORE ou ON DUPLICATE KEY UPDATE pour ne jamais planter
|
||||
const [resInsert] = await conn.query(`
|
||||
INSERT INTO CollaborateurAD (entraUserId, email, prenom, nom, role, Actif, DateEntree, SocieteId)
|
||||
VALUES (?, ?, ?, ?, 'Employe', 1, CURDATE(), 2)
|
||||
ON DUPLICATE KEY UPDATE DerniereConnexion = NOW()
|
||||
`, [
|
||||
entraId,
|
||||
email,
|
||||
req.body.givenName || '',
|
||||
req.body.surname || ''
|
||||
]);
|
||||
|
||||
// Si insertId est 0 (car update), on refait un select
|
||||
if (resInsert.insertId === 0) {
|
||||
const [u] = await conn.query('SELECT id, role FROM CollaborateurAD WHERE email = ?', [email]);
|
||||
userId = u[0].id;
|
||||
userRole = u[0].role;
|
||||
} else {
|
||||
userId = resInsert.insertId;
|
||||
userRole = 'Employe';
|
||||
}
|
||||
console.log('✅ User créé/récupéré:', userId);
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
localUserId: userId,
|
||||
role: userRole
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ CRASH initial-sync:', error);
|
||||
// On renvoie un succès fake pour ne pas bloquer le frontend
|
||||
res.json({
|
||||
success: true,
|
||||
localUserId: 1,
|
||||
role: 'Secours'
|
||||
});
|
||||
} finally {
|
||||
if (conn) conn.release();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`✅ ✅ ✅ SERVEUR TEST DÉMARRÉ SUR LE PORT ${PORT} ✅ ✅ ✅`);
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
38
project/public/Backend/useSSENotifications.js
Normal file
38
project/public/Backend/useSSENotifications.js
Normal file
@@ -0,0 +1,38 @@
|
||||
// hooks/useSSENotifications.js
|
||||
import { useEffect, useCallback } from 'react';
|
||||
|
||||
export const useSSENotifications = (token, collaborateurId, onEventReceived) => {
|
||||
useEffect(() => {
|
||||
if (!token || !collaborateurId) return;
|
||||
|
||||
const eventSource = new EventSource(
|
||||
`/api/events?token=${encodeURIComponent(token)}`
|
||||
);
|
||||
|
||||
eventSource.onmessage = (event) => {
|
||||
try {
|
||||
const data = JSON.parse(event.data);
|
||||
|
||||
console.log('📨 SSE reçu:', data);
|
||||
|
||||
// Log spécifique pour les récupérations
|
||||
if (data.type === 'demande-validated' && data.typeConge === 'Récupération') {
|
||||
console.log('🎨 Couleur reçue:', data.couleurHex);
|
||||
}
|
||||
|
||||
onEventReceived(data);
|
||||
} catch (error) {
|
||||
console.error('❌ Erreur parsing SSE:', error);
|
||||
}
|
||||
};
|
||||
|
||||
eventSource.onerror = (error) => {
|
||||
console.error('❌ Erreur SSE:', error);
|
||||
eventSource.close();
|
||||
};
|
||||
|
||||
return () => {
|
||||
eventSource.close();
|
||||
};
|
||||
}, [token, collaborateurId, onEventReceived]);
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
// webhook-utils.js (VERSION ES MODULES)
|
||||
// webhook-utils.js (VERSION ES MODULES - CORRIGÉE)
|
||||
// Pour projets avec "type": "module" dans package.json
|
||||
|
||||
import axios from 'axios';
|
||||
@@ -65,6 +65,7 @@ class WebhookManager {
|
||||
for (let attempt = 1; attempt <= retries; attempt++) {
|
||||
try {
|
||||
console.log(`📤 Envoi webhook: ${eventType} vers ${targetUrl} (tentative ${attempt}/${retries})`);
|
||||
console.log(` Données:`, JSON.stringify(data, null, 2));
|
||||
|
||||
const response = await axios.post(
|
||||
`${targetUrl}/api/webhook/receive`,
|
||||
|
||||
Reference in New Issue
Block a user