amin.mallol

UK based, no sponsorship needed

Amin Mallol

Full-stack engineer, Rails and Next.js

I built and ran four production SaaS products for a London fund manager, mostly on my own, for five years.

Open to London on-site, hybrid, or fully remote.

in production
5 yrsin production
SaaS products
4SaaS products
commits
~4,500commits
fully remote
3 yrsfully remote

Selected work

Four products, five years

All four are real, all four carry real users, and the commit split on every one of them is on its page. Pick the lens that matches the role you are hiring for: the order and the summaries change.

Side projects

An ebook storefront, a spec gate enforced by a database trigger, and a £60 commercial failure with a written kill rule.

See all five →

How I work

Four decisions, not four adjectives

Every one of these comes with the incident that taught it. If you want to probe one in an interview, the code is still there and I can walk you through it.

  1. 01

    Fail closed, unless closing fails worse

    A default is a security decision. Picking one means knowing which way the failure hurts, and writing that down next to the code so the next person does not quietly reverse it.

    Evidence

    The investor portal returns 404 for any host not in its tenant map, after a fallback let a misconfigured alias impersonate a real fund and receive its cookies. The admin app in the same product deliberately does not, because its default host is the public marketing site.

    Cynad
  2. 02

    Put the invariant where it cannot be bypassed

    If a rule matters, it does not belong in the layer that is easiest to write it in. It belongs in the lowest layer that can still enforce it, because that is the only version of the rule that survives a refactor, a second client, or a script someone runs at midnight.

    Evidence

    devSpec's specification gate is a Postgres trigger, so no API route can route around it. Cynad's publish-once prices are enforced in the model and re-checked cross-row in the bulk import path, because the valuation code depends on the invariant rather than re-deriving it.

    devSpec · Cynad
  3. 03

    Know the bug class, not just the bug

    Fixing the reported case is half the work. The question worth asking is what category it belongs to, because that is what tells you where else the same mistake is already sitting.

    Evidence

    Rate limiting keyed on the request path meant two spellings of the same route disabled every throttle in the file, not just one. The fix resolves through the router and matches on the action. The related shape, found by asking what else leaks through an alternate path, was a password oracle in two-factor sign-in.

    Cynad
  4. 04

    Let the machine type; keep the deciding

    Generated code is cheap and confidently wrong output is cheaper still, so the leverage is not in producing more of it. It is in specifying precisely what is wanted beforehand, and in putting the rules somewhere nothing can route around afterwards.

    Evidence

    Work is specified in versioned work orders that name the API contract and what is out of scope before anything is written. devSpec enforces the same idea as a product: its gate is a Postgres trigger, so no client, no stray API call and no agent can get past an unanswered question.

    devSpec
  5. 05

    Constraints are a design input

    A 512MB budget or a 30-second request cap is not an obstacle to route around; it is information about which designs are available. Taking it seriously early is cheaper than discovering it in production.

    Evidence

    FlexiForm's job system runs as threads in one process rather than four forked ones, Selenium is lazily loaded because it costs 11MB resident, and spreadsheet exports are streamed to disk instead of buffered, where the buffer would cost three times the file size inside a web thread.

    FlexiForm

AI-augmented engineering

Where the speed comes from

I started writing software before the AI wave and I would still be doing this without it. What changed is where my hours go. I no longer spend them hunting a missing bracket, wiring up the fourth near-identical form, or reading a file top to bottom to find one thing. I spend them on the decisions that are actually expensive to get wrong: the architecture, the database schema, where an invariant has to live, what the user is really trying to do, and what we are not going to build.

The risk in working this way is obvious, and it is not speed. It is confidently wrong output arriving faster than you can check it. So the parts of my practice I have actually invested in are the ones that catch it: writing the specification before anything is generated, planting controls to detect when a model is making things up, and measuring code health with real static analysis rather than an impression. When something is genuinely subtle, I read the code and fix it myself.

None of this is a substitute for knowing the stack. It is how I avoid spending a senior engineer's day on work that does not need one.

Tech stack

What I have actually used, and where

No logo wall and no skill bars. Each entry says how long and on which product, because that is the only version of this list you can interview against.

Frontend

  • Next.js

    4 yrs

    Cynad · Weazly · FlexiForm · Sesame

    Five production App Router apps, Next 13 through 16. Host-based multi-tenant routing, locale-segmented routing, proxy-level auth gating and HTTPS upgrade.

  • React

    5 yrs

    every product

    React 18 and 19. 334 components on Cynad alone; the two largest regulated forms are ~5,000 lines each and I would not write them that way again.

  • TypeScript

    1 yr

    Ignitopedia · devSpec · this site

    Honest version: the production work at Tiger Hill is JavaScript, and that was a founding decision I inherited. New personal code is TypeScript with strict mode, including this site, which also has the CI none of those frontends have.

  • Redux Toolkit

    4 yrs

    Cynad · Weazly · FlexiForm · Sesame

    Hand-rolled thunks across 47 slices. Includes an idempotent session teardown that collapses nine simultaneous 401s into one logout, acting on 401 and never 403.

  • Tailwind CSS

    3 yrs

    Cynad · this site

    v3 alongside Sass in production; v4 with CSS custom properties here.

  • Sass

    5 yrs

    Cynad · Weazly · FlexiForm · Sesame

    Around 53,000 lines of it across the Tiger Hill frontends.

  • MUI

    4 yrs

    all four products

    v5 through v7, with Emotion SSR caching, mostly for data-dense admin surfaces.

  • Motion / Framer Motion

    3 yrs

    all four products

    v10 through v12, with reduced-motion respected.

