22 projects outside school

Personal projects

Everything I have built outside school: automations in production, apps I use every day, and a few games.

Automation & AI

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

DataDawn

in production

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

in production

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

in production

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

in production

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

in production

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

A memory journal kept by telling your day to a Telegram bot, by voice or text, with evening, weekly, monthly and yearly summaries

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

A journal you keep without opening an app: you tell your day as it goes to a Telegram bot, which transcribes, files and summarises it.

Context

Personal project started on 13/10/2026, at version 0.8.0 since 17/10. Deliberately kept apart from JARVIS: Memogram stays a journal and only forwards what looks like a request.

Features

Telling:

  • Notes by voice, text or captioned photo
  • Correct by replying to the note, or add to it with +
  • The day ends at 7 am; an account of another day ("my Thursday") is filed under the right day

Reading back:

  • A summary every evening, then every week, month and year
  • Commands /aujourdhui, /hier, /semaine, /mois, /cherche, /qui
  • Search by meaning, without the exact word
  • "One year ago" in the evening message
  • Reading PWA opened by a single-use link sent by the bot: day, week, month, people, search always visible

Remembering:

  • Daily memory exercise: recall a past note from memory, spaced reviews
  • Before a meeting: what the journal knows about the person

Links

Private repo. Intimate data: no public demo.

Architecture

Two halves: an always-reachable server, and a PC that does the heavy lifting when it is on.

Telegram (voice/text) ──webhook──▶ Next.js on Vercel + Postgres (Neon)
                                    ├─ immediate cloud transcription (Mistral Voxtral)
                                    ├─ summaries (Mistral): evening cron, Monday, 1st of month
                                    └─ PC work queue
                                                 ▲
PC on ── Python worker (every 15 min) ───────────┘
         ├─ re-transcribes voice notes (faster-whisper large-v3, GPU)
         ├─ writes the summaries the cloud could not (claude -p)
         ├─ archives voice notes locally
         └─ mirrors the journal into the Obsidian vault

Nothing depends on credit

Every cloud pass returns a typed result; a failure (missing key, exhausted credit, outage) moves the work to the PC queue instead of losing it. The bot says the transcription will come the next time the PC is on.

Technical choices

  • Two transcriptions: Voxtral, guided by a vocabulary of proper names, is the reference; Whisper on the PC is only used when the cloud failed, and never overwrites a manual correction.
  • No audio stored server-side: the Telegram file id is kept, the archive lives on the PC.
  • Explicit states: an entry goes pending_cloud → pending_local → done; any edit marks the summaries covering its date as stale, regenerated by the next cron.
  • A single cron (Vercel Hobby compatible) that catches up missed days, regenerates from day up to year, and sends the evening draft.
  • Memory-frugal worker: it waits for enough free RAM, volunteers as the first target when memory runs out, and retries on the next pass without loss.
  • No "logical" LLM correction of the text: in a journal, inventing is worse than misspelling.
  • Layers: short routes → services → repositories (Drizzle). Vitest tests on PGlite, no network; pytest on the worker side.

Bridges to other apps

A structured extraction spots what is expressed as an intention (task, reminder, idea) and announces it before handing it to the JARVIS assistant, with 10 minutes to cancel. Nights, job applications and expenses mentioned in a note go to the dedicated apps only when backed by a quote from the note.

Stack

TechRole
Next.js 16 / React 19Webhook, API, reading PWA
Drizzle + Postgres (Neon)Entries, summaries, work queues
Mistral (Voxtral, large, embed)Transcription, summaries, semantic search
Python + faster-whisperPC worker (GPU)
Zod, joseValidation, sessions
Vitest + PGlite, pytestNetwork-free tests
Deux agents Claude construisent un projet seulsvidéo · 0:28

MAO

paused

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 orchestrating Claude agents (Prompt, Chef, Worker) to build projects end to end through Claude Code CLI

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

A framework that gets several Claude agents to work together to build whole projects without micro-management.

Context

Personal project started on 2026-02-03. First versions (0.1 → 0.4) the same day, memory system in v0.5.0 (April 24), cross-project dashboard and run history in v0.8.0 (April 25), v1.2.0 on May 1 with memory shared across projects. The Completeness Gate was reworked in July 2026.

Claude Code alone does good work, but long tasks need constant re-prompting. MAO automates that loop: one agent clarifies the need, another plans, a third executes.

Features

Subscription instead of API - The worker goes through Claude Code CLI as a subprocess: MAO uses the subscription, not per-token API billing.

Memory system - MAO records patterns, errors and successes, then feeds them back into the prompts of later runs, including across projects.

Completeness Gate - A run only ends once the checks pass.

Overnight mode - Detached tmux, atomic checkpoint, resume after interruption.

Live web UI - Chef/Worker split view over WebSocket, cross-project dashboard, security approval queue.

Links

Private repo. Tool used locally on WSL, no hosted demo.

Concept

Three Claude agents collaborate to bootstrap a full project:

┌──────────────┐
│ PromptAgent  │  Dialogue with the user
│  (dialogue)  │  → specs, bootstrap, prompts
└──────┬───────┘
       │  mao run
       ▼
┌──────────────┐       ┌──────────────┐
│  ChefAgent   │ ────▶ │ WorkerAgent  │
│  (plans)     │ ◀──── │ (executes)   │
└──────────────┘       └──────────────┘
                        Claude Code CLI → real code on disk

Workflow: mao init → conversation → mao run → bootstrapped project.

Subscription instead of API

The main provider calls Claude Code CLI as a subprocess (claude --print --output-format=json) instead of the Anthropic API. MAO uses the Claude Code subscription; the returned JSON is used to track tokens and estimated cost per run. The direct API provider is still a stub.

Memory system

MAO records what it learns during execution, in five types: PATTERN, LEARNING, DECISION, ERROR, SUCCESS.

  • Retrieval without embeddings: weighted sum of tag match, keyword overlap, confidence and recency (exponential decay, 30-day half-life)
  • Markdown injection into system prompts, within a character budget
  • Since v1.2: a global memory pool shared across projects

Hierarchical execution

