22 projets hors école

Projets perso

Tout ce que j'ai construit en dehors de l'école : des automatisations en service, des applications que j'utilise chaque jour, et quelques jeux.

Automatisation & IA

Un workflow de relance de devisvidéo · 0:16

DataDawn

en service

Mon cabinet d'automatisation : des assistants IA en service chez des PME, l'équipe valide ce qui compte.

n8n · Claude · Mistral · Next.js · PostgreSQL

Fil d'offres notées et mode Découvrirvidéo · 0:43

JobHunter

en service

Collecte d'offres chaque matin, notation contre le profil de chacun, trajet réel, le tout rangé dans un hub.

Python · API France Travail · Claude · Next.js · PostgreSQL

La présentation, section par sectionvidéo · 0:24

JARVIS

en service

Un assistant personnel qui trie les mails de cinq comptes et prépare le reste, sans rien envoyer sans mon feu vert.

Claude · Telegram · Gmail API · Python

« Ce soir ? », sections, fichevidéo · 0:25

Magpie

en service

Les captures d'écran, vidéos et liens mis de côté deviennent des fiches classées et recherchables.

Claude · Next.js · Obsidian · PostgreSQL

Jour, semaine, mois, recherchevidéo · 0:24

Memogram

en service

Un journal tenu en écrivant à un bot Telegram : chaque journée est résumée, rangée par semaine et par mois.

Telegram · Claude · Next.js

Memogram

Memogram

Journal de mémoire tenu en racontant sa journée à un bot Telegram, en vocal ou en texte, avec résumés du soir, de la semaine, du mois et de l'année

TypeScript · Next.js 16 · Telegram Bot API · Mistral · faster-whisper · Python · Drizzle · PWA

Un journal qu'on tient sans ouvrir d'app : on raconte sa journée au fil de l'eau à un bot Telegram, il transcrit, range et résume.

Contexte

Projet perso démarré le 13/10/2026, en version 0.8.0 depuis le 17/10. Volontairement séparé de JARVIS : Memogram reste un journal, il ne fait que lui transmettre ce qui ressemble à une demande.

Fonctionnalités

Raconter :

  • Notes en vocal, en texte ou en photo légendée
  • Corriger en répondant à la note, ou compléter avec +
  • La journée se coupe à 7 h ; un récit d'un autre jour (« ma journée de jeudi ») est rangé au bon jour

Relire :

  • Résumé chaque soir, puis chaque semaine, chaque mois et chaque année
  • Commandes /aujourdhui, /hier, /semaine, /mois, /cherche, /qui
  • Recherche par le sens, sans le mot exact
  • « Il y a un an » dans le message du soir
  • PWA de relecture ouverte par un lien à usage unique envoyé par le bot : jour, semaine, mois, personnes, recherche toujours visible

Se souvenir :

  • Exercice de mémoire quotidien : retrouver de tête une note passée, revues espacées
  • Fiche avant un rendez-vous : ce que le journal sait de la personne

Liens

Repo privé. Données intimes : pas de démo publique.

Architecture

Deux moitiés : un serveur toujours joignable et un PC qui fait le travail lourd quand il est allumé.

Telegram (vocal/texte) ──webhook──▶ Next.js sur Vercel + Postgres (Neon)
                                     ├─ transcription cloud immédiate (Mistral Voxtral)
                                     ├─ résumés (Mistral) : cron du soir, lundi, 1er du mois
                                     └─ file de travail du PC
                                                  ▲
PC allumé ── worker Python (toutes les 15 min) ───┘
             ├─ re-transcrit les vocaux (faster-whisper large-v3, GPU)
             ├─ fait les résumés que le cloud n'a pas pu faire (claude -p)
             ├─ archive les vocaux en local
             └─ recopie le journal dans le vault Obsidian

Rien ne dépend d'un crédit

Chaque passe cloud renvoie un résultat typé ; un échec (clé absente, crédit épuisé, panne) bascule le travail vers la file du PC au lieu de le perdre. Le bot prévient que la transcription arrivera au prochain allumage du PC.

Choix techniques

  • Deux transcriptions : Voxtral, guidé par un vocabulaire de noms propres, fait foi ; Whisper sur le PC ne sert que si le cloud a échoué, et n'écrase jamais une correction manuelle.
  • Pas de stockage audio côté serveur : on garde l'identifiant de fichier Telegram, l'archive vit sur le PC.
  • États explicites : une entrée passe par pending_cloud → pending_local → done ; toute modification rend « périmés » les résumés qui couvrent sa date, regénérés au cron suivant.
  • Un seul cron (compatible Vercel Hobby) qui rattrape les jours manqués, regénère du jour vers l'année et envoie le brouillon du soir.
  • Worker sobre en mémoire : il attend d'avoir assez de RAM libre, se déclare première cible en cas de manque de mémoire, et réessaie au tour suivant sans perte.
  • Pas de correction « logique » par LLM sur le texte : sur un journal, inventer est pire que mal orthographier.
  • Couches : routes courtes → services → repositories (Drizzle). Tests Vitest sur PGlite, zéro réseau ; tests pytest côté worker.

Ponts vers d'autres apps

Une extraction structurée repère ce qui est exprimé comme une intention (tâche, rappel, idée) et l'annonce avant de le confier à l'assistant JARVIS, avec 10 minutes pour annuler. Les nuits, candidatures et dépenses racontées partent vers les apps dédiées seulement si elles sont prouvées par une citation de la note.

Stack

TechRôle
Next.js 16 / React 19Webhook, API, PWA de relecture
Drizzle + Postgres (Neon)Entrées, résumés, files de travail
Mistral (Voxtral, large, embed)Transcription, résumés, recherche par le sens
Python + faster-whisperWorker PC (GPU)
Zod, joseValidation, sessions
Vitest + PGlite, pytestTests sans réseau
Deux agents Claude construisent un projet seulsvidéo · 0:28

MAO

en pause

Un orchestrateur où deux agents Claude, un chef qui planifie et un ouvrier qui code, construisent un projet de A à Z sans intervention.

Python · FastAPI · Claude · React · Vite

MAO - Multi-Agent Orchestrator

MAO - Multi-Agent Orchestrator

Framework d'orchestration d'agents Claude (Prompt, Chef, Worker) qui génère des projets de A à Z via Claude Code CLI

Python 3.11 · FastAPI · React 19 · Vite · Claude Code CLI · WebSockets · Pydantic · Multi-Agent

Framework qui fait collaborer plusieurs agents Claude pour générer des projets entiers sans micro-management.

Contexte

Projet personnel démarré le 03/02/2026. Premières versions (0.1 → 0.4) le jour même, memory system en v0.5.0 (24/04), dashboard cross-projet et historique des runs en v0.8.0 (25/04), v1.2.0 le 01/05 avec la mémoire partagée entre projets. Le Completeness Gate a été retravaillé en juillet 2026.

Claude Code seul fait du bon travail, mais sur des tâches longues il faut le relancer sans arrêt. MAO automatise cette boucle : un agent clarifie le besoin, un autre planifie, un troisième exécute.

Fonctionnalités

Abonnement plutôt qu'API - Le worker passe par Claude Code CLI en subprocess : MAO consomme l'abonnement, pas des tokens API facturés à l'unité.

Memory system - MAO note patterns, erreurs et succès, puis les réinjecte dans les prompts des runs suivants, y compris d'un projet à l'autre.

Completeness Gate - Un run ne se termine qu'une fois les vérifications passées.

Overnight mode - tmux détaché, checkpoint atomique, reprise après interruption.

Web UI temps réel - Split view Chef/Worker via WebSocket, dashboard cross-projet, file d'approbation sécurité.

Liens

Repo privé. Outil utilisé en local sur WSL, pas de démo hébergée.

Concept

Trois agents Claude collaborent pour bootstrapper un projet complet :

┌──────────────┐
│ PromptAgent  │  Dialogue avec l'utilisateur
│  (dialogue)  │  → specs, bootstrap, prompts
└──────┬───────┘
       │  mao run
       ▼
┌──────────────┐       ┌──────────────┐
│  ChefAgent   │ ────▶ │ WorkerAgent  │
│ (planifie)   │ ◀──── │ (exécute)    │
└──────────────┘       └──────────────┘
                        Claude Code CLI → code réel sur disque

Workflow : mao init → conversation → mao run → projet bootstrappé.

Abonnement plutôt qu'API

