Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion backend/DivineoBunker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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

Expand Down
Binary file removed backend/__pycache__/jules_engine.cpython-312.pyc
Binary file not shown.
Binary file removed backend/__pycache__/main.cpython-312.pyc
Binary file not shown.
Binary file removed backend/__pycache__/models.cpython-312.pyc
Binary file not shown.
Binary file not shown.
11 changes: 8 additions & 3 deletions backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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.")
Expand Down
Binary file not shown.
30 changes: 19 additions & 11 deletions js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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 => {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)';
});
Expand Down Expand Up @@ -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 });
Expand All @@ -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 {
Expand Down