+26
−0
Loading
Un seul magasin, trois références. `ExerciseImage` plutôt qu'un réemploi de
`Document` : une capture lâchée dans un fil de chat n'est pas une pièce de
l'espace documentaire, et les deux n'ont ni le même cycle de vie ni la même
audience. Le stockage physique, lui, reste partagé (`common/uploads.ts`).
Le corps d'un message n'est plus obligatoire quand une image est jointe — c'est
l'usage courant, notamment sur Instagram. La règle « du texte OU une image » ne
peut pas vivre dans les DTO (`@ValidateIf` désactive TOUS les validateurs d'une
propriété, on ne peut donc pas retirer le seul `@MinLength`) : elle est portée
par `assertHasContent`, appelé là où tous les chemins d'écriture convergent,
soit un point par canal.
Sécurité :
- SVG exclu de la liste blanche, contrairement aux logos : un SVG peut porter du
script, et ces images-ci sont téléversées par des JOUEURS. Le format n'apporte
rien pour une capture ou une photo.
- `assertBelongs` avant toute référence : sans ce contrôle, un identifiant deviné
permettrait de rattacher l'image d'un autre exercice.
- L'identifiant est tiré au hasard sur 32 octets, et non généré en cuid. La route
de lecture est servie sans session — une balise `<img>` ne peut pas émettre
l'en-tête « voir comme » — donc l'URL tient lieu de capacité et doit être
imprévisible, ce qu'un cuid (compteur + empreinte machine) n'est pas. Faire de
cette clé l'identifiant lui-même évite en prime une jointure à ne pas oublier
dans chaque lecture.
Limite connue, déjà signalée pour les documents : une image téléversée puis
abandonnée avant l'envoi reste orpheline en base et sur le disque. Elle est
emportée par la suppression de l'exercice et par la purge de rétention, mais
aucune purge intermédiaire n'existe.
Non vérifié : aucune chaîne Node dans cet environnement, donc rien n'a été
compilé, typé ni testé. Contrôles faits à la main (équilibre des accolades,
absence de doublon de clé i18n, correspondance classes CSS / TSX, symboles
importés tous utilisés, props obligatoires présentes sur les 7 usages du
composant).
Co-Authored-By:
Claude (RCA) <noreply@anthropic.com>