| État du compte | Comptes | Part |
|---|---|---|
| Chargement… | ||
| Cours | Inscrits | Part | Abonnés actifs | Personnalisé | À choisir |
|---|---|---|---|---|---|
| Chargement… | |||||
Essais de paiement exclus. Les jours sans inscription ni vente sont repliés.
| Jour | Inscriptions | Ventes | Encaissé |
|---|---|---|---|
| Chargement… | |||
Cadence de réponse anormale ou budget de génération atteint. Pour bloquer un compte : Utilisateurs → Modifier → décocher « Compte actif ».
Questions générées par utilisateur. Budget quotidien : 4x la banque.
Un élève est un compte qui a répondu au moins une fois (comptes clos exclus). L'écart type mesure la dispersion entre élèves : faible, ils se ressemblent ; élevé, quelques-uns tirent la moyenne. La progression est exactement celle que chaque étudiant voit sur sa courbe.
| Par élève | Élèves | Moyenne | Écart type | Minimum | 1er quartile | Médiane | 3e quartile | Maximum |
|---|---|---|---|---|---|---|---|---|
| Chargement… | ||||||||
Les dix premiers de chaque mesure. Un temps très court n'est pas un mérite en soi : à lire avec la réussite, il distingue l'élève rapide du compte qui clique sans lire.
Élèves ayant ouvert le chapitre au moins une fois.
Archives des « Statistiques d'utilisation », enregistrées au moment de chaque réinitialisation annuelle (le bouton ci-dessous demande un nom, ex. « 2025-26 »).
Reset annuel (10 septembre, après les rattrapages et la fin des abonnements) : les « Statistiques d'utilisation » sont d'abord archivées sous un nom à choisir (consultables ensuite sous « Historique »), puis toutes les données d'entraînement (training_sessions et attempts) sont définitivement supprimées pour tous les utilisateurs. Les comptes et les questions restent en place, mais chaque étudiant perd son historique de sessions, ses scores et sa courbe de progression.
Revenu brut : encaissé moins remboursé, avant frais. Revenu net : revenu brut moins les coûts ci-dessous, dont les frais Stripe réels des ventes, repris d'office. Les essais de paiement sont encaissés comme les autres et repris d'office dans les coûts. Leurs frais Stripe sont un coût de la plateforme : Hugo est remboursé de ses essais en entier, avant toute répartition. Les pièces comptables restent dans l'onglet Légal.
| Formule | Ventes | Encaissé | Remboursé | Revenu brut | Frais Stripe | Revenu net de frais | Comptes aujourd'hui |
|---|---|---|---|---|---|---|---|
| Chargement… | |||||||
| Date | Libellé | Montant | Justification | Saisi par | |
|---|---|---|---|---|---|
| Chargement… | |||||
Mesure anonyme : ni cookie, ni adresse IP, ni identifiant conservé. Une visite est un chargement de la page ; la même personne qui revient compte pour deux visites. Les navigateurs qui demandent à ne pas être pistés ne sont pas comptés, les robots non plus.
| Étape | Visites | Part des visites |
|---|---|---|
| Chargement… | ||
Visites arrivées par un lien court créé dans SysAdmin › Liens courts. Les autres visites n'ont pas de canal.
| Canal | Visites | Part des visites | Vers l'inscription |
|---|---|---|---|
| Chargement… | |||
| Destination | Cliqué depuis | Visites | Part des visites | Clics | Profondeur au clic |
|---|---|---|---|---|---|
| Chargement… | |||||
| Jour | Visites | Clics vers l'inscription | Inscriptions |
|---|---|---|---|
| Chargement… | |||
| DB ID | User # | Nom | Prénom | Pseudo | Cours | Email vérifié | Abonnement | Statut de l'abonnement | Expiration | Compte créé le | CGU acceptées | Réductions | Réponses | Questions | Réussite | Sessions | Abandons | Erreurs | Temps/q | Succès | Chapitres | Dernière activité | Rang | TF1 | TF2 | VF | Actions |
|---|
Des adresses de comptes qui n'existent pas encore. Quand quelqu'un s'inscrit avec une de ces adresses, la remise de la liste est posée sur son compte pour son prochain paiement, comme la remise du bouton Abonnement, message compris. Une adresse sert une fois par liste ; si elle figure dans plusieurs listes actives, la plus récente l'emporte. Une adresse qui a déjà un compte ne reçoit rien d'elle-même : la remise se pose alors à la main.
| Liste | Remise | Message | Adresses | Inscrites | Déjà un compte | État | |
|---|---|---|---|---|---|---|---|
| Chargement… | |||||||
Attribue ou retire un ou plusieurs succès (Ctrl/Cmd + clic) à un ou plusieurs comptes (e-mails séparés par des virgules). L'attribution est identique à une obtention normale ; le retrait supprime la ligne, le succès peut être regagné.
Part des utilisateurs actifs ayant obtenu chaque succès.
| Succès | Description | Type | Obtenu par | % |
|---|---|---|---|---|
| Chargement… | ||||
| Rang | Pseudo | Taux de réussite | Séries terminées |
|---|---|---|---|
| Chargement… | |||
Bandeau affiché au choix du mode : tirage aléatoire au chargement puis toutes les 30 secondes, sans répétition immédiate. Lien facultatif, page interne seulement (cours.php, profile.php…) ; sans lien, l'astuce est un simple conseil.
| Astuce | Lien | Chapitre | État | |
|---|---|---|---|---|
| Chargement… | ||||
Le mot de passe actuel et, si elle est active, la 2FA sont exigés pour toute modification : une session volée ne suffit pas à changer les identifiants. Chaque action les demande dans une fenêtre dédiée.
Une passkey (Face ID, Touch ID, Proton Pass, Bitwarden, clé de sécurité) remplace le mot de passe et le code 2FA à la connexion. Mot de passe et 2FA restent en secours.
Ce navigateur ne prend pas en charge les passkeys.
Bandeau visible en haut de toutes les pages (sauf pendant une session de QCM), aussi pour les visiteurs non connectés. Une seule annonce à la fois, texte brut, 300 caractères. Publier remplace l'annonce en cours ; le journal garde tout.
Affiché à droite du texte, avec le même libellé que les astuces (« vers mes révisions », « voir le cours »…). Pages du site uniquement : une adresse complète du site est ramenée à son chemin, les autres sites sont refusés.
Vérifications en direct : base de données, Stripe, rendu des schémas. Actualiser recharge tous les tests.
Chargement…
Dimensionnement de référence pour 400 inscrits : Exoscale Standard Medium, 2 vCPU / 4 Go / 50 Go SSD. Pic attendu : 80 à 120 élèves actifs, 3 à 6 requêtes par seconde. Seuils : charge inférieure au nombre de CPU, plus de 1 Go de mémoire disponible, swap stable, plus de 5 Go de disque. Si la charge dépasse les CPU ou si le swap grossit pendant un pic, passer à la taille supérieure. Ces mesures se rafraîchissent toutes les 15 secondes tant que cet onglet est affiché.
Chargement…
Alarmes journalisées par le serveur QCM (cadence de réponse, budgets de génération, vitesse de couverture de la banque). Un digest e-mail quotidien part aussi vers admin@ s'il y a du nouveau.
| Date | Type | Détail | Utilisateur | Contexte | Temps / question | |
|---|---|---|---|---|---|---|
| Chargement… | ||||||
Lire une alarme. Le type dit la règle franchie (survoler le type pour la condition exacte), la colonne Détail dit la mesure, puis ce que le compte a fait de 24 h avant à 12 h après : séries ouvertes dans l'ordre avec les réponses données, chapitres marqués lus avec leur rythme. Un curieux ouvre des séries et des chapitres espacés, répond un peu, s'arrête ; un aspirateur enchaîne sans répondre, à quelques secondes d'intervalle, et marque des chapitres « lus » en un quart de minute chacun.
Journalisé seulement, rien n'est refusé : harvest (rafale : 5 séries en 30 min et 120 questions servies pour moins de 15 % de réponses ; ou 400 questions servies en 24 h pour moins de 15 % de réponses) · burst (plus de 10 validations par minute, série rendue avec moins de 20 s par réponse, ou frein du Trou Noir contourné) · coverage_24h (40 % de la banque répondue en 24 h) · coverage_7d (75 % en 7 jours) · rhythm_regular (20 validations à intervalle presque fixe) · synthetic_input (sélections produites par un script) · no_pointer_move (clic souris sans mouvement, une vraie main le fait aussi) · course_volume (plus de 40 ouvertures de chapitres du cours en 24 h, ou 30 en une minute : le polycopié en fait 22, au-delà c'est un compte partagé ou un script) · series_volume (plus de 15 séries démarrées en 10 min ou 40 en 24 h).
Frein posé en Trou Noir : paced (10 validations d'affilée sous 10 s, 15 s par question pendant 30 questions) · paced_hard (la barre de 15 s est attendue sans lire, 60 s pendant 50 questions).
Refus jusqu'à la période suivante : gen_budget_hour (max(120, 33 % de la banque) questions tirées en une heure) · gen_budget (max(600, banque) dans la journée) · gen_budget_week (max(2 × jour, 3 × banque) en sept jours) · reveal_cap_hour (150 corrections en une heure) · reveal_cap_day (500 dans la journée). La colonne Contexte dit si la couverture vient du Trou Noir, qui sert la banque entière : dans ce mode une couverture large est normale, c'est le temps par question qui distingue un joueur d'un script.
Authentification du courrier, certificats émis sur nos domaines, domaines ressemblants. Les alertes partent aussi par Signal ; cette page en donne le détail. Les anomalies passent en tête.
Qui a fait quoi depuis la console. Seules les actions qui modifient quelque chose sont retenues : tracer les consultations noierait le journal. 200 dernières lignes.
| Date | Compte | Action | Cible | Détails | IP |
|---|---|---|---|---|---|
| Chargement… | |||||
Tout ce qui peut refuser quelque chose à un compte, avec le message que l'élève lit. Depuis la fiche d'un compte, « Lever les blocages » efface ses compteurs et lève le frein ; les budgets de tirage ne se lèvent pas. Le cours ne bloque plus rien : il signale (VF). Tout le reste (rafales, rythme, volume, couverture) est journalisé seulement.
| Où | Règle | Effet | Message affiché | Levable |
|---|---|---|---|---|
| Par compte, en révisant | ||||
| Trou Noir | 10 validations d'affilée à moins de 10 s chacune | 15 s par question pendant 30 questions ; si la barre est attendue sans lire (moyenne entre 15 et 20 s), 60 s pendant 50 questions. Tombe après une heure sans validation. | « Tu réponds trop vite, même un physicien n'est pas si rapide ! Le délai reste en place pour les N prochaines questions : prends vraiment le temps de lire, et il disparaîtra. Attendre seulement la fin de la barre le rallonge. » | oui |
| QCM | Plus de 10 séries démarrées en une minute | Refus jusqu'à la fin de la minute | « Trop de séries démarrées d'un coup. Réessaie dans N s. » | oui |
| QCM | Plus de 60 suites de série en une minute (pages du Trou Noir, reprise d'une question) | Refus jusqu'à la fin de la minute | « Tu vas un peu vite. Réessaie dans N s. » | oui |
| QCM | Corrections révélées : plus de 150 en une heure | Corrections retenues une heure ; en fin de série, la série est enregistrée sans ses corrections | « Tu as vu beaucoup de corrections cette heure. Réessaie dans une heure. » | oui |
| QCM | Corrections révélées : plus de 500 dans la journée | Corrections retenues jusqu'au lendemain | « Tu as atteint le nombre de corrections disponibles pour aujourd'hui. Réessaie demain. » | oui |
| QCM | Questions tirées : plus de max(120, 33 % de la banque) en une heure | Tirage refusé une heure | « Tu as atteint le nombre de questions disponibles pour cette heure. Réessaie dans une heure. » | non (budget) |
| QCM | Questions tirées : plus de max(600, banque) dans la journée | Tirage refusé jusqu'au lendemain | « Tu as atteint le nombre de questions disponibles pour aujourd'hui. Réessaie demain. » | non (budget) |
| QCM | Questions tirées : plus de max(2 × jour, 3 × banque) en sept jours | Tirage refusé | « Tu as atteint le nombre de questions disponibles pour cette semaine. Réessaie dans quelques jours. » | non (budget) |
| Mes Erreurs | Accès découverte : 2 séries par jour | Limite de la formule, pas une protection (pas de lien FAQ) | « Mes Erreurs est limité à 2 séries par jour en Accès découverte. À nouveau disponible demain. » | oui |
| Historique | Plus de 60 appels en une minute | Refus jusqu'à la fin de la minute | « Trop de requêtes, réessaie dans un instant. » | oui |
| Historique | Plus de 20 relectures en une minute | Refus jusqu'à la fin de la minute | « Trop de relectures d'un coup, réessaie dans un instant. » | oui |
| Historique | Plus de 300 relectures dans la journée | Refus jusqu'au lendemain | « Limite quotidienne de relectures atteinte. Réessaie demain. » | oui |
| Cours | Marquage « Lu » : 60 par minute, et pas avant 25 s après l'ouverture | Le « Lu » n'est pas posé (invisible, aucun message) | – | oui |
| Par compte, accès et sécurité | ||||
| Connexion | 10 mots de passe faux sur le compte en 15 min | Connexion refusée jusqu'à la fin des 15 min ; un succès remet à zéro | « Trop de tentatives. Réessaie dans N min. » | oui |
| Connexion | 5 mots de passe faux pour le couple adresse IP + compte en 15 min | Connexion refusée depuis cette adresse ; les autres adresses restent libres | « Trop de tentatives pour ce compte depuis cette connexion. Réessaie dans N min. » | non (par adresse, retombe seul) |
| Vérification | 6 codes faux en 15 min ; 3 envois de code par heure | Refus jusqu'à la fin de la fenêtre | « Trop de tentatives. Réessaie dans N min. » | oui |
| Mot de passe | 3 demandes de réinitialisation par heure ; 5 ressaisies fausses du mot de passe en 15 min (profil) | Refus jusqu'à la fin de la fenêtre | « Trop de tentatives. Réessaie dans N min. » | oui |
| Profil | Export de ses données : 1 par semaine | Refus | « Un export par semaine. Pour plus, écris-nous depuis la page « Nous écrire ». » | oui |
| CGU | Version majeure non acceptée 15 jours après sa première présentation (si la fenêtre est active) | QCM et cours suspendus jusqu'à l'acceptation ; profil, contact et abonnement ouverts | « Les conditions générales ont changé et le délai pour les accepter est écoulé : accepte la version en vigueur pour retrouver l'accès. » | par l'acceptation |
| Par adresse IP, dimensionné pour un amphi derrière une seule adresse | ||||
| Connexion | 20 échecs en 15 min : preuve de travail exigée ; 300 échecs : verrou d'adresse | Calcul invisible de quelques secondes, puis refus | « Trop de tentatives. Réessaie dans N min. » | non (retombe seul) |
| Inscription et courrier | 500 inscriptions par heure ; 600 codes par 15 min ; 200 envois de code, 100 réinitialisations, 60 signalements, 30 messages de contact par heure | Refus jusqu'à la fin de la fenêtre | « Trop de tentatives. Réessaie dans N min. » | non (retombe seul) |
| nginx | 400 connexions simultanées ; 300 requêtes par seconde (pointe 600) ; fichiers statiques 2000 par seconde (pointe 5000) | Réponse 429 ou 503 sans message applicatif ; la page réessaie d'elle-même | « Le serveur est très sollicité. Réessaie dans quelques secondes. » | non (retombe seul) |
Le test général vérifie que le serveur sait envoyer. Les messages ci-dessous sont ceux que reçoit un client, avec des données d'exemple (prénom Camille, code, dates, montants) ; rien n'est écrit en base.
Les comptes de cette liste sont les tiens, pas ceux d'étudiants. Leurs paiements sont enregistrés comme essais de paiement (hors ventes), ils ne déclenchent pas les alarmes anti-extraction, et tu peux rouvrir pour eux seuls ce qui est fermé à tout le monde. Une ouverture se referme seule au bout de 24 heures.
| Adresse | Compte | E-mail vérifié | Abonnement | Reconnu | |
|---|---|---|---|---|---|
| Chargement… | |||||
Une adresse courte par endroit où tu diffuses le site : un groupe WhatsApp, une affiche, un e-mail. Elle mène à la page d'accueil ; le visiteur ne voit ensuite que l'adresse normale du site, et la visite est comptée sous ce canal dans Statistiques › Public. Aucun cookie : l'étiquette décrit le lien, pas la personne.
Lettres minuscules, chiffres et tirets, 20 caractères au plus. Plus c'est court, mieux ça se lit dans un message.
| Adresse à diffuser | Canal | Passages | Visites mesurées | Vers l'inscription | Dernière visite | État | |
|---|---|---|---|---|---|---|---|
| Chargement… | |||||||
La prod est un appareil lié du compte bot Signal ; le serveur perso reste l'appareil principal. Les messages (connexions à la console, ventes, sauvegardes en échec, alarmes) sont déposés dans une file vidée chaque minute par cron ; le message de test part en direct.
Chargement…
sudo -u www-data signal-cli --config /opt/nginx/private/signal-cli link -n "CoPhy prod"
signal-cli -a +41BOT addDevice --uri 'sgnl://linkdevice?…'
Ensuite, désactive sur le serveur perso les envois que la prod fait désormais elle-même, pour ne pas recevoir les messages deux fois.
| ID | Code | Nom du sujet | Nombre de questions | Actions |
|---|
| Matière | Code | Sujets associés | Examens | Questions | Utilisateurs | Actions |
|---|
L'ordre dans lequel les sujets s'affichent aux étudiants : liste des sujets des QCM, personnalisation du cours dans le profil, statistiques. Par défaut, celui du cours.
Une colonne par matière. Deux examens : A (automne) ou P (printemps) pour chaque sujet, à cliquer pour changer. U : examen unique, pour information. – : sujet absent de la matière. Custom : A ou P sur tous les sujets, pour l'élève qui choisit deux examens (il peut ensuite les changer).
| # | Chapitre | Titre | Partie | Cours | Sujets | Modifié | Actions |
|---|---|---|---|---|---|---|---|
| Chargement… | |||||||
| # | Slug | Sujet | Type | Titre | Essai | Tentatives | Réussite | Import → Validation | Modifiée | Actions |
|---|
Format : voir la documentation de l'onglet Import.
Variables aléatoires + expressions {{ v * t }}, math $\vec{F}$,
schéma Typst/CeTZ dans diagram: |.
Importe plusieurs questions en une seule fois depuis un fichier YAML. Les schémas sont écrits en Typst dans le YAML : il n'y a pas d'image à joindre.
Le format YAML est plus simple que JSON : pas de guillemets doubles partout, support natif des textes multiligne, etc.
Chaque question est d'abord validée et affichée en aperçu : tu peux l'éditer, la rejeter ou l'accepter avant l'import définitif.
Chaque question importée doit être relue et validée par l'autre personne que celle qui l'a importée. Tant qu'elle n'est pas validée, elle n'apparaît ni dans l'onglet Questions ni côté étudiants.
Colle ici le bloc « Exporter mes décisions » du fichier de revue hors ligne. Chaque décision est appliquée comme un clic en ligne ; une question modifiée entre-temps ou déjà tranchée est sautée et signalée.
| # | Slug | Sujet | Type | Titre | Importé par | À valider par | Date d'import | Actions |
|---|---|---|---|---|---|---|---|---|
| Chargement… | ||||||||
Refusées à la relecture : jamais servies aux étudiants, visibles par Théo et Hugo. Le motif du refus dit quoi corriger, et la colonne « À corriger par » désigne qui doit s'en charger : l'auteur de l'import. « Éditer » ouvre la question pour la corriger ; « Renvoyer en validation » la sort du refus une fois corrigée. Un ré-import du même slug fait pareil.
| # | Slug | Sujet | Type | Titre | Importé par | Refusé par | À corriger par | Date du refus | Actions | |
|---|---|---|---|---|---|---|---|---|---|---|
| Chargement… | ||||||||||
Pièces comptables au sens du CO (art. 957 ss) : chaque encaissement avec son numéro de reçu, l'identité du payeur (conservée même après suppression du compte, obligation de 10 ans) et les références Stripe pour la traçabilité. Pas de TVA : chiffre d'affaires sous le seuil d'assujettissement (CHF 100'000).
| Reçu n° | Date | User # | Nom | Montant | Remboursement | Moyen | Réf. Stripe | Abonnement jusqu'au | Litige | |
|---|---|---|---|---|---|---|---|---|---|---|
| Chargement… | ||||||||||
Chaque compte reste lié à la version qu'il a acceptée, jusqu'à ce qu'il accepte la suivante (article 10). L'instantané de chaque version est la preuve du texte accepté : son empreinte ne doit jamais changer une fois la version publiée.
| Version | Type | En vigueur du | au | Durée | Comptes liés | dont abonnés | Première acceptation | Dernière acceptation | Taille | Empreinte | Copie publique | Texte |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chargement… | ||||||||||||