feat(server): service de découverte de chaîne (GET /api/channel) #1

Merged
kyuno merged 1 commit from feature/channel-discovery into main 2026-09-16 09:29:31 +02:00
Owner

Résumé

Première brique du pipeline décrit pour l'app : lister les vidéos/streams d'une chaîne YouTube, filtrables par mots-clés sur le titre (équivalent généralisé de streamExtractor.cmd). La file d'attente et le téléchargement suivront dans une PR séparée.

Détails

  • server/src/services/ytDlpRunner.ts : exécution bas niveau de yt-dlp via child_process.spawn — jamais de shell, arguments toujours en tableau (exclut l'injection de commande).
  • server/src/services/ChannelDiscoveryService.ts : accepte un handle (@nom) ou une URL de chaîne, valide strictement l'entrée (premier caractère forcément alphanumérique) et ajoute un séparateur -- avant l'URL passée à yt-dlp, en défense en profondeur contre l'injection d'options. Parse yt-dlp --flat-playlist -j, filtre par mots-clés (ET, insensible à la casse) sur le titre.
  • server/src/routes/channel.ts : GET /api/channel?channel=...&section=videos|streams&keywords=a,b — validation de schéma Fastify, 400 si entrée invalide, 502 si yt-dlp échoue.
  • spec/architecture.md mis à jour (section API, structure des services).

Tests

14 tests (4 fichiers) : ytDlpRunner testé via un vrai sous-processus (node -e ..., pas yt-dlp), ChannelDiscoveryService testé avec ytDlpRunner mocké, route testée via app.inject().

Un test de route a révélé une regex de validation trop permissive (--exec était accepté comme handle valide) qu'un test de service, avec un exemple d'entrée moins bien choisi, avait laissée passer — corrigé avant ce commit (voir it.each dans channelDiscoveryService.test.ts).

Vérifications locales

  • npm run lint (Biome, racine) : clean
  • npm run typecheck + npm test + npm run build (server) : clean, 14/14 tests passent
  • Testé en navigateur via le serveur de dev (placeholder + /health) lors du PR précédent ; cette PR est backend-only, pas de changement frontend

🤖 Generated with Claude Code

## Résumé Première brique du pipeline décrit pour l'app : lister les vidéos/streams d'une chaîne YouTube, filtrables par mots-clés sur le titre (équivalent généralisé de `streamExtractor.cmd`). La file d'attente et le téléchargement suivront dans une PR séparée. ## Détails - `server/src/services/ytDlpRunner.ts` : exécution bas niveau de yt-dlp via `child_process.spawn` — jamais de shell, arguments toujours en tableau (exclut l'injection de commande). - `server/src/services/ChannelDiscoveryService.ts` : accepte un handle (`@nom`) ou une URL de chaîne, valide strictement l'entrée (premier caractère forcément alphanumérique) et ajoute un séparateur `--` avant l'URL passée à yt-dlp, en défense en profondeur contre l'injection d'options. Parse `yt-dlp --flat-playlist -j`, filtre par mots-clés (ET, insensible à la casse) sur le titre. - `server/src/routes/channel.ts` : `GET /api/channel?channel=...&section=videos|streams&keywords=a,b` — validation de schéma Fastify, `400` si entrée invalide, `502` si yt-dlp échoue. - `spec/architecture.md` mis à jour (section API, structure des services). ## Tests 14 tests (4 fichiers) : `ytDlpRunner` testé via un vrai sous-processus (`node -e ...`, pas yt-dlp), `ChannelDiscoveryService` testé avec `ytDlpRunner` mocké, route testée via `app.inject()`. Un test de route a révélé une regex de validation trop permissive (`--exec` était accepté comme handle valide) qu'un test de service, avec un exemple d'entrée moins bien choisi, avait laissée passer — corrigé avant ce commit (voir `it.each` dans `channelDiscoveryService.test.ts`). ## Vérifications locales - `npm run lint` (Biome, racine) : clean - `npm run typecheck` + `npm test` + `npm run build` (server) : clean, 14/14 tests passent - Testé en navigateur via le serveur de dev (placeholder + `/health`) lors du PR précédent ; cette PR est backend-only, pas de changement frontend 🤖 Generated with [Claude Code](https://claude.com/claude-code)
kyuno added 1 commit 2026-09-16 08:05:58 +02:00
feat(server): service de découverte de chaîne (GET /api/channel)
Some checks failed
Publier l'image Docker / test (pull_request) Failing after 4s
Publier l'image Docker / publish (pull_request) Has been skipped
0e78b44a55
Première brique du pipeline : lister les vidéos/streams d'une chaîne
YouTube (yt-dlp --flat-playlist), filtrables par mots-clés sur le titre.

- ytDlpRunner.ts : exécution de yt-dlp via child_process.spawn (jamais de
  shell, arguments en tableau - exclut l'injection de commande)
- ChannelDiscoveryService.ts : validation stricte du handle/URL de chaîne
  + séparateur `--` avant l'URL (défense en profondeur contre l'injection
  d'options yt-dlp), parsing tolérant des lignes JSON, filtrage mots-clés
- routes/channel.ts : GET /api/channel (validation de schéma Fastify,
  400 si entrée invalide, 502 si yt-dlp échoue)
- 14 tests (unitaires services + intégration route via app.inject) - un
  test de route a révélé une regex de validation trop permissive qu'un
  test de service avait manquée, corrigée avant ce commit

La file d'attente et le téléchargement suivront dans une PR séparée.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
kyuno merged commit 1a92322896 into main 2026-09-16 09:29:31 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: kyuno/youtubeDownloader#1
No description provided.