Churros

La plateforme et application accompagnant la vie étudiante à l’ENSEEIHT (et plus à venir).

C’est une biletterie, un espace de communication des clubs et associations étudiantes, de partage de documents de révision, un annuaire étudiant, et un portail vers d’autres services offerts par l’association étudiante.

Contexte

Quand j’arrive à l’ENSEEIHT en 2022, la gestion des billets venait de passer aux mains d’une entreprise tierce, alors même que net7, l’association informatique étudiante de l’école, maintient et développe une billetterie.

Les fonctions d’annuaires et de liste des membres de clubs sont elles dans un portail, simple site web, lui également veillissant et ne répondant plus vraiment aux attentes des étudiant·es.

Il y a alors deux ans, un ancien président de net7 avait démarré une refonte totale de ces deux sites, en une seule application moderne intégrant un système de billetterie et un annuaire. À ce stade, l’application comprend un système rudimentaire de comptes (authentification et inscriptions) et posts.

Les débuts d'application déjà développés

Après avoir convaincu l’AE de rompre leur contrat avec l’entreprise tierce, dont l’application était remplie de failles de sécurité et globalement mal faite, je reprend les débuts de cette application, en offrant à l’AE des étapes et retours réguliers pour assurer de l’avancement de l’appli. Nous sommes alors en mai, 4 mois avant la rentrée. L’ensemble du corps étudiant s’inscrira dès le premier jour, et l’appli doit être prête à cette date.

Document partagé de feedback avec l'AE
Roadmap partagée avec l'AE

Notifications

Une des fonctionnalités phares de la nouvelle application est le support des notifications, pour par exemple prévenir qu’un shotgun (ouverture des inscriptions à un évènement) démarre. C’était un des arguments de vente principaux de l’entreprise tierce pour vendre son appli à l’AE.

Une notification destinée aux admins, annonçant une nouvelle inscription (désactivée pendant la rentrée)

Cependant, étant donné les contraintes de développement, Churros a démarré (voir Capacitor) comme une PWA, c’est-à-dire un site web avec des fonctionnalités supplémentaires qui la rapproche d’une application. Par exemple, les notifications Push.

Le support des notifications Push pour les sites web sur iOS était à l’époque très récent. Il fallait s’assurer que ces fameuses notifications fonctionnaient correctement au sein de la population générale, pas simplement sur quelques téléphones. On a donc demandé aux membres organisateurs de l’AE de tester massivement ces notifications, lors d’une de ces périodes de retours.

Cependant, à cette période, les notifications restent assez instables: lors du déploiement d’une mise à jour de l’application, on perd les notifications programmées (mais pas encore envoyées).

Plus tard, un serveur de notifications dédiés sera développé (voir Notella).

Enfin, avant la rentrée arrive, et l’on vérifie qu’elle supporte le pic de charge: la rentrée d’une nouvelle promotion d’n7ien·nes.

Stress test de l'application, on simule des dizaines d'inscriptions simultanées par seconde

Et enfin, le jour J arrive, et l’appli est présentée aux premières années, qui s’inscrivent en masse. Globalement, tout se passe bien, et les inscriptions aux évènements d’intégration de l’AE se déroulent sans soucis.

Diffusion d'une vidéo annonçant l'appli dans le grand amphithéâtre de l'école, réalisée par l'asso vidéo étudiante, TVn7

Fonctionnalités

Annuaire, groupes et clubs

Churros étant aussi un “réseau social” étudiant, il est possible de se faire un profil, et de rejoindre des clubs ou associations.

Être membre permet d’accéder aux évènements limités à celui-ci, et à la gestion des évènements, si l’on a des responsabilités. C’est aussi administrativement important d’avoir une liste des bureaux (président·e, et vices-président·es, trésorier·es et secréatires) de tout les clubs.

La page de l'asso photo, Photo7

Évènements

Quand l’AE ou un club organise un évènement, il est visible dans l’application. C’est ici que l’on peut réserver sa place.

Liste des évènements
Un évènement

Billetterie

La billetterie de Churros propose de nombreuses options pour représenter tout ce qu’une AE peut souhaiter d’avoir: limiter des billets à des promos, faire des évènements avec des personnes extérieures à l’école, pouvoir parrainer des personnes, faire des billets sur invitation, grouper des billets ensemble et limiter la somme de places sur les billets du groupe…

Réglages possible sur la billetterie d'un évènement

Une fois réservés, les billets sont scannables par les managers via un QR code, que la personne présente à l’entrée de l’évènement

Une communucation par Websockets permet à la page affichant le QR code de réagir en temps réel: dès que la place est scannée, et d’afficher une animation.

Les managers d’un évènement peuvent être rajoutés via un lien d’invitation, on en ayant un certain rôle (président·e, etc) au sein du groupe (club ou association) qui organise l’évènement en question.

Paiements

L’AE est paternaire avec Sumeria (anciennement Lydia), et utilise donc leur solution pour recevoir l’argent lors de l’organisation d’évènement paiements.

Churros s’intègre avec Sumeria pour permettre aux étudiant·es de payer leur place aux évènements.

Pour cela, Churros expose à Sumeria un webhook, sur lequel Sumeria envoie une requête pour notifier de la terminaison d’un paiement.

Par mesure de sécurité, Churros vient vérifier manuellement l’état du paiement au moment de l’accès au QR code.

Un API polyvalent

