Carnet de recettes familial : import par URL ou photo (extraction IA), recherche textuelle et sémantique, chat contextuel par recette, PWA avec partage depuis le navigateur.
- Node.js (LTS recommandé)
- pnpm 10.x (
packageManagerdu projet :[email protected]) - Compte OpenAI pour les fonctionnalités IA (import, chat, embeddings)
pnpm installSi Vite échoue au démarrage à cause d’esbuild, reconstruire le binaire :
pnpm rebuild esbuildpnpm devCette commande lance convex dev --start vite :
| Service | URL |
|---|---|
| Application (Vite) | http://localhost:5173 |
| Backend Convex local | http://127.0.0.1:3210 |
| Tableau de bord Convex | http://127.0.0.1:6790/?d=anonymous-workspace |
Au premier convex dev, choisir « Start without an account (run Convex locally) » pour un backend anonyme local.
Le fichier .env.local (ignoré par git) est généré automatiquement avec VITE_CONVEX_URL.
Une fois le backend Convex actif :
pnpx @convex-dev/authCela génère les clés JWT nécessaires à @convex-dev/auth (connexion par mot de passe).
pnpm seedCompte par défaut :
| Champ | Valeur |
|---|---|
[email protected] |
|
| Mot de passe | recettes123 |
| Nom affiché | Famille |
Les variables d’environnement Convex (pas le fichier .env du frontend) :
pnpx convex env set OPENAI_API_KEY <votre-clé>Vérifier les variables :
pnpx convex env list| Tâche | Commande |
|---|---|
| Dev (backend + frontend) | pnpm dev |
| Frontend seul | pnpm dev:frontend |
| Backend Convex seul | pnpm dev:backend |
| Lint | pnpm lint |
| Vérification TypeScript | pnpm typecheck |
| Build production frontend | pnpm build |
| Aperçu du build | pnpm preview |
| Format (Prettier) | pnpm format |
| Compte de test | pnpm seed |
Définies avec pnpx convex env set <NOM> <valeur> (local) ou via le dashboard / CLI en production (--prod).
| Variable | Obligatoire | Description | Valeur par défaut |
|---|---|---|---|
OPENAI_API_KEY |
Oui (IA) | Clé API OpenAI | — |
OPENAI_IMPORT_MODEL |
Non | Modèle pour l’import depuis une URL (extraction texte HTML) | gpt-5.4-mini |
OPENAI_VISION_MODEL |
Non | Modèle pour l’import depuis des photos (vision) | gpt-4.1 |
OPENAI_CHAT_MODEL |
Non | Modèle du chat contextuel sur une recette | gpt-5.4-mini |
OPENAI_EMBEDDING_MODEL |
Non | Modèle des embeddings (recherche sémantique) | text-embedding-3-small |
VAPID_PUBLIC_KEY |
Non (push) | Clé publique VAPID pour l’envoi des notifications push | — |
VAPID_PRIVATE_KEY |
Non (push) | Clé privée VAPID (secret, côté Convex uniquement) | — |
VAPID_SUBJECT |
Non (push) | Identité de l’émetteur VAPID : mailto:… en dev ; en prod, l’autorité du site (https://votre-domaine, sans chemin) |
— |
Exemples de surcharge :
pnpx convex env set OPENAI_CHAT_MODEL gpt-4.1-mini
pnpx convex env set OPENAI_EMBEDDING_MODEL text-embedding-3-smallEn production :
pnpx convex env set OPENAI_API_KEY <clé> --prod| Fichier / variable | Rôle |
|---|---|
.env.local → VITE_CONVEX_URL |
URL du déploiement Convex pour le client React (créé par convex dev) |
.env.local → VITE_VAPID_PUBLIC_KEY |
Même clé publique que VAPID_PUBLIC_KEY (abonnement push côté navigateur) |
CONVEX_SITE_URL |
Utilisé côté Convex pour la config auth (convex/auth.config.ts) |
Ne pas committer .env.local ni de clés API.
| Constante | Valeur | Fichier |
|---|---|---|
| Photos par recette | 8 max | convex/lib/recipeImageLimits.ts |
| Taille max par photo | 5 Mo | idem |
| Dimensions embedding | 1536 | convex/lib/recipeEmbeddings.ts (aligné sur text-embedding-3-small) |
- Développement :
pnpm seed(compte famille ci-dessus). - Production — premier compte : l’inscription publique est désactivée ; créer le compte initial via le dashboard Convex, mutation interne
admin:createUserAccount, par exemple :{ "email": "[email protected]", "password": "motdepasse", "name": "Nouveau" } - Comptes suivants : une fois connecté, les autres comptes se gèrent depuis Paramètres → Utilisateurs (création, modification, mot de passe, suppression).
recettes/
├── src/ # React 19, Vite 7, Tailwind 4, shadcn/ui (UI en français)
├── convex/ # Backend Convex (queries, mutations, actions, schéma)
│ ├── schema.ts # Tables recipes, chat, pushSubscriptions, auth
│ └── lib/ # IA, embeddings, import URL, etc.
├── public/ # Assets PWA
└── components.json # Config shadcn/ui
- Frontend : React Router 7,
@convex-dev/auth, thème clair/sombre, PWA (partage vers/import, notifications push). - Backend : Convex (DB temps réel, stockage fichiers, recherche full-text + vectorielle).
- Auth : fournisseur mot de passe (
@convex-dev/auth). - IA : OpenAI via actions Convex (
convex/lib/recipeAi.ts,recipeChatAi.ts,recipeEmbeddings.ts).
Il n’y a pas de création manuelle de recette vide : les recettes entrent par import URL ou import photo, puis éventuelle édition dans l’interface.
- Liste et fiche recette (ingrédients, étapes, notes, tags, photos, couverture).
- Import depuis une URL de page recette (IA + téléchargement optionnel de l’image de couverture).
- Import depuis une ou plusieurs photos (jusqu’à 8, 5 Mo chacune).
- Recherche textuelle (index
searchText) et recherche sémantique (embeddings). - Conversations de chat par recette (historique persisté).
- Notifications push lorsqu’un autre membre importe une recette (image de couverture incluse si disponible).
- PWA installable ; cible de partage
GET /importpour préremplir l’import depuis une autre app.
Configuration une fois par déploiement (local ou production avec --prod sur les commandes convex env set) :
npx web-push generate-vapid-keys
pnpx convex env set VAPID_PUBLIC_KEY <clé_publique>
pnpx convex env set VAPID_PRIVATE_KEY <clé_privée>VAPID_SUBJECT identifie l’émetteur auprès des services push (passé à web-push comme « subject ») :
- Développement local : une adresse de contact suffit, par ex.
mailto:[email protected]. - Production : l’autorité du serveur qui sert la PWA, c’est-à-dire l’origine HTTPS du site (schéma + hôte, sans chemin), par ex.
https://recettes.example.com.
# local
pnpx convex env set VAPID_SUBJECT mailto:[email protected]
# production
pnpx convex env set VAPID_SUBJECT https://recettes.example.com --prodExposer la même clé publique au build du frontend :
| Environnement | Variable |
|---|---|
| Développement | VITE_VAPID_PUBLIC_KEY dans .env.local, puis redémarrer pnpm dev |
| Production (ex. Vercel) | VITE_VAPID_PUBLIC_KEY dans les variables du projet hébergeur (même valeur que VAPID_PUBLIC_KEY) |
Les push nécessitent HTTPS en production. Sur iOS, la PWA doit être installée sur l’écran d’accueil (Safari 16.4+).
Si des recettes existent sans index de recherche ou sans embedding :
pnpx convex run recipeSearch:backfillSearchText
pnpx convex run recipeSearch:backfillEmbeddings(OPENAI_API_KEY requise pour les embeddings.)
- Guidelines API :
convex/_generated/ai/guidelines.md(à lire avant de modifier le backend). - Fichiers générés :
convex/_generated/(ne pas éditer à la main ; régénérés parconvex dev). - Instructions agents / cloud : voir aussi AGENTS.md.
pnpx shadcn@latest add <composant>Les composants sont ajoutés sous src/components/ui selon components.json.
- Se connecter à Convex :
pnpx convex login. - Configurer les variables d’environnement en production (
pnpx convex env set ... --prod), notammentOPENAI_API_KEYet, pour les notifications push,VAPID_PUBLIC_KEY,VAPID_PRIVATE_KEY,VAPID_SUBJECT. - Déployer le backend et builder le frontend en une commande :
pnpx convex deploy --cmd='npm run build'Cette commande pousse les fonctions Convex vers la production, injecte VITE_CONVEX_URL pour le build, puis exécute npm run build (tsc -b && vite build). Le site statique se trouve dans dist/.
- Héberger le contenu de
dist/(Vercel, Netlify, etc.). Inutile de définirVITE_CONVEX_URLmanuellement dans la CI si vous utilisez cette commande.
Le dépôt inclut un fichier [vercel.json](./vercel.json) à la racine. Il redirige toutes les routes vers index.html pour que React Router gère le routage côté client (/import, /recipes/:id, etc.) sans erreur 404 sur un rechargement direct ou un lien profond.
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}Sur Vercel : connecter le repo, utiliser la même commande de build que ci-dessus (pnpx convex deploy --cmd='npm run build') et le répertoire de sortie dist. Définir aussi VITE_VAPID_PUBLIC_KEY dans les variables d’environnement du projet (même valeur que VAPID_PUBLIC_KEY).
En développement, utiliser **pnpx convex dev** (ou pnpm dev), pas convex deploy, qui cible la production.
| Problème | Piste |
|---|---|
| Erreur esbuild / Vite | pnpm rebuild esbuild |
| Import ou chat IA indisponible | pnpx convex env set OPENAI_API_KEY ... puis redémarrer pnpm dev |
| État local Convex perdu / incohérent | Données anonymes dans ~/.convex/anonymous-convex-backend-state/ |
| Auth / JWT | Relancer pnpx @convex-dev/auth après un nouveau déploiement local |
| Connexion refusée | En dev : pnpm seed. En prod (premier compte) : admin:createUserAccount via le dashboard Convex |
| Push non reçues | Vérifier les clés VAPID (Convex + VITE_VAPID_PUBLIC_KEY), abonnement activé sur l’appareil, HTTPS en production |