For large projects, an ArchitectAgent splits the work into subsystems before delegating to Chef/Workers. Coordination goes through an internal message bus. Specialised workers (backend, frontend, test, devops) are routed by capability tags. Effort is set per task (low → max).

Completeness Gate

A run is only marked complete after a set of registered checks pass (including a smoke test of the project's scripts). Since July 2026, rejection accounting is progress-aware, and an opt-in setting lets a run close with caveats when the gate is exhausted.

Web UI

Seven React pages (Vite + shadcn/ui components + Zustand + Tailwind 4):

  • Prompt - chat with PromptAgent + project list
  • Dashboard - cross-project view: statuses, 30-day runs, memory by type
  • Settings - Chef/Worker configuration
  • Approvals - security queue + audit log
  • Split View - live Chef ↔ Worker over WebSocket (NarratorAgent, timers, effort)
  • Stats - timeline, files and languages produced
  • Memory - entry CRUD, retrieval preview

Security module

  • Modes: autonomous (default, checks disabled) or strict (checks on, risky commands blocked or sent for approval)
  • Auto-whitelist in strict: detected dev scripts (package.json, Makefile, pyproject.toml)
  • JSONL audit log

Overnight mode

For multi-hour runs: uvicorn backend in a detached tmux session, atomic per-run checkpoint (temp + swap), resume of an interrupted run from the UI, manual pause/resume.

Stack

TechVersionRole
Python3.11+Orchestration core
Pydantic2.xTyped models and settings
Typer0.12+CLI
Loguru0.7+Structured logs
FastAPI0.109+Web UI backend
WebSockets12+Live streaming
React19Web UI
Vite7Front build
Zustand5Front state
Schéma : qui passe par la passerelle
Schéma : qui passe par la passerelle

Home Gateway

in production

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

Personal hub that alone holds the access to my accounts and serves it, under control and with a trace, to my other apps

TypeScript · Next.js 16 · PostgreSQL · Drizzle · OAuth · Encryption · Access log

The single access point of my personal ecosystem: it keeps the keys, the other apps ask.

Context

Personal project started in July 2026, first to feed my browser's "new tab" page without storing any token in it. It became the hub of my personal assistant: every new service goes through it rather than through one more connector.

Features

Centralized reads:

  • Read feeds for my notes, calendars, mail, tasks, repositories, deployments and bank balances
  • Several accounts per service, connected from a private console

Controlled actions:

  • Mail drafts and sending, file organisation, calendar writes, quick capture into my notes
  • Human approval on mobile for sensitive actions, trust rules for the rest

Governance:

  • Device tokens revocable one at a time from the console
  • Every access logged and viewable, never purged without my decision

Links

Private repo. Personal infrastructure, no public demo.

Role

A single entry point between my apps and my online accounts (mail, calendar, storage, code repositories, hosting, banks). Client apps never hold a service token: each one gets its own device token, revocable one at a time, and the hub makes the calls on their behalf.

Browser extension ────┐
Assistant routines ───┤                       ┌─► Mail / calendar / storage accounts
Personal apps ────────┼─► Hub (gatekeeper) ───┼─► Code repositories / hosting
Phone / PC ───────────┘    │                  └─► Banks (read)
                           └─► Access log (written before any access)

Access control

  • One device token per client, stored hashed, bound to a list of scopes ("doors") and rate-limited
  • One door = one line in a central registry: adding an access happens in a reviewed commit
  • Strict CORS, never open to everyone; an unconfigured door answers an explicit error
  • Multi-tenant: the tenant is derived from the token presented, never from a variable; doors backed by owner-only credentials refuse a guest token

Secrets

  • Refresh tokens encrypted (AES-256-GCM) with associated data bound to owner, provider and account, plus a key version
  • Access tokens kept in memory only, never written to the database
  • Fail-closed owner login (empty user list = nobody gets in), signed OAuth state + PKCE
  • Logs redact anything that looks like a token

Traceability and approval

  • Fail-closed access log: every sensitive read and every action is recorded (what, who, why) before it runs; if the row cannot be written, nothing happens
  • Closed list of actions: a routine can only request actions declared in code, never a free parameter
  • Human approval: a sensitive action waits for my go-ahead on mobile, expires if I do not answer, and is refused if it was altered after being sent (digest checked)
  • Trust rules: some repetitive actions can run without a button press, under an explicit rule, capped over 24 h and announced before acting; at the slightest doubt, back to the button

Stack

TechRole
Next.js 16 (App Router)Machine doors + owner console
TypeScriptStrict typing
PostgreSQL + DrizzleTokens, encrypted accounts, log, rules
NextAuthOwner login
VitestTests (encryption, redaction, gatekeeper, actions)

Route → service → repository layers, additive-only migrations, replayed idempotently at build time.

Apps

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

Nightjar

in production

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

A PWA that finds tonight's film in under a minute: free-text mood search, taste learned from what you watched, availability on your own subscriptions

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

The right film in under a minute: say what you feel like watching the way you would on the couch, Nightjar answers with a poster, its reason, and where to watch it tonight.

Context

Personal project started on 30/10/2026, live since 02/11. Born from an evening spent looking for a film longer than watching it.

Features

Choosing:

  • "Tonight": one main film and four others, tuned by mood, length, who you are with, and only on your subscriptions
  • Free-text mood, with the understood words highlighted and editable
  • "Like…": neighbours of one or more starting films
  • Trailer, rating, length and platforms on every card

Learning taste:

  • Seen, liked, loved, keep, not for me, more or less like this
  • Quick calibration on posters at first launch
  • A bank of kept films, with those just arrived on your platforms

Together:

  • A watch party shared by link, guests without an account, voting and a common ranking

Links

Private repo, personal app: no public demo.

Architecture

TMDB + IMDb ratings ──nightly sync (GitHub Actions)──▶ Postgres (Neon)
                                                        ├─ ~18,000 films, French availability per platform
                                                        └─ mood axes (rules, refined at night)
Free text ──rule-based parsing──▶ filters + deterministic score ──▶ cards with their "why"
Gestures (seen, liked, loved, kept, not for me) ──▶ taste profile as poles

Search without paid AI

A sentence like "tense locked-room, not too gory, under 1 h 45, on my subscriptions" is split by rules: duration, years, platforms, exclusions, context, quoted titles. Ranking is a deterministic score shown on every card, with the sentence that explains it. No request goes through a model: answers in under two seconds, at zero cost.

Mood, measured

Genres are too coarse ("horror" puts a slow psychological film next to a jump-scare one). Each film gets seven continuous axes (tension, jump scares, gore, humour, pace…): a first rule-based pass at every sync, then a nightly refinement by Claude on the subscription, never during a search.

Technical choices

  • Taste as poles: each loved film is a pole of its own, with its own era; an era factor avoids suggesting a 1950s film to someone who only likes recent ones.
  • Diversity: MMR selection so the five suggestions are not five copies of the same film.
  • Sync outside Vercel: the initial import is about 18,000 calls, it runs in GitHub Actions, with a rate limiter on a monotonic clock.
  • Watching together: a shared link, guests without an account who vote, a common ranking.
  • Machine bridges by token: the Memogram journal sends the films you talk about, Magpie the films spotted in saved videos; Nightjar stays the single source of truth for a film's state.
  • Layers: short Server Actions and routes → services → repositories (Drizzle). Vitest tests on PGlite, no network; ten written architecture decisions.

Stack

TechRole
Next.js 16 / React 19App, Server Actions, offline PWA
Drizzle + Postgres (Neon)Catalogue, taste, watch parties
TMDB, JustWatch, IMDbFilm data, French availability, ratings
GitHub Actions + ClaudeNightly sync and mood scoring
next-auth + passkeysFace ID sign-in
Vitest + PGliteNetwork-free tests
Navigation et recherchevidéo · 0:26

Obsidian Web

in production

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 to access an Obsidian vault from any device via GitHub

TypeScript · React · PWA · Vercel · GitHub API

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

Access your Obsidian notes from any device - mobile, tablet, desktop.

Context

Personal project started in November 2025.

Initial need: access my Obsidian notes on mobile without paying for Obsidian Sync ($8/month). Solution: use GitHub as a free and reliable sync layer.

What it does

Editing:

  • Markdown editor with keyboard shortcuts
  • Quick switcher (Ctrl+P) for fast navigation
  • Automatic daily notes
  • Full tag and backlink support

Visualization:

  • Graph view of note connections
  • Activity heatmap (commit history)
  • Media support: images, PDFs, Excalidraw

Mobile & Offline:

  • Installable as native app (PWA)
  • Works offline
  • Sync via GitHub, no proprietary server

Links

Architecture

100% client-side - no proprietary backend. All operations go directly through the GitHub API.

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

Data flow:

  • Read: Octokit → Parse frontmatter → Extract wikilinks → Markdown render
  • Write: CodeMirror → SHA validation → GitHub commit → Sync

Tech Stack

TechVersionRole
Next.js16SSR Framework + API Routes
TypeScript5.9Strict typing
NextAuth.js5.xGitHub OAuth + Sessions
Octokit4.xOfficial GitHub API client
CodeMirror6Mobile-friendly Markdown editor
D3.js7Force-directed graph visualization
Zustand5.xLightweight state management
PostgreSQL16Tags/backlinks/graph index
TailwindCSS4Utility-first styling

Metrics & Features

  • 36 color themes (18 dark + 18 light) via OKLCH
  • Implemented phases: P0 (Auth) → P7 (CRUD Notes/Folders)
  • Offline support via Service Worker + Cache API
  • Private notes: path-based (_private/) + frontmatter + #private tag
  • Lock System: SHA-256 PIN, configurable auto-lock timer
  • Media: images, PDFs, canvas (React Flow), audio, Excalidraw

Security

  • Data never passes through third-party server: GitHub OAuth → encrypted JWT cookie
  • Access restriction via ALLOWED_USERS (whitelist)
  • PIN hashed with SHA-256, never stored in plaintext
Le score de la nuit, le rituel du soir, les objectifsvidéo · 0:30

Sleep Tracker

in production

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

Mobile-first, installable sleep tracking PWA that treats nights as health data

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

A web app to log your nights and understand your sleep, designed for the phone and for privacy.

Context

Personal project started on 01/07/2026, deployed on Vercel. Personal use. "Celestial planisphere" art direction: starry vault, sleep stages as layers of the sky, score as a sextant.

Features

Logging:

  • Quick night entry, retroactive entry, naps
  • Factors, tags and notes per night
  • Generic CSV import (with mapping), Oura CSV, Apple Health export, without duplicates

Understanding:

  • Dashboard, calendar, night detail with hypnogram
  • Trends, weekday averages, correlation insights
  • Composite score with every component explained
  • Non-clinical circadian coaching and evening wind-down

Motivation:

  • Personal goals with progress bars
  • Weekly challenges, personal records, streaks, rewards
  • Evening journal (mood, dream, reflection), covered by the same consent

Account and privacy:

  • Sign-in by password or passkey (Face ID, Touch ID, Windows Hello)
  • Full data export and erasure
  • Installable, offline reading, bedtime reminder notification

Links

Private repo. The live app is behind a login: no public demo.

Architecture

Flat structure at the root (app/, components/, lib/, db/, core/), layers enforced by ESLint:

Route / Server Action (≤ 20 lines) → Service → Repository → Drizzle schema

app/** cannot import the database layer (no-restricted-imports rule).

Pure metrics engine

Calculations live in lib/metrics/*, with no database access, tested by vectors (one assertion per formula): duration, efficiency, rolling averages, 14-day sleep debt, social jetlag, regularity, chronotype (MSFsc), weighted composite score, streaks, Pearson and Spearman correlations.

Recorded decisions (15 ADRs)

  • A night's date is the wake-up date
  • Sleep stages stored as aggregates on the session
  • Regularity = a documented proxy, not an SRI
  • Composite score = a transparent weighted blend, broken down on screen
  • Offline: server is authoritative, last write wins by updatedAt
  • File import only, no live wearable sync
  • Forgotten password without email: single-use link, only its hash is stored

Health data

Nights are treated as health data (GDPR art. 9): granular consent at onboarding, CSV + JSON export (art. 20), full cascading deletion (art. 17). The service worker only caches static assets, never the API or the data.

Machine gates

Two entry points for other personal apps, each behind a token whose hash alone is stored, with a trace written before any read or write (refused if the trace fails): a last-night summary read by the JARVIS assistant (dedicated consent, off by default), and writing nights told to Memogram, which never overwrites a manual entry.

Stack

TechRole
Next.js 16 / React 19App Router, Server Actions
Drizzle + postgres-jsPostgres database (Neon in prod)
next-auth v5 + SimpleWebAuthnbcrypt password and passkeys
Tailwind v4 + shadcn/uiInterface
recharts + custom componentsCharts, heatmap
Vitest + PGliteUnit and integration tests on the real migrations
gitleaksSecret scanning in the verify gate
Tirer ou attendre : le verdict chiffrévidéo · 0:27

HSR Lab

in production

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

Personal Honkai: Star Rail PWA that crosses a game knowledge base with the player's roster to advise on teams, builds and pulls

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

A personal logbook for Honkai: Star Rail: the game data on one side, my characters on the other, and engines that answer "which team?", "which build?", "should I pull on this banner?".

Context

Personal project started on 22/07/2026. v0.1.0 and v0.2.0 (team analysis) shipped the same day, followed in October by the "Astral Express conductor's logbook" art direction and passkey sign-in. The data comes from a public guide site, credited as the source in the interface and never republished: the app is single-user.

Features

Knowledge base:

  • Character, light cone and relic set sheets
  • Versioned tier lists with a diff between two snapshots
  • Current, announced and past banners

My account:

  • Editable roster, light cones, teams and gacha profile
  • "My build" on every character sheet

Advice:

  • Team builder and team analysis with an explained score
  • One-click replacement suggestions
  • Pull Advisor: PULL, WAIT or SKIP based on the actual roster

Admin:

  • Data freshness and coverage, staleness cron

Links

Private repo. Single-user app behind a login: no public demo.

Architecture

scripts/ingest: crawler → parsers (cheerio) → Zod validation → normalisation
                      → data/kb/*.json (committed) → database load
app/ (RSC) → lib/server/services → lib/server/repositories → Postgres
                   └── lib/domain/engines: pure engines, no I/O

Ingestion pipeline

  • Polite crawl: strictly sequential requests at least 1 s apart with jitter, on-disk cache of raw HTML, robots.txt respected, explicit user agent.
  • Parsers tested against committed HTML fixtures, recent and legacy layouts.
  • No guessed fields: a parser that cannot find a value writes null, and the coverage report flags it.
  • Drift guard: if a field's coverage drops by more than 5 % versus the previous run, ingestion fails loudly.
  • Versioned data: the canonical JSON is committed, so git history doubles as the meta changelog. ingest:diff shows what would change without writing.
  • Idempotent load, skipped when the file hash has not changed.

Decision engines

Pure functions in lib/domain/engines:

  • Validator for per-game-mode constraints (exclusivity, non-stackable variants)
  • Team builder with explained substitutions and duplicate prevention
  • Team analysis: comparison with a corpus of reference compositions, a score out of 10 split into 4 components (meta alignment, tiers, roles, mode fit), one-click replacement suggestions, redirection to the closest achievable compositions
  • Character builder: target build versus owned gear, remaining farming cost
  • Pull Advisor over 5 axes, verdict PULL / WAIT / SKIP

Operations

Daily read-only Vercel cron that detects stale data without ever writing to the knowledge base. Single-user auth (next-auth v5, bcrypt, passkeys), account created through a first-login link.

Stack

TechRole
Next.js 16 / React 19App Router, PWA
Drizzle + postgres-jsPostgres (Neon in prod)
cheerio + tsxIngestion parsers
Zod v4Knowledge base contract
VitestParsers and engines
PlaywrightVisual check screenshots
Une dépense notée en trois gestesvidéo · 0:27

Expense Tracker

in production

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

Offline-first personal expense tracker in Flutter web, with optional sync across devices

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

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

A personal cash book that works with no account and no network, and syncs across devices when you want it to.

Context

Personal project started in July 2026. The goal: track expenses with fast entry, amounts that are always exact, and data that stays in the browser by default. Art direction v2, "the household cash book, kept clean", has been in production since October 2026.

Features

Entry:

  • Amount-first quick entry (numeric keypad, category grid with a pre-selected suggestion), opened with the n key on the web
  • Expenses, income and transfers, with notes, tags and reversible deletion
  • Recurrences materialized on launch, with bounded catch-up

Organization:

  • Multiple accounts, each with its own currency and opening balance
  • Default and custom categories, with keywords feeding the suggestion
  • Budgets per category or per account, with an explicit state when an exchange rate is missing
  • Multi-currency with manually entered rates

Reading:

  • Dashboard with summaries and charts over a period
  • French and English interface, light or dark theme

Import:

  • Bank CSV statement import: encoding, delimiter, decimals and dates detected, offline categorization and de-duplication
  • Optional AI pass on uncertain rows only, sending nothing but the merchant label
  • Being integrated, not yet in service: on the owner side, bank operations imported through his personal hub, simulated by default, and matched with expenses told in his Memogram journal

Links

Private repo.

Architecture

A single Flutter web app, organized by feature: each lib/features/<name>/ folder holds three layers.

presentation/  screens, widgets, @riverpod controllers
     │
domain/        immutable freezed entities, interfaces, pure services (no Hive import)
     │
data/          Hive DTOs + hand-written mappers + repositories

Data lives in the browser (Hive). An account stays optional: signed in, the app pushes and pulls a delta to TypeScript Vercel serverless functions backed by Neon Postgres (Drizzle). The local store remains the source of truth; sync runs in the background and never blocks a read or a write.

Technical choices

  • Exact amounts: integers in the currency's smallest unit; the number of decimals is derived from ISO-4217 (0 for the yen, 3 for some dinars), never hardcoded to 2.
  • Derived balance: an account's balance is computed from its transactions, never stored.
  • Cross-currency transfers: debited amount, credited amount and the applied rate frozen at creation.
  • Conflicts: last-write-wins per row, server revision cursor, deletions synced as tombstones.
  • Frozen registries: Hive type ids and field numbers reserved for life, versioned schema with idempotent migrations.
  • Authentication: argon2id password hashing, JWT session in an httpOnly cookie.
  • State: 100% Riverpod code generation, no StateNotifier or ChangeNotifier.

Quality

  • Strict very_good_analysis and riverpod_lint lints.
  • Flutter tests on the app side, Vitest on the API side with an in-memory Postgres (PGlite): no test needs a real database.
  • GitHub Actions CI on both halves; 24 architecture decisions recorded as ADRs.
Visit the site ↗
Chaque chiffre se déplie en calcul sourcévidéo · 0:32

HaltèrEgo

in development

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

Personal strength-training and calorie coach, as a PWA, that shows the calculation behind every number

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

A strength-training and nutrition coach that shows its calculations instead of asking to be trusted.

Context

Personal project started on 20/10/2026, in development. A private app, designed for a single user. Version 0.4.0 covers the first five phases of the plan: foundation, "the instrument" art direction, nutrition engine, workouts, food log and weekly review. The last three are awaiting validation in real conditions.

Features

Nutrition:

  • Calorie and macro targets computed during onboarding, each number with its formula
  • Food log: accent-tolerant search, favourites, custom foods, "same as yesterday"
  • Morning weigh-in and remaining kcal for the day

Workouts:

  • Ready-made programs, thumb-friendly log with rest timer and screen kept awake
  • Suggested progression with the calculation expanded, history and records
  • Works without a network at the gym

Weekly loop:

  • Sunday review: trend curve, measured expenditure, new target explained in plain words
  • Plateau detection and deload week

Links

Private repo. Personal app with restricted access, no public demo.

Principle

A 100% deterministic engine: no AI, every target and every recommendation comes from a published formula, shown expanded on screen. The engines are pure modules, with no database, tested against vectors, with their sources cited in the code.

Screens (workout, meals, review) ─► Services ─► Repositories ─► PostgreSQL
                                      │
                                      ├─► lib/nutrition (targets, trend, expenditure, review)
                                      └─► lib/training  (programs, progression, e1RM, plateau)

Nutrition engine

  • Basal metabolism: Mifflin-St Jeor, Katch-McArdle, Cunningham
  • Weight trend: exponential moving average (α = 0.1), missing days interpolated
  • Measured expenditure: logged intake minus change in stores (7,700 kcal/kg), least-squares line over 2 to 8 weeks; without enough data the app refuses to measure and says why
  • Sunday review: new target, change capped at ±200 kcal per review
  • Simulator of 8 weeks of noisy fictional life: expenditure recovered within ±50 kcal (median 21 kcal over 200 draws)

Training engine

  • 44 exercises in French, 3 programs (full body 3 d, upper/lower 4 d, PPL 6 d)
  • Double progression, Epley e1RM, records
  • Plateau detected after 3 sessions without progress → lighter session; deload week on signal

Offline

The workout log works in airplane mode: every action goes into a local queue replayed in order, without duplicates (IDs generated by the phone). The service worker caches static assets only, never health data.

Data and compliance

  • Single account created through a first-login link, passkeys (WebAuthn), no public sign-up
  • Database hosted in the EU; GDPR export and erasure covering every table
  • Foods: embedded CIQUAL table + Open Food Facts called server-side with a 7-day cache; values frozen at entry time
  • Additive migrations applied by the production build; a destructive migration fails both tests and build

Stack

TechRole
Next.js 16 / React 19App Router, mobile-first PWA
TypeScriptStrict mode
Tailwind 4 + shadcn/uiInterface
Drizzle + PostgreSQLData
next-auth v5 + SimpleWebAuthnLogin + passkeys
Vitest + PGliteUnit and integration tests
Du scrutin à l'élu, chaque chiffre sourcévidéo · 0:28

Politica France

in production

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

Public platform mapping French political life, where every data point links back to its official source

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

politica-france.vercel.app ↗

Who sits where, who voted for what: French political life, sourced line by line.

Context

Personal project started in June 2026 and published online. Phases 0 to 6 and seven follow-up iterations are delivered. The project is on pause, waiting for feedback from its first testers.

Features

People and organisations:

  • French MPs, senators, government members and MEPs, with search on every keystroke
  • Profiles with mandates and attendance rate
  • Parties and groups: description, neutral summary, link to the official programme, left-right placement

Votes and bills:

  • Votes with For / Against / Abstain results, individual votes collapsed
  • Amendments: lifecycle from filing to outcome, text and explanatory statement, search by author, group or bill

Territory and relationships:

  • Constituency map and 2024 legislative election results
  • Relationship graph between political actors

Transparency:

  • Methodology and sources page, CSV export with provenance, correction requests
  • Light or dark theme, automatic or manual

Links

Principle

The priority was set from day one: accuracy > completeness > freshness, and no invented data. Every displayed value comes from a raw snapshot kept with its provenance; the whole database can be re-derived from those snapshots.

Official sources ─► Connectors ─► Raw snapshot + provenance (content_hash)
                                        │
                                        ▼
                    Identities + bitemporal versioned facts ─► Services ─► Pages

Data model

  • Identity + fact satellites versioned bitemporally (what was true, and when we learned it)
  • Each value typed FAIT_SOURCE (taken from a source) or ANALYSE_DERIVEE (calculation documented in the methodology)
  • Idempotent ingestion: a replayed job creates no duplicates

Connectors

French National Assembly (MPs, votes, amendments), Senate, government composition (DILA), 2024 legislative elections (Ministry of the Interior), European Parliament, Wikidata (descriptions, left-right placement) and Wikipedia (party summaries), the last two flagged as third-party sources. The amendments connector filters the archive by file name so that only the targeted bill is unpacked.

Public mode

  • Rate limiting, CSP and HSTS headers
  • Legal notice, GDPR page, data protection impact assessment (DPIA), per-entity correction requests
  • Robots and sitemap depending on the mode (private or public)

Quality

  • Route (≤ 20 lines) → service → repository layers; the database is imported only in repositories
  • Network-free tests (a real-network health signal runs separately, non-blocking)
  • Fixed headcounts checked (577 MPs, 348 senators), secret scan before commit
  • Decisions recorded as ADRs; light and dark palettes checked for AA contrast

Stack

TechRole
Next.js 16 / React 19App Router, server rendering
TypeScript + zodStrict typing, validation
PostgreSQL + DrizzleBitemporal data, linear migrations
MapLibreChoropleth map of constituencies
d3-forceRelationship graph
Tailwind 4Interface
Vitest + PGliteTests
Visit the site ↗

Games & cards

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

HUMAN

in beta

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

Introspective iOS/Android card game: 11 themes, 115 mirror questions between vulnerability and gratitude

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

Introspective mobile app to bring people closer through questions that matter. No winner, no score - just listening.

Context

Idea and first prototype in August 2024. Project restarted in 2026, full release planned for late 2026. Designed and built solo. Personal IP.

What it does

11 themes - Each round digs into one topic (self, others, time passing, fear…). 5 question pairs per theme.

Mirror mechanic - For each subject, two complementary questions: one that pushes you to share what hurts, one that pushes you to acknowledge what helps. You choose which side to flip.

"Toward others" variant - Instead of answering for yourself, you guess what the other person would say.

Filterable catalog - All questions browsable outside a game, by theme.

Distribution

Public web beta in progress - testable without signup. EAS iOS and Android builds planned for late May 2026. Private repo.

Links

  • Closed beta, invitation only.

Concept

Card game for 1+ players, no competition, built to strengthen listening and respect (playable solo or in group). Each themed round serves 5 mirror pairs: a dark side (vulnerability, doubts) and a light side (gratitude, strength).

Architecture

┌─────────────────────────────────────────┐
│              App (Expo)                 │
├─────────────┬───────────────────────────┤
│  Navigation │  React Navigation v7      │
│  Theme      │  Centralized tokens       │
│  Constants  │  Animation durations      │
│  Screens    │  Home / Game / Catalog    │
│  Components │  Card / Flip / Gradient   │
│  Data       │  11 themes × 5 pairs      │
└─────────────┴───────────────────────────┘

3D Animation

Card flips use a custom 3D perspective via react-native-reanimated 4.1, without useNativeDriver (incompatible with matrix-based 3D transforms). Interpolation on rotateY with fine-grained front/back opacity control.

Design System

TokenValue
Deep black#0D0D0D
Gold#D4A574
Cream#F0E6D8
HeadersPlayfair Display
BodyDM Sans

Stack

TechVersionRole
React Native0.81Mobile runtime
ExpoSDK 54Build, OTA, linking
TypeScript5.9 (strict)Typing
Reanimated4.13D flip
React Navigationv7Native stack
EASlatestBuild + Submit

Quality Shield

  • Strict TS, 0 any
  • 0 magic number: every token lives in theme/ and constants/
  • Files <300 lines, components <150
  • 42 TS files, 1420 lines, 0 type errors

Offline-first

Everything ships in the bundle: no backend, no network calls, fully standalone. The 115 questions are typed data, split across 3 files for readability.

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

Drink'n'Reveal

in production

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

Adult drinking card game: a print-ready physical deck and a companion PWA that runs the game

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

drink-n-reveal.vercel.app ↗

A drinking card game for nights with friends, in two formats: the printed deck, and a PWA that runs the game on a phone.

Context

Personal project started in July 2026, for 1 or 2 copies, not published. The physical deck comes first; the PWA is a companion. Adults only, drink responsibly: a soft option swaps sips for a dare or a non-alcoholic drink.

Features

The game:

  • Each turn, the active player draws a Question card and a Special card
  • Four question types: Secret, Public, "Who is the most…" (a superlative to guess) and Action
  • In progress, not yet released: a fifth type, "The verdict" (an accusation settled by a group vote), and an assigned theme shown during the superlative timer
  • 20 kinds of special cards to deflect, block or send an effect back
  • The number of sips grows each round
  • Deck adjusted to the player count with three tier symbols

The companion PWA:

  • Full game playable offline, installable
  • Dark neon theme
  • Screens reworked for quick reading: who plays, what to do, which effect

The physical deck:

  • Printer-ready PDFs, generated from the same faces as the screen
  • Printing and cutting guide in the project docs

Links

Private repo.

Architecture

Strict separation, enforced by an ESLint no-restricted-imports rule:

core/        pure domain: card data + game engine
             (reducer, resolution stack, deck, RNG, drinks)
             no React, Next or browser import
     │
lib/         adapters: design tokens, PDF pipeline, IndexedDB, hooks
     │
components/  React UI, including CardFace (SVG card faces)
app/         screens: setup, table, deck, rules, print preview
scripts/     print.ts, verify-print.ts, generate-icons.mjs

One card face for screen and print

Each face is an SVG-React component. On screen it renders as is; for print it is serialized (renderToStaticMarkup), then rasterized by sharp at 300 dpi. No headless browser in the chain. Face colors are sRGB hex for rasterization, mirrored as CSS variables on screen.

Print pipeline

  • pnpm print outputs double-sided PDFs: A4 and A3 impositions, and single cards
  • Poker size 63 × 88 mm, 3 mm bleed, crop marks
  • pnpm print:verify checks dimensions, TrimBox/BleedBox and resolution

Game engine

  • Immutable, JSON-serializable state, persisted offline (localStorage + IndexedDB, no database)
  • Deck assembled by player count, reproducible seeded draw (mulberry32)
  • Card totals per tier are derived by code: the original spec was inconsistent, and a test prints the discrepancy report
  • Structured event log with a v2 state migration
  • Vitest unit tests on the engine, Playwright end-to-end runs in a mobile viewport; 6 ADRs
Visit the site ↗
Une grille de mots fléchés remplie, mot à motvidéo · 0:25

MotJuste

in production

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

Next.js · React · PostgreSQL · Passkeys

Motjuste

Motjuste

French arrow-word puzzle generator and game, as an offline PWA with grids synced across devices

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

motjuste.vercel.app ↗

Endless French arrow-word grids, with real words and hand-written clues, on phone as well as computer.

Context

Personal project started on October 17, 2026, for my own use and a few guests. The target: newspaper puzzle pages, with difficulty levels 1 to 4. It went from 0.1.0 to 0.8.1, in production, between October 17 and 19.

Features

The grids:

  • Generated on demand, difficulty 1 to 4, several sizes
  • Three clue levels per word
  • Daily grid, numbered like an edition, with difficulty following the week; it earns extra points and past days stay available
  • The clue strip tells whether the typed word is right or not yet
  • "Corrected in the margin" screen at the end of a grid

Progress:

  • Ten achievements and ten items to unlock (colors, paper, effect, titles)
  • Found-word effects: ink stamp on the whole word, sparks, halo, letter rain
  • A single Customize page: theme, color, letters, effect, paper, icon; the change shows at once

Account:

  • Optional, with passkeys
  • Invite a friend with a single-use link, the guest picks their own address
  • Report a clue in two taps

Links

Private repo.

Generation engine

The engine (lib/engine/) is pure and deterministic: no framework or database import, it runs from the command line as well as in the browser. A seed always yields the same grid.

mask.ts      grid shape
   │
slots.ts     word slots
   │
assign.ts    clue placement by matching
             (max 2 clues per cell, every cell used)
   │
fill.ts      constraint-based filling
             (MRV + forward checking + node budget)
   │
generate.ts  final grid

In the app, generation runs in a Web Worker. A bench (pnpm bench) measures success rate, time and grid quality.

Clue bank

  • Base lexicon: Lexique 3.83 (CC BY-SA 4.0)
  • 8,877 words, each with three clue levels: direct, classic, cryptic
  • Written in batches following a guide, checked at merge time: a clue never contains the word or its family, 28 characters max
  • The generator only sees defined words

Device first, server second

  • Grids stored in IndexedDB, the game is fully playable without a database or account
  • Signed in, grids in progress and finished sync
  • Layered server: API routes → services → repositories → Drizzle schema; pages never import the database
  • Account with a first-login link and passkeys (next-auth v5 + SimpleWebAuthn)

Progress protection

  • Migrations applied at build time, and any destructive migration fails the build
  • Replaced versions of each grid kept 60 days on the server
  • Catalogue locked by a fingerprint registry: a published grid can no longer change its words
  • Size rules (file, component, function) enforced by ESLint; 5 ADRs
Visit the site ↗

Lab

Experiments and tools on hold, kept for what they taught me.

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

    Timebeat

    Cross-platform time tracker (Web + Tauri Desktop + Capacitor Mobile) with Supabase cloud sync and offline-first SQLite

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

    GitHub ↗

    Multi-platform time tracker built for devs and creatives: web, desktop, mobile, one account, one state.

    Context

    Personal project bootstrapped early March 2026, MVP shipped 12/03, v1.0.3 on 13/03. On pause while prepping the v1.1 goals system.

    Why another tracker

    Existing tools force one mechanic (strict Pomodoro, manual timer, or intrusive auto-tracking). Timebeat offers a free timer OR time-boxed mode chosen per session, a clean visual dashboard, and real cloud sync via Supabase - without having to host a backend.

    What works

    Web - Next.js SSG, Supabase magic-link auth, project/task CRUD, timer, Recharts dashboard, user settings.

    Desktop - Tauri v2 app (~20 MB), same UI as web, deeper integration planned for v1.2 (global shortcuts, tray icon).

    Mobile - Capacitor in place, Android build validated. P1 phase.

    Links

    • GitHub - code public
    • No hosted demo yet

    Monorepo architecture

    Turborepo + pnpm workspace, 7 shared packages + 3 apps:

    apps/
    ├── web        (Next.js 15 SSG)
    ├── desktop    (Tauri v2 - Rust backend)
    └── mobile     (Capacitor 6 - P1)
    
    packages/
    ├── types       (shared models)
    ├── constants   (keys, durations, enums)
    ├── utils       (formatters, date helpers)
    ├── db          (Prisma client)
    ├── core        (timer state machine)
    ├── ui          (shadcn-based components)
    └── hooks       (shared React hooks)
    

    @timebeat/* imports via pnpm workspace paths. Incremental builds with Turborepo.

    Stack

    TechVersionRole
    Next.js15App router, SSG
    React19UI
    TypeScript5.7Strict typing
    Tailwind4Styling
    Tauriv2Desktop Rust
    Capacitor6Mobile
    SupabaselatestAuth + Postgres + Realtime
    Prisma6Type-safe ORM
    ZustandlatestState + persist
    RechartslatestDashboard charts

    Offline-first

    The timer has to keep running without network. Architecture:

    • Zustand state persisted locally (localStorage on web, native Tauri store on desktop)
    • Sessions queued in an outbox when offline
    • On reconnect: flush to Supabase, conflicts resolved by updatedAt
    • Local SQLite on desktop for long-term history

    Timer state machine

    Pure logic isolated in @timebeat/core:

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

    Supports free timer OR time-boxed (Pomodoro-ready). Serializable state for crash recovery.

    Data model

    Six Prisma entities:

    EntityRole
    UserAccount (Supabase Auth)
    ProjectContainer
    TaskFine-grained unit
    SessionOne timed period
    GoalObjective (v1.1)
    DailyStatsAggregate snapshot

    Roadmap

    • v1.0.x ✅ - Magic-link auth, project/task CRUD, timer, dashboard, settings, Tauri desktop
    • v1.1 ⏳ - Goals & objectives system, notifications, Capacitor mobile
    • v1.2 - Teams, sharing, exports
  • WSL TerminalTerminal pour WSL2 avec onglets, panneaux, Git, Docker et SSH (Tauri, React, xterm.js).
    WSL Terminal

    WSL Terminal

    Modern terminal emulator for WSL2 with multi-tabs and developer tools

    Tauri · Rust · React · Terminal · WSL

    GitHub ↗

    Modern terminal emulator for WSL2, optimized for development.

    Context

    Personal project started in December 2025. Solo development over 2 weeks.

    Windows Terminal is fine, but I wanted something with better developer integration: Git panels, Docker management, project navigation, customizable UI - without Electron's overhead.

    What it does

    Terminal:

    • Multi-tabs with drag-and-drop
    • Resizable horizontal/vertical split panes
    • Multi-window (detach tabs)
    • Automatic session restore

    Dev tools:

    • Git panel: branches, staging, commits, push/pull
    • Docker panel: containers and images
    • SSH manager: save and quick connect
    • Project switcher by category

    Interface:

    • 6 themes (Catppuccin, Dracula, Nord, One Dark, Gruvbox, Tokyo Night)
    • Font ligatures (Fira Code, JetBrains Mono)
    • Command palette Ctrl+Shift+P
    • Quake mode (dropdown)

    Links

    • GitHub
    • Installers in Releases

    Architecture

    Tauri app with Rust backend and React frontend:

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

    Tech Stack

    TechVersionRole
    Tauri2.0Lightweight desktop framework
    Rust1.77+Backend process management
    React19UI framework
    TypeScript5Strict typing
    xterm.js5Terminal emulation
    TailwindCSS4Styling
    Zustand5State management

    Metrics

    • Installer: ~15MB (vs ~150MB Electron)
    • RAM: 80-120MB in use
    • Supported shells: WSL (all distros), PowerShell, CMD

    Integrations

    • Auto-detection of installed WSL distributions
    • Project switcher integrated with ~/projects/
    • File watcher for hot reload config
  • Process TrackerLancer et surveiller ses services de développement locaux depuis une app de bureau (Tauri, React).
    Process Tracker

    Process Tracker

    Desktop app to manage local development services

    Tauri · Rust · React · DevTools · Cross-platform

    GitHub ↗

    Desktop app to manage local development services. No more duplicate processes, port conflicts and uncertainty.

    Context

    Personal project started in December 2025.

    Problem solved: when developing with multiple services (backend, frontend, database), you often end up with duplicate processes, port conflicts, and no visibility on what's running.

    What it does

    Service management:

    • One-click Start/Stop/Restart
    • Global status dashboard
    • Automatic HTTP health checks
    • Service dependency management
    • Execution history

    Advanced:

    • External process detection
    • Service groups for batch operations
    • WSL support from Windows
    • Auto-restart crashed services

    Links

    • GitHub
    • Installers in Releases (.exe, .AppImage, .deb)

    Architecture

    Tauri app with Rust-side process management:

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

    Tech Stack

    TechVersionRole
    Tauri2.0Desktop framework
    Rust1.77+Process management
    React18UI dashboard
    TypeScript5Frontend typing
    TailwindCSS3Styling
    Vite5Build tooling

    Configuration

    // .ptrc (commit to Git)
    {
      "services": [
        { "name": "api", "command": "pnpm dev", "port": 3000 },
        { "name": "db", "command": "docker start postgres" }
      ]
    }
    
    • .ptrc: service definitions (versioned)
    • .pt-registry.json: runtime state (gitignored)
    • Environment variable support
    • Configurable health check timeouts

    Advanced Features

    • External process detection
    • Service groups (batch operations)
    • WSL support from Windows
    • Auto-restart on crash
  • System MonitorMoniteur système léger dans le terminal : CPU, RAM, GPU, réseau (Rust).
    System Monitor

    System Monitor

    Ultra-lightweight TUI system monitor in Rust with themes and GPU support

    Rust · TUI · CLI · Performance · Cross-platform

    GitHub ↗

    Terminal system performance monitor. Inspired by htop/btop/nvtop but much lighter.

    Context

    Personal project started in November 2025. Solo development over one week.

    Goal: a minimalist system monitor, keyboard-driven, that consumes almost nothing while remaining visually pleasing.

    What it does

    Performance:

    • Near-zero consumption: 0.0% CPU, ~4MB RAM
    • Single 1.7MB binary
    • Instant startup (<100ms)

    Monitoring:

    • CPU, RAM, Swap in real-time
    • NVIDIA GPU: usage, VRAM, temperature, power draw
    • 60-second sparklines for all metrics
    • Top 5 processes by consumption

    Interface:

    • 9 visual themes (Matrix, Dracula, Nord, Tokyo Night, Gruvbox, etc.)
    • Full keyboard navigation
    • Persistent config saved in one keypress

    Links

    • GitHub
    • Pre-compiled binaries in Releases (Linux, macOS Intel/ARM, Windows)

    Architecture

    Layered design separating collection, history and rendering:

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

    Tech Stack

    TechVersionRole
    Rust1.75+Zero-cost systems language
    Ratatui0.26TUI framework (tui-rs successor)
    sysinfo0.30Cross-platform system metrics
    nvml-wrapper0.9NVIDIA NVML API (GPU)
    crossterm0.27Cross-platform terminal I/O
    clap4.xCLI parsing
    thiserror1.xError handling

    Performance Metrics

    • CPU: 0.0% utilization at idle
    • RAM: ~4MB footprint
    • Binary: 1.7MB (stripped, LTO enabled)
    • Startup: <100ms

    Optimizations

    • Lazy Updates: refresh only if tick_elapsed
    • Diff Rendering: ratatui compares buffers, redraws only changed cells
    • Batch /proc Reads: single refresh_all() for all metrics
    • SmartString: stack-allocated for small strings (process names)

    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

    Personal audio workstation for mashups and sound design in C++ with JUCE

    C++ · JUCE · Audio · DSP · CMake

    GitHub ↗

    Personal audio workstation for creating mashups and designing sounds (kicks, synths).

    Context

    Personal project started in November 2025. Solo development.

    Goal: a DAW tailored for mashup creation and sound design, without commercial DAW bloat. Building it myself to deeply understand audio processing.

    What it does

    Mixer:

    • Multi-track with timeline
    • WAV, MP3, FLAC import/export
    • VST3 hosting

    Built-in effects:

    • Parametric EQ
    • Compressor
    • Reverb
    • Delay

    Sound design:

    • Kick Designer for electronic music
    • Basic synthesizer (oscillators, filter, envelope)

    Links

    Architecture

    Modular audio engine with chainable effect processors:

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

    Tech Stack

    TechVersionRole
    C++20Core language
    JUCE7Audio framework (GPL)
    CMake3.22+Build system
    ASIO-Minimal real-time latency
    ALSA-Linux backend

    DSP Implementation

    • Parametric EQ: Biquad filters per band
    • Compressor: RMS detection, attack/release
    • Reverb: Schroeder algorithm
    • Delay: Delay lines with feedback

    Specifications

    • Sample rates: 44.1kHz / 48kHz
    • Latency: minimal via ASIO
    • License: GPL v3 (due to JUCE)