Liaison d'un véhicule avec un user
This commit is contained in:
parent
566a7ba794
commit
c1a051463e
2 changed files with 354 additions and 170 deletions
442
index.php
442
index.php
|
|
@ -141,7 +141,6 @@ function authenticate(PDO $db, bool $required = true, ?string $requiredRole = nu
|
|||
]);
|
||||
}
|
||||
|
||||
// Vérifier l'expiration du jeton
|
||||
if (!empty($user['token_expires_at']) && strtotime($user['token_expires_at']) < time()) {
|
||||
sendJson(401, [
|
||||
'success' => false,
|
||||
|
|
@ -149,7 +148,6 @@ function authenticate(PDO $db, bool $required = true, ?string $requiredRole = nu
|
|||
]);
|
||||
}
|
||||
|
||||
// Vérifier le rôle requis (ex: 'admin')
|
||||
if ($requiredRole !== null && strtolower((string)$user['role']) !== strtolower($requiredRole)) {
|
||||
sendJson(403, [
|
||||
'success' => false,
|
||||
|
|
@ -160,6 +158,57 @@ function authenticate(PDO $db, bool $required = true, ?string $requiredRole = nu
|
|||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formate une ligne de voiture avec son propriétaire
|
||||
*/
|
||||
function formatCarRow(array $row): array
|
||||
{
|
||||
$row['id'] = (int)$row['id'];
|
||||
$row['annee'] = (int)$row['annee'];
|
||||
$row['dernier_km'] = isset($row['dernier_km']) ? (int)$row['dernier_km'] : null;
|
||||
|
||||
$row['proprietaire'] = null;
|
||||
if (!empty($row['user_id'])) {
|
||||
$row['proprietaire'] = [
|
||||
'id' => (int)$row['user_id'],
|
||||
'username' => $row['proprietaire_username'] ?? null,
|
||||
'nom' => $row['proprietaire_nom'] ?? null,
|
||||
];
|
||||
}
|
||||
unset($row['proprietaire_username'], $row['proprietaire_nom']);
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère une voiture par son ID avec les informations du propriétaire
|
||||
*/
|
||||
function getCarById(PDO $db, int $carId): ?array
|
||||
{
|
||||
$stmt = $db->prepare('
|
||||
SELECT c.*,
|
||||
u.username AS proprietaire_username,
|
||||
u.nom AS proprietaire_nom,
|
||||
(SELECT valeur FROM kilometrage WHERE car_id = c.id ORDER BY date_releve DESC, id DESC LIMIT 1) AS dernier_km
|
||||
FROM cars c
|
||||
LEFT JOIN users u ON c.user_id = u.id
|
||||
WHERE c.id = ?
|
||||
');
|
||||
$stmt->execute([$carId]);
|
||||
$car = $stmt->fetch();
|
||||
return $car ? formatCarRow($car) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si l'utilisateur est le propriétaire de la voiture ou un administrateur
|
||||
*/
|
||||
function canModifyCar(array $car, array $currentUser): bool
|
||||
{
|
||||
if (strtolower((string)$currentUser['role']) === 'admin') {
|
||||
return true;
|
||||
}
|
||||
return !empty($car['user_id']) && (int)$car['user_id'] === (int)$currentUser['id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Recherche d'une voiture par sa plaque d'immatriculation
|
||||
*/
|
||||
|
|
@ -170,8 +219,11 @@ function findCarByPlate(PDO $db, string $plaque): void
|
|||
|
||||
$stmt = $db->prepare('
|
||||
SELECT c.*,
|
||||
u.username AS proprietaire_username,
|
||||
u.nom AS proprietaire_nom,
|
||||
(SELECT valeur FROM kilometrage WHERE car_id = c.id ORDER BY date_releve DESC, id DESC LIMIT 1) AS dernier_km
|
||||
FROM cars c
|
||||
LEFT JOIN users u ON c.user_id = u.id
|
||||
WHERE UPPER(c.immatriculation) = :raw
|
||||
OR REPLACE(REPLACE(REPLACE(REPLACE(UPPER(c.immatriculation), "-", ""), " ", ""), ".", ""), "_", "") = :norm
|
||||
LIMIT 1
|
||||
|
|
@ -188,7 +240,7 @@ function findCarByPlate(PDO $db, string $plaque): void
|
|||
|
||||
sendJson(200, [
|
||||
'success' => true,
|
||||
'data' => $car
|
||||
'data' => formatCarRow($car)
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -201,45 +253,51 @@ try {
|
|||
if (empty($segments)) {
|
||||
sendJson(200, [
|
||||
'success' => true,
|
||||
'message' => 'API Voitures avec Authentification opérationnelle',
|
||||
'message' => 'API Voitures avec Gestion des Propriétaires & Authentification opérationnelle',
|
||||
'database' => DB_NAME,
|
||||
'comptes_demo' => [
|
||||
'admin' => ['username' => 'admin', 'password' => 'adminpassword', 'token_fixe' => 'admin-token-secret-12345'],
|
||||
'user' => ['username' => 'user', 'password' => 'userpassword', 'token_fixe' => 'user-token-secret-67890']
|
||||
'admin' => ['username' => 'admin', 'password' => 'adminpassword', 'role' => 'admin', 'token_fixe' => 'admin-token-secret-12345'],
|
||||
'user' => ['username' => 'user', 'password' => 'userpassword', 'role' => 'user', 'token_fixe' => 'user-token-secret-67890']
|
||||
],
|
||||
'regles_droits' => [
|
||||
'Admins' => 'Accès total à toutes les voitures, détails confidentiels, modifications et suppressions.',
|
||||
'Propriétaires' => 'Peuvent modifier/supprimer leurs propres voitures et gérer leurs entretiens, kilométrages et notes.',
|
||||
'Public' => 'Consultation générale des voitures et recherche par immatriculation.'
|
||||
],
|
||||
'endpoints' => [
|
||||
'Authentification' => [
|
||||
'POST /auth/login' => '[PUBLIC] Se connecter et obtenir un jeton (username, password)',
|
||||
'POST /auth/register' => '[PUBLIC] Créer un compte utilisateur (username, password, nom)',
|
||||
'GET /auth/me' => '[AUTHENTIFIÉ] Obtenir le profil de l\'utilisateur connecté',
|
||||
'GET /auth/me' => '[AUTHENTIFIÉ] Obtenir son profil et son rôle',
|
||||
'POST /auth/logout' => '[AUTHENTIFIÉ] Révoquer le jeton de session'
|
||||
],
|
||||
'Voitures' => [
|
||||
'GET /cars' => '[PUBLIC] Liste des voitures (filtrable par ?immatriculation=...)',
|
||||
'GET /cars/{id}' => '[PUBLIC] Détails d\'une voiture',
|
||||
'GET /cars' => '[PUBLIC] Liste des voitures (filtrable par ?immatriculation=..., ?user_id=..., ?mine=true)',
|
||||
'GET /cars/mes-voitures' => '[AUTHENTIFIÉ] Liste uniquement les voitures de l\'utilisateur connecté',
|
||||
'GET /cars/{id}' => '[PUBLIC] Détails d\'une voiture avec son propriétaire',
|
||||
'GET /cars/immatriculation/{plaque}' => '[PUBLIC] Identifier une voiture par sa plaque',
|
||||
'GET /cars/{id}/etat' => '[AUTHENTIFIÉ] État complet (voiture, dernier km, entretiens, notes)',
|
||||
'POST /cars' => '[AUTHENTIFIÉ] Créer une voiture (marque, modele, annee, dateAchat, VIN, immatriculation)',
|
||||
'PUT /cars/{id}' => '[AUTHENTIFIÉ] Modifier les paramètres d\'une voiture',
|
||||
'DELETE /cars/{id}' => '[ADMIN] Supprimer une voiture et toutes ses données associées'
|
||||
'GET /cars/{id}/etat' => '[PROPRIÉTAIRE ou ADMIN] État complet (voiture, dernier km, entretiens, notes)',
|
||||
'POST /cars' => '[AUTHENTIFIÉ] Créer une voiture (attribuée automatiquement à l\'utilisateur connecté)',
|
||||
'PUT /cars/{id}' => '[PROPRIÉTAIRE ou ADMIN] Modifier les paramètres d\'une voiture',
|
||||
'DELETE /cars/{id}' => '[PROPRIÉTAIRE ou ADMIN] Supprimer une voiture et toutes ses données associées'
|
||||
],
|
||||
'Kilométrage' => [
|
||||
'GET /cars/{id}/kilometrage' => '[PUBLIC] Historique des relevés kilométriques',
|
||||
'POST /cars/{id}/kilometrage' => '[AUTHENTIFIÉ] Ajouter un relevé kilométrique (valeur, date_releve)',
|
||||
'DELETE /kilometrage/{id}' => '[ADMIN] Supprimer un relevé kilométrique'
|
||||
'POST /cars/{id}/kilometrage' => '[PROPRIÉTAIRE ou ADMIN] Ajouter un relevé kilométrique',
|
||||
'DELETE /kilometrage/{id}' => '[PROPRIÉTAIRE ou ADMIN] Supprimer un relevé kilométrique'
|
||||
],
|
||||
'Entretiens' => [
|
||||
'GET /cars/{id}/maintenance' => '[PUBLIC] Historique des entretiens d\'une voiture',
|
||||
'GET /maintenance/{id}' => '[PUBLIC] Détails d\'un entretien',
|
||||
'POST /cars/{id}/maintenance' => '[AUTHENTIFIÉ] Ajouter un entretien (type_entretien, date_evenement, kilometrage, ...)',
|
||||
'PUT /maintenance/{id}' => '[AUTHENTIFIÉ] Modifier un entretien',
|
||||
'DELETE /maintenance/{id}' => '[ADMIN] Supprimer un entretien'
|
||||
'POST /cars/{id}/maintenance' => '[PROPRIÉTAIRE ou ADMIN] Ajouter un entretien',
|
||||
'PUT /maintenance/{id}' => '[PROPRIÉTAIRE ou ADMIN] Modifier un entretien',
|
||||
'DELETE /maintenance/{id}' => '[PROPRIÉTAIRE ou ADMIN] Supprimer un entretien'
|
||||
],
|
||||
'Notes (Contenu interne)' => [
|
||||
'GET /cars/{id}/notes' => '[AUTHENTIFIÉ] Consulter les notes d\'une voiture',
|
||||
'POST /cars/{id}/notes' => '[AUTHENTIFIÉ] Ajouter une note (titre, contenu)',
|
||||
'PUT /notes/{id}' => '[AUTHENTIFIÉ] Modifier une note',
|
||||
'DELETE /notes/{id}' => '[AUTHENTIFIÉ] Supprimer une note'
|
||||
'Notes (Confidentielles)' => [
|
||||
'GET /cars/{id}/notes' => '[PROPRIÉTAIRE ou ADMIN] Consulter les notes de suivi',
|
||||
'POST /cars/{id}/notes' => '[PROPRIÉTAIRE ou ADMIN] Ajouter une note',
|
||||
'PUT /notes/{id}' => '[PROPRIÉTAIRE ou ADMIN] Modifier une note',
|
||||
'DELETE /notes/{id}' => '[PROPRIÉTAIRE ou ADMIN] Supprimer une note'
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
|
@ -268,7 +326,6 @@ try {
|
|||
sendJson(401, ['success' => false, 'error' => 'Identifiants invalides (nom d\'utilisateur ou mot de passe incorrect)']);
|
||||
}
|
||||
|
||||
// Génération d'un nouveau jeton valide 7 jours
|
||||
$token = bin2hex(random_bytes(32));
|
||||
$expiresAt = date('Y-m-d H:i:s', time() + (7 * 86400));
|
||||
|
||||
|
|
@ -302,7 +359,6 @@ try {
|
|||
$nom = !empty($body['nom']) ? trim((string)$body['nom']) : null;
|
||||
$password = password_hash((string)$body['password'], PASSWORD_DEFAULT);
|
||||
|
||||
// Vérifier existence
|
||||
$stmtCheck = $db->prepare('SELECT id FROM users WHERE username = ?');
|
||||
$stmtCheck->execute([$username]);
|
||||
if ($stmtCheck->fetch()) {
|
||||
|
|
@ -332,7 +388,7 @@ try {
|
|||
]);
|
||||
}
|
||||
|
||||
// GET /auth/me (Profil de l'utilisateur connecté)
|
||||
// GET /auth/me
|
||||
if ($action === 'me' && $method === 'GET') {
|
||||
$user = authenticate($db, true);
|
||||
sendJson(200, [
|
||||
|
|
@ -347,7 +403,7 @@ try {
|
|||
]);
|
||||
}
|
||||
|
||||
// POST /auth/logout (Révocation du jeton)
|
||||
// POST /auth/logout
|
||||
if ($action === 'logout' && $method === 'POST') {
|
||||
$user = authenticate($db, true);
|
||||
$stmt = $db->prepare('UPDATE users SET api_token = NULL, token_expires_at = NULL WHERE id = ?');
|
||||
|
|
@ -373,6 +429,24 @@ try {
|
|||
// RESSOURCE: CARS (/cars ...)
|
||||
// =========================================================================
|
||||
if ($resource === 'cars' || $resource === 'voitures') {
|
||||
// GET /cars/mes-voitures : Liste des voitures de l'utilisateur connecté
|
||||
if (isset($segments[1]) && (strtolower($segments[1]) === 'mes-voitures' || strtolower($segments[1]) === 'mine') && $method === 'GET') {
|
||||
$currentUser = authenticate($db, true);
|
||||
$stmt = $db->prepare('
|
||||
SELECT c.*,
|
||||
u.username AS proprietaire_username,
|
||||
u.nom AS proprietaire_nom,
|
||||
(SELECT valeur FROM kilometrage WHERE car_id = c.id ORDER BY date_releve DESC, id DESC LIMIT 1) AS dernier_km
|
||||
FROM cars c
|
||||
LEFT JOIN users u ON c.user_id = u.id
|
||||
WHERE c.user_id = ?
|
||||
ORDER BY c.id ASC
|
||||
');
|
||||
$stmt->execute([$currentUser['id']]);
|
||||
$list = array_map('formatCarRow', $stmt->fetchAll());
|
||||
sendJson(200, ['success' => true, 'data' => $list]);
|
||||
}
|
||||
|
||||
// GET /cars/immatriculation/{plaque} (Public)
|
||||
if (isset($segments[1]) && strtolower($segments[1]) === 'immatriculation' && $method === 'GET') {
|
||||
$plaque = $segments[2] ?? null;
|
||||
|
|
@ -385,18 +459,25 @@ try {
|
|||
$carId = isset($segments[1]) && is_numeric($segments[1]) ? (int)$segments[1] : null;
|
||||
$subResource = $segments[2] ?? null;
|
||||
|
||||
// 1. GET /cars/{id}/etat [CONTENU RESTREINT - AUTHENTIFICATION REQUISE]
|
||||
// 1. GET /cars/{id}/etat [PROPRIÉTAIRE OU ADMIN REQUIS]
|
||||
if ($carId && $subResource === 'etat' && $method === 'GET') {
|
||||
$currentUser = authenticate($db, true);
|
||||
$car = getCarById($db, $carId);
|
||||
if (!$car) {
|
||||
sendJson(404, ['success' => false, 'error' => "Voiture #{$carId} introuvable"]);
|
||||
}
|
||||
|
||||
if (!canModifyCar($car, $currentUser)) {
|
||||
sendJson(403, [
|
||||
'success' => false,
|
||||
'error' => "Accès refusé. Les administrateurs et le propriétaire du véhicule sont les seuls autorisés à consulter son état complet."
|
||||
]);
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $db->prepare('CALL sp_getEtatVoiture(:id)');
|
||||
$stmt->execute([':id' => $carId]);
|
||||
|
||||
$car = $stmt->fetch();
|
||||
if (!$car) {
|
||||
sendJson(404, ['success' => false, 'error' => "Voiture #{$carId} introuvable"]);
|
||||
}
|
||||
$carRow = $stmt->fetch();
|
||||
|
||||
$maintenances = [];
|
||||
if ($stmt->nextRowset()) {
|
||||
|
|
@ -411,7 +492,10 @@ try {
|
|||
|
||||
sendJson(200, [
|
||||
'success' => true,
|
||||
'consulted_by' => $currentUser['username'],
|
||||
'consulted_by' => [
|
||||
'username' => $currentUser['username'],
|
||||
'role' => $currentUser['role']
|
||||
],
|
||||
'data' => [
|
||||
'voiture' => $car,
|
||||
'maintenances' => $maintenances,
|
||||
|
|
@ -419,17 +503,6 @@ try {
|
|||
]
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
$stmtCar = $db->prepare('
|
||||
SELECT c.*,
|
||||
(SELECT valeur FROM kilometrage WHERE car_id = c.id ORDER BY date_releve DESC, id DESC LIMIT 1) AS dernier_km
|
||||
FROM cars c WHERE c.id = ?
|
||||
');
|
||||
$stmtCar->execute([$carId]);
|
||||
$car = $stmtCar->fetch();
|
||||
if (!$car) {
|
||||
sendJson(404, ['success' => false, 'error' => "Voiture #{$carId} introuvable"]);
|
||||
}
|
||||
|
||||
$stmtMaint = $db->prepare('SELECT * FROM maintenance_logs WHERE car_id = ? ORDER BY date_evenement DESC');
|
||||
$stmtMaint->execute([$carId]);
|
||||
|
||||
|
|
@ -438,7 +511,10 @@ try {
|
|||
|
||||
sendJson(200, [
|
||||
'success' => true,
|
||||
'consulted_by' => $currentUser['username'],
|
||||
'consulted_by' => [
|
||||
'username' => $currentUser['username'],
|
||||
'role' => $currentUser['role']
|
||||
],
|
||||
'data' => [
|
||||
'voiture' => $car,
|
||||
'maintenances' => $stmtMaint->fetchAll(),
|
||||
|
|
@ -468,9 +544,20 @@ try {
|
|||
sendJson(200, ['success' => true, 'data' => $data]);
|
||||
}
|
||||
|
||||
// POST: [ACTION PROTÉGÉE - AUTHENTIFICATION REQUISE]
|
||||
// POST: [PROPRIÉTAIRE OU ADMIN REQUIS]
|
||||
if ($method === 'POST') {
|
||||
authenticate($db, true);
|
||||
$currentUser = authenticate($db, true);
|
||||
$car = getCarById($db, $carId);
|
||||
if (!$car) {
|
||||
sendJson(404, ['success' => false, 'error' => "Voiture #{$carId} introuvable"]);
|
||||
}
|
||||
|
||||
if (!canModifyCar($car, $currentUser)) {
|
||||
sendJson(403, [
|
||||
'success' => false,
|
||||
'error' => "Accès refusé. Seul le propriétaire ou un administrateur peut enregistrer un relevé kilométrique pour cette voiture."
|
||||
]);
|
||||
}
|
||||
|
||||
$body = getBody();
|
||||
if (!isset($body['valeur'])) {
|
||||
|
|
@ -507,9 +594,20 @@ try {
|
|||
sendJson(200, ['success' => true, 'data' => $stmt->fetchAll()]);
|
||||
}
|
||||
|
||||
// POST: [ACTION PROTÉGÉE - AUTHENTIFICATION REQUISE]
|
||||
// POST: [PROPRIÉTAIRE OU ADMIN REQUIS]
|
||||
if ($method === 'POST') {
|
||||
authenticate($db, true);
|
||||
$currentUser = authenticate($db, true);
|
||||
$car = getCarById($db, $carId);
|
||||
if (!$car) {
|
||||
sendJson(404, ['success' => false, 'error' => "Voiture #{$carId} introuvable"]);
|
||||
}
|
||||
|
||||
if (!canModifyCar($car, $currentUser)) {
|
||||
sendJson(403, [
|
||||
'success' => false,
|
||||
'error' => "Accès refusé. Seul le propriétaire ou un administrateur peut ajouter un entretien pour cette voiture."
|
||||
]);
|
||||
}
|
||||
|
||||
$body = getBody();
|
||||
if (empty($body['type_entretien']) || empty($body['date_evenement']) || !isset($body['kilometrage'])) {
|
||||
|
|
@ -546,21 +644,30 @@ try {
|
|||
sendJson(405, ['success' => false, 'error' => 'Méthode non autorisée pour cette sous-ressource']);
|
||||
}
|
||||
|
||||
// 4. /cars/{id}/notes [CONTENU RESTREINT - AUTHENTIFICATION REQUISE]
|
||||
// 4. /cars/{id}/notes [PROPRIÉTAIRE OU ADMIN REQUIS]
|
||||
if ($carId && $subResource === 'notes') {
|
||||
// GET: Protégé (Notes de suivi confidentielles)
|
||||
if ($method === 'GET') {
|
||||
authenticate($db, true);
|
||||
$currentUser = authenticate($db, true);
|
||||
$car = getCarById($db, $carId);
|
||||
if (!$car) {
|
||||
sendJson(404, ['success' => false, 'error' => "Voiture #{$carId} introuvable"]);
|
||||
}
|
||||
|
||||
if (!canModifyCar($car, $currentUser)) {
|
||||
sendJson(403, [
|
||||
'success' => false,
|
||||
'error' => "Accès refusé. Seul le propriétaire ou un administrateur peut consulter ou ajouter des notes pour cette voiture."
|
||||
]);
|
||||
}
|
||||
|
||||
// GET: Notes
|
||||
if ($method === 'GET') {
|
||||
$stmt = $db->prepare('SELECT * FROM notes WHERE car_id = ? ORDER BY date_creation DESC');
|
||||
$stmt->execute([$carId]);
|
||||
sendJson(200, ['success' => true, 'data' => $stmt->fetchAll()]);
|
||||
}
|
||||
|
||||
// POST: [ACTION PROTÉGÉE - AUTHENTIFICATION REQUISE]
|
||||
// POST: Ajouter une note
|
||||
if ($method === 'POST') {
|
||||
authenticate($db, true);
|
||||
|
||||
$body = getBody();
|
||||
if (empty($body['contenu'])) {
|
||||
sendJson(400, ['success' => false, 'error' => 'Le champ contenu est obligatoire']);
|
||||
|
|
@ -588,39 +695,59 @@ try {
|
|||
|
||||
// --- ACTIONS PRINCIPALES SUR LES VOITURES ---
|
||||
|
||||
// GET /cars : Liste toutes les voitures (Public)
|
||||
// GET /cars : Liste toutes les voitures (Public / Filtrable)
|
||||
if ($carId === null && $subResource === null && $method === 'GET') {
|
||||
// Filtre par immatriculation
|
||||
if (!empty($_GET['immatriculation'])) {
|
||||
findCarByPlate($db, (string)$_GET['immatriculation']);
|
||||
}
|
||||
|
||||
$sql = 'SELECT c.*,
|
||||
$currentUser = authenticate($db, false);
|
||||
$where = [];
|
||||
$params = [];
|
||||
|
||||
// Filtre mes voitures (?mine=true)
|
||||
if (!empty($_GET['mine']) && $currentUser) {
|
||||
$where[] = 'c.user_id = ?';
|
||||
$params[] = $currentUser['id'];
|
||||
} elseif (!empty($_GET['user_id'])) {
|
||||
$where[] = 'c.user_id = ?';
|
||||
$params[] = (int)$_GET['user_id'];
|
||||
}
|
||||
|
||||
$sql = '
|
||||
SELECT c.*,
|
||||
u.username AS proprietaire_username,
|
||||
u.nom AS proprietaire_nom,
|
||||
(SELECT valeur FROM kilometrage WHERE car_id = c.id ORDER BY date_releve DESC, id DESC LIMIT 1) AS dernier_km
|
||||
FROM cars c
|
||||
ORDER BY c.id ASC';
|
||||
$stmt = $db->query($sql);
|
||||
sendJson(200, ['success' => true, 'data' => $stmt->fetchAll()]);
|
||||
LEFT JOIN users u ON c.user_id = u.id
|
||||
';
|
||||
|
||||
if (!empty($where)) {
|
||||
$sql .= ' WHERE ' . implode(' AND ', $where);
|
||||
}
|
||||
$sql .= ' ORDER BY c.id ASC';
|
||||
|
||||
$stmt = $db->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$rows = array_map('formatCarRow', $stmt->fetchAll());
|
||||
|
||||
sendJson(200, ['success' => true, 'data' => $rows]);
|
||||
}
|
||||
|
||||
// GET /cars/{id} : Consulter une voiture (Public)
|
||||
if ($carId !== null && $subResource === null && $method === 'GET') {
|
||||
$stmt = $db->prepare('
|
||||
SELECT c.*,
|
||||
(SELECT valeur FROM kilometrage WHERE car_id = c.id ORDER BY date_releve DESC, id DESC LIMIT 1) AS dernier_km
|
||||
FROM cars c
|
||||
WHERE c.id = ?
|
||||
');
|
||||
$stmt->execute([$carId]);
|
||||
$car = $stmt->fetch();
|
||||
$car = getCarById($db, $carId);
|
||||
if (!$car) {
|
||||
sendJson(404, ['success' => false, 'error' => "Voiture #{$carId} introuvable"]);
|
||||
}
|
||||
sendJson(200, ['success' => true, 'data' => $car]);
|
||||
}
|
||||
|
||||
// POST /cars : Créer une voiture [ACTION PROTÉGÉE - AUTHENTIFICATION REQUISE]
|
||||
// POST /cars : Créer une voiture [AUTHENTIFIÉ REQUIS - ATTRIBUTION DU USER_ID]
|
||||
if ($carId === null && $method === 'POST') {
|
||||
authenticate($db, true);
|
||||
$currentUser = authenticate($db, true);
|
||||
|
||||
$body = getBody();
|
||||
$required = ['marque', 'modele', 'annee', 'dateAchat'];
|
||||
|
|
@ -637,7 +764,19 @@ try {
|
|||
$vin = !empty($body['VIN']) ? trim((string)$body['VIN']) : null;
|
||||
$immatriculation = !empty($body['immatriculation']) ? strtoupper(trim((string)$body['immatriculation'])) : null;
|
||||
|
||||
// Vérifier unicité de l'immatriculation
|
||||
// Détermination du propriétaire (user_id):
|
||||
// Si l'utilisateur est admin et spécifie un user_id, on l'attribue à cet utilisateur; sinon c'est l'utilisateur connecté
|
||||
$targetUserId = (int)$currentUser['id'];
|
||||
if (strtolower((string)$currentUser['role']) === 'admin' && !empty($body['user_id'])) {
|
||||
$targetUserId = (int)$body['user_id'];
|
||||
$chkUser = $db->prepare('SELECT id FROM users WHERE id = ?');
|
||||
$chkUser->execute([$targetUserId]);
|
||||
if (!$chkUser->fetch()) {
|
||||
sendJson(400, ['success' => false, 'error' => "L'utilisateur #$targetUserId spécifié est introuvable."]);
|
||||
}
|
||||
}
|
||||
|
||||
// Vérifier unicité de la plaque
|
||||
if ($immatriculation !== null) {
|
||||
$normImmat = str_replace(['-', ' ', '.', '_'], '', $immatriculation);
|
||||
$stmtCheck = $db->prepare('
|
||||
|
|
@ -654,10 +793,11 @@ try {
|
|||
}
|
||||
}
|
||||
|
||||
// Appel de la procédure stockée sp_insertVoiture
|
||||
// Procédure stockée sp_insertVoiture avec user_id
|
||||
try {
|
||||
$stmt = $db->prepare('CALL sp_insertVoiture(:marque, :modele, :annee, :dateAchat, :vin, :immatriculation)');
|
||||
$stmt = $db->prepare('CALL sp_insertVoiture(:user_id, :marque, :modele, :annee, :dateAchat, :vin, :immatriculation)');
|
||||
$stmt->execute([
|
||||
':user_id' => $targetUserId,
|
||||
':marque' => $marque,
|
||||
':modele' => $modele,
|
||||
':annee' => $annee,
|
||||
|
|
@ -669,8 +809,8 @@ try {
|
|||
$stmt->closeCursor();
|
||||
$newId = isset($res['new_id']) ? (int)$res['new_id'] : (int)$db->lastInsertId();
|
||||
} catch (Exception $e) {
|
||||
$stmt = $db->prepare('INSERT INTO cars (marque, modele, annee, dateAchat, VIN, immatriculation) VALUES (?, ?, ?, ?, ?, ?)');
|
||||
$stmt->execute([$marque, $modele, $annee, $dateAchat, $vin, $immatriculation]);
|
||||
$stmt = $db->prepare('INSERT INTO cars (user_id, marque, modele, annee, dateAchat, VIN, immatriculation) VALUES (?, ?, ?, ?, ?, ?, ?)');
|
||||
$stmt->execute([$targetUserId, $marque, $modele, $annee, $dateAchat, $vin, $immatriculation]);
|
||||
$newId = (int)$db->lastInsertId();
|
||||
}
|
||||
|
||||
|
|
@ -679,33 +819,40 @@ try {
|
|||
$kmStmt->execute([$newId, $dateAchat, (int)$body['kilometrage_initial']]);
|
||||
}
|
||||
|
||||
$stmtGet = $db->prepare('
|
||||
SELECT c.*,
|
||||
(SELECT valeur FROM kilometrage WHERE car_id = c.id ORDER BY date_releve DESC, id DESC LIMIT 1) AS dernier_km
|
||||
FROM cars c
|
||||
WHERE c.id = ?
|
||||
');
|
||||
$stmtGet->execute([$newId]);
|
||||
$createdCar = getCarById($db, $newId);
|
||||
|
||||
sendJson(201, [
|
||||
'success' => true,
|
||||
'message' => 'Voiture créée avec succès',
|
||||
'data' => $stmtGet->fetch()
|
||||
'data' => $createdCar
|
||||
]);
|
||||
}
|
||||
|
||||
// PUT / PATCH /cars/{id} : Mettre à jour les paramètres [ACTION PROTÉGÉE - AUTHENTIFICATION REQUISE]
|
||||
// PUT / PATCH /cars/{id} : Mettre à jour les paramètres [SEUL LE PROPRIÉTAIRE OU ADMIN]
|
||||
if ($carId !== null && $subResource === null && ($method === 'PUT' || $method === 'PATCH')) {
|
||||
authenticate($db, true);
|
||||
$currentUser = authenticate($db, true);
|
||||
$car = getCarById($db, $carId);
|
||||
|
||||
$check = $db->prepare('SELECT id FROM cars WHERE id = ?');
|
||||
$check->execute([$carId]);
|
||||
if (!$check->fetch()) {
|
||||
if (!$car) {
|
||||
sendJson(404, ['success' => false, 'error' => "Voiture #{$carId} introuvable"]);
|
||||
}
|
||||
|
||||
// Vérification de la propriété
|
||||
if (!canModifyCar($car, $currentUser)) {
|
||||
sendJson(403, [
|
||||
'success' => false,
|
||||
'error' => "Accès refusé. Seul le propriétaire de la voiture ou un administrateur est autorisé à la modifier."
|
||||
]);
|
||||
}
|
||||
|
||||
$body = getBody();
|
||||
$allowedFields = ['marque', 'modele', 'annee', 'dateAchat', 'VIN', 'immatriculation'];
|
||||
|
||||
// Seul l'admin peut réassigner le user_id de la voiture
|
||||
if (strtolower((string)$currentUser['role']) === 'admin' && array_key_exists('user_id', $body)) {
|
||||
$allowedFields[] = 'user_id';
|
||||
}
|
||||
|
||||
$updates = [];
|
||||
$params = [];
|
||||
|
||||
|
|
@ -744,31 +891,32 @@ try {
|
|||
$stmt = $db->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
|
||||
$stmtGet = $db->prepare('
|
||||
SELECT c.*,
|
||||
(SELECT valeur FROM kilometrage WHERE car_id = c.id ORDER BY date_releve DESC, id DESC LIMIT 1) AS dernier_km
|
||||
FROM cars c
|
||||
WHERE c.id = ?
|
||||
');
|
||||
$stmtGet->execute([$carId]);
|
||||
$updatedCar = getCarById($db, $carId);
|
||||
|
||||
sendJson(200, [
|
||||
'success' => true,
|
||||
'message' => 'Paramètres de la voiture mis à jour avec succès',
|
||||
'data' => $stmtGet->fetch()
|
||||
'data' => $updatedCar
|
||||
]);
|
||||
}
|
||||
|
||||
// DELETE /cars/{id} : Supprimer une voiture [ACTION PROTÉGÉE - RÔLE ADMIN REQUIS]
|
||||
// DELETE /cars/{id} : Supprimer une voiture [SEUL LE PROPRIÉTAIRE OU ADMIN]
|
||||
if ($carId !== null && $subResource === null && $method === 'DELETE') {
|
||||
authenticate($db, true, 'admin');
|
||||
$currentUser = authenticate($db, true);
|
||||
$car = getCarById($db, $carId);
|
||||
|
||||
$check = $db->prepare('SELECT id FROM cars WHERE id = ?');
|
||||
$check->execute([$carId]);
|
||||
if (!$check->fetch()) {
|
||||
if (!$car) {
|
||||
sendJson(404, ['success' => false, 'error' => "Voiture #{$carId} introuvable"]);
|
||||
}
|
||||
|
||||
// Vérification de la propriété
|
||||
if (!canModifyCar($car, $currentUser)) {
|
||||
sendJson(403, [
|
||||
'success' => false,
|
||||
'error' => "Accès refusé. Seul le propriétaire de la voiture ou un administrateur est autorisé à la supprimer."
|
||||
]);
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $db->prepare('CALL sp_deleteVoiture(:id)');
|
||||
$stmt->execute([':id' => $carId]);
|
||||
|
|
@ -793,15 +941,24 @@ try {
|
|||
if ($resource === 'kilometrage') {
|
||||
$kmId = isset($segments[1]) && is_numeric($segments[1]) ? (int)$segments[1] : null;
|
||||
|
||||
// DELETE: [ACTION PROTÉGÉE - RÔLE ADMIN REQUIS]
|
||||
if ($kmId && $method === 'DELETE') {
|
||||
authenticate($db, true, 'admin');
|
||||
$currentUser = authenticate($db, true);
|
||||
|
||||
// Récupérer la voiture liée
|
||||
$stmtKm = $db->prepare('SELECT car_id FROM kilometrage WHERE id = ?');
|
||||
$stmtKm->execute([$kmId]);
|
||||
$kmRow = $stmtKm->fetch();
|
||||
if (!$kmRow) {
|
||||
sendJson(404, ['success' => false, 'error' => "Relevé kilométrique #{$kmId} introuvable"]);
|
||||
}
|
||||
|
||||
$car = getCarById($db, (int)$kmRow['car_id']);
|
||||
if (!canModifyCar($car, $currentUser)) {
|
||||
sendJson(403, ['success' => false, 'error' => "Accès refusé. Seul le propriétaire du véhicule ou un administrateur peut supprimer ce relevé."]);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare('DELETE FROM kilometrage WHERE id = ?');
|
||||
$stmt->execute([$kmId]);
|
||||
if ($stmt->rowCount() === 0) {
|
||||
sendJson(404, ['success' => false, 'error' => "Relevé kilométrique #{$kmId} introuvable"]);
|
||||
}
|
||||
sendJson(200, ['success' => true, 'message' => "Relevé kilométrique #{$kmId} supprimé"]);
|
||||
}
|
||||
|
||||
|
|
@ -818,7 +975,6 @@ try {
|
|||
sendJson(400, ['success' => false, 'error' => 'Identifiant d\'entretien requis']);
|
||||
}
|
||||
|
||||
// GET: Public
|
||||
if ($method === 'GET') {
|
||||
$stmt = $db->prepare('SELECT * FROM maintenance_logs WHERE id = ?');
|
||||
$stmt->execute([$maintId]);
|
||||
|
|
@ -829,9 +985,20 @@ try {
|
|||
sendJson(200, ['success' => true, 'data' => $item]);
|
||||
}
|
||||
|
||||
// PUT/PATCH: [ACTION PROTÉGÉE - AUTHENTIFICATION REQUISE]
|
||||
if ($method === 'PUT' || $method === 'PATCH') {
|
||||
authenticate($db, true);
|
||||
$currentUser = authenticate($db, true);
|
||||
|
||||
$stmtMaint = $db->prepare('SELECT car_id FROM maintenance_logs WHERE id = ?');
|
||||
$stmtMaint->execute([$maintId]);
|
||||
$maintRow = $stmtMaint->fetch();
|
||||
if (!$maintRow) {
|
||||
sendJson(404, ['success' => false, 'error' => "Entretien #{$maintId} introuvable"]);
|
||||
}
|
||||
|
||||
$car = getCarById($db, (int)$maintRow['car_id']);
|
||||
if (!canModifyCar($car, $currentUser)) {
|
||||
sendJson(403, ['success' => false, 'error' => "Accès refusé. Seul le propriétaire du véhicule ou un administrateur peut modifier cet entretien."]);
|
||||
}
|
||||
|
||||
$body = getBody();
|
||||
$allowed = ['type_entretien', 'date_evenement', 'kilometrage', 'description', 'prix'];
|
||||
|
|
@ -862,15 +1029,23 @@ try {
|
|||
]);
|
||||
}
|
||||
|
||||
// DELETE: [ACTION PROTÉGÉE - RÔLE ADMIN REQUIS]
|
||||
if ($method === 'DELETE') {
|
||||
authenticate($db, true, 'admin');
|
||||
$currentUser = authenticate($db, true);
|
||||
|
||||
$stmtMaint = $db->prepare('SELECT car_id FROM maintenance_logs WHERE id = ?');
|
||||
$stmtMaint->execute([$maintId]);
|
||||
$maintRow = $stmtMaint->fetch();
|
||||
if (!$maintRow) {
|
||||
sendJson(404, ['success' => false, 'error' => "Entretien #{$maintId} introuvable"]);
|
||||
}
|
||||
|
||||
$car = getCarById($db, (int)$maintRow['car_id']);
|
||||
if (!canModifyCar($car, $currentUser)) {
|
||||
sendJson(403, ['success' => false, 'error' => "Accès refusé. Seul le propriétaire du véhicule ou un administrateur peut supprimer cet entretien."]);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare('DELETE FROM maintenance_logs WHERE id = ?');
|
||||
$stmt->execute([$maintId]);
|
||||
if ($stmt->rowCount() === 0) {
|
||||
sendJson(404, ['success' => false, 'error' => "Entretien #{$maintId} introuvable"]);
|
||||
}
|
||||
sendJson(200, ['success' => true, 'message' => "Entretien #{$maintId} supprimé avec succès"]);
|
||||
}
|
||||
|
||||
|
|
@ -878,7 +1053,7 @@ try {
|
|||
}
|
||||
|
||||
// =========================================================================
|
||||
// RESSOURCE: NOTES DIRECT (/notes/{id}) [CONTENU RESTREINT - AUTHENTIFICATION REQUISE]
|
||||
// RESSOURCE: NOTES DIRECT (/notes/{id}) [PROPRIÉTAIRE OU ADMIN REQUIS]
|
||||
// =========================================================================
|
||||
if ($resource === 'notes') {
|
||||
$noteId = isset($segments[1]) && is_numeric($segments[1]) ? (int)$segments[1] : null;
|
||||
|
|
@ -887,23 +1062,27 @@ try {
|
|||
sendJson(400, ['success' => false, 'error' => 'Identifiant de note requis']);
|
||||
}
|
||||
|
||||
// GET: Authentifié
|
||||
if ($method === 'GET') {
|
||||
authenticate($db, true);
|
||||
$currentUser = authenticate($db, true);
|
||||
|
||||
$stmt = $db->prepare('SELECT * FROM notes WHERE id = ?');
|
||||
$stmt->execute([$noteId]);
|
||||
$item = $stmt->fetch();
|
||||
if (!$item) {
|
||||
$stmtNote = $db->prepare('SELECT car_id, titre, contenu, date_creation FROM notes WHERE id = ?');
|
||||
$stmtNote->execute([$noteId]);
|
||||
$noteRow = $stmtNote->fetch();
|
||||
if (!$noteRow) {
|
||||
sendJson(404, ['success' => false, 'error' => "Note #{$noteId} introuvable"]);
|
||||
}
|
||||
sendJson(200, ['success' => true, 'data' => $item]);
|
||||
|
||||
$car = getCarById($db, (int)$noteRow['car_id']);
|
||||
if (!canModifyCar($car, $currentUser)) {
|
||||
sendJson(403, ['success' => false, 'error' => "Accès refusé. Seul le propriétaire du véhicule ou un administrateur peut accéder à cette note."]);
|
||||
}
|
||||
|
||||
// PUT/PATCH: Authentifié
|
||||
if ($method === 'PUT' || $method === 'PATCH') {
|
||||
authenticate($db, true);
|
||||
// GET: Consulter la note
|
||||
if ($method === 'GET') {
|
||||
sendJson(200, ['success' => true, 'data' => $noteRow]);
|
||||
}
|
||||
|
||||
// PUT/PATCH: Modifier la note
|
||||
if ($method === 'PUT' || $method === 'PATCH') {
|
||||
$body = getBody();
|
||||
$allowed = ['titre', 'contenu'];
|
||||
$updates = [];
|
||||
|
|
@ -933,15 +1112,10 @@ try {
|
|||
]);
|
||||
}
|
||||
|
||||
// DELETE: Authentifié
|
||||
// DELETE: Supprimer la note
|
||||
if ($method === 'DELETE') {
|
||||
authenticate($db, true);
|
||||
|
||||
$stmt = $db->prepare('DELETE FROM notes WHERE id = ?');
|
||||
$stmt->execute([$noteId]);
|
||||
if ($stmt->rowCount() === 0) {
|
||||
sendJson(404, ['success' => false, 'error' => "Note #{$noteId} introuvable"]);
|
||||
}
|
||||
sendJson(200, ['success' => true, 'message' => "Note #{$noteId} supprimée avec succès"]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,9 +53,9 @@ CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_getKilometrages` (IN `p_id` INT,
|
|||
END$$
|
||||
|
||||
DROP PROCEDURE IF EXISTS `sp_insertVoiture`$$
|
||||
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_insertVoiture` (IN `p_marque` VARCHAR(255), IN `p_modele` VARCHAR(255), IN `p_annee` INT, IN `p_dateAchat` DATE, IN `p_VIN` VARCHAR(255), IN `p_immatriculation` VARCHAR(20)) BEGIN
|
||||
INSERT INTO cars (marque, modele, annee, dateAchat, VIN, immatriculation)
|
||||
VALUES (p_marque, p_modele, p_annee, p_dateAchat, p_VIN, p_immatriculation);
|
||||
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_insertVoiture` (IN `p_user_id` INT, IN `p_marque` VARCHAR(255), IN `p_modele` VARCHAR(255), IN `p_annee` INT, IN `p_dateAchat` DATE, IN `p_VIN` VARCHAR(255), IN `p_immatriculation` VARCHAR(20)) BEGIN
|
||||
INSERT INTO cars (user_id, marque, modele, annee, dateAchat, VIN, immatriculation)
|
||||
VALUES (p_user_id, p_marque, p_modele, p_annee, p_dateAchat, p_VIN, p_immatriculation);
|
||||
SELECT LAST_INSERT_ID() AS new_id;
|
||||
END$$
|
||||
|
||||
|
|
@ -63,6 +63,35 @@ DELIMITER ;
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Structure de la table `users`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `users`;
|
||||
CREATE TABLE IF NOT EXISTS `users` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`username` varchar(50) NOT NULL,
|
||||
`password` varchar(255) NOT NULL,
|
||||
`nom` varchar(100) DEFAULT NULL,
|
||||
`role` varchar(20) NOT NULL DEFAULT 'user',
|
||||
`api_token` varchar(64) DEFAULT NULL,
|
||||
`token_expires_at` datetime DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `idx_username` (`username`),
|
||||
UNIQUE KEY `idx_api_token` (`api_token`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
--
|
||||
-- Déchargement des données de la table `users`
|
||||
--
|
||||
|
||||
INSERT INTO `users` (`id`, `username`, `password`, `nom`, `role`, `api_token`) VALUES
|
||||
(1, 'admin', '$2y$10$v0vjF8yL15gA1kXfA9q3hOb00Q0pM0N8dMh2pA7uT1VlqjXlZ9rKq', 'Administrateur', 'admin', 'admin-token-secret-12345'),
|
||||
(2, 'user', '$2y$10$Q4M1s1Fk6vjF8yL15gA1kXfA9q3hOb00Q0pM0N8dMh2pA7uT1Vlqy', 'Utilisateur Standard', 'user', 'user-token-secret-67890');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Structure de la table `cars`
|
||||
--
|
||||
|
|
@ -70,6 +99,7 @@ DELIMITER ;
|
|||
DROP TABLE IF EXISTS `cars`;
|
||||
CREATE TABLE IF NOT EXISTS `cars` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int DEFAULT NULL,
|
||||
`marque` varchar(50) NOT NULL,
|
||||
`modele` varchar(50) NOT NULL,
|
||||
`annee` int NOT NULL,
|
||||
|
|
@ -77,6 +107,7 @@ CREATE TABLE IF NOT EXISTS `cars` (
|
|||
`VIN` varchar(17) DEFAULT NULL,
|
||||
`immatriculation` varchar(20) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_cars_user_id` (`user_id`),
|
||||
UNIQUE KEY `idx_immatriculation` (`immatriculation`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
|
|
@ -84,9 +115,9 @@ CREATE TABLE IF NOT EXISTS `cars` (
|
|||
-- Déchargement des données de la table `cars`
|
||||
--
|
||||
|
||||
INSERT INTO `cars` (`id`, `marque`, `modele`, `annee`, `dateAchat`, `VIN`, `immatriculation`) VALUES
|
||||
(1, 'Peugeot', '207', 2009, '2025-05-20', 'VF3WA8HZCXXXXXXXX', 'AB-123-CD'),
|
||||
(2, 'Peugeot', '208', 2010, '2025-05-20', 'VF3WA8HZCXXXXXXXX', 'EF-456-GH');
|
||||
INSERT INTO `cars` (`id`, `user_id`, `marque`, `modele`, `annee`, `dateAchat`, `VIN`, `immatriculation`) VALUES
|
||||
(1, 1, 'Peugeot', '207', 2009, '2025-05-20', 'VF3WA8HZCXXXXXXXX', 'AB-123-CD'),
|
||||
(2, 2, 'Peugeot', '208', 2010, '2025-05-20', 'VF3WA8HZCXXXXXXXX', 'EF-456-GH');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
|
@ -185,31 +216,10 @@ ALTER TABLE `notes`
|
|||
ADD CONSTRAINT `fk_notes_car_id` FOREIGN KEY (`car_id`) REFERENCES `cars` (`id`) ON DELETE CASCADE;
|
||||
|
||||
--
|
||||
-- Structure de la table `users`
|
||||
-- Contraintes pour la table `cars`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `users`;
|
||||
CREATE TABLE IF NOT EXISTS `users` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`username` varchar(50) NOT NULL,
|
||||
`password` varchar(255) NOT NULL,
|
||||
`nom` varchar(100) DEFAULT NULL,
|
||||
`role` varchar(20) NOT NULL DEFAULT 'user',
|
||||
`api_token` varchar(64) DEFAULT NULL,
|
||||
`token_expires_at` datetime DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `idx_username` (`username`),
|
||||
UNIQUE KEY `idx_api_token` (`api_token`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
--
|
||||
-- Déchargement des données de la table `users`
|
||||
--
|
||||
|
||||
INSERT INTO `users` (`id`, `username`, `password`, `nom`, `role`, `api_token`) VALUES
|
||||
(1, 'admin', '$2y$10$v0vjF8yL15gA1kXfA9q3hOb00Q0pM0N8dMh2pA7uT1VlqjXlZ9rKq', 'Administrateur', 'admin', 'admin-token-secret-12345'),
|
||||
(2, 'user', '$2y$10$Q4M1s1Fk6vjF8yL15gA1kXfA9q3hOb00Q0pM0N8dMh2pA7uT1Vlqy', 'Utilisateur Standard', 'user', 'user-token-secret-67890');
|
||||
ALTER TABLE `cars`
|
||||
ADD CONSTRAINT `fk_cars_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL;
|
||||
|
||||
COMMIT;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue