Skip to content
Aidan Alsaadoun

Things I've built, and why they were hard.

Each project as a short case study: what it is, why it was technically interesting, what I built and what it's made of. Language, stars and last push are live from GitHub.

market-settlement-engine

Solo build, in a fortnight.

Settlement Engine

Event ingestion and on-chain/off-chain reconciliation for a Solidity prediction market.

A parimutuel market contract on Sepolia, plus a Go service that ingests the contract’s event logs into an append-only PostgreSQL ledger and continuously reconciles on-chain state against the database, alerting on any divergence.

Why it's interesting

Built to explore the correctness problems real-money trading platforms face: idempotent event ingestion, auditable state, and detecting drift between two systems of record.

What I built

  • Parimutuel yes/no market contract (createMarket, buy, resolve, claim) with Foundry lifecycle tests, deployed and verified on Sepolia. Checks-effects-interactions on claim, multiply-before-divide payout maths, call{value:} with the success flag checked.
  • A Go indexer where backfill and live tail are the same loop: each pass closes the gap between the last checkpoint and the safe head (latest − 6 confirmations), whether that gap is fifteen thousand blocks or five.
  • Idempotent ingestion keyed on (tx_hash, log_index) with ON CONFLICT DO NOTHING; the checkpoint advances only after every insert in a range succeeds, so a crash re-processes work instead of skipping it.
  • Event sourcing
  • Idempotency
  • Checkpointing & recovery
  • At-least-once delivery
  • Reconciliation
  • Confirmation depth
  • Fault injection
  • Re-entrancy safety
How an event becomes a verified row
  1. SettlementMarket.solSepolia · source of truth

    createMarket · buy · resolve · claim. Emits an event for every state change.

  2. Go indexerpolling loop

    Reads chunked block ranges up to latest − 6. The checkpoint advances only after every insert in a range succeeds.

  3. chain_eventsPostgreSQL · append-only ledger

    Idempotent insert: ON CONFLICT (tx_hash, log_index) DO NOTHING. Replaying any range is a no-op.

  4. foldderived, disposable

    Truncates and replays the ledger in chain order, in one transaction, into markets and positions.

  5. reconcilerreconciliation_runs · audit trail

    On-chain view calls vs off-chain SQL sums. Every comparison recorded; divergence raises an alert.

The contract’s pools and the database’s sums are two accounts of the same events, so they must always agree. The reconciler is the proof that they do.

ukdevjobs

Solo build. Zero runtime dependencies, by design.

ukdevjobs-cli

Search, filter, track and apply to UK developer jobs with salary data, from the terminal.

One search fans out to five job boards in parallel, normalises every listing into an annual GBP salary range, collapses duplicates across boards, and remembers what you have seen and applied to in a local SQLite database. The same search path is exposed as a CLI and as an MCP server.

Why it's interesting

A small tool with real integration problems: five APIs with five auth schemes and inconsistent schemas, free-text salary parsing, concurrency that must not let one failing board sink a search, and a wire protocol implemented from the spec.

  • API integration
  • Data normalisation
  • Concurrency & error isolation
  • Schema design & state machines
  • Protocol implementation
  • CLI exit-code contracts
  • Offline-first testing
From the README
$ ukdevjobs search python --location London --salary-min 70k --remote

ID            TITLE                       COMPANY          LOCATION      SALARY (£/yr)   POSTED
----------------------------------------------------------------------------------------------
reed:9001     Senior Python Developer     Fintech Labs     London        £78k-£92k       2026-08-21 +
adzuna:5002   DevOps Engineer             CloudWorks       Manchester    ~£60k (est.)    2026-08-22
remotive:3001 Staff Software Engineer     Orbit Analytics  UK, Ireland   £90k-£110k      2026-08-21

3 job(s), + = first time seen, * = applied.

What I built

  • Layered architecture: board adapters are pure translators with no I/O, so each one is an ~80-line module tested against a recorded fixture. Caching, retries, parallelism and credential masking are implemented once, in the aggregator.
  • Salary normalisation that parses free text, detects the period (day rate, hourly, monthly, annual) and annualises to GBP, flagging model estimates so they can be excluded.
  • Error isolation: one thread per board. A timeout, 5xx or schema change becomes a warning on stderr, and the command only exits non-zero when every board fails.

Python · SQLite · JSON-RPC / MCP · GitHub Actions · Docusaurus

Case study GitHubPythonStars: 1updated last month
  • gym-app

    Solo build, in production at skyeapp.fit.

    Skye

    A gym companion app: log sessions, track progression, build the habit.

    A mobile-first PWA for live workout logging with autosave, reusable templates and splits, a time-boxed workout generator, history and progression stats, and a seeded library of around 75 exercises.

    Why it's interesting

    A complete product owned end-to-end: schema, auth, API, UI, deployment and cost. It runs in production for about a pound a month.

    What I built

    • Next.js 15 App Router with strict TypeScript and Tailwind v4, designed mobile-first with PWA install for a near-native feel.
    • Relational schema on Neon Postgres via Drizzle ORM and drizzle-kit migrations: exercises, workout_templates, template_exercises, sessions with snapshotted plans, and a sets_log of weight, reps, RPE and time.
    • Full-stack product ownership
    • Relational schema design
    • Authentication
    • PWA

    Next.js 15 · TypeScript · Tailwind v4 · Neon Postgres · Drizzle · better-auth · Vercel · Resend

    Case study GitHubskyeapp.fit TypeScriptStars: 1updated 2 months ago
  • aws-profile-switcher

    aws-profile-switcher

    Interactive terminal AWS profile switcher.

    A curses TUI over ~/.aws/config that previews region, output format, SSO URL, role ARN and the live account ID before switching AWS_PROFILE, then updates .zshrc with an automatic backup.

    Why it's interesting

    Small, sharp developer tooling: safe mutation of a file people care about, read-only AWS calls, and no dependencies to install.

    What I built

    • INI parsing of ~/.aws/config with default first, then alphabetical; SSO and role-assumption profiles tagged in the list.
    • Live account lookup via aws sts get-caller-identity, read-only and optional. Credentials are never read or stored.
    • Developer tooling
    • Safe file mutation
    • Least privilege

    Python 3.10+ · curses · AWS CLI · pytest

    Case study GitHubPythonStars: 1updated 5 months ago
  • skyerise

    Skyerise

    Sunrise and sunset quality forecast.

    A mobile-first web app that scores tomorrow’s sunrise or sunset from 0 to 100 using six weighted weather factors (high, mid and low cloud, humidity, visibility and EU air quality) from Open-Meteo, so you only set the alarm for the good ones.

    Why it's interesting

    A transparent scoring heuristic with documented weights, no backend and no auth: a static export that still does something useful.

    What I built

    • The scoring model in scoring.ts, with each factor’s weight and optimal condition documented so the heuristic can be tuned.
    • Open-Meteo fetchers for forecast, geocoding and air quality, aggregated into a per-event report.
    • Domain modelling
    • Third-party APIs
    • Static export
  • Clarify

    Solo hackathon project.

    Clarify

    Accessibility-first reading assistant for students with learning difficulties.

    Paste dense text and get a summary, key points, click-for-definitions, translation and read-aloud audio, built for students and learners with ADHD or autism.

    Why it's interesting

    A solo hackathon build that put accessibility first and shipped a working product on a deadline.

    What I built

    • Summaries, key-point extraction, ELI5 mode and key-term search on top of Groq-hosted Llama models.
    • Read-aloud in English and Arabic via PlayAI, with Zod validating every model response before it reaches the UI.
    • Accessibility
    • LLM integration
    • Rapid delivery