How MiroFish Tracks and Associates Simulations with Specific Projects
The MiroFish backend tracks and associates simulations with specific projects by storing a project_id field in the SimulationState dataclass and persisting that relationship to a JSON file on disk, ensuring durable linkage across server restarts.
The 666ghj/mirofish repository implements a robust backend architecture that tracks and associates simulations with specific projects through persistent storage mechanisms. By embedding unique project identifiers directly into simulation state objects and serializing them to structured JSON files, the system maintains reliable relationships between computational workflows and their originating project metadata.
Project and Simulation Data Models
Project Persistence Architecture
In backend/app/models/project.py, the Project dataclass defines the metadata structure for projects, including fields for id, name, status, and associated files. The ProjectManager class generates a unique project_id using the format proj_<12‑hex> and persists the entire model to project.json under the directory UPLOAD_FOLDER/projects/<project_id>/.
Simulation State Structure
The SimulationState dataclass in backend/app/services/simulation_manager.py contains the critical project_id: str field that establishes the association between a simulation and its parent project. This field is populated during simulation creation and maintained throughout the simulation lifecycle within the state object.
How the Project Manager Creates the Association
Generating Unique Project Identifiers
When ProjectManager.create_project() is invoked, it generates a unique 12-character hexadecimal identifier prefixed with proj_. This identifier serves as the canonical reference stored in the project's JSON file and subsequently referenced by all associated simulations.
Linking Simulations via project_id
The SimulationManager.create_simulation() method accepts a project_id parameter, which it injects into the SimulationState dataclass during instantiation. This creates the in-memory association that is subsequently persisted to disk through the _save_simulation_state() method.
Persistent Storage Implementation
File System Layout
The backend maintains separate directory structures for projects and simulations. Projects reside in UPLOAD_FOLDER/projects/<project_id>/project.json, while simulations store their state in uploads/simulations/<simulation_id>/state.json. The project_id field within state.json maintains the cross-reference between these storage locations.
State Serialization
The _save_simulation_state() method in SimulationManager serializes the entire SimulationState object—including the project_id—to JSON format. This ensures the project-simulation association survives server restarts, crashes, or deployments across multiple workers.
Retrieving Project-Simulation Relationships
To resolve which project owns a specific simulation, SimulationManager.get_simulation(simulation_id) loads the corresponding state.json file from disk, reconstructs the SimulationState object, and exposes the stored project_id. API endpoints in backend/app/api/simulation.py leverage this method to answer project affiliation queries and enforce project-based access controls.
Complete Workflow Example
The following examples demonstrate creating a project, associating a simulation, and retrieving the relationship.
Creating a Project and Linked Simulation
from backend.app.models.project import ProjectManager
from backend.app.services.simulation_manager import SimulationManager
# 1️⃣ Create a new project
project = ProjectManager.create_project(name="Social Media Analysis")
print("Project ID:", project.project_id) # e.g. proj_9f3a8b7c2d1e
# 2️⃣ Initialise the simulation manager
sim_mgr = SimulationManager()
# 3️⃣ Create a simulation that belongs to the project
sim_state = sim_mgr.create_simulation(
project_id=project.project_id,
graph_id="graph_12345", # ID of the Zep graph that stores the knowledge base
enable_twitter=True,
enable_reddit=False,
)
print("Simulation ID:", sim_state.simulation_id)
print("Linked Project ID:", sim_state.project_id) # matches the project above
Retrieving the Project from a Simulation
# Load an existing simulation
sim_state = sim_mgr.get_simulation("sim_a1b2c3d4e5f6")
if sim_state:
# Use the stored project_id to fetch the project details
project = ProjectManager.get_project(sim_state.project_id)
print(f"Simulation {sim_state.simulation_id} belongs to project '{project.name}'")
API-Level Lookup
# Inside a Flask route (simplified)
def get_simulation_info(simulation_id: str):
state = SimulationManager().get_simulation(simulation_id)
project = ProjectManager.get_project(state.project_id)
return {
"simulation_id": state.simulation_id,
"project_id": project.project_id,
"project_name": project.name,
"status": state.status,
}
Key Implementation Files
-
backend/app/models/project.py– Defines theProjectdataclass,ProjectStatusenumeration, andProjectManagerclass responsible for generating uniqueproject_idvalues and persisting project metadata to JSON files. -
backend/app/services/simulation_manager.py– Contains theSimulationStatedataclass with the criticalproject_idfield, theSimulationManagerclass, and methods includingcreate_simulation(),get_simulation(), and_save_simulation_state()that handle JSON serialization of project associations. -
backend/app/api/simulation.py– Flask API endpoints that expose simulation data and project relationships to clients, utilizingSimulationManagerto resolveproject_idassociations and enforce project-based access controls. -
backend/config.py– Configuration module providingUPLOAD_FOLDERandOASIS_SIMULATION_DATA_DIRpaths that define the physical directory structure where project and simulation state files reside.
Summary
- The MiroFish backend tracks and associates simulations with specific projects by storing a
project_idfield in theSimulationStatedataclass defined inbackend/app/services/simulation_manager.py. - Project identifiers follow the format
proj_<12‑hex>and persist toUPLOAD_FOLDER/projects/<project_id>/project.jsonvia theProjectManagerclass. - Simulation state—including the project association—serializes to
uploads/simulations/<simulation_id>/state.jsonthrough the_save_simulation_state()method. - The
SimulationManagerprovidescreate_simulation()andget_simulation()methods to establish and resolve project relationships at runtime. - API endpoints in
backend/app/api/simulation.pyexpose these relationships to clients, enabling project-based simulation management and access control.
Frequently Asked Questions
How does MiroFish ensure the project-simulation link survives server restarts?
MiroFish persists the association in JSON files on disk rather than relying solely on runtime memory. The project_id is stored inside state.json within the simulation's directory (uploads/simulations/<simulation_id>/), and the _save_simulation_state() method writes this file whenever the simulation state changes. When the server restarts, get_simulation() reloads the JSON and reconstructs the SimulationState object, restoring the link.
What is the format of the project_id used to link simulations?
The ProjectManager generates unique identifiers using the format proj_<12‑hex>, where <12‑hex> represents a 12-character hexadecimal string. This format ensures uniqueness while remaining human-readable. The generated ID is stored in the project's project.json file and subsequently referenced by the project_id field in SimulationState when create_simulation() is invoked.
Can a simulation be transferred to a different project after creation?
Based on the current implementation in backend/app/services/simulation_manager.py, the project_id is set during create_simulation() and stored as a field in the SimulationState dataclass. While the _save_simulation_state() method could theoretically overwrite the JSON file with modified data, the standard API in backend/app/api/simulation.py does not expose endpoints to modify the project_id field after initial creation. Consequently, simulations remain bound to their originating project for their entire lifecycle.
Which source files contain the core logic for tracking project-simulation associations?
The primary implementation resides in three key files: backend/app/models/project.py defines the ProjectManager class responsible for generating project IDs and persisting project metadata; backend/app/services/simulation_manager.py contains the SimulationState dataclass with the project_id field and the SimulationManager methods that serialize this relationship to disk; and backend/app/api/simulation.py exposes these relationships through REST API endpoints. Configuration paths defined in backend/config.py determine the physical directory structure where these associations are stored.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →