TROIS PRODUITS EN PRODUCTIONCARRIVSTUDYLUMINASANADE--:--:--MONTRÉAL · UTC-5
DISPONIBLE · STAGE 2027MONTRÉAL · UTC-5B.ING · DÉC. 2027

HoussamNadir.

le modèle génère, le code décide. trois produits en production, seul. un invariant non testé n’existe pas. du prompt jusqu’au webhook de paiement

Étudiant en génie informatique à Polytechnique Montréal. J’expédie des produits complets, seul : pipelines LLM à sorties structurées, scoring déterministe, comptabilité transactionnelle sans course, sécurité cloud. Trois plateformes en production, de la landing bilingue au webhook de paiement signé.

3
PRODUITS EN PRODUCTION
110k+
LIGNES DE TYPESCRIPT
941
CAS DE TEST · SANADE
3,65
GPA · HIVER 2026
01 · ./PRINCIPES --APPLIQUÉS

Ma thèse d'ingénierie

Trois principes, tenus dans les trois produits. Ce ne sont pas des slogans : chacun est vérifié par du code.

PRINCIPE I

Le modèle extrait, le code décide

Un LLM est excellent pour reformuler et classer, désastreux pour produire un nombre censé être reproductible. Chaque chiffre affiché à l'utilisateur sort d'une fonction pure.

Carrivscore ATS déterministeStudyLuminaERS, fonction pure de ~850 lignesSanadezéro modèle entraîné
PRINCIPE II

Un invariant non testé n'existe pas

Les règles produit descendent au niveau du test : elles échouent la CI au lieu de vivre dans un document que personne ne relit.

Cliquetles any ne remontent jamaisSeuilsclient ≡ serveur, vérifiéArchitecturefaits ⇸ projectionsCouleursaucun littéral en dur
PRINCIPE III

La contrainte d'exécution est une contrainte de conception

Le serverless, le débit d'un fournisseur, la mort d'une Lambda : des paramètres d'architecture, pas des accidents à absorber en production.

Timeout90 s < durée de vie LambdaCréditréservé avant l'appelRate limiten base, pas en mémoire
LE BUG QUI A CRÉÉ UNE RÈGLE

Huit copies d’une palette codaient les valeurs du thème clair en dur : le meilleur score possible s’affichait à 1,59:1 de contraste sur le thème sombre, invisible. Après passage aux tokens : 9,95:1. Depuis, un test interdit les couleurs littérales dans les composants.

CE QUE JE REFUSE D'EXPÉDIER

Une expérience inventée par un modèle, un score qui régresse sans raison explicable, un crédit débité pour une génération jamais reçue, un PDF joli mais illisible par un ATS. Ces quatre refus ont chacun produit une ligne d'architecture.

02 · QUATRE DOSSIERS, RIEN DE CACHÉ

Études de cas

CAS 01Carriv
RÔLEConception & développement, seulPÉRIODE2026STATUTEn productionVOIR EN LIGNE ↗

Carriv : adapter un CV à une offre, sans jamais rien inventer

Postuler correctement demande 30 à 45 minutes par candidature ; demander à un chatbot de « faire le CV » produit des expériences inventées qui s'effondrent en entretien. Carriv adapte un profil maître à une offre donnée sous une règle de zéro invention inscrite dans chaque prompt.

Capture Carriv : CV adapté et score ATS
APERÇU AUTOMATIQUE DE CARRIV.COM · CAPTURÉ APRÈS STABILISATION
CE QUE ÇA CHANGE POUR LE CANDIDAT
01

30 à 45 minutes de travail par candidature ramenées à une trentaine de secondes.

02

Rien d'inventé : tout ce qui est écrit sur le CV est défendable en entretien.

03

Le PDF passe les filtres ATS au lieu d'être rejeté par sa mise en page.

04

Le crédit est remboursé automatiquement si la génération échoue. Jamais payé pour rien.

LE PROBLÈME

Le modèle peut réordonner, sélectionner, reformuler et omettre, mais jamais fabriquer une expérience, une date, un employeur, un diplôme ou un chiffre. La traduction est la seule transformation autorisée, avec fidélité stricte du niveau de diplôme.

LA DÉCISION CENTRALE

Le score ATS n'est pas produit par le modèle. Un vrai ATS est un moteur de correspondance de mots-clés, pas un juge : le LLM extrait et classe les écarts, le score est une fonction déterministe. Re-scorer donne toujours le même nombre, et appliquer une reformulation ne peut qu'ajouter un mot-clé, donc jamais faire baisser le score.

