1. Présentation du projet
Contexte et objectifs de l'application CuisineWeek
CuisineWeek est une application mobile Android développée en Kotlin dans le cadre du BTS SIO option SLAM. Elle permet à l'utilisateur de consulter des recettes de cuisine, de planifier ses repas à la semaine et de générer automatiquement une liste de courses à partir du menu planifié.
Fonctionnalités principales
| Module | Fonctionnalité | Statut |
| Catalogue | Affichage de la liste des recettes avec RecyclerView | ✅ Implémenté |
| Catalogue | Recherche et filtrage des recettes | 🔄 Prévu Sprint 5 |
| Menu semaine | Navigation jour par jour avec DatePicker | ✅ Implémenté |
| Menu semaine | Ajout / suppression de repas (Midi, Soir, Matin) | ✅ Implémenté |
| Liste courses | Scan code-barre via OpenFoodFacts | ✅ Implémenté |
| Liste courses | Cases à cocher et partage | ✅ Implémenté |
| Recettes perso | Création de recettes personnalisées | 🔄 Prévu Sprint 5 |
2. Architecture MVVM
Model – View – ViewModel : séparation des responsabilités
L'application suit le pattern architectural MVVM (Model-View-ViewModel) recommandé par Google pour les applications Android. Ce pattern garantit une séparation claire entre la logique métier et l'interface utilisateur.
🖥️ VIEW — Couche présentation
MainActivity
RecettesFragment
SemaineFragment
CoursesFragment
SelectionRecetteDialog
RecetteAdapter
ArticleCoursesAdapter
⬆️ observe LiveData ⬇️ appelle fonctions
🧠 VIEWMODEL — Couche logique
RecetteViewModel
MenuViewModel
CoursesViewModel
⬆️ LiveData ⬇️ appelle fonctions suspend
📦 REPOSITORY — Couche d'accès aux données
RecetteRepository
RetrofitClient (OpenFoodFacts)
⬆️ entités ⬇️ requêtes SQL / HTTP
🗄️ DATA — Couche données
AppDatabase (Room)
RecetteDao
MenuDao
ArticleCoursesDao
OpenFoodFactsApi (Retrofit)
DatabaseSeeder
Principes appliqués
| Principe | Application dans CuisineWeek |
| Séparation des responsabilités | Chaque couche a un rôle unique et ne connaît pas les détails des autres |
| Réactivité (LiveData) | L'UI se met à jour automatiquement quand les données changent en BDD |
| Asynchronisme (Coroutines) | Toutes les opérations BDD et réseau s'exécutent en arrière-plan (Dispatchers.IO) |
| Singleton (AppDatabase) | Une seule instance de la BDD dans toute l'application (pattern @Volatile + synchronized) |
| Injection de dépendances | Les DAOs sont injectés dans les ViewModels via AppDatabase.getDatabase() |
3. Classes
Représentation UML des classes principales et leurs relations
Entités (data/entity)
PK id : Int
+ nom : String
+ description : String
+ tempsPrep : Int
+ tempsCuisson : Int
+ nbPersonnes : Int
+ difficulte : String
FK categorieId : Int?
+ imageUri : String?
+ estPersonnalisee : Boolean
PK id : Int
+ nom : String
+ icone : String
PK id : Int
+ nom : String
+ uniteDefaut : String
+ categorieCourses : String
PK/FK recetteId : Int
PK/FK ingredientId : Int
+ quantite : Double
+ unite : String
PK id : Int
+ semaineDu : String
+ nbPersonnes : Int
PK/FK menuId : Int
PK/FK recetteId : Int
PK jour : String
PK typeRepas : String
PK id : Int
+ nom : String
+ quantite : String
+ codeBarres : String
+ coche : Boolean
DAOs (data/dao)
getAllRecettes() : LiveData<List<Recette>>
searchRecettes(q) : LiveData<List<Recette>>
getRecetteById(id) : Recette?
getCount() : Int
insert(recette) : Long
update(recette)
delete(recette)
getMenuBySemaine(s) : MenuSemaine?
insertMenu(menu) : Long
insertMenuRecette(mr)
deleteMenuRecette(id,j,t)
getRecetteIdPourRepas() : Int?
getRecettesDuJour() : LiveData
getAllArticles() : LiveData<List>
insert(article)
update(article)
delete(article)
deleteAll()
ViewModels (viewmodel)
- repository : RecetteRepository
+ toutesLesRecettes : LiveData
rechercherRecettes(q)
inserer(recette)
supprimer(recette)
- menuDao : MenuDao
- recetteDao : RecetteDao
+ jourActuel : LiveData<LocalDate>
+ recetteMidi : LiveData<Recette?>
+ recetteSoir : LiveData<Recette?>
+ recetteMatin : LiveData<Recette?>
jourSuivant()
jourPrecedent()
allerALaDate(date)
ajouterRecette(id, type)
supprimerRepas(type)
chargerMenuDuJour()
- dao : ArticleCoursesDao
+ articles : LiveData<List>
ajouterDepuisScan(barcode)
toggleCoche(article)
supprimer(article)
toutEffacer()
5. Modèle Logique de Données (MLD)
Traduction du modèle conceptuel en tables relationnelles pour la base de données CuisineWeek
CATEGORIE (
id,
nom
)
RECETTE (
id,
nom,
description,
tempsPrep,
tempsCuisson,
nbPersonnes,
difficulte,
#categorieId → CATEGORIE.id
)
INGREDIENT (
id,
nom,
unite
)
RECETTE_INGREDIENT (
id,
#recetteId → RECETTE.id,
#ingredientId → INGREDIENT.id,
quantite
)
MENU_SEMAINE (
id,
semaine,
dateDebut,
dateFin
)
MENU_RECETTE (
id,
#menuId → MENU_SEMAINE.id,
#recetteId → RECETTE.id,
jour,
momentRepas
)
ARTICLE_COURSES (
id,
nom,
quantite,
coche,
#menuId → MENU_SEMAINE.id
)
Contraintes d'intégrité
| Table |
Contrainte |
Comportement |
| RECETTE |
categorieId → CATEGORIE.id |
SET NULL si catégorie supprimée |
| RECETTE_INGREDIENT |
recetteId → RECETTE.id |
CASCADE DELETE |
| RECETTE_INGREDIENT |
ingredientId → INGREDIENT.id |
RESTRICT |
| MENU_RECETTE |
menuId → MENU_SEMAINE.id |
CASCADE DELETE |
| MENU_RECETTE |
recetteId → RECETTE.id |
RESTRICT |
| ARTICLE_COURSES |
menuId → MENU_SEMAINE.id |
CASCADE DELETE |
Relations principales
CATEGORIE
1 -------- N
RECETTE
RECETTE
N -------- N
via RECETTE_INGREDIENT
INGREDIENT
MENU_SEMAINE
1 -------- N
MENU_RECETTE
N
|
1
RECETTE
MENU_SEMAINE
1 -------- N
ARTICLE_COURSES
5. Diagramme de cas d'utilisation
Actions disponibles pour l'utilisateur (acteur unique — pas de gestion de comptes)
🍳 Module Recettes
- Consulter la liste des recettes
- Rechercher une recette par nom
- Filtrer par catégorie
- Consulter le détail d'une recette
- Créer une recette personnalisée
- Modifier une recette personnalisée
- Supprimer une recette personnalisée
📅 Module Menu Semaine
- Naviguer entre les jours
- Sélectionner une date via DatePicker
- Ajouter une recette au midi
- Ajouter une recette au soir
- Ajouter une recette au matin
- Changer une recette planifiée
- Supprimer un repas planifié
🛒 Module Courses
- Scanner un code-barre produit
- Ajouter un produit à la liste
- Cocher un article acheté
9. Intégration API OpenFoodFacts
Documentation de l'intégration de l'API externe
Endpoint utilisé
GET https://world.openfoodfacts.org/api/v0/product/{barcode}.json
GET https://world.openfoodfacts.org/api/v0/product/3017620422003.json
Réponse JSON (extraite)
{
"status": 1,
"product": {
"product_name": "Nutella",
"quantity": "400g",
"nutrition_grades": "e"
}
}
Modèles de données Kotlin
| Classe Kotlin | Champ JSON | Type | Description |
| OpenFoodFactsResponse.status | status | Int | 1=trouvé, 0=introuvable |
| OpenFoodFactsResponse.product | product | Product? | Objet produit (nullable) |
| Product.nom | product_name | String? | Nom du produit |
| Product.quantite | quantity | String? | Quantité (ex: "400g") |
| Product.nutriscore | nutrition_grades | String? | Lettre A→E |
Gestion des erreurs réseau
try {
val response = RetrofitClient.api.getProduct(barcode)
if (response.status == 1 && response.product != null) {
}
} catch (e: Exception) {
e.printStackTrace()
}
10. Stack technique
Toutes les technologies et bibliothèques utilisées
| Catégorie | Technologie | Version | Rôle |
| Langage | Kotlin | 2.1.0 | Langage principal Android |
| IDE | Android Studio | Meerkat 2024.3 | Environnement de développement |
| Build | Gradle | 8.11.1 | Gestion des dépendances et compilation |
| Build | Android Gradle Plugin | 8.9.1 | Plugin Android pour Gradle |
| Build | KSP | 2.1.0-1.0.29 | Génération de code Room à la compilation |
| BDD locale | Room | 2.6.1 | ORM SQLite Android (Jetpack) |
| Architecture | ViewModel | 2.7.0 | Survie aux rotations d'écran |
| Architecture | LiveData | 2.7.0 | Données observables réactives |
| Architecture | Coroutines | 1.7.3 | Asynchronisme (Dispatchers.IO) |
| UI | RecyclerView | 1.3.2 | Listes scrollables performantes |
| UI | CardView | 1.0.0 | Cartes avec ombres et coins arrondis |
| UI | Material Design | 1.11.0 | BottomNavigationView, FAB |
| UI | ConstraintLayout | 2.1.4 | Layouts flexibles et contraints |
| Réseau | Retrofit | 2.9.0 | Client HTTP pour l'API REST |
| Réseau | Gson Converter | 2.9.0 | Désérialisation JSON → Kotlin |
| Scanner | ZXing Android Embedded | 4.3.0 | Scan code-barre via caméra |
| API externe | OpenFoodFacts | v0 | Base de données produits alimentaires |
| Navigation | Fragment + FragmentManager | 1.6.2 | Navigation entre les écrans |
CuisineWeek · Documentation Technique v1.0 · BTS SIO SLAM 2025–2026