<aside>
Engineering and product decision records documenting the development and operational evolution of Musecat, including infrastructure, data modelling, localisation, and scaling decisions.
<aside>
For the features summary, please refer to Musecat Key Features
</aside>
</aside>
<aside>
23.02 Finding Arcades More EasilyProblem: Before this project, finding arcade information usually meant searching Namuwiki or each arcade’s official homepage.
Problem: The information was often outdated, difficult to compare, and not practical to sort by distance.
Problem: It was especially inconvenient to find an arcade that matched multiple conditions, such as a place where two friends could both play the games they wanted.
Decision: Start a website where users could simply select the games they wanted and see matching arcades listed by distance.
Before
------
search Namuwiki / official websites
-> collect scattered arcade information
-> manually compare machines and locations
-> estimate which arcade is closer
Goal
----
select desired games
-> find matching arcades
-> sort by distance
Impact: This became the starting point of the project.
</aside>
<aside>
23.03 Manual Update Workflow on FirebaseDecision: In the earliest stage, members wrote simple string-based change requests, and the admin manually updated the Firebase data.
Context: At that time, the project did not yet have a clear concept of database design, frontend/backend separation, or API architecture.
Early workflow
--------------
member
-> writes a short text request
-> sends it to admin
admin
-> reads the request manually
-> edits Firebase directly
Impact: This was sufficient for the earliest prototype stage, but the process depended entirely on manual interpretation and direct data editing.

</aside>
<aside>
23.04 Introduced a Dedicated Admin Input FormProblem: It became clear that having the admin edit data directly was inefficient and difficult to maintain.
Problem: In particular, with only two people managing the data, it was hard to consistently follow the expected JSON format by hand.
Decision: Build a separate web page that only served as an input form for the admin workflow.
Admin form flow
---------------
admin fills form
-> form validates input structure
-> form outputs JSON
-> admin uses the JSON in Firebase workflow
Implementation: The form generated JSON from structured inputs, but it did not write directly to Firebase.
Reason: Direct write access was intentionally avoided to reduce potential security risk.
Impact: This reduced manual formatting mistakes and made the admin input process more structured, even before a real backend or API workflow existed.