POST /api/generate · LE PIPELINE
resolveApiUser session ou token personnel (extension) enforceRateLimit 30 générations / h / utilisateur getProfile scopé userId : jamais d'accès croisé reserveCredit findOneAndUpdate atomique { credits: { $gte: 1 } } → 402 analyzeJob Structured Outputs · modèle principal adaptCVAndLetter Structured Outputs · modèle principal scoreATS matching déterministe, pondéré must=2 / nice=1 createApplication catch → refundCredit + alerte
~30 s
GÉNÉRATION
10
MODÈLES PDF
30/h
PLAFOND
2
DEVISES
REMBOURSEMENT GARANTI

Client OpenAI plafonné à 90 s et une seule reprise, au lieu de 10 minutes et 2 retries. Sur Vercel, une requête pendue doit échouer pendant que la Lambda vit encore, sinon le catch qui rembourse ne s'exécute jamais et l'utilisateur paie une génération qu'il n'a pas reçue.

LE MUR ATS

L'application a une direction artistique affirmée ; les PDF restent strictement ATS-safe : une colonne, typographie seule, aucune couleur ni décor. C'est exactement là que la plupart des générateurs échouent.

SÉCURITÉ PAIEMENT

Le montant Stripe n'est jamais cru côté client : le nombre de crédits vient de la table serveur indexée par Price ID, webhook vérifié par signature. Tokens d'extension stockés en SHA-256 uniquement. Plafond explicite à 30 pages contre les bombes de décompression PDF.

SvelteKit 2Svelte 5 runesTypeScript strictMongoDBbetter-authOpenAI Structured OutputsStripepuppeteer-coreVercelVitest
CAS 02StudyLumina
RÔLEConception & développement, seulPÉRIODE2026STATUTEn productionVOIR EN LIGNE ↗

StudyLumina : mesurer la préparation réelle à un examen

Les outils d'étude IA s'arrêtent à la génération de contenu. StudyLumina mesure la préparation réelle, chapitre par chapitre, et indique quoi faire aujourd'hui. Aucune note n'est jamais produite par un LLM.

Capture StudyLumina : préparation par chapitre
APERÇU AUTOMATIQUE DE APP.STUDYLUMINA.COM · CAPTURÉ APRÈS STABILISATION
CE QUE ÇA CHANGE POUR L'ÉTUDIANT
01

Une réponse à la seule question utile : suis-je prêt, sur quel chapitre, et que faire aujourd'hui.

02

Chaque réponse est citée (document et page), donc vérifiable au lieu d'être crue.

03

Le score s'expose à la contradiction : l'erreur moyenne face aux vraies notes est affichée.

04

On dépose un PDF et on continue à travailler : résumé, flashcards et quiz arrivent en arrière-plan.

LE PROBLÈME

Un résumé ne dit pas si l'étudiant est prêt. Sans rattachement d'un document à un chapitre, impossible d'attribuer une réponse de quiz à une matière, donc impossible de mesurer autre chose qu'une moyenne globale sans valeur.

LA DÉCISION CENTRALE

Cours → Chapitre → Document est obligatoire : un document orphelin n'existe pas. C'est la condition de possibilité de tout le produit. L'Exam Readiness Score est une fonction pure de ~850 lignes, sans réseau ni LLM, et l'ajout du facteur de rétention est gaté : un chapitre sans flashcard révisée obtient un score strictement identique à avant, prouvé par test.

INGESTION ASYNCHRONE · 6 FILES BULLMQ
upload → ingestion extraction PDF, nettoyage pages → embeddings chunking, batch + rate-limit, pgvector → course-map rattachement chunks ↔ chapitres → summary | flashcards | quiz (en parallèle) RAG hybride : pgvector + BM25 (GIN) fusionnés, filtrés cours/chapitre, SQL paramétré. Sur un follow-up, la question est condensée en requête autonome avant récupération. Citations → document + page.
47 600
LIGNES TS
78
ROUTES API
74
FICHIERS DE TESTS
25
MODÈLES PRISMA
UN SCORE FALSIFIABLE

L'étudiant saisit sa vraie note après l'examen ; le produit affiche l'erreur moyenne entre score prédit et note obtenue. La note réelle n'est jamais réinjectée dans le calcul : le score se rend réfutable au lieu de se déclarer juste.

HONNÊTETÉ DU SCORE

