Skip to content

Dette technique au 18/03/2026

MVP trés solide mais pas industrialisé, Startup 8/10 - Entreprise: 4/10

1.1 Absence total de test unitaire. Urgent

Section titled “1.1 Absence total de test unitaire. Urgent”

Par soucis de rapidité les features ont étés priviligé aux tests unitaires (pas de TDD ici), les mises à jour futures de l’application par des tiers ou une équipe future présentent donc un risque aujourd’hui.

Les cubits utilisent une condition avant d’appeler les repository afin de permetre l’injection : this.repoParam == null ? defaultRepo() : repoInParam() mais quelques uns font des appels en dur :

  • AuthCubit -> force AuthRepository()
  • ReadyToWorkCubit -> force WorkerStatusRepository(), LocationService(), SocketService()

1.3 Écart de type models front vs back Important

Section titled “1.3 Écart de type models front vs back Important”

Certains models en front, de part leur “vieilles” ou un refactor récent en back s’écarte au fetch des models back, forçant des cast aprés cout dans les cubits ou pire dans l’ui. Parfois c’est à raison (des vars inéxistantes crée dynamiquement par les controllers back) mais souvent c’est à tord. Sont suspectés :

  • User
  • Mission (Important full String)
  • WorkerProfile
  • Looking
  • Rank
  • Notification
  • TokenLedger
  • Feedback

Correlé avec les tests unitaires, ici l’idée est de bloquer le push en prod en cas de test cassé et d’url api dev en prod ou prod en dev. En l’état c’est inéxistant et ça posera un problème en cas d’agrandissement de l’équipe.

Le front renvoie ses propres messages génériques dans les toasters et non une adaptation du message serveur. Il faut revoir ça.

1.6 Error handling : 3 patterns incompatibles dans les repositories Moyen

Section titled “1.6 Error handling : 3 patterns incompatibles dans les repositories Moyen”

Les repositories utilisent 3 conventions différentes pour remonter les erreurs aux cubits :

  • Pattern A (data?, ApiErrorResponse?) → ProfileRepo, UserRepo, ChatRepo
  • Pattern B (data?, String?) → WorkerDashboardRepo, NotificationRepo, SkillRepo
  • Pattern C throw Exception(...) → TokenRepo, StripeRepo, ReportRepo

Chaque cubit doit gérer les 3 → code défensif partout, risque d’oubli de catch. Il faut standardiser sur un seul pattern (recommandé : (T?, ApiErrorResponse?)).

ProfileCubit.fetchProfile() n’a aucune protection contre les appels concurrents. Si l’UI trigger 2 appels rapides (pull-to-refresh + retour de background), les 2 requêtes partent et les emits se chevauchent. Ajouter un guard if (state.loadStatus is ProfileLoadLoading) return;.

1.8 NotificationCubit mélange de responsabilités Mineur

Section titled “1.8 NotificationCubit mélange de responsabilités Mineur”

NotificationCubit gère à la fois les notifications (fetch, socket, mark as read, delete) ET la soumission de feedback. C’est une violation du Single Responsibility. Le feedback devrait vivre dans un cubit dédié FeedbackCubit.

1.9 MissionRepository : worker + owner mélangés Moyen

Section titled “1.9 MissionRepository : worker + owner mélangés Moyen”

MissionRepository fait 340 lignes et contient les méthodes worker (accept, decline, getMissionWorkerIds) ET owner (create, cancel, giveFeedback, putInProgress). À terme, séparer en WorkerMissionRepository et OwnerMissionRepository pour la lisibilité et le respect du SRP.

1.10 ProfileCubit recréé à chaque transition auth Mineur

Section titled “1.10 ProfileCubit recréé à chaque transition auth Mineur”

ProfileCubit est instancié dans auth_gate.dart (pas au root). Chaque transition d’auth (logout/login, vérification email) détruit et recrée le cubit → perte du cache local en mémoire. Acceptable aujourd’hui mais à surveiller si on ajoute du state lourd (préférences, drafts, etc.).


2.1 Des duplications subsistent dans le code Mineur

Section titled “2.1 Des duplications subsistent dans le code Mineur”

Certains controllers sont encore “God” il faut refactor :

  • MissionController (partiellement entamé)
  • UserController (pas fait)

