MIKHAIL NERI

Case study · Client build

PrepBenchmark

A finance exam prep review and rankings platform built solo on Laravel 12 and Filament v4.

Visit prepbenchmark.com

Role
Sole developer, end to end
Status
Live
Period
Jun 2026 to Aug 2026
Stack
Laravel 12, PHP 8, Filament v4, MySQL, Blade SSR, Vanilla JS, AWS SES

Summary

Problem
An affiliate business has to earn a reader's trust with useful, well organised content before asking for a click, and the WordPress prototype could not model the exam domain.
System
One Laravel application: a Filament CMS for the editorial team and a server rendered public site, with certifications, exam levels, providers and provider course levels as separate relationships.
Outcome
Live at prepbenchmark.com with scored provider reviews across CFA, FRM and CAIA, CPA in progress, filters that cannot contradict, and relevance ranked search.

What needed to exist

A review site that earns trust before it asks for a click.

PrepBenchmark reviews and ranks the prep providers that finance candidates buy before sitting the CFA, FRM and CAIA exams, with CPA coverage in progress. The business runs on affiliate revenue, and that set the whole engineering brief: the site has to earn a reader's trust with useful, well organised content long before it asks anyone to click through to a provider.

It began as a WordPress prototype. I rebuilt it as a Laravel application so the exam domain could be modelled properly instead of bent into posts and categories, and so the editorial team could work inside an admin shaped around their content.

Architecture

One Laravel application, two audiences.

An editorial team works inside Filament; readers get a fast, crawlable public site. Everything the editors touch lives in Filament: providers, scored reviews, articles, taxonomies and media, with the article editor built on Filament's Tiptap based rich editor.

Deployment is a scripted tarball over SSH to shared cPanel hosting, the honest fit for a content site at this stage rather than infrastructure that bills for headroom nobody is using yet.

Decisions

Model the domain properly, render on the server, and test before pricing.

Split the exam from the provider's course

Context
Certifications, exam levels, providers and provider course levels were modelled as one idea.
Tempting answer
Keep the shortcut and patch the filters around it.
What I did
Split the exam relationship from the provider course relationship on every article and review, with globally unique level slugs.
Why
The fix is cheap while content is thin and expensive once live filters and a real archive depend on it.

No SPA on the public site

Context
A content site whose job is ranking in search and loading fast on a candidate's phone between study sessions.
Tempting answer
A single page app framework for the front end.
What I did
Every page is server rendered and crawlable, with small progressive enhancements: filters that submit on change and a load more control.
Why
Nothing falls over with JavaScript off, and search engines read every page as the reader sees it.

Verify before costing

Context
Asked to scope tables, blockquotes and inline code in the article editor.
Tempting answer
Estimate from the editor feature list.
What I did
Built a throwaway article and inspected what the editor actually produced.
Why
Three of the four features already worked. The real gap was template styling, so the estimate covered only that.

Testing it took under an hour. That is the habit the whole engagement ran on: surface the tradeoff or the inconsistency before building against it, rather than guessing and invoicing the guess.

Hard problems

Filters that cannot contradict themselves, and dates that mean something.

A reader studying for CFA meets four things that sound like one: the certification, its own levels (CFA Level I to III, FRM Part I and Part II), the prep provider, and the provider's course levels, which do not line up with the exam's levels at all.

  1. HP.01

    Filters narrowed on the server

    The level dropdown offers only the levels of the selected certification. Choose FRM and the options become FRM Part I and FRM Part II, so a reader can never land on a silently empty page.

  2. HP.02

    Search ranked by field

    A title match outranks an excerpt match, which outranks a body match, through a weighted SQL CASE expression rather than a FULLTEXT index or an external search service.

  3. HP.03

    Three dates

    Articles carry when they went live, when they were last fact checked, and when they last changed. The page labels whichever of reviewed or updated is most recent, so the two never blur.

Implementation

SEO built in, not sprinkled on.

Filtered archive URLs canonicalise back to their base page, so filter combinations never become a wall of near duplicate pages. Archives carry BreadcrumbList and ItemList structured data, articles carry Article and BreadcrumbList, and the sitemap lists real content rather than the filter space.

Email runs on AWS SES for both transactional and marketing mail, with bounce handling, a confirmed unsubscribe flow and reCAPTCHA v3 on every public form.

Result

Live, with the machine built before the words.

The platform is live at prepbenchmark.com. Before this work the client had no working article platform, no search and no way to filter by certification or exam level. All of it now runs in production, along with review, ranking and comparison surfaces per certification and an email system that went from nonexistent to automated.

The remaining work is editorial: deeper written verdicts, the published methodology and the head to head comparisons sit on surfaces that are already built and waiting on the client's content.

Lessons

Modelling mistakes do not announce themselves.

They wait for the first feature that actually needs the distinction, then charge interest. And estimating from documentation would have put a price on work that was already done.

Building something like this?

Start a project

WooCommerce cart bridge Next system