La couverture agit en multiplicateur de confiance : trois bonnes réponses ne peuvent pas faire lire « Ready ». Le score global est lissé, donc un seul mauvais quiz ne fait pas tout s'effondrer.

MODÈLE DE DONNÉES

Modèle bridge DocumentChapterSpan avec plages de pages plutôt qu'une clé étrangère : un PDF couvre souvent plusieurs chapitres, un chapitre s'étale sur plusieurs PDF. Aucune métrique scalaire en JSON brut.

Next.js 15React 18PostgreSQL + pgvectorPrisma 6BullMQ + RedisAuth.js v5Gemini / OpenAI / DeepSeekStripePino + Prometheusnext-intl
CAS 03Sanade
RÔLEConception & développement, seulPÉRIODE2025-2026STATUTEn productionVOIR EN LIGNE ↗

Sanade : le suivi d'habitudes qui arbitre au lieu d'enregistrer

Les trackers affichent fidèlement l'écart entre le prévu et le fait, pendant des mois, sans jamais rien en faire. Sanade calcule le temps réellement utilisable dans la journée, propose deux ou trois objectifs tenables et écarte le reste en disant pourquoi.

Capture Sanade : arbitrage du jour
APERÇU AUTOMATIQUE DE SANADE.APP · CAPTURÉ APRÈS STABILISATION
CE QUE ÇA CHANGE POUR L'UTILISATEUR
01

Deux ou trois objectifs tenables pour aujourd'hui, au lieu d'une liste de douze qui culpabilise.

02

Chaque objectif écarté est motivé : l'utilisateur voit pourquoi, il ne subit pas un tri opaque.

03

On écrit sa note en français, en darija translittérée ou en arabe : le texte brut est conservé tel quel.

04

Web et mobile partagent le même cœur de domaine : aucune divergence de calcul entre les deux.

LE PROBLÈME

Une capacité déclarée est une capacité fantasmée. Et avec six domaines et des décalages temporels, un cycle d'analyse teste des centaines de paires : un seuil individuel garantirait mécaniquement des faux liens à chaque passage.

LA DÉCISION CENTRALE

Faits contre projections, visible dans les noms de tables : tout calcul stocké porte le préfixe proj_, donc clearProjections() est sûr à tout moment et une formule de score peut être corrigée sans laisser un historique incohérent. Aucune table de faits ne pointe vers une projection, et un test d'architecture le vérifie, parce que la règle a déjà été violée en silence une fois.

INGESTION · UNE EXTRACTION NE CRÉE JAMAIS DE DONNÉE
texte brut (FR / darija translittérée / arabe) → RawNote stockée telle quelle, jamais réécrite → prompt versionné + LLM côté serveur → JSON validé par schéma Zod strict ├─ échec → une réparation, puis échec journalisé └─ succès → Extraction { proposals, confidence } → écran de revue validation item par item → Trackable (PLAN) ou LogEntry (CHECKIN)
62 000
LIGNES TS
941
TESTS
13 700
DOMAINE PUR
0
SERVICE REQUIS
LA BIENVEILLANCE EST DANS LA FORMULE

Une journée non renseignée sort du calcul au lieu de compter zéro : elle fait baisser la confiance affichée, jamais le score. Trois jours sans données affichent « score 74, confiance faible », pas « score 31 », sinon le produit punirait le fait de ne pas ouvrir l'application.

RIGUEUR STATISTIQUE

Ce qui est affiché est une fréquence conditionnelle empirique : deux nombres refaisables à la main. Les liens sont testés par cycle complet, le nombre de tests est compté, et la publication est filtrée sur le taux de fausses découvertes. Chaque motif fige son cycle.

CŒUR DE DOMAINE PUR

packages/core n'importe jamais db, api, ingestion ni React : 13 700 lignes testables sans base, sans réseau, sans clé d'API. La logique ne peut pas diverger entre web et mobile : c'est une propriété de la structure, pas une discipline.

TypeScript ESMNext.js 16 / React 19Expo · React NativetRPC v11Prisma + PostgreSQLPGlite (WASM)ZodVitest · PlaywrightTurborepo · pnpmSentry
CAS 04CSPM-Lite
RÔLEOutil personnelPÉRIODE2025STATUTOutil interne

CSPM-Lite : la sécurité cloud qui bloque le pipeline

Un outil CLI qui analyse un compte AWS, détecte les mauvaises configurations, évalue la conformité et produit des rapports exploitables, puis refuse de laisser passer le déploiement.

~/cspm-lite
$ cspm-lite scan --account prod --gate
CE QUE ÇA CHANGE POUR L'ÉQUIPE
01

