@startuml
!theme plain
title Turnstone — Docker Compose Deployment

skinparam node {
    BackgroundColor #F5F5F5
}

cloud "LLM Provider" as llm {
    component [vLLM / OpenAI API\nport 8000] as llm_api
}

node "Docker Host" as host {

    frame "turnstone-net (bridge network)" as net {

        node "redis" <<redis:7.4-alpine>> as redis_node {
            component [Redis Server\nport 6379] as redis
            note bottom of redis
                Healthcheck: redis-cli ping
                Volume: redis-data
            end note
        }

        node "server" <<turnstone image>> as server_node {
            component [turnstone-server\nport 8080] as server
            note bottom of server
                Command: turnstone-server
                  --host 0.0.0.0
                  --port 8080
                Depends: redis (healthy)
                Volume: turnstone-data
                  (/data)
            end note
        }

        node "bridge ×N" <<turnstone image>> as bridge_node {
            component [turnstone-bridge] as bridge
            note bottom of bridge
                Command: turnstone-bridge
                  --server-url http://server:8080
                  --redis-host redis
                Depends: server + redis
                Scalable: --scale bridge=N
                node_id: auto from hostname
            end note
        }

        node "console" <<turnstone image>> as console_node {
            component [turnstone-console\nport 8090] as console
            note bottom of console
                Command: turnstone-console
                  --redis-host redis
                  --port 8090
                Depends: redis
            end note
        }

        node "postgres (profile: production)" <<pgautoupgrade>> as pg_node {
            component [PostgreSQL\nport 5432] as postgres
            note bottom of postgres
                Healthcheck: pg_isready
                Volume: postgres-data
                Required for cluster
                  and production profiles
            end note
        }

        node "pgbouncer (optional)" <<bitnami/pgbouncer>> as pgb_node {
            component [PgBouncer\nport 6432] as pgbouncer
            note bottom of pgbouncer
                pool_mode: transaction
                Recommended for clusters
                  > 50 nodes
                See docs/pgbouncer.md
            end note
        }

        node "sim (profile: sim)" <<turnstone image>> as sim_node {
            component [turnstone-sim] as sim
            note bottom of sim
                Command: turnstone-sim
                  --redis-host redis
                  --nodes 100
                  --scenario steady
                Depends: redis
                Optional: only with
                  --profile sim
            end note
        }
    }
}

actor "Browser\nUser" as browser
actor "MQ Client" as mqclient

' External connections
browser --> server : HTTP + SSE\nport 8080
browser --> console : HTTP + SSE\nport 8090
mqclient --> redis : Redis protocol\nport 6379

' Internal connections
server --> redis : Redis protocol\n(6379)
server --> llm_api : OpenAI API\n(HTTPS/HTTP)

bridge --> server : HTTP REST\n(POST /v1/api/send, etc.)
bridge <-- server : SSE\n(GET /v1/api/events)
bridge --> redis : Redis protocol\n(queues + pubsub)

console --> redis : Redis PUBSUB + LIST\n(cluster events,\nws creation commands)
console --> server : HTTP polling + proxy\n(GET /v1/api/dashboard,\nproxy /node/{id}/*)

sim --> redis : Redis protocol\n(queues + pubsub + keys)

' Database connections (production/cluster profiles)
server ..> pgbouncer : PostgreSQL\n(pool_size=2)
console ..> pgbouncer : PostgreSQL\n(auth/admin)
pgbouncer --> postgres : transaction\npooling

' Environment variables
note right of host
    **Environment Variables:**
    • LLM_BASE_URL — LLM endpoint
    • OPENAI_API_KEY — API key
    • REDIS_PASSWORD — Redis auth
    • TURNSTONE_AUTH_TOKEN — API auth
    • TURNSTONE_DB_URL — PostgreSQL URL
    • POSTGRES_PASSWORD — DB password
end note

' Volumes
database "redis-data" as rv
database "turnstone-data" as tv
database "postgres-data" as pv

redis_node --> rv
server_node --> tv
pg_node --> pv

@enduml