Le provider principal appelle Claude Code CLI en subprocess (claude --print --output-format=json) au lieu de l'API Anthropic. MAO consomme l'abonnement Claude Code ; le JSON renvoyé sert à suivre tokens et coût estimé par run. Le provider API direct reste un stub.

Memory system

MAO capture ce qu'il apprend pendant l'exécution, en cinq types : PATTERN, LEARNING, DECISION, ERROR, SUCCESS.

  • Retrieval sans embeddings : somme pondérée de correspondance de tags, recouvrement de mots-clés, confiance et récence (décroissance exponentielle, demi-vie 30 jours)
  • Injection markdown dans les system prompts, avec un budget de caractères
  • Depuis la v1.2 : pool de mémoire global partagé entre projets

Exécution hiérarchique

Pour les gros projets, un ArchitectAgent découpe en sous-systèmes avant de déléguer aux Chef/Workers. Coordination via un message bus interne. Workers spécialisés (backend, frontend, test, devops) routés par capability tags. Effort réglable par tâche (low → max).

Completeness Gate

Un run n'est déclaré terminé qu'après une série de vérifications enregistrées (dont un smoke test des scripts du projet). Depuis juillet 2026, la comptabilité des rejets tient compte de la progression, et une option permet de clore avec réserves quand le gate est épuisé.

Web UI

Sept pages React (Vite + composants shadcn/ui + Zustand + Tailwind 4) :

  • Prompt - chat avec PromptAgent + liste des projets
  • Dashboard - vue cross-projet : statuts, runs sur 30 jours, mémoire par type
  • Settings - configuration Chef/Worker
  • Approvals - file de sécurité + audit log
  • Split View - Chef ↔ Worker en temps réel via WebSocket (NarratorAgent, timers, effort)
  • Stats - timeline, fichiers et langages produits
  • Memory - CRUD des entrées, aperçu du retrieval

Module Security

  • Modes : autonomous (défaut, checks désactivés) ou strict (checks actifs, commandes risquées bloquées ou soumises à approbation)
  • Auto-whitelist en strict : scripts dev détectés (package.json, Makefile, pyproject.toml)
  • Audit log JSONL

Overnight mode

Pour les runs de plusieurs heures : backend uvicorn en tmux détaché, checkpoint atomique (temp + swap) par run, reprise d'un run interrupted depuis l'UI, pause/resume manuels.

Stack

TechVersionRôle
Python3.11+Core orchestration
Pydantic2.xModèles et settings typés
Typer0.12+CLI
Loguru0.7+Logs structurés
FastAPI0.109+Backend Web UI
WebSockets12+Stream temps réel
React19Web UI
Vite7Build front
Zustand5State front
Schéma : qui passe par la passerelle
Schéma : qui passe par la passerelle

Home Gateway

en service

Le point d'accès unique de mes outils : il détient les accès à mes comptes, les sert à mes autres apps et garde la trace de chaque usage.

Next.js · PostgreSQL · Drizzle · NextAuth

Home Gateway

Home Gateway

Hub personnel qui détient seul les accès à mes comptes et les sert, sous contrôle et avec trace, à mes autres applications

TypeScript · Next.js 16 · PostgreSQL · Drizzle · OAuth · Chiffrement · Journal d'accès

Le point d'accès unique de mon écosystème perso : il garde les clés, les autres apps demandent.

Contexte

Projet perso démarré en juillet 2026, d'abord pour alimenter la page « nouvel onglet » de mon navigateur sans y stocker de jeton. Il est devenu le hub de mon assistant personnel : chaque nouveau service passe par lui plutôt que par un connecteur de plus.

Fonctionnalités

Lecture centralisée :

  • Flux en lecture pour mes notes, agendas, mails, tâches, dépôts, déploiements et soldes bancaires
  • Plusieurs comptes par service, connectés depuis une console privée

Actions sous contrôle :

  • Brouillons et envois de mail, rangement de fichiers, écriture d'agenda, capture rapide dans mes notes
  • Validation humaine sur mobile pour ce qui est sensible, règles de confiance pour le reste

Gouvernance :

  • Jetons d'appareil révocables un par un depuis la console
  • Journal de chaque accès consultable, jamais purgé sans décision de ma part

Liens

Repo privé. Infrastructure personnelle, pas de démo publique.

Rôle

Un point d'entrée unique entre mes applications et mes comptes en ligne (mail, agenda, stockage, dépôts de code, hébergement, banques). Les applications clientes ne détiennent jamais un jeton de service : elles reçoivent un jeton d'appareil propre à chacune, révocable un par un, et le hub fait les appels à leur place.

Extension navigateur ─┐
Routines d'assistant ─┤                     ┌─► Comptes mail / agenda / stockage
Apps perso ───────────┼─► Hub (portier) ────┼─► Dépôts de code / hébergement
Téléphone / PC ───────┘    │                └─► Banques (lecture)
                           └─► Journal d'accès (écrit avant tout accès)

Contrôle d'accès

  • Jeton d'appareil par client, stocké haché, borné à une liste de portées (« portes ») et limité en débit
  • Une porte = une ligne dans un registre central : ajouter un accès se fait dans un commit relu
  • CORS strict, jamais ouvert à tous ; une porte non configurée répond une erreur explicite
  • Multi-locataire : le locataire se déduit du jeton présenté, jamais d'une variable ; les portes adossées à des accès propres au propriétaire refusent un jeton invité

Secrets

  • Jetons de rafraîchissement chiffrés (AES-256-GCM) avec données associées liées au propriétaire, au fournisseur et au compte, et une version de clé
  • Jetons d'accès gardés en mémoire seulement, jamais écrits en base
  • Connexion du propriétaire fail-closed (liste d'utilisateurs vide = personne n'entre), état OAuth signé + PKCE
  • Les logs masquent tout ce qui ressemble à un jeton

Traçabilité et feu vert

  • Journal d'accès fail-closed : chaque lecture sensible et chaque action est inscrite (quoi, qui, pourquoi) avant d'être exécutée ; si la ligne ne peut pas s'écrire, rien ne se passe
  • Liste fermée d'actions : une routine ne peut demander que des actions déclarées dans le code, jamais un paramètre libre
  • Feu vert humain : une action sensible attend ma validation sur mobile, expire si je ne réponds pas, et est refusée si elle a été modifiée après l'envoi (empreinte vérifiée)
  • Règles de confiance : certaines actions répétitives peuvent passer sans bouton, sous une règle explicite, plafonnée sur 24 h et annoncée avant d'agir ; au moindre doute, retour au bouton

Stack

TechRôle
Next.js 16 (App Router)Portes machine + console propriétaire
TypeScriptTypage strict
PostgreSQL + DrizzleJetons, comptes chiffrés, journal, règles
NextAuthConnexion du propriétaire
VitestTests (chiffrement, masquage, portier, actions)

Couches route → service → repository, migrations additives seulement, rejouées de façon idempotente au build.

Applications

Ce soir, une ambiance en phrase libre, la banquevidéo · 0:17

Nightjar

en service

Le film du soir en moins d'une minute : une envie dite en phrase libre, un goût appris sur ce qu'on a vu, seulement sur ses abonnements.

Next.js · PostgreSQL · TMDB · GitHub Actions

Nightjar

Nightjar

PWA qui trouve le film du soir en moins d'une minute : recherche par ambiance en phrase libre, goût appris sur ce qu'on a vu, dispo sur ses abonnements

TypeScript · Next.js 16 · React 19 · Drizzle · PostgreSQL · TMDB · GitHub Actions · PWA · Passkeys

Le bon film en moins d'une minute : on dit ce qu'on a envie de voir comme on le dirait sur le canapé, Nightjar répond avec une affiche, sa raison et l'endroit où le regarder ce soir.

Contexte

Projet perso démarré le 30/10/2026, en ligne depuis le 02/11. Né d'une soirée passée à chercher un film plus longtemps qu'à le regarder.

Fonctionnalités

Choisir :

  • « Ce soir » : un film principal et quatre autres, réglés par humeur, durée, avec qui, et seulement sur ses abonnements
  • Ambiance en phrase libre, avec les mots compris surlignés et modifiables
  • « Comme… » : des voisins d'un ou plusieurs films de départ
  • Bande-annonce, note, durée et plateformes sur chaque carte

Apprendre le goût :

  • Gestes déjà vu, aimé, adoré, garder, pas pour moi, plus ou moins comme ça
  • Calibrage rapide sur des affiches au premier lancement
  • Banque des films gardés, avec ceux qui viennent d'arriver sur ses plateformes