Backend

  • Ruby on Rails

    5 yrs

    Cynad · Weazly · FlexiForm · Sesame

    Four API-only apps, Rails 7 through 8.1, on Ruby 4. 103 models, 123 controllers, 264 migrations between them, all JSON:API.

  • PostgreSQL

    5 yrs

    every product

    DISTINCT ON for append-only answer history, plpgsql triggers enforcing product rules, atomic UPDATE ... RETURNING as a job guard, and Solid Queue running on Postgres rather than Redis.

  • Authentication

    5 yrs

    all four products

    Devise with JWT denylist revocation, TOTP two-factor with encrypted secrets, account lockout, and a two-step sign-in designed not to leak a password oracle.

  • Authorization

    4 yrs

    Cynad · Weazly · FlexiForm

    76 Pundit policies, fail-closed: every action must declare one or the request fails. Includes a four-level tenancy graph walk and tenant-aware policy context.

  • Background jobs

    2 yrs

    Weazly · FlexiForm

    Sidekiq with Redis on one, Solid Queue on Postgres on the other, including concurrency limits, recurring schedules and a stale-run reconciler.

  • Node / Next route handlers

    3 yrs

    FlexiForm · Weazly · Ignitopedia

    Stripe checkout sessions and signature-verified webhooks, PayPal create-and-capture, SEC proxying with retry and backoff.

Infrastructure & tooling

  • Heroku

    5 yrs

    all four products

    Nine apps, Postgres, S3 via add-on, custom buildpacks for headless Chrome, and real work done inside a 512MB dyno.

  • Vercel

    1 yr

    Ignitopedia · devSpec · this site

    Edge-region pinning, cron jobs, Neon Postgres, preview deployments.

  • AWS S3

    4 yrs

    Cynad · FlexiForm · Sesame

    Active Storage, with object keys built to mirror the tenancy tree so a file's path says who owns it.

  • GitHub Actions

    1 yr

    Cynad API · this site

    Brakeman with exit-on-warn, bundler-audit, RuboCop and RSpec against a Postgres service container. I added it to a repository that had gone 2,655 commits with nothing mechanical checking it.

  • Resend

    2 yrs

    all four products

    Transactional and outreach mail, domain verification, and HMAC-signed webhooks for delivery, bounce, complaint and click events.

  • Stripe

    3 yrs

    Weazly · FlexiForm · Sesame

    Embedded checkout, subscriptions, server-owned price catalogues so a client can never post an amount, signature-verified webhooks.

Testing & quality

  • RSpec

    5 yrs

    all four Rails APIs

    Around 1,100 examples on Cynad. On FlexiForm the spec suite is larger than the application code. PDF endpoints are tested against real headless Chrome rather than stubs, by policy.

  • Playwright

    2 yrs

    Cynad investor portal · this site

    68 specs in five tiers: auth setup, smoke, read-only journeys that ask the API for the value they assert, a seed fingerprint check that fails fast on drift, and mutating tests on a single worker.

  • Jest / Vitest + RTL

    3 yrs

    Cynad investor portal · this site

    40 unit suites on the portal; Vitest here, including a test that validates all site content against its schema.

  • Accessibility

    2 yrs

    Cynad investor portal · this site

    axe-core run inside the Playwright suite rather than as a one-off audit.

  • Security tooling

    1 yr

    Cynad API

    Brakeman and bundler-audit as a merge gate. Brakeman is what caught a file read taking an unvalidated parameter in the CSV import path.

AI-augmented engineering

  • Claude Code

    since 2025

    every repository above

    Daily driver since late 2025, with per-project permission allowlists, hooks and a written operating protocol that separates a hypothesis from a decision and stops after two failed attempts at the same fix.

  • Agent specification

    since 2025

    Cynad

    Versioned, superseding work orders naming the repository, stack, API contract and out-of-scope list, including a cross-repository handoff carrying a role-by-action permission matrix.

  • LLM-as-judge evaluation

    since 2026

    Cynad · due diligence

    A code-health framework fusing a pinned judge model with eslint, sonarjs, jscpd, coverage and npm audit into a weighted score, windowed over 90 days of churn and pinned to a commit so runs are comparable.

  • Verification technique

    since 2026

    research and content work

    Planted control statistics in extraction requests to detect confabulation, with every claim traced back to a primary source before it is published.

About

First engineer, and for most of it the only one

I joined Tiger Hill Advisors in December 2021 as its first and, for most of that time, only engineer. What started as one investor portal became four products: a multi-tenant fund administration platform now serving four fund managers on their own domains, an SEC filings intelligence tool with an AI research layer, a form and survey platform with a usage-metered billing engine, and a regulated bullion brokerage with KYC and vault custody.

Three years of that has been fully remote, as the only engineer, with four live tenant deployments and no customer-facing incident. When a company asks whether someone can be trusted with this much ownership unsupervised, that is the answer I have, and it is the part of the job I am proudest of.

I work in Rails and Next.js because that is what the problems needed: an API that has to be correct about other people's money, and front ends that real users sit in front of every day. I care most about where an invariant lives, because the right answer is usually further down the stack than it is comfortable to put it.

Contact

Hiring, or just curious

I am open to London on-site, hybrid and fully remote roles. If you have a specific question about any of the work above, ask it directly: the code is still in front of me and I would rather answer precisely than send a brochure.