Skip to main content

System Overview

SimSwarm is a FastAPI backend, a Vue single-page app, a Temporal-orchestrated simulation lifecycle, and a set of supporting datastores. This page maps the running components and how they connect. It reflects the actual services defined in docker-compose.yml and the API router assembled in saas/router.py.

Services

The Compose stack (docker-compose.yml) defines the following containers:

ServiceImageRole
appfishcloud-appFastAPI application (saas.main:create_app), serves the API on 127.0.0.1:8080.
celeryfishcloud-appCelery worker with embedded beat (--beat), --concurrency=4. Runs the off-pod report task and scheduled maintenance.
dbpostgres:16-alpinePrimary application database (user fishcloud, db fishcloud).
redisredis:7-alpineCelery broker + result backend.
temporal-dbpostgres:16-alpineDedicated Postgres for Temporal's own state.
temporaltemporalio/auto-setup:1.22.7Temporal server (frontend on 127.0.0.1:7233, namespace fishcloud).
temporal-workerfishcloud-appRuns python -m saas.workflows.worker; executes the simulation workflow + activities.
caddycaddy:2-alpineTLS-terminating reverse proxy on :80/:443; serves the built frontend from a shared volume.
frontend-initfishcloud-appOne-shot: copies the built frontend into the frontend_dist volume.
migratefishcloud-appOne-shot: runs alembic upgrade head on deploy.

Two datastores are external to this Compose file and run separately (managed or on their own hosts):

  • Neo4j — the entity graph database.
  • MinIO — S3-compatible object storage for rich simulation artifacts and model weights. See Storage.

GPU pods are ephemeral and not part of the Compose stack — they are provisioned per-job from a cloud provider (RunPod) and torn down on completion. See Data Flow.

API surface

saas.main:create_app() is an app factory. It accepts an optional Settings (overridden in tests), configures structured logging and the slowapi rate limiter, calls init_db, and mounts a single api_router (prefix /api). That router (saas/router.py) includes one sub-router per feature:

RouterSourceResponsibility
healthsaas/health.pyLiveness/health endpoint.
jobssaas/jobs/api.pyCreate/list/get/delete jobs, sim-data URLs, graph; mounts share/draft/retry sub-routers.
authsaas/auth/api.pyRegister, login, email verification, password reset.
progresssaas/jobs/progress.pyLive progress stream for a running job.
exportsaas/jobs/export.pyPDF export of a completed report.
sharesaas/jobs/share.pyPublic share-token endpoints + demo listing.
fetchsaas/jobs/fetch.pyServer-side URL fetch for seed building.
profilesaas/auth/profile.pyPassword change, account deletion.
aisaas/jobs/ai.pyLLM-assisted goal generation.

All routes are mounted under /api.

How it connects

The API never runs a simulation itself. On job creation it starts a Temporal workflow and returns immediately; the temporal-worker owns the rest of the lifecycle. Report generation is handed off to the Celery worker after the sim finishes. The next page traces that flow end to end.