feat: Version 3.3.4 - Nouvelle architecture pages, optimisations widgets Flutter et API

- Mise à jour VERSION vers 3.3.4
- Optimisations et révisions architecture API (deploy-api.sh, scripts de migration)
- Ajout documentation Stripe Tap to Pay complète
- Migration vers polices Inter Variable pour Flutter
- Optimisations build Android et nettoyage fichiers temporaires
- Amélioration système de déploiement avec gestion backups
- Ajout scripts CRON et migrations base de données

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
pierre
2025-10-05 20:11:15 +02:00
parent 242a90720e
commit b6584c83fa
1625 changed files with 145669 additions and 51249 deletions

132
bao/bin/list-entites Executable file
View File

@@ -0,0 +1,132 @@
#!/usr/bin/env php
<?php
declare(strict_types=1);
/**
* Script de listing des entités (amicales) avec données déchiffrées
* Usage: ./list-entites <environment> [--stripe] [--limit=N]
*/
require_once __DIR__ . '/../lib/CryptoService.php';
require_once __DIR__ . '/../lib/DatabaseConnection.php';
require_once __DIR__ . '/../lib/helpers.php';
// Vérifier les arguments
if ($argc < 2) {
error("Usage: " . basename($argv[0]) . " <environment> [--stripe] [--limit=N]");
error("Exemple: " . basename($argv[0]) . " dev --stripe");
exit(1);
}
$environment = strtoupper($argv[1]);
$stripeOnly = false;
$limit = 50;
// Parser les options
for ($i = 2; $i < $argc; $i++) {
if ($argv[$i] === '--stripe') {
$stripeOnly = true;
} elseif (preg_match('/--limit=(\d+)/', $argv[$i], $matches)) {
$limit = (int)$matches[1];
}
}
try {
// Ouvrir le tunnel SSH si nécessaire
$tunnelScript = __DIR__ . '/_ssh-tunnel.sh';
exec("$tunnelScript open $environment 2>&1", $output, $exitCode);
if ($exitCode !== 0) {
error("Impossible d'ouvrir le tunnel SSH");
exit(1);
}
// Connexion à la base de données
$db = new DatabaseConnection($environment);
$pdo = $db->connect();
info("Environnement: $environment");
if ($stripeOnly) {
info("Filtre: Stripe activé uniquement");
}
info("Limite: $limit\n");
// Construction de la requête
$sql = "
SELECT
e.id,
e.encrypted_name,
e.encrypted_email,
e.encrypted_phone,
e.ville,
e.chk_stripe,
e.chk_mdp_manuel,
e.chk_username_manuel,
COUNT(DISTINCT u.id) as nb_users,
COUNT(DISTINCT o.id) as nb_operations
FROM entites e
LEFT JOIN users u ON u.fk_entite = e.id
LEFT JOIN operations o ON o.fk_entite = e.id
WHERE 1=1
";
if ($stripeOnly) {
$sql .= " AND e.chk_stripe = 1";
}
$sql .= " GROUP BY e.id ORDER BY e.id DESC LIMIT :limit";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
$stmt->execute();
$entites = $stmt->fetchAll();
if (empty($entites)) {
warning("Aucune entité trouvée");
exit(0);
}
// Déchiffrer les données
$config = DatabaseConfig::getInstance();
$crypto = new CryptoService($config->getEncryptionKey());
$decryptedEntites = [];
foreach ($entites as $entite) {
$decryptedEntites[] = [
'id' => $entite['id'],
'name' => truncate($crypto->decryptWithIV($entite['encrypted_name']) ?? '-', 30),
'ville' => truncate($entite['ville'] ?? '-', 20),
'email' => truncate($crypto->decryptSearchable($entite['encrypted_email']) ?? '-', 30),
'phone' => $crypto->decryptWithIV($entite['encrypted_phone']) ?? '-',
'users' => $entite['nb_users'],
'ops' => $entite['nb_operations'],
'stripe' => $entite['chk_stripe'] ? '✓' : '✗',
];
}
// Affichage
title("LISTE DES ENTITÉS (AMICALES) - " . count($decryptedEntites) . " résultat(s)");
table(
[
'id' => 'ID',
'name' => 'Nom',
'ville' => 'Ville',
'email' => 'Email',
'phone' => 'Téléphone',
'users' => 'Users',
'ops' => 'Ops',
'stripe' => 'Stripe',
],
$decryptedEntites,
true
);
success("Affichage terminé");
} catch (Exception $e) {
error("Erreur: " . $e->getMessage());
exit(1);
}