package socket import ( "context" protoSocket "git.toki-labs.com/toki/proto-socket/go" altv1 "git.toki-labs.com/toki/alt/packages/contracts/gen/go/alt/v1" "git.toki-labs.com/toki/alt/packages/domain/trading" ) // LiveService is the narrow interface for live broker capability discovery. // It is intentionally minimal for this milestone so no order/account/audit // surface is exposed until subsequent subtasks add them. type LiveService interface { GetLiveBrokerCapabilities(ctx context.Context, accountID string) (trading.BrokerCapability, error) } func liveHandlers(deps Deps) []sessionHandler { return []sessionHandler{ { requestType: protoSocket.TypeNameOf(&altv1.GetLiveBrokerCapabilitiesRequest{}), register: func(client *protoSocket.WsClient) { protoSocket.AddRequestListenerTyped[*altv1.GetLiveBrokerCapabilitiesRequest, *altv1.GetLiveBrokerCapabilitiesResponse]( &client.Communicator, func(req *altv1.GetLiveBrokerCapabilitiesRequest) (*altv1.GetLiveBrokerCapabilitiesResponse, error) { return handleGetLiveBrokerCapabilities(deps, req) }, ) }, }, } } func handleGetLiveBrokerCapabilities(deps Deps, req *altv1.GetLiveBrokerCapabilitiesRequest) (*altv1.GetLiveBrokerCapabilitiesResponse, error) { if req.GetAccountId() == "" { return &altv1.GetLiveBrokerCapabilitiesResponse{ Error: &altv1.ErrorInfo{Code: backtestErrorInvalidRequest, Message: "invalid live trading request: account_id is required"}, }, nil } if deps.Live == nil { return &altv1.GetLiveBrokerCapabilitiesResponse{ Error: &altv1.ErrorInfo{Code: backtestErrorUnavailable, Message: "live trading is not available"}, }, nil } ctx, cancel := context.WithTimeout(context.Background(), handlerTimeout) defer cancel() cap, err := deps.Live.GetLiveBrokerCapabilities(ctx, req.GetAccountId()) if err != nil { return &altv1.GetLiveBrokerCapabilitiesResponse{ Error: &altv1.ErrorInfo{Code: backtestErrorInternal, Message: err.Error()}, }, nil } return &altv1.GetLiveBrokerCapabilitiesResponse{ BrokerCapabilities: liveCapabilityToProto(cap), }, nil }