Robin Malaval

Full-stack engineer. I build software end to end, then I run it. Five products, one pair of hands, from the first commit to the server bill. I made this site because a CV can't show how things hold under load.

Next.js, Node, PostgreSQL, Stripe

See the work
git log

Commit history of Dewex, Dewex OS, Swiss Local Adventures, riview.me: 4,171 commits from 22 Feb 2025 to 6 Oct 2026.

    Selected work, four products

    Booking SaaS, in production since July 2026

    Dewex

    A booking website for every outdoor activity operator: their brand, their calendar, their Stripe account. One Next.js app runs all of them.

    • 2,390commits in 93 days
    • 8,547tests, Postgres in CI
    • 100SQL migrations

    dewex.io, 1 of 4

    Sell on your own website.

    The front door. An operator signs in at app.dewex.io with Google or a magic link, gets a site from the Default template, adds activities by hand, from a description or from a URL, and connects a Stripe account. The site is live at {slug}.dewex.io or on a custom domain with HTTPS issued on demand.

    Dewex in 46 seconds: build the site, sell, run the day

    Studio, 2 of 4

    A website builder, no code.

    Every tenant site is a validated JSON document rendered by 75 section components in 18 families; the LLM never writes HTML. Studio edits it section by section with a desktop and a phone preview. Saves are versioned, a conflict is a recoverable state, and the translation worker's writes are rebased silently because it is the only other writer. Content is translated asynchronously into 20 other locales, never on the request path.

    • 75section components
    • 18section families
    • 21site locales

    Client site, 3 of 4

    Their site, native booking.

    The site Studio builds, with the booking engine inside it: a calendar of open departures, a seat hold, the Stripe payment element. hold_seats is one guarded UPDATE on the departure row; the second traveler on the last seat waits on the row lock, re-evaluates and gets a clean sold_out. The payment is a direct charge on the operator's Stripe account, the commission snapshotted in integer cents when the intent is created.

    • 2→1concurrent holds, last seat
    • 15 minhold TTL, swept every 60 s
    • 6%Starter fee, none from Pro

    Back office, 4 of 4

    One place to run the business.

    Departures calendar with capacity per slot, bookings, customers, payment status driven by Stripe webhooks: events claimed by id with a takeover window, status transitions compare-and-swap. Bilingual, phone-first, every query scoped by tenant, row level security on all 48 tables with zero browser-facing policies. Deployed on one VPS behind a health-gated deploy that fails loudly; rollback adds one commit.

    • 48tables, all under RLS
    • 16Stripe event types handled
    • 1commit to roll back

    Internal platform, 2026

    Dewex OS

    The machine that runs the company: lead analysis, human QA, AI demo factory, outreach, finance. 13 BullMQ queues, 9 supervised LLM agents.

    • 3,438tests green
    • 49migrations, each tested
    • $4.38busiest LLM day

    Workspace, 1 of 3

    Thirteen desks, nine heads.

    One worker process runs every queue; each LLM agent is a row in a registry, not a process. Concurrency per queue is measured, not guessed. A graceful SIGTERM handler and a stall budget mean a deploy no longer kills a job mid-flight.

    • 13BullMQ queues
    • 9LLM agents in the registry
    Prospecting workspace, screen to come

    Demo factory & QA, 2 of 3

    Nothing ships unreviewed.

    A demo site is never ready without an agent verdict or a human one at the same content hash. The prompt forbids inventing any fact the scraped page does not contain. The writer and its reviewer run on different models, because the same model on both sides is one opinion.

    Money & ops, 3 of 3

    A circuit breaker, shipped in shadow mode.

    Two fuses on every paid call: a per-lead loop detector and a daily cap, calibrated on measured days and watched for two days before enforcement. Every deploy validates the environment and diffs each database insert against the live schema before building, then restarts only the processes whose files changed.

    • 150calls per lead per day, fuse 1
    • $100daily cap, fuse 2

    Client platform, live since 2025

    Swiss Local Adventures

    Four-language booking site for a Swiss tour operator, with GetYourGuide's Supplier API implemented both ways.

    • 4locales
    • 6OTA endpoints
    • 209commits, solo

    The site, 1 of 3

    Sell direct, stay on the OTA.

    The operator used to sell only through GetYourGuide. Now the same tours sell on their own site in four languages, and still on the OTA, from one inventory.

    Swiss Local Adventures home page: "Explore Switzerland beyond the postcard" over a mountain lake, a Book Now button top right
    swisslocaladventures.ch: the operator's own site, in four languages

    The booking, 2 of 3

    One availability, two storefronts.

    Calendar, time slot, participants, checkout. Availability is computed the same way for the website and for GetYourGuide: capacity minus confirmed bookings minus unexpired holds, bucketed in maps so a month view is one query, not one per day.

    The OTA link, 3 of 3

    Built against their self-test tool.

    GetYourGuide calls six endpoints on the site: availabilities, pricing categories, a 60-minute reserve, an idempotent book, cancel booking, cancel reservation. After every change on either side the site pushes fresh availability back. Four product configurations, one code path, and the fixes it took to pass their self-test tool are in the commit history.

    • 60 minreservation hold
    • 90 daysavailability pushed ahead

    Restaurant review SaaS, live since 2025

    riview.me

    Turns a QR scan at a restaurant table into a Google review or private feedback, gated by a sign-in and a reward wheel.

    • 3Stripe plans
    • 10poster templates
    • 80commits, solo

    The landing, 1 of 3

    Three plans, one seven-day trial.

    Freemium, Starter, Pro, monthly or annual, with a card only when needed. Landing, pricing and the Stripe checkout all live in the same Next.js app.

    riview.me in 57 seconds: scan, rate, spin, and the dashboard behind it

    The funnel, 2 of 3

    Scan, rate, spin.

    A customer scans, signs in with Google or a magic link, rates the visit. At or above the threshold the venue set, the review goes to Google; below it, it stays private with a comment. Either way the venue gets a contact and the customer spins for a reward, redeemable once at the counter.

    The venue, 3 of 3

    Quotas recomputed on every scan.

    No mutable counter that drifts from Stripe: on every scan the site counts the reviews since the current billing period start. Annual plans get a monthly anniversary computed on the fly.

    Side projects

    2 more, outside the products

    • 2026, volunteer

      Algoritmi

      The "call staff" flow of a guest portal for hostels with no front desk in Takayama, on WebRTC and server-sent events.

      • WebRTC
      • SSE
      • 3 languages
      algoritmigroup.com
    • 2023 to 2024, prototype

      Drinxlab

      A cocktail machine: printed housing, eight pumps, an ESP32 in C++ and an app mapping pumps to recipes.

      • ESP32
      • C++
      • Station F