- Shipped
- August 25, 2026 at 2:03 PM UTC
- Author
- kamo
- Commit
- b93ae3c
The face now comes from the same directory index every other member list on the platform reads (useMemberProfiles), so a person's picture on the scoreboard is identical to their picture in the pickers and the attendance console rather than merely similar. Initials stay as the fallback, with the hue still derived from the member id so somebody with no photo keeps a stable identity across periods. The avatar URL is deliberately NOT added to the scoreboard endpoint. Building one is MemberAvatarUrlService's job and it lives in SecurityService: it needs the avatar repository, a JDBC read for the photo extension (a lazily-loaded Avatar is a Hibernate proxy, so instanceof AvatarPhoto is false often enough to serve a 404) and the forwarded host. Its own javadoc says not to add another copy, and a second implementation in MediaService would have been exactly that. MUI's Avatar rather than an img or next/image, specifically for its fallback: it renders the children when the image fails to LOAD, not merely when the src is absent. That is the case that actually happens — an avatar row can outlive the object behind it, so a well-formed URL 404s and a hand-rolled img would leave a broken-image glyph in the middle of the board. The 'sm' variant, matching every other small disc: ten originals downloaded to be drawn at 20px is the kind of waste that only shows up on someone else's connection. getAvatarSizedUrl leaves a generated SVG avatar alone. The directory is walked only once a board exists and only for the ids on it, and the index is a module-scoped session cache shared with those other screens, so in practice this is paid once if at all.