diff --git a/backend/DivineoBunker.py b/backend/DivineoBunker.py index be0b8d8..17615d6 100644 --- a/backend/DivineoBunker.py +++ b/backend/DivineoBunker.py @@ -8,6 +8,8 @@ class DivineoBunker: def __init__(self): # 🛡️ Configuración Maestra (abvetos.com) self.secret_key = os.getenv("LVT_SECRET_KEY", "DEVELOPMENT_SECRET_DO_NOT_USE_IN_PROD") + # Pre-encode secret key to bytes to save CPU cycles on high-frequency auth verification + self._secret_key_bytes = self.secret_key.encode() self.patent = "PCT/EP2025/067317" self.algorithm_v = "V10_Divineo_Shopify_Final" @@ -35,7 +37,8 @@ def _verify_auth(self, user_id, token): try: ts, sig = token.split('.') if int(time.time()) - int(ts) > 600: return False # Ventana 10 min - expected = hmac.new(self.secret_key.encode(), f"{user_id}:{ts}".encode(), hashlib.sha256).hexdigest() + # Optimization: Use pre-encoded _secret_key_bytes + expected = hmac.new(self._secret_key_bytes, f"{user_id}:{ts}".encode(), hashlib.sha256).hexdigest() return hmac.compare_digest(sig, expected) except: return False diff --git a/backend/__pycache__/jules_engine.cpython-312.pyc b/backend/__pycache__/jules_engine.cpython-312.pyc deleted file mode 100644 index e245657..0000000 Binary files a/backend/__pycache__/jules_engine.cpython-312.pyc and /dev/null differ diff --git a/backend/__pycache__/main.cpython-312.pyc b/backend/__pycache__/main.cpython-312.pyc deleted file mode 100644 index 326c467..0000000 Binary files a/backend/__pycache__/main.cpython-312.pyc and /dev/null differ diff --git a/backend/__pycache__/models.cpython-312.pyc b/backend/__pycache__/models.cpython-312.pyc deleted file mode 100644 index a1357dc..0000000 Binary files a/backend/__pycache__/models.cpython-312.pyc and /dev/null differ diff --git a/backend/__pycache__/test_jules.cpython-312-pytest-9.0.2.pyc b/backend/__pycache__/test_jules.cpython-312-pytest-9.0.2.pyc deleted file mode 100644 index a7209d8..0000000 Binary files a/backend/__pycache__/test_jules.cpython-312-pytest-9.0.2.pyc and /dev/null differ diff --git a/backend/main.py b/backend/main.py index fb88c85..a154183 100644 --- a/backend/main.py +++ b/backend/main.py @@ -27,14 +27,17 @@ ) # 🛡️ Configuración Maestra (abvetos.com) - Secrets moved to environment variables -SECRET_KEY = os.getenv("LVT_SECRET_KEY", "DEVELOPMENT_SECRET_DO_NOT_USE_IN_PROD") +_SECRET_KEY = os.getenv("LVT_SECRET_KEY", "DEVELOPMENT_SECRET_DO_NOT_USE_IN_PROD") +# Pre-encode secret key to bytes to save CPU cycles on high-frequency auth verification +SECRET_KEY_BYTES = _SECRET_KEY.encode() PATENT = "PCT/EP2025/067317" def verify_auth(user_id: str, token: str) -> bool: try: ts, sig = token.split('.') if int(time.time()) - int(ts) > 600: return False # Ventana 10 min - expected = hmac.new(SECRET_KEY.encode(), f"{user_id}:{ts}".encode(), hashlib.sha256).hexdigest() + # Optimization: Use pre-encoded SECRET_KEY_BYTES + expected = hmac.new(SECRET_KEY_BYTES, f"{user_id}:{ts}".encode(), hashlib.sha256).hexdigest() return hmac.compare_digest(sig, expected) except: return False @@ -50,7 +53,9 @@ def calculate_fit(user_waist: float, item_id: str): return is_perfect, round(fit_index, 3), item @app.post("/api/recommend") -async def recommend_garment(scan: UserScan, garment_id: str = "BALMAIN_SS26_SLIM"): +def recommend_garment(scan: UserScan, garment_id: str = "BALMAIN_SS26_SLIM"): + # Optimization: defined as sync 'def' so FastAPI runs it in a thread pool. + # This prevents the blocking LLM call in get_jules_advice from stalling the event loop. # 1. Seguridad y Handshake if not verify_auth(scan.user_id, scan.token): raise HTTPException(status_code=403, detail="Acceso restringido al búnker.") diff --git a/backend/tests/__pycache__/test_main.cpython-312-pytest-9.0.2.pyc b/backend/tests/__pycache__/test_main.cpython-312-pytest-9.0.2.pyc deleted file mode 100644 index 8ee3541..0000000 Binary files a/backend/tests/__pycache__/test_main.cpython-312-pytest-9.0.2.pyc and /dev/null differ diff --git a/js/main.js b/js/main.js index dcf1947..c173374 100644 --- a/js/main.js +++ b/js/main.js @@ -35,6 +35,15 @@ class TryOnYouBunker { this.selectedGarmentId = "BALMAIN_SS26_SLIM"; this.version = "11.0.0"; this.biometricAnalyzer = new MediaPipeBiometricAnalyzer(); + // Cache frequently accessed DOM elements + this.ui = { + julesResult: document.getElementById('jules-result'), + recommendationText: document.getElementById('recommendation-text'), + privatePassModal: document.getElementById('private-pass-modal'), + privatePassInput: document.getElementById('private-pass-input'), + julesForm: document.getElementById('jules-form'), + productItems: document.querySelectorAll('.product-item') + }; this.shopifyInventory = { "BALMAIN_SS26_SLIM": { "name": "Balmain Slim-Fit Jeans", @@ -68,8 +77,7 @@ class TryOnYouBunker { } setupEventListeners() { - const julesForm = document.getElementById('jules-form'); - if (julesForm) julesForm.addEventListener('submit', this.handleDivineoExecution.bind(this)); + if (this.ui.julesForm) this.ui.julesForm.addEventListener('submit', this.handleDivineoExecution.bind(this)); // Navigation document.querySelectorAll('.nav-menu a[href^="#"]').forEach(link => { @@ -105,8 +113,8 @@ class TryOnYouBunker { const formData = new FormData(event.target); const eventType = formData.get('event_type'); - const resultContainer = document.getElementById('jules-result'); - const resultText = document.getElementById('recommendation-text'); + const resultContainer = this.ui.julesResult; + const resultText = this.ui.recommendationText; const submitBtn = event.target.querySelector('button[type="submit"]'); try { @@ -156,7 +164,7 @@ class TryOnYouBunker { selectGarment(garmentId, element) { this.selectedGarmentId = garmentId; - document.querySelectorAll('.product-item').forEach(item => { + this.ui.productItems.forEach(item => { item.classList.remove('selected'); item.style.borderColor = 'rgba(255, 255, 255, 0.1)'; }); @@ -210,6 +218,8 @@ class TryOnYouBunker { if (entry.isIntersecting) { entry.target.style.opacity = '1'; entry.target.style.transform = 'translateY(0)'; + // Optimization: stop observing once the transition is triggered + observer.unobserve(entry.target); } }); }, { threshold: 0.1 }); @@ -223,18 +233,16 @@ class TryOnYouBunker { } requestPrivatePass() { - const modal = document.getElementById('private-pass-modal'); - modal.style.display = 'flex'; + if (this.ui.privatePassModal) this.ui.privatePassModal.style.display = 'flex'; } closePrivatePass() { - const modal = document.getElementById('private-pass-modal'); - modal.style.display = 'none'; + if (this.ui.privatePassModal) this.ui.privatePassModal.style.display = 'none'; } verifyPrivatePass() { - const input = document.getElementById('private-pass-input'); - if (input.value === "SAC_MUSEUM_2026") { + const input = this.ui.privatePassInput; + if (input && input.value === "SAC_MUSEUM_2026") { this.showNotification('ACCESO CONCEDIDO', 'success'); setTimeout(() => { window.location.href = "/staff-dashboard"; }, 1500); } else {