Enterprise n’a pas de service et duplique ses logiques à travers divers controllers/services. Il faut fix ça et créer :

  • EnterpriseService->create
  • EnterpriseService->update
  • EnterpriseService->delete

2.2 Validation dupliquée dans les controllers Moyen

Section titled “2.2 Validation dupliquée dans les controllers Moyen”

Chaque controller gère sa validation inline avec Validator::make(), ce qui duplique le même bloc de 6-10 lignes dans chaque méthode. Il faut migrer vers des FormRequest dédiés qui centralisent les règles de validation par route.

2.4 getUsersAdmin : N+1 queries Important ✅ Résolu 18/03/2026

Section titled “2.4 getUsersAdmin : N+1 queries Important ✅ Résolu 18/03/2026”

Fix : Eager loading avec User::with(...). commit cce33293eccad614101fc59fa0be3ef4d1858344

Cette route admin fait autant de requêtes SQL que d’utilisateurs (1 requête par user dans une boucle). Avec 200 users → 201 requêtes. Il faut passer sur de l’eager loading (User::with(['workerProfile', 'enterpriseProfile'])->get()) pour descendre à 3 requêtes max.

2.5 Système centralisé d’erreur / logging Urgent

Section titled “2.5 Système centralisé d’erreur / logging Urgent”

Les erreurs sont gérées à la volée lors des appels de services, commandes, controllers, etc. Trois chantiers :

  • Exception Handler Laravel : renvoyer du JSON propre au lieu du HTML par défaut quand une erreur non attrapée survient
  • Logging persistant : écrire les logs dans un volume monté, pas dans le container éphémère Docker
  • Monitoring : intégrer un service type Sentry pour le suivi en temps réel

8 models (EnterpriseStats, WorkerStats, MissionStats, etc.) utilisent $guarded = [], ce qui autorise le mass assignment sur n’importe quel champ. Même si l’API ne le fait pas aujourd’hui, c’est un problème en devenir. Il faut les passer en $fillable explicite.

2.7 Dépendance circulaire NotificationsService / FeedbackService Mineur

Section titled “2.7 Dépendance circulaire NotificationsService / FeedbackService Mineur”

FeedbackService injecte NotificationsService dans son constructeur, et NotificationsService a besoin de FeedbackService pour hydrater les notifications. Le contournement actuel (app(FeedbackService::class)) fonctionne mais masque le problème.

2.8 Couverture de tests à étendre Important

Section titled “2.8 Couverture de tests à étendre Important”

Les tokens et paiements (Stripe) sont bien couverts. En revanche les autres flows critiques (matching, auth, chat, notifications) ne le sont pas. À traiter.

Même si j’ai set les property des models et corrigé une partie des soucis de type, le projet reste globalement dans son état légacy à ce sujet et est principalement dynamic (et c’est négatif le dynamisme ici xD)


3.1 Installer supervisord dans le container de l’api `Critique ✅ Résolu 18/03/2026

Section titled “3.1 Installer supervisord dans le container de l’api `Critique ✅ Résolu 18/03/2026”

commit : f82a50a27869e35af567d63b5d84663b4958c6fc

actuellement le compose de l’api lance les services en vrac dans le container docker. Bien que plus propre que le legacy (rien), il serait préférable de passer sur un supervisord en process main qui contrôle, relance et monitor :

  • Nginx
  • Php-fpm (l’api)
  • Reverb
  • Cron -> Scheduler

Actuellement aucun docker ignore. C’est anecdotique mais c’est une optimisation à faire.

3.3 ajouter —isolated sur le compose api Mineur

Section titled “3.3 ajouter —isolated sur le compose api Mineur”

Afin d’éviter une concurrence entre 2déploiements (peu probable mais pas impossible) ajouter --isolated dans le docker de l’api.

Aujourd’hui on crée le serveur hetzner à la main, on installe coolify dessus, on ajoutes les autorisations git et les serveurs secondaires puis on lance le script du repo Infra qui lui va setup les envs, les clefs (dev, preprod, prod) etc. On ne peut réutiliser se script aprés coup, il sert uniquement à l’initialisation de départ de l’env.

Passer sur terraform et l’IAC permettrait un déploiement total via code, automatisé à 100%, et adaptable à la réalité actuel de l’infra (peut tout reconstruire si c pas bon, rebuild pour agrandir le serveur si on a besoin d’un plus gros, ne rien faire si tout est parfait).