Skip to content

Forme d'onde des extraits calculée par l'API (#474) - #477

Merged
Oasis35 merged 4 commits into
env/stagingfrom
claude/project-thread-xtdcdr
Nov 2, 2026
Merged

Oasis35 merged 4 commits into
env/stagingfrom
claude/project-thread-xtdcdr

Conversation

@Oasis35

@Oasis35 Oasis35 commented Nov 2, 2026

Copy link
Copy Markdown
Owner

Contexte

À la reprise d'une partie à 10 s, la waveform restait plate pendant tout le premier palier : le front ne la calculait qu'à la fin du palier. Décision (#474) : l'API calcule la forme de chaque extrait, la stocke en base, et l'envoie avec la partie. Le navigateur ne calcule plus qu'en repli.

Ce que fait la PR

  • Calcul : nouveau projet InSeconds.Waveform (NLayer). Un extrait MP3 devient un blob versionné de 1984 octets (180 barres, 1800 valeurs de basses, les 30 s). Colonnes waveform, waveform_source, waveform_computed_at sur catalogue.tracks (migration TrackWaveform).
  • Déclenchement : une étape de catalogue-refresh (23 h UTC : morceaux sans forme, extrait remplacé détecté au nom de fichier de l'URL Deezer, ancien format à l'octet de version) et, pour un ajout manuel, un message Wolverine différé de 15 min qui glisse jusqu'au dernier ajout. Un seul verrou consultatif PostgreSQL (474) entre les deux.
  • Staging : rien n'est calculé (Catalogue:Waveform:ComputeOnAdd=false, pas de catalogue-refresh, piège 16).
  • Réponses : la forme part en base64 dans le démarrage du Daily et le morceau courant de Runs (une silhouette n'identifie pas le morceau, piège 31). Un morceau sans forme déclenche un Warning côté API (identifiant en base seulement).
  • Front : waveformFromBlob dessine la forme dès la première image. Sans forme, calcul navigateur dès l'événement playing, avec un Warning WaveformFallback (une fois par morceau et par page) via POST /api/client-errors qui accepte désormais level: warning.
  • Téléchargement d'extrait : en mémoire, limité à *.dzcdn.net et 3 Mo, jamais d'URL signée dans un journal. Aucun audio n'est écrit sur disque ni en base (piège 47).
  • Observabilité : compteurs, durée et jauge des formes manquantes, spans InSeconds.Catalogue, nouveaux panneaux du tableau Grafana Exploitation.
  • Docs : piège 50, piège 47 et conformité Deezer, réglages, tâches, déploiement.

Après le déploiement en prod

Lancer catalogue-refresh à la main depuis /jobs pour le premier remplissage ; le panneau « Formes manquantes » doit retomber à 0.

Vérifications faites en session cloud

  • Front : Vitest (1500 tests), npm run lint:arch, npm run build verts.
  • Back : tests unitaires et d'architecture verts ; suite d'intégration verte sur un PostgreSQL local (pas de Docker dans la session), la CI la rejoue avec Testcontainers.
  • Les E2E Playwright n'ont pas été lancés en local : à voir en CI.

Generated by Claude Code

Nouveau projet InSeconds.Waveform (NLayer) : un extrait MP3 devient un blob
versionné de 1984 octets (180 barres, 1800 valeurs de basses). Trois colonnes
sur catalogue.tracks (waveform, waveform_source, waveform_computed_at) et leur
migration.

Le calcul est une étape de catalogue-refresh (extrait remplacé détecté au nom
de fichier de l'URL Deezer, ancien format à l'octet de version) et, pour un
ajout manuel, un message Wolverine différé de 15 min qui glisse jusqu'au
dernier ajout. Un seul verrou consultatif PostgreSQL entre les deux. Rien au
staging (Catalogue:Waveform:ComputeOnAdd=false).

La forme part en base64 dans StartSession (Daily) et le morceau courant de
Runs ; un morceau sans forme est journalisé en Warning. Téléchargement de
l'extrait en mémoire, limité au CDN de Deezer et à 3 Mo. Niveau warning
accepté par POST /api/client-errors. Métriques et traces du catalogue.
Faux Deezer de l'hôte de test : MP3 synthétique.
…rage du son (#474)

Le front décode le blob de l'API (waveformFromBlob) et dessine la forme
avant le premier son : plus de forme plate pendant tout le premier palier
quand on reprend une partie à 10 s. Sans forme, le navigateur la calcule
dès l'événement playing (et non plus à la fin du palier) et le dit par un
Warning WaveformFallback, une fois par morceau et par page.

Tableau Grafana Exploitation : panneaux des formes d'onde. Documentation :
piège 50, piège 47 et conformité Deezer (valeurs dérivées stockées),
réglages, tâche catalogue-refresh, déploiement et premier remplissage.
…ecture, garde-fous

- PostgresWaveformLock passe dans Persistence/, le Warning "sans forme"
  dans LoggedTrackWaveforms (Application) : le port de lecture ne journalise plus.
- Le téléchargement d'extrait revérifie l'hôte final après une redirection.
- Les diagnostics (warning) du front ont leur propre plafond par page, pour ne
  pas consommer celui des vraies erreurs.
- Sonar : codePointAt à la place de charCodeAt.
- Jauge et runbook : les formes manquantes sont les échecs du dernier passage.
- Corrections de doc (quatre nombres d'en-tête, cinq ports Deezer).
@sonarqubecloud

sonarqubecloud Bot commented Nov 2, 2026

Copy link
Copy Markdown

@Oasis35
Oasis35 marked this pull request as ready for review November 2, 2026 13:59
@Oasis35
Oasis35 merged commit 6dfcda7 into env/staging Nov 2, 2026
13 checks passed
@Oasis35
Oasis35 deleted the claude/project-thread-xtdcdr branch November 2, 2026 13:59
Oasis35 added a commit that referenced this pull request Nov 2, 2026
Promotion env/staging vers main (#464 à #477)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant