Badges : permettre d'agrandir le badge proportionnellement à l'image

Le format déduit de l'image importée (300 dpi supposés, étape
précédente) donne un badge minuscule pour une image à résolution web —
ajout d'un contrôle « largeur du badge (mm) » dans l'écran de
personnalisation : la hauteur suit proportionnellement (ratio de
l'image). PUT /editions/{id}/badges/template/size écrase la taille
déduite de l'image ; la réimporter la recalcule à nouveau.

Vérifié : pytest (250 passés), ruff, tsc --noEmit, eslint, vite build,
smoke — tous verts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
AdamThomas
2026-09-20 20:51:01 +02:00
co-authored by Claude Sonnet 5
parent bc165757ca
commit 55c5d539a8
11 changed files with 174 additions and 0 deletions
+23
View File
@@ -22,6 +22,7 @@ from app.api.schemas import (
BadgeFieldRead,
BadgeFieldsSet,
BadgeGenerateRequest,
BadgeSizeUpdate,
BadgeTemplateRead,
)
from app.auth.deps import require_coordinator
@@ -219,6 +220,28 @@ def set_fields(
return _fields(session, edition.id)
@router.put("/template/size", response_model=BadgeTemplateRead)
def set_size(
payload: BadgeSizeUpdate,
edition: Edition = Depends(get_edition),
_guard: Account = Depends(require_coordinator),
session: Session = Depends(get_session),
) -> BadgeTemplateRead:
"""Redimensionne le badge indépendamment de l'image (ex. une image
importée à basse résolution donne un format minuscule à 300 dpi
supposés — l'utilisateur l'agrandit ici). Écrase la taille déduite de
l'image ; ré-importer l'image la recalcule à nouveau depuis ses pixels
(`set_front_image`)."""
if payload.badge_width_mm <= 0 or payload.badge_height_mm <= 0:
raise HTTPException(status_code=422, detail={"code": "badge.invalid_size"})
template = _get_or_create_template(session, edition.id)
template.front_image_width_mm = payload.badge_width_mm
template.front_image_height_mm = payload.badge_height_mm
session.add(template)
session.commit()
return _template_read(template, _fields(session, edition.id))
# --------------------------------------------------------------------------- #
# Génération du PDF #
# --------------------------------------------------------------------------- #
+9
View File
@@ -374,6 +374,15 @@ class BadgeTemplateRead(ApiModel):
fields: list[BadgeFieldRead]
class BadgeSizeUpdate(ApiModel):
"""Ajuste la taille du badge indépendamment d'un nouvel import d'image —
ex. agrandir proportionnellement une image importée trop petite (voir
`app/api/badges.py:set_size`). Écrase la taille déduite de l'image."""
badge_width_mm: float
badge_height_mm: float
class BadgeGenerateRequest(ApiModel):
# None/absent = tous les bénévoles de l'édition.
volunteer_ids: list[uuid.UUID] | None = None
+1
View File
@@ -60,6 +60,7 @@
"badge.empty_image": "L'image est vide.",
"badge.image_too_large": "L'image est trop volumineuse.",
"badge.duplicate_field_type": "Le champ « {field_type} » ne peut apparaître qu'une fois.",
"badge.invalid_size": "La taille du badge doit être strictement positive.",
"badge.no_fields": "Aucun champ n'est configuré sur le recto du badge.",
"badge.no_volunteers": "Aucun bénévole ne correspond à cette sélection.",
"badge.role.referent": "Référent",