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 the Project dataclass, ProjectStatus enumeration, and ProjectManager class responsible for generating unique project_id values and persisting project metadata to JSON files.

  • backend/app/services/simulation_manager.py – Contains the SimulationState dataclass with the critical project_id field, the SimulationManager class, and methods including create_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, utilizing SimulationManager to resolve project_id associations and enforce project-based access controls.

  • backend/config.py – Configuration module providing UPLOAD_FOLDER and OASIS_SIMULATION_DATA_DIR paths 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_id field in the SimulationState dataclass defined in backend/app/services/simulation_manager.py.
  • Project identifiers follow the format proj_<12‑hex> and persist to UPLOAD_FOLDER/projects/<project_id>/project.json via the ProjectManager class.
  • Simulation state—including the project association—serializes to uploads/simulations/<simulation_id>/state.json through the _save_simulation_state() method.
  • The SimulationManager provides create_simulation() and get_simulation() methods to establish and resolve project relationships at runtime.
  • API endpoints in backend/app/api/simulation.py expose these relationships to clients, enabling project-based simulation management and access control.

Frequently Asked Questions

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.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →