Initialisation Multi-IA
This commit is contained in:
1 parent
ee643eb542
commit
0cc8945187
6 files changed
+39
-160
No files matched your search
@@ -1,47 +0,0 @@
|
|||||||
# Roadmap Stratégique : Automatisme d'Attachement (Projet ATT-STIC)
|
|
||||||
|
|
||||||
## Pile Technologique (Stack) & Environnement
|
|
||||||
* **Serveur Hôte (aethas38) :**
|
|
||||||
* **OS :** Debian GNU/Linux 13 (trixie) - Kernel 6.12.107+deb13-amd64
|
|
||||||
* **CPU :** 1 Socket, 1 Thread par cœur
|
|
||||||
* **RAM :** 24 Go (23 GiB Total / 11 GiB Disponible)
|
|
||||||
* **Stockage :** 915 Go Total (801 Go libres / 8% utilisés)
|
|
||||||
* **Environnement :** Docker v29.7.2, Docker Compose v5.5.0, Python 3.13.5
|
|
||||||
* **Orchestration / Déploiement :** Docker géré strictement via Dockge
|
|
||||||
* **Gestion de version (VCS) :** Gitea (Auto-hébergé)
|
|
||||||
* **Environnement de Développement (IDE) :** Visual Studio Code (Extensions: Remote-SSH, Docker, Python, Git Graph, Spreadsheet Viewer)
|
|
||||||
* **Interface Web (UI) :** Conteneur léger (HTML/CSS/JS + Backend Python Flask/FastAPI). Intégration de la charte graphique SERFIM TIC et du logo Aethas38.
|
|
||||||
* **Traitement de Données :** VBA (pour la macro locale) et moteur Python pour l'intégration web.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Phase 0 : Audit Infrastructure et Initialisation de l'Environnement
|
|
||||||
* [x] **Tâche 0.1 :** Exécution du script d'audit sur le serveur Debian pour définir les limites matérielles CPU/RAM.
|
|
||||||
* [x] **Tâche 0.2 :** Configuration de l'environnement VSCode (liste des extensions nécessaires et configuration du workspace).
|
|
||||||
* [x] **Tâche 0.3 :** Initialisation du dépôt sur Gitea et premier commit de cette roadmap.
|
|
||||||
* [x] **Tâche 0.4 :** Création du Dashboard local et extraction des codes couleurs/typographie depuis `https://serfimtic.com` pour les assets graphiques.
|
|
||||||
|
|
||||||
## Phase 1 : Audit et Restructuration des Fichiers Excel (Data Foundation)
|
|
||||||
* [ ] **Tâche 1.1 - Mécanisme de Sauvegarde Préalable :** Création du protocole garantissant que *chaque fichier* est sauvegardé avant modification, indicé sous le format `Semaine_Année_CodeAffaire`.
|
|
||||||
* [ ] **Tâche 1.2 - Analyse du Fichier de Suivi (Commun) :** Normalisation de la structure pour lecture des données sans briser les formules complexes (Code affaire, N° de commande, Montants).
|
|
||||||
* [ ] **Tâche 1.3 - Analyse du Fichier d'Attachement :** Mapping exact entre les données du suivi et les cellules de destination (en-tête de date, zones de cumul). Validation de l'intégrité des formules basiques existantes.
|
|
||||||
* [ ] **Tâche 1.4 - Refonte du Fichier Macro :** Audit, nettoyage et restructuration des macros existantes en modules indépendants.
|
|
||||||
|
|
||||||
## Phase 2 : Développement du Conteneur Web (Interface & Backend)
|
|
||||||
* [ ] **Tâche 2.1 - Maquette & UI :** Développement de l'interface utilisateur en appliquant la charte graphique SERFIM TIC et en intégrant le logo Aethas38.
|
|
||||||
* [ ] **Tâche 2.2 - Création du Backend :** Script de gestion des uploads/downloads des fichiers de suivi et d'attachement.
|
|
||||||
* [ ] **Tâche 2.3 - Dockge & Déploiement Local :** Écriture du `docker-compose.yml` optimisé pour le serveur Debian, testé localement puis déployé via Dockge.
|
|
||||||
|
|
||||||
## Phase 3 : Développement du Moteur de Traitement (Core Logic)
|
|
||||||
* [ ] **Tâche 3.1 - Identification & Sécurité :** Script pour capturer l'identité de l'utilisateur (log web ou session) et horodatage de l'action.
|
|
||||||
* [ ] **Tâche 3.2 - Injection des Métadonnées :** Remplissage automatique des en-têtes (Semaine/Année, Code Affaire, Numéro de Commande).
|
|
||||||
* [ ] **Tâche 3.3 - Moteur de Calcul :** Logique d'addition des données de la semaine en cours avec l'historique pour générer la vue cumulative.
|
|
||||||
|
|
||||||
## Phase 4 : Sécurisation et Clôture (Safe Exit)
|
|
||||||
* [ ] **Tâche 4.1 - Verrouillage des Données :** Implémentation de la fonction retournant dans le fichier de suivi pour verrouiller les cellules traitées.
|
|
||||||
* [ ] **Tâche 4.2 - Onglet Justifications :** Préparation de l'architecture pour le second onglet dédié aux justifications hebdomadaires.
|
|
||||||
|
|
||||||
## Phase 5 : Finalisation, Traçabilité et Mises à Jour (Gitea)
|
|
||||||
* [ ] **Tâche 5.1 - Rapport de Traitement :** Génération automatique d'une synthèse (lignes traitées, auteur, valeurs transférées, statut des verrouillages).
|
|
||||||
* [ ] **Tâche 5.2 - Phase de Test (UAT) :** Tests complets de l'outil avec de faux jeux de données.
|
|
||||||
* [ ] **Tâche 5.3 - Livraison Continue (CI/CD basique) :** Validation du flux de mise à jour entre le dépôt Gitea et les conteneurs Dockge.
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
import os
|
|
||||||
import shutil
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
def securiser_fichier_excel(chemin_original, code_affaire):
|
|
||||||
"""
|
|
||||||
Crée une copie de sauvegarde d'un fichier Excel avant traitement.
|
|
||||||
Nomenclature : Semaine_Annee_CodeAffaire
|
|
||||||
"""
|
|
||||||
if not os.path.exists(chemin_original):
|
|
||||||
print(f"❌ Erreur : Le fichier '{chemin_original}' est introuvable.")
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 1. Obtenir la date actuelle
|
|
||||||
aujourdhui = datetime.now()
|
|
||||||
annee = aujourdhui.strftime("%Y")
|
|
||||||
semaine = aujourdhui.strftime("%V") # %V donne le numéro de semaine ISO
|
|
||||||
|
|
||||||
# 2. Créer le dossier de sauvegarde s'il n'existe pas
|
|
||||||
dossier_backup = "backups_excel"
|
|
||||||
os.makedirs(dossier_backup, exist_ok=True)
|
|
||||||
|
|
||||||
# 3. Extraire l'extension (.xlsx ou .xlsm)
|
|
||||||
_, extension = os.path.splitext(chemin_original)
|
|
||||||
|
|
||||||
# 4. Construire le nouveau nom
|
|
||||||
nouveau_nom = f"S{semaine}_{annee}_{code_affaire}{extension}"
|
|
||||||
chemin_destination = os.path.join(dossier_backup, nouveau_nom)
|
|
||||||
|
|
||||||
# 5. Copier le fichier
|
|
||||||
shutil.copy2(chemin_original, chemin_destination)
|
|
||||||
print(f"✅ Fichier sécurisé : {chemin_destination}")
|
|
||||||
|
|
||||||
return chemin_destination
|
|
||||||
|
|
||||||
# --- TEST DU MODULE ---
|
|
||||||
if __name__ == "__main__":
|
|
||||||
# Test à blanc : on crée un faux fichier Excel pour vérifier que le script fonctionne
|
|
||||||
fichier_test = "mon_suivi_financier.xlsx"
|
|
||||||
with open(fichier_test, "w") as f:
|
|
||||||
f.write("Données de test")
|
|
||||||
|
|
||||||
securiser_fichier_excel(fichier_test, "CHANTIER_SERFIM_01")
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Données de test
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import os
|
|
||||||
import requests
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
|
|
||||||
# Couleurs pour le terminal (Inspiration AETHAS38 / SERFIM TIC)
|
|
||||||
CYAN = '\033[96m'
|
|
||||||
MAGENTA = '\033[95m'
|
|
||||||
GREEN = '\033[92m'
|
|
||||||
YELLOW = '\033[93m'
|
|
||||||
RED = '\033[91m'
|
|
||||||
RESET = '\033[0m'
|
|
||||||
|
|
||||||
def print_header():
|
|
||||||
print(f"\n{CYAN}=================================================={RESET}")
|
|
||||||
print(f"{MAGENTA} A E T H A S 3 8 T E C H C O R E {RESET}")
|
|
||||||
print(f"{CYAN}=================================================={RESET}")
|
|
||||||
print(f" Interface de Développement & Budget LLM \n")
|
|
||||||
|
|
||||||
def check_openrouter_budget():
|
|
||||||
"""Interroge l'API OpenRouter avec la Management Key pour lire le solde."""
|
|
||||||
load_dotenv()
|
|
||||||
|
|
||||||
# On récupère STRICTEMENT la Management Key
|
|
||||||
mgmt_key = os.getenv("OPENROUTER_MANAGEMENT_KEY")
|
|
||||||
|
|
||||||
if not mgmt_key:
|
|
||||||
print(f"{RED}[ERREUR] OPENROUTER_MANAGEMENT_KEY introuvable dans le fichier .env.{RESET}")
|
|
||||||
print("Veuillez créer une Management API Key sur OpenRouter et l'ajouter au .env.")
|
|
||||||
return
|
|
||||||
|
|
||||||
print(f"{YELLOW}Interrogation des serveurs OpenRouter...{RESET}")
|
|
||||||
|
|
||||||
url = "https://openrouter.ai/api/v1/credits"
|
|
||||||
headers = {
|
|
||||||
"Authorization": f"Bearer {mgmt_key}"
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
|
||||||
response = requests.get(url, headers=headers)
|
|
||||||
|
|
||||||
if response.status_code == 200:
|
|
||||||
data = response.json().get("data", {})
|
|
||||||
total_credits = data.get("total_credits", 0)
|
|
||||||
total_usage = data.get("total_usage", 0)
|
|
||||||
remaining = total_credits - total_usage
|
|
||||||
|
|
||||||
print(f"\n{GREEN}--- STATUT BUDGET OPENROUTER ---{RESET}")
|
|
||||||
print(f"Crédits achetés : {total_credits:.4f} $")
|
|
||||||
print(f"Crédits consommés : {total_usage:.4f} $")
|
|
||||||
|
|
||||||
# Alerte visuelle si le budget est bas
|
|
||||||
if remaining < 1.0:
|
|
||||||
print(f"Solde restant : {RED}{remaining:.4f} ${RESET} ⚠️ (Recharge conseillée)")
|
|
||||||
else:
|
|
||||||
print(f"Solde restant : {CYAN}{remaining:.4f} ${RESET}")
|
|
||||||
print(f"{GREEN}--------------------------------{RESET}\n")
|
|
||||||
|
|
||||||
elif response.status_code == 403:
|
|
||||||
print(f"{RED}[ERREUR 403] Accès refusé.{RESET} Vérifiez que vous utilisez bien une Management Key et non une clé API standard.")
|
|
||||||
else:
|
|
||||||
print(f"{RED}[ERREUR {response.status_code}]{RESET} {response.text}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{RED}[ERREUR RESEAU] Impossible de joindre OpenRouter : {e}{RESET}")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
print_header()
|
|
||||||
check_openrouter_budget()
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
from fasthtml.common import *
|
||||||
|
import os
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
# En-têtes pour le style visuel
|
||||||
|
theme_hdrs = [
|
||||||
|
Script(src="https://cdn.tailwindcss.com"),
|
||||||
|
Style("""
|
||||||
|
body { background-color: #0f172a; color: #f8fafc; font-family: system-ui, sans-serif; }
|
||||||
|
.sidebar { background-color: #1e293b; border-right: 1px solid #333; height: 100vh; padding: 20px; }
|
||||||
|
.main-content { padding: 20px; height: 100vh; display: flex; flex-direction: column; }
|
||||||
|
""")
|
||||||
|
]
|
||||||
|
|
||||||
|
# Initialisation de l'application FastHTML
|
||||||
|
app, rt = fast_app(hdrs=theme_hdrs)
|
||||||
|
|
||||||
|
@rt('/')
|
||||||
|
def get():
|
||||||
|
return Title("AETHAS38 Multi-IA"), Body(
|
||||||
|
Div( # On utilise Div au lieu de Grid
|
||||||
|
Div(
|
||||||
|
H2("AETHAS 38", style="color:#00e5ff; font-weight:bold; font-size:24px;"),
|
||||||
|
P("Tech Core - Multi IA", style="color:#a855f7; margin-bottom: 20px;"),
|
||||||
|
cls="sidebar"
|
||||||
|
),
|
||||||
|
Div(
|
||||||
|
H3("Interface prête pour l'intégration des modèles", style="font-size:20px; margin-bottom:10px;"),
|
||||||
|
P("Le serveur local FastHTML fonctionne correctement."),
|
||||||
|
cls="main-content"
|
||||||
|
),
|
||||||
|
style="display: grid; grid-template-columns: 250px 1fr;" # C'est ici qu'on définit la grille
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
serve()
|
||||||
@@ -1 +0,0 @@
|
|||||||
Données de test
|
|
||||||
Reference in new issue
Block a user