chore: update

This commit is contained in:
2026-06-12 17:51:17 +02:00
parent d18052e749
commit ce45314c78
7 changed files with 356 additions and 33 deletions
+117
View File
@@ -9,6 +9,7 @@ import (
"net/http"
"slices"
"strconv"
"time"
"github.com/gin-gonic/gin"
)
@@ -497,3 +498,119 @@ func ReportDeliveryIssue(c *gin.Context) {
log.Printf("📋 [ISSUE] Créé par %s pour commande #%d: %s", username, commandID, req.IssueType)
c.JSON(http.StatusCreated, gin.H{"success": true, "issue": issue})
}
// GET /api/v1/livreur/stats
func GetMyDeliveryStats(c *gin.Context) {
database := c.MustGet("database").(*db.Database)
username, exists := c.Get("username")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
return
}
if c.GetString("role") != "livreur" {
c.JSON(http.StatusForbidden, gin.H{"error": "Accès réservé aux livreurs"})
return
}
usernameStr := username.(string)
gdb := database.GDB
type DayRow struct {
Day time.Time `gorm:"column:day"`
Count int `gorm:"column:count"`
Revenue float64 `gorm:"column:revenue"`
}
type WeekRow struct {
WeekNum int `gorm:"column:week_num"`
Year int `gorm:"column:year"`
Count int `gorm:"column:count"`
Revenue float64 `gorm:"column:revenue"`
}
type MonthRow struct {
MonthNum int `gorm:"column:month_num"`
Year int `gorm:"column:year"`
Count int `gorm:"column:count"`
Revenue float64 `gorm:"column:revenue"`
}
var dayRows []DayRow
gdb.Raw(`
SELECT DATE(updated_at) AS day,
COUNT(*) AS count,
COALESCE(SUM(total_prix), 0) AS revenue
FROM commandes
WHERE livreur_assign = ?
AND status IN ('livre', 'approved')
AND updated_at >= NOW() - INTERVAL '30 days'
GROUP BY DATE(updated_at)
ORDER BY day
`, usernameStr).Scan(&dayRows)
var weekRows []WeekRow
gdb.Raw(`
SELECT EXTRACT(WEEK FROM updated_at)::int AS week_num,
EXTRACT(YEAR FROM updated_at)::int AS year,
COUNT(*) AS count,
COALESCE(SUM(total_prix), 0) AS revenue
FROM commandes
WHERE livreur_assign = ?
AND status IN ('livre', 'approved')
AND updated_at >= NOW() - INTERVAL '12 weeks'
GROUP BY week_num, year
ORDER BY year, week_num
`, usernameStr).Scan(&weekRows)
var monthRows []MonthRow
gdb.Raw(`
SELECT EXTRACT(MONTH FROM updated_at)::int AS month_num,
EXTRACT(YEAR FROM updated_at)::int AS year,
COUNT(*) AS count,
COALESCE(SUM(total_prix), 0) AS revenue
FROM commandes
WHERE livreur_assign = ?
AND status IN ('livre', 'approved')
AND updated_at >= NOW() - INTERVAL '12 months'
GROUP BY month_num, year
ORDER BY year, month_num
`, usernameStr).Scan(&monthRows)
monthNames := [13]string{"", "Jan", "Fév", "Mar", "Avr", "Mai", "Jun", "Jul", "Aoû", "Sep", "Oct", "Nov", "Déc"}
byDay := make([]gin.H, len(dayRows))
for i, r := range dayRows {
byDay[i] = gin.H{
"label": r.Day.Format("02/01"),
"count": r.Count,
"revenue": r.Revenue,
}
}
byWeek := make([]gin.H, len(weekRows))
for i, r := range weekRows {
byWeek[i] = gin.H{
"label": fmt.Sprintf("S%d", r.WeekNum),
"count": r.Count,
"revenue": r.Revenue,
}
}
byMonth := make([]gin.H, len(monthRows))
for i, r := range monthRows {
label := "?"
if r.MonthNum >= 1 && r.MonthNum <= 12 {
label = monthNames[r.MonthNum]
}
byMonth[i] = gin.H{
"label": label,
"count": r.Count,
"revenue": r.Revenue,
}
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"by_day": byDay,
"by_week": byWeek,
"by_month": byMonth,
})
}
+1
View File
@@ -379,6 +379,7 @@ func SetupRoutes(router *gin.Engine, database *db.Database, geoService *services
// QUEUE PERSONNELLE
// ============================================
livreurGroupV1.GET("/queue", handlers.GetMyQueue)
livreurGroupV1.GET("/stats", handlers.GetMyDeliveryStats)
// ============================================
// ALERTES POLICE
+2
View File
@@ -19,6 +19,8 @@ TELEGRAM_WEBHOOK_URL=https://uber-demo.club/webhook/telegram
BACKEND_LINK_SECRET=QxAEEGUGRMtWbNvC2REo27haN78Rl5c5EQ
LBTELEGRAM_URL=http://lbtelegram:8081
LBTELEGRAM_BOT1_USERNAME=GetRezStealer_bot
LBTELEGRAM_BOT2_USERNAME=rezDJDFJSFUltraFast_bot
BACKEND_LINK_SECRET=change_me_internal_secret
API_PORT=8080
FRONTEND_PORT=5173
GIN_MODE=release
+17 -1
View File
@@ -126,7 +126,23 @@ server {
}
# ---------------------------------------------------
# Webhooks Telegram (LBTelegram — /webhook/bot1, /webhook/bot2…)
# Webhook Telegram principal → backend Go
# ---------------------------------------------------
location = /webhook/telegram {
limit_except POST { deny all; }
set $upstream_backend http://backend:8080;
proxy_pass $upstream_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# ---------------------------------------------------
# Webhooks LBTelegram (/webhook/bot1, /webhook/bot2…)
# ---------------------------------------------------
location /webhook/ {
limit_except POST { deny all; }
+212
View File
@@ -0,0 +1,212 @@
services:
# =========================================================
# Backend Go
# =========================================================
backend:
image: xor1234/backend-mln:pre-prod
container_name: gestion-backend
restart: unless-stopped
environment:
- DB_HOST=${DB_HOST:-postgres}
- DB_PORT=${DB_PORT:-5432}
- DB_USER=${DB_USER:-postgres}
- DB_PASSWORD=${DB_PASSWORD}
- DB_NAME=${DB_NAME:-gestion_db}
- DB_SSLMODE=${DB_SSLMODE:-disable}
- SESSION_SECRET=${SESSION_SECRET}
- USER_JWT_SECRET=${USER_JWT_SECRET}
- USER_JWT_SECRET_OLD=${USER_JWT_SECRET_OLD}
- ADMIN_JWT_SECRET=${ADMIN_JWT_SECRET}
- ADMIN_JWT_SECRET_OLD=${ADMIN_JWT_SECRET_OLD}
- REDIS_HOST=${REDIS_HOST:-redis}
- REDIS_PORT=${REDIS_PORT:-6379}
- REDIS_PASSWORD=${REDIS_PASSWORD}
- TOMTOM_API_KEY=${TOMTOM_API_KEY}
- TOMTOM_API_KEY_1=${TOMTOM_API_KEY_1}
- TOMTOM_API_KEY_2=${TOMTOM_API_KEY_2}
- TOMTOM_API_KEY_3=${TOMTOM_API_KEY_3}
- API_PORT=${API_PORT:-8080}
- NOWPAYMENTS_IPN_SECRET=${NOWPAYMENTS_IPN_SECRET}
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
- TELEGRAM_BOT_USERNAME=${TELEGRAM_BOT_USERNAME}
- TELEGRAM_WEBHOOK_SECRET=${TELEGRAM_WEBHOOK_SECRET}
- TELEGRAM_WEBHOOK_URL=${TELEGRAM_WEBHOOK_URL}
- LBTELEGRAM_URL=http://lbtelegram:8081
- LBTELEGRAM_BOT1_USERNAME=${LBTELEGRAM_BOT1_USERNAME:-GetRezStealer_bot}
- LBTELEGRAM_BOT2_USERNAME=${LBTELEGRAM_BOT2_USERNAME:-rezDJDFJSFUltraFast_bot}
- BACKEND_LINK_SECRET=${BACKEND_LINK_SECRET:-change_me_internal_secret}
volumes:
- backend_uploads:/app/uploads
networks:
- gestion-network
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
# =========================================================
# Frontend Web (React/Vite — servi en HTTP interne)
# =========================================================
frontend:
image: xor1234/frontend-mln:pre-prod
container_name: gestion-frontend
restart: unless-stopped
networks:
- gestion-network
depends_on:
- backend
waf:
image: xor1234/backend-mln:waf-pre-prod
container_name: gestion-waf
restart: unless-stopped
environment:
- DISABLE_MODSEC_ENV_SUBST=true
- PARANOIA=2
- ANOMALY_INBOUND=5
- ANOMALY_OUTBOUND=4
- MODSEC_AUDIT_LOG=/var/log/modsec/modsec_audit.log
ports:
- "80:80"
- "443:443"
volumes:
- backend_uploads:/usr/share/nginx/html/uploads:ro
- ./certs:/etc/nginx/certs:ro
- ./backend/nginx.conf:/etc/nginx/conf.d/app.conf:ro
- ./backend/custom-rules.conf:/etc/nginx/modsec/custom-rules.conf:ro
- /var/log/waf/nginx:/var/log/nginx
- /var/log/waf/modsec:/var/log/modsec
networks:
- gestion-network
depends_on:
- backend
- frontend
# =========================================================
# PostgreSQL
# =========================================================
postgres:
image: postgres:16-alpine
container_name: gestion-postgres
restart: unless-stopped
environment:
- POSTGRES_USER=${DB_USER:-postgres}
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=${DB_NAME:-gestion_db}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- gestion-network
healthcheck:
test:
[
"CMD-SHELL",
"pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-gestion_db}",
]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
# =========================================================
# Redis
# =========================================================
redis:
image: redis:7-alpine
container_name: gestion-redis
restart: unless-stopped
command: >
redis-server
--requirepass ${REDIS_PASSWORD}
--appendonly yes
--appendfsync everysec
--maxmemory 256mb
--maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
networks:
- gestion-network
healthcheck:
test:
[
"CMD",
"redis-cli",
"--no-auth-warning",
"-a",
"${REDIS_PASSWORD}",
"ping",
]
interval: 10s
timeout: 3s
retries: 5
start_period: 10s
# =========================================================
# LBTelegram — Gateway Telegram load balancer
# =========================================================
lbtelegram:
image: xor1234/load-balancer-tlg:latest
container_name: gestion-lbtelegram
restart: unless-stopped
env_file: ./.env.lbtelegram
environment:
- REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0
- DATABASE_URL=postgres://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}?sslmode=disable
networks:
- gestion-network
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
backend:
condition: service_started
clamav:
deploy:
resources:
limits:
memory: 1g
cpus: 0.5
image: clamav/clamav:latest
container_name: gestion-clamav
restart: unless-stopped
volumes:
- backend_uploads:/app/uploads:ro
- clamav_data:/var/lib/clamav
networks:
- gestion-network
healthcheck:
test: ["CMD", "clamdcheck.sh"]
interval: 60s
timeout: 10s
retries: 3
start_period: 120s
dozzle-agent:
image: amir20/dozzle:latest
command: agent
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "7007:7007"
restart: unless-stopped
networks:
gestion-network:
driver: bridge
internal: false
driver_opts:
com.docker.network.bridge.name: gestion-br0
volumes:
postgres_data:
driver: local
redis_data:
driver: local
backend_uploads:
driver: local
clamav_data:
driver: local
+7 -2
View File
@@ -27,8 +27,13 @@ services:
- TOMTOM_API_KEY_3=${TOMTOM_API_KEY_3}
- API_PORT=${API_PORT:-8080}
- NOWPAYMENTS_IPN_SECRET=${NOWPAYMENTS_IPN_SECRET}
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
- TELEGRAM_BOT_USERNAME=${TELEGRAM_BOT_USERNAME}
- TELEGRAM_WEBHOOK_SECRET=${TELEGRAM_WEBHOOK_SECRET}
- TELEGRAM_WEBHOOK_URL=${TELEGRAM_WEBHOOK_URL}
- LBTELEGRAM_URL=http://lbtelegram:8081
- LBTELEGRAM_BOT1_USERNAME=${LBTELEGRAM_BOT1_USERNAME:-rezsssnfdsjfdsfbot}
- LBTELEGRAM_BOT1_USERNAME=${LBTELEGRAM_BOT1_USERNAME:-GetRezStealer_bot}
- LBTELEGRAM_BOT2_USERNAME=${LBTELEGRAM_BOT2_USERNAME:-rezDJDFJSFUltraFast_bot}
- BACKEND_LINK_SECRET=${BACKEND_LINK_SECRET:-change_me_internal_secret}
volumes:
- backend_uploads:/app/uploads
@@ -145,7 +150,7 @@ services:
image: xor1234/load-balancer-tlg:latest
container_name: gestion-lbtelegram
restart: unless-stopped
env_file: ./lbtelegram.env
env_file: ./.env.lbtelegram
environment:
- REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0
- DATABASE_URL=postgres://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}?sslmode=disable
-30
View File
@@ -1,30 +0,0 @@
# Gateway
PORT=8081
ENV=production
BOT_COUNT=2
# Bots Telegram
BOT1_TOKEN=change_me_bot1_token
BOT1_USERNAME=change_me_bot1_username
BOT1_WEBHOOK_SECRET=change_me_bot1_webhook_secret
BOT2_TOKEN=change_me_bot2_token
BOT2_USERNAME=change_me_bot2_username
BOT2_WEBHOOK_SECRET=change_me_bot2_webhook_secret
# URL publique de la gateway (pour setWebhook Telegram)
GATEWAY_URL=https://uber-demo.club
# JWT
JWT_SECRET=change_me_jwt_secret
JWT_TTL_SECONDS=300
# Load balancer: roundrobin | leastconn | failover
LB_STRATEGY=failover
# Health check interval en secondes
HEALTH_CHECK_INTERVAL=30
# URL interne du backend pour valider les tokens de liaison
BACKEND_LINK_URL=http://backend:8080/api/internal/telegram/link
BACKEND_LINK_SECRET=change_me_backend_link_secret