Une faille critique arrête le déploiement : la sécurité devient une porte, plus un rapport.

02

Deux sorties : du JSON pour la machine, du HTML lisible pour la revue humaine.

03

Des contrôles alignés CIS sans licence d'outil commercial.

LE PROBLÈME

Une mauvaise configuration cloud ne se voit pas dans une revue de code : bucket S3 public, port SSH ouvert, utilisateur sans MFA. Elle se voit en production, ou dans une fuite.

LA DÉCISION CENTRALE

Le rapport ne suffit pas : personne ne lit un rapport. Le contrôle devient bloquant : une faille critique arrête le pipeline CI/CD, ce qui déplace la sécurité de l'audit vers la porte d'entrée.

CONTRÔLES ET SORTIES
scan compte AWS → détection S3 public · SSH ouvert · absence de MFA → conformité contrôles alignés CIS Benchmark → priorisation criticité + recommandation de remédiation → rapports JSON (machine) + HTML (humain) → gate CI/CD faille critique → build bloqué
CIS
RÉFÉRENTIEL
2
FORMATS DE RAPPORT
CI
BLOCAGE ACTIF
A
COURS CYBERSÉCURITÉ
POURQUOI CET OUTIL

Le cours de cybersécurité donne les concepts ; un compte AWS réel donne les mauvaises surprises. Cet outil est né du besoin de vérifier mes propres déploiements avant qu'un correcteur, ou un attaquant, ne le fasse.

LABORATOIRES ASSOCIÉS

Découverte réseau, énumération de services, sécurité web de base et dépannage en environnement Linux. Advent of Cyber (TryHackMe, déc. 2025) pour la démarche d'investigation structurée.

PythonAWS SDK (boto3)CIS BenchmarkLinuxGitHub ActionsJSON / HTML
03 · AGRÉGÉ SUR LES TROIS PLATEFORMES

Ce que ça représente

~110 000
LIGNES DE TYPESCRIPT
941 + 74
CAS DE TEST · FICHIERS DE TESTS
78
ROUTES API · STUDYLUMINA
3
PRODUITS BILINGUES FR/EN
0
MODÈLE ML ENTRAÎNÉ
2
WEBHOOKS STRIPE EN PROD

Les trois produits partagent la même colonne vertébrale : validation par schéma à toutes les frontières, jamais de .parse() qui explose, clients externes initialisés paresseusement pour qu'un build passe sans secret, et un échec bruyant préféré à une valeur fabriquée en silence.

04 · FILTRER PAR DOMAINE

Capacités

TypeScript strictexpert
Next.js · SvelteKit · Reactavancé
Node.js · API typées (tRPC)avancé
Pythonavancé
C / C++ · systèmessolide
PostgreSQL · Prisma · MongoDBavancé
AWS · déploiement serverlesssolide
Docker · Linux · WSLavancé
Files de travaux (BullMQ · Redis)solide
RAG · pgvector · embeddingssolide
Sécurité applicative · authentificationavancé
Posture cloud · CIS · IAMsolide
Reconnaissance réseau · Linuxsolide
05 · GLISSER →

Parcours

→ DÉC. 2027

B.Ing. génie informatique

Polytechnique Montréal

Parcours orienté systèmes sécurisés, cloud et environnements distribués.

Cybersécurité : ASystèmes répartis & infonuagique : B+GPA : 3,65 (hiver 2026)
DEPUIS OCT. 2024

Représentant de marque

Qualcomm / Snapdragon PC, Channel Partners

Vulgarisation de solutions techniques auprès du public : adapter le discours à chaque interlocuteur, rendre une architecture compréhensible en deux minutes. C'est la compétence qui rend une décision d'ingénierie défendable.

2025-2026

Trois produits expédiés seul

Carriv · StudyLumina · Sanade

Conception, développement, mise en production, paiement, e-mails transactionnels, SEO bilingue et observabilité, sans équipe.

CERTIFICATIONS & LANGUES

Repères

Advent of Cyber · TryHackMe · déc. 2025Français : natifAnglais : courantMontréal, QC · ouvert au télétravail
~/contact
$ ouvrir --canal stage-2027

Donnez-moi la contrainte, je reviens avec l’architecture.

Je cherche un stage où je touche à la production : pipeline, sécurité, données, pas seulement à la maquette. Réponse sous 24 h.

MONTRÉAL, QCUTC-5FR / ENDISPONIBLE 2027