package sessionbroker import ( "encoding/json" "net/http" "github.com/go-chi/chi/v5" "github.com/example/remote-access-platform/backend/internal/platform/httpx" ) type Module struct { service *Service } func NewModule(service *Service) *Module { return &Module{service: service} } func (m *Module) Name() string { return "session-broker" } func (m *Module) Service() *Service { return m.service } func (m *Module) RegisterRoutes(router chi.Router) { router.Route("/sessions", func(r chi.Router) { r.Get("/", m.listSessions) r.Post("/", m.startSession) r.Post("/{sessionID}/attach", m.attachSession) r.Post("/{sessionID}/detach", m.detachSession) r.Post("/{sessionID}/takeover", m.takeoverSession) r.Post("/{sessionID}/terminate", m.terminateSession) r.Post("/{sessionID}/fail", m.markFailed) }) } func (m *Module) listSessions(w http.ResponseWriter, r *http.Request) { userID := r.URL.Query().Get("user_id") if userID == "" { httpx.WriteError(w, http.StatusBadRequest, "user_id is required") return } sessions, err := m.service.ListSessions(r.Context(), userID) if err != nil { status, message := m.service.MapError(err) httpx.WriteError(w, status, message) return } httpx.WriteJSON(w, http.StatusOK, map[string]any{"sessions": sessions}) } func (m *Module) startSession(w http.ResponseWriter, r *http.Request) { var cmd StartRemoteSessionCommand if err := json.NewDecoder(r.Body).Decode(&cmd); err != nil { httpx.WriteError(w, http.StatusBadRequest, "invalid start session payload") return } result, err := m.service.StartRemoteSession(r.Context(), cmd) if err != nil { status, message := m.service.MapError(err) httpx.WriteError(w, status, message) return } httpx.WriteJSON(w, http.StatusCreated, result) } func (m *Module) attachSession(w http.ResponseWriter, r *http.Request) { var cmd AttachToSessionCommand if err := json.NewDecoder(r.Body).Decode(&cmd); err != nil { httpx.WriteError(w, http.StatusBadRequest, "invalid attach session payload") return } cmd.SessionID = chi.URLParam(r, "sessionID") result, err := m.service.AttachToSession(r.Context(), cmd) if err != nil { status, message := m.service.MapError(err) httpx.WriteError(w, status, message) return } httpx.WriteJSON(w, http.StatusOK, result) } func (m *Module) detachSession(w http.ResponseWriter, r *http.Request) { var cmd DetachFromSessionCommand if err := json.NewDecoder(r.Body).Decode(&cmd); err != nil { httpx.WriteError(w, http.StatusBadRequest, "invalid detach session payload") return } cmd.SessionID = chi.URLParam(r, "sessionID") result, err := m.service.DetachFromSession(r.Context(), cmd) if err != nil { status, message := m.service.MapError(err) httpx.WriteError(w, status, message) return } httpx.WriteJSON(w, http.StatusAccepted, result) } func (m *Module) takeoverSession(w http.ResponseWriter, r *http.Request) { var cmd TakeoverSessionCommand if err := json.NewDecoder(r.Body).Decode(&cmd); err != nil { httpx.WriteError(w, http.StatusBadRequest, "invalid takeover session payload") return } cmd.SessionID = chi.URLParam(r, "sessionID") result, err := m.service.TakeoverSession(r.Context(), cmd) if err != nil { status, message := m.service.MapError(err) httpx.WriteError(w, status, message) return } httpx.WriteJSON(w, http.StatusOK, result) } func (m *Module) terminateSession(w http.ResponseWriter, r *http.Request) { var cmd TerminateSessionCommand if err := json.NewDecoder(r.Body).Decode(&cmd); err != nil { httpx.WriteError(w, http.StatusBadRequest, "invalid terminate session payload") return } cmd.SessionID = chi.URLParam(r, "sessionID") if err := m.service.TerminateSession(r.Context(), cmd); err != nil { status, message := m.service.MapError(err) httpx.WriteError(w, status, message) return } httpx.WriteJSON(w, http.StatusAccepted, map[string]any{ "status": "terminated", "message": httpx.NewMessage( "session.terminated", "status.session.terminated", "Session terminated.", nil, "", ), }) } func (m *Module) markFailed(w http.ResponseWriter, r *http.Request) { var cmd MarkSessionFailedCommand if err := json.NewDecoder(r.Body).Decode(&cmd); err != nil { httpx.WriteError(w, http.StatusBadRequest, "invalid fail session payload") return } cmd.SessionID = chi.URLParam(r, "sessionID") if err := m.service.MarkSessionFailed(r.Context(), cmd); err != nil { status, message := m.service.MapError(err) httpx.WriteError(w, status, message) return } httpx.WriteJSON(w, http.StatusAccepted, map[string]any{ "status": "failed", "message": httpx.NewMessage( "session.failed", "status.session.failed", "Session marked as failed.", nil, "", ), }) }