chore: update custom-rules & update style & script data
This commit is contained in:
@@ -196,33 +196,3 @@
|
|||||||
group: "{{ docker_group }}"
|
group: "{{ docker_group }}"
|
||||||
mode: "0640"
|
mode: "0640"
|
||||||
ignore_errors: yes
|
ignore_errors: yes
|
||||||
|
|
||||||
- name: Build Docker project
|
|
||||||
ansible.builtin.command:
|
|
||||||
cmd: docker compose -f docker-compose-prod.yml build
|
|
||||||
chdir: "{{ docker_dir }}/docker"
|
|
||||||
become: yes
|
|
||||||
become_user: "{{ docker_user }}"
|
|
||||||
tags: build
|
|
||||||
|
|
||||||
- name: Start Docker project
|
|
||||||
ansible.builtin.command:
|
|
||||||
cmd: docker compose -f docker-compose-prod.yml up -d
|
|
||||||
chdir: "{{ docker_dir }}/docker"
|
|
||||||
become: yes
|
|
||||||
become_user: "{{ docker_user }}"
|
|
||||||
tags: start
|
|
||||||
|
|
||||||
- name: Show Docker containers
|
|
||||||
ansible.builtin.command:
|
|
||||||
cmd: docker compose ps
|
|
||||||
chdir: "{{ docker_dir }}/docker"
|
|
||||||
become: yes
|
|
||||||
become_user: "{{ docker_user }}"
|
|
||||||
register: docker_ps
|
|
||||||
tags: start
|
|
||||||
|
|
||||||
- name: Display Docker containers
|
|
||||||
debug:
|
|
||||||
var: docker_ps.stdout_lines
|
|
||||||
tags: start
|
|
||||||
|
|||||||
@@ -1,3 +1,11 @@
|
|||||||
|
SecRuleRemoveById 932235
|
||||||
|
SecRuleRemoveById 911100
|
||||||
|
|
||||||
|
SecRule REQUEST_URI "@streq /api/v2/admin/protected/products" \
|
||||||
|
"id:399002,phase:2,nolog,pass,\
|
||||||
|
ctl:ruleRemoveById=920120,\
|
||||||
|
ctl:ruleRemoveById=920121"
|
||||||
|
|
||||||
SecRule IP:BANNED "@eq 1" \
|
SecRule IP:BANNED "@eq 1" \
|
||||||
"id:100000,phase:1,deny,status:403,log,\
|
"id:100000,phase:1,deny,status:403,log,\
|
||||||
msg:'IP is banned'"
|
msg:'IP is banned'"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
// ✅ loginUser et registerUser retournent AuthResponse
|
// ✅ loginUser et registerUser retournent AuthResponse
|
||||||
// ✅ sessionStorage (pas localStorage)
|
// ✅ sessionStorage (pas localStorage)
|
||||||
|
|
||||||
const API_URL = "http://localhost:8080/api/v1";
|
const API_URL = "/api/v1";
|
||||||
import type {
|
import type {
|
||||||
ConfirmReceptionResponse,
|
ConfirmReceptionResponse,
|
||||||
CheckoutCartResponse,
|
CheckoutCartResponse,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import type {
|
|||||||
DeliveryPersonDetails,
|
DeliveryPersonDetails,
|
||||||
DeliveryPersonStats,
|
DeliveryPersonStats,
|
||||||
} from "./api_admin_types";
|
} from "./api_admin_types";
|
||||||
const API_URL = "http://localhost:8080/api/v2";
|
const API_URL = "/api/v2";
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// 🔐 TYPES - ADMIN
|
// 🔐 TYPES - ADMIN
|
||||||
@@ -825,59 +825,6 @@ export const getCommandByID = async (commandId: number) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* ✅ Récupérer les items d'une commande
|
|
||||||
*/
|
|
||||||
export const getCommandItems = async (commandId: number) => {
|
|
||||||
const token = sessionStorage.getItem("admin_token");
|
|
||||||
|
|
||||||
if (!token) {
|
|
||||||
throw new Error("Token admin non trouvé");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
console.log("🔍 [GET_COMMAND_ITEMS] Appel:", commandId);
|
|
||||||
|
|
||||||
// Utiliser l'endpoint cabine qui est accessible avec le token admin
|
|
||||||
const response = await fetch(
|
|
||||||
`http://localhost:8080/api/v1/cabine/commands/${commandId}/items`,
|
|
||||||
{
|
|
||||||
method: "GET",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
console.error("❌ [GET_COMMAND_ITEMS] Erreur API:", data);
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
items: [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("✅ [GET_COMMAND_ITEMS] Réponse:", data);
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
items: data.items || [],
|
|
||||||
count: data.count || 0,
|
|
||||||
command_info: data.command_info,
|
|
||||||
client_info: data.client_info,
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
console.error("❌ [GET_COMMAND_ITEMS] Erreur fetch:", error);
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
items: [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ✅ Mettre à jour le statut d'une commande
|
* ✅ Mettre à jour le statut d'une commande
|
||||||
*/
|
*/
|
||||||
@@ -2653,7 +2600,6 @@ export default {
|
|||||||
// Commands
|
// Commands
|
||||||
getAllCommands,
|
getAllCommands,
|
||||||
getCommandByID,
|
getCommandByID,
|
||||||
getCommandItems,
|
|
||||||
getCommandCount,
|
getCommandCount,
|
||||||
getCommandCountCompleted,
|
getCommandCountCompleted,
|
||||||
getCommandCountInRoute,
|
getCommandCountInRoute,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
// ✅ Utilise /api/v1/cabine/* endpoints uniquement
|
// ✅ Utilise /api/v1/cabine/* endpoints uniquement
|
||||||
// ✅ sessionStorage pour la persistance
|
// ✅ sessionStorage pour la persistance
|
||||||
|
|
||||||
const API_URL = "http://localhost:8080/api/v1/cabine";
|
const API_URL = "/api/v1/cabine";
|
||||||
import type {
|
import type {
|
||||||
DeliveryPerson,
|
DeliveryPerson,
|
||||||
DeliveryPersonsStats,
|
DeliveryPersonsStats,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// ✅ Fonctions helper pour le dashboard livreur
|
// ✅ Fonctions helper pour le dashboard livreur
|
||||||
// ✅ Utilise /api/v1/livreur/* endpoints
|
// ✅ Utilise /api/v1/livreur/* endpoints
|
||||||
|
|
||||||
const API_URL = "http://localhost:8080/api/v1/livreur";
|
const API_URL = "/api/v1/livreur";
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// 🔐 TYPES - LIVREUR
|
// 🔐 TYPES - LIVREUR
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import "./AdminAlerts.css";
|
|||||||
import Sidebar from "../../components/Sidebar";
|
import Sidebar from "../../components/Sidebar";
|
||||||
import { isAdminAuthenticated, deleteAlertAdmin } from "../../api/api_admin";
|
import { isAdminAuthenticated, deleteAlertAdmin } from "../../api/api_admin";
|
||||||
import { getAllAlerts, getAlertDetails } from "../../api/api_cabine";
|
import { getAllAlerts, getAlertDetails } from "../../api/api_cabine";
|
||||||
|
import Toast from "../../components/Toast";
|
||||||
|
|
||||||
interface Alert {
|
interface Alert {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -32,6 +33,12 @@ interface AlertStats {
|
|||||||
resolved: number;
|
resolved: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ToastState {
|
||||||
|
show: boolean;
|
||||||
|
message: string;
|
||||||
|
type: "success" | "error" | "warning" | "info";
|
||||||
|
}
|
||||||
|
|
||||||
function AdminAlerts() {
|
function AdminAlerts() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
@@ -54,6 +61,26 @@ function AdminAlerts() {
|
|||||||
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
||||||
const [alertToDelete, setAlertToDelete] = useState<number | null>(null);
|
const [alertToDelete, setAlertToDelete] = useState<number | null>(null);
|
||||||
|
|
||||||
|
// État pour le Toast
|
||||||
|
const [toast, setToast] = useState<ToastState>({
|
||||||
|
show: false,
|
||||||
|
message: "",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fonction pour afficher un toast
|
||||||
|
const showToast = (
|
||||||
|
message: string,
|
||||||
|
type: "success" | "error" | "warning" | "info" = "success",
|
||||||
|
) => {
|
||||||
|
setToast({ show: true, message, type });
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fonction pour fermer le toast
|
||||||
|
const handleCloseToast = () => {
|
||||||
|
setToast({ ...toast, show: false });
|
||||||
|
};
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// 🔐 VÉRIFICATION AUTHENTIFICATION
|
// 🔐 VÉRIFICATION AUTHENTIFICATION
|
||||||
// ============================================
|
// ============================================
|
||||||
@@ -249,11 +276,14 @@ function AdminAlerts() {
|
|||||||
setSelectedAlert(result.alert as Alert);
|
setSelectedAlert(result.alert as Alert);
|
||||||
setShowDetailsModal(true);
|
setShowDetailsModal(true);
|
||||||
} else {
|
} else {
|
||||||
alert("Impossible de récupérer les détails");
|
showToast(
|
||||||
|
"Impossible de récupérer les détails de l'alerte",
|
||||||
|
"error",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("❌ Erreur récupération détails:", error);
|
console.error("❌ Erreur récupération détails:", error);
|
||||||
alert("Erreur lors de la récupération des détails");
|
showToast("Erreur lors de la récupération des détails", "error");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -281,15 +311,21 @@ function AdminAlerts() {
|
|||||||
setShowDeleteConfirm(false);
|
setShowDeleteConfirm(false);
|
||||||
setAlertToDelete(null);
|
setAlertToDelete(null);
|
||||||
|
|
||||||
// Message de succès
|
// Afficher le toast de succès
|
||||||
alert("Alerte supprimée avec succès");
|
showToast(
|
||||||
|
`Alerte #${alertToDelete} supprimée avec succès`,
|
||||||
|
"success",
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
console.error("❌ [DELETE_ALERT] Erreur:", result.error);
|
console.error("❌ [DELETE_ALERT] Erreur:", result.error);
|
||||||
alert(result.error || "Erreur lors de la suppression");
|
showToast(
|
||||||
|
result.error || "Erreur lors de la suppression",
|
||||||
|
"error",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("❌ [DELETE_ALERT] Erreur:", error);
|
console.error("❌ [DELETE_ALERT] Erreur:", error);
|
||||||
alert("Erreur lors de la suppression de l'alerte");
|
showToast("Erreur lors de la suppression de l'alerte", "error");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -673,6 +709,16 @@ function AdminAlerts() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Toast Notifications */}
|
||||||
|
{toast.show && (
|
||||||
|
<Toast
|
||||||
|
message={toast.message}
|
||||||
|
type={toast.type}
|
||||||
|
duration={3000}
|
||||||
|
onClose={handleCloseToast}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -20,11 +20,10 @@ import AdminLayout from "../../components/AdminLayout";
|
|||||||
import "./AdminOrders.css";
|
import "./AdminOrders.css";
|
||||||
import {
|
import {
|
||||||
getAllCommands,
|
getAllCommands,
|
||||||
getCommandItems,
|
|
||||||
getDeliverymanLocationForCommand,
|
getDeliverymanLocationForCommand,
|
||||||
isAdminAuthenticated,
|
isAdminAuthenticated,
|
||||||
} from "../../api/api_admin";
|
} from "../../api/api_admin";
|
||||||
|
import { getCommandItems } from "../../api/api_cabine";
|
||||||
import type { DeliverymanLocationResponse } from "../../api/api_admin_types";
|
import type { DeliverymanLocationResponse } from "../../api/api_admin_types";
|
||||||
|
|
||||||
// Interface correspondant au backend
|
// Interface correspondant au backend
|
||||||
|
|||||||
@@ -24,13 +24,13 @@ import SidebarCabine from "../../components/SidebarCabine";
|
|||||||
import "./CabineOrders.css";
|
import "./CabineOrders.css";
|
||||||
import {
|
import {
|
||||||
getAllCommands,
|
getAllCommands,
|
||||||
getCommandItems,
|
|
||||||
getDeliverymanLocationForCommand,
|
getDeliverymanLocationForCommand,
|
||||||
} from "../../api/api_admin";
|
} from "../../api/api_admin";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
deleteCommand,
|
deleteCommand,
|
||||||
isCabineAuthenticated, // ⭐ AJOUT
|
isCabineAuthenticated,
|
||||||
|
getCommandItems,
|
||||||
} from "../../api/api_cabine";
|
} from "../../api/api_cabine";
|
||||||
|
|
||||||
import type { DeliverymanLocationResponse } from "../../api/api_admin_types";
|
import type { DeliverymanLocationResponse } from "../../api/api_admin_types";
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,239 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# SCRIPT DE SIMULATION RÉALISTE - E-COMMERCE
|
||||||
|
# Version avec validation GPS + Simulation déplacement livreur
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
BASE_URL="https://d437671454fb1f66-90-50-148-138.serveousercontent.com"
|
||||||
|
ADMIN_TOKEN=""
|
||||||
|
CABINE_TOKEN=""
|
||||||
|
LIVREUR_TOKEN=""
|
||||||
|
NUM_PRODUCTS=13
|
||||||
|
|
||||||
|
# Couleurs pour l'affichage
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
MAGENTA='\033[0;35m'
|
||||||
|
CYAN='\033[0;36m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
declare -A PRODUCT_DETAILS
|
||||||
|
declare -a PRODUCT_IDS
|
||||||
|
|
||||||
|
# Compteurs de tests
|
||||||
|
TOTAL_TESTS=0
|
||||||
|
PASSED_TESTS=0
|
||||||
|
FAILED_TESTS=0
|
||||||
|
|
||||||
|
# Fonctions d'affichage
|
||||||
|
print_section() {
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}================================================${NC}"
|
||||||
|
echo -e "${BLUE}$1${NC}"
|
||||||
|
echo -e "${BLUE}================================================${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_test() {
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}▶ $1${NC}"
|
||||||
|
((TOTAL_TESTS++))
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success() {
|
||||||
|
echo -e "${GREEN}✓ $1${NC}"
|
||||||
|
((PASSED_TESTS++))
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
echo -e "${RED}✗ $1${NC}"
|
||||||
|
((FAILED_TESTS++))
|
||||||
|
}
|
||||||
|
|
||||||
|
print_info() {
|
||||||
|
echo -e "${MAGENTA}ℹ $1${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_warning() {
|
||||||
|
echo -e "${YELLOW}⚠ $1${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour extraire le token
|
||||||
|
extract_token() {
|
||||||
|
local response="$1"
|
||||||
|
local token=$(echo "$response" | jq -r '.token // .access_token // empty' 2>/dev/null)
|
||||||
|
echo "$token"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour extraire un ID
|
||||||
|
extract_id() {
|
||||||
|
local response="$1"
|
||||||
|
local field="${2:-id}"
|
||||||
|
local id=$(echo "$response" | jq -r ".${field} // .product.id // .product_id // empty" 2>/dev/null)
|
||||||
|
echo "$id"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour vérifier les erreurs
|
||||||
|
check_error() {
|
||||||
|
local response="$1"
|
||||||
|
if echo "$response" | jq -e '.error' >/dev/null 2>&1; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour vérifier le succès
|
||||||
|
check_success() {
|
||||||
|
local response="$1"
|
||||||
|
if echo "$response" | jq -e '.id // .token // .success // .command_id' >/dev/null 2>&1; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 0. VÉRIFICATION PRÉALABLE
|
||||||
|
# ============================================
|
||||||
|
print_section "0. VÉRIFICATION PRÉALABLE"
|
||||||
|
|
||||||
|
print_test "Vérification du serveur"
|
||||||
|
HEALTH_CHECK=$(curl -s -X GET "$BASE_URL/api/v1/health")
|
||||||
|
if [ -n "$HEALTH_CHECK" ]; then
|
||||||
|
print_success "Serveur accessible"
|
||||||
|
else
|
||||||
|
print_error "Serveur non accessible"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 1. AUTHENTIFICATION ADMIN
|
||||||
|
# ============================================
|
||||||
|
print_section "0. AUTHENTIFICATION CLIENT"
|
||||||
|
|
||||||
|
CLIENT_TOKEN=$(extract_token "$CLIENT_LOGIN")
|
||||||
|
|
||||||
|
print_test "Création client"
|
||||||
|
CLIENT_REGISTER=$(curl -s -X POST "$BASE_URL/api/v1/auth/register" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"username\":\"salut\",\"password\":\"salut1234_\",\"role\":\"client\",\"nom\": \"Dupont\",\"prenom\": \"Jean\",\"telephone\": \"+33612345678\"}")
|
||||||
|
CLIENT_TOKEN=$(extract_token "$CLIENT_REGISTER")
|
||||||
|
if [ -n "$CLIENT_TOKEN" ]; then
|
||||||
|
print_success "Client créé et authentifié"
|
||||||
|
else
|
||||||
|
print_error "Échec authentification client"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 1. AUTHENTIFICATION ADMIN
|
||||||
|
# ============================================
|
||||||
|
print_section "1. AUTHENTIFICATION ADMIN"
|
||||||
|
|
||||||
|
ADMIN_TOKEN=$(extract_token "$ADMIN_LOGIN")
|
||||||
|
|
||||||
|
print_test "Création admin"
|
||||||
|
UNIQUE_ADMIN="admin_$(date +%s)"
|
||||||
|
ADMIN_REGISTER=$(curl -s -X POST "$BASE_URL/api/v2/admin/auth/register" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"username\":\"$UNIQUE_ADMIN\",\"password\":\"AdminPass123!\",\"role\":\"admin\"}")
|
||||||
|
ADMIN_TOKEN=$(extract_token "$ADMIN_REGISTER")
|
||||||
|
if [ -n "$ADMIN_TOKEN" ]; then
|
||||||
|
print_success "Admin créé et authentifié"
|
||||||
|
else
|
||||||
|
print_error "Échec authentification admin"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_test "Création livreur"
|
||||||
|
UNIQUE_LIVREUR="livreur_$(date +%s)"
|
||||||
|
ADMIN_REGISTER=$(curl -s -X POST "$BASE_URL/api/v2/admin/auth/register" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"username\":\"$UNIQUE_LIVREUR\",\"password\":\"AdminPass123!\",\"role\":\"livreur\"}")
|
||||||
|
LIVREUR_TOKEN=$(extract_token "$ADMIN_REGISTER")
|
||||||
|
if [ -n "$LIVREUR_TOKEN" ]; then
|
||||||
|
print_success "Admin créé et authentifié"
|
||||||
|
else
|
||||||
|
print_error "Échec authentification admin"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_test "Création cabine"
|
||||||
|
UNIQUE_CABINE="cabine_$(date +%s)"
|
||||||
|
ADMIN_REGISTER=$(curl -s -X POST "$BASE_URL/api/v2/admin/auth/register" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"username\":\"$UNIQUE_CABINE\",\"password\":\"AdminPass123!\",\"role\":\"cabine\"}")
|
||||||
|
CABINE_TOKEN=$(extract_token "$ADMIN_REGISTER")
|
||||||
|
if [ -n "$CABINE_TOKEN" ]; then
|
||||||
|
print_success "Admin créé et authentifié"
|
||||||
|
else
|
||||||
|
print_error "Échec authentification admin"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 2. CRÉATION MASSIVE DE PRODUITS
|
||||||
|
# ============================================
|
||||||
|
print_section "2. CRÉATION MASSIVE DE PRODUITS"
|
||||||
|
|
||||||
|
print_info "Création de $NUM_PRODUCTS produits..."
|
||||||
|
|
||||||
|
PREDEFINED_PRODUCTS=(
|
||||||
|
'{"name":"Zipette Borealis 1", "category":"zipette&co", "description":"Plante luminescente aux teintes bleutées inspirée des aurores boréales", "price":24.99, "stock":35.00}'
|
||||||
|
'{"name":"Zipette Titan 1", "category":"zipette&co", "description":"Plante géante fictive atteignant jusqu'\''à 2 mètres en intérieur", "price":19.99, "stock":50.00}'
|
||||||
|
'{"name":"Zipette Borealis 2", "category":"zipette&co", "description":"Plante luminescente aux teintes bleutées inspirée des aurores boréales", "price":24.99, "stock":35.00}'
|
||||||
|
'{"name":"Zipette Titan 2", "category":"zipette&co", "description":"Plante géante fictive atteignant jusqu'\''à 2 mètres en intérieur", "price":19.99, "stock":50.00}'
|
||||||
|
'{"name":"Zipette Borealis 3", "category":"zipette&co", "description":"Plante luminescente aux teintes bleutées inspirée des aurores boréales", "price":24.99, "stock":35.00}'
|
||||||
|
'{"name":"Zipette Titan 3", "category":"zipette&co", "description":"Plante géante fictive atteignant jusqu'\''à 2 mètres en intérieur", "price":19.99, "stock":50.00}'
|
||||||
|
'{"name":"Titan 4", "category":"gros&semi", "description":"Plante géante fictive atteignant jusqu'\''à 2 mètres en intérieur", "price":19.99, "stock":50.00}'
|
||||||
|
'{"name":"Borealis 4", "category":"gros&semi", "description":"Plante luminescente aux teintes bleutées inspirée des aurores boréales", "price":24.99, "stock":35.00}'
|
||||||
|
'{"name":"Titan 5", "category":"gros&semi", "description":"Plante géante fictive atteignant jusqu'\''à 2 mètres en intérieur", "price":19.99, "stock":50.00}'
|
||||||
|
'{"name":"Kush 1", "category":"weed&hash", "description":"Variété fictive aux arômes terreux et notes citronnées, culture indoor facile", "price":14.99, "stock":80.00}'
|
||||||
|
'{"name":"Haze 1", "category":"weed&hash", "description":"Plante fictive à dominance sativa, réputée pour son parfum épicé", "price":16.99, "stock":60.00}'
|
||||||
|
'{"name":"Hash Gold 1", "category":"weed&hash", "description":"Résine fictive premium à la texture souple et aux notes florales", "price":9.99, "stock":120.00}'
|
||||||
|
'{"name":"Hash Black 1", "category":"weed&hash", "description":"Résine fictive sombre, goût intense et épicé", "price":11.99, "stock":90.00}'
|
||||||
|
'{"name":"Kush 2", "category":"weed&hash", "description":"Variété fictive compacte, floraison rapide et parfum boisé", "price":14.99, "stock":75.00}'
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
for ((i=0; i<NUM_PRODUCTS && i<${#PREDEFINED_PRODUCTS[@]}; i++)); do
|
||||||
|
PRODUCT_JSON=${PREDEFINED_PRODUCTS[$i]}
|
||||||
|
PRODUCT_NAME=$(echo "$PRODUCT_JSON" | jq -r '.name')
|
||||||
|
PRODUCT_CATEGORY=$(echo "$PRODUCT_JSON" | jq -r '.category')
|
||||||
|
PRODUCT_DESC=$(echo "$PRODUCT_JSON" | jq -r '.description')
|
||||||
|
PRODUCT_PRICE=$(echo "$PRODUCT_JSON" | jq -r '.price')
|
||||||
|
PRODUCT_STOCK=$(echo "$PRODUCT_JSON" | jq -r '.stock')
|
||||||
|
|
||||||
|
print_test "Création produit $((i+1))/$NUM_PRODUCTS: $PRODUCT_NAME"
|
||||||
|
|
||||||
|
PRODUCT_RESPONSE=$(curl -s -X POST "$BASE_URL/api/v2/admin/protected/products" \
|
||||||
|
-H "Authorization: Bearer $ADMIN_TOKEN" \
|
||||||
|
-F "name=$PRODUCT_NAME" \
|
||||||
|
-F "category=$PRODUCT_CATEGORY" \
|
||||||
|
-F "description=$PRODUCT_DESC" \
|
||||||
|
-F "stock=$PRODUCT_STOCK" \
|
||||||
|
-F "prices[0][quantity]=1" \
|
||||||
|
-F "prices[0][price]=$PRODUCT_PRICE" \
|
||||||
|
-F "prices[1][quantity]=3" \
|
||||||
|
-F "prices[1][price]=$(echo "scale=2; $PRODUCT_PRICE * 3 * 0.9" | bc)" \
|
||||||
|
-F "prices[2][quantity]=5" \
|
||||||
|
-F "prices[2][price]=$(echo "scale=2; $PRODUCT_PRICE * 5 * 0.85" | bc)")
|
||||||
|
|
||||||
|
PRODUCT_ID=$(extract_id "$PRODUCT_RESPONSE")
|
||||||
|
if [ -n "$PRODUCT_ID" ]; then
|
||||||
|
PRODUCT_IDS+=("$PRODUCT_ID")
|
||||||
|
PRODUCT_DETAILS["$PRODUCT_ID"]="$PRODUCT_JSON"
|
||||||
|
print_success "Produit créé (ID: $PRODUCT_ID) - $PRODUCT_NAME - ${PRODUCT_PRICE}€"
|
||||||
|
else
|
||||||
|
print_warning "Échec création produit $PRODUCT_NAME"
|
||||||
|
echo "Response: $PRODUCT_RESPONSE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 0.5
|
||||||
|
done
|
||||||
|
|
||||||
|
print_info "Total produits créés: ${#PRODUCT_IDS[@]}"
|
||||||
Reference in New Issue
Block a user