La vision d’ensemble derrière Churros était que la plateforme serve d’endroit unique de stockage de toutes les données relatives à la vie étudiante.

Ces données sont ensuites réutilistables de manières très diverses par d’autres services.

La technologie pour construire cette API n’est donc pas REST, comme c’est souvent le cas, mais GraphQL, une autre manière d’architecturer un API, qui permet au client d’exprimer ses besoins en données.

Par exemple, si un service tiers à besoin des photos de profils de l’ensemble des étudiants d’une promotion (pour faire un “trombinoscope”, par exemple), avec un API REST, si l’URL vers la photo n’est pas incluse dans la réponse d’un endpoint “lister les élèves d’une promo”, il faut faire n+1 requêtes, avec n le nombre d’étudiants:

/students?promo=2025
/students/1
/students/2
/students/3
...

Avec GraphQL, il suffit d’une requête: c’est le client qui décide quels données figurent dans la réponse. Il n’y a donc ni trop de données, ni pas assez:

query Trombinoscope {
  users(graduationYear: 2025) {
    profilePicture
  }
}

Étant donné le projet de base de donnée centrale qu’est Churros, il nous fallait un API dont les besoins en données soient inconnus.

L’API est développé avec les technologies suivantes:

  • Typescript: le langage de programmation. C’est un superset de Javascript, avec des types explicites.
  • Express: un framework de développement d’API, qui permet notamment de servir les routes de l’API qui sont en dehors de GraphQL: les médias (photos de profils, documents de la frappe), un webhook pour Lydia (voir Paiements), de quoi se connecter à Apple/Google Wallet, etc.
  • Pothos: permet de faire un serveur GraphQL en définissant les implémentations des différents champs de l’API, appelés resolvers en GraphQL.
  • Prisma: permet d’accéder à la base de données et de gérer l’évolution de sa structure, via des migrations.
  • PostgreSQL: la base de données relationnelle utilisée. Intéréssante notamment pour ses capacités de recherche texte approximative (appelée “fuzzy search”), et tout simplement pour sa popularité.

GraphQL étant moins populaire, j’ai développé, parallèlement à Churros, un système de génération de site de documentation interactif, Graphinx, qui a donc pu servir à documenter l’API de Churros:

Réagir aux bugs

L’application étant jeune, on s’attendait à avoir des bugs.

On a donc rendu le signalement de problèmes le plus simple, en l’intégrant directement à l’application

Un signalement devient une issue sur Gitlab, l’endroit où l’on développe. Passer d’une demande utilisateur au développement est donc naturel et sans efforts.

Notella

Afin de programmer les notifications et de les envoyer par la suite, un serveur séparé a été développé en Go, en utilisant NATS Jetstream pour communiquer en temps réel avec Churros.

Churros envoie un message Jetstream à Notella pour programmer une notification, et Notella la garde en mémoire.

Au moment d’envoyer la notification, Notella récupère l’ensemble des appareils qui ont activé les notifications, détermine à qui envoyer la notification (par exemple, on n’envoie pas une notification “le shotgun se ferme bientôt” aux gens qui ont déjà réservé leur place), et l’envoie via le service push associé à l’appareil (APNS pour Apple, Mozilla pour Firefox, Firebase pour Android, etc.)

En cas de mise à jour ou de redémarrage, Notella récupère les notifications programmées depuis une instance Redis.

Capacitor

Capacitor permet de packager une application web et de la mettre sur les stores iOS et Android.

Bien que le développement ne soit pas terminé par manque de resources, la merge request associé à ceci est quasiment finie, et les démarches administratives pour pouvoir publier en tant qu’association sur l’App Store sans payer ont été réalisées.

Déploiement

L’application est packagée sous forme de container Docker, et nécéssite plusieurs services tierces: base de données (PostgreSQL), serveur de cache et de messages pub/sub pour la communication en temps réel (Redis), service de programmation de notifications (Notella), etc.

Il est facile, via Docker, de lancer la plateforme ainsi que tout ses services, que ce soit:

  • En développement: avec Docker Compose (il suffit de taper docker compose up pour lancer tout les services tierces)
  • En production: avec Kubernetes.
Pods k8s de Churros en production

Quand une fonctionnalité est finie, de nombreux processus tournent sur notre instance Gitlab pour vérifier que le code fonctionne correctement (de la CI/CD)

Ensuite, au moment de sortir une nouvelle version de l’appli, les images Docker sont construites et publiées, et, par exemple, si la structure de la base de données à changer, elle est mise à jour dans le dépôt git de Notella

Enfin, quand la nouvelle version est prête à être déployée sur l’infrastructure de net7, Renovate propose de mettre à jour la version de Churros dans les fichiers de déploiement Kubernetes centraux.

En effet, net7 utilise FluxCD pour implémenter la pratique GitOps: le changement des fichiers Kubernetes dans le dépôt a pour conséquence leur modification dans les serveurs de production.

Documentation

Étant donné l’évolution rapide de l’équipe de développement, qui est une conséquence de la nature étudiante de l’association, il est essentiel de garder l’application maintenable, même après ma propre diplomation en 2025.

Un wiki pour développeurs documente l’architecture du code et le développement de l’application. Un fichier CONTRIBUTING.md explique comment contribuer au code.

Le prototype de l’application, expliquant son design, est disponible sur Penpot, une alternative open-source à Figma (net7 pensait à éventuellement héberger sa propre instance de Penpot)

time spent*

1952 hours coding


*tracked by WakaTime

réalisé avec