À plusieurs :

  • Soirée partagée par lien, invités sans compte, vote et classement commun

Liens

Repo privé, application personnelle : pas de démo publique.

Architecture

TMDB + notes IMDb ──synchro de nuit (GitHub Actions)──▶ Postgres (Neon)
                                                        ├─ ~18 000 films, dispo FR par plateforme
                                                        └─ axes d'ambiance (règles, affinés la nuit)
Phrase libre ──analyse par règles──▶ filtres + score déterministe ──▶ cartes avec leur « pourquoi »
Gestes (vu, aimé, adoré, gardé, pas pour moi) ──▶ profil de goût en pôles

Recherche sans IA payante

Une phrase comme « huis clos tendu, pas trop gore, moins de 1 h 45, sur mes abonnements » est découpée par règles : durée, années, plateformes, exclusions, contexte, titres cités. Le classement est un score déterministe affiché sur chaque carte, avec la phrase qui l'explique. Aucune requête ne passe par un modèle : réponse en moins de deux secondes, coût nul.

L'ambiance, mesurée

Les genres sont trop grossiers (« horreur » range ensemble un film lent et psychologique et un film à sursauts). Chaque film reçoit sept axes continus (tension, sursauts, gore, humour, rythme…) : une première lecture par règles à chaque synchro, puis un affinage la nuit par Claude sur l'abonnement, jamais pendant une recherche.

Choix techniques

  • Goût en pôles : chaque film adoré est un pôle à lui seul, avec sa propre époque ; un facteur d'époque évite de proposer un film des années 50 à qui n'aime que des films récents.
  • Diversité : sélection MMR pour que les cinq propositions ne soient pas cinq fois le même film.
  • Synchro hors Vercel : l'import initial compte environ 18 000 appels, il tourne dans GitHub Actions, limiteur sur horloge monotone.
  • Soirée à plusieurs : un lien partagé, des invités sans compte qui votent, un classement commun.
  • Ponts machine par jeton : le journal Memogram y envoie les films racontés, Magpie les films repérés dans des vidéos ; Nightjar reste seul maître de l'état d'un film.
  • Couches : Server Actions et routes courtes → services → repositories (Drizzle). Tests Vitest sur PGlite, sans réseau ; dix décisions d'architecture écrites.

Stack

TechRôle
Next.js 16 / React 19App, Server Actions, PWA hors ligne
Drizzle + Postgres (Neon)Catalogue, goûts, soirées
TMDB, JustWatch, IMDbFiches, dispo FR, notes
GitHub Actions + ClaudeSynchro et notation d'ambiance de nuit
next-auth + passkeysConnexion Face ID
Vitest + PGliteTests sans réseau
Navigation et recherchevidéo · 0:26

Obsidian Web

en service

Mes notes Obsidian lisibles et modifiables depuis n'importe quel navigateur : arborescence, recherche, liens.

Next.js · React · GitHub API · PWA

Obsidian Web

Obsidian Web

PWA pour accéder à un vault Obsidian depuis n'importe quel appareil via GitHub

TypeScript · React · PWA · Vercel · GitHub API

obsidian-web-kikii95s-projects.vercel.app ↗GitHub ↗

Accédez à vos notes Obsidian depuis n'importe quel appareil - mobile, tablet, PC.

Contexte

Projet perso démarré en novembre 2025.

Besoin initial : accéder à mes notes Obsidian sur mobile sans payer Obsidian Sync (8$/mois). Solution : utiliser GitHub comme couche de sync gratuite et fiable.

Ce que ça fait

Édition :

  • Éditeur Markdown avec raccourcis clavier
  • Quick switcher (Ctrl+P) pour navigation rapide
  • Daily notes automatiques
  • Support complet tags et backlinks

Visualisation :

  • Vue graphe des connexions entre notes
  • Heatmap d'activité (historique commits)
  • Support média : images, PDFs, Excalidraw

Mobile & Offline :

  • Installable comme app native (PWA)
  • Fonctionne hors-ligne
  • Sync via GitHub, pas de serveur propriétaire

Liens

Architecture

100% client-side - aucun backend propriétaire. Toutes les opérations passent directement par l'API GitHub.

Browser/PWA ◄──► Next.js API ◄──► GitHub API ◄──► obsidian-vault (repo)
     │                │
     └── Service Worker (Cache + Offline)

Flux de données :

  • Lecture : Octokit → Parse frontmatter → Extract wikilinks → Rendu Markdown
  • Écriture : CodeMirror → SHA validation → GitHub commit → Sync

Stack Détaillé

TechVersionRôle
Next.js16Framework SSR + API Routes
TypeScript5.9Typage strict
NextAuth.js5.xOAuth GitHub + Sessions
Octokit4.xClient GitHub API officiel
CodeMirror6Éditeur Markdown mobile-friendly
D3.js7Graphe force-directed des connexions
Zustand5.xState management léger
PostgreSQL16Index tags/backlinks/graph
TailwindCSS4Styling utility-first

Métriques & Features

  • 36 thèmes couleurs (18 dark + 18 light) via OKLCH
  • Phases implémentées : P0 (Auth) → P7 (CRUD Notes/Folders)
  • Support offline via Service Worker + Cache API
  • Notes privées : path-based (_private/) + frontmatter + tag #private
  • Lock System : PIN SHA-256, auto-lock timer configurable
  • Media : images, PDFs, canvas (React Flow), audio, Excalidraw

Sécurité

  • Données jamais sur serveur tiers : GitHub OAuth → JWT cookie chiffré
  • Restriction accès par ALLOWED_USERS (whitelist)
  • PIN hashé SHA-256, jamais stocké en clair
Le score de la nuit, le rituel du soir, les objectifsvidéo · 0:30

Sleep Tracker

en service

Suivi du sommeil installable sur téléphone : scores, tendances, et des données de santé traitées comme telles.

Next.js · PostgreSQL · Drizzle · Passkeys

Sleep Tracker

Sleep Tracker

PWA de suivi du sommeil, mobile d'abord et installable, qui traite les nuits comme des données de santé

TypeScript · Next.js 16 · React 19 · Drizzle · PostgreSQL · next-auth · PWA · RGPD

Une app web pour noter ses nuits et comprendre son sommeil, pensée pour le téléphone et pour la confidentialité.

Contexte

Projet perso démarré le 01/07/2026, déployé sur Vercel. Usage personnel. Direction artistique « planisphère céleste » : voûte étoilée, stades du sommeil en couches du ciel, score en sextant.

Fonctionnalités

Saisie :

  • Ajout rapide d'une nuit, saisie rétroactive, siestes
  • Facteurs, tags et notes par nuit
  • Import CSV générique (avec mapping), CSV Oura, export Apple Health, sans doublon

Comprendre :

  • Tableau de bord, calendrier, fiche de nuit avec hypnogramme
  • Tendances, moyennes par jour de la semaine, insights par corrélation
  • Score composite dont chaque composante est expliquée
  • Coaching circadien non clinique et rituel du soir

Motivation :

  • Objectifs personnels avec barre de progression
  • Défis hebdomadaires, records personnels, séries, récompenses
  • Journal du soir (humeur, rêve, réflexion), couvert par le même consentement

Compte et confidentialité :

  • Connexion par mot de passe ou passkey (Face ID, Touch ID, Windows Hello)
  • Export et effacement complet des données
  • Installable, lecture hors ligne, rappel du coucher par notification

Liens

Repo privé. L'app en ligne est derrière une connexion : pas de démo publique.

Architecture

Structure plate à la racine (app/, components/, lib/, db/, core/), couches imposées par ESLint :

Route / Server Action (≤ 20 lignes) → Service → Repository → Schéma Drizzle

