From 740c3d7516aae9c211dcb138a8f4ceb9cc392c2d Mon Sep 17 00:00:00 2001 From: Gilles Soulier Date: Sun, 18 Jan 2026 06:26:17 +0100 Subject: [PATCH] before claude --- CHANGELOG.md | 5 +- README.md | 2 + TODO.md | 1 + analytics-ui/app.py | 324 +++++++ docker-compose.yml | 30 + pgadmin-servers.json | 14 + pricewatch.egg-info/PKG-INFO | 52 +- pricewatch.egg-info/SOURCES.txt | 1 + pricewatch/app/api/main.py | 168 +++- pricewatch/app/api/schemas.py | 45 + .../core/__pycache__/schema.cpython-313.pyc | Bin 8730 -> 10534 bytes pricewatch/app/core/schema.py | 45 + .../app/db/__pycache__/models.cpython-313.pyc | Bin 14099 -> 16913 bytes .../db/__pycache__/repository.cpython-313.pyc | Bin 8005 -> 10585 bytes ...014e51c4927_ajout_champs_amazon_produit.py | 350 +++++++ ...467e98fcbea_ajout_champs_amazon_produit.py | 28 + .../20260117_03_classification_rules.py | 114 +++ ...e68b0f0c9e4_ajout_champs_amazon_produit.py | 28 + ...jout_champs_amazon_produit.cpython-313.pyc | Bin 0 -> 13633 bytes ...jout_champs_amazon_produit.cpython-313.pyc | Bin 0 -> 749 bytes .../20260114_02_webhooks.cpython-313.pyc | Bin 0 -> 2090 bytes ...0260115_02_product_details.cpython-313.pyc | Bin 0 -> 1341 bytes ...17_03_classification_rules.cpython-313.pyc | Bin 0 -> 4345 bytes ...jout_champs_amazon_produit.cpython-313.pyc | Bin 0 -> 749 bytes pricewatch/app/db/models.py | 69 ++ pricewatch/app/db/repository.py | 55 +- .../__pycache__/pipeline.cpython-313.pyc | Bin 2779 -> 2948 bytes pricewatch/app/scraping/pipeline.py | 9 +- .../amazon/__pycache__/store.cpython-313.pyc | Bin 17722 -> 24861 bytes pricewatch/app/stores/amazon/selectors.yml | 32 + pricewatch/app/stores/amazon/store.py | 201 ++++- pricewatch/app/tasks/scheduler.py | 10 + pricewatch/app/tasks/scrape.py | 30 + webui/dist/assets/fa-brands-400-D1LuMI3I.ttf | Bin 0 -> 210792 bytes .../dist/assets/fa-brands-400-D_cYUPeE.woff2 | Bin 0 -> 118684 bytes .../dist/assets/fa-regular-400-BjRzuEpd.woff2 | Bin 0 -> 25472 bytes webui/dist/assets/fa-regular-400-DZaxPHgR.ttf | Bin 0 -> 68064 bytes webui/dist/assets/fa-solid-900-CTAAxXor.woff2 | Bin 0 -> 158220 bytes webui/dist/assets/fa-solid-900-D0aA9rwL.ttf | Bin 0 -> 426112 bytes .../assets/fa-v4compatibility-C9RhG_FT.woff2 | Bin 0 -> 4796 bytes .../assets/fa-v4compatibility-CCth-dXg.ttf | Bin 0 -> 10836 bytes webui/dist/assets/index-BURbFjJa.css | 5 + webui/dist/assets/index-ZvFbjZEA.js | 18 + webui/dist/favicon.svg | 5 + webui/dist/index.html | 14 + webui/src/App.vue | 854 ++++++++++++------ webui/src/assets/stores/aliexpress.svg | 55 +- webui/src/assets/stores/amazon.svg | 55 +- webui/src/assets/stores/backmarket.svg | 55 +- webui/src/assets/stores/cdiscount.svg | 55 +- webui/src/components/CardActions.vue | 144 +++ webui/src/components/MiniLineChart.vue | 18 +- webui/src/components/PriceBlock.vue | 319 +++++++ webui/src/components/PriceHistoryHover.vue | 2 +- webui/src/components/ProductCard.vue | 600 ++++++++++++ webui/src/components/ProductSummary.vue | 200 ++++ webui/src/index.css | 113 ++- webui/src/types/api.ts | 28 + webui/src/types/app.ts | 12 +- webui/tsconfig.json | 4 +- 60 files changed, 3815 insertions(+), 354 deletions(-) create mode 100644 pgadmin-servers.json create mode 100644 pricewatch/app/db/migrations/versions/0014e51c4927_ajout_champs_amazon_produit.py create mode 100644 pricewatch/app/db/migrations/versions/1467e98fcbea_ajout_champs_amazon_produit.py create mode 100644 pricewatch/app/db/migrations/versions/20260117_03_classification_rules.py create mode 100644 pricewatch/app/db/migrations/versions/3e68b0f0c9e4_ajout_champs_amazon_produit.py create mode 100644 pricewatch/app/db/migrations/versions/__pycache__/0014e51c4927_ajout_champs_amazon_produit.cpython-313.pyc create mode 100644 pricewatch/app/db/migrations/versions/__pycache__/1467e98fcbea_ajout_champs_amazon_produit.cpython-313.pyc create mode 100644 pricewatch/app/db/migrations/versions/__pycache__/20260114_02_webhooks.cpython-313.pyc create mode 100644 pricewatch/app/db/migrations/versions/__pycache__/20260115_02_product_details.cpython-313.pyc create mode 100644 pricewatch/app/db/migrations/versions/__pycache__/20260117_03_classification_rules.cpython-313.pyc create mode 100644 pricewatch/app/db/migrations/versions/__pycache__/3e68b0f0c9e4_ajout_champs_amazon_produit.cpython-313.pyc create mode 100644 webui/dist/assets/fa-brands-400-D1LuMI3I.ttf create mode 100644 webui/dist/assets/fa-brands-400-D_cYUPeE.woff2 create mode 100644 webui/dist/assets/fa-regular-400-BjRzuEpd.woff2 create mode 100644 webui/dist/assets/fa-regular-400-DZaxPHgR.ttf create mode 100644 webui/dist/assets/fa-solid-900-CTAAxXor.woff2 create mode 100644 webui/dist/assets/fa-solid-900-D0aA9rwL.ttf create mode 100644 webui/dist/assets/fa-v4compatibility-C9RhG_FT.woff2 create mode 100644 webui/dist/assets/fa-v4compatibility-CCth-dXg.ttf create mode 100644 webui/dist/assets/index-BURbFjJa.css create mode 100644 webui/dist/assets/index-ZvFbjZEA.js create mode 100644 webui/dist/favicon.svg create mode 100644 webui/dist/index.html create mode 100644 webui/src/components/CardActions.vue create mode 100644 webui/src/components/PriceBlock.vue create mode 100644 webui/src/components/ProductCard.vue create mode 100644 webui/src/components/ProductSummary.vue diff --git a/CHANGELOG.md b/CHANGELOG.md index 623e305..f6693cd 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,11 +53,14 @@ Le format est basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.0.0/) - Web UI: popup ajout produit central + favicon - API: logs Uvicorn exposes pour l UI - Parsing prix: gestion des separateurs de milliers (espace, NBSP, point) -- API/DB: description + msrp + images/specs exposes, reduction calculee +- API/DB: exposition des champs Amazon enrichis (note, badge, stock texte, modele) +- Web UI: carte produit analytique avec resume, historique plein format et actions compactes +- Web UI: slider colonnes responsive + modal ajout produit scrollable avec footer sticky ### Corrigé - Migration Alembic: down_revision aligne sur 20260114_02 - Amazon: extraction images via data-a-dynamic-image + filtrage logos +- API: suppression du calcul automatique des reductions (valeurs explicites uniquement) --- diff --git a/README.md b/README.md index c2c7800..e47d482 100755 --- a/README.md +++ b/README.md @@ -152,6 +152,8 @@ Guide de migration JSON -> DB: `MIGRATION_GUIDE.md` L'API est protegee par un token simple. +Note: l endpoint `/products` expose des champs Amazon explicites (asin, note, badge Choix d Amazon, stock_text/in_stock, model_number/model_name, main_image/gallery_images). Les reductions ne sont plus calculees cote API. + ```bash export PW_API_TOKEN=change_me docker compose up -d api diff --git a/TODO.md b/TODO.md index e9770d6..971a785 100755 --- a/TODO.md +++ b/TODO.md @@ -170,6 +170,7 @@ Liste des tâches priorisées pour le développement de PriceWatch. - [x] Tests performance (100+ produits) - [x] CRUD produits - [x] Historique prix +- [ ] Ajouter migration DB pour les nouveaux champs Amazon (note, badge, stock texte, modele) ### Documentation - [x] Migration guide (JSON -> DB) diff --git a/analytics-ui/app.py b/analytics-ui/app.py index e3883ef..e54180b 100644 --- a/analytics-ui/app.py +++ b/analytics-ui/app.py @@ -76,6 +76,81 @@ def _serialize_decimal(value): return value +def fetch_product_history(product_id: int) -> Tuple[List[Dict[str, Any]], Optional[str]]: + """Récupère l'historique complet des scraps pour un produit.""" + rows: List[Dict[str, Any]] = [] + try: + with get_db_connection() as conn: + with conn.cursor(cursor_factory=RealDictCursor) as cur: + cur.execute( + """ + SELECT + ph.id, + ph.price, + ph.shipping_cost, + ph.stock_status, + ph.fetch_method, + ph.fetch_status, + ph.fetched_at + FROM price_history ph + WHERE ph.product_id = %s + ORDER BY ph.fetched_at DESC + """, + (product_id,), + ) + fetched = cur.fetchall() + for item in fetched: + serialized = {key: _serialize_decimal(value) for key, value in item.items()} + if serialized.get("fetched_at"): + serialized["fetched_at"] = serialized["fetched_at"].strftime( + "%Y-%m-%d %H:%M:%S" + ) + rows.append(serialized) + return rows, None + except Exception as exc: + return rows, str(exc) + + +def fetch_all_price_history(limit: int = 500) -> Tuple[List[Dict[str, Any]], Optional[str]]: + """Récupère toutes les entrées de price_history avec infos produit.""" + rows: List[Dict[str, Any]] = [] + try: + with get_db_connection() as conn: + with conn.cursor(cursor_factory=RealDictCursor) as cur: + cur.execute( + """ + SELECT + ph.id, + ph.product_id, + p.source, + p.reference, + p.title, + ph.price, + ph.shipping_cost, + ph.stock_status, + ph.fetch_method, + ph.fetch_status, + ph.fetched_at + FROM price_history ph + LEFT JOIN products p ON p.id = ph.product_id + ORDER BY ph.fetched_at DESC + LIMIT %s + """, + (limit,), + ) + fetched = cur.fetchall() + for item in fetched: + serialized = {key: _serialize_decimal(value) for key, value in item.items()} + if serialized.get("fetched_at"): + serialized["fetched_at"] = serialized["fetched_at"].strftime( + "%Y-%m-%d %H:%M:%S" + ) + rows.append(serialized) + return rows, None + except Exception as exc: + return rows, str(exc) + + def fetch_products_list(limit: int = 200) -> Tuple[List[Dict[str, Any]], Optional[str]]: rows: List[Dict[str, Any]] = [] try: @@ -260,6 +335,68 @@ TEMPLATE = """ +
+

Historique complet des scraps

+
+
+ + +
+
+ + + + + + + + + + + + + + +
DatePrixFrais portStockMéthodeStatut
Sélectionnez un produit puis cliquez sur "Charger l'historique"
+
+
+
+
+

Parcourir la table price_history