</aside>
<aside>
23.05 Gradually Standardized the User Report FormDecision: Using Next.js dynamic routes, each arcade page reused its own arcade id, and the user report form gradually became more standardized.
Implementation: Users were guided to submit reports with a more structured format: target arcade id, selected game, and a string-based change request.
Dynamic route example
---------------------
/arcade/[id]
-> use arcade id from the page
-> pre-fill report target
Report form structure
---------------------
arcadeId: <current arcade id>
game: <selected game>
request: <string change description>
Impact: Even though the payload was still simple, this was an important step toward making user submissions more consistent and easier to process than completely free-form reports.
</aside>
<aside>
23.05 Manually Seeded the Initial Arcade DatasetDecision: Start entering the initial arcade data manually from existing wiki-based sources so the service could launch with usable coverage.
Implementation: Around 45 arcades were entered by hand, including location, business hours, and game lists.
Initial data sources
--------------------
wiki / public online information
-> manually review
-> manually enter into service data
Community Input: A promotional post was also published on DCInside(Korean reddit), and additional reports were collected through Google Sheets.
Impact: This created a practical starting dataset large enough to support an actual public launch. (https://gall.dcinside.com/board/view/?id=rhythmgame_new1&no=517696)
</aside>
<aside>
23.06.17 Alpha Service LaunchDecision: Launch the service once the initial arcade dataset and reporting flow were in place.
Impact: The project moved from an internal experiment to a publicly usable service on June 17, 2023.
</aside>
<aside>
23.07 Started Researching REST APIs and SQL DatabasesProblem: Firebase was becoming increasingly difficult to manage because the data structure was not sufficiently normalized and the database model was hard to maintain as the service grew.
Problem: As user traffic increased, arcade update requests began reaching around 20 or more per day, and the existing manual workflow stopped scaling.
Decision: Start researching REST APIs and SQL databases, and plan a database transition away from the existing Firebase structure.
Why change was needed
---------------------
more users
-> more update requests
-> more manual review work
-> more structural inconsistency in Firebase
-> harder service maintenance
Goal: User-submitted changes needed to move into an automated pipeline so they could be reflected in the service much faster.
Impact: This became the starting point for designing a more structured backend and a more maintainable database model.
</aside>
<aside>
23.07 Chose PocketBase as the Next Database FoundationProblem: Once the number of arcades exceeded 150, the service needed more advanced product capabilities:
New requirements
----------------
1. search
2. advanced game filtering
3. region filtering (state, city)
4. directions / send to map app
5. per-machine attributes
- streaming support
- headphone amp
- other user-requested machine details
Problem: The previous structure was not good enough for this level of normalization, especially because game series and version management had been treated as a single combined concept.
Decision: The next backend needed to support normalized data design, usable REST APIs, and a more maintainable admin workflow without requiring heavy direct SQL usage from day one.
What was needed
---------------
normalized data model
+ REST API support
+ auth support
+ SDK support
+ lower operational complexity
Decision: PocketBase was selected as the new foundation.
Reason: PocketBase uses SQLite underneath while providing built-in authentication, REST APIs, and SDK support, which made it a strong fit for moving away from Firebase without jumping immediately into a fully custom backend stack.
Impact: This decision made large-scale normalization the main task of the next phase and created the base for more structured arcade, game, and region data handling.
</aside>
<aside>
23.08 Used PocketBase SDK for Direct Document UpdatesDecision: With PocketBase, documents could now be updated by sending direct API requests through the SDK instead of relying only on manual data handling.
PocketBase workflow
-------------------
admin action
-> SDK request
-> direct document update
Limitation: Rollback support for malicious or problematic edits was not built in at this stage.
Limitation: Authentication only assumed admin login. Regular end-user account login was not yet part of the model.
Limitation: There was also an unresolved issue where the auth session could be lost after roughly two days away from the site.
Impact: Even with SDK-based editing, administrators still had to continuously monitor which documents were changed and how they were changed, because the system was not yet safe enough to trust unattended.
</aside>
<aside>
23.09.02 Beta Service LaunchContext: After the Alpha launch on June 17, 2023, Musecat was upgraded to Beta over roughly two and a half months.
Announcement: Musecat Beta Update
Headline: The Beta release was positioned as a major step forward through search and a much larger, more usable data experience.
Beta highlights
---------------
1. search
2. advanced filters
3. region filtering
4. customizable home listing behavior
5. inline edit requests without moving to a separate page
Details: The announcement explicitly highlighted advanced filtering, including region-based filtering, and noted that filter settings were remembered between sessions.
Details: It also introduced customization for how arcade lists are shown on the home screen and how nearby arcades are explored based on location.
Details: Edit requests were improved so users could modify currently displayed information inline.
Follow-up Work: The post also listed ongoing improvements such as arcade photos, response speed improvements, alert features, business-hour notes, temporary closure support, feedback channels, report UX improvements, and general bug fixes.
Impact: This marked the public Beta release of Musecat on September 2, 2023, and established the service as more than a basic directory by turning search, filtering, and reporting into core product features.
</aside>
<aside>
23.12 Started Preparing for a VPS Self-Hosting MigrationProblem: After arcade images were added during the Beta period, the project began to approach the limits of free hosting.
Problem: Vercel’s free hosting quota was already under pressure, and the free backend hosting limit of 5 GB had also become a concern after usage exceeded roughly 3.5 GB.
Short-Term Response: In the short term, the only workable option was to selectively manage arcade images and reduce image quality as much as possible.
Decision: It became clear that a server migration was no longer optional, but inevitable.
Why migration became necessary
------------------------------
more arcade images
-> higher hosting usage
-> tighter quota pressure
-> image quality compromises
-> migration becomes unavoidable
Research Focus: This triggered research into self-hosting and VPS operations, including internet fundamentals such as IP, TCP, and reverse proxy architecture.
Goal: Begin researching a migration path where both the Next.js frontend and the PocketBase backend could be moved onto a VPS-based self-hosted environment.
Impact: Infrastructure ownership became a core technical theme of the next phase, not just for cost reasons, but because the product had outgrown the assumptions of the free hosting stack.
</aside>
<aside>
</aside>
<aside>
</aside>
<aside>
</aside>
<aside>
</aside>
<aside>
</aside>