app/** ne peut pas importer la couche base de données (règle no-restricted-imports).

Moteur de métriques pur

Les calculs vivent dans lib/metrics/*, sans accès base, testés par vecteurs (une assertion par formule) : durée, efficacité, moyennes glissantes, dette de sommeil sur 14 jours, jetlag social, régularité, chronotype (MSFsc), score composite pondéré, séries, corrélations Pearson et Spearman.

Décisions actées (15 ADR)

  • La date d'une nuit est la date du réveil
  • Stades stockés en agrégats sur la session
  • Régularité = indicateur approché documenté, pas un SRI
  • Score composite = mélange pondéré transparent, détaillé à l'écran
  • Hors ligne : serveur qui fait autorité, dernier écrit gagne par updatedAt
  • Import par fichier uniquement, pas de synchro de montre en direct
  • Mot de passe oublié sans email : lien à usage unique dont seul le hachage est stocké

Données de santé

Les nuits sont traitées comme des données de santé (RGPD art. 9) : consentement granulaire à l'onboarding, export CSV + JSON (art. 20), suppression complète en cascade (art. 17). Le service worker ne met en cache que le statique, jamais l'API ni les données.

Portes machine

Deux points d'entrée pour d'autres apps perso, chacun derrière un jeton dont seul le hachage est stocké et une trace écrite avant toute lecture ou écriture (refus si la trace échoue) : un résumé de la dernière nuit lu par l'assistant JARVIS (consentement dédié, désactivé par défaut), et l'écriture des nuits racontées dans Memogram, qui n'écrase jamais une saisie manuelle.

Stack

TechRôle
Next.js 16 / React 19App Router, Server Actions
Drizzle + postgres-jsBase Postgres (Neon en prod)
next-auth v5 + SimpleWebAuthnMot de passe bcrypt et passkeys
Tailwind v4 + shadcn/uiInterface
recharts + composants maisonGraphiques, heatmap
Vitest + PGliteTests unitaires et d'intégration sur les vraies migrations
gitleaksScan de secrets dans la gate verify
Tirer ou attendre : le verdict chiffrévidéo · 0:27

HSR Lab

en service

Un assistant pour Honkai: Star Rail : base de connaissances, constructeur d'équipes et conseiller de tirage chiffré.

Next.js · PostgreSQL · Drizzle · Zod

HSR Lab

HSR Lab

PWA personnelle pour Honkai: Star Rail qui croise une base de connaissance du jeu avec le roster du joueur pour conseiller équipes, builds et tirages

TypeScript · Next.js 16 · Drizzle · PostgreSQL · cheerio · Zod · Vitest · PWA

Un carnet de bord perso pour Honkai: Star Rail : les données du jeu d'un côté, mes personnages de l'autre, et des moteurs qui répondent à « quelle équipe ? », « quel build ? », « je tire sur cette bannière ? ».

Contexte

Projet perso démarré le 22/07/2026. v0.1.0 et v0.2.0 (analyse d'équipe) livrées le même jour, puis direction artistique « carnet de bord du contrôleur de l'Express astral » et connexion par passkey en octobre. Les données viennent d'un site de guides public, citées comme source dans l'interface et jamais republiées : l'app est mono-utilisateur.

Fonctionnalités

Base de connaissance :

  • Fiches personnages, cônes de lumière, sets de reliques
  • Tier lists versionnées avec diff entre deux instantanés
  • Bannières courantes, annoncées et historiques

Mon compte :

  • Roster, cônes de lumière, équipes et profil de tirage éditables
  • « Mon build » sur chaque fiche personnage

Conseil :

  • Constructeur et analyse d'équipe avec score expliqué
  • Suggestions de remplacement en un clic
  • Pull Advisor : TENTE, ATTENDS ou PASSE selon le roster réel

Admin :

  • Fraîcheur et couverture des données, cron de péremption

Liens

Repo privé. App mono-utilisateur derrière une connexion : pas de démo publique.

Architecture

scripts/ingest : crawler → parsers (cheerio) → validation Zod → normalisation
                       → data/kb/*.json (committé) → chargement en base
app/ (RSC) → lib/server/services → lib/server/repositories → Postgres
                   └── lib/domain/engines : moteurs purs, sans I/O

Pipeline d'ingestion

  • Crawl poli : requêtes strictement séquentielles espacées d'au moins 1 s avec jitter, cache disque du HTML brut, robots.txt respecté, user-agent explicite.
  • Parsers testés sur des fixtures HTML committées, layouts récents et anciens.
  • Aucun champ deviné : un parser qui ne trouve pas une valeur écrit null et le rapport de couverture le signale.
  • Garde de dérive : si la couverture d'un champ chute de plus de 5 % par rapport au run précédent, l'ingestion échoue bruyamment.
  • Données versionnées : le JSON canonique est committé, donc l'historique git sert de changelog de la meta. ingest:diff montre ce qui changerait sans écrire.
  • Chargement idempotent, sauté quand le hash du fichier n'a pas changé.

Moteurs de décision

Fonctions pures dans lib/domain/engines :

  • Validateur de contraintes par mode de jeu (exclusivités, variantes non alignables)
  • Team builder avec substitutions expliquées et anti-doublon
  • Analyse d'équipe : comparaison avec un corpus de compositions de référence, score sur 10 décomposé en 4 composantes (alignement meta, tiers, rôles, adéquation au mode), suggestions de remplacement appliquables en un clic, réorientation vers les compositions réalisables les plus proches
  • Character builder : build visé contre équipement possédé, coût de farm restant
  • Pull Advisor sur 5 axes, verdict TENTE / ATTENDS / PASSE

Exploitation

Cron Vercel quotidien en lecture seule qui détecte les données périmées sans jamais écrire dans la base de connaissance. Auth mono-utilisateur (next-auth v5, bcrypt, passkeys), compte créé par lien de première connexion.

Stack

TechRôle
Next.js 16 / React 19App Router, PWA
Drizzle + postgres-jsPostgres (Neon en prod)
cheerio + tsxParsers d'ingestion
Zod v4Contrat de la base de connaissance
VitestParsers et moteurs
PlaywrightCaptures de vérification visuelle
Une dépense notée en trois gestesvidéo · 0:27

Expense Tracker

en service

Suivi des dépenses hors ligne : saisie rapide, budgets, plusieurs devises, import de relevés bancaires.

Flutter · Riverpod · Hive · Node.js

Expense Tracker

Expense Tracker

Suivi de dépenses personnel en Flutter web, hors ligne d'abord, avec synchronisation optionnelle entre appareils

Flutter · Dart · Riverpod · Hive · TypeScript · Neon Postgres · Drizzle · Vercel · Offline-first

expense-tracker-one-bay-10.vercel.app ↗

Un carnet de comptes personnel qui fonctionne sans compte ni réseau, et se synchronise entre appareils quand on le souhaite.

Contexte

Projet perso démarré en juillet 2026. L'objectif : suivre ses dépenses avec une saisie rapide, des montants toujours justes et des données qui restent dans le navigateur par défaut. La direction artistique v2, « le livre de caisse du foyer, bien tenu », est en production depuis octobre 2026.

Fonctionnalités

Saisie :

  • Saisie rapide qui commence par le montant (pavé numérique, grille de catégories avec suggestion présélectionnée), ouverte avec la touche n sur le web
  • Dépenses, revenus et virements, avec notes, tags et suppression réversible
  • Récurrences matérialisées au lancement, avec rattrapage borné

Organisation :

  • Plusieurs comptes, chacun avec sa devise et son solde d'ouverture
  • Catégories par défaut et personnalisées, avec mots-clés qui alimentent la suggestion
  • Budgets par catégorie ou par compte, avec un état explicite quand un taux de change manque
  • Multi-devises avec taux saisis à la main

Lecture :

  • Tableau de bord avec synthèses et graphiques sur une période
  • Interface en français et en anglais, thème clair ou sombre

Import :

  • Import d'un relevé CSV : encodage, séparateur, décimales et dates détectés, catégorisation hors ligne et dédoublonnage
  • Passe d'IA facultative sur les seules lignes incertaines, qui n'envoie que le libellé du marchand
  • En cours d'intégration, pas encore en service : côté propriétaire, import des opérations bancaires via son hub personnel, en simulation par défaut, et rapprochement avec les dépenses racontées dans son journal Memogram

Liens

Repo privé.

Architecture

Une seule app Flutter web, organisée par fonctionnalité : chaque dossier lib/features/<nom>/ contient trois couches.

presentation/  écrans, widgets, contrôleurs @riverpod
     │
domain/        entités freezed immuables, interfaces, services purs (aucun import Hive)
     │
data/          DTO Hive + mappers écrits à la main + dépôts

Les données vivent dans le navigateur (Hive). Un compte reste optionnel : connecté, l'app pousse et tire un delta vers des fonctions serverless Vercel en TypeScript adossées à Neon Postgres (Drizzle). Le stockage local reste la source de vérité, la synchro tourne en arrière-plan et ne bloque jamais une lecture ou une écriture.

Choix techniques

  • Montants exacts : entiers dans la plus petite unité de la devise ; le nombre de décimales est dérivé de la norme ISO-4217 (0 pour le yen, 3 pour certains dinars), jamais codé en dur à 2.
  • Solde dérivé : le solde d'un compte se calcule à partir des transactions, il n'est jamais stocké.
  • Virements multi-devises : montant débité, montant crédité et taux appliqué figé à la création.
  • Conflits : dernière écriture gagnante par ligne, curseur de révision côté serveur, suppressions synchronisées comme pierres tombales.
  • Registres figés : identifiants de types Hive et numéros de champs réservés à vie, schéma versionné avec migrations idempotentes.
  • Authentification : mots de passe hachés en argon2id, session JWT dans un cookie httpOnly.
  • État : 100 % génération de code Riverpod, sans StateNotifier ni ChangeNotifier.

Qualité

  • Lints very_good_analysis et riverpod_lint en mode strict.
  • Tests Flutter côté app, Vitest côté API avec un Postgres en mémoire (PGlite) : aucun test n'a besoin d'une vraie base.
  • CI GitHub Actions sur les deux moitiés ; 24 décisions d'architecture consignées en ADR.
Voir le site ↗
Chaque chiffre se déplie en calcul sourcévidéo · 0:32

HaltèrEgo

en développement

Un coach de musculation et de calories qui montre ses calculs au lieu de les cacher.

Next.js · PostgreSQL · Drizzle · Vitest

HaltèrEgo

HaltèrEgo

Coach perso de musculation et de calories, en PWA, qui affiche le calcul derrière chaque chiffre

TypeScript · Next.js 16 · React 19 · PWA · PostgreSQL · Drizzle · Passkeys · Offline-first

Un coach de musculation et de nutrition qui montre ses calculs au lieu de demander qu'on le croie.

Contexte

Projet perso démarré le 20/10/2026, en développement. Application privée, pensée pour un seul utilisateur. La v0.4.0 couvre les cinq premières phases du plan : fondation, direction artistique « l'instrument », moteur nutrition, séances, journal alimentaire et bilan hebdomadaire. Les trois dernières attendent leur validation en conditions réelles.

Fonctionnalités

Nutrition :

  • Cibles caloriques et macros calculées à l'onboarding, chaque chiffre avec sa formule
  • Journal alimentaire : recherche tolérante aux accents, favoris, aliments perso, « comme hier »
  • Pesée du matin et kcal restantes de la journée

Séances :

  • Programmes prêts, carnet au pouce avec minuteur de repos et écran maintenu allumé
  • Progression proposée et calcul déplié, historique et records
  • Fonctionne sans réseau à la salle

Boucle hebdomadaire :

  • Bilan du dimanche : courbe de tendance, dépense mesurée, nouvelle cible expliquée en clair
  • Détection de plateau et semaine allégée

Liens

Repo privé. Application personnelle à accès restreint, pas de démo publique.

Principe

Moteur 100 % déterministe : aucune IA, chaque cible et chaque recommandation sort d'une formule publiée, affichée dépliée à l'écran. Les moteurs sont des modules purs, sans base de données, testés par vecteurs, avec leurs sources citées dans le code.

Écrans (séance, repas, bilan) ─► Services ─► Repositories ─► PostgreSQL
                                   │
                                   ├─► lib/nutrition (cibles, tendance, dépense, bilan)
                                   └─► lib/training  (programmes, progression, e1RM, plateau)

Moteur nutrition

  • Métabolisme de base : Mifflin-St Jeor, Katch-McArdle, Cunningham
  • Tendance du poids : moyenne mobile exponentielle (α = 0,1), jours manquants interpolés
  • Dépense mesurée : apports notés moins variation des réserves (7 700 kcal/kg), droite des moindres carrés sur 2 à 8 semaines ; sans assez de données, l'app refuse de mesurer et dit pourquoi
  • Bilan du dimanche : nouvelle cible, écart plafonné à ±200 kcal par bilan
  • Simulateur de 8 semaines de vie fictive bruitée : dépense retrouvée à ±50 kcal (médiane 21 kcal sur 200 tirages)

Moteur entraînement

  • 44 exercices en français, 3 programmes (full body 3 j, haut/bas 4 j, PPL 6 j)
  • Double progression, e1RM d'Epley, records
  • Plateau détecté après 3 séances sans gain → séance allégée ; semaine allégée sur signal

Hors ligne

Le carnet de séance fonctionne en mode avion : chaque geste part dans une file locale rejouée dans l'ordre, sans doublon (identifiants générés par le téléphone). Le service worker ne met en cache que le statique, jamais de donnée de santé.

Données et conformité

  • Compte unique créé par lien de première connexion, passkeys (WebAuthn), pas d'inscription publique
  • Base hébergée dans l'UE ; export et effacement RGPD couvrant chaque table
  • Aliments : table CIQUAL embarquée + Open Food Facts appelé côté serveur avec cache de 7 jours ; valeurs figées à la saisie
  • Migrations additives appliquées par le build de prod ; une migration destructive fait échouer tests et build

Stack

TechRôle
Next.js 16 / React 19App Router, PWA mobile-first
TypeScriptMode strict
Tailwind 4 + shadcn/uiInterface
Drizzle + PostgreSQLDonnées
next-auth v5 + SimpleWebAuthnConnexion + passkeys
Vitest + PGliteTests unitaires et d'intégration
Du scrutin à l'élu, chaque chiffre sourcévidéo · 0:28

Politica France

en service

La vie politique française en données sourcées : élus, mandats, scrutins, carte des circonscriptions.

Next.js · PostgreSQL · MapLibre · D3

Politica France

Politica France

Plateforme publique de cartographie de la vie politique française où chaque donnée renvoie à sa source officielle

TypeScript · Next.js 16 · PostgreSQL · Drizzle · MapLibre · D3.js · Open Data · Vitest

politica-france.vercel.app ↗

Qui siège où, qui a voté quoi : la vie politique française, sourcée ligne par ligne.

Contexte

Projet perso démarré en juin 2026 et mis en ligne publiquement. Les phases 0 à 6 et sept approfondissements sont livrés. Le projet est en pause, en attente des retours des premiers testeurs.

Fonctionnalités

Acteurs et organisations :

  • Députés, sénateurs, gouvernement et eurodéputés français, avec recherche à chaque frappe
  • Fiches avec mandats et taux de présence
  • Partis et groupes : description, résumé neutre, lien vers le programme officiel, placement gauche-droite

Votes et textes :

  • Scrutins avec résultat Pour / Contre / Abstention, votes individuels repliés
  • Amendements : cycle de vie du dépôt au sort, dispositif et exposé des motifs, recherche par auteur, groupe ou dossier

Territoire et relations :

  • Carte des circonscriptions et résultats des législatives 2024
  • Graphe des relations entre acteurs

Transparence :

  • Page méthodologie et sources, export CSV avec provenance, demande de correction
  • Thème clair ou sombre, automatique ou manuel

Liens

Principe

Axe fixé dès le départ : véracité > exhaustivité > fraîcheur, et zéro invention de donnée. Toute valeur affichée vient d'un snapshot brut conservé avec sa provenance ; la base entière est re-dérivable depuis ces snapshots.

Sources officielles ─► Connecteurs ─► Snapshot brut + provenance (content_hash)
                                            │
                                            ▼
                       Identités + faits versionnés bitemporels ─► Services ─► Pages

Modèle de données

  • Identité + satellites de faits versionnés de façon bitemporelle (ce qui était vrai, et quand on l'a su)
  • Chaque valeur typée FAIT_SOURCE (repris d'une source) ou ANALYSE_DERIVEE (calcul documenté dans la méthodologie)
  • Ingestion idempotente : un job rejoué ne crée pas de doublon

Connecteurs

Assemblée nationale (députés, scrutins, amendements), Sénat, composition du gouvernement (DILA), législatives 2024 (ministère de l'Intérieur), Parlement européen, Wikidata (descriptions, placement gauche-droite) et Wikipédia (résumés de partis), ces deux derniers marqués comme sources tierces. Le connecteur d'amendements filtre l'archive par nom de fichier pour ne décompresser que le dossier ciblé.

Régime public

  • Limitation de débit, en-têtes CSP et HSTS
  • Mentions légales, page RGPD, analyse d'impact (DPIA), demande de correction par entité
  • Robots et sitemap selon le régime (privé ou public)

Qualité

  • Couches route (≤ 20 lignes) → service → repository ; la base n'est importée que dans les repositories
  • Tests sans réseau (un signal de santé réseau réel tourne à part, non bloquant)
  • Effectifs figés vérifiés (577 députés, 348 sénateurs), scan de secrets avant commit
  • Décisions tracées en ADR ; palette claire et sombre vérifiée au contraste AA

Stack

TechRôle
Next.js 16 / React 19App Router, rendu serveur
TypeScript + zodTypage strict, validation
PostgreSQL + DrizzleDonnées bitemporelles, migrations linéaires
MapLibreCarte choroplèthe des circonscriptions
d3-forceGraphe des relations
Tailwind 4Interface
Vitest + PGliteTests
Voir le site ↗

Jeux & cartes

Choisir une partie, retourner les cartesvidéo · 0:38

HUMAN

en bêta

Un jeu de cartes d'introspection en application mobile et web, en bêta fermée auprès de testeurs invités.

React Native · Expo · TypeScript

Human

Human

Jeu de cartes introspectif iOS/Android : 11 thèmes, 115 questions miroir entre vulnérabilité et gratitude

React Native · Expo · TypeScript · Reanimated · Mobile · iOS · Android

Application mobile introspective pour rapprocher des gens autour de questions qui comptent. Pas de gagnant, pas de score : juste l'écoute.

Contexte

Idée et premier prototype en août 2024. Projet relancé en 2026, sortie prévue fin 2026. Conçu, designé et développé en solo. Propriété intellectuelle personnelle.

Ce que ça fait

11 thèmes - Chaque partie creuse un sujet (relation à soi, aux autres, au temps qui passe, à la peur…). 5 paires de questions par thème.

Mécanique miroir - Pour chaque sujet, deux questions complémentaires : une qui pousse à parler de ce qui fait mal, une qui pousse à reconnaître ce qui aide. Tu choisis quelle face retourner.

Variante "Vers les autres" - Au lieu de répondre soi-même, on devine ce que l'autre dirait.

Catalogue filtrable - Toutes les questions consultables hors partie, par thème.

Distribution

Bêta web publique en cours - testable sans inscription. Build EAS iOS et Android prévu pour fin mai 2026. Repo privé.

Liens

  • Bêta fermée, sur invitation.

Concept

Jeu de cartes pour 1+ joueurs, sans compétition, conçu pour renforcer l'écoute et le respect (jouable seul ou à plusieurs). Chaque partie thématique propose 5 paires de questions miroir : une face sombre (vulnérabilité, doutes) et une face lumière (gratitude, force).

Architecture

┌─────────────────────────────────────────┐
│              App (Expo)                 │
├─────────────┬───────────────────────────┤
│  Navigation │  React Navigation v7      │
│  Theme      │  Tokens centralisés       │
│  Constants  │  Animation durations      │
│  Screens    │  Home / Game / Catalog    │
│  Components │  Card / Flip / Gradient   │
│  Data       │  11 thèmes × 5 paires     │
└─────────────┴───────────────────────────┘

Animation 3D

Le retournement des cartes utilise une perspective 3D custom via react-native-reanimated 4.1, sans useNativeDriver (incompatible avec les transformations 3D matricielles). Interpolations sur rotateY, gestion fine de l'opacité face avant/arrière.

Design System

TokenValeur
Noir profond#0D0D0D
Doré#D4A574
Crème#F0E6D8
HeadersPlayfair Display
BodyDM Sans

Stack

TechVersionRôle
React Native0.81Runtime mobile
ExpoSDK 54Build, OTA, linking
TypeScript5.9 (strict)Typage
Reanimated4.1Flip 3D
React Navigationv7Native stack
EASlatestBuild + Submit

Quality Shield

  • Strict mode TS, 0 any
  • 0 magic number : tous les tokens dans theme/ et constants/
  • Fichiers <300 lignes, composants <150
  • 42 fichiers TS, 1420 lignes, 0 erreur de type

Offline-first

Tout est embarqué : aucun backend, aucun appel réseau, jeu standalone. Les 115 questions sont stockées en données typées, splittées en 3 fichiers pour la lisibilité.

Une partie, du setup au premier verdictvidéo · 0:34

Drink'n'Reveal

en service

Un jeu de cartes de soirée (18+) : un deck imprimable et une application compagnon qui marche hors ligne.

Next.js · React · Tailwind · pdf-lib

Drink'n'Reveal

Drink'n'Reveal

Jeu de cartes à boire pour adultes : un deck physique prêt pour l'imprimeur et une PWA compagnon qui joue la partie

Next.js 16 · React 19 · TypeScript · PWA · SVG · pdf-lib · sharp · Vitest · Playwright

drink-n-reveal.vercel.app ↗

Un jeu de cartes à boire pour soirées entre amis, en deux formats : le deck imprimé, et une PWA qui fait tourner la partie sur un téléphone.

Contexte

Projet perso démarré en juillet 2026, pour 1 ou 2 exemplaires, sans publication. Le deck physique est la priorité ; la PWA sert de compagnon. Jeu réservé aux adultes, à consommer avec modération : une option douce remplace les gorgées par un gage ou une boisson sans alcool.

Fonctionnalités

Le jeu :

  • À chaque tour, le joueur actif pioche une carte Question et une carte Spéciale
  • Quatre types de questions : Secrète, Publique, « Qui est le plus… » (superlatif à deviner) et Action
  • En préparation, pas encore publié : un cinquième type, « Le verdict » (accusation tranchée au vote du groupe), et un thème imposé affiché pendant le chrono des superlatifs
  • 20 types de cartes spéciales pour dévier, bloquer ou renvoyer un effet
  • Le nombre de gorgées augmente à chaque manche
  • Deck ajusté au nombre de joueurs grâce à trois symboles de palier

La PWA compagnon :

  • Partie complète jouable hors ligne, installable
  • Thème sombre néon
  • Écrans repensés pour une lecture rapide : qui joue, quoi faire, quel effet

Le deck physique :

  • PDF prêts pour l'imprimeur, générés depuis les mêmes faces que l'écran
  • Guide d'impression et de découpe dans la documentation du projet

Liens

Repo privé.

Architecture

Séparation stricte, imposée par une règle ESLint no-restricted-imports :

core/        domaine pur : données des cartes + moteur de jeu
             (reducer, pile de résolution, deck, RNG, gorgées)
             aucun import React, Next ou navigateur
     │
lib/         adaptateurs : tokens design, pipeline PDF, IndexedDB, hooks
     │
components/  UI React, dont CardFace (faces de cartes en SVG)
app/         écrans : préparation, table, deck, règles, aperçu impression
scripts/     print.ts, verify-print.ts, generate-icons.mjs

Une seule face de carte pour l'écran et l'impression

Chaque face est un composant SVG-React. À l'écran, il est rendu tel quel ; pour l'impression, il est sérialisé (renderToStaticMarkup), puis rasterisé par sharp à 300 dpi. Aucun navigateur headless dans la chaîne. Les couleurs des faces sont en sRGB hexadécimal pour la rasterisation, et reprises en variables CSS côté écran.

Pipeline d'impression

  • pnpm print produit des PDF recto-verso : impositions A4 et A3, et cartes à l'unité
  • Format poker 63 × 88 mm, fond perdu de 3 mm, repères de coupe
  • pnpm print:verify contrôle dimensions, TrimBox/BleedBox et résolution

Moteur de jeu

  • État immuable et sérialisable en JSON, persisté hors ligne (localStorage + IndexedDB, aucune base de données)
  • Deck assemblé selon le nombre de joueurs, tirage reproductible par graine (mulberry32)
  • Les totaux de cartes par palier sont dérivés par le code : la spécification d'origine était incohérente, un test imprime le rapport d'écarts
  • Journal d'événements structuré avec migration de l'état en v2
  • Tests unitaires Vitest sur le moteur, parcours de bout en bout Playwright en viewport mobile ; 6 ADR
Voir le site ↗
Une grille de mots fléchés remplie, mot à motvidéo · 0:25

MotJuste

en service

Des mots fléchés en français générés à l’infini, jouables hors ligne.

Next.js · React · PostgreSQL · Passkeys

Motjuste

Motjuste

Générateur et jeu de mots fléchés français, en PWA jouable hors ligne, avec grilles synchronisées entre appareils

Next.js 16 · React 19 · TypeScript · PWA · Web Worker · IndexedDB · Drizzle · Neon Postgres · Passkeys

motjuste.vercel.app ↗

Des grilles de mots fléchés françaises à l'infini, avec de vrais mots et des définitions écrites, sur téléphone comme sur ordinateur.

Contexte

Projet perso démarré le 17 octobre 2026, pour mon usage et celui de quelques invités. La référence visée : les pages jeux de la presse, avec des forces de 1 à 4. Il est passé de la 0.1.0 à la 0.8.1, en production, entre le 17 et le 19 octobre.

Fonctionnalités

Les grilles :

  • Générées à la demande, forces 1 à 4, plusieurs formats
  • Trois niveaux de définitions par mot
  • Grille du jour, numérotée comme une édition, dont la force suit la semaine ; elle rapporte plus de points et les jours passés restent à rattraper
  • La bande indique si le mot saisi est juste ou pas encore
  • Écran « corrigé en marge » en fin de grille

La progression :

  • Dix succès et dix objets à débloquer (couleurs, papier, effet, titres)
  • Effets au mot trouvé : tampon d'encre sur le mot entier, étincelles, halo, pluie de lettres
  • Une seule page Personnaliser : thème, couleur, lettres, effet, papier, icône ; l'effet se voit aussitôt

Le compte :

  • Facultatif, avec passkeys
  • Invitation d'un ami par lien à usage unique, l'invité choisit son adresse
  • Signaler une définition en deux touchers

Liens

Repo privé.

Moteur de génération

Le moteur (lib/engine/) est pur et déterministe : aucun import de framework ni de base, il tourne en ligne de commande comme dans le navigateur. Une graine donne toujours la même grille.

mask.ts      forme de la grille
   │
slots.ts     emplacements des mots
   │
assign.ts    rattachement des définitions par couplage
             (2 définitions max par case, chaque case utilisée)
   │
fill.ts      remplissage par contraintes
             (MRV + vérification en avant + budget de nœuds)
   │
generate.ts  grille finale

Dans l'app, la génération tourne dans un Web Worker. Un banc (pnpm bench) mesure taux de réussite, temps et qualité des grilles.

Banque de définitions

  • Lexique de base : Lexique 3.83 (CC BY-SA 4.0)
  • 8 877 mots, chacun avec trois niveaux de définition : direct, classique, détourné
  • Rédigée par lots selon un guide, contrôlée à la fusion : une définition ne contient jamais le mot ni sa famille, 28 caractères au maximum
  • Le générateur ne voit que des mots définis

Appareil d'abord, serveur ensuite

  • Grilles stockées en IndexedDB, jeu entièrement jouable sans base ni compte
  • Connecté, les grilles en cours et terminées se synchronisent
  • Serveur en couches : routes API → services → dépôts → schéma Drizzle ; les pages n'importent jamais la base
  • Compte avec lien de première connexion et passkeys (next-auth v5 + SimpleWebAuthn)

Protection de la progression

  • Migrations appliquées au build, et toute migration destructive fait échouer le build
  • Versions remplacées de chaque grille gardées 60 jours côté serveur
  • Catalogue verrouillé par un registre d'empreintes : une grille publiée ne peut plus changer de mots
  • Règles de taille (fichier, composant, fonction) imposées par ESLint ; 5 ADR
Voir le site ↗

Laboratoire

Des essais et des outils mis en pause, gardés pour ce qu'ils m'ont appris.

  • TimebeatSuivi du temps de travail sur web, bureau et mobile (Next.js, Tauri, Capacitor, Supabase).
    Timebeat

    Timebeat

    Tracker de temps cross-platform (Web + Desktop Tauri + Mobile Capacitor) avec sync cloud Supabase et offline-first SQLite

    Next.js 15 · Tauri 2 · Capacitor 6 · Supabase · Prisma · Turborepo · TypeScript · Zustand

    GitHub ↗

    Tracker de temps multi-plateforme pensé pour devs et créatifs : web, desktop, mobile, avec un même compte et le même état.

    Contexte

    Projet personnel bootstrappé début mars 2026, MVP shippé le 12/03, v1.0.3 le 13/03. En pause pour préparer la phase v1.1 (système de goals).

    Pourquoi un nouveau tracker

    Les outils existants forcent une mécanique unique (Pomodoro strict, timer manuel, ou auto-tracking intrusif). Timebeat propose un timer libre OU time-boxed au choix par session, avec un dashboard visuel sobre et une vraie sync cloud via Supabase - sans devoir héberger un backend.

    Ce qui marche

    Web - Next.js SSG, auth magic-link Supabase, CRUD projet/tâche, timer, dashboard avec charts Recharts, paramètres user.

    Desktop - App Tauri v2 (~20 MB), même UI que web, intégration plus poussée prévue pour la v1.2 (raccourcis globaux, tray icon).

    Mobile - Capacitor en place, build Android validé. Phase P1.

    Liens

    • GitHub - code en public
    • Pas de démo hostée pour l'instant

    Architecture monorepo

    Turborepo + pnpm workspace, 7 packages partagés + 3 apps :

    apps/
    ├── web        (Next.js 15 SSG)
    ├── desktop    (Tauri v2 - Rust backend)
    └── mobile     (Capacitor 6 - P1)
    
    packages/
    ├── types       (modèles partagés)
    ├── constants   (clés, durées, enums)
    ├── utils       (formatters, date helpers)
    ├── db          (Prisma client)
    ├── core        (state machine timer)
    ├── ui          (composants shadcn-based)
    └── hooks       (React hooks partagés)
    

    Imports @timebeat/* via les paths du workspace pnpm. Build incrémental via Turborepo.

    Stack

    TechVersionRôle
    Next.js15App router, SSG
    React19UI
    TypeScript5.7Typage strict
    Tailwind4Styles
    Tauriv2Desktop Rust
    Capacitor6Mobile
    SupabaselatestAuth + Postgres + Realtime
    Prisma6ORM type-safe
    ZustandlatestState + persist
    RechartslatestDashboard charts

    Offline-first

    Le timer doit pouvoir tourner sans réseau. Architecture :

    • State Zustand persisté localement (localStorage web, store Tauri natif desktop)
    • Sessions queued dans une outbox quand offline
    • À la reconnexion : flush vers Supabase, gestion des conflits par updatedAt
    • SQLite local sur desktop pour l'historique long

    State machine timer

    Logique pure isolée dans @timebeat/core :

    idle ──start──► running ──pause──► paused
                       │                  │
                       ├──stop──► idle ◄──┘
                       │
                       └──tick──► running (élapsed +1s)
    

    Support timer libre OU time-boxed (Pomodoro-ready). État sérialisable pour reprise après crash.

    Modèle données

    Six entités Prisma :

    EntitéRôle
    UserCompte (Supabase Auth)
    ProjectConteneur
    TaskGranularité fine
    SessionUne période chronométrée
    GoalObjectif (v1.1)
    DailyStatsAggregat snapshot

    Roadmap

    • v1.0.x ✅ - Auth magic-link, CRUD projet/tâche, timer, dashboard, settings, desktop Tauri
    • v1.1 ⏳ - Système de goals & objectives, notifications, mobile Capacitor
    • v1.2 - Équipes, partage, exports
  • WSL TerminalTerminal pour WSL2 avec onglets, panneaux, Git, Docker et SSH (Tauri, React, xterm.js).
    WSL Terminal

    WSL Terminal

    Émulateur de terminal moderne pour WSL2 avec multi-onglets et outils développeur

    Tauri · Rust · React · Terminal · WSL

    GitHub ↗

    Émulateur de terminal moderne pour WSL2, optimisé pour le développement.

    Contexte

    Projet perso démarré en décembre 2025. Développé en solo sur 2 semaines.

    Windows Terminal est correct, mais je voulais quelque chose avec une meilleure intégration développeur : panneaux Git, gestion Docker, navigation projet, UI personnalisable - sans la lourdeur d'Electron.

    Ce que ça fait

    Terminal :

    • Multi-onglets avec drag-and-drop
    • Split panes horizontal/vertical redimensionnables
    • Multi-fenêtres (détacher des onglets)
    • Restauration de session automatique

    Outils dev :

    • Panneau Git : branches, staging, commits, push/pull
    • Panneau Docker : conteneurs et images
    • Manager SSH : sauvegarde et connexion rapide
    • Switcher de projets par catégorie

    Interface :

    • 6 thèmes (Catppuccin, Dracula, Nord, One Dark, Gruvbox, Tokyo Night)
    • Font ligatures (Fira Code, JetBrains Mono)
    • Palette de commandes Ctrl+Shift+P
    • Mode Quake (dropdown)

    Liens

    • GitHub
    • Installeurs dans les Releases

    Architecture

    Application Tauri avec backend Rust et frontend React :

    ┌─────────────────────────────────────┐
    │           React Frontend            │
    │  (xterm.js + Zustand + TailwindCSS) │
    └──────────────┬──────────────────────┘
                   │ IPC (Tauri)
    ┌──────────────┴──────────────────────┐
    │           Rust Backend              │
    │    (Shell spawn + Process mgmt)     │
    └─────────────────────────────────────┘
    

    Stack Détaillé

    TechVersionRôle
    Tauri2.0Desktop framework léger
    Rust1.77+Backend process management
    React19UI framework
    TypeScript5Typage strict
    xterm.js5Émulation terminal
    TailwindCSS4Styling
    Zustand5State management

    Métriques

    • Installeur : ~15MB (vs ~150MB Electron)
    • RAM : 80-120MB en usage
    • Shells supportés : WSL (toutes distros), PowerShell, CMD

    Intégrations

    • Détection auto des distributions WSL installées
    • Switcher de projets intégré à ~/projects/
    • File watcher pour hot reload config
  • Process TrackerLancer et surveiller ses services de développement locaux depuis une app de bureau (Tauri, React).
    Process Tracker

    Process Tracker

    Application desktop pour gérer les services de développement local

    Tauri · Rust · React · DevTools · Cross-platform

    GitHub ↗

    Application desktop pour gérer les services de développement local. Fini les processus dupliqués, conflits de ports et incertitudes.

    Contexte

    Projet perso démarré en décembre 2025.

    Problème résolu : quand on développe avec plusieurs services (backend, frontend, database), on se retrouve souvent avec des processus dupliqués, des conflits de ports, et aucune visibilité sur ce qui tourne.

    Ce que ça fait

    Gestion services :

    • Start/Stop/Restart en un clic
    • Dashboard de statut global
    • Health checks HTTP automatiques
    • Gestion des dépendances entre services
    • Historique des exécutions

    Avancé :

    • Détection de processus externes
    • Groupes de services pour batch operations
    • Support WSL depuis Windows
    • Redémarrage auto des services crashés

    Liens

    • GitHub
    • Installeurs dans les Releases (.exe, .AppImage, .deb)

    Architecture

    Application Tauri avec gestion de processus côté Rust :

    ┌─────────────────────────────────────┐
    │           React Dashboard           │
    │   (Service cards + Status monitor)  │
    └──────────────┬──────────────────────┘
                   │ IPC
    ┌──────────────┴──────────────────────┐
    │           Rust Process Manager      │
    │  (spawn, health check, restart)     │
    └─────────────────────────────────────┘
    

    Stack Détaillé

    TechVersionRôle
    Tauri2.0Desktop framework
    Rust1.77+Process management
    React18UI dashboard
    TypeScript5Frontend typage
    TailwindCSS3Styling
    Vite5Build tooling

    Configuration

    // .ptrc (commit dans Git)
    {
      "services": [
        { "name": "api", "command": "pnpm dev", "port": 3000 },
        { "name": "db", "command": "docker start postgres" }
      ]
    }
    
    • .ptrc : définition services (versionné)
    • .pt-registry.json : état runtime (gitignored)
    • Support variables d'environnement
    • Timeouts health check configurables

    Features Avancées

    • Détection processus externes
    • Groupes de services (batch operations)
    • Support WSL depuis Windows
    • Redémarrage automatique si crash
  • System MonitorMoniteur système léger dans le terminal : CPU, RAM, GPU, réseau (Rust).
    System Monitor

    System Monitor

    Moniteur système TUI ultra-léger en Rust avec thèmes et support GPU

    Rust · TUI · CLI · Performance · Cross-platform

    GitHub ↗

    Moniteur de performances système en terminal. Inspiré de htop/btop/nvtop mais beaucoup plus léger.

    Contexte

    Projet perso démarré en novembre 2025. Développé en solo sur une semaine.

    Objectif : un moniteur système minimaliste, pilotable au clavier, qui consomme presque rien tout en restant visuellement agréable.

    Ce que ça fait

    Performance :

    • Consommation quasi-nulle : 0.0% CPU, ~4MB RAM
    • Binaire unique de 1.7MB
    • Démarrage instantané (<100ms)

    Monitoring :

    • CPU, RAM, Swap en temps réel
    • GPU NVIDIA : usage, VRAM, température, power draw
    • Sparklines 60 secondes pour toutes les métriques
    • Top 5 processus par consommation

    Interface :

    • 9 thèmes visuels (Matrix, Dracula, Nord, Tokyo Night, Gruvbox, etc.)
    • Navigation clavier complète
    • Config persistante en un keypress

    Liens

    • GitHub
    • Binaires pré-compilés dans les Releases (Linux, macOS Intel/ARM, Windows)

    Architecture

    Design en couches séparant collecte, historique et rendu :

    /proc/* + sysinfo + nvml
             │
             ▼
    ┌─────────────────┐
    │   Collectors    │  ← CPU, Memory, GPU, Network, Disk, Process
    └────────┬────────┘
             │
             ▼
    ┌─────────────────┐
    │ MetricsHistory  │  ← RingBuffer<60> pour sparklines
    └────────┬────────┘
             │
             ▼
    ┌─────────────────┐
    │    Widgets      │  ← ratatui::Widget pour chaque métrique
    └────────┬────────┘
             │
             ▼
    ┌─────────────────┐
    │ ratatui::Frame  │  ← Diff rendering, terminal output
    └─────────────────┘
    

    Stack Détaillé

    TechVersionRôle
    Rust1.75+Langage système zero-cost
    Ratatui0.26TUI framework (successeur tui-rs)
    sysinfo0.30Métriques système cross-platform
    nvml-wrapper0.9API NVIDIA NVML (GPU)
    crossterm0.27Terminal I/O cross-platform
    clap4.xCLI parsing
    thiserror1.xError handling

    Métriques Performance

    • CPU : 0.0% utilisation en idle
    • RAM : ~4MB footprint
    • Binaire : 1.7MB (stripped, LTO enabled)
    • Startup : <100ms

    Optimisations

    • Lazy Updates : refresh uniquement si tick_elapsed
    • Diff Rendering : ratatui compare buffers, redessine que les cellules modifiées
    • Batch /proc Reads : single refresh_all() pour toutes métriques
    • SmartString : stack-allocated pour petites strings (noms process)

    Release Profile

    [profile.release]
    opt-level = 3
    lto = true
    codegen-units = 1
    panic = "abort"
    strip = true
    
  • DAW customUne station audio personnelle pour les mashups et le sound design (C++20, JUCE).
    DAW Custom

    DAW Custom

    Station de travail audio personnelle pour mashups et sound design en C++ avec JUCE

    C++ · JUCE · Audio · DSP · CMake

    GitHub ↗

    Station de travail audio personnelle pour créer des mashups et designer des sons (kicks, synthés).

    Contexte

    Projet perso démarré en novembre 2025. Développé en solo.

    Objectif : un DAW taillé pour la création de mashups et le sound design, sans le bloat des DAW commerciaux. Construire moi-même pour comprendre le traitement audio en profondeur.

    Ce que ça fait

    Mixer :

    • Multi-pistes avec timeline
    • Import/export WAV, MP3, FLAC
    • Hosting VST3

    Effets intégrés :

    • EQ paramétrique
    • Compresseur
    • Reverb
    • Delay

    Sound design :

    • Kick Designer pour musique électronique
    • Synthétiseur basique (oscillateurs, filtre, enveloppe)

    Liens

    Architecture

    Moteur audio modulaire où chaque effet est un processeur chaînable :

    Audio Input → [Effect Chain] → Mixer → Output
                      │
        ┌─────────────┼─────────────┐
        │             │             │
      EQ      Compressor      Reverb
    (Biquad)    (RMS)      (Schroeder)
    

    Stack Détaillé

    TechVersionRôle
    C++20Langage core
    JUCE7Framework audio (GPL)
    CMake3.22+Build system
    ASIO-Latence minimale temps réel
    ALSA-Backend Linux

    DSP Implémenté

    • EQ paramétrique : Filtres biquad par bande
    • Compresseur : Détection RMS, attack/release
    • Reverb : Algorithme Schroeder
    • Delay : Delay lines avec feedback

    Spécifications

    • Sample rates : 44.1kHz / 48kHz
    • Latence : minimale via ASIO
    • Licence : GPL v3 (due à JUCE)