Game Backlog
A full-stack game backlog application built with Flutter and Laravel, featuring interchangeable local and remote data sources, automatic game metadata enrichment, CI/CD, and Docker deployment.

The Problem
The goal of this project was not simply to build another game tracker, but to explore how a mobile application can be designed around interchangeable data sources and a clean separation between presentation, business logic, and persistence.
- Mobile applications should not depend on a single storage implementation.
- Business logic should remain independent from the UI.
- Additional game information should be retrieved automatically instead of entered manually.
- The architecture should be maintainable and easy to extend.
The Solution
The application uses Flutter as the client and communicates through a repository abstraction instead of directly accessing storage. Depending on the implementation, requests can be handled by a local SQLite database or a Laravel REST API. The backend enriches games with additional metadata, reducing manual input while demonstrating a scalable full-stack architecture.
- Manage a personal game backlog and wishlist.
- Track play and ownership status.
- Retrieve additional game metadata automatically.
- Switch between local and remote data sources through a shared abstraction.
Architecture
Full-Stack Application Flow
The application is built around a repository abstraction that separates the Flutter frontend from the underlying storage implementation. Instead of communicating directly with a database or API, the UI interacts with a common interface that can delegate requests to either a local SQLite data source or a Laravel REST API. The backend exposes CRUD endpoints, processes background enrichment jobs, and persists data, allowing the application to switch data sources without changing the rest of the codebase.
abstract class GameDataSource {
Future<List<Game>> retrieveGames();
Future<Game?> getGame(int id);
Future<Game> insertGame(Game game);
Future<Game> updateGame(Game game);
Future<void> removeGame(int id);
Future<void> deleteAllGames();
}
Screenshots




Technical Analysis
Repository Abstraction
Rather than tightly coupling the UI to a specific storage solution, the application communicates with a repository interface. This makes it possible to switch between local SQLite storage and a REST API without changing the rest of the application.
Separation Of Responsibilities
The project follows a layered architecture where presentation, business logic, and data access are separated. This keeps widgets lightweight and makes the application easier to maintain and extend.
Automatic Metadata Enrichment
Newly added games are enriched by backend jobs that retrieve additional information such as artwork and metadata from an external source. This improves the user experience while demonstrating asynchronous backend processing.
Deployment And Automation
The project includes a GitLab CI/CD pipeline and Dockerized services for reproducible deployments. Automated testing helps verify that important functionality continues to work as new features are introduced.
Challenges
The biggest challenge was designing an architecture that could support multiple storage implementations without affecting the rest of the application. Building clear abstractions between the UI, repository layer, and backend services made the project significantly more flexible and easier to maintain.
What This Project Demonstrates
Cross-Platform Development
The project demonstrates building a mobile application using Flutter while integrating it with a custom backend.
Clean Application Architecture
The application is organized into separate layers for presentation, repositories, services, and data sources, reducing coupling between components.
Full-Stack Engineering
The project combines mobile development, backend APIs, databases, background jobs, CI/CD, and Docker into a single application.
Production-Oriented Workflow
Beyond local development, the project includes automated deployment, containerization, environment configuration, and testing practices that mirror real-world software development.

A Bit About Me
Outside of software development, I enjoy gaming, anime, and working on personal projects that help me learn something new.
Whether it's building applications, automating workflows, or experimenting with new technologies, I enjoy creating things and understanding how they work.