349 lines
13 KiB
Markdown
349 lines
13 KiB
Markdown
---
|
|
project_name: chartbastan
|
|
user_name: Ramez
|
|
date: 2026-01-15T22:00:00.000Z
|
|
communication_language: French
|
|
document_output_language: French
|
|
user_skill_level: intermediate
|
|
sections_completed:
|
|
- technology_stack
|
|
- implementation_patterns
|
|
- architecture_decisions
|
|
- project_structure
|
|
---
|
|
|
|
# Contexte de Projet pour Agents AI
|
|
|
|
_Ce fichier contient les règles, patterns et décisions critiques que les agents AI doivent suivre lors de l'implémentation de ce projet._
|
|
|
|
---
|
|
|
|
## Stack Technologique
|
|
|
|
### Frontend (Next.js 16)
|
|
- **Framework:** Next.js 16.0.0 (latest)
|
|
- **Language:** TypeScript avec strict mode activé
|
|
- **Styling:** Tailwind CSS v4.0.0 + shadcn/ui (style "new-york")
|
|
- **UI Library:** shadcn/ui v1.4.4 (canary pour Tailwind v4)
|
|
- **API Routes:** Node.js (intégré à Next.js) pour APIs légères, authentification
|
|
- **Bundler:** Turbopack (activé par défaut dans Next.js 16)
|
|
- **Port:** 3000 (développement), production (Vercel)
|
|
|
|
### Backend (Python FastAPI)
|
|
- **Framework:** FastAPI 0.128.0 (latest stable)
|
|
- **Language:** Python 3.10+
|
|
- **ORM Primaire:** SQLAlchemy 2.0.45 (async support)
|
|
- **Documentation:** OpenAPI 3.1 (Swagger UI + Redoc)
|
|
- **Migrations:** Alembic pour les schémas SQLAlchemy
|
|
- **Port:** 8000 (développement)
|
|
|
|
### State Management
|
|
- **État UI Local:** Zustand v5.0.9 avec `unstable_ssrSafe`
|
|
- **Données Serveur:** React Query (TanStack Query)
|
|
- **Pattern:** Séparation claire (Zustand pour UI, React Query pour API)
|
|
|
|
### Base de Données
|
|
- **Phase 1:** SQLite (fichier local, partagé entre FastAPI et Next.js)
|
|
- **ORM FastAPI:** SQLAlchemy 2.0.45 avec migrations Alembic
|
|
- **ORM Next.js:** Drizzle ORM v0.44.7 avec `better-sqlite3` driver
|
|
- **Phase 2+:** PostgreSQL (migration planifiée depuis SQLite)
|
|
|
|
### Authentification & Sécurité
|
|
- **Solution:** Better Auth v1.4.4 (compatible Next.js 16)
|
|
- **Authorization:** RBAC (Gratuit vs Premium)
|
|
- **Session:** JWT (stateless) + Secure cookies
|
|
- **HTTPS:** TLS 1.3 obligatoire en production
|
|
- **Headers de Sécurité:** CSP, X-Frame-Options, SameSite
|
|
|
|
### Communication Asynchrone
|
|
- **Queue:** RabbitMQ pour traitement asynchrone
|
|
- **Pattern:** Producer/Consumer avec events JSON `{event, version, timestamp, data, metadata}`
|
|
- **Usage:** Découplage scraping ↔ analyse, gestion des pics de charge
|
|
|
|
### Infrastructure & Déploiement
|
|
- **Frontend:** Vercel (auto-build, CDN intégré)
|
|
- **Backend:** Railway ou Render (budget 10-20€/mois Phase 1)
|
|
- **CI/CD:** GitHub Actions (lint + tests sur PR, auto-deploy)
|
|
- **Monitoring Phase 1:** Sentry (erreurs), UptimeRobot (uptime)
|
|
|
|
### API Externes
|
|
- **Twitter API:** 1000 req/heure (gratuit, rate limiting critique)
|
|
- **Reddit API:** Non limité (généreuse)
|
|
- **RSS Feeds:** Diverses sources sportives
|
|
|
|
---
|
|
|
|
## Décisions Architecturales Critiques
|
|
|
|
### Architecture des Données
|
|
- **Database:** SQLite Phase 1 → PostgreSQL Phase 2+ (migration planifiée)
|
|
- **Naming:** `snake_case` pour tables et colonnes (cohérence SQLAlchemy/Drizzle)
|
|
- **Foreign Keys:** Format `{table}_id` (ex: `user_id`, `match_id`)
|
|
- **Indexes:** Format `idx_{table}_{column}` (ex: `idx_users_email`)
|
|
|
|
### API & Communication
|
|
- **Pattern:** RESTful avec OpenAPI 3.1
|
|
- **Response Wrapper:** `{data, meta}` (succès) ou `{error, meta}` (erreur)
|
|
- **Date Format:** ISO 8601 UTC (ex: `"2026-01-15T10:30:00Z"`)
|
|
- **JSON Naming:** `snake_case` dans les réponses API (cohérence avec DB)
|
|
- **Rate Limiting:** 10 req/min (Gratuit), 100 req/min (Premium)
|
|
|
|
### Frontend Architecture
|
|
- **Naming Python:** `snake_case` (fichiers, fonctions, variables, classes PascalCase)
|
|
- **Naming TypeScript/JS:** `camelCase` (fonctions, variables), `PascalCase` (composants, types), `kebab-case.tsx` (fichiers)
|
|
- **Hooks:** Préfixe `use` (ex: `useUser()`, `usePredictions()`)
|
|
- **Constants:** `UPPER_SNAKE_CASE` (ex: `MAX_PREDICTIONS_FREE`)
|
|
|
|
### Patterns d'Implémentation
|
|
- **Organisation du Code:** Feature-based avec co-location des tests et composants
|
|
- **Gestion d'État:** Updates immutables uniquement (jamais mutation directe)
|
|
- **Gestion d'Erreurs:** Format standardisé avec codes d'erreur et logging à Sentry
|
|
- **Server Components:** Par défaut, `use client` uniquement si nécessaire (interactivité, hooks)
|
|
- **Async/Await:** FastAPI async partout, Next.js Server Components pour réduction bundle
|
|
|
|
---
|
|
|
|
## Structure du Projet
|
|
|
|
### Organisation Globale
|
|
```
|
|
chartbastan/
|
|
├── frontend/ # Next.js 16 Application
|
|
├── backend/ # FastAPI Application
|
|
├── docs/ # Documentation projet
|
|
└── monitoring/ # Prometheus + Grafana (Phase 2+)
|
|
```
|
|
|
|
### Frontend (Next.js)
|
|
- **Route:** `src/app/` (App Router)
|
|
- **Composants UI:** `src/components/ui/` (shadcn/ui copiés localement)
|
|
- **Features:** `src/components/features/` (organisés par domaine fonctionnel)
|
|
- **Stores:** `src/stores/` (Zustand)
|
|
- **Hooks:** `src/hooks/` (React hooks custom)
|
|
- **Utils:** `src/lib/` (helpers, API client, validations Zod)
|
|
- **API Routes:** `src/app/api/` (Next.js API routes pour auth légère)
|
|
- **Types:** `src/types/` (TypeScript types)
|
|
- **Tests:** `tests/` (co-locés ou séparé)
|
|
|
|
### Backend (FastAPI)
|
|
- **Routes:** `app/api/v1/` (REST endpoints)
|
|
- **Models:** `app/models/` (SQLAlchemy)
|
|
- **Schemas:** `app/schemas/` (Pydantic pour validation)
|
|
- **Services:** `app/services/` (logique métier)
|
|
- **Repositories:** `app/repositories/` (couche d'accès aux données)
|
|
- **Scrapers:** `app/scrapers/` (modules de scraping)
|
|
- **Workers:** `app/workers/` (background workers)
|
|
- **Queues:** `app/queues/` (gestion RabbitMQ)
|
|
- **ML:** `app/ml/` (analyse de sentiment, calcul d'énergie)
|
|
- **Utils:** `app/utils/` (logger, validators, formatters)
|
|
|
|
---
|
|
|
|
## Conventions de Code & Nommage
|
|
|
|
### Python (FastAPI)
|
|
- **Fichiers:** `snake_case.py` (ex: `user_service.py`, `prediction_service.py`)
|
|
- **Classes:** `PascalCase` (ex: `UserService`, `PredictionService`)
|
|
- **Fonctions:** `snake_case` (ex: `get_user_by_id()`, `calculate_energy_score()`)
|
|
- **Variables:** `snake_case` (ex: `user_id`, `energy_score`, `is_premium`)
|
|
- **Constantes:** `UPPER_SNAKE_CASE` (ex: `MAX_PREDICTIONS_FREE`, `API_RATE_LIMIT`)
|
|
|
|
### TypeScript/JavaScript (Next.js)
|
|
- **Fichiers Composants:** `PascalCase.tsx` ou `kebab-case.tsx` (ex: `UserCard.tsx`, `user-card.tsx`)
|
|
- **Fichiers Utilitaires:** `camelCase.ts` (ex: `api.ts`, `utils.ts`, `constants.ts`)
|
|
- **Composants UI:** `PascalCase` (ex: `Button`, `Card`, `Dialog`)
|
|
- **Hooks:** `camelCase` avec préfixe `use` (ex: `useUser()`, `usePredictions()`)
|
|
- **Fonctions:** `camelCase` (ex: `getUserById()`, `calculateEnergyScore()`)
|
|
- **Variables:** `camelCase` (ex: `userId`, `energyScore`, `isPremium`)
|
|
- **Constantes:** `UPPER_SNAKE_CASE` (ex: `MAX_PREDICTIONS_FREE`, `API_RATE_LIMIT`)
|
|
|
|
### Database (SQLite)
|
|
- **Tables:** `snake_case` pluriel (ex: `users`, `predictions`, `matches`, `energy_scores`)
|
|
- **Colonnes:** `snake_case` (ex: `user_id`, `created_at`, `is_premium`)
|
|
- **Foreign Keys:** `{table}_id` (ex: `user_id`, `match_id`, `prediction_id`)
|
|
- **Indexes:** `idx_{table}_{column}` (ex: `idx_users_email`, `idx_predictions_match_id`)
|
|
|
|
---
|
|
|
|
## Formats Standards
|
|
|
|
### API REST (FastAPI)
|
|
- **Endpoints:** Pluriels, `snake_case`, `/api/v1/` (ex: `/api/v1/users`, `/api/v1/predictions`)
|
|
- **Route Params:** Format `{id}` (ex: `/api/v1/users/{id}`)
|
|
- **Query Params:** `snake_case` (ex: `?user_id=123&limit=10`)
|
|
- **Headers:** Préfixe `X-` pour customs (ex: `X-API-Key`, `X-RateLimit-Remaining`)
|
|
- **Success Response:**
|
|
```json
|
|
{
|
|
"data": { ... },
|
|
"meta": {
|
|
"timestamp": "ISO_8601",
|
|
"version": "v1"
|
|
}
|
|
}
|
|
```
|
|
- **Error Response:**
|
|
```json
|
|
{
|
|
"error": {
|
|
"code": "ERROR_CODE",
|
|
"message": "Message utilisateur-friendly",
|
|
"details": { ... }
|
|
},
|
|
"meta": {
|
|
"timestamp": "ISO_8601",
|
|
"request_id": "id_unique"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Events RabbitMQ
|
|
- **Event Naming:** `{entity}.{action}` (ex: `user.created`, `prediction.updated`, `match.analyzed`)
|
|
- **Format:**
|
|
```json
|
|
{
|
|
"event": "prediction.created",
|
|
"version": "1.0",
|
|
"timestamp": "ISO_8601",
|
|
"data": { ... },
|
|
"metadata": {
|
|
"source": "api",
|
|
"user_id": 123
|
|
}
|
|
}
|
|
```
|
|
|
|
### JSON dans Frontend/Backend
|
|
- **Backend → Frontend:** `snake_case` (cohérence avec DB)
|
|
- **Frontend → Backend:** `camelCase` (convertis en `snake_case` côté serveur)
|
|
- **Booléens:** `true`/`false` (jamais 1/0)
|
|
- **Nulls:** `null` (jamais `undefined` en JSON)
|
|
- **Dates:** ISO 8601 UTC (ex: `"2026-01-15T10:30:00Z"`)
|
|
- **Tableaux:** Toujours des arrays (jamais d'objets pour listes)
|
|
|
|
---
|
|
|
|
## Patterns de Qualité & Testing
|
|
|
|
### Code Quality
|
|
- **Python:** PEP 8 compliance, black formatting, type hints obligatoires
|
|
- **TypeScript:** Strict mode activé, no implicit any
|
|
- **Linting:**
|
|
- Python: flake8/black
|
|
- TypeScript/Next.js: ESLint avec règles Next.js
|
|
- **Testing:**
|
|
- Unit: pytest pour Python, Vitest + Testing Library pour React
|
|
- Integration: Tests d'intégration entre services
|
|
- E2E: Playwright pour scénarios utilisateur finaux
|
|
|
|
### Gestion d'Erreurs
|
|
- **Logging:** Logger structuré en JSON dans tous les services
|
|
- **Monitoring:** Sentry pour tracking des erreurs en production
|
|
- **Error Boundary:** React Error Boundaries pour erreurs de rendu
|
|
- **Try/Catch:** Toujours logger avec contexte avant relancer
|
|
|
|
---
|
|
|
|
## Anti-Patterns à Éviter
|
|
|
|
### État
|
|
❌ **Mutation directe:** `state.count++` (utiliser `setCount(c => c + 1)`)
|
|
❌ **State dans composants:** State local dans les composants (utiliser stores globaux)
|
|
|
|
### Nommage
|
|
❌ **Mixing conventions:** `user_id` (Python) + `userId` (TypeScript) dans le même fichier
|
|
❌ **Incohérence:** Tables `Users` dans un endroit, `users` dans un autre (tout en `snake_case` pluriel)
|
|
|
|
### API
|
|
❌ **Response variable:** Parfois `{data}` d'autres fois `{error}` (toujours wrapper standardisé)
|
|
❌ **Magic numbers:** `1000` dans le code sans constante (utiliser `MAX_TWEETS_PER_HOUR`)
|
|
❌ **HTTP status codes:** 200 pour succès, 404 pour "not found" (respecter les standards)
|
|
|
|
### Testing
|
|
❌ **Test manquants:** Fonctions sans tests unitaires
|
|
❌ **Mocks statiques:** Données de test en dur dans le code (utiliser factories)
|
|
❌ **Tests non isolés:** Tests qui touchent la base de données ou APIs externes
|
|
|
|
---
|
|
|
|
## Points d'Intégration Critiques
|
|
|
|
### Frontend ↔ Backend
|
|
- **Communication:** HTTP REST via `lib/api.ts` client
|
|
- **Cache:** React Query pour synchronisation et cache client
|
|
- **Auth:** JWT token dans header `Authorization: Bearer {token}`
|
|
- **Conversion:** `camelCase` ↔ `snake_case` automatique côté frontend
|
|
|
|
### FastAPI ↔ RabbitMQ
|
|
- **Pattern:** Producer/Consumer avec events JSON
|
|
- **Tâches:** Scraping, analysis, notifications
|
|
- **Workers:** Consommateurs asynchrones des tâches RabbitMQ
|
|
|
|
### Base de Données Partagée
|
|
- **FastAPI:** SQLAlchemy sync sessions
|
|
- **Next.js:** Drizzle sync queries
|
|
- **Partage:** SQLite fichier partagé via filesystem (Phase 1)
|
|
|
|
### APIs Externes
|
|
- **Twitter:** Scraping avec rate limiting (1000 req/heure)
|
|
- **Reddit:** Scraping sans limite stricte
|
|
- **RSS:** Scraping de multiples sources sportives
|
|
|
|
---
|
|
|
|
## Workflow de Développement
|
|
|
|
### Configuration de l'Environnement
|
|
- **Développement:** `.env.local` (jamais commité dans git)
|
|
- **Template:** `.env.example` (valeurs placeholder)
|
|
- **Variables:** Utiliser les variables d'environnement, jamais de secrets en dur
|
|
|
|
### Branching Git
|
|
- **Conventions:** `feature/short-description` pour nouvelles fonctionnalités
|
|
- **Main:** `main` toujours stable et deployable
|
|
- **Release:** Tags `vX.Y.Z` (ex: `v1.0.0`)
|
|
|
|
### CI/CD (GitHub Actions)
|
|
- **On Pull Request:** Lint + tests automatiques
|
|
- **On Merge:** Build + auto-deploy
|
|
- **Environnements:** Séparés dev/staging/production
|
|
|
|
---
|
|
|
|
## Optimisations de Performance
|
|
|
|
### Frontend (Next.js)
|
|
- **Server Components:** Maximiser pour réduire le bundle client
|
|
- **Code Splitting:** Par route automatique (App Router)
|
|
- **Lazy Loading:** Composants lourds (D3.js) avec dynamic imports
|
|
- **Image Optimization:** Next.js Image component
|
|
- **Font:** next/font pour optimisation des polices
|
|
|
|
### Backend (FastAPI)
|
|
- **Async:** Toujours async/await pour I/O operations
|
|
- **Database:** Requêtes optimisées, indexes appropriés
|
|
- **Cache:** Phase 2+ : Redis pour données fréquemment accédées
|
|
- **Connection Pooling:** SQLAlchemy connection pooling (Phase 2+)
|
|
|
|
---
|
|
|
|
## Checklist d'Implémentation
|
|
|
|
### Avant de Commiter
|
|
- [ ] Code linté (ESLint/flake8)
|
|
- [ ] Tests passants (pytest/Vitest)
|
|
- [ ] Types corrects (no `any` implicites)
|
|
- [ ] Documentation mise à jour si nécessaire
|
|
- [ ] Secrets pas dans le code
|
|
|
|
### Déploiement
|
|
- [ ] Variables d'environnement configurées (Vercel/Railway)
|
|
- [ ] Base de données attachée
|
|
- [ ] Monitoring actif (Sentry)
|
|
- [ ] HTTPS activé en production
|
|
- [ ] Rate limiting configuré
|
|
|
|
---
|
|
|
|
**Ce fichier est la source unique de vérité pour l'implémentation cohérente du projet chartbastan. Tous les agents AI doivent le lire avant d'implémenter du code.**
|