chore: update
ci-api / test (push) Successful in 33m26s
ci-web / test (push) Successful in 15m10s

This commit is contained in:
Xor290
2026-08-05 18:20:57 +02:00
parent 373d592320
commit fbda118856
8 changed files with 1636 additions and 1513 deletions
+13 -2
View File
@@ -16,8 +16,9 @@ const (
PoolSizePerService = 5 // slots par service externe poolé PoolSizePerService = 5 // slots par service externe poolé
) )
// Services externes gérés par pool pré-provisionné (non auto-créables par API). // Services externes gérés par pool pré-provisionné (non auto-créables par
// TomTom n'y figure pas : ses clés sont créées à la volée par le worker. // API). TomTom n'y figure pas : ses clés sont saisies directement par
// l'admin au moment du déploiement (voir ProvisionConfig.TomTomAPIKey*).
const ( const (
ServiceTelegram = "telegram" ServiceTelegram = "telegram"
ServiceNowPayments = "nowpayments" ServiceNowPayments = "nowpayments"
@@ -75,6 +76,16 @@ type ProvisionConfig struct {
S3Bucket string S3Bucket string
S3Endpoint string S3Endpoint string
// TomTom (GPS livreur : géocodage, itinéraire, ETA — voir
// services/tomtom_keys.go côté gestion). Jusqu'à 4 clés, utilisées en
// rotation automatique par le backend si l'une atteint son quota
// (403/429) ; seule TomTomAPIKey est requise, les 3 suivantes sont des
// clés de secours optionnelles.
TomTomAPIKey string
TomTomAPIKey1 string
TomTomAPIKey2 string
TomTomAPIKey3 string
// Load-balancer Telegram (chart lbtelegram) : installé seulement si au // Load-balancer Telegram (chart lbtelegram) : installé seulement si au
// moins un bot est renseigné. GATEWAY_URL (URL publique de la démo) et // moins un bot est renseigné. GATEWAY_URL (URL publique de la démo) et
// les DSN/secrets sont générés par le provisioner. Les 3 réglages // les DSN/secrets sont générés par le provisioner. Les 3 réglages
@@ -30,6 +30,13 @@ type createRequest struct {
S3Bucket string `json:"s3_bucket" binding:"omitempty,max=63"` S3Bucket string `json:"s3_bucket" binding:"omitempty,max=63"`
S3Endpoint string `json:"s3_endpoint" binding:"omitempty,max=255"` S3Endpoint string `json:"s3_endpoint" binding:"omitempty,max=255"`
// TomTom : jusqu'à 4 clés (1 principale + 3 de secours, rotation
// automatique côté backend en cas de quota atteint).
TomTomAPIKey string `json:"tomtom_api_key" binding:"omitempty"`
TomTomAPIKey1 string `json:"tomtom_api_key_1" binding:"omitempty"`
TomTomAPIKey2 string `json:"tomtom_api_key_2" binding:"omitempty"`
TomTomAPIKey3 string `json:"tomtom_api_key_3" binding:"omitempty"`
LBBot1Username string `json:"lb_bot1_username" binding:"omitempty,max=64"` LBBot1Username string `json:"lb_bot1_username" binding:"omitempty,max=64"`
LBBot1Token string `json:"lb_bot1_token" binding:"omitempty"` LBBot1Token string `json:"lb_bot1_token" binding:"omitempty"`
LBBot2Username string `json:"lb_bot2_username" binding:"omitempty,max=64"` LBBot2Username string `json:"lb_bot2_username" binding:"omitempty,max=64"`
@@ -74,6 +81,10 @@ func (h *Handler) Create(c *gin.Context) {
StorageDriver: req.StorageDriver, StorageDriver: req.StorageDriver,
S3Bucket: req.S3Bucket, S3Bucket: req.S3Bucket,
S3Endpoint: req.S3Endpoint, S3Endpoint: req.S3Endpoint,
TomTomAPIKey: req.TomTomAPIKey,
TomTomAPIKey1: req.TomTomAPIKey1,
TomTomAPIKey2: req.TomTomAPIKey2,
TomTomAPIKey3: req.TomTomAPIKey3,
LBBot1Username: req.LBBot1Username, LBBot1Username: req.LBBot1Username,
LBBot1Token: req.LBBot1Token, LBBot1Token: req.LBBot1Token,
LBBot2Username: req.LBBot2Username, LBBot2Username: req.LBBot2Username,
@@ -835,6 +835,21 @@ func (h *HelmProvisioner) buildBackendValues(d Demo, resources []ExternalResourc
// marchand NowPayments, pas à une valeur générée par le pool. // marchand NowPayments, pas à une valeur générée par le pool.
secrets["NOWPAYMENTS_IPN_SECRET"] = cfg.NowPaymentsIPNSecret secrets["NOWPAYMENTS_IPN_SECRET"] = cfg.NowPaymentsIPNSecret
} }
// TomTom : seule la première clé est requise, les 3 suivantes sont des
// clés de secours optionnelles (rotation automatique côté backend, voir
// services/tomtom_keys.go côté gestion).
if cfg.TomTomAPIKey != "" {
secrets["TOMTOM_API_KEY"] = cfg.TomTomAPIKey
}
if cfg.TomTomAPIKey1 != "" {
secrets["TOMTOM_API_KEY_1"] = cfg.TomTomAPIKey1
}
if cfg.TomTomAPIKey2 != "" {
secrets["TOMTOM_API_KEY_2"] = cfg.TomTomAPIKey2
}
if cfg.TomTomAPIKey3 != "" {
secrets["TOMTOM_API_KEY_3"] = cfg.TomTomAPIKey3
}
if cfg.LBTelegramEnabled() { if cfg.LBTelegramEnabled() {
env["LBTELEGRAM_URL"] = fmt.Sprintf("http://%s-lbtelegram-lbtelegram.%s.svc.cluster.local:8081", d.Namespace, d.Namespace) env["LBTELEGRAM_URL"] = fmt.Sprintf("http://%s-lbtelegram-lbtelegram.%s.svc.cluster.local:8081", d.Namespace, d.Namespace)
env["LBTELEGRAM_BOT1_USERNAME"] = cfg.LBBot1Username env["LBTELEGRAM_BOT1_USERNAME"] = cfg.LBBot1Username
-1510
View File
File diff suppressed because one or more lines are too long
+1510
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Omnex — Plateforme de gestion de commandes & livraison</title> <title>Omnex — Plateforme de gestion de commandes & livraison</title>
<meta name="description" content="Déployez en un clic une démo complète de la plateforme de gestion de commandes et de livraison." /> <meta name="description" content="Déployez en un clic une démo complète de la plateforme de gestion de commandes et de livraison." />
<script type="module" crossorigin src="/assets/index-B44IZlvi.js"></script> <script type="module" crossorigin src="/assets/index-iTNViNPy.js"></script>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
+78
View File
@@ -44,6 +44,12 @@ export function CreateDemoModal({ isOpen, onClose, onCreated }: CreateDemoModalP
const [nowPaymentsApiKey, setNowPaymentsApiKey] = useState('') const [nowPaymentsApiKey, setNowPaymentsApiKey] = useState('')
const [nowPaymentsIpnSecret, setNowPaymentsIpnSecret] = useState('') const [nowPaymentsIpnSecret, setNowPaymentsIpnSecret] = useState('')
const [enableTomTom, setEnableTomTom] = useState(false)
const [tomtomApiKey, setTomtomApiKey] = useState('')
const [tomtomApiKey1, setTomtomApiKey1] = useState('')
const [tomtomApiKey2, setTomtomApiKey2] = useState('')
const [tomtomApiKey3, setTomtomApiKey3] = useState('')
const [enableLBTelegram, setEnableLBTelegram] = useState(false) const [enableLBTelegram, setEnableLBTelegram] = useState(false)
const [lbBot1Username, setLbBot1Username] = useState('') const [lbBot1Username, setLbBot1Username] = useState('')
const [lbBot1Token, setLbBot1Token] = useState('') const [lbBot1Token, setLbBot1Token] = useState('')
@@ -68,6 +74,11 @@ export function CreateDemoModal({ isOpen, onClose, onCreated }: CreateDemoModalP
setEnableNowPayments(false) setEnableNowPayments(false)
setNowPaymentsApiKey('') setNowPaymentsApiKey('')
setNowPaymentsIpnSecret('') setNowPaymentsIpnSecret('')
setEnableTomTom(false)
setTomtomApiKey('')
setTomtomApiKey1('')
setTomtomApiKey2('')
setTomtomApiKey3('')
setEnableLBTelegram(false) setEnableLBTelegram(false)
setLbBot1Username('') setLbBot1Username('')
setLbBot1Token('') setLbBot1Token('')
@@ -104,6 +115,10 @@ export function CreateDemoModal({ isOpen, onClose, onCreated }: CreateDemoModalP
toast({ status: 'warning', title: 'Au moins un bot (username) requis pour le load-balancer' }) toast({ status: 'warning', title: 'Au moins un bot (username) requis pour le load-balancer' })
return return
} }
if (enableTomTom && !tomtomApiKey.trim()) {
toast({ status: 'warning', title: 'La clé API TomTom principale est requise' })
return
}
const params: CreateDemoParams = { const params: CreateDemoParams = {
username: username.trim(), username: username.trim(),
@@ -117,6 +132,14 @@ export function CreateDemoModal({ isOpen, onClose, onCreated }: CreateDemoModalP
...(storageDriver === 's3' ...(storageDriver === 's3'
? { s3Bucket: s3Bucket.trim(), s3Endpoint: s3Endpoint.trim() } ? { s3Bucket: s3Bucket.trim(), s3Endpoint: s3Endpoint.trim() }
: {}), : {}),
...(enableTomTom
? {
tomtomApiKey: tomtomApiKey.trim(),
tomtomApiKey1: tomtomApiKey1.trim() || undefined,
tomtomApiKey2: tomtomApiKey2.trim() || undefined,
tomtomApiKey3: tomtomApiKey3.trim() || undefined,
}
: {}),
...(enableLBTelegram ...(enableLBTelegram
? { ? {
lbBot1Username: lbBot1Username.trim() || undefined, lbBot1Username: lbBot1Username.trim() || undefined,
@@ -258,6 +281,61 @@ export function CreateDemoModal({ isOpen, onClose, onCreated }: CreateDemoModalP
</Stack> </Stack>
)} )}
{/* --- TomTom (GPS livreur) --- */}
<FormControl isDisabled={submitting}>
<HStack justify="space-between">
<FormLabel mb={0}>TomTom (GPS livreur)</FormLabel>
<Switch
isChecked={enableTomTom}
onChange={(e) => setEnableTomTom(e.target.checked)}
/>
</HStack>
</FormControl>
{enableTomTom && (
<Stack spacing={3} pl={3} borderLeftWidth="2px" borderColor="primary.500">
<Text fontSize="xs" color="gray.500">
Géocodage, itinéraire et ETA des livreurs. Jusqu'à 4 clés le backend bascule
automatiquement sur la suivante si une clé atteint son quota.
</Text>
<FormControl isRequired isDisabled={submitting}>
<FormLabel fontSize="sm">Clé API TomTom (principale)</FormLabel>
<PasswordInput
placeholder="clé API TomTom"
value={tomtomApiKey}
onChange={(e) => setTomtomApiKey(e.target.value)}
autoComplete="off"
/>
</FormControl>
<FormControl isDisabled={submitting}>
<FormLabel fontSize="sm">Clé API TomTom #2 (optionnelle)</FormLabel>
<PasswordInput
placeholder="clé de secours"
value={tomtomApiKey1}
onChange={(e) => setTomtomApiKey1(e.target.value)}
autoComplete="off"
/>
</FormControl>
<FormControl isDisabled={submitting}>
<FormLabel fontSize="sm">Clé API TomTom #3 (optionnelle)</FormLabel>
<PasswordInput
placeholder="clé de secours"
value={tomtomApiKey2}
onChange={(e) => setTomtomApiKey2(e.target.value)}
autoComplete="off"
/>
</FormControl>
<FormControl isDisabled={submitting}>
<FormLabel fontSize="sm">Clé API TomTom #4 (optionnelle)</FormLabel>
<PasswordInput
placeholder="clé de secours"
value={tomtomApiKey3}
onChange={(e) => setTomtomApiKey3(e.target.value)}
autoComplete="off"
/>
</FormControl>
</Stack>
)}
{/* --- Load-balancer Telegram (multi-bots) --- */} {/* --- Load-balancer Telegram (multi-bots) --- */}
<FormControl isDisabled={submitting}> <FormControl isDisabled={submitting}>
<HStack justify="space-between"> <HStack justify="space-between">
+8
View File
@@ -75,6 +75,10 @@ export interface CreateDemoParams {
storageDriver: StorageDriver storageDriver: StorageDriver
s3Bucket?: string s3Bucket?: string
s3Endpoint?: string s3Endpoint?: string
tomtomApiKey?: string
tomtomApiKey1?: string
tomtomApiKey2?: string
tomtomApiKey3?: string
lbBot1Username?: string lbBot1Username?: string
lbBot1Token?: string lbBot1Token?: string
lbBot2Username?: string lbBot2Username?: string
@@ -177,6 +181,10 @@ export const api = {
...(params.storageDriver === 's3' ...(params.storageDriver === 's3'
? { s3_bucket: params.s3Bucket, s3_endpoint: params.s3Endpoint } ? { s3_bucket: params.s3Bucket, s3_endpoint: params.s3Endpoint }
: {}), : {}),
...(params.tomtomApiKey ? { tomtom_api_key: params.tomtomApiKey } : {}),
...(params.tomtomApiKey1 ? { tomtom_api_key_1: params.tomtomApiKey1 } : {}),
...(params.tomtomApiKey2 ? { tomtom_api_key_2: params.tomtomApiKey2 } : {}),
...(params.tomtomApiKey3 ? { tomtom_api_key_3: params.tomtomApiKey3 } : {}),
...(params.lbBot1Username ? { lb_bot1_username: params.lbBot1Username, lb_bot1_token: params.lbBot1Token } : {}), ...(params.lbBot1Username ? { lb_bot1_username: params.lbBot1Username, lb_bot1_token: params.lbBot1Token } : {}),
...(params.lbBot2Username ? { lb_bot2_username: params.lbBot2Username, lb_bot2_token: params.lbBot2Token } : {}), ...(params.lbBot2Username ? { lb_bot2_username: params.lbBot2Username, lb_bot2_token: params.lbBot2Token } : {}),
...(params.lbStrategy ? { lb_strategy: params.lbStrategy } : {}), ...(params.lbStrategy ? { lb_strategy: params.lbStrategy } : {}),