1er
This commit is contained in:
16
docs/ARCHITECTURE.md
Normal file
16
docs/ARCHITECTURE.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Architecture cible
|
||||
|
||||
## Backend
|
||||
- FastAPI (routes, services, scheduler)
|
||||
- SQLite via SQLAlchemy
|
||||
- Scraper Playwright avec module par boutique
|
||||
- Logs/artefacts dans `backend/logs` et `backend/data`
|
||||
|
||||
## Frontend
|
||||
- SPA (React/Vite par défaut)
|
||||
- Thème Gruvbox dark, responsive
|
||||
- Configurable via `frontend/config_frontend.json`
|
||||
|
||||
## Déploiement
|
||||
- Docker Compose pour backend+frontend
|
||||
- Cron interne (APScheduler) pour `scrape_all`
|
||||
83
docs/db_structure.md
Normal file
83
docs/db_structure.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Structure base de données
|
||||
|
||||
## Vue d'ensemble
|
||||
- `products` : produit suivi (URL canonique, store, catégories, statut).
|
||||
- `scrape_runs` : trace des runs pour mesurer taux réussite / blocages.
|
||||
- `product_snapshots` : historique des données extraites (prix, stock, badges, raw JSON).
|
||||
|
||||
## Diagramme
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌──────────────┐
|
||||
│ products │ 1 N │ product_ │
|
||||
│ (stores) │──────>│ snapshots │
|
||||
│ id PK │ │ id PK │
|
||||
│ store │ │ product_id FK│
|
||||
│ url │ │ scraped_at │
|
||||
│ asin │ │ price_current│
|
||||
│ ... │ │ stock_text │
|
||||
└─────────────┘ │ ... │
|
||||
└──────────────┘
|
||||
|
||||
┌──────────────┐
|
||||
│ scrape_runs │
|
||||
│ id PK │
|
||||
│ started_at │
|
||||
│ ended_at │
|
||||
│ status │
|
||||
│ items_ok │
|
||||
│ items_failed │
|
||||
│ items_total │
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
> Commentaire : `products` lie les snapshots ; `scrape_runs` peut être lié aux snapshots si on enregistre `scrape_run_id`.
|
||||
> Commentaire : les indexes `product_id`, `scraped_at` et `asin` servent à accélérer les historiques et recherches.
|
||||
|
||||
## Schéma base de données (SQLite)
|
||||
Proposer un schéma minimal + extensible.
|
||||
|
||||
### Tables
|
||||
1) `products`
|
||||
- `id` (PK)
|
||||
- `store` (ex: amazon_fr)
|
||||
- `url`
|
||||
- `asin`
|
||||
- `title`
|
||||
- `image_url`
|
||||
- `category`
|
||||
- `type`
|
||||
- `is_active` (bool)
|
||||
- `created_at`, `updated_at`
|
||||
|
||||
2) `scrape_runs`
|
||||
- `id` (PK)
|
||||
- `started_at`, `ended_at`
|
||||
- `status` (success/partial/failed)
|
||||
- `items_total`, `items_ok`, `items_failed`
|
||||
- `log_path` (option)
|
||||
|
||||
3) `product_snapshots`
|
||||
- `id` (PK)
|
||||
- `product_id` (FK → products.id)
|
||||
- `scraped_at`
|
||||
- `price_current`
|
||||
- `price_list` (nullable)
|
||||
- `lowest_30d_price` (nullable)
|
||||
- `stock_text` (nullable)
|
||||
- `in_stock` (nullable)
|
||||
- `rating_value` (nullable)
|
||||
- `rating_count` (nullable)
|
||||
- `prime_eligible` (nullable)
|
||||
- `amazon_choice` (nullable)
|
||||
- `limited_time_deal` (nullable)
|
||||
- `amazon_exclusive` (nullable)
|
||||
- `raw_json_path` (nullable)
|
||||
- `scrape_status` (ok/blocked/missing_fields/error)
|
||||
- `error_message` (nullable)
|
||||
|
||||
4) (option) `tags`
|
||||
- `id`, `name`
|
||||
|
||||
5) (option) `product_tags`
|
||||
- `product_id`, `tag_id`
|
||||
53
docs/frontend_structure.md
Normal file
53
docs/frontend_structure.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Structure frontend
|
||||
|
||||
## Layout principal
|
||||
- Header fixe (logo + actions + versions)
|
||||
- Grille responsive de cartes produits.
|
||||
- Zone debug/logs avec sections SQLite et journaux JSON. (repliable)
|
||||
|
||||
## Diagramme ASCII (UI globale)
|
||||
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────────────┐
|
||||
│ suivi_produits [Add Product] [Refresh] [Settings] FE vX BE vY │
|
||||
│ (header fixed) [debug] (⋯) │
|
||||
├──────────────────────────────────────────────────────────────────────────┤
|
||||
│ Grid (cols = config_frontend.json) │
|
||||
│ │
|
||||
│ ┌──────────────────────────── Card Produit ──────────────────────────┐ │
|
||||
│ │ Boutique + Titre (2 lignes) │ │
|
||||
│ │ Amazon │ │
|
||||
│ │ Samsung SSD Interne 9100 Pro… │ │
|
||||
│ │ │ │
|
||||
│ │ ┌───────────────┐ ┌──────────────────────────────────────────┐ │ │
|
||||
│ │ │ Image │ │ ACTUEL 249€99 │ │ │
|
||||
│ │ │ (non rognée) │ │ PRIX CONSEILLÉ 329€99 (si présent) │ │ │
|
||||
│ │ │ │ │ RÉDUCTION -24% (si présent) │ │ │
|
||||
│ │ └───────────────┘ │ STOCK Disponible │ │ │
|
||||
│ │ │ NOTE 4,7 (967) │ │ │
|
||||
│ │ │ CHOIX AMAZON Oui/Non │ │ │
|
||||
│ │ │ PRIME Oui/Non │ │ │
|
||||
│ │ │ DEAL Oui/Non │ │ │
|
||||
│ │ │ Ref: ASIN [Lien produit] │ │ │
|
||||
│ │ └──────────────────────────────────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ ┌────────────────────── Graph 30j (clair) ─────────────────────┐ │ │
|
||||
│ │ │ ligne + points, axes lisibles, tooltip │ │ │
|
||||
│ │ └──────────────────────────────────────────────────────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ Min 249€99 Max 249€99 Tendance → stable +0.0% Dernier: now │ │
|
||||
│ │ Catégorie: SSD Type: NVMe │ │
|
||||
│ │ │ │
|
||||
│ │ [Scrap] [Edit] [Delete] [Détail] │ │
|
||||
│ └────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└──────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
page de debug et log qui affiche le contenue des differentes tables sqlite dans des section distincte, une section log qui affiche les log json de scrap
|
||||
---
|
||||
|
||||
|
||||
|
||||
> Commentaire : le render React maintient `columns_desktop` depuis `config_frontend.json` et passe en 1 colonne sur mobile.
|
||||
> Commentaire : chaque `Card` inclut image non rognée, badges, actions (Scrap/Edit/Delete/Détail) et graphique 30j.
|
||||
53
docs/scrap.md
Normal file
53
docs/scrap.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Procédure de scraping Amazon.fr
|
||||
|
||||
## Objectif
|
||||
- Extraire les champs requis (prix, stock, note, badges, image) sans casser le pipeline si un champ manque.
|
||||
- Produire un snapshot propre + artefacts de debug si blocage.
|
||||
|
||||
## Pré-requis
|
||||
- Playwright installé (Chromium).
|
||||
- Config lue depuis `backend/config_backend.json`.
|
||||
- Lancement via `scrape_product` ou `scrape_all`.
|
||||
|
||||
## Étapes de scraping
|
||||
1. **Initialiser le navigateur**
|
||||
- Chromium, locale `fr-FR`, timezone `Europe/Paris`, viewport réaliste.
|
||||
- `user-agent` défini dans la config.
|
||||
|
||||
2. **Charger la page produit**
|
||||
- Délai aléatoire 1–3s entre requêtes.
|
||||
- Timeout contrôlé.
|
||||
|
||||
3. **Détecter blocage/captcha**
|
||||
- Si captcha / robot-check :
|
||||
- Marquer `scrape_status = blocked`.
|
||||
- Sauvegarder `screenshot` + `page.content()` dans `backend/data/screenshots`.
|
||||
- Log détaillé + retour sans crash.
|
||||
|
||||
4. **Extraire les champs**
|
||||
- Priorité aux IDs stables (ex: `#productTitle`, `#acrCustomerReviewText`, `#availability`).
|
||||
- Prix : gérer variantes (prix fractionné, promo).
|
||||
- Champs optionnels : si absent → `null` + log "missing field".
|
||||
|
||||
5. **Normaliser les valeurs**
|
||||
- Prix : `"249,99 €"` → `249.99`.
|
||||
- Notes : `"4,7 sur 5"` → `4.7`.
|
||||
- Stock : `in_stock` booléen + texte brut.
|
||||
|
||||
6. **Sauvegarder le snapshot**
|
||||
- Insérer un enregistrement `product_snapshots`.
|
||||
- Écrire un JSON raw dans `backend/data/raw/YYYY-MM/...`.
|
||||
|
||||
## Logs & erreurs
|
||||
- Chaque scrap doit tracer : start, fields manquants, status, fin.
|
||||
- Échec contrôlé si un champ est absent (jamais de crash global).
|
||||
|
||||
## Champs obligatoires
|
||||
- `url`, `asin`, `title`, `image_main_url`, `price_current`, `stock_status`, `rating_value`, `rating_count`.
|
||||
|
||||
## Champs optionnels
|
||||
- `price_list`, `discount_percent`, `lowest_30d_price`, `amazon_choice`, `limited_time_deal`, `prime_eligible`, `amazon_exclusive`.
|
||||
|
||||
## Notes
|
||||
- Pas de calcul inventé (pas de réduction sans source).
|
||||
- Stratégie captcha par défaut : abandon + log + retry plus tard.
|
||||
22
docs/tools.md
Normal file
22
docs/tools.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Outils utilisés
|
||||
|
||||
## Backend
|
||||
- **Python 3.11+** : langage principal pour API FastAPI, gestion SQLite et scraping Playwright.
|
||||
- **Poetry** : gestionnaire des dépendances/tests (`poetry run pytest`) et packaging.
|
||||
- **FastAPI + Uvicorn** : framework asynchrone + ASGI pour exposer les endpoints REST.
|
||||
- **SQLAlchemy** : ORM pour modéliser `products`, `scrape_runs`, `product_snapshots`.
|
||||
- **Playwright** : navigateur Chromium pour le scraping Amazon.fr.
|
||||
- **Loguru** : logs structurés avec rotation simple.
|
||||
- **APScheduler** : scheduler interne pour déclencher `scrape_all` selon `interval_minutes`.
|
||||
|
||||
## Frontend
|
||||
- **React + Vite** : SPA rapide, bundler moderne et hot reload.
|
||||
- **Chart.js** : visualisation des historiques (courbes 30j).
|
||||
- **FontAwesome** : icônes et badges (prime, amazon choice, deal, etc.).
|
||||
- **Sass** : styles Gruvbox (variables, mixins, responsive grids).
|
||||
|
||||
## Outils DevOps & QA
|
||||
- **Docker Compose** (à venir) : orchestrera backend + frontend + scheduler.
|
||||
- **.env / dotenv** : configuration flexible (`.env.example`).
|
||||
- **Pytest / Ruff / Mypy** : tests unitaires + lint + typage.
|
||||
- **Pre-commit** : hooks `ruff` et `mypy` pour garantir la qualité avant commit.
|
||||
Reference in New Issue
Block a user