9.0 KiB
Documentation Technique et Fonctionnelle : AI Weekly Synth
Objectif de l'application
AI Weekly Synth est une application web permettant de générer automatiquement des synthèses d'actualités personnalisées et thématisées. Conçue pour la veille technologique ou sectorielle (par défaut centrée sur l'Intelligence Artificielle), elle utilise l'IA générative (Google Gemini) pour rechercher, filtrer, résumer et catégoriser les actualités récentes. L'application est multi-utilisateurs, garantissant à chacun un espace de veille privé et sur-mesure.
Fonctionnalités offertes
- Authentification sécurisée : Connexion via compte Google (SSO) garantissant la protection des données personnelles.
- Génération de synthèses par IA : Recherche sur le web et création de résumés structurés basés sur les paramètres de l'utilisateur.
- Envoi par email : Envoi direct de la synthèse via l'API Gmail (OAuth popup pour obtenir un access token).
- Gestion des sources personnalisées : Ajout d'URLs spécifiques (blogs, sites d'actualité) avec import/export CSV et import en masse.
- Configuration sur-mesure (Paramètres) :
- Choix du thème de veille (ex: "Intelligence Artificielle", "Cybersécurité", "Économie").
- Définition de la fenêtre de recherche (ex: les 7 derniers jours).
- Personnalisation des catégories de la synthèse (jusqu'à 20 catégories).
- Choix du modèle d'IA (Gemini 3.1 Pro, 3.0 Flash, 3.1 Flash Lite, 2.5 Flash).
- Modification du "prompt" de comportement de l'agent de recherche.
- Export/import des paramètres en JSON.
- Historique et consultation : Sauvegarde de toutes les synthèses générées pour une consultation ultérieure, avec liens directs vers les articles sources et suppression avec double confirmation.
Structure du projet
src/
├── main.tsx # Point d'entrée React
├── App.tsx # Router, Layout, ProtectedRoute, Login
├── index.css # Import Tailwind uniquement
├── firebase.ts # Init Firebase, helpers auth, gestion erreurs Firestore
├── types.ts # Interfaces (NewsItem, SynthesisData, AppSettings, etc.) + DEFAULT_SETTINGS
├── components/
│ └── AuthContext.tsx # Provider React Context pour l'authentification
├── pages/
│ ├── Home.tsx # Dashboard : liste des synthèses avec apercu et suppression
│ ├── GenerateSynthesis.tsx # Declenchement de la generation IA
│ ├── SynthesisDetail.tsx # Lecture detaillee + envoi email + suppression
│ ├── Sources.tsx # CRUD sources personnalisees (unitaire, CSV, masse)
│ └── Settings.tsx # Parametres utilisateur (theme, categories, modele IA, etc.)
└── services/
└── geminiService.ts # Logique IA : generation 2 passes + validation/scraping URLs
Architecture de la solution
L'application repose sur une architecture Serverless (BaaS - Backend as a Service). Il n'y a pas de serveur backend intermediaire.
- Frontend : Application Single Page (SPA) en React 19 qui gère l'interface, le routage (
react-router-domv7) et l'état de l'application. - Backend / Base de données : Firebase Firestore (NoSQL) pour stocker les paramètres, les sources et les synthèses. Les requêtes sont faites directement depuis le client React.
- Sécurité des données : Les
firestore.rulesgarantissent le cloisonnement des données (Multi-tenant). Chaque document possède un champauthorUidouuserIdvérifié à chaque requête (isDocOwner()). - Intelligence Artificielle : Le SDK
@google/genaiest appelé directement depuis le frontend. L'outilgoogleSearchest activé pour le "Grounding" (recherche web en temps réel).
Pipeline de generation (geminiService.ts)
La generation s'effectue en 2 passes :
-
Passe 1 - Recherche : Gemini avec
googleSearchgrounding produit des news brutes par categorie (JSON structure viaresponseSchema). Les categories sont dynamiques, basees sur lessettings.categoriesde l'utilisateur (clescategory_0,category_1, etc.). -
Validation/Scraping des URLs : Chaque URL retournee est verifiee via 3 proxies CORS en cascade (
allorigins->codetabs->corsproxy.io). Les articles sont filtres si : URL invalide/404, contenu d'erreur (soft 404), ou date de publication trop ancienne (via meta tags, JSON-LD, balise<time>). Le contenu textuel est extrait (max 4000 caracteres). -
Passe 2 - Reecriture : Gemini recrit les titres et resumes en se basant sur le contenu scrape reel des articles, garantissant la fidelite des resumes.
Collections Firestore
| Collection | Document ID | Champs cles | Acces |
|---|---|---|---|
syntheses |
auto-generated | week, sections[] (ou champs legacy), authorUid, createdAt |
Owner uniquement |
sources |
auto-generated | title, url, authorUid, createdAt |
Owner uniquement |
settings |
{userId} |
theme, categories[], maxAgeDays, maxItemsPerCategory, aiModel, searchAgentBehavior |
Owner uniquement |
Routes
| Path | Composant | Description |
|---|---|---|
/login |
Login (dans App.tsx) |
Connexion Google |
/ |
Home |
Dashboard des syntheses |
/generate |
GenerateSynthesis |
Lancement de la generation |
/synthesis/:id |
SynthesisDetail |
Vue detaillee d'une synthese |
/sources |
Sources |
Gestion des sources personnalisees |
/settings |
Settings |
Parametres de generation |
Choix technologiques
- Framework UI : React 19 avec Vite 6 (plugin
@vitejs/plugin-react). - Langage : TypeScript 5.8 avec typage strict (
src/types.tscentralise les interfaces). - Styling : Tailwind CSS v4 (via
@tailwindcss/viteplugin, import unique dansindex.css). - Icônes :
lucide-reactpour les icônes SVG. - Base de données & Auth : Firebase 12 (Firestore + Authentication avec Google provider).
- IA : API Google Gemini (
@google/genai) avec génération structurée (responseSchema+Typeenum) et grounding (googleSearch). - Utilitaires :
date-fnspour le formatage des dates en français.
Maintenance et Evolution
Points d'attention pour les developpeurs
-
Rate Limiting
- Le
RateLimiterdansgeminiService.tsest configure a 29 requetes/minute. Il est in-memory et par-onglet : plusieurs onglets ouverts peuvent depasser le quota. Tout nouvel appel Gemini doit passer parawait geminiRateLimiter.acquire().
- Le
-
Generation Structuree (JSON Schema)
- Le schema de reponse est genere dynamiquement a partir de
settings.categories. Si vous modifiez la structure des donnees (ex: ajout d'un champimageUrlpar article), vous devez mettre a jour :newsItemSchemadansgeminiService.tsET l'interfaceNewsItemdanstypes.ts.
- Le schema de reponse est genere dynamiquement a partir de
-
Donnees legacy (SynthesisData)
SynthesisDatacontient des champs legacy optionnels (majorAnnouncements,financialSector, etc.) ET le nouveau formatsections[]. Le code deHome.tsxetSynthesisDetail.tsxgere les deux formats via des fallbacks. Les nouvelles syntheses utilisent uniquementsections[].
-
Cle API Gemini
- La cle
GEMINI_API_KEYest injectee dans le bundle client viavite.config.ts(process.env.GEMINI_API_KEY). Elle est donc exposee dans le JavaScript du navigateur. Pour la production, il faudrait passer par un backend ou une Cloud Function.
- La cle
-
Proxies CORS
fetchHtmlContentutilise 3 proxies tiers en cascade pour le scraping. Ces services sont non garantis et peuvent etre indisponibles. Si le scraping echoue, l'article est conserve avec unscrapedContentvide.
-
Regles de securite Firestore (
firestore.rules)- Les regles sont strictes avec validation de champs (types, tailles, formats). Si vous ajoutez une nouvelle collection ou un nouveau champ, vous devez mettre a jour les regles ET les fonctions de validation (
isValidSynthesis,isValidSettings,isValidSource).
- Les regles sont strictes avec validation de champs (types, tailles, formats). Si vous ajoutez une nouvelle collection ou un nouveau champ, vous devez mettre a jour les regles ET les fonctions de validation (
-
Envoi email Gmail
- L'envoi utilise l'API Gmail directement depuis le client (
SynthesisDetail.tsx).getGmailAccessToken()dansfirebase.tsre-declenche unsignInWithPopupa chaque envoi pour obtenir le scopegmail.send.
- L'envoi utilise l'API Gmail directement depuis le client (
Dependances inutilisees dans package.json
motion,clsx,tailwind-merge: importees mais non utilisees dans le code source actuel.express,@types/express,dotenv: suggerent un composant serveur prevu ou supprime, aucun code serveur present.
Evolutions possibles
- Securiser la cle API : Deplacer l'appel Gemini vers une Cloud Function Firebase.
- Generation automatique (CRON) : Cloud Function + Cloud Scheduler pour generer automatiquement chaque semaine.
- Export PDF/Markdown : Bouton de telechargement sur la vue de detail.
- Error Boundary React : Aucun error boundary n'est en place, un crash dans un composant fait tomber toute l'app.
- Nettoyage des donnees legacy : Supprimer les champs
majorAnnouncements,financialSector, etc. deSynthesisDataune fois les anciennes syntheses migrees.