Skip to content
06Selected work

Systems built for the real world.

Five platforms, five different sets of constraints — and the engineering decisions each one turned on.

  1. 01Consumer AI

    Mindora

    AI journaling and wellness companion

    Web · Android

    JAVA 21SPRING BOOT 3REACT 19REACT NATIVEPYTHONELASTICSEARCHRABBITMQKUBERNETES

    AI & Intelligent Systems
    Challenge
    Journaling apps capture what you write and tell you nothing about it. Understanding how your mood moved across months of entries meant reading every one of them back.
    Approach
    A product where the writing surface and the analysis are one system. Entries are scored for mood as they are written, indexed for retrieval, and returned as trends — a mood radar, positivity over time, a month at a glance — beside an assistant that answers questions about your own entries and helps rewrite, summarise and tag them. The mobile client is React Native at feature parity with the web app.
    Engineering
    Twelve deployable services — eleven Java, one Python Flask — behind a Spring Cloud Gateway with Eureka discovery and Redis-backed distributed rate limiting. The journal service publishes to an exchange the search service consumes, so Elasticsearch indexing never sits on the write path. Entries are stored as ciphertext under AES-GCM in the primary database, and the AI layer falls through Gemini to Anthropic to HuggingFace and finally to deterministic heuristics, so a provider outage degrades the feature instead of breaking it.

    Architecture & system highlights

    Services
    12 deployable — 11 Spring Boot 3 / Java 21, 1 Python Flask
    Encryption
    AES-256-GCM journal content at rest; bcrypt password hashes
    AI fallback
    4 tiers: Gemini → Anthropic → HuggingFace → deterministic heuristics
    Search
    RabbitMQ events keep Elasticsearch indexing off the write path
    Edge
    Spring Cloud Gateway, Eureka discovery, Redis-backed rate limiting
    Clients
    React 19 web and React Native mobile at feature parity
  2. 02Retail & commerce

    Aqvion POS

    Retail operations as an installable desktop application

    Windows desktop · Multi-terminal

    JAVA 21SPRING BOOT 3POSTGRESQLNEXT.JSELECTRONNSIS

    Software Engineering
    Challenge
    Small and mid-size retailers run sales, stock, suppliers, payables and online orders across separate systems or on paper. Cloud POS is worse, not better, when the shop's connection is unreliable and the till still has to take money.
    Approach
    One platform covering point of sale, inventory with batch and expiry tracking, customers and store credit, suppliers and purchasing, accounts payable, cash-register sessions, quotations, promotions, budgets and financial reporting — shipped as a single Windows installer rather than a hosted service.
    Engineering
    Electron bundles the entire stack: the Next.js front end, the Spring Boot backend, a JRE, Node and PostgreSQL, assembled by electron-builder into one NSIS installer. The main process supervises those children with wait-on readiness checks, a single-instance lock and graceful shutdown. Inventory is a ledger — current stock is a read model over an auditable movement history — and receipts print to 58mm and 80mm thermal hardware.

    Architecture & system highlights

    Packaging
    1 NSIS installer: Electron, Next.js, Spring Boot, bundled JRE, Node, PostgreSQL
    Deployment
    Whole stack runs on the shop's own machine — no hosted service
    Backend
    Modular monolith: one Spring Boot app with hard module boundaries
    Inventory
    Ledger model — stock is a read model over an auditable movement history
    Process control
    wait-on readiness checks, single-instance lock, graceful shutdown
    Receipts
    Formatted for 58 mm and 80 mm thermal paper
  3. 03Education

    School Management System

    Offline-first school administration

    Windows desktop

    ELECTRONREACTTYPESCRIPTSQLITEPRISMA

    Software Engineering
    Challenge
    Schools on unreliable connections still need admissions, fees, exams, results and attendance to work every day. A cloud product stops being a product the moment the line drops.
    Approach
    A Windows application where every core function runs against a local database with no server and no internet: admissions and student records, fee structures, slips, exam fees, fines and discounts, marks and result cards, attendance, behaviour records, certificates, and reporting — under role-based access.
    Engineering
    Electron and React over SQLite through Prisma, packaged as a single Windows installer. Report cards, fee slips and certificates are generated locally as PDFs, with Excel import and export for bulk data and built-in database backup and restore. WhatsApp messaging is isolated as an optional integration so the core never depends on it.

    Architecture & system highlights

    Server
    None — every core function runs on a local SQLite database
    Stack
    Electron, React, TypeScript, Prisma, single Windows installer
    Documents
    Report cards, fee slips and certificates generated locally as PDF
    Data
    Excel import and export; built-in backup and restore
    Access
    Role-based access control
    Integrations
    WhatsApp isolated as optional, so the core never depends on it
  4. 04Brand & digital product

    AQVION LABS

    This site — a design system, not a template

    Web

    NEXT.JS 16TYPESCRIPTTAILWIND V4CANVASFRAMER MOTION

    Digital Products
    Challenge
    A technology company's own site is the first proof of how it builds. A template would have said the opposite of everything the copy claims.
    Approach
    A design system before a page: colour sampled directly from the brand mark so interface and logo share one colour space, a fluid type scale, one easing family, and layout primitives everything else composes from. The hero's Intelligence Field is a canvas systems diagram — data paths converging on the emblem — rather than a stock particle effect.
    Engineering
    The field runs at roughly 0.2ms a frame: static structure is painted once to its own canvas, and only the pulse trails are redrawn, into dirty rectangles rather than a full clear. Everything animated is transform or opacity. The hero copy is server-rendered at full opacity and the entrance is opt-in behind an attribute set before first paint, so no content ever waits on JavaScript to become visible.

    Architecture & system highlights

    Hero canvas
    ~0.2 ms per frame: static layer painted once, dirty-rectangle redraws
    Motion
    Transform and opacity only; reduced-motion respected
    Rendering
    Server-rendered, statically generated; no content waits on JavaScript
    Stack
    Next.js 16, TypeScript, Tailwind CSS v4
  5. 05Autonomous AI

    LEO

    Hands-free autonomous AI, running on your own machine

    Web · Self-hosted

    TYPESCRIPTREACTNODE 22FASTER WHISPEROLLAMAWEB AUDIO APIPOSTGRESDOCKER

    AI & Intelligent Systems
    Challenge
    A wake word means an always-open microphone. Every assistant that offers one answers the question the same way — stream the audio to a provider and let them decide what was said — which is the arrangement a self-hosted system exists to avoid.
    Approach
    A voice and command layer built onto a self-hosted orchestration core. The microphone stays open in the browser but audio does not leave it continuously: an energy detector finds speech bursts and sends only those to a gateway on the same machine, which transcribes them locally and speaks replies back through a cloned voice. Push-to-talk remains the default and the wake word is opt-in, so the always-listening mode is a choice rather than the price of using it.
    Engineering
    Bursts are detected by RMS over 2,048-sample frames with 450 ms of trailing silence and three frames of pre-roll, resampled to 16 kHz and encoded as PCM16 LE before leaving the page, so a silent room sends nothing at all. Faster Whisper is loaded with local_files_only, which means a voice session can never quietly trigger a model download, and replies are generated by a local Ollama model rather than a hosted one. The text-to-speech key is read on the gateway and is never logged, returned, or included in an error message.

    Architecture & system highlights

    Wake word
    RMS burst detection: 2,048-sample frames, 450 ms end silence, 3 pre-roll frames
    Burst limit
    Speech leaves the browser in segments of 250–2,500 ms, as 16 kHz PCM16 LE
    Recognition
    Faster Whisper on the gateway with local_files_only — no session-time model download
    Replies
    Local Ollama qwen3:4b-instruct; no hosted model in the default path
    Speech out
    Cloned voice streamed as pcm_24000, 16-bit signed mono
    Secrets
    TTS key read on the gateway; never logged, returned, or in an error message