DEV Community

All Smart Accessories
All Smart Accessories

Posted on

I built a case compatibility checker covering 67 phone models (and open-sourced it)

Why I built this

I run a phone accessories blog. Every week the same question shows up in comments and support emails:

"I have a Galaxy S24 Ultra — which case fits it?"

I was answering it by hand, then linking to a buying guide, then hoping the reader found the right section. That's a bad experience, so I built a tool that just answers it.

Case Compatibility Checker — pick a brand, pick a model, and you get the compatible case types plus screen protector info.

67 models are covered: Apple iPhone 6 through 17, Samsung Galaxy S7 through S24 Ultra, the Note line up to the Note 20 Ultra, plus Pixel, OnePlus, HTC, LG, Motorola, Xiaomi, ZTE and Nokia.

Two front-ends, one dataset

The interesting design problem: I wanted a web tool and a CLI, without duplicating the data or the logic.

casefinder/
  casefinder/
    __init__.py
    __main__.py
    cli.py        # argparse front-end
    data.py       # dataset loading
    data/
      phones.json # the actual dataset
  index.html      # static web front-end
  app.js          # fetches the same phones.json
  styles.css
Enter fullscreen mode Exit fullscreen mode

Both front-ends read the same phones.json. The CLI runs offline for shell scripting; the web app fetches the file over HTTP. A test asserts they're identical, so they can't silently drift apart.

pip install casefinder
casefinder check "Galaxy S24 Ultra"
Enter fullscreen mode Exit fullscreen mode
Model:        Galaxy S24 Ultra
Brand:        Samsung
Released:     2024
MagSafe:      no

Case types:
  - rugged
  - clear
  - slim
  - wallet
  - battery
  - kickstand
  - waterproof
  - stylish
  - bumper

Screen protector: tempered glass, film
Guide: https://allsmartaccessories.com/top-10-best-galaxy-s24-ultra-cases/
Enter fullscreen mode Exit fullscreen mode

Where the data came from

This is the part I care most about. I did not invent any of it.

The 67 models and their compatible case types were derived from my existing published guides — each entry links back to the real post it came from. Every one of those 67 URLs was verified with a live HTTP request before it went into the dataset.

{
  "model": "Galaxy S24 Ultra",
  "brand": "Samsung",
  "released": 2024,
  "magsafe": false,
  "caseTypes": ["rugged", "clear", "slim"],
  "screenProtector": ["tempered glass", "film"],
  "postUrl": "https://allsmartaccessories.com/top-10-best-galaxy-s24-ultra-cases/"
}
Enter fullscreen mode Exit fullscreen mode

dimensionsMm is deliberately null rather than a guessed number. The UI hides that row instead of showing something made up.

TDD, in the order I actually built it

I wrote each test file first, watched it fail, then implemented. Not because it's fashionable — because I kept changing my mind about the schema and the tests caught me.

  1. test_schema.py — the shape of phones.json
  2. test_cli.py — brands, models, check subcommands
  3. test_packaging.py — the wheel builds and the entry point works
  4. test_webapp.py — the HTML renders, and no innerHTML anywhere
  5. test_sync.py — CLI data and web data are the same file

22 tests, and a GitHub Action runs them on every push.

The one that caught me

My XSS test grepped app.js for innerHTML. It failed — on my own comment where I'd written "we never use innerHTML here." That was a genuinely useful failure, because it proved the gate was real and not decoration. I fixed the test to strip comments first.

The SEO angle

The web page is a single static HTML file with 67 real <a> links to the guides. No framework, no build step, ~49 KB total, zero external requests.

Two reasons:

  1. Crawlable. Google sees actual text and 67 internal links. A JS-only widget would show up as an empty page.
  2. Fast. No render-blocking fonts, no CDN, no framework hydration.

Plus WebApplication JSON-LD and OG tags, matching what the rest of my WordPress site already emits via Yoast.

What I'd do differently

  • I should have written the schema first. I rewrote phones.json twice because I kept adding fields mid-build.
  • pip install from a relative path is a trap in tests. Had to be explicit about it.
  • Verify URLs earlier. I discovered the bad Note 20 Ultra link late and had to re-check all 67 anyway.

Try it

It's MIT licensed. If you maintain a product database and want the same "two front-ends, one dataset" structure, the test that keeps them in sync is the piece worth stealing.

If you found this useful, the Case Compatibility Checker is free and covers 67 models.

Top comments (0)