37 Commits
Author SHA1 Message Date
Michael 20765ba653 perf: keep-alive + cache URL finale pour proxy audio
Agent keep-alive réutilise connexions TLS. Cache URL résolue 10min
→ seeks/reprises sautent la chaîne de redirects.
2026-05-03 23:14:17 +02:00
Michael fdcba26c7f fix: proxy suit les redirects côté serveur (302 → CORS bypass) 2026-05-03 23:01:00 +02:00
Michael c86887f037 feat: proxy audio backend pour Web Audio API sans CORS
Nouveau endpoint /api/audio/proxy?url=... re-stream l'audio externe
avec Access-Control-Allow-Origin:*. Fallback: direct → proxy → no-cors.
Analyser actif en mode proxy → vraie synchronisation waveform/son.
2026-05-03 21:52:13 +02:00
MichaelandClaude Sonnet 4.6 6786226a6c feat: hero player, LU/NOUVEAU badges, metadata resync, sticky mini-bar
- Refresh podcast title/author/imageUrl/description on RSS sync (fixes
  legacy 'Unknown Podcast' records)
- Always-visible Resync button on Library cards
- LU badge on completed episodes, NOUVEAU badge on <7-day-old episodes
- AudioPlayer gains mode='inline' that embeds in the Dashboard hero card
- Floating player suppressed on /dashboard to avoid dual audio
- Sticky mini-bar appears via IntersectionObserver when inline player
  scrolls out of view (shares the same <audio> element)
- Fix: 'Reprendre' button called undefined setSelectedEpisode; now calls
  playEpisode
- Add progress field to Episode TS interface

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 11:33:47 +02:00
MichaelandClaude Sonnet 4.5 a3225cb4c4 feat: light/dark theme (cream+gold+grey), reduced radii, stagger animations, search fallback
- globals.css: full dual-theme system via .light-theme/.dark-theme classes
  → Dark: deep navy with indigo/cyan glow gradients
  → Light: warm cream #f7f3eb with gold top-left & grey bottom-right gradients
  → Radius tokens: --radius-card 1rem, --radius-panel 1.25rem (sharper cards)
  → New animations: float, scale-in, shimmer skeleton, ping-slow, spin-slow,
    glow-beat, gold-shimmer + stagger-grid cascade (up to 20 items)