+
+
+ + + + 0 / 0 + +
+
+
ID
+
-
+
Product ID
+
-
+
Store
+
-
+
Référence
+
-
+
Titre produit
+
-
+
Prix
+
-
+
Frais de port
+
-
+
Stock
+
-
+
Méthode
+
-
+
Statut
+
-
+
Date scraping
+
-
+
+
+
@@ -377,5 +685,21 @@ def products_json(): return jsonify(products) +@app.route("/product//history.json") +def product_history_json(product_id: int): + history, error = fetch_product_history(product_id) + if error: + return jsonify({"error": error}), 500 + return jsonify(history) + + +@app.route("/price_history.json") +def all_price_history_json(): + history, error = fetch_all_price_history() + if error: + return jsonify({"error": error}), 500 + return jsonify(history) + + if __name__ == "__main__": app.run(host="0.0.0.0", port=80) diff --git a/docker-compose.yml b/docker-compose.yml index 23a7229..9860185 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,6 +33,19 @@ services: depends_on: - postgres - redis + + worker: + build: . + command: python -m pricewatch.app.cli.main worker + env_file: + - .env + environment: + PW_DB_HOST: postgres + PW_REDIS_HOST: redis + TZ: Europe/Paris + depends_on: + - postgres + - redis frontend: build: ./webui @@ -75,6 +88,23 @@ services: depends_on: - postgres + pgadmin: + image: dpage/pgadmin4:latest + ports: + - "8072:80" + environment: + TZ: Europe/Paris + PGADMIN_DEFAULT_EMAIL: admin@pricewatch.dev + PGADMIN_DEFAULT_PASSWORD: pricewatch + PGADMIN_CONFIG_SERVER_MODE: "False" + PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: "False" + volumes: + - pricewatch_pgadmin:/var/lib/pgadmin + - ./pgadmin-servers.json:/pgadmin4/servers.json:ro + depends_on: + - postgres + volumes: pricewatch_pgdata: pricewatch_redisdata: + pricewatch_pgadmin: diff --git a/pgadmin-servers.json b/pgadmin-servers.json new file mode 100644 index 0000000..72931a0 --- /dev/null +++ b/pgadmin-servers.json @@ -0,0 +1,14 @@ +{ + "Servers": { + "1": { + "Name": "PriceWatch PostgreSQL", + "Group": "Servers", + "Host": "postgres", + "Port": 5432, + "MaintenanceDB": "pricewatch", + "Username": "pricewatch", + "PassFile": "/pgadmin4/pgpass", + "SSLMode": "prefer" + } + } +} diff --git a/pricewatch.egg-info/PKG-INFO b/pricewatch.egg-info/PKG-INFO index ac434d9..8affc0d 100644 --- a/pricewatch.egg-info/PKG-INFO +++ b/pricewatch.egg-info/PKG-INFO @@ -196,6 +196,8 @@ Guide de migration JSON -> DB: `MIGRATION_GUIDE.md` L'API est protegee par un token simple. +Note: l endpoint `/products` expose des champs Amazon explicites (asin, note, badge Choix d Amazon, stock_text/in_stock, model_number/model_name, main_image/gallery_images). Les reductions ne sont plus calculees cote API. + ```bash export PW_API_TOKEN=change_me docker compose up -d api @@ -204,8 +206,54 @@ docker compose up -d api Exemples: ```bash -curl -H "Authorization: Bearer $PW_API_TOKEN" http://localhost:8000/products -curl http://localhost:8000/health +curl -H "Authorization: Bearer $PW_API_TOKEN" http://localhost:8001/products +curl http://localhost:8001/health +``` + +Filtres (exemples rapides): + +```bash +curl -H "Authorization: Bearer $PW_API_TOKEN" \\ + "http://localhost:8001/products?price_min=100&stock_status=in_stock" +curl -H "Authorization: Bearer $PW_API_TOKEN" \\ + "http://localhost:8001/products/1/prices?fetch_status=success&fetched_after=2026-01-14T00:00:00" +curl -H "Authorization: Bearer $PW_API_TOKEN" \\ + "http://localhost:8001/logs?fetch_status=failed&fetched_before=2026-01-15T00:00:00" +``` + +Exports (CSV/JSON): + +```bash +curl -H "Authorization: Bearer $PW_API_TOKEN" \\ + "http://localhost:8001/products/export?format=csv" +curl -H "Authorization: Bearer $PW_API_TOKEN" \\ + "http://localhost:8001/logs/export?format=json" +``` + +CRUD (examples rapides): + +```bash +curl -H "Authorization: Bearer $PW_API_TOKEN" -X POST http://localhost:8001/products \\ + -H "Content-Type: application/json" \\ + -d '{"source":"amazon","reference":"REF1","url":"https://example.com"}' +``` + +Webhooks (exemples rapides): + +```bash +curl -H "Authorization: Bearer $PW_API_TOKEN" -X POST http://localhost:8001/webhooks \\ + -H "Content-Type: application/json" \\ + -d '{"event":"price_changed","url":"https://example.com/webhook","enabled":true}' +curl -H "Authorization: Bearer $PW_API_TOKEN" -X POST http://localhost:8001/webhooks/1/test +``` + +## Web UI (Phase 4) + +Interface Vue 3 dense avec themes Gruvbox/Monokai, header fixe, sidebar filtres, et split compare. + +```bash +docker compose up -d frontend +# Acces: http://localhost:3000 ``` ## Configuration (scrap_url.yaml) diff --git a/pricewatch.egg-info/SOURCES.txt b/pricewatch.egg-info/SOURCES.txt index 48f824a..fab1309 100755 --- a/pricewatch.egg-info/SOURCES.txt +++ b/pricewatch.egg-info/SOURCES.txt @@ -22,6 +22,7 @@ pricewatch/app/scraping/pipeline.py pricewatch/app/scraping/pw_fetch.py pricewatch/app/stores/__init__.py pricewatch/app/stores/base.py +pricewatch/app/stores/price_parser.py pricewatch/app/stores/amazon/__init__.py pricewatch/app/stores/amazon/store.py pricewatch/app/stores/cdiscount/__init__.py diff --git a/pricewatch/app/api/main.py b/pricewatch/app/api/main.py index e3ec42e..06d2b19 100644 --- a/pricewatch/app/api/main.py +++ b/pricewatch/app/api/main.py @@ -22,6 +22,10 @@ from sqlalchemy.orm import Session from pricewatch.app.api.schemas import ( BackendLogEntry, + ClassificationOptionsOut, + ClassificationRuleCreate, + ClassificationRuleOut, + ClassificationRuleUpdate, EnqueueRequest, EnqueueResponse, HealthStatus, @@ -52,7 +56,8 @@ from pricewatch.app.core.config import get_config from pricewatch.app.core.logging import get_logger from pricewatch.app.core.schema import ProductSnapshot from pricewatch.app.db.connection import check_db_connection, get_session -from pricewatch.app.db.models import PriceHistory, Product, ScrapingLog, Webhook +from pricewatch.app.db.models import ClassificationRule, PriceHistory, Product, ScrapingLog, Webhook +from pricewatch.app.db.repository import ProductRepository from pricewatch.app.scraping.pipeline import ScrapingPipeline from pricewatch.app.tasks.scrape import scrape_product from pricewatch.app.tasks.scheduler import RedisUnavailableError, check_redis_connection, ScrapingScheduler @@ -188,6 +193,7 @@ def create_product( url=payload.url, title=payload.title, category=payload.category, + type=payload.type, description=payload.description, currency=payload.currency, msrp=payload.msrp, @@ -241,6 +247,129 @@ def update_product( return _product_to_out(session, product) +@app.get( + "/classification/rules", + response_model=list[ClassificationRuleOut], + dependencies=[Depends(require_token)], +) +def list_classification_rules( + session: Session = Depends(get_db_session), +) -> list[ClassificationRuleOut]: + """Liste les regles de classification.""" + rules = ( + session.query(ClassificationRule) + .order_by(ClassificationRule.sort_order, ClassificationRule.id) + .all() + ) + return [ + ClassificationRuleOut( + id=rule.id, + category=rule.category, + type=rule.type, + keywords=rule.keywords or [], + sort_order=rule.sort_order, + is_active=rule.is_active, + ) + for rule in rules + ] + + +@app.post( + "/classification/rules", + response_model=ClassificationRuleOut, + dependencies=[Depends(require_token)], +) +def create_classification_rule( + payload: ClassificationRuleCreate, + session: Session = Depends(get_db_session), +) -> ClassificationRuleOut: + """Cree une regle de classification.""" + rule = ClassificationRule( + category=payload.category, + type=payload.type, + keywords=payload.keywords, + sort_order=payload.sort_order or 0, + is_active=True if payload.is_active is None else payload.is_active, + ) + session.add(rule) + session.commit() + session.refresh(rule) + return ClassificationRuleOut( + id=rule.id, + category=rule.category, + type=rule.type, + keywords=rule.keywords or [], + sort_order=rule.sort_order, + is_active=rule.is_active, + ) + + +@app.patch( + "/classification/rules/{rule_id}", + response_model=ClassificationRuleOut, + dependencies=[Depends(require_token)], +) +def update_classification_rule( + rule_id: int, + payload: ClassificationRuleUpdate, + session: Session = Depends(get_db_session), +) -> ClassificationRuleOut: + """Met a jour une regle de classification.""" + rule = session.query(ClassificationRule).filter(ClassificationRule.id == rule_id).one_or_none() + if not rule: + raise HTTPException(status_code=404, detail="Regle non trouvee") + updates = payload.model_dump(exclude_unset=True) + for key, value in updates.items(): + setattr(rule, key, value) + session.commit() + session.refresh(rule) + return ClassificationRuleOut( + id=rule.id, + category=rule.category, + type=rule.type, + keywords=rule.keywords or [], + sort_order=rule.sort_order, + is_active=rule.is_active, + ) + + +@app.delete( + "/classification/rules/{rule_id}", + dependencies=[Depends(require_token)], +) +def delete_classification_rule( + rule_id: int, + session: Session = Depends(get_db_session), +) -> dict[str, str]: + """Supprime une regle de classification.""" + rule = session.query(ClassificationRule).filter(ClassificationRule.id == rule_id).one_or_none() + if not rule: + raise HTTPException(status_code=404, detail="Regle non trouvee") + session.delete(rule) + session.commit() + return {"status": "deleted"} + + +@app.get( + "/classification/options", + response_model=ClassificationOptionsOut, + dependencies=[Depends(require_token)], +) +def get_classification_options( + session: Session = Depends(get_db_session), +) -> ClassificationOptionsOut: + """Expose la liste des categories et types issus des regles actives.""" + rules = ( + session.query(ClassificationRule) + .filter(ClassificationRule.is_active == True) + .order_by(ClassificationRule.sort_order, ClassificationRule.id) + .all() + ) + categories = sorted({rule.category for rule in rules if rule.category}) + types = sorted({rule.type for rule in rules if rule.type}) + return ClassificationOptionsOut(categories=categories, types=types) + + @app.delete("/products/{product_id}", dependencies=[Depends(require_token)]) def delete_product( product_id: int, @@ -703,6 +832,13 @@ def preview_scrape(payload: ScrapePreviewRequest) -> ScrapePreviewResponse: if snapshot is None: _add_backend_log("ERROR", f"Preview scraping KO: {payload.url}") return ScrapePreviewResponse(success=False, snapshot=None, error=result.get("error")) + config = get_config() + if config.enable_db: + try: + with get_session(config) as session: + ProductRepository(session).apply_classification(snapshot) + except Exception as exc: + snapshot.add_note(f"Classification ignoree: {exc}") return ScrapePreviewResponse( success=bool(result.get("success")), snapshot=snapshot.model_dump(mode="json"), @@ -719,7 +855,9 @@ def commit_scrape(payload: ScrapeCommitRequest) -> ScrapeCommitResponse: _add_backend_log("ERROR", "Commit scraping KO: snapshot invalide") raise HTTPException(status_code=400, detail="Snapshot invalide") from exc - product_id = ScrapingPipeline(config=get_config()).process_snapshot(snapshot, save_to_db=True) + product_id = ScrapingPipeline(config=get_config()).process_snapshot( + snapshot, save_to_db=True, apply_classification=False + ) _add_backend_log("INFO", f"Commit scraping OK: product_id={product_id}") return ScrapeCommitResponse(success=True, product_id=product_id) @@ -808,12 +946,9 @@ def _product_to_out(session: Session, product: Product) -> ProductOut: ) images = [image.image_url for image in product.images] specs = {spec.spec_key: spec.spec_value for spec in product.specs} - discount_amount = None - discount_percent = None - if latest and latest.price is not None and product.msrp: - discount_amount = float(product.msrp) - float(latest.price) - if product.msrp > 0: - discount_percent = (discount_amount / float(product.msrp)) * 100 + main_image = images[0] if images else None + gallery_images = images[1:] if len(images) > 1 else [] + asin = product.reference if product.source == "amazon" else None history_rows = ( session.query(PriceHistory) .filter(PriceHistory.product_id == product.id, PriceHistory.price != None) @@ -830,12 +965,23 @@ def _product_to_out(session: Session, product: Product) -> ProductOut: id=product.id, source=product.source, reference=product.reference, + asin=asin, url=product.url, title=product.title, category=product.category, + type=product.type, description=product.description, currency=product.currency, msrp=float(product.msrp) if product.msrp is not None else None, + rating_value=float(product.rating_value) if product.rating_value is not None else None, + rating_count=product.rating_count, + amazon_choice=product.amazon_choice, + amazon_choice_label=product.amazon_choice_label, + discount_text=product.discount_text, + stock_text=product.stock_text, + in_stock=product.in_stock, + model_number=product.model_number, + model_name=product.model_name, first_seen_at=product.first_seen_at, last_updated_at=product.last_updated_at, latest_price=float(latest.price) if latest and latest.price is not None else None, @@ -845,9 +991,11 @@ def _product_to_out(session: Session, product: Product) -> ProductOut: latest_stock_status=latest.stock_status if latest else None, latest_fetched_at=latest.fetched_at if latest else None, images=images, + main_image=main_image, + gallery_images=gallery_images, specs=specs, - discount_amount=discount_amount, - discount_percent=discount_percent, + discount_amount=None, + discount_percent=None, history=history_points, ) diff --git a/pricewatch/app/api/schemas.py b/pricewatch/app/api/schemas.py index dad001f..6ec6364 100644 --- a/pricewatch/app/api/schemas.py +++ b/pricewatch/app/api/schemas.py @@ -22,12 +22,23 @@ class ProductOut(BaseModel): id: int source: str reference: str + asin: Optional[str] = None url: str title: Optional[str] = None category: Optional[str] = None + type: Optional[str] = None description: Optional[str] = None currency: Optional[str] = None msrp: Optional[float] = None + rating_value: Optional[float] = None + rating_count: Optional[int] = None + amazon_choice: Optional[bool] = None + amazon_choice_label: Optional[str] = None + discount_text: Optional[str] = None + stock_text: Optional[str] = None + in_stock: Optional[bool] = None + model_number: Optional[str] = None + model_name: Optional[str] = None first_seen_at: datetime last_updated_at: datetime latest_price: Optional[float] = None @@ -35,6 +46,8 @@ class ProductOut(BaseModel): latest_stock_status: Optional[str] = None latest_fetched_at: Optional[datetime] = None images: list[str] = [] + main_image: Optional[str] = None + gallery_images: list[str] = [] specs: dict[str, str] = {} discount_amount: Optional[float] = None discount_percent: Optional[float] = None @@ -47,6 +60,7 @@ class ProductCreate(BaseModel): url: str title: Optional[str] = None category: Optional[str] = None + type: Optional[str] = None description: Optional[str] = None currency: Optional[str] = None msrp: Optional[float] = None @@ -56,6 +70,7 @@ class ProductUpdate(BaseModel): url: Optional[str] = None title: Optional[str] = None category: Optional[str] = None + type: Optional[str] = None description: Optional[str] = None currency: Optional[str] = None msrp: Optional[float] = None @@ -208,6 +223,36 @@ class VersionResponse(BaseModel): api_version: str +class ClassificationRuleOut(BaseModel): + id: int + category: Optional[str] = None + type: Optional[str] = None + keywords: list[str] = Field(default_factory=list) + sort_order: int = 0 + is_active: bool = True + + +class ClassificationRuleCreate(BaseModel): + category: Optional[str] = None + type: Optional[str] = None + keywords: list[str] = Field(default_factory=list) + sort_order: Optional[int] = 0 + is_active: Optional[bool] = True + + +class ClassificationRuleUpdate(BaseModel): + category: Optional[str] = None + type: Optional[str] = None + keywords: Optional[list[str]] = None + sort_order: Optional[int] = None + is_active: Optional[bool] = None + + +class ClassificationOptionsOut(BaseModel): + categories: list[str] = Field(default_factory=list) + types: list[str] = Field(default_factory=list) + + class BackendLogEntry(BaseModel): time: datetime level: str diff --git a/pricewatch/app/core/__pycache__/schema.cpython-313.pyc b/pricewatch/app/core/__pycache__/schema.cpython-313.pyc index 201237b690abdb9feb37f2f13d5278e2daa0828e..844bc6f18c0384b1e72388ed14a7b4142d4abcb2 100644 GIT binary patch delta 2498 zcmai$OH3PA6ox%!Yy!aq0uBaaJmzH{0Vf!TM?w+@=MA*wl8}cJXKW8&wIq_o?r=U!|&w2{i<_xODO ze|+w_v*2Ff;duGF#Zqd3zwQ^;c!%pr`STK^(WL!gYR=Y_UZqlKJ8DFh0i#?OEDsi& zz!=3+CNN4p7a)KQO)?jf{ENB8Pz524NYcT@Qv_Udpi!7aM5Pe=C=+Nz^{1sZgtepCXx zYzw+KcR5g?u**S`ZP#T}`wJMt2S~U>7arQAo#-H;yMvv<;$U&FF+cdBf&(2!^Z+Gy z1-sz_{iN!F3oQ0g`1avC_n;%eVl)g{8U^YMS7{$qwe~WLV{Z^UO|Nwx)m&xP_8#IG z*y6|^5jy6dpzkr__7eBd|GJN3cd9q&gI_;^PNGxjG#WvpXbio9tmsYTMQ@>TgwO;! z<1wPMXcC=6=evv01$5D4KtT_ME}_dP)NMvrx_9iM5DTl{2lI6H8c`UZQ0^n=HKGXl z)(<;~;vFCZ%*t)-;0W1{K^_1r1Hma`9Yir=+z!TRQrVCA&B|3$Ie@OoL$U4cLe^*b z$>^G^^`nzxj6crKNg|WvnJAx3NFpB=xE#$Uc~LV~w4`=S%qBP{sxk>#imJSlqZKI3 zRRy?YMCKC;57|7Ddtfwm7s!~Ta7=T8S|p zmZ80SIfILUB{8|_i%4opR8$8TkFe1g#|%$P{0(sDXHLk=nItDFISWe;5sCnha4G|V z5kAZb!g27BS}SyT+5Y`4`NVl&@qr-EHCg1o@hBE^E0pzxg4PC1Q}D~P?YenaVfgIB#;3F zH#;ONd;~6}49c7k64iK^lS$JtDXzD3HxdFL;T0}dnzyoXPCHz&`}~~!WSoWNC1hTV z@Cg?8{^vSN<18pS4_y;46#YmlKIRpX~Gt1=U=W4xfiYa(z-=FIrWmg#2rD3|P(CEPFpk}LvY z7)HidnX7@fijT4i7b*-*PMXZQwcjdh>$esk;~q&Y3W#R6zMH*o^;6byT*B|R9K;gB zaz*=n*BbSU_G67k-PA(10qR%nuI-_j9PA_QXswTWo_(iwCq=!leOT8|z0kg|`?l^1 zj`o4%%xogTiP3hWd=u9`(H_`+)JyGW``0zZ)Q_uoK?;uh+86a+>JM$LzKc4jdFWcr z>4?S1Xb5}Bd=vQT3>H6@vmiM-EJ=bqiNBx2avlqQ@#G6wE@C-^g&gh@e!2{jqoaI8 zDIE5J!`?rQk$~komKiL?Scb6N!tw!@J6Jx(au3U=cS>xUrJ>yT6`gf76j4??vsO{P z(m3?0$Y?ju2X3{cy|=qGo3kNR=Uk#!22Ve&8!41m>5*ry)+J@dfA*98LEx1{Myk z8&Vt54iAY2fOeQy=$b{_XH9np@)Gso9A(McwwjjU9AN60d$$?Po=jlRxMZx zkZB?C06@k(f8y43TDdJ2AfDF;TNwuW-+}XearEDPOSMsFz1M8WTMoU(LZGdFrDJph zj->-Imlk$D^O~(I)|ORM>zb+JCH$M^re`Kc+;m zIt0;GS0)KTeK3MhESSbC911dx{c&Jx^N+UNe1b-iJ@;Xa5 z*eNoLa#u^$e-`F&$qv^)j_vw1YI~xA)w{Y&#WI>#177gWLM_yRAL=0hB@l%D&;X4P zf&tc`J`UP^2o6I8j(Anj?k%WA&_Q3$O(V?#9y(bVE|>4h!%=xx zLGOQz-5)qwr|a)J*h7^KmDJcRORM0xEX>bPV^h-Z9?|Jg6 zu*{&1j3$S1ERl-EC+!IwADN1!u%A8>d84hC`ich;8YGWPnp8>3B|YSf&LE+E2o;@V z4|$40Ryh&BGK%qOQmhN3t5Q^_LVG<3Gl55e&oJE}nb3DAuhTI}Ug!hG$pSjw%nc)f zXem4?W|QAI!()xKVvL}YKIURIa6bcJFhB(J26{?9m3|WIH zBi*qUA(SMKY>nt8*|fbf4lrv2g{VkOM%*KrOT1kmccb^bgpyZVmi5aX list[str]: + """Filtre les URLs de galerie vides.""" + return [url.strip() for url in v if url and url.strip()] + model_config = ConfigDict( use_enum_values=True, json_schema_extra={ diff --git a/pricewatch/app/db/__pycache__/models.cpython-313.pyc b/pricewatch/app/db/__pycache__/models.cpython-313.pyc index eb11a166ea4ba1268d52a0b03a2b47d184f7b999..96c47fa004378688fcdfc74b0e0ddfa8478f569b 100644 GIT binary patch delta 4536 zcma)=drVu`9mjo*v5oPAhcU*yZZHo!JObg75FjLwkQX6|FL|vduCZ_624j1?>gtTMrP<|b)AgKD5;WgMw5gq zv6r=HAt8~F>M@hGH0ox4pDi7biQdxQ=(yrE6VBsgTsfE1nMF+Y9DAW%n+-7j*>kyy zI(*8jB=%x3Xy8okQfPo5jH#q!O6i!Aj4^C_i~^_~lq#c?Dub#@QDJ*IU}lO{P^>Zo zt4?8doMsKB*e%nn-9*(&XIam_o^7*4F7V&*LqYe-W#u|`T&Z+T_Y zCTbU@YBp10aC37StK}5-IOh)mrqqE9>L8_BU}7px z!}W3fomuwXP&>q_+NB3DoFK@s;V`F31sJUla2=_7n~bz_N9@`*DRJJ3T=@q#yE4 zjuM`A*YVf@T|Tcr&A5C)Zy==abGpZPwtw6wTnF&rq%-96CNxg^bhx0|#fJ=o!YJdHZ30TN9%wLB&xp|iGI9+%v>%4qfaE!4UDZzwp)6CVzr^tpKtIDtML-r(dY zPeK}SLPn=*z0*0#ivwyqb255M{WZfZh_|%8Oo#Z;SR(#Q8wvNpc9DLRLnwJDhd~mu zQJ>F42C#kv5?b*yosPLI zUad5Wf75BDf69tJ)%7xAxy0POqEycX7B8)3NzL-eq1oCw}yI@?bi%~*UN9^wmkK}7#7mk|P($ZB zbP%A1l%dv}jqyTDim`UAGyBAzCL<@8SlZWL-wT5*^2pKI%X1eN-1C>>+UnFGTn6|g zR=$`yzS@JXB>DBkdxAZ?`&PHpCE-)GnH^7D)P#(N0-Zd1<0|La> zNOZ~Y1LlYeI;=9%f>01;8YPV42Jtf>EUCu&WspSCX#!{Gr~qL~W||xh!cP&0BQCyc zoMgsDw$T_CkiCMEi$aa+utY5@u!J`ZxrUODGJ`UK@*2uFQE0T$Y0yBUF@}rSh$oVR z)kzeb8L2`klZdZZYEVnKTJ{^m6hc=~2*>~l zU@<5jEbpltgknNDUw}DNuJ%oBRE5oDT z!7*E$DZXD}VxEf26_=8J>)Xz61vvCw6zU#oX**XWy?`f6g$pDoUy5So1LhpAJo*+} z!pJW``a)<3eIufC2pLMSvCU&j)S$TzTrfkDFJ#Lmxi z>FpN5x=rk;C-OJ3_$~3L^}jtai^a^7)rk$%%F9odo^uiB6ny6fePd}?jfri}VlYjK9a2h2i5JpN=z_Lm>eJWkDW8K6Vl6BaqHYus(O6@wxpUPL#U4g&W5!=wpjPp`LC{QQS>{V9vAOBnU=q!s(SuuCKi;XQzk&(}rxx(%dud300Wc&)YPw+735nS>pU4sXj%4w9K|kTCcUb)F`2)_$sf5afZM@sz3?#~g>yFJX zqU%hWO;nV>q&sO{yr-E77k6*n28-bC!Oz0Fw`Y1niUykCZoWOyON4r6+uO5rtKsy` z@LkwvKW;@=M6!}^S<>GvzFoYO^Kt3&@V${=k1U`1Vo!`a{}pGCbM}~RBsSuR>0XT~ zUnORIXBo(lwF)vrQ}TB4ZQR53{-85cAWH8PI!C-A$Q=}VF?@ujpQA)k@=!iO@t|y^ zi@(Hb77D#DHojHiyV!_=LF?}Xd0Vn3m1Zj+DJ4bqk&}Nhm=}*M>%SO|8*GujS^2F0 zo!t8}+k@KH2TJWMxuIGZj@5TVepHvrpyPgp*~2Kp)4HX!rP^P}TF-$XhJKNNkf z7m^Y5$_o)hO>KO?sZkmu_wXGwMn1<94YL0uT2!ARjUtMd+SU|U8nV`i=h|bYGuU+w z1;76E>qFy;d@6Qzl&k&-jSyTC|FSsRaVCF^VeHJT`-y}Wo(yM+f9TlHRx{vg{Syg3 SpA0eZ4;f(oA;Bm0{C@yC%~zuU delta 2036 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 a(yyV!&9gs-hOX&<>Tfd^|3e{^=l=nkmR`mH diff --git a/pricewatch/app/db/migrations/versions/0014e51c4927_ajout_champs_amazon_produit.py b/pricewatch/app/db/migrations/versions/0014e51c4927_ajout_champs_amazon_produit.py new file mode 100644 index 0000000..6d2d9bf --- /dev/null +++ b/pricewatch/app/db/migrations/versions/0014e51c4927_ajout_champs_amazon_produit.py @@ -0,0 +1,350 @@ +"""Ajout champs Amazon produit + +Revision ID: 0014e51c4927 +Revises: 20260115_02_product_details +Create Date: 2026-01-17 19:23:01.866891 +""" + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# Revision identifiers, used by Alembic. +revision = '0014e51c4927' +down_revision = '20260115_02_product_details' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column('price_history', 'price', + existing_type=sa.NUMERIC(precision=10, scale=2), + comment='Product price', + existing_nullable=True) + op.alter_column('price_history', 'shipping_cost', + existing_type=sa.NUMERIC(precision=10, scale=2), + comment='Shipping cost', + existing_nullable=True) + op.alter_column('price_history', 'stock_status', + existing_type=sa.VARCHAR(length=20), + comment='Stock status (in_stock, out_of_stock, unknown)', + existing_nullable=True) + op.alter_column('price_history', 'fetch_method', + existing_type=sa.VARCHAR(length=20), + comment='Fetch method (http, playwright)', + existing_nullable=False) + op.alter_column('price_history', 'fetch_status', + existing_type=sa.VARCHAR(length=20), + comment='Fetch status (success, partial, failed)', + existing_nullable=False) + op.alter_column('price_history', 'fetched_at', + existing_type=postgresql.TIMESTAMP(), + comment='Scraping timestamp', + existing_nullable=False) + op.alter_column('product_images', 'image_url', + existing_type=sa.TEXT(), + comment='Image URL', + existing_nullable=False) + op.alter_column('product_images', 'position', + existing_type=sa.INTEGER(), + comment='Image position (0=main)', + existing_nullable=False) + op.alter_column('product_specs', 'spec_key', + existing_type=sa.VARCHAR(length=200), + comment="Specification key (e.g., 'Brand', 'Color')", + existing_nullable=False) + op.alter_column('product_specs', 'spec_value', + existing_type=sa.TEXT(), + comment='Specification value', + existing_nullable=False) + op.add_column('products', sa.Column('rating_value', sa.Numeric(precision=3, scale=2), nullable=True, comment='Note moyenne')) + op.add_column('products', sa.Column('rating_count', sa.Integer(), nullable=True, comment="Nombre d'evaluations")) + op.add_column('products', sa.Column('amazon_choice', sa.Boolean(), nullable=True, comment="Badge Choix d'Amazon")) + op.add_column('products', sa.Column('amazon_choice_label', sa.Text(), nullable=True, comment="Libelle Choix d'Amazon")) + op.add_column('products', sa.Column('discount_text', sa.Text(), nullable=True, comment='Texte de reduction affiche')) + op.add_column('products', sa.Column('stock_text', sa.Text(), nullable=True, comment='Texte brut du stock')) + op.add_column('products', sa.Column('in_stock', sa.Boolean(), nullable=True, comment='Disponibilite derivee')) + op.add_column('products', sa.Column('model_number', sa.Text(), nullable=True, comment='Numero du modele')) + op.add_column('products', sa.Column('model_name', sa.Text(), nullable=True, comment='Nom du modele')) + op.alter_column('products', 'source', + existing_type=sa.VARCHAR(length=50), + comment='Store ID (amazon, cdiscount, etc.)', + existing_nullable=False) + op.alter_column('products', 'reference', + existing_type=sa.VARCHAR(length=100), + comment='Product reference (ASIN, SKU, etc.)', + existing_nullable=False) + op.alter_column('products', 'url', + existing_type=sa.TEXT(), + comment='Canonical product URL', + existing_nullable=False) + op.alter_column('products', 'title', + existing_type=sa.TEXT(), + comment='Product title', + existing_nullable=True) + op.alter_column('products', 'category', + existing_type=sa.TEXT(), + comment='Product category (breadcrumb)', + existing_nullable=True) + op.alter_column('products', 'description', + existing_type=sa.TEXT(), + comment='Product description', + existing_nullable=True) + op.alter_column('products', 'currency', + existing_type=sa.VARCHAR(length=3), + comment='Currency code (EUR, USD, GBP)', + existing_nullable=True) + op.alter_column('products', 'msrp', + existing_type=sa.NUMERIC(precision=10, scale=2), + comment='Recommended price', + existing_nullable=True) + op.alter_column('products', 'first_seen_at', + existing_type=postgresql.TIMESTAMP(), + comment='First scraping timestamp', + existing_nullable=False) + op.alter_column('products', 'last_updated_at', + existing_type=postgresql.TIMESTAMP(), + comment='Last metadata update', + existing_nullable=False) + op.alter_column('scraping_logs', 'url', + existing_type=sa.TEXT(), + comment='Scraped URL', + existing_nullable=False) + op.alter_column('scraping_logs', 'source', + existing_type=sa.VARCHAR(length=50), + comment='Store ID (amazon, cdiscount, etc.)', + existing_nullable=False) + op.alter_column('scraping_logs', 'reference', + existing_type=sa.VARCHAR(length=100), + comment='Product reference (if extracted)', + existing_nullable=True) + op.alter_column('scraping_logs', 'fetch_method', + existing_type=sa.VARCHAR(length=20), + comment='Fetch method (http, playwright)', + existing_nullable=False) + op.alter_column('scraping_logs', 'fetch_status', + existing_type=sa.VARCHAR(length=20), + comment='Fetch status (success, partial, failed)', + existing_nullable=False) + op.alter_column('scraping_logs', 'fetched_at', + existing_type=postgresql.TIMESTAMP(), + comment='Scraping timestamp', + existing_nullable=False) + op.alter_column('scraping_logs', 'duration_ms', + existing_type=sa.INTEGER(), + comment='Fetch duration in milliseconds', + existing_nullable=True) + op.alter_column('scraping_logs', 'html_size_bytes', + existing_type=sa.INTEGER(), + comment='HTML response size in bytes', + existing_nullable=True) + op.alter_column('scraping_logs', 'errors', + existing_type=postgresql.JSONB(astext_type=sa.Text()), + comment='Error messages (list of strings)', + existing_nullable=True) + op.alter_column('scraping_logs', 'notes', + existing_type=postgresql.JSONB(astext_type=sa.Text()), + comment='Debug notes (list of strings)', + existing_nullable=True) + op.alter_column('webhooks', 'event', + existing_type=sa.VARCHAR(length=50), + comment='Event name', + existing_nullable=False) + op.alter_column('webhooks', 'url', + existing_type=sa.TEXT(), + comment='Webhook URL', + existing_nullable=False) + op.alter_column('webhooks', 'secret', + existing_type=sa.VARCHAR(length=200), + comment='Secret optionnel', + existing_nullable=True) + op.alter_column('webhooks', 'created_at', + existing_type=postgresql.TIMESTAMP(), + comment='Creation timestamp', + existing_nullable=False) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column('webhooks', 'created_at', + existing_type=postgresql.TIMESTAMP(), + comment=None, + existing_comment='Creation timestamp', + existing_nullable=False) + op.alter_column('webhooks', 'secret', + existing_type=sa.VARCHAR(length=200), + comment=None, + existing_comment='Secret optionnel', + existing_nullable=True) + op.alter_column('webhooks', 'url', + existing_type=sa.TEXT(), + comment=None, + existing_comment='Webhook URL', + existing_nullable=False) + op.alter_column('webhooks', 'event', + existing_type=sa.VARCHAR(length=50), + comment=None, + existing_comment='Event name', + existing_nullable=False) + op.alter_column('scraping_logs', 'notes', + existing_type=postgresql.JSONB(astext_type=sa.Text()), + comment=None, + existing_comment='Debug notes (list of strings)', + existing_nullable=True) + op.alter_column('scraping_logs', 'errors', + existing_type=postgresql.JSONB(astext_type=sa.Text()), + comment=None, + existing_comment='Error messages (list of strings)', + existing_nullable=True) + op.alter_column('scraping_logs', 'html_size_bytes', + existing_type=sa.INTEGER(), + comment=None, + existing_comment='HTML response size in bytes', + existing_nullable=True) + op.alter_column('scraping_logs', 'duration_ms', + existing_type=sa.INTEGER(), + comment=None, + existing_comment='Fetch duration in milliseconds', + existing_nullable=True) + op.alter_column('scraping_logs', 'fetched_at', + existing_type=postgresql.TIMESTAMP(), + comment=None, + existing_comment='Scraping timestamp', + existing_nullable=False) + op.alter_column('scraping_logs', 'fetch_status', + existing_type=sa.VARCHAR(length=20), + comment=None, + existing_comment='Fetch status (success, partial, failed)', + existing_nullable=False) + op.alter_column('scraping_logs', 'fetch_method', + existing_type=sa.VARCHAR(length=20), + comment=None, + existing_comment='Fetch method (http, playwright)', + existing_nullable=False) + op.alter_column('scraping_logs', 'reference', + existing_type=sa.VARCHAR(length=100), + comment=None, + existing_comment='Product reference (if extracted)', + existing_nullable=True) + op.alter_column('scraping_logs', 'source', + existing_type=sa.VARCHAR(length=50), + comment=None, + existing_comment='Store ID (amazon, cdiscount, etc.)', + existing_nullable=False) + op.alter_column('scraping_logs', 'url', + existing_type=sa.TEXT(), + comment=None, + existing_comment='Scraped URL', + existing_nullable=False) + op.alter_column('products', 'last_updated_at', + existing_type=postgresql.TIMESTAMP(), + comment=None, + existing_comment='Last metadata update', + existing_nullable=False) + op.alter_column('products', 'first_seen_at', + existing_type=postgresql.TIMESTAMP(), + comment=None, + existing_comment='First scraping timestamp', + existing_nullable=False) + op.alter_column('products', 'msrp', + existing_type=sa.NUMERIC(precision=10, scale=2), + comment=None, + existing_comment='Recommended price', + existing_nullable=True) + op.alter_column('products', 'currency', + existing_type=sa.VARCHAR(length=3), + comment=None, + existing_comment='Currency code (EUR, USD, GBP)', + existing_nullable=True) + op.alter_column('products', 'description', + existing_type=sa.TEXT(), + comment=None, + existing_comment='Product description', + existing_nullable=True) + op.alter_column('products', 'category', + existing_type=sa.TEXT(), + comment=None, + existing_comment='Product category (breadcrumb)', + existing_nullable=True) + op.alter_column('products', 'title', + existing_type=sa.TEXT(), + comment=None, + existing_comment='Product title', + existing_nullable=True) + op.alter_column('products', 'url', + existing_type=sa.TEXT(), + comment=None, + existing_comment='Canonical product URL', + existing_nullable=False) + op.alter_column('products', 'reference', + existing_type=sa.VARCHAR(length=100), + comment=None, + existing_comment='Product reference (ASIN, SKU, etc.)', + existing_nullable=False) + op.alter_column('products', 'source', + existing_type=sa.VARCHAR(length=50), + comment=None, + existing_comment='Store ID (amazon, cdiscount, etc.)', + existing_nullable=False) + op.drop_column('products', 'model_name') + op.drop_column('products', 'model_number') + op.drop_column('products', 'in_stock') + op.drop_column('products', 'stock_text') + op.drop_column('products', 'discount_text') + op.drop_column('products', 'amazon_choice_label') + op.drop_column('products', 'amazon_choice') + op.drop_column('products', 'rating_count') + op.drop_column('products', 'rating_value') + op.alter_column('product_specs', 'spec_value', + existing_type=sa.TEXT(), + comment=None, + existing_comment='Specification value', + existing_nullable=False) + op.alter_column('product_specs', 'spec_key', + existing_type=sa.VARCHAR(length=200), + comment=None, + existing_comment="Specification key (e.g., 'Brand', 'Color')", + existing_nullable=False) + op.alter_column('product_images', 'position', + existing_type=sa.INTEGER(), + comment=None, + existing_comment='Image position (0=main)', + existing_nullable=False) + op.alter_column('product_images', 'image_url', + existing_type=sa.TEXT(), + comment=None, + existing_comment='Image URL', + existing_nullable=False) + op.alter_column('price_history', 'fetched_at', + existing_type=postgresql.TIMESTAMP(), + comment=None, + existing_comment='Scraping timestamp', + existing_nullable=False) + op.alter_column('price_history', 'fetch_status', + existing_type=sa.VARCHAR(length=20), + comment=None, + existing_comment='Fetch status (success, partial, failed)', + existing_nullable=False) + op.alter_column('price_history', 'fetch_method', + existing_type=sa.VARCHAR(length=20), + comment=None, + existing_comment='Fetch method (http, playwright)', + existing_nullable=False) + op.alter_column('price_history', 'stock_status', + existing_type=sa.VARCHAR(length=20), + comment=None, + existing_comment='Stock status (in_stock, out_of_stock, unknown)', + existing_nullable=True) + op.alter_column('price_history', 'shipping_cost', + existing_type=sa.NUMERIC(precision=10, scale=2), + comment=None, + existing_comment='Shipping cost', + existing_nullable=True) + op.alter_column('price_history', 'price', + existing_type=sa.NUMERIC(precision=10, scale=2), + comment=None, + existing_comment='Product price', + existing_nullable=True) + # ### end Alembic commands ### diff --git a/pricewatch/app/db/migrations/versions/1467e98fcbea_ajout_champs_amazon_produit.py b/pricewatch/app/db/migrations/versions/1467e98fcbea_ajout_champs_amazon_produit.py new file mode 100644 index 0000000..e8e67f4 --- /dev/null +++ b/pricewatch/app/db/migrations/versions/1467e98fcbea_ajout_champs_amazon_produit.py @@ -0,0 +1,28 @@ +"""Ajout champs Amazon produit + +Revision ID: 1467e98fcbea +Revises: 3e68b0f0c9e4 +Create Date: 2026-01-17 20:08:32.991650 +""" + +from alembic import op +import sqlalchemy as sa + + +# Revision identifiers, used by Alembic. +revision = '1467e98fcbea' +down_revision = '3e68b0f0c9e4' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### diff --git a/pricewatch/app/db/migrations/versions/20260117_03_classification_rules.py b/pricewatch/app/db/migrations/versions/20260117_03_classification_rules.py new file mode 100644 index 0000000..ab79c09 --- /dev/null +++ b/pricewatch/app/db/migrations/versions/20260117_03_classification_rules.py @@ -0,0 +1,114 @@ +"""Ajout classification rules et type produit + +Revision ID: 20260117_03_classification_rules +Revises: 3e68b0f0c9e4 +Create Date: 2026-01-17 20:05:00.000000 +""" + +from datetime import datetime, timezone + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + + +# Revision identifiers, used by Alembic. +revision = "20260117_03_classification_rules" +down_revision = "3e68b0f0c9e4" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + op.add_column( + "products", + sa.Column("type", sa.Text(), nullable=True, comment="Product type"), + ) + + op.create_table( + "classification_rules", + sa.Column("id", sa.Integer(), primary_key=True, autoincrement=True), + sa.Column("category", sa.String(length=80), nullable=True, comment="Categorie cible"), + sa.Column("type", sa.String(length=80), nullable=True, comment="Type cible"), + sa.Column( + "keywords", + postgresql.JSONB(astext_type=sa.Text()), + nullable=False, + comment="Mots-cles de matching", + ), + sa.Column("sort_order", sa.Integer(), nullable=False, server_default="0"), + sa.Column("is_active", sa.Boolean(), nullable=False, server_default=sa.text("true")), + sa.Column( + "created_at", + sa.TIMESTAMP(), + nullable=False, + server_default=sa.text("CURRENT_TIMESTAMP"), + comment="Creation timestamp", + ), + ) + op.create_index("ix_classification_rule_order", "classification_rules", ["sort_order"]) + op.create_index("ix_classification_rule_active", "classification_rules", ["is_active"]) + + rules_table = sa.table( + "classification_rules", + sa.column("category", sa.String), + sa.column("type", sa.String), + sa.column("keywords", postgresql.JSONB), + sa.column("sort_order", sa.Integer), + sa.column("is_active", sa.Boolean), + sa.column("created_at", sa.TIMESTAMP), + ) + + now = datetime.now(timezone.utc) + op.bulk_insert( + rules_table, + [ + { + "category": "Informatique", + "type": "Ecran", + "keywords": ["ecran", "moniteur", "display"], + "sort_order": 0, + "is_active": True, + "created_at": now, + }, + { + "category": "Informatique", + "type": "PC portable", + "keywords": ["pc portable", "ordinateur portable", "laptop", "notebook"], + "sort_order": 1, + "is_active": True, + "created_at": now, + }, + { + "category": "Informatique", + "type": "Unite centrale", + "keywords": ["unite centrale", "tour", "desktop", "pc fixe"], + "sort_order": 2, + "is_active": True, + "created_at": now, + }, + { + "category": "Informatique", + "type": "Clavier", + "keywords": ["clavier", "keyboard"], + "sort_order": 3, + "is_active": True, + "created_at": now, + }, + { + "category": "Informatique", + "type": "Souris", + "keywords": ["souris", "mouse"], + "sort_order": 4, + "is_active": True, + "created_at": now, + }, + ], + ) + + +def downgrade() -> None: + op.drop_index("ix_classification_rule_active", table_name="classification_rules") + op.drop_index("ix_classification_rule_order", table_name="classification_rules") + op.drop_table("classification_rules") + op.drop_column("products", "type") diff --git a/pricewatch/app/db/migrations/versions/3e68b0f0c9e4_ajout_champs_amazon_produit.py b/pricewatch/app/db/migrations/versions/3e68b0f0c9e4_ajout_champs_amazon_produit.py new file mode 100644 index 0000000..1d9c955 --- /dev/null +++ b/pricewatch/app/db/migrations/versions/3e68b0f0c9e4_ajout_champs_amazon_produit.py @@ -0,0 +1,28 @@ +"""Ajout champs Amazon produit + +Revision ID: 3e68b0f0c9e4 +Revises: 0014e51c4927 +Create Date: 2026-01-17 19:45:03.730218 +""" + +from alembic import op +import sqlalchemy as sa + + +# Revision identifiers, used by Alembic. +revision = '3e68b0f0c9e4' +down_revision = '0014e51c4927' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### diff --git a/pricewatch/app/db/migrations/versions/__pycache__/0014e51c4927_ajout_champs_amazon_produit.cpython-313.pyc b/pricewatch/app/db/migrations/versions/__pycache__/0014e51c4927_ajout_champs_amazon_produit.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d3f310f978dc2c9550dc0a57a053b28c6c9b427 GIT binary patch literal 13633 zcmc&*T}<0p77maf2uVvzTUuJEOMf6Of1yAN(?9;&LLs3sl>U26atUseIK6h-!mf6@ zqh0OmysR{uS!sA!t=hNM%t*6pEA_RHVFqcDclK%brEfFSnU_56Id%+A;)1V`TO^{{SQ$yU%R`17(=tf$^_&q=G{tWrJm#VZ2d#orCw6EiXs zo#&Hji5W=pi(-mNQ!$niWUn_u9tx5GHKW7*OlN1XoAd;u-F;oBv@1mFXSzDOdOL%` z9+d?*-x+K_-P?P*FX(-P9SoEy zpoCG}7ZvI73z`f6~PM6|9qW^_8=3*27lzxfm;~RhC)3Hdw0-td;9+)X$);KGxq?#%{C0x!odX z4ZFi~?{`|{thK?p>z3*$*w=_p@A3Mv$n*eHXAc-y&1b(so&81|oCgh@8~2|vVcl8WGu5XK88~;DBAN_{J*J4md7tyJ zN7$o%&YryY7Wm$OtNoZk`(88cYnJ3;o3~thi$Qz+CfWmAuKl<{`+-fgpV)Hktv0l` zZMpV#8`?XzTzjWM`)2bV+;Z(*2JM^8`^hcW-fcsB&pWl7Kfw>Ny#{vkb@7zCE}k}7 z!QRE$w<%}8%K3o}&NBwijn~?9s_}p zigWTpnkb&Am`swCtn65;Ph}Dbel|fAzceqT(+G`1WFzNi^F;=WiVvC*z0XN9FK47T z_@?x%OmQbjDlX6G+F88FXcw6lAq6<7Xk{R3!-;cxDU-UN5+9`kif@j{(RnUO0M3UeZp2`BBXl3Rgu0vu0 z#jC0zF^-pWJJ~4Zv3HCtBnjM`Oe@>;P>_)1<3v)b)FYRniConvRx#6&aitOhJ%SAJ zrCgm>sh63S&a+8gfd0T-spHN`X%dx`N<47)$-BSL-ujSFWJs>I@IJK?TBE6w6dwgXm@T#b4aSiceIXGdSxIq$ zq*5eMu2kxiOLxHKwL79>CM7TK3W>>CN|;zPK?=2TlH%vp=o%ND7r}%UcMb9}7>6M! zJqDx}dQ)l(KpfZ)Ni6Oe7vPX60sCWuq-x}3@>pK1p8^S52}23mDh>%h2ct7jp!ceg zskmAVH%lS#7t4Tcfk7#ix@j%$9u}mum=b1%grL$<;UOW4FDb@If=gwRvxF|zgfdA& zMZ90F2Mzh_e3C5sVE_!5+>)4~QSzn>=d1}V8pdXHm}$}a+R8-rezY=Ruk8V)ijp}( zNeb?X;XQ|S?^~;9S_atBP%Fb;nbvQrK$j71-x*JfcV?>HlA+6eKt&TNR0#$}$gMn%&e+J$SQ_(Uq9cg8z z+2K~^(%@u3aV902&h3a0ZM}$*n6{)S{yBk4GA9v|La*9;5sM6{E%vSL2_A5nbPO7= zI^eExs6Z#@p^9g;E3oL~Z{-qVT*_6eUJBY^IC6~M1;cm>a}1ad<)grgJm=Pj%q^Wq1L}jT%oqj07TJwm9r$7gvPIts+JCZ_Nn^~#j zA)y%EmpY6=c8=T_^EtsXl1lc&Pf{Bxzl<;kNsOQ^ef)Kj|L(6w53 z$&9H8b9(jAG1S&#)K-MKV1~KuB@ z`}%73+RXCl>)B{L`{1J=9gc$o125h&Yo_9cDw==q};3t4t1%P%Z9F0MF#RfKwqRCUkmUhI24 zmA&<7x$*IebD6| zanfQ8j)mvB=S9`);q1-Ca$|DEnJUH<=!!2l&aXHH#Gv7hEmi6hqZ!)=h2ySas&$Mu zd1uTpF2m%tn*lrqfQfUAEqM)q-cp+%Tk;zKU?0Wqm1h7aeEMLyA-Gy+O5#QmqoW=- zW7=Nm7D1B^Wtm_hsI3$fUYa(v`G^_ddcHk*XEz!D@X{?Eqm6%GX^X>4Mb7^I76fqS zJNfpYx1Ta;O!jE60nu%OSb}cDy3_V;L)*)ySIy6xUj&vLhF9xMy9R5k8P;@qRVzai z(9HR8>5z{t8BNt>P7FSwjd!5517l0R!pX;l^DQpG^Z`5`3i7g5P@(2!pZK>bFT0kd z(KED={CWhV~(t46rpwbALLLm%Ui}eAYtx>ystIZY6I)W@1&Tc#eA|gUcZ6Y zytUi%t=(>!6*9Sow{p`+v_b2}@t>XQNYz>%sTzn_;m%0?MYclsZX3Gy82V+JJv7)< zoekc-HhA~h;H@`|m1z{((BAzv=Kp}9z2;WckhiKv8>|N{vobbV4{gfYlyB={8zXyU zQ&!!tj@oFeomJqNW!`4im^0qY4gxlKjoIMMcu&~iZ8eOp`4<3fY&+Wl-_$tRPRp~_ z%mxj-=62haw}q27Si23Zo2}hFHh6n&@Sd{4d)fwXpAB9+*4uBx8mxQp2R2y$HxD-d z>ZF-HWBR4ZyU=HCq0iYupSOj+U<*B93q5EHJ!A_#Y>GC|%8#%YZCL&#%eFMaUN-QW zuPgeVaMUvE7<s8AuYnY7~ST}nfvNm|9Z17I&ypRjK7NR#{2Tngk!GpLMa8lgpYe|iowM z>0K1fDC$sfAg1V9JiUVg-@WK*6t_`Kptz1=8pRD1Qz&LoL{P9OCQ)2Pf!SMn5C!IG zDK5IS0R?_8MfaoVNAUrQFp5(s`cQ;WoIr5}#W;#l6k{kZp+Lu`_RunQ5->W2t^YLbQiiC#Xb}mYo%y56yKuhb`Sxd8i=N|Sb^_TbPff+a#MmLjzUC{ zLNSjb1_I*yR7~ds&oqtI_^wVVUaN{hDp8B^K7#Ty_>=zPGRAmIUitU0G7#E0_EVJ; z!meID$XgOU09Y3W5CGO}gc+j{fKj7I#Z*Pn41lR|(L$ISd^QV^0Q`KZ=J2~>F907j zffojI0Cd&_R1gvZ48)p?dmLUWiZuhwWc*4ZSpXX?9cDAwfElbPb_Q%_oy0Lw!-Dy^ z5x|Dc*o@&kz?e;1Nn8+c5UMJ*lcE?S!1~Q#B>_tSo-7^SlISPEOlH3@iVB#XcT(j8 z{_o;3#&ZGFVa8Kr;}9z>9fqRdGEj|}!HVM404tiH(8r-q`ak{kinA4i+gj;2E6(=y z5(Mjyua^puAFVh$)~;m_cCR>l){37NT>P|6= z=2QR#q0u6);?xX))cj5H^6-E0yP|kBv~9A~Lc&WW88HBwn373?Ef0K)>#Dkt!xsu} zNNr|lDirW59*&ENQI1nQ@F`1jR)}ipOE3I`4WEFo1Ck5sBSWcOuV|0K_a2x>)DoDL zH2PE4u!L5dHM;^#}{8TeEnlOX5lZ{cbg zK3;IY@IyseS=o=}t}^E@+Z<(e|8Ug(({cOU?TLT2W)}$mjwjxq-I4OL OmR}N1xx7s4@P7cjSjkEN literal 0 HcmV?d00001 diff --git a/pricewatch/app/db/migrations/versions/__pycache__/1467e98fcbea_ajout_champs_amazon_produit.cpython-313.pyc b/pricewatch/app/db/migrations/versions/__pycache__/1467e98fcbea_ajout_champs_amazon_produit.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f451a3bce8078357ccc8e6ef44c5dade80075dbd GIT binary patch literal 749 zcmaJ<&2G~`5MKWzcHE>Y0;$jg@->InPFm6=LWqh=2rBh}AHZ6#w~2%Qm~~pUr@TZT zqHk0!5<=p{ttj-)tka5!10&7nnVs?Md^5Z3bR2@>fBT%g*9rNdoJT>wmgQUgT$6wR z3A8{z(LU;+yUI3B3@`%|8bJe^fdLk(9oRv0hs;c9p=H&UGcmfYtNGEam{%^F(ySEj zQAV$d+%2Jq=Sk%_pZIwq5xE@|y&zM0kD{Srpe{{> zYce4>+UX4eTOFYinR(M9+(G@;nw{k=LX^-T!ZU_UjB^N6O#8bBwB` yh(5xdp=sJLy`h=+n?&3GO1AH8(%xCvw_7h4o!hNv2%RSj=XX=rTK8>)n$I8M@4x>5 literal 0 HcmV?d00001 diff --git a/pricewatch/app/db/migrations/versions/__pycache__/20260114_02_webhooks.cpython-313.pyc b/pricewatch/app/db/migrations/versions/__pycache__/20260114_02_webhooks.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..848d12a55cd32d287f15af2f6fdcc3f7c714a19e GIT binary patch literal 2090 zcma)7O>7%g5Z*tp*K0dXO&~P1$O`$XON;F^L2^`;CQXq{NE)(1K#H{5cpvsQ>s|Nl zIzODE3JHk|y;MR;q)327xcQi4j};&h2au}Q-ZwWkVAf=3mMLi)#@Fw}5!eC=6y4R^cYuk2uVwDa}vvSWpBUQ6gAWcpQaC zQY1y}VeSh!22|9e1$i zKdk14d* zcz6zefPfz}_X0UH8zkUJ!Z5uM_B}|Hzh=dNI(`F!3n8RqO+fWBBP~+l;Ug4;5Wc;| zNC@FwSYXS4!>^ubn7UD>Z zu)bVLo*^$CA$#rfa?Z;Of2O>2hODL9d3SVgUS39`J|-QmnXY!fQ_e%PM6&dLQU&1* z_}2g*KgO4tOxHA#g5DvVq0ePF60c#Ss^L|25v`J>R(EZ~Dq&PbmP;aN310g{;10Bd zXd#dVb7Fug$1;UK((u&Sf4w7TgM(LrF?-G54z zGLX=Kx~jRP(^yekZmHgh^su^RJg6g*3hVq+GI2~>jU;>%sy74(=V(N{ZJYI~MWRK^ zMP-DEsJPg$%0!q$D=vwS+qQ``3*4k^Y_2$UN0}R&nmICMSUOtyl{ol0a!+(jT(f34eN|S+n zaC2y@uwK|6Z@!h?>2FH60!9C3YO8y_d*j0Pr%ma4AkA#fZq2XHZ+zLf^GENWgTD># z&VK%TwkgdAfXkcXTgCO_w$i+q-e$Jm&f)sdiI1HE%wos ze}qe(IcQE1`lXJo=}eqNRaLi3s!F1oiK+`mspXXOz|_oA1yxsZ51c|I-1;*lN$QAt z%r0QfDpgeITVy&A0jeQOcU0T*st{9WPsbwNsM>nnL^ts;Xz5UOuEX|{XIb_?F2V}0 rIvBS5In(`8WD*zFq-UL%){@UUyI@P6Uy~2TIQt3v>LSm+?M3uI+6J;K literal 0 HcmV?d00001 diff --git a/pricewatch/app/db/migrations/versions/__pycache__/20260115_02_product_details.cpython-313.pyc b/pricewatch/app/db/migrations/versions/__pycache__/20260115_02_product_details.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f37a272705da08b618e6059b43e20813e9ecc63 GIT binary patch literal 1341 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 bja1rWP(}8x3U9etkB9rN;AK6>Z0!F65Mq$H literal 0 HcmV?d00001 diff --git a/pricewatch/app/db/migrations/versions/__pycache__/3e68b0f0c9e4_ajout_champs_amazon_produit.cpython-313.pyc b/pricewatch/app/db/migrations/versions/__pycache__/3e68b0f0c9e4_ajout_champs_amazon_produit.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e38926cf5abeb318516932dc375f30f173d20056 GIT binary patch literal 749 zcmaJ<&2G~`5MKWzcHE>Y0;$jg@->In&QF^rLWqh=2rBh}AHdqIm&Cz;%sQ>wQ(mGE z(G#x|Ef*wC+=@c)%sQ=zI55(Dp4l1C&Ns8GR?8tMUzeZbcRC?Il=CR)SF(D8pBoYo zAb}R>XW9oHbXVENnE_^CLM^C4JutvRwF5h-?~$1a4YaJvawbN*aXmko<@3^IQ<@gS zJxS?xp1B3&(L634=Oe#}MT{r!Pe*Q#A03bVPd*#+{yM_N$o2hBpC5Kuf7l&3Z-LX2 zyQc^vx9fM0_WjO&XW({*qyFK@?;Q+!ez$Y%{8Sv;n$+{+TsAig%jRZ5rt%&|L&HE_ znFu#zLThplAwjvz3sl(S+;KgtQt>_%ND-;!0Zc0t-YOw(#<&s*4)Jf_yh^XrT4~=E1_0 zs`)jjKS1qWHlqA8TUXvj|Ah)P6{wW9F6+R{Ib`SUEop^el(R6D7EO3Mjv1%{Nk@E1 zXu_sEy^^}1(uRjU%9g4f{&mMdGd2wqI_8OxPQ(kIMIy|ziWI2(|838HmE!A2_-lBM zQMDA&MYuCGP5Y(SH1mF&XuIFY?ww7VdkcHH^K#Kz?mR$=vsZz5ED{s5FZ BzMudA literal 0 HcmV?d00001 diff --git a/pricewatch/app/db/models.py b/pricewatch/app/db/models.py index 20693b1..88ef2f2 100644 --- a/pricewatch/app/db/models.py +++ b/pricewatch/app/db/models.py @@ -84,6 +84,36 @@ class Product(Base): msrp: Mapped[Optional[Decimal]] = mapped_column( Numeric(10, 2), nullable=True, comment="Recommended price" ) + type: Mapped[Optional[str]] = mapped_column( + Text, nullable=True, comment="Product type" + ) + rating_value: Mapped[Optional[Decimal]] = mapped_column( + Numeric(3, 2), nullable=True, comment="Note moyenne" + ) + rating_count: Mapped[Optional[int]] = mapped_column( + Integer, nullable=True, comment="Nombre d'evaluations" + ) + amazon_choice: Mapped[Optional[bool]] = mapped_column( + Boolean, nullable=True, comment="Badge Choix d'Amazon" + ) + amazon_choice_label: Mapped[Optional[str]] = mapped_column( + Text, nullable=True, comment="Libelle Choix d'Amazon" + ) + discount_text: Mapped[Optional[str]] = mapped_column( + Text, nullable=True, comment="Texte de reduction affiche" + ) + stock_text: Mapped[Optional[str]] = mapped_column( + Text, nullable=True, comment="Texte brut du stock" + ) + in_stock: Mapped[Optional[bool]] = mapped_column( + Boolean, nullable=True, comment="Disponibilite derivee" + ) + model_number: Mapped[Optional[str]] = mapped_column( + Text, nullable=True, comment="Numero du modele" + ) + model_name: Mapped[Optional[str]] = mapped_column( + Text, nullable=True, comment="Nom du modele" + ) # Timestamps first_seen_at: Mapped[datetime] = mapped_column( @@ -331,6 +361,45 @@ class ScrapingLog(Base): return f"" +class ClassificationRule(Base): + """ + Regles de classification categorie/type basees sur des mots-cles. + """ + + __tablename__ = "classification_rules" + + id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) + category: Mapped[Optional[str]] = mapped_column( + String(80), nullable=True, comment="Categorie cible" + ) + type: Mapped[Optional[str]] = mapped_column( + String(80), nullable=True, comment="Type cible" + ) + keywords: Mapped[list[str]] = mapped_column( + JSON().with_variant(JSONB, "postgresql"), + nullable=False, + default=list, + comment="Mots-cles de matching", + ) + sort_order: Mapped[int] = mapped_column( + Integer, nullable=False, default=0, comment="Ordre de priorite (0=haut)" + ) + is_active: Mapped[bool] = mapped_column( + Boolean, nullable=False, default=True, comment="Regle active" + ) + created_at: Mapped[datetime] = mapped_column( + TIMESTAMP, nullable=False, default=utcnow, comment="Creation timestamp" + ) + + __table_args__ = ( + Index("ix_classification_rule_order", "sort_order"), + Index("ix_classification_rule_active", "is_active"), + ) + + def __repr__(self) -> str: + return f"" + + class Webhook(Base): """ Webhooks pour notifications externes. diff --git a/pricewatch/app/db/repository.py b/pricewatch/app/db/repository.py index d0b451c..daa915b 100644 --- a/pricewatch/app/db/repository.py +++ b/pricewatch/app/db/repository.py @@ -13,7 +13,14 @@ from sqlalchemy.orm import Session from pricewatch.app.core.logging import get_logger from pricewatch.app.core.schema import ProductSnapshot -from pricewatch.app.db.models import PriceHistory, Product, ProductImage, ProductSpec, ScrapingLog +from pricewatch.app.db.models import ( + ClassificationRule, + PriceHistory, + Product, + ProductImage, + ProductSpec, + ScrapingLog, +) logger = get_logger("db.repository") @@ -49,12 +56,58 @@ class ProductRepository: product.title = snapshot.title if snapshot.category: product.category = snapshot.category + if snapshot.type: + product.type = snapshot.type if snapshot.description: product.description = snapshot.description if snapshot.currency: product.currency = snapshot.currency if snapshot.msrp is not None: product.msrp = snapshot.msrp + if snapshot.rating_value is not None: + product.rating_value = snapshot.rating_value + if snapshot.rating_count is not None: + product.rating_count = snapshot.rating_count + if snapshot.amazon_choice is not None: + product.amazon_choice = snapshot.amazon_choice + if snapshot.amazon_choice_label: + product.amazon_choice_label = snapshot.amazon_choice_label + if snapshot.discount_text: + product.discount_text = snapshot.discount_text + if snapshot.stock_text: + product.stock_text = snapshot.stock_text + if snapshot.in_stock is not None: + product.in_stock = snapshot.in_stock + if snapshot.model_number: + product.model_number = snapshot.model_number + if snapshot.model_name: + product.model_name = snapshot.model_name + + def apply_classification(self, snapshot: ProductSnapshot) -> None: + """Applique les regles de classification au snapshot.""" + if not snapshot.title: + return + + rules = ( + self.session.query(ClassificationRule) + .filter(ClassificationRule.is_active == True) + .order_by(ClassificationRule.sort_order, ClassificationRule.id) + .all() + ) + if not rules: + return + + title = snapshot.title.lower() + for rule in rules: + keywords = rule.keywords or [] + if isinstance(keywords, str): + keywords = [keywords] + if any(keyword and keyword.lower() in title for keyword in keywords): + if rule.category: + snapshot.category = rule.category + if rule.type: + snapshot.type = rule.type + return def add_price_history(self, product: Product, snapshot: ProductSnapshot) -> Optional[PriceHistory]: """Ajoute une entree d'historique de prix si inexistante.""" diff --git a/pricewatch/app/scraping/__pycache__/pipeline.cpython-313.pyc b/pricewatch/app/scraping/__pycache__/pipeline.cpython-313.pyc index da613bb4ea70b8829ee894fa1a03f46393cfe98c..c26e458f4ddcf96bd94ac9d5ffa9bdb4dacd379b 100644 GIT binary patch delta 847 zcmZ8fO>7cD6n?Y+3oeFs>CzSfCDkSEMy33O#FCT}dh-C?M9aY-S|uVhOFek9CPuHC zx%6Z_a;=_?miFRNZPJR3@#w+B#+rKQ#Tj5N@@Dhix8M8TH#5n6^*zx%hl=6?5^sOp zt8R#!o}UQi@iB_1K?p)oruk&O2{Q&7fj6+RyzA9liwBzC(mrdKpL5?vFYK%S zJ=OTA8m+s#Y6`y;gNgzp(LJwDzT@8>{6TEy7l_xE;?AaF%Rets4sn;SEH&G!_Q=UB2K9;PajZ6x^lm9>p|^y#+t(~Tyx44^8W&o Gx{|-DiIgM& delta 661 zcmZn>zb(r5nU|M~0SJESrDwin+sOBZk6VCWbtgXkG{#D9Zv9&tnZ`ogBa-r;^7O$`S?Bt4 zR5VF>hG3>Vc1QMfCJ3Fz7%c%)PQW4-d=`l+Vo0M~HTeMrQ`qz;-(<6u;V2RY zT6~M6I4`lFI3vI07FTg%S!#Sqetb&OWOH_177n2F{b)03G56kcZ*@rcCT%?$fNU^%e zPyWbZCe0Y4$yTHYG_HsfL?{7?TP#WW`8h>elYKcO7&Rs@<1|$l0SdP<++=b3#=^)d z`<+dKRpKK9kSG!dX#%ASKTVM$!^s9*9~g}%D{@OP+Dx|Mw&j&$l=#E|B*5wbKgn{u diff --git a/pricewatch/app/scraping/pipeline.py b/pricewatch/app/scraping/pipeline.py index cbf7865..8874a32 100644 --- a/pricewatch/app/scraping/pipeline.py +++ b/pricewatch/app/scraping/pipeline.py @@ -25,7 +25,12 @@ class ScrapingPipeline: def __init__(self, config: Optional[AppConfig] = None) -> None: self.config = config - def process_snapshot(self, snapshot: ProductSnapshot, save_to_db: bool = True) -> Optional[int]: + def process_snapshot( + self, + snapshot: ProductSnapshot, + save_to_db: bool = True, + apply_classification: bool = True, + ) -> Optional[int]: """ Persiste un snapshot en base si active. @@ -39,6 +44,8 @@ class ScrapingPipeline: try: with get_session(app_config) as session: repo = ProductRepository(session) + if apply_classification: + repo.apply_classification(snapshot) product_id = repo.safe_save_snapshot(snapshot) session.commit() return product_id diff --git a/pricewatch/app/stores/amazon/__pycache__/store.cpython-313.pyc b/pricewatch/app/stores/amazon/__pycache__/store.cpython-313.pyc index 7d485cd8cfbba8503326f3be1f7cce59d10b0056..a15294bb252673f46cf4b350c09cb5980b09f2bc 100644 GIT binary patch delta 9343 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 diff --git a/pricewatch/app/stores/amazon/selectors.yml b/pricewatch/app/stores/amazon/selectors.yml index 652ab5e..e41d3d4 100755 --- a/pricewatch/app/stores/amazon/selectors.yml +++ b/pricewatch/app/stores/amazon/selectors.yml @@ -15,6 +15,13 @@ price: - "#priceblock_dealprice" - ".a-price-range .a-price .a-offscreen" +# Texte de réduction explicite +discount_text: + - "#regularprice_savings" + - "#dealprice_savings" + - "#savingsPercentage" + - "span.savingsPercentage" + # Devise (généralement dans le symbole) currency: - "span.a-price-symbol" @@ -32,6 +39,24 @@ stock_status: - "#availability" - ".a-declarative .a-size-medium" +# Note moyenne +rating_value: + - "#acrPopover" + - "#averageCustomerReviews .a-icon-alt" + - "#averageCustomerReviews span.a-icon-alt" + +# Nombre d'évaluations +rating_count: + - "#acrCustomerReviewText" + - "#acrCustomerReviewLink" + +# Badge Choix d'Amazon +amazon_choice: + - "#acBadge_feature_div" + - "#acBadge_feature_div .ac-badge" + - "#acBadge_feature_div .ac-badge-rectangle" + - "#acBadge_feature_div .ac-badge-rectangle-icon" + # Images produit images: - "#landingImage" @@ -44,6 +69,13 @@ category: - "#wayfinding-breadcrumbs_feature_div" - ".a-breadcrumb" +# Description (détails de l'article) +description: + - "#detailBullets_feature_div" + - "#detailBulletsWrapper_feature_div" + - "#productDetails_detailBullets_sections1" + - "#feature-bullets" + # Caractéristiques techniques (table specs) specs_table: - "#productDetails_techSpec_section_1" diff --git a/pricewatch/app/stores/amazon/store.py b/pricewatch/app/stores/amazon/store.py index 26f98e2..0b0886f 100755 --- a/pricewatch/app/stores/amazon/store.py +++ b/pricewatch/app/stores/amazon/store.py @@ -130,13 +130,19 @@ class AmazonStore(BaseStore): title = self._extract_title(soup, debug_info) price = self._extract_price(soup, debug_info) currency = self._extract_currency(soup, debug_info) - stock_status = self._extract_stock(soup, debug_info) - images = self._extract_images(soup, debug_info) + stock_status, stock_text, in_stock = self._extract_stock_details(soup, debug_info) + main_image, gallery_images, images = self._extract_images(soup, debug_info) category = self._extract_category(soup, debug_info) specs = self._extract_specs(soup, debug_info) description = self._extract_description(soup, debug_info) msrp = self._extract_msrp(soup, debug_info) reference = self.extract_reference(url) or self._extract_asin_from_html(soup) + rating_value = self._extract_rating_value(soup, debug_info) + rating_count = self._extract_rating_count(soup, debug_info) + amazon_choice, amazon_choice_label = self._extract_amazon_choice(soup, debug_info) + discount_text = self._extract_discount_text(soup, debug_info) + model_number, model_name = self._extract_model_details(specs) + asin = reference # Déterminer le statut final (ne pas écraser FAILED) if debug_info.status != DebugStatus.FAILED: @@ -153,12 +159,24 @@ class AmazonStore(BaseStore): currency=currency or "EUR", shipping_cost=None, # Difficile à extraire stock_status=stock_status, + stock_text=stock_text, + in_stock=in_stock, reference=reference, + asin=asin, category=category, description=description, images=images, + main_image=main_image, + gallery_images=gallery_images, specs=specs, msrp=msrp, + rating_value=rating_value, + rating_count=rating_count, + amazon_choice=amazon_choice, + amazon_choice_label=amazon_choice_label, + discount_text=discount_text, + model_number=model_number, + model_name=model_name, debug=debug_info, ) @@ -203,14 +221,26 @@ class AmazonStore(BaseStore): return None def _extract_description(self, soup: BeautifulSoup, debug: DebugInfo) -> Optional[str]: - """Extrait la description (meta tags).""" - meta = soup.find("meta", property="og:description") or soup.find( - "meta", attrs={"name": "description"} - ) - if meta: - description = meta.get("content", "").strip() - if description: - return description + """Extrait la description depuis les détails de l'article.""" + selectors = self.get_selector("description", []) + if isinstance(selectors, str): + selectors = [selectors] + + for selector in selectors: + element = soup.select_one(selector) + if not element: + continue + items = [ + item.get_text(" ", strip=True) + for item in element.select("li") + if item.get_text(strip=True) + ] + if items: + return "\n".join(items) + text = " ".join(element.stripped_strings) + if text: + return text + return None def _extract_price(self, soup: BeautifulSoup, debug: DebugInfo) -> Optional[float]: @@ -271,8 +301,10 @@ class AmazonStore(BaseStore): # Défaut basé sur le domaine return "EUR" - def _extract_stock(self, soup: BeautifulSoup, debug: DebugInfo) -> StockStatus: - """Extrait le statut de stock.""" + def _extract_stock_details( + self, soup: BeautifulSoup, debug: DebugInfo + ) -> tuple[StockStatus, Optional[str], Optional[bool]]: + """Extrait le statut de stock avec texte brut.""" selectors = self.get_selector("stock_status", []) if isinstance(selectors, str): selectors = [selectors] @@ -280,22 +312,27 @@ class AmazonStore(BaseStore): for selector in selectors: element = soup.select_one(selector) if element: - text = element.get_text(strip=True).lower() - if "en stock" in text or "available" in text or "in stock" in text: - return StockStatus.IN_STOCK + text = element.get_text(strip=True) + normalized = text.lower() + if "en stock" in normalized or "available" in normalized or "in stock" in normalized: + return StockStatus.IN_STOCK, text, True elif ( - "rupture" in text - or "indisponible" in text - or "out of stock" in text + "rupture" in normalized + or "indisponible" in normalized + or "out of stock" in normalized ): - return StockStatus.OUT_OF_STOCK + return StockStatus.OUT_OF_STOCK, text, False - return StockStatus.UNKNOWN + return StockStatus.UNKNOWN, None, None - def _extract_images(self, soup: BeautifulSoup, debug: DebugInfo) -> list[str]: - """Extrait les URLs d'images.""" - images = [] - seen = set() + def _extract_images( + self, soup: BeautifulSoup, debug: DebugInfo + ) -> tuple[Optional[str], list[str], list[str]]: + """Extrait l'image principale et la galerie.""" + images: list[str] = [] + seen: set[str] = set() + main_image: Optional[str] = None + max_gallery = 15 selectors = self.get_selector("images", []) if isinstance(selectors, str): selectors = [selectors] @@ -309,6 +346,8 @@ class AmazonStore(BaseStore): if self._is_product_image(url) and url not in seen: images.append(url) seen.add(url) + if main_image is None: + main_image = url dynamic = element.get("data-a-dynamic-image") if dynamic: urls = self._extract_dynamic_images(dynamic) @@ -316,6 +355,8 @@ class AmazonStore(BaseStore): if self._is_product_image(dyn_url) and dyn_url not in seen: images.append(dyn_url) seen.add(dyn_url) + if main_image is None: + main_image = dyn_url # Fallback: chercher tous les img tags si aucune image trouvée if not images: @@ -326,8 +367,15 @@ class AmazonStore(BaseStore): if url not in seen: images.append(url) seen.add(url) + if main_image is None: + main_image = url - return images + if main_image is None and images: + main_image = images[0] + gallery_images = [url for url in images if url != main_image] + gallery_images = gallery_images[:max_gallery] + final_images = [main_image] + gallery_images if main_image else gallery_images + return main_image, gallery_images, final_images def _extract_dynamic_images(self, raw: str) -> list[str]: """Extrait les URLs du JSON data-a-dynamic-image.""" @@ -393,8 +441,111 @@ class AmazonStore(BaseStore): if key and value: specs[key] = value + # Détails de l'article sous forme de liste + detail_list = soup.select("#detailBullets_feature_div li") + for item in detail_list: + text = item.get_text(" ", strip=True) + if ":" not in text: + continue + key, value = text.split(":", 1) + key = key.strip() + value = value.strip() + if key and value and key not in specs: + specs[key] = value + return specs + def _extract_rating_value(self, soup: BeautifulSoup, debug: DebugInfo) -> Optional[float]: + """Extrait la note moyenne.""" + selectors = self.get_selector("rating_value", []) + if isinstance(selectors, str): + selectors = [selectors] + + for selector in selectors: + element = soup.select_one(selector) + if not element: + continue + text = element.get_text(" ", strip=True) or element.get("title", "").strip() + match = re.search(r"([\d.,]+)", text) + if match: + value = match.group(1).replace(",", ".") + try: + return float(value) + except ValueError: + continue + return None + + def _extract_rating_count(self, soup: BeautifulSoup, debug: DebugInfo) -> Optional[int]: + """Extrait le nombre d'évaluations.""" + selectors = self.get_selector("rating_count", []) + if isinstance(selectors, str): + selectors = [selectors] + + for selector in selectors: + element = soup.select_one(selector) + if not element: + continue + text = element.get_text(" ", strip=True) + match = re.search(r"([\d\s\u202f\u00a0]+)", text) + if match: + numeric = re.sub(r"[^\d]", "", match.group(1)) + if numeric: + return int(numeric) + return None + + def _extract_amazon_choice( + self, soup: BeautifulSoup, debug: DebugInfo + ) -> tuple[Optional[bool], Optional[str]]: + """Extrait le badge Choix d'Amazon.""" + selectors = self.get_selector("amazon_choice", []) + if isinstance(selectors, str): + selectors = [selectors] + + for selector in selectors: + element = soup.select_one(selector) + if element: + label_candidates = [ + element.get_text(" ", strip=True), + element.get("aria-label", "").strip(), + element.get("title", "").strip(), + element.get("data-a-badge-label", "").strip(), + ] + label = next((item for item in label_candidates if item), "") + normalized = label.lower() + if "choix d'amazon" in normalized or "amazon's choice" in normalized: + return True, label + if label: + return True, label + return True, None + return None, None + + def _extract_discount_text(self, soup: BeautifulSoup, debug: DebugInfo) -> Optional[str]: + """Extrait le texte de réduction explicite.""" + selectors = self.get_selector("discount_text", []) + if isinstance(selectors, str): + selectors = [selectors] + + for selector in selectors: + element = soup.select_one(selector) + if not element: + continue + text = element.get_text(" ", strip=True) + if text: + return text + return None + + def _extract_model_details(self, specs: dict[str, str]) -> tuple[Optional[str], Optional[str]]: + """Extrait le numero et le nom du modele depuis les specs.""" + model_number = None + model_name = None + for key, value in specs.items(): + normalized = key.lower() + if "numéro du modèle de l'article" in normalized or "numero du modele de l'article" in normalized: + model_number = value + if "nom du modèle" in normalized or "nom du modele" in normalized: + model_name = value + return model_number, model_name + def _extract_asin_from_html(self, soup: BeautifulSoup) -> Optional[str]: """Extrait l'ASIN depuis le HTML (fallback).""" selectors = self.get_selector("asin", []) diff --git a/pricewatch/app/tasks/scheduler.py b/pricewatch/app/tasks/scheduler.py index cb11883..30c1ce5 100644 --- a/pricewatch/app/tasks/scheduler.py +++ b/pricewatch/app/tasks/scheduler.py @@ -6,6 +6,7 @@ from __future__ import annotations from dataclasses import dataclass from datetime import datetime, timedelta, timezone +import hashlib from typing import Optional import redis @@ -127,11 +128,13 @@ class ScrapingScheduler: interval_hours: int = 24, use_playwright: Optional[bool] = None, save_db: bool = True, + job_id: Optional[str] = None, ) -> ScheduledJobInfo: """Planifie un scraping recurrent (intervalle en heures).""" interval_seconds = int(timedelta(hours=interval_hours).total_seconds()) next_run = datetime.now(timezone.utc) + timedelta(seconds=interval_seconds) + resolved_job_id = job_id or self._job_id_for_url(url) job = self.scheduler.schedule( scheduled_time=next_run, func=scrape_product, @@ -139,6 +142,13 @@ class ScrapingScheduler: kwargs={"use_playwright": use_playwright, "save_db": save_db}, interval=interval_seconds, repeat=None, + id=resolved_job_id, ) logger.info(f"Job planifie: {job.id}, prochaine execution: {next_run.isoformat()}") return ScheduledJobInfo(job_id=job.id, next_run=next_run) + + @staticmethod + def _job_id_for_url(url: str) -> str: + """Genere un job_id stable pour eviter les doublons.""" + fingerprint = hashlib.sha1(url.strip().lower().encode("utf-8")).hexdigest() + return f"scrape_{fingerprint}" diff --git a/pricewatch/app/tasks/scrape.py b/pricewatch/app/tasks/scrape.py index 44486d6..7b4ff21 100644 --- a/pricewatch/app/tasks/scrape.py +++ b/pricewatch/app/tasks/scrape.py @@ -157,6 +157,36 @@ def scrape_product( ) success = False fetch_error = str(exc) + # Si captcha detecte via HTTP, forcer une tentative Playwright. + if ( + fetch_method == FetchMethod.HTTP + and use_playwright + and snapshot.debug.errors + and any("captcha" in error.lower() for error in snapshot.debug.errors) + ): + logger.info("[FETCH] Captcha detecte, tentative Playwright") + pw_result = fetch_playwright( + canonical_url, + headless=not headful, + timeout_ms=timeout_ms, + save_screenshot=save_screenshot, + ) + if pw_result.success and pw_result.html: + try: + snapshot = store.parse(pw_result.html, canonical_url) + snapshot.debug.method = FetchMethod.PLAYWRIGHT + snapshot.debug.duration_ms = pw_result.duration_ms + snapshot.debug.html_size_bytes = len(pw_result.html.encode("utf-8")) + snapshot.add_note("Captcha detecte via HTTP, fallback Playwright") + success = snapshot.debug.status != DebugStatus.FAILED + except Exception as exc: + snapshot.add_note(f"Fallback Playwright echoue: {exc}") + logger.error(f"[PARSE] Exception fallback Playwright: {exc}") + fetch_error = str(exc) + else: + error = pw_result.error or "Erreur Playwright" + snapshot.add_note(f"Fallback Playwright echoue: {error}") + fetch_error = error else: snapshot = ProductSnapshot( source=store.store_id, diff --git a/webui/dist/assets/fa-brands-400-D1LuMI3I.ttf b/webui/dist/assets/fa-brands-400-D1LuMI3I.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0f82a8360517d2c8b7d16e85434d40c6fb735954 GIT binary patch literal 210792 zcmd4437DKkwfJ52_P%#d?>$>j_ssN6W+s`Qt&@;t2#F*RAj-ZdK}3-?YLLhx!zSp} zOHdY3#Hh&iDk>r>D(YNCL`CI#@# z-rDQbsZ*y;oqD6RQYxq>luH$lJAT>FnLA!}sZzR!(5+`*c-FQrw;XjC3H(YW-~74@ z-tyYDH*9`hscyG&_NC4}=d9QCeY$WDY3~Kb&LzNog8NAP&j6k0UbuaS_XvN0@@`bh zKXJjuXP@PKwdFpgS|@nF?!vQnY;!ibUrs#btKvmxU3kuCKKJZZ%GI1x%H6u{;x}#o z$nVQrl&gKYQn{sywz_;C^@Gb!*>PrU)jkz+$fnevypyM;$D=0Toq0I5-#!Mi`;SQ zlyC#{bB=AtyeWTT{x8%Oc5Hsfzw!FJ)Z0wi zj;U+Xv_rzAY%k!Kbk5aEoB9bSZlSM@JSL6JBlr)>`%8h8Ys%h3yg)r2n3;AG=QioaP1ynBZ1}c%U8YW3hl!&e(l<5A zYoy1G>EG1bK)uxCC(N{W!5vpV^0h6h?_i @@Z|Lo2o%N8V+8O&i2d+$8BHR07ve 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 z

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