MatthiasMRC/dbmovies-test: A Flutter Movie App That Reads Like a Hiring Screen
A tiny TMDB browser that shows how much architecture, state discipline, and localization you can pack into one repo.
- dbmovies-test is less a movie app than a compact demonstration of Flutter judgment under assessment pressure.
- A single Provider-backed fetch powers both browse and favorites flows, which keeps the app's state story easy to reason about.
- French localization and helper methods keep view code thin, so the widgets read like composition rather than plumbing.
- The repo stops where production starts, and the hardcoded API key and fixed list length make that boundary obvious.
A technical test disguised as a movie app
The interesting thing about dbmovies-test is not that it browses movies. It is that the repo behaves like a compact answer key to a Flutter technical assessment. In a few folders, it reveals whether the author understands separation of concerns, state flow, localization, and the hygiene that keeps a small app readable.
One fetch, two screens, one source of truth
The app's core move is simple. It fetches popular films once, stores them in a provider, and lets multiple screens consume that same state. That is why the repo feels calmer than its size suggests. The plumbing is visible, but it is not noisy.
@override
void initState() {
super.initState();
context.read<MovieProvider>().getPostData();
}
That startup fetch belongs in `initState`, not in `build`. It keeps the first request from looping and makes the state transition easy to audit: loading starts, the network returns, `notifyListeners()` fires, and the screens redraw. The repo uses that same discipline across the provider and the widgets, so the app reads as one clean loop instead of a pile of callbacks.
The details that make it feel finished
The polish is where the repo earns trust. `api_service.dart` keeps the HTTP layer separate, `movie_model.dart` keeps JSON parsing out of the widgets, and `movie_card.dart` takes care of presentation details that would otherwise sprawl across the UI. Even the app's French angle is deliberate: the fetch uses `language: 'fr-FR'`, and dates are formatted with `DateFormat.yMMMM('fr')`.
String posterUrl() {
return poster_path == null
? ''
: 'https://image.tmdb.org/t/p/w500$poster_path';
}
That tiny helper does more than shorten a widget. It keeps image URL assembly inside the model, which means the UI can stay focused on layout, fallback states, and the favorite toggle. The same pattern shows up in the rendering layer: if a poster is missing, the card falls back cleanly instead of pretending the data is richer than it is.
Where the test ends and production begins
This is where the repo stops being a polished technical test and starts advertising its limits. The hardcoded API key is the obvious one. The fixed item count in the list is another. Add the lack of obvious retry logic, surfaced error states, or deeper secret management, and you get a clean boundary line between "good assessment project" and "production app."
| Concern | dbmovies-test | Production Flutter app |
|---|---|---|
| Networking | A thin `Dio` service wraps the TMDB request. | Retry policies, interceptors, cancellation, and typed failures. |
| State management | Provider keeps the demo simple and readable. | Separate remote state, local state, and cache layers with clearer boundaries. |
| Error handling | The happy path is the main story. | Explicit empty, offline, and failure states with user feedback. |
| Secret management | The API key lives in source with a warning comment. | Secrets stay outside the repo and are injected at deploy time. |
| Localization | French fetch and date formatting are already wired in. | Strings, dates, and locale rules are externalized more broadly. |
| List rendering | A fixed list size and poster fallback are enough for the test. | Paging, bounds checks, and more defensive rendering are expected. |
| Scalability | Small, legible, and easy to review. | Test coverage, analytics, and stronger module boundaries matter more. |
That contrast is the point. The repo is not trying to outbuild a mature streaming app or a heavyweight Flutter architecture. It is trying to prove that the author can keep a small surface area coherent, and on that narrow brief it succeeds.
Why this stack still works
Compared with Riverpod, Bloc, or a more layered production stack, Provider plus Dio looks modest. That is not a weakness here. For a technical test, the stack is small enough to explain, easy enough to reason about, and clear enough to show real judgment without burying the signal under framework ceremony. The repo earns its keep by being disciplined, not by being maximal.
That is why the project reads like a hiring screen. It shows that the author can isolate services, shape model data, wire a provider to multiple consumers, localize the experience, and stop before the codebase outruns the problem. For a tiny movie app, that is a surprisingly complete answer.