- tailwind.config.js: reduce 2xl/3xl/4xl radii to match CSS vars; add accent-gold
- Navigation.tsx: add Sun/Moon toggle button using useTheme()
- Dashboard.tsx: shimmer skeletons, stagger-grid on episode grid
- Trending.tsx: stagger-grid on podcast grid
- podcastController.ts: iTunes search fallback → local DB regex search

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-17 10:51:21 +02:00
Michael e649a16620 feat: improve search UX and backend inclusivity on AddPodcast page 2026-04-16 21:06:54 +02:00
Michael 17f2496dda feat: implement global audio player with playback controls, progress tracking, and persistent settings 2026-04-16 15:34:09 +02:00
Michael e01b661aa2 feat: implement podcastIndexService using iTunes API for search and trending podcasts 2026-04-16 15:03:10 +02:00
Michael a993e2d658 feat: implement podcast discovery and management controllers and services 2026-04-16 14:57:49 +02:00
Michael 7923f4cf09 feat: initialize backend project with dependencies and build scripts 2026-04-16 14:50:12 +02:00
Michael aa54304bf3 feat: implement backend episode management and progress tracking controllers and routes 2026-04-16 14:48:32 +02:00
MichaelandClaude Sonnet 4.6 177917c06e Résout tous les conflits de merge
- podcastController: createPodcastFromRss sans feedData (parse le RSS réel)
- Discover.tsx: stub vide (remplacé par /trending et /add)
- App.tsx + Navigation.tsx: conflits déjà résolus

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 14:19:55 +02:00
Michael ad1c65b1f5 feat: implement rssParserService to handle feed parsing, episode extraction, and podcast synchronization 2026-04-16 14:16:45 +02:00
Michael 1e3caea1ab feat: implement rssParserService to handle feed parsing, episode extraction, and database synchronization 2026-04-16 14:16:35 +02:00
Michael 0d9bffbc46 feat: implement rssParserService to handle feed parsing, episode extraction, and database synchronization 2026-04-16 14:15:18 +02:00
Michael 1028774a65 feat: implement podcast controller with subscription, search, and sync functionality 2026-04-16 13:56:48 +02:00
Michael e075434dd7 feat: implement RSS parsing service and podcast controller for feed ingestion and episode synchronization 2026-04-16 13:55:18 +02:00
Michael ba376930b0 feat: implement RSS feed parsing service and add library page UI for podcast management 2026-04-16 13:50:10 +02:00
Michael aaf7b82985 feat: implement trending podcasts page and RSS parsing service for feed data extraction 2026-04-16 13:44:05 +02:00
Michael cdc0a4671c feat: implement podcast controller for subscription management, search, and discovery functionality 2026-04-16 13:32:26 +02:00
Michael d81b3a6516 feat: implement podcast subscription management, library page, and associated service methods 2026-04-16 13:28:23 +02:00
Michael 872ef5c31a feat: implement backend podcast subscription controllers and frontend library page with optimistic updates 2026-04-16 13:07:46 +02:00
Michael 34db9e2542 feat: implement podcast controller for subscription management, discovery, and search functionality 2026-04-16 12:46:22 +02:00
MichaelandClaude Sonnet 4.6 a8cef14226 Rend l'abonnement idempotent (409 → 200)
Abonner deux fois au même podcast retourne 200 au lieu de 409.
Tous les messages d'erreur traduits en français.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 11:40:22 +02:00
MichaelandClaude Sonnet 4.6 eb6821ca76 Corrige TypeError dans subscribeFromDiscovery
result.podcast est un plain object (toJSON()), appeler .toJSON() dessus crashe.
Fix: refetch le podcast depuis MongoDB après création pour avoir un vrai Document Mongoose.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 11:29:55 +02:00
MichaelandClaude Sonnet 4.6 84c5cd6363 Migre eslint v8 → v9 (flat config), supprime les dépréciations
- eslint 8 → 9, @typescript-eslint/* → typescript-eslint (package unifié)
- Remplace .eslintrc.json par eslint.config.mjs (backend) et eslint.config.js (frontend)
- Ajoute eslint-plugin-react, eslint-plugin-react-hooks, globals (frontend)
- Supprime rimraf@3, @humanwhocodes/* qui étaient des deps transitives d'eslint v8

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 11:27:46 +02:00
MichaelandClaude Sonnet 4.6 3914f28e19 Corrige subscribe 500 et trending 500
- subscribe: passe undefined à createPodcastFromRss pour qu'il parse vraiment le flux RSS (bug: on passait feedData avec episodes:[] vide)
- trending/discover: retournent [] au lieu de 500 si l'API iTunes échoue
- trending: utilise l'iTunes RSS officiel (itunes.apple.com/fr/rss/toppodcasts) au lieu de l'API Marketing Tools instable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 11:24:44 +02:00
MichaelandClaude Sonnet 4.6 59144e9ce6 Remplace PodcastIndex par iTunes Search API (gratuit, sans clé)
- Réécriture complète de podcastIndexService avec l'API iTunes d'Apple
- Recherche de podcasts : itunes.apple.com/search (gratuit, pas d'auth)
- Tendances : top podcasts France via rss.applemarketingtools.com + lookup RSS URLs
- Suppression des vérifications isConfigured() dans le contrôleur

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 11:21:26 +02:00
MichaelandClaude Sonnet 4.6 c7a5c171d1 Traduit l'UI en français et corrige les bugs de recherche/abonnement
- Traduit toutes les pages et composants en français (Dashboard, Login, Discover, Navigation, Header, EpisodeCard, AudioPlayer)
- Corrige l'erreur 500 sur /api/podcasts/discover : z.coerce.number() au lieu de z.number() pour limit/offset (paramètres query string)
- Corrige l'abonnement manuel via URL RSS : crée le podcast depuis le flux RSS au lieu de renvoyer 400

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 11:15:42 +02:00
MichaelandClaude Haiku 4.5 00d92fc668 fix: switch backend to CommonJS to fix ESM module resolution
Remove 'type: module' and use CommonJS output so Node.js resolves
imports without requiring explicit .js extensions.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-16 11:01:48 +02:00
MichaelandClaude Haiku 4.5 ffb85ade90 fix: add @types/cors and fix jwt expiresIn type
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-16 10:58:11 +02:00
MichaelandClaude Haiku 4.5 1822ab1afe fix: single container without nginx — Express serves frontend
- Remove separate backend/ and frontend/ Dockerfiles
- Add root Dockerfile (3-stage: frontend build → backend build → runtime)
- Frontend static files served by Express from /public
- Simplify docker-compose to 3 services: mongodb, redis, app (port 3579)
- Fix vite proxy not to strip /api prefix from paths
- Default API URL to relative /api instead of hardcoded localhost

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-16 10:43:06 +02:00
Michael a8787857b5 fix: add proper Dockerfiles for backend and frontend, simplify docker-compose 2026-04-16 10:28:40 +02:00
Michael 9bb61cc8a7 feat: implement podcast discovery with PodcastIndex API integration and Discover page 2026-04-16 10:01:05 +02:00
Michael d7f158a498 docs: add comprehensive getting started guide and linting configuration 2026-04-16 09:56:48 +02:00
Michael 8c00a1b0f5 feat: implement authentication and core API endpoints - auth, podcasts, episodes 2026-04-16 09:55:15 +02:00
Michael 8df1161023 feat: initialize Podcastic project foundation - setup backend and frontend 2026-04-16 09:53:36 +02:00