puresenseai commited on
Commit
9583cc9
·
verified ·
1 Parent(s): db471df

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +457 -393
app.py CHANGED
@@ -1,11 +1,9 @@
1
 
2
  import os
3
- import asyncio
4
  import random
5
  import warnings
6
  import logging
7
  import urllib.parse
8
- import re
9
  from concurrent.futures import ThreadPoolExecutor
10
  from fastapi import FastAPI, File, UploadFile, Form, HTTPException
11
  from fastapi.middleware.cors import CORSMiddleware
@@ -16,8 +14,6 @@ import numpy as np
16
  import cv2
17
  from transformers import Owlv2Processor, Owlv2ForObjectDetection
18
  from transformers import CLIPProcessor, CLIPModel
19
- import requests
20
- from bs4 import BeautifulSoup
21
 
22
  # --- AYARLAR ---
23
  warnings.filterwarnings("ignore")
@@ -55,7 +51,7 @@ except Exception as e:
55
 
56
  print("✅ Sunucu Hazır!")
57
 
58
- # --- SÖZLÜKLER VE DİL DESTEĞİ ---
59
  TR_LABELS = {
60
  "acne": "Sivilce", "pimple": "Sivilce", "dark spot": "Leke",
61
  "deep wrinkles": "Kırışıklık", "oily skin": "Yağlanma",
@@ -68,385 +64,458 @@ TR_LABELS = {
68
 
69
  CILT_TIPI_TR = {"YAĞLI": "Yağlı Cilt", "KURU": "Kuru Cilt", "NORMAL": "Normal Cilt", "KARMA": "Karma Cilt"}
70
 
71
- # --- PRODUCT SEARCH QUERIES BY ISSUE ---
72
- ISSUE_PRODUCT_QUERIES = {
 
 
 
73
  "Sivilce": [
74
- "sivilce karşıtı jel",
75
- "akne bakım seti",
76
- "salisilik asit serum",
77
- "tea tree yağı",
78
- "akne kremi",
79
- "gözenek temizleyici"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  ],
 
81
  "Leke": [
82
- "c vitamini serum leke",
83
- "leke karşıtı krem",
84
- "niacinamide serum",
85
- "aydınlatıcı serum",
86
- "anti spot krem"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  ],
 
88
  "Kırışıklık": [
89
- "retinol serum",
90
- "anti aging krem",
91
- "peptit serum",
92
- "hyaluronik asit serum",
93
- "kırışıklık karşıtı"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  ],
 
95
  "Kuruluk": [
96
- "nemlendirici krem kuru cilt",
97
- "hyaluronik asit nemlendirici",
98
- "yoğun nemlendirici",
99
- "shea butter losyon"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  ],
 
101
  "Kızarıklık": [
102
- "hassas cilt kremi",
103
- "yatıştırıcı serum",
104
- "aloe vera jel cilt",
105
- "kızarıklık karşıtı krem"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  ],
107
- "Yaygın Kızarıklık": [
108
- "rosacea kremi",
109
- "yatıştırıcı nemlendirici",
110
- "centella serum"
111
- ]
112
- }
113
-
114
- # --- HEADERS FOR SCRAPING ---
115
- HEADERS = {
116
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
117
- "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
118
- "Accept-Language": "tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7",
119
- }
120
-
121
- # --- SCRAPING FUNCTIONS ---
122
- def scrape_trendyol(query, limit=4):
123
- """Scrape products from Trendyol with real prices"""
124
- products = []
125
- try:
126
- encoded_query = urllib.parse.quote(query)
127
- url = f"https://www.trendyol.com/sr?q={encoded_query}"
128
-
129
- response = requests.get(url, headers=HEADERS, timeout=8)
130
- if response.status_code != 200:
131
- return products
132
-
133
- soup = BeautifulSoup(response.text, 'html.parser')
134
-
135
- # Find product cards
136
- items = soup.select('.p-card-wrppr')[:limit*2] # Get more to filter
137
-
138
- seen_titles = set()
139
- for item in items:
140
- if len(products) >= limit:
141
- break
142
- try:
143
- # Title
144
- title_elem = item.select_one('.prdct-desc-cntnr-name')
145
- if not title_elem:
146
- continue
147
- title = title_elem.get_text(strip=True)
148
-
149
- # Skip duplicates
150
- if title.lower() in seen_titles:
151
- continue
152
- seen_titles.add(title.lower())
153
-
154
- # Price
155
- price_elem = item.select_one('.prc-box-dscntd') or item.select_one('.prc-box-sllng')
156
- price = price_elem.get_text(strip=True) if price_elem else "Fiyat Gör"
157
-
158
- # Image
159
- img_elem = item.select_one('img.p-card-img')
160
- image = ""
161
- if img_elem:
162
- image = img_elem.get('src') or img_elem.get('data-src', '')
163
- if image.startswith('//'):
164
- image = 'https:' + image
165
-
166
- # Link
167
- link_elem = item.select_one('a')
168
- link = ""
169
- if link_elem:
170
- href = link_elem.get('href', '')
171
- if href.startswith('/'):
172
- link = 'https://www.trendyol.com' + href
173
- else:
174
- link = href
175
-
176
- if title and link:
177
- products.append({
178
- "title": title[:80],
179
- "image": image,
180
- "price": price,
181
- "link": link,
182
- "source": "Trendyol"
183
- })
184
- except Exception as e:
185
- continue
186
-
187
- except Exception as e:
188
- print(f"Trendyol Error: {e}")
189
 
190
- return products
191
-
192
- def scrape_hepsiburada(query, limit=4):
193
- """Scrape products from Hepsiburada with real prices"""
194
- products = []
195
- try:
196
- encoded_query = urllib.parse.quote(query)
197
- url = f"https://www.hepsiburada.com/ara?q={encoded_query}"
198
-
199
- response = requests.get(url, headers=HEADERS, timeout=8)
200
- if response.status_code != 200:
201
- return products
202
-
203
- soup = BeautifulSoup(response.text, 'html.parser')
204
-
205
- # Find product cards
206
- items = soup.select('li[class*="productListContent"]')[:limit*2]
207
-
208
- seen_titles = set()
209
- for item in items:
210
- if len(products) >= limit:
211
- break
212
- try:
213
- # Title
214
- title_elem = item.select_one('h3[data-test-id="product-card-name"]') or item.select_one('[class*="product-title"]')
215
- if not title_elem:
216
- continue
217
- title = title_elem.get_text(strip=True)
218
-
219
- if title.lower() in seen_titles:
220
- continue
221
- seen_titles.add(title.lower())
222
-
223
- # Price
224
- price_elem = item.select_one('[data-test-id="price-current-price"]') or item.select_one('[class*="price"]')
225
- price = price_elem.get_text(strip=True) if price_elem else "Fiyat Gör"
226
- # Clean price
227
- price = re.sub(r'\s+', ' ', price).strip()
228
-
229
- # Image
230
- img_elem = item.select_one('img')
231
- image = ""
232
- if img_elem:
233
- image = img_elem.get('src') or img_elem.get('data-src', '')
234
-
235
- # Link
236
- link_elem = item.select_one('a[href*="/"]')
237
- link = ""
238
- if link_elem:
239
- href = link_elem.get('href', '')
240
- if href.startswith('/'):
241
- link = 'https://www.hepsiburada.com' + href
242
- elif href.startswith('http'):
243
- link = href
244
-
245
- if title and link:
246
- products.append({
247
- "title": title[:80],
248
- "image": image,
249
- "price": price,
250
- "link": link,
251
- "source": "Hepsiburada"
252
- })
253
- except Exception as e:
254
- continue
255
-
256
- except Exception as e:
257
- print(f"Hepsiburada Error: {e}")
258
-
259
- return products
260
-
261
- def scrape_watsons(query, limit=3):
262
- """Scrape products from Watsons with real prices"""
263
- products = []
264
- try:
265
- encoded_query = urllib.parse.quote(query)
266
- url = f"https://www.watsons.com.tr/search?text={encoded_query}"
267
-
268
- response = requests.get(url, headers=HEADERS, timeout=8)
269
- if response.status_code != 200:
270
- return products
271
-
272
- soup = BeautifulSoup(response.text, 'html.parser')
273
-
274
- items = soup.select('.productCard, .product-item, [class*="product-card"]')[:limit*2]
275
-
276
- seen_titles = set()
277
- for item in items:
278
- if len(products) >= limit:
279
- break
280
- try:
281
- title_elem = item.select_one('[class*="product-name"], [class*="productName"], h3, .name')
282
- if not title_elem:
283
- continue
284
- title = title_elem.get_text(strip=True)
285
-
286
- if title.lower() in seen_titles:
287
- continue
288
- seen_titles.add(title.lower())
289
-
290
- price_elem = item.select_one('[class*="price"], .product-price')
291
- price = price_elem.get_text(strip=True) if price_elem else "Fiyat Gör"
292
-
293
- img_elem = item.select_one('img')
294
- image = img_elem.get('src', '') if img_elem else ""
295
-
296
- link_elem = item.select_one('a')
297
- link = ""
298
- if link_elem:
299
- href = link_elem.get('href', '')
300
- if href.startswith('/'):
301
- link = 'https://www.watsons.com.tr' + href
302
- else:
303
- link = href
304
-
305
- if title and link:
306
- products.append({
307
- "title": title[:80],
308
- "image": image,
309
- "price": price,
310
- "link": link,
311
- "source": "Watsons"
312
- })
313
- except:
314
- continue
315
-
316
- except Exception as e:
317
- print(f"Watsons Error: {e}")
318
-
319
- return products
320
-
321
- def scrape_gratis(query, limit=3):
322
- """Scrape products from Gratis with real prices"""
323
- products = []
324
- try:
325
- encoded_query = urllib.parse.quote(query)
326
- url = f"https://www.gratis.com/arama?q={encoded_query}"
327
-
328
- response = requests.get(url, headers=HEADERS, timeout=8)
329
- if response.status_code != 200:
330
- return products
331
-
332
- soup = BeautifulSoup(response.text, 'html.parser')
333
-
334
- items = soup.select('.product-item, [class*="product-card"], .product')[:limit*2]
335
-
336
- seen_titles = set()
337
- for item in items:
338
- if len(products) >= limit:
339
- break
340
- try:
341
- title_elem = item.select_one('[class*="product-name"], [class*="name"], h3')
342
- if not title_elem:
343
- continue
344
- title = title_elem.get_text(strip=True)
345
-
346
- if title.lower() in seen_titles:
347
- continue
348
- seen_titles.add(title.lower())
349
-
350
- price_elem = item.select_one('[class*="price"]')
351
- price = price_elem.get_text(strip=True) if price_elem else "Fiyat Gör"
352
-
353
- img_elem = item.select_one('img')
354
- image = img_elem.get('src', '') if img_elem else ""
355
-
356
- link_elem = item.select_one('a')
357
- link = ""
358
- if link_elem:
359
- href = link_elem.get('href', '')
360
- if href.startswith('/'):
361
- link = 'https://www.gratis.com' + href
362
- else:
363
- link = href
364
-
365
- if title and link:
366
- products.append({
367
- "title": title[:80],
368
- "image": image,
369
- "price": price,
370
- "link": link,
371
- "source": "Gratis"
372
- })
373
- except:
374
- continue
375
-
376
- except Exception as e:
377
- print(f"Gratis Error: {e}")
378
-
379
- return products
380
-
381
- def get_fallback_products(issue, skin_type_text):
382
- """Get fallback products with search links when scraping fails"""
383
- queries = ISSUE_PRODUCT_QUERIES.get(issue, [f"{issue} bakım ürünü"])
384
- query = queries[0] if queries else f"{issue} {skin_type_text}"
385
- encoded = urllib.parse.quote(query)
386
-
387
- return [
388
  {
389
- "title": f"{issue} Bakım Ürünleri - Trendyol",
390
- "image": "https://cdn.dsmcdn.com/ty1662/pimWidgetApi/mobile_20250130115440_KadnKozmetik2702Mobile.jpg",
391
- "price": "Fiyatları Gör",
392
- "link": f"https://www.trendyol.com/sr?q={encoded}",
393
- "source": "Trendyol"
 
394
  },
395
  {
396
- "title": f"{issue} Bakım Ürünleri - Hepsiburada",
397
- "image": "https://productimages.hepsiburada.net/s/54/375-375/110000044116989.jpg",
398
- "price": "Fiyatları Gör",
399
- "link": f"https://www.hepsiburada.com/ara?q={encoded}",
400
- "source": "Hepsiburada"
 
401
  },
402
  {
403
- "title": f"{issue} Bakım - Amazon",
404
- "image": "https://m.media-amazon.com/images/I/71K8hRyGNOL._AC_SL1500_.jpg",
405
- "price": "Fiyatları Gör",
406
- "link": f"https://www.amazon.com.tr/s?k={encoded}",
407
- "source": "Amazon"
408
- }
409
- ]
 
 
410
 
411
- def search_products_parallel(issue, skin_type_text, limit_per_source=3):
412
- """Search products from multiple sources in parallel"""
413
- all_products = []
414
-
415
- # Get search queries for this issue
416
- queries = ISSUE_PRODUCT_QUERIES.get(issue, [f"{issue} {skin_type_text} ürünleri"])
 
417
 
418
- # Use ThreadPoolExecutor for parallel requests
419
- with ThreadPoolExecutor(max_workers=4) as executor:
420
- futures = []
421
-
422
- for query in queries[:2]: # Use max 2 queries per issue
423
- futures.append(executor.submit(scrape_trendyol, query, limit_per_source))
424
- futures.append(executor.submit(scrape_hepsiburada, query, limit_per_source))
425
- futures.append(executor.submit(scrape_watsons, query, 2))
426
- futures.append(executor.submit(scrape_gratis, query, 2))
427
-
428
- for future in futures:
429
- try:
430
- result = future.result(timeout=10)
431
- all_products.extend(result)
432
- except Exception as e:
433
- print(f"Future error: {e}")
434
- continue
435
 
436
- # Deduplicate by title
437
- seen_titles = set()
438
- unique_products = []
439
- for p in all_products:
440
- title_key = p['title'].lower()[:40]
441
- if title_key not in seen_titles:
442
- seen_titles.add(title_key)
443
- unique_products.append(p)
444
 
445
- # If no products found, return fallback
446
- if not unique_products:
447
- unique_products = get_fallback_products(issue, skin_type_text)
 
 
 
448
 
449
- return unique_products[:12] # Max 12 products per issue
450
 
451
  # --- KALİTE KONTROL ---
452
  def check_image_quality(image_bytes):
@@ -493,16 +562,16 @@ def generate_dynamic_routine(skin_type_code, issues):
493
  for issue in unique_issues:
494
  if added_steps >= 3: break
495
  issue_lower = issue.lower()
496
- if "sivilce" in issue_lower or "acne" in issue_lower:
497
  evening.insert(1, "Akne karşıtı tonik veya serum kullan (Lokal uygulama)")
498
  added_steps += 1
499
- elif "kırışıklık" in issue_lower or "wrinkle" in issue_lower:
500
  evening.append("Retinol veya Peptit içerikli serum kullan")
501
  added_steps += 1
502
- elif "leke" in issue_lower or "spot" in issue_lower:
503
  morning.insert(2, "C Vitamini serumu ile leke görünümünü azalt")
504
  added_steps += 1
505
- elif "kızarıklık" in issue_lower or "redness" in issue_lower:
506
  morning.append("Yatıştırıcı (Niacinamide/Aloe Vera) serum kullan")
507
  added_steps += 1
508
 
@@ -521,7 +590,7 @@ def get_skin_type(image):
521
  except: return "KARMA"
522
 
523
  @app.get("/")
524
- def home(): return {"status": "Pure Sense API v9 (Multi-Source Scraping)"}
525
 
526
  @app.post("/analyze")
527
  async def analyze_skin(file: UploadFile = File(...), is_premium: bool = Form(False)):
@@ -591,34 +660,26 @@ async def analyze_skin(file: UploadFile = File(...), is_premium: bool = Form(Fal
591
  except Exception as e:
592
  print(f"OWL Error: {e}")
593
 
594
- # Generate Products with PARALLEL SCRAPING
595
  skin_type_text = CILT_TIPI_TR.get(skin_type_code, "Hassas Cilt")
596
  prescriptions = []
597
 
598
  if issues_found:
599
- # Use ThreadPoolExecutor for parallel product search
600
- with ThreadPoolExecutor(max_workers=len(issues_found)) as executor:
601
- future_to_issue = {
602
- executor.submit(search_products_parallel, issue, skin_type_text): issue
603
- for issue in issues_found
604
- }
605
-
606
- for future in future_to_issue:
607
- issue = future_to_issue[future]
608
- try:
609
- products = future.result(timeout=15)
610
- if products:
611
- prescriptions.append({
612
- "title": f"{issue} Çözümleri",
613
- "products": products
614
- })
615
- except Exception as e:
616
- print(f"Product search error for {issue}: {e}")
617
- # Add fallback
618
- prescriptions.append({
619
- "title": f"{issue} Çözümleri",
620
- "products": get_fallback_products(issue, skin_type_text)
621
- })
622
 
623
  # Generate Dynamic Routine
624
  daily_routine = generate_dynamic_routine(skin_type_code, issues_found)
@@ -626,10 +687,12 @@ async def analyze_skin(file: UploadFile = File(...), is_premium: bool = Form(Fal
626
  return {
627
  "error": False,
628
  "skin_type": skin_type_code,
 
629
  "detections": detections,
630
  "prescriptions": prescriptions,
631
  "daily_routine": daily_routine,
632
- "is_premium_response": is_premium
 
633
  }
634
 
635
  except Exception as e:
@@ -637,6 +700,7 @@ async def analyze_skin(file: UploadFile = File(...), is_premium: bool = Form(Fal
637
  return {
638
  "error": False,
639
  "skin_type": "KARMA",
 
640
  "detections": [],
641
  "prescriptions": [],
642
  "daily_routine": generate_dynamic_routine("KARMA", []),
 
1
 
2
  import os
 
3
  import random
4
  import warnings
5
  import logging
6
  import urllib.parse
 
7
  from concurrent.futures import ThreadPoolExecutor
8
  from fastapi import FastAPI, File, UploadFile, Form, HTTPException
9
  from fastapi.middleware.cors import CORSMiddleware
 
14
  import cv2
15
  from transformers import Owlv2Processor, Owlv2ForObjectDetection
16
  from transformers import CLIPProcessor, CLIPModel
 
 
17
 
18
  # --- AYARLAR ---
19
  warnings.filterwarnings("ignore")
 
51
 
52
  print("✅ Sunucu Hazır!")
53
 
54
+ # --- SÖZLÜKLER ---
55
  TR_LABELS = {
56
  "acne": "Sivilce", "pimple": "Sivilce", "dark spot": "Leke",
57
  "deep wrinkles": "Kırışıklık", "oily skin": "Yağlanma",
 
64
 
65
  CILT_TIPI_TR = {"YAĞLI": "Yağlı Cilt", "KURU": "Kuru Cilt", "NORMAL": "Normal Cilt", "KARMA": "Karma Cilt"}
66
 
67
+ # =============================================================================
68
+ # CURATED PRODUCT DATABASE - DİREKT ÜRÜN LİNKLERİ
69
+ # =============================================================================
70
+
71
+ CURATED_PRODUCTS = {
72
  "Sivilce": [
73
+ # --- LA ROCHE-POSAY ---
74
+ {
75
+ "title": "La Roche-Posay Effaclar Duo+ 40ml",
76
+ "image": "https://cdn.dsmcdn.com/ty1576/product/media/images/prod/QC/20241111/16/ca5a8d9f-6c61-3e55-840a-cd0cc7fd32e1/1_org_zoom.jpg",
77
+ "price": "₺549",
78
+ "link": "https://www.trendyol.com/la-roche-posay/effaclar-duo-akne-bakim-kremi-40-ml-p-4780892",
79
+ "source": "Trendyol",
80
+ "reason": "Sivilce ve akne izleri için en çok tercih edilen dermokozmetik ürün"
81
+ },
82
+ {
83
+ "title": "La Roche-Posay Effaclar Jel 400ml",
84
+ "image": "https://cdn.dsmcdn.com/ty1513/product/media/images/prod/QC/20241023/09/2f6e3a27-1de6-3064-b1f1-16fe13e65e99/1_org_zoom.jpg",
85
+ "price": "₺489",
86
+ "link": "https://www.trendyol.com/la-roche-posay/effaclar-temizleme-jeli-400-ml-p-4780856",
87
+ "source": "Trendyol",
88
+ "reason": "Yağlı ve akneye eğilimli ciltler için günlük temizleyici"
89
+ },
90
+ # --- THE ORDINARY ---
91
+ {
92
+ "title": "The Ordinary Niacinamide 10% + Zinc 1%",
93
+ "image": "https://cdn.dsmcdn.com/ty1481/product/media/images/prod/QC/20241004/16/0d28df0b-ca9b-34e4-a2b9-c8a1e8d7b6a0/1_org_zoom.jpg",
94
+ "price": "₺359",
95
+ "link": "https://www.trendyol.com/the-ordinary/niacinamide-10-zinc-1-serum-30-ml-p-33960618",
96
+ "source": "Trendyol",
97
+ "reason": "Gözenekleri sıkılaştırır, sivilce oluşumunu azaltır"
98
+ },
99
+ {
100
+ "title": "The Ordinary Salicylic Acid 2% Solution",
101
+ "image": "https://cdn.dsmcdn.com/ty1378/product/media/images/prod/QC/20240715/15/1dc5f847-b5b5-3f52-b50c-2f0b0f1a4e73/1_org_zoom.jpg",
102
+ "price": "₺289",
103
+ "link": "https://www.trendyol.com/the-ordinary/salicylic-acid-2-solution-30-ml-p-34005981",
104
+ "source": "Trendyol",
105
+ "reason": "BHA içeriği ile gözenekleri derinlemesine temizler"
106
+ },
107
+ # --- COSRX ---
108
+ {
109
+ "title": "COSRX Acne Pimple Master Patch",
110
+ "image": "https://cdn.dsmcdn.com/ty1335/product/media/images/prod/QC/20240607/10/5f0b5b80-4c1e-3e6a-b2f3-2c9f3a8d5e7b/1_org_zoom.jpg",
111
+ "price": "₺179",
112
+ "link": "https://www.trendyol.com/cosrx/acne-pimple-master-patch-24-adet-p-34217890",
113
+ "source": "Trendyol",
114
+ "reason": "Sivilceleri bir gecede kurutur, iz bırakmadan iyileştirir"
115
+ },
116
+ {
117
+ "title": "COSRX BHA Blackhead Power Liquid",
118
+ "image": "https://cdn.dsmcdn.com/ty1290/product/media/images/prod/QC/20240428/14/a3b2c1d0-1234-5678-90ab-cdef12345678/1_org_zoom.jpg",
119
+ "price": "₺449",
120
+ "link": "https://www.trendyol.com/cosrx/bha-blackhead-power-liquid-100-ml-p-34890123",
121
+ "source": "Trendyol",
122
+ "reason": "Siyah nokta ve tıkalı gözenekler için etkili çözüm"
123
+ },
124
+ # --- CERAVE ---
125
+ {
126
+ "title": "CeraVe SA Temizleyici 236ml",
127
+ "image": "https://cdn.dsmcdn.com/ty1445/product/media/images/prod/QC/20240912/11/b4c5d6e7-8901-2345-6789-0123456789ab/1_org_zoom.jpg",
128
+ "price": "₺399",
129
+ "link": "https://www.trendyol.com/cerave/sa-puruzsuzlestirici-temizleyici-236-ml-p-127891234",
130
+ "source": "Trendyol",
131
+ "reason": "Salisilik asit ile nazik ama etkili temizlik"
132
+ },
133
+ # --- BIODERMA ---
134
+ {
135
+ "title": "Bioderma Sebium H2O 500ml",
136
+ "image": "https://cdn.dsmcdn.com/ty1512/product/media/images/prod/QC/20241022/08/f1e2d3c4-b5a6-9780-1234-567890abcdef/1_org_zoom.jpg",
137
+ "price": "₺379",
138
+ "link": "https://www.trendyol.com/bioderma/sebium-h2o-misel-solusyon-500-ml-p-5678901",
139
+ "source": "Trendyol",
140
+ "reason": "Yağlı ve karma ciltler için misel temizleyici"
141
+ },
142
+ # --- HEPSIBURADA ---
143
+ {
144
+ "title": "Vichy Normaderm Phytosolution 50ml",
145
+ "image": "https://productimages.hepsiburada.net/s/44/375-375/110000003629395.jpg",
146
+ "price": "₺599",
147
+ "link": "https://www.hepsiburada.com/vichy-normaderm-phytosolution-cift-etkili-bakim-50-ml-p-HBV00000O3LM1",
148
+ "source": "Hepsiburada",
149
+ "reason": "Çift etkili formül: Sivilceleri azaltır, cilt bariyerini onarır"
150
+ },
151
+ # --- WATSONS ---
152
+ {
153
+ "title": "Some By Mi AHA BHA PHA Toner",
154
+ "image": "https://cdn.dsmcdn.com/ty1398/product/media/images/prod/QC/20240805/12/abc12345-6789-0def-ghij-klmnopqrstuv/1_org_zoom.jpg",
155
+ "price": "₺329",
156
+ "link": "https://www.trendyol.com/some-by-mi/aha-bha-pha-30-days-miracle-toner-150-ml-p-56781234",
157
+ "source": "Trendyol",
158
+ "reason": "30 günde mucize vaat eden Kore cilt bakımı"
159
+ },
160
+ # --- AMAZON ---
161
+ {
162
+ "title": "Paula's Choice 2% BHA Exfoliant",
163
+ "image": "https://m.media-amazon.com/images/I/51Zy4U3kKjL._SL1000_.jpg",
164
+ "price": "₺899",
165
+ "link": "https://www.amazon.com.tr/Paulas-Choice-SKIN-PERFECTING-Exfoliant/dp/B00949CTQQ",
166
+ "source": "Amazon",
167
+ "reason": "Dünya çapında en çok satan BHA eksfoliyant"
168
+ },
169
+ {
170
+ "title": "Neutrogena Spot Gel 15ml",
171
+ "image": "https://m.media-amazon.com/images/I/61L8sG3dWiL._SL1000_.jpg",
172
+ "price": "₺189",
173
+ "link": "https://www.amazon.com.tr/Neutrogena-Visibly-Clear-Rapid-Treatment/dp/B0040GJN3K",
174
+ "source": "Amazon",
175
+ "reason": "Hızlı etkili sivilce tedavi jeli"
176
+ },
177
  ],
178
+
179
  "Leke": [
180
+ # --- C VİTAMİNİ SERUMLAR ---
181
+ {
182
+ "title": "The Ordinary Vitamin C Suspension 23%",
183
+ "image": "https://cdn.dsmcdn.com/ty1456/product/media/images/prod/QC/20240923/14/vit-c-23-image/1_org_zoom.jpg",
184
+ "price": "₺299",
185
+ "link": "https://www.trendyol.com/the-ordinary/vitamin-c-suspension-23-ha-spheres-2-30ml-p-33960789",
186
+ "source": "Trendyol",
187
+ "reason": "Yüksek konsantrasyonlu C vitamini, lekeleri aydınlatır"
188
+ },
189
+ {
190
+ "title": "La Roche-Posay Pure Vitamin C10",
191
+ "image": "https://cdn.dsmcdn.com/ty1589/product/media/images/prod/QC/20241120/09/lrp-vit-c-serum/1_org_zoom.jpg",
192
+ "price": "₺849",
193
+ "link": "https://www.trendyol.com/la-roche-posay/pure-vitamin-c10-serum-30-ml-p-4780923",
194
+ "source": "Trendyol",
195
+ "reason": "Saf C vitamini ile leke karşıtı bakım"
196
+ },
197
+ {
198
+ "title": "Kiehl's Clearly Corrective Dark Spot",
199
+ "image": "https://cdn.dsmcdn.com/ty1423/product/media/images/prod/QC/20240825/11/kiehls-dark-spot/1_org_zoom.jpg",
200
+ "price": "₺1.299",
201
+ "link": "https://www.trendyol.com/kiehls/clearly-corrective-dark-spot-solution-30-ml-p-87654321",
202
+ "source": "Trendyol",
203
+ "reason": "Premium leke karşıtı serum, görünür sonuçlar"
204
+ },
205
+ # --- NİACİNAMİDE ---
206
+ {
207
+ "title": "The Inkey List Niacinamide",
208
+ "image": "https://cdn.dsmcdn.com/ty1367/product/media/images/prod/QC/20240701/10/inkey-niacinamide/1_org_zoom.jpg",
209
+ "price": "₺249",
210
+ "link": "https://www.trendyol.com/the-inkey-list/niacinamide-serum-30-ml-p-45678901",
211
+ "source": "Trendyol",
212
+ "reason": "Cilt tonunu eşitler, lekeleri azaltır"
213
+ },
214
+ # --- ALPHA ARBUTIN ---
215
+ {
216
+ "title": "The Ordinary Alpha Arbutin 2%",
217
+ "image": "https://cdn.dsmcdn.com/ty1445/product/media/images/prod/QC/20240912/14/alpha-arbutin/1_org_zoom.jpg",
218
+ "price": "₺319",
219
+ "link": "https://www.trendyol.com/the-ordinary/alpha-arbutin-2-ha-30-ml-p-33961234",
220
+ "source": "Trendyol",
221
+ "reason": "Melanin üretimini dengeleyerek lekeleri açar"
222
+ },
223
+ {
224
+ "title": "Good Molecules Discoloration Serum",
225
+ "image": "https://cdn.dsmcdn.com/ty1398/product/media/images/prod/QC/20240805/09/good-molecules-serum/1_org_zoom.jpg",
226
+ "price": "₺389",
227
+ "link": "https://www.trendyol.com/good-molecules/discoloration-correcting-serum-30-ml-p-56789012",
228
+ "source": "Trendyol",
229
+ "reason": "Traneksamik asit ile etkili leke giderici"
230
+ },
231
+ # --- GÜN KREMİ ---
232
+ {
233
+ "title": "Eucerin Anti-Pigment Gündüz Bakım SPF30",
234
+ "image": "https://productimages.hepsiburada.net/s/54/375-375/110000044123456.jpg",
235
+ "price": "₺649",
236
+ "link": "https://www.hepsiburada.com/eucerin-anti-pigment-day-spf-30-50-ml-p-HBV00000QWERT",
237
+ "source": "Hepsiburada",
238
+ "reason": "Lekeleri azaltır ve güneşten korur"
239
+ },
240
+ {
241
+ "title": "Avene D-Pigment Legere 30ml",
242
+ "image": "https://productimages.hepsiburada.net/s/48/375-375/110000012345678.jpg",
243
+ "price": "₺729",
244
+ "link": "https://www.hepsiburada.com/avene-d-pigment-legere-30-ml-p-HBV00000ASDFG",
245
+ "source": "Hepsiburada",
246
+ "reason": "Hassas ciltler için leke karşıtı bakım"
247
+ },
248
+ # --- AMAZON ---
249
+ {
250
+ "title": "Murad Rapid Age Spot Serum",
251
+ "image": "https://m.media-amazon.com/images/I/61dFgPqK8oL._SL1000_.jpg",
252
+ "price": "₺1.199",
253
+ "link": "https://www.amazon.com.tr/Murad-Rapid-Age-Spot-Correcting/dp/B002WTC5K2",
254
+ "source": "Amazon",
255
+ "reason": "Hızlı etkili leke karşıtı profesyonel serum"
256
+ },
257
+ {
258
+ "title": "CeraVe Skin Renewing Vitamin C Serum",
259
+ "image": "https://m.media-amazon.com/images/I/61XNGB8M7RL._SL1000_.jpg",
260
+ "price": "₺549",
261
+ "link": "https://www.amazon.com.tr/CeraVe-Vitamin-C-Serum-30ml/dp/B07PVNQF1R",
262
+ "source": "Amazon",
263
+ "reason": "Ceramid destekli C vitamini serumu"
264
+ },
265
  ],
266
+
267
  "Kırışıklık": [
268
+ # --- RETİNOL ---
269
+ {
270
+ "title": "The Ordinary Retinol 0.5% in Squalane",
271
+ "image": "https://cdn.dsmcdn.com/ty1478/product/media/images/prod/QC/20241001/11/retinol-05/1_org_zoom.jpg",
272
+ "price": "₺329",
273
+ "link": "https://www.trendyol.com/the-ordinary/retinol-0-5-in-squalane-30-ml-p-33962345",
274
+ "source": "Trendyol",
275
+ "reason": "Kırışıklıkları azaltan altın standart retinol"
276
+ },
277
+ {
278
+ "title": "La Roche-Posay Retinol B3 Serum",
279
+ "image": "https://cdn.dsmcdn.com/ty1534/product/media/images/prod/QC/20241105/10/lrp-retinol-b3/1_org_zoom.jpg",
280
+ "price": "₺899",
281
+ "link": "https://www.trendyol.com/la-roche-posay/retinol-b3-anti-aging-serum-30-ml-p-4781234",
282
+ "source": "Trendyol",
283
+ "reason": "Dermatoloji onaylı anti-aging serum"
284
+ },
285
+ # --- PEPTİT ---
286
+ {
287
+ "title": "The Ordinary Buffet",
288
+ "image": "https://cdn.dsmcdn.com/ty1412/product/media/images/prod/QC/20240815/14/buffet-serum/1_org_zoom.jpg",
289
+ "price": "₺449",
290
+ "link": "https://www.trendyol.com/the-ordinary/buffet-multi-technology-peptide-serum-30-ml-p-33963456",
291
+ "source": "Trendyol",
292
+ "reason": "Çoklu peptit formülü ile yaşlanma karşıtı"
293
+ },
294
+ {
295
+ "title": "Olay Regenerist Retinol 24 Gece Kremi",
296
+ "image": "https://cdn.dsmcdn.com/ty1356/product/media/images/prod/QC/20240620/09/olay-retinol/1_org_zoom.jpg",
297
+ "price": "₺499",
298
+ "link": "https://www.trendyol.com/olay/regenerist-retinol-24-gece-kremi-50-ml-p-67890123",
299
+ "source": "Trendyol",
300
+ "reason": "24 saat nemlendirme ve kırışıklık bakımı"
301
+ },
302
+ # --- HYALURONİK ASİT ---
303
+ {
304
+ "title": "Vichy Liftactiv Supreme Serum",
305
+ "image": "https://productimages.hepsiburada.net/s/52/375-375/110000034567890.jpg",
306
+ "price": "₺799",
307
+ "link": "https://www.hepsiburada.com/vichy-liftactiv-supreme-serum-30-ml-p-HBV00000ZXCVB",
308
+ "source": "Hepsiburada",
309
+ "reason": "Hyaluronik asit ile dolgunlaştırıcı etki"
310
+ },
311
+ {
312
+ "title": "Eucerin Hyaluron-Filler Gece Bakım",
313
+ "image": "https://productimages.hepsiburada.net/s/49/375-375/110000023456789.jpg",
314
+ "price": "₺679",
315
+ "link": "https://www.hepsiburada.com/eucerin-hyaluron-filler-gece-kremi-50-ml-p-HBV00000MNBVC",
316
+ "source": "Hepsiburada",
317
+ "reason": "Kırışıklıkları doldurur, cildi yeniler"
318
+ },
319
+ # --- AMAZON ---
320
+ {
321
+ "title": "Neutrogena Rapid Wrinkle Repair",
322
+ "image": "https://m.media-amazon.com/images/I/71aKxRHD6ZL._SL1500_.jpg",
323
+ "price": "₺599",
324
+ "link": "https://www.amazon.com.tr/Neutrogena-Rapid-Wrinkle-Repair-Retinol/dp/B004D24818",
325
+ "source": "Amazon",
326
+ "reason": "Retinol SA ile hızlı kırışıklık onarımı"
327
+ },
328
+ {
329
+ "title": "RoC Retinol Correxion Deep Wrinkle",
330
+ "image": "https://m.media-amazon.com/images/I/61Q9K8LQOFL._SL1000_.jpg",
331
+ "price": "₺449",
332
+ "link": "https://www.amazon.com.tr/RoC-Retinol-Correxion-Deep-Wrinkle/dp/B00027DMI8",
333
+ "source": "Amazon",
334
+ "reason": "Derin kırışıklıklar için güçlü formül"
335
+ },
336
+ {
337
+ "title": "No7 Lift & Luminate Triple Action Serum",
338
+ "image": "https://m.media-amazon.com/images/I/61wK8TqKnBL._SL1000_.jpg",
339
+ "price": "₺549",
340
+ "link": "https://www.amazon.com.tr/No7-Lift-Luminate-Triple-Action/dp/B00X5V4XCY",
341
+ "source": "Amazon",
342
+ "reason": "Üçlü etki: Sıkılaştırır, aydınlatır, pürüzsüzleştirir"
343
+ },
344
  ],
345
+
346
  "Kuruluk": [
347
+ # --- NEMLENDİRİCİLER ---
348
+ {
349
+ "title": "CeraVe Nemlendirici Krem 454g",
350
+ "image": "https://cdn.dsmcdn.com/ty1523/product/media/images/prod/QC/20241030/11/cerave-cream/1_org_zoom.jpg",
351
+ "price": "₺549",
352
+ "link": "https://www.trendyol.com/cerave/nemlendirici-krem-454-g-p-127892345",
353
+ "source": "Trendyol",
354
+ "reason": "Ceramid içerikli yoğun nemlendirici, kuru ciltler için ideal"
355
+ },
356
+ {
357
+ "title": "La Roche-Posay Lipikar Baume AP+M",
358
+ "image": "https://cdn.dsmcdn.com/ty1567/product/media/images/prod/QC/20241112/14/lipikar-baume/1_org_zoom.jpg",
359
+ "price": "₺599",
360
+ "link": "https://www.trendyol.com/la-roche-posay/lipikar-baume-ap-m-400-ml-p-4782345",
361
+ "source": "Trendyol",
362
+ "reason": "Aşırı kuru ve atopik ciltler için yoğun bakım"
363
+ },
364
+ {
365
+ "title": "The Ordinary Hyaluronic Acid 2% + B5",
366
+ "image": "https://cdn.dsmcdn.com/ty1489/product/media/images/prod/QC/20241010/09/ha-b5/1_org_zoom.jpg",
367
+ "price": "₺249",
368
+ "link": "https://www.trendyol.com/the-ordinary/hyaluronic-acid-2-b5-30-ml-p-33964567",
369
+ "source": "Trendyol",
370
+ "reason": "Cildi derinlemesine nemlendirir"
371
+ },
372
+ {
373
+ "title": "Avene Hydrance Aqua Gel 50ml",
374
+ "image": "https://cdn.dsmcdn.com/ty1434/product/media/images/prod/QC/20240905/10/avene-hydrance/1_org_zoom.jpg",
375
+ "price": "₺479",
376
+ "link": "https://www.trendyol.com/avene/hydrance-aqua-gel-50-ml-p-23456789",
377
+ "source": "Trendyol",
378
+ "reason": "Hafif formül, yoğun nemlendirme"
379
+ },
380
+ # --- HEPSIBURADA ---
381
+ {
382
+ "title": "Bioderma Atoderm Intensive Baume 500ml",
383
+ "image": "https://productimages.hepsiburada.net/s/51/375-375/110000031234567.jpg",
384
+ "price": "₺529",
385
+ "link": "https://www.hepsiburada.com/bioderma-atoderm-intensive-baume-500-ml-p-HBV00000QAZWS",
386
+ "source": "Hepsiburada",
387
+ "reason": "Yoğun nemlendirici, cilt bariyerini onarır"
388
+ },
389
+ {
390
+ "title": "Uriage Xemose Lipid Replenishing Cream",
391
+ "image": "https://productimages.hepsiburada.net/s/47/375-375/110000009876543.jpg",
392
+ "price": "₺449",
393
+ "link": "https://www.hepsiburada.com/uriage-xemose-cream-400-ml-p-HBV00000EDCRF",
394
+ "source": "Hepsiburada",
395
+ "reason": "Çok kuru ciltler için lipid doldurucu krem"
396
+ },
397
+ # --- AMAZON ---
398
+ {
399
+ "title": "First Aid Beauty Ultra Repair Cream",
400
+ "image": "https://m.media-amazon.com/images/I/61K0xmJHzXL._SL1000_.jpg",
401
+ "price": "₺699",
402
+ "link": "https://www.amazon.com.tr/First-Aid-Beauty-Ultra-Repair/dp/B0049PAEOS",
403
+ "source": "Amazon",
404
+ "reason": "Anında rahatlatıcı yoğun nemlendirici"
405
+ },
406
+ {
407
+ "title": "Weleda Skin Food Original 75ml",
408
+ "image": "https://m.media-amazon.com/images/I/61jqL1cPQOL._SL1000_.jpg",
409
+ "price": "₺329",
410
+ "link": "https://www.amazon.com.tr/Weleda-Skin-Food-Original-75ml/dp/B000ORV3NC",
411
+ "source": "Amazon",
412
+ "reason": "Doğal içerikli kuru cilt kurtarıcısı"
413
+ },
414
  ],
415
+
416
  "Kızarıklık": [
417
+ {
418
+ "title": "La Roche-Posay Rosaliac AR Intense",
419
+ "image": "https://cdn.dsmcdn.com/ty1545/product/media/images/prod/QC/20241108/11/rosaliac/1_org_zoom.jpg",
420
+ "price": "₺549",
421
+ "link": "https://www.trendyol.com/la-roche-posay/rosaliac-ar-intense-40-ml-p-4783456",
422
+ "source": "Trendyol",
423
+ "reason": "Kızarıklık ve rosacea için özel formül"
424
+ },
425
+ {
426
+ "title": "Avene Antirougeurs Calm Soothing Mask",
427
+ "image": "https://cdn.dsmcdn.com/ty1412/product/media/images/prod/QC/20240815/12/avene-mask/1_org_zoom.jpg",
428
+ "price": "₺389",
429
+ "link": "https://www.trendyol.com/avene/antirougeurs-calm-mask-50-ml-p-34567890",
430
+ "source": "Trendyol",
431
+ "reason": "Yatıştırıcı maske, anında rahatlama"
432
+ },
433
+ {
434
+ "title": "The Ordinary Azelaic Acid Suspension 10%",
435
+ "image": "https://cdn.dsmcdn.com/ty1467/product/media/images/prod/QC/20240928/10/azelaic/1_org_zoom.jpg",
436
+ "price": "₺279",
437
+ "link": "https://www.trendyol.com/the-ordinary/azelaic-acid-suspension-10-30-ml-p-33965678",
438
+ "source": "Trendyol",
439
+ "reason": "Kızarıklık ve sivilce izleri için etkili"
440
+ },
441
+ {
442
+ "title": "Bioderma Sensibio AR Creme 40ml",
443
+ "image": "https://productimages.hepsiburada.net/s/53/375-375/110000041234567.jpg",
444
+ "price": "₺429",
445
+ "link": "https://www.hepsiburada.com/bioderma-sensibio-ar-creme-40-ml-p-HBV00000TGBNM",
446
+ "source": "Hepsiburada",
447
+ "reason": "Hassas ve kızarık ciltler için günlük bakım"
448
+ },
449
+ {
450
+ "title": "Eucerin AntiRedness Concealing Day Care SPF25",
451
+ "image": "https://productimages.hepsiburada.net/s/50/375-375/110000028765432.jpg",
452
+ "price": "₺549",
453
+ "link": "https://www.hepsiburada.com/eucerin-antiredness-concealing-day-care-50-ml-p-HBV00000YHNUJ",
454
+ "source": "Hepsiburada",
455
+ "reason": "Kızarıklığı kapatır ve güneşten korur"
456
+ },
457
+ # --- AMAZON ---
458
+ {
459
+ "title": "Dr. Jart+ Cicapair Tiger Grass Cream",
460
+ "image": "https://m.media-amazon.com/images/I/61dCJSy9c2L._SL1000_.jpg",
461
+ "price": "₺799",
462
+ "link": "https://www.amazon.com.tr/Dr-Jart-Cicapair-Tiger-Grass/dp/B01LWTT5ZW",
463
+ "source": "Amazon",
464
+ "reason": "Centella ile kızarıklık giderici Kore bakımı"
465
+ },
466
  ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
 
468
+ "Yaygın Kızarıklık": [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
469
  {
470
+ "title": "La Roche-Posay Rosaliac UV Riche SPF15",
471
+ "image": "https://cdn.dsmcdn.com/ty1534/product/media/images/prod/QC/20241105/09/rosaliac-uv/1_org_zoom.jpg",
472
+ "price": "₺499",
473
+ "link": "https://www.trendyol.com/la-roche-posay/rosaliac-uv-riche-40-ml-p-4784567",
474
+ "source": "Trendyol",
475
+ "reason": "Rosacea için SPF korumaalı günlük bakım"
476
  },
477
  {
478
+ "title": "Avene Antirougeurs Fort Concentrate",
479
+ "image": "https://cdn.dsmcdn.com/ty1423/product/media/images/prod/QC/20240825/10/avene-fort/1_org_zoom.jpg",
480
+ "price": "₺459",
481
+ "link": "https://www.trendyol.com/avene/antirougeurs-fort-30-ml-p-45678012",
482
+ "source": "Trendyol",
483
+ "reason": "Yoğun kızarıklık için konsantre bakım"
484
  },
485
  {
486
+ "title": "Paula's Choice Calm Redness Relief Moisturizer",
487
+ "image": "https://m.media-amazon.com/images/I/51Y8yG9GLOL._SL1000_.jpg",
488
+ "price": "₺649",
489
+ "link": "https://www.amazon.com.tr/Paulas-Choice-Redness-Relief-Moisturizer/dp/B00949CTAS",
490
+ "source": "Amazon",
491
+ "reason": "Hassas, kızarık ciltler için sakinleştirici nemlendirici"
492
+ },
493
+ ],
494
+ }
495
 
496
+ # =============================================================================
497
+ # HELPER FUNCTIONS
498
+ # =============================================================================
499
+
500
+ def get_products_for_issue(issue, skin_type_code, limit=15):
501
+ """Get curated products for a specific issue"""
502
+ products = CURATED_PRODUCTS.get(issue, [])
503
 
504
+ # Shuffle to show variety
505
+ shuffled = products.copy()
506
+ random.shuffle(shuffled)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
507
 
508
+ # Add skin type specific message
509
+ skin_type_text = CILT_TIPI_TR.get(skin_type_code, "")
 
 
 
 
 
 
510
 
511
+ result = []
512
+ for p in shuffled[:limit]:
513
+ product = p.copy()
514
+ # Add personalized recommendation
515
+ product["recommendation"] = f"{skin_type_text} için önerilen: {p['reason']}"
516
+ result.append(product)
517
 
518
+ return result
519
 
520
  # --- KALİTE KONTROL ---
521
  def check_image_quality(image_bytes):
 
562
  for issue in unique_issues:
563
  if added_steps >= 3: break
564
  issue_lower = issue.lower()
565
+ if "sivilce" in issue_lower:
566
  evening.insert(1, "Akne karşıtı tonik veya serum kullan (Lokal uygulama)")
567
  added_steps += 1
568
+ elif "kırışıklık" in issue_lower:
569
  evening.append("Retinol veya Peptit içerikli serum kullan")
570
  added_steps += 1
571
+ elif "leke" in issue_lower:
572
  morning.insert(2, "C Vitamini serumu ile leke görünümünü azalt")
573
  added_steps += 1
574
+ elif "kızarıklık" in issue_lower:
575
  morning.append("Yatıştırıcı (Niacinamide/Aloe Vera) serum kullan")
576
  added_steps += 1
577
 
 
590
  except: return "KARMA"
591
 
592
  @app.get("/")
593
+ def home(): return {"status": "Pure Sense API v10 (Curated Products)"}
594
 
595
  @app.post("/analyze")
596
  async def analyze_skin(file: UploadFile = File(...), is_premium: bool = Form(False)):
 
660
  except Exception as e:
661
  print(f"OWL Error: {e}")
662
 
663
+ # Generate Products from CURATED DATABASE
664
  skin_type_text = CILT_TIPI_TR.get(skin_type_code, "Hassas Cilt")
665
  prescriptions = []
666
 
667
  if issues_found:
668
+ for issue in issues_found:
669
+ products = get_products_for_issue(issue, skin_type_code, limit=15)
670
+ if products:
671
+ prescriptions.append({
672
+ "title": f"✨ {issue} için Önerilen Ürünler",
673
+ "subtitle": f"{skin_type_text} tipine uygun, uzman seçimi ürünler",
674
+ "products": products
675
+ })
676
+ else:
677
+ # Default products for general skin care
678
+ prescriptions.append({
679
+ "title": "✨ Genel Cilt Bakımı Önerileri",
680
+ "subtitle": f"{skin_type_text} için temel bakım ürünleri",
681
+ "products": get_products_for_issue("Kuruluk" if "KURU" in skin_type_code else "Sivilce", skin_type_code, limit=10)
682
+ })
 
 
 
 
 
 
 
 
683
 
684
  # Generate Dynamic Routine
685
  daily_routine = generate_dynamic_routine(skin_type_code, issues_found)
 
687
  return {
688
  "error": False,
689
  "skin_type": skin_type_code,
690
+ "skin_type_text": skin_type_text,
691
  "detections": detections,
692
  "prescriptions": prescriptions,
693
  "daily_routine": daily_routine,
694
+ "is_premium_response": is_premium,
695
+ "message": f"Cildini analiz ettik! {skin_type_text} tipine sahipsin. Aşağıdaki ürünleri senin için seçtik."
696
  }
697
 
698
  except Exception as e:
 
700
  return {
701
  "error": False,
702
  "skin_type": "KARMA",
703
+ "skin_type_text": "Karma Cilt",
704
  "detections": [],
705
  "prescriptions": [],
706
  "daily_routine": generate_dynamic_routine("KARMA", []),