Initial commit: itinova-podcasts v1

Stack: Node.js/Express + React/Vite + tRPC + MySQL (Drizzle ORM)
Features: Gestion de podcasts, établissements, mots-clés, upload audio S3
Migrations: 0000-0002 (users, etablissements, mots_cles, podcasts, podcast_mots_cles)
This commit is contained in:
manus-admin
2026-04-12 18:34:56 -04:00
commit aab11c8308
138 changed files with 27782 additions and 0 deletions

125
todo.md Normal file
View File

@@ -0,0 +1,125 @@
# Itinova Podcasts - TODO
## Base de données
- [x] Table `etablissements` (id, nom, description, logoUrl, createdAt)
- [x] Table `podcasts` (id, titre, resume, etablissementId, audioUrl, audioKey, duree, statut, auteurId, createdAt, updatedAt)
- [x] Table `mots_cles` (id, label)
- [x] Table `podcast_mots_cles` (podcastId, motCleId) - relation many-to-many
- [x] Migration DB avec `pnpm db:push`
## Backend API (tRPC)
- [x] Router `etablissements` : list, create, update, delete (admin)
- [x] Router `podcasts` : list (public), getById, create (auth), update (auth), delete (auth/admin)
- [x] Router `motsCles` : list (public), create (admin)
- [x] Route upload audio : POST /api/upload-audio (S3)
- [x] Filtrage podcasts par établissement et mots-clés
- [x] Pagination des podcasts
## Interface Web d'Administration
- [x] Layout dashboard avec sidebar (AdminLayout)
- [x] Page d'accueil / tableau de bord avec statistiques
- [x] Page liste des podcasts (tableau avec recherche/filtres)
- [x] Formulaire création/édition podcast (titre, résumé, établissement, mots-clés, upload audio)
- [x] Confirmation suppression podcast
- [x] Page gestion des établissements (liste, ajout, édition, suppression)
- [x] Page gestion des mots-clés
- [x] Gestion des rôles utilisateurs (admin peut promouvoir)
## Interface Mobile Responsive (Écoute)
- [x] Page d'accueil mobile avec logo Itinova et CTA
- [x] Page liste/écoute avec filtres (établissement, mots-clés)
- [x] Lecteur audio HTML5 intégré avec contrôles (play/pause, progress, volume)
- [x] Carte podcast avec titre, résumé, établissement, durée
- [x] Connexion OAuth pour professionnels sur mobile
- [x] Formulaire publication podcast sur mobile (après connexion)
- [x] Navigation mobile avec bottom bar
## Authentification & Sécurité
- [x] Authentification Manus OAuth (déjà en place)
- [x] Rôles : admin (gestion complète) / user (publication propres podcasts)
- [x] Protection des routes d'administration
- [x] Validation des formulaires (zod)
## Tests
- [x] Tests unitaires routers podcasts
- [x] Tests unitaires routers établissements
- [x] Tests upload audio
## Design & UX
- [x] Palette couleurs Itinova (bleu institutionnel, blanc, accents)
- [x] Typographie professionnelle (Inter)
- [x] Responsive mobile-first pour interface écoute
- [x] États de chargement (skeletons)
- [x] Messages d'erreur et de succès (toasts)
## Compte administrateur local
- [x] Étendre le schéma DB avec champ `passwordHash` et `username` dans la table users
- [x] Ajouter route tRPC `auth.loginLocal` (vérification username + bcrypt)
- [x] Créer le compte immuable `adminServPodcast` (protégé contre modification/suppression)
- [x] Page de connexion avec choix : connexion Manus OAuth ou connexion locale
- [x] Formulaire de connexion locale (username + mot de passe)
- [x] Tests Vitest pour `auth.loginLocal`
## Suppression connexion Manus OAuth
- [x] Page /login : afficher directement le formulaire local, supprimer le choix Manus
- [x] AdminLayout : supprimer le bouton "Se connecter avec Manus"
- [x] Interface mobile : supprimer les boutons/liens de connexion Manus
- [x] Retirer les imports getLoginUrl inutilisés
## Gestion des utilisateurs (CRUD complet)
- [x] API : route createUser (nom, username, mot de passe, rôle)
- [x] API : route updateUser (nom, username, mot de passe optionnel, rôle)
- [x] API : route deleteUser (avec protection compte immuable)
- [x] Page AdminUtilisateurs : tableau avec colonnes (nom, identifiant, rôle, méthode, date)
- [x] Bouton "Nouvel utilisateur" en haut à droite
- [x] Boutons Modifier / Supprimer en fin de chaque ligne
- [x] Modale création utilisateur (formulaire validé)
- [x] Modale modification utilisateur (formulaire pré-rempli)
- [x] Dialogue de confirmation suppression
- [x] Protection : compte immuable non modifiable/supprimable
## Bugs
- [x] Erreur 404 sur le bouton "Nouveau podcast" dans l'interface admin
## Logos en-tête page d'accueil
- [x] Uploader logo Itinova vers CDN
- [x] Uploader logo Santinova vers CDN
- [x] Intégrer les deux logos côte à côte dans l'en-tête de la page d'accueil (mobile + web)
## Corrections UI
- [x] Supprimer le bouton "Nouveau podcast" du tableau de bord
## Bug session
- [x] Le bouton Connexion n'apparaît pas toujours : session OAuth Manus résiduelle reconnecte l'utilisateur automatiquement sans passer par la connexion locale
## Refonte UI moderne
- [x] Styles globaux : palette Itinova enrichie, typographie Inter, tokens CSS, animations
- [x] Page d'accueil mobile : header avec logos, hero gradient, cartes podcast modernes, lecteur flottant redesigné
- [x] Composant PodcastCard : design carte moderne avec waveform visuelle, badges colorés
- [x] Composant PodcastPlayer : lecteur bottom-sheet moderne avec artwork, progression animée
- [x] Interface admin : sidebar redesignée, dashboard avec métriques visuelles, tableaux épurés
- [x] AdminLayout : sidebar avec icônes plus grandes, couleurs riches, transitions
## Bug logos
- [x] Logos Itinova/Santinova invisibles sur la page Login (filtre brightness-0 invert sur fond bleu les rend blancs sur blanc)
## Enregistrement audio depuis smartphone
- [x] Composant AudioRecorder : enregistrement microphone via MediaRecorder API
- [x] Chronomètre d'enregistrement en temps réel
- [x] Prévisualisation audio avant upload (lecture du fichier enregistré)
- [x] Choix dans PodcastForm : onglet "Fichier existant" / onglet "Enregistrer"
- [x] Upload du fichier enregistré vers S3 (même route que upload fichier)
- [x] Interface mobile : bouton "Enregistrer un podcast" accessible sans admin
## Logos page de connexion
- [x] Logo Itinova en haut de la page de connexion
- [x] "powered by" + logo Santinova en bas de la page de connexion
## Logos panneau droit connexion
- [x] Logo Itinova en haut du panneau droit (formulaire) de la page de connexion
- [x] "powered by" + logo Santinova en bas du panneau droit (formulaire) de la page de connexion
## Correction logos page connexion (v2)
- [x] Supprimer les logos du panneau gauche bleu
- [x] Logo Itinova juste au-dessus de la carte de connexion (panneau droit)
- [x] "powered by" + logo Santinova sur la même ligne, juste en dessous de la carte de connexion