About a year ago, I set off to create my first app start to finish: the personal media library management app My MediaVerse (also referred to as MMV, formerly known as Project Loopbreaker). My goal was to have a working demo built by graduation that I could display as part of my portfolio. I was able to achieve that back in March when I publicly shared V1 of My MediaVerse in the form of a read-only demo site (available at demo.mymediaverseuniverse.com). I’m a fiction writer, and I sometimes compare programming with writing. In that vein, I liken the completion of my demo site to a first draft. Now the next stage begins: editing (in the form of refactoring).
Over the past year, I have learned A TON about software development from my apprenticeship, schoolwork, and building my app. So before I make major updates to the app’s functionality, my next big step is what I call The Great Refactor!
Since releasing the demo, I’ve been analyzing and tweaking the frontend and backend to incorporate best practices I’ve learned. I’ve laid out plans in four major stages: backend, frontend, backend testing, and frontend testing, to serve as a solidified base before I start adding new features. Some of the major changes:
My Program.cs became what I’ve learned is a “god file,” performing far too many tasks and in need of better organization. A large part of improving this has involved breaking up services into extension methods where possible, removing unnecessary services, and simplifying database connection logic.
Refactoring my MediaController
The main goal of the app is to allow the user to easily import what they want to watch/read/listen to from multiple services and save it in a database for easy retrieval. The MediaController routes the user’s traffic to the appropriate database action to retrieve or edit a saved media item. My controller had become “fat” and held far more responsibilities than it should. To remedy this, I’ve divided up this file into several media type-specific controllers (one for books, one for television shows, one for podcasts, etc.).
Adjusting Typesense indexing
MMV uses a self-hosted instance of the open-source program Typesense to index media items and power the search engine. Typesense indexes the content you have stored to make fast search possible. Previously, I had the app index the database after any individual item was added. This was fine during testing, but would be wasted processing when I start bulk uploading. I adjusted this so that indexing happened either manually in the Admin dashboard, or on a schedule like the rest of the enrichment services that will be added.
Reorganizing Scripts
MMV currently has a folder to hold all locally run scripts – some are Python and organize Obsidian personal notes specifically, while others are PowerShell. I am combining similar scripts into “modules” that are easier for the user to run rather than having to manually open and run each script as well as archiving one-time use scripts that are no longer needed.
Frontend
I was completely new to React (although I had JavaScript experience) when I started building MMV. One of the largest lessons I learned here was similar to some of my backend refactoring: break pages down into smaller, single-responsibility components, and reuse code where possible. I had already made the Media Profile Page modular with components specific for each media type, so I have a template to follow.
Keeping existing AI infrastructure
The decision process on this was interesting because it didn’t go as expected. In addition to being written with the assistance of AI (mainly my buddy Claude Code), the app itself uses AI to create note summaries and generate embeddings for user-requested media recommendations. The summary generation uses gpt-oss-120b model via DigitalOcean’s Gradient AI platform, while the embeddings are generated using the text-embedding-3-large model directly from the OpenAI API. When laying out my plan for refactoring, I considered consolidating these into one service for simplicity. However, upon further analysis I realized that since each model served a specific, different purpose and single-user cost differences are negligible, maintaining the current structure is what made the most sense. Instead of consolidating, I am refactoring the code to be cleaner and more effective.
DevOps
In addition to programming, working on MMV has provided a hands-on opportunity for me to create infrastructure and DevOps processes from scratch. I purchased a small DigitalOcean Droplet (brand of a VM) originally with the intent to just self-host Typesense. Over the course of creating MMV, I’ve stumbled into the amazing world of open-source software and have started hosting other services, such as the analytics program Umami to track visits and usage. I used Docker to run these services in containers, and set them up using Docker Compose. I’ve realized though that my system and location for Compose files need to be more consistent. I also plan on setting up more YAML build pipelines that will make testing an automatic part of the process.
Testing, testing, testing
With all of the changes I’ve made, I’ve also decided to completely redo my testing suites for frontend and backend to reflect the updates to the program. Some of this involves switching libraries from any that have become monetized to ones that are still open-source. Since I had never used React before this project, the frontend test suite is basically going to be a complete rewrite with best practices that I’ve learned along the way.
Thus far, the backend and backend test refactors have been completed. The frontend refactor is about 85% done (the main remnants are breaking up some of the more complex mega-elements) and I have just begun rebuilding the frontend test suite. My goal is to have a working version of the app for personal use by mid-June. Once The Great Refactor is complete, I plan to continue enhancing the app’s feature set, such as support for video games, music, and courses, and webpage archival using ArchiveBox. More to come!

Leave a Reply