package api import ( "net/http" "browser.local/platform/dto" ) // serverClientManagerLifecycles godoc // @Summary List Client Manager lifecycle installations // @Description Returns safe durable lifecycle, health, real job progress, and action availability for the authorized server without component secrets or machine details. // @Tags client-managers // @Produce json // @Param id path string true "Server instance ID" // @Success 200 {object} dto.ClientManagerInstallationListResponse // @Failure 401 {object} dto.ErrorResponse // @Failure 403 {object} dto.ErrorResponse // @Router /api/v1/server-instances/{id}/client-managers [get] func (h *coreHandlers) serverClientManagerLifecycles(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { writeMethodNotAllowed(w, http.MethodGet) return } views, err := h.core.ListClientManagerLifecyclesForSession(bearerToken(r), r.PathValue("id")) if err != nil { writeServiceError(w, err) return } writeJSON(w, http.StatusOK, dto.ClientManagerLifecycleViewsFromDomain(views)) } // serverClientManagerLifecycleDetail godoc // @Summary Get one Client Manager lifecycle installation // @Tags client-managers // @Produce json // @Param id path string true "Server instance ID" // @Param profileKey path string true "Client Manager profile key" // @Success 200 {object} dto.ClientManagerInstallationResponse // @Failure 401 {object} dto.ErrorResponse // @Failure 403 {object} dto.ErrorResponse // @Failure 404 {object} dto.ErrorResponse // @Router /api/v1/server-instances/{id}/client-managers/{profileKey} [get] func (h *coreHandlers) serverClientManagerLifecycleDetail(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { writeMethodNotAllowed(w, http.MethodGet) return } view, err := h.core.GetClientManagerLifecycleForSession(bearerToken(r), r.PathValue("id"), r.PathValue("profileKey")) if err != nil { writeServiceError(w, err) return } writeJSON(w, http.StatusOK, dto.ClientManagerLifecycleViewFromDomain(view)) } // serverClientManagerDeploy godoc // @Summary Deploy an available Client Manager distribution // @Description Queues a typed Run deployment after server, endpoint, artifact, target, revision, and key-generation authorization. // @Tags client-managers // @Accept json // @Produce json // @Param id path string true "Server instance ID" // @Param body body dto.ClientManagerDeployRequest true "Deployment request" // @Success 202 {object} dto.ClientManagerInstallationResponse // @Failure 400 {object} dto.ErrorResponse // @Failure 401 {object} dto.ErrorResponse // @Failure 403 {object} dto.ErrorResponse // @Router /api/v1/server-instances/{id}/client-managers/deploy [post] func (h *coreHandlers) serverClientManagerDeploy(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { writeMethodNotAllowed(w, http.MethodPost) return } request, err := decodeJSON[dto.ClientManagerDeployRequest](r) if err != nil { writeDecodeError(w, err) return } view, err := h.core.DeployClientManagerForSession(bearerToken(r), request.ToDomain(r.PathValue("id"))) if err != nil { writeServiceError(w, err) return } writeJSON(w, http.StatusAccepted, dto.ClientManagerLifecycleViewFromDomain(view)) } // serverClientManagerControl godoc // @Summary Control a deployed Client Manager // @Description Queues a declared typed start, stop, restart, status, or rollback operation. // @Tags client-managers // @Accept json // @Produce json // @Param id path string true "Server instance ID" // @Param body body dto.ClientManagerControlRequest true "Control request" // @Success 202 {object} dto.ClientManagerInstallationResponse // @Failure 400 {object} dto.ErrorResponse // @Failure 401 {object} dto.ErrorResponse // @Failure 403 {object} dto.ErrorResponse // @Router /api/v1/server-instances/{id}/client-managers/control [post] func (h *coreHandlers) serverClientManagerControl(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { writeMethodNotAllowed(w, http.MethodPost) return } request, err := decodeJSON[dto.ClientManagerControlRequest](r) if err != nil { writeDecodeError(w, err) return } view, err := h.core.ControlClientManagerForSession(bearerToken(r), request.ToDomain(r.PathValue("id"))) if err != nil { writeServiceError(w, err) return } writeJSON(w, http.StatusAccepted, dto.ClientManagerLifecycleViewFromDomain(view)) } // serverClientManagerUpdateLifecycle godoc // @Summary Update a Client Manager through staged activation // @Tags client-managers // @Accept json // @Produce json // @Param id path string true "Server instance ID" // @Param body body dto.ClientManagerUpdateRequest true "Approved staged update request" // @Success 202 {object} dto.ClientManagerInstallationResponse // @Failure 400 {object} dto.ErrorResponse // @Failure 401 {object} dto.ErrorResponse // @Failure 403 {object} dto.ErrorResponse // @Router /api/v1/server-instances/{id}/client-managers/update [post] func (h *coreHandlers) serverClientManagerUpdateLifecycle(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { writeMethodNotAllowed(w, http.MethodPost) return } request, err := decodeJSON[dto.ClientManagerUpdateRequest](r) if err != nil { writeDecodeError(w, err) return } view, err := h.core.UpdateClientManagerForSession(bearerToken(r), request.ToDomain(r.PathValue("id"))) if err != nil { writeServiceError(w, err) return } writeJSON(w, http.StatusAccepted, dto.ClientManagerLifecycleViewFromDomain(view)) } // serverClientManagerRetry godoc // @Summary Retry a failed Client Manager lifecycle intent // @Tags client-managers // @Accept json // @Produce json // @Param id path string true "Server instance ID" // @Param body body dto.ClientManagerRetryRequest true "Retry request" // @Success 202 {object} dto.ClientManagerInstallationResponse // @Failure 400 {object} dto.ErrorResponse // @Failure 401 {object} dto.ErrorResponse // @Failure 403 {object} dto.ErrorResponse // @Router /api/v1/server-instances/{id}/client-managers/retry [post] func (h *coreHandlers) serverClientManagerRetry(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { writeMethodNotAllowed(w, http.MethodPost) return } request, err := decodeJSON[dto.ClientManagerRetryRequest](r) if err != nil { writeDecodeError(w, err) return } view, err := h.core.RetryClientManagerLifecycleForSession(bearerToken(r), request.ToDomain(r.PathValue("id"))) if err != nil { writeServiceError(w, err) return } writeJSON(w, http.StatusAccepted, dto.ClientManagerLifecycleViewFromDomain(view)) } // serverClientManagerRevokeSession godoc // @Summary Revoke the active Client Manager component session // @Tags client-managers // @Accept json // @Produce json // @Param id path string true "Server instance ID" // @Param body body dto.ClientManagerRevokeSessionRequest true "Session revoke request" // @Success 200 {object} dto.ClientManagerInstallationResponse // @Failure 401 {object} dto.ErrorResponse // @Failure 403 {object} dto.ErrorResponse // @Router /api/v1/server-instances/{id}/client-managers/revoke-session [post] func (h *coreHandlers) serverClientManagerRevokeSession(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { writeMethodNotAllowed(w, http.MethodPost) return } request, err := decodeJSON[dto.ClientManagerRevokeSessionRequest](r) if err != nil { writeDecodeError(w, err) return } view, err := h.core.RevokeClientManagerSessionForSession(bearerToken(r), request.ToDomain(r.PathValue("id"))) if err != nil { writeServiceError(w, err) return } writeJSON(w, http.StatusOK, dto.ClientManagerLifecycleViewFromDomain(view)) } // serverClientManagerUninstall godoc // @Summary Safely uninstall a Client Manager // @Description Stops the supervised process and removes only the controlled installation workspace while retaining audit and distribution history. // @Tags client-managers // @Accept json // @Produce json // @Param id path string true "Server instance ID" // @Param body body dto.ClientManagerUninstallRequest true "Confirmed uninstall request" // @Success 202 {object} dto.ClientManagerInstallationResponse // @Failure 400 {object} dto.ErrorResponse // @Failure 401 {object} dto.ErrorResponse // @Failure 403 {object} dto.ErrorResponse // @Router /api/v1/server-instances/{id}/client-managers/uninstall [post] func (h *coreHandlers) serverClientManagerUninstall(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { writeMethodNotAllowed(w, http.MethodPost) return } request, err := decodeJSON[dto.ClientManagerUninstallRequest](r) if err != nil { writeDecodeError(w, err) return } view, err := h.core.UninstallClientManagerForSession(bearerToken(r), request.ToDomain(r.PathValue("id"))) if err != nil { writeServiceError(w, err) return } writeJSON(w, http.StatusAccepted, dto.ClientManagerLifecycleViewFromDomain(view)) } // runClientManagerLifecycleInput godoc // @Summary Get fenced Client Manager lifecycle input // @Description Returns a safe typed lifecycle contract only to the authenticated Run endpoint holding the active job lease. // @Tags run-job-channel // @Accept json // @Produce json // @Param body body dto.ClientManagerLifecycleInputRequest true "Fenced lifecycle input request" // @Success 200 {object} dto.ClientManagerLifecycleInputResponse // @Failure 400 {object} dto.ErrorResponse // @Failure 401 {object} dto.ErrorResponse // @Router /api/v1/run/jobs/client-manager-input [post] func (h *coreHandlers) runClientManagerLifecycleInput(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { writeMethodNotAllowed(w, http.MethodPost) return } request, err := decodeJSON[dto.ClientManagerLifecycleInputRequest](r) if err != nil { writeDecodeError(w, err) return } input, err := h.core.GetClientManagerLifecycleInput(request.ToDomain()) if err != nil { writeServiceError(w, err) return } writeJSON(w, http.StatusOK, dto.ClientManagerLifecycleInputFromDomain(input)) } // runClientManagerLifecycleChunk godoc // @Summary Read one fenced Client Manager artifact chunk // @Description Streams a checksummed artifact chunk only to the active typed lifecycle job lease. // @Tags run-job-channel // @Accept json // @Produce json // @Param body body dto.RunUpdateChunkRequest true "Fenced chunk request" // @Success 200 {object} dto.RunUpdateChunkResponse // @Failure 400 {object} dto.ErrorResponse // @Failure 401 {object} dto.ErrorResponse // @Router /api/v1/run/jobs/client-manager-chunk [post] func (h *coreHandlers) runClientManagerLifecycleChunk(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { writeMethodNotAllowed(w, http.MethodPost) return } request, err := decodeJSON[dto.RunUpdateChunkRequest](r) if err != nil { writeDecodeError(w, err) return } chunk, err := h.core.ReadClientManagerLifecycleChunk(request.ToDomain()) if err != nil { writeServiceError(w, err) return } writeJSON(w, http.StatusOK, dto.RunUpdateChunkFromDomain(chunk)) } // clientManagerRegister godoc // @Summary Register an installed Client Manager component // @Description Verifies a current component-key HMAC, nonce, deployment fence, target, revision, and capabilities before issuing an isolated expiring component session. // @Tags client-manager-component // @Accept json // @Produce json // @Param body body dto.ClientManagerRegisterRequest true "Signed component registration" // @Success 200 {object} dto.ClientManagerRegisterResponse // @Failure 400 {object} dto.ErrorResponse // @Failure 401 {object} dto.ErrorResponse // @Router /api/v1/client-managers/register [post] func (h *coreHandlers) clientManagerRegister(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { writeMethodNotAllowed(w, http.MethodPost) return } request, err := decodeJSON[dto.ClientManagerRegisterRequest](r) if err != nil { writeDecodeError(w, err) return } result, err := h.core.RegisterClientManager(request.ToDomain()) if err != nil { writeServiceError(w, err) return } writeJSON(w, http.StatusOK, dto.ClientManagerRegisterFromDomain(result)) } // clientManagerHeartbeat godoc // @Summary Accept a Client Manager component heartbeat // @Description Accepts monotonic health reports using the isolated component session; Run control credentials are not valid here. // @Tags client-manager-component // @Accept json // @Produce json // @Param body body dto.ClientManagerHeartbeatRequest true "Component heartbeat" // @Success 200 {object} dto.ClientManagerHeartbeatResponse // @Failure 400 {object} dto.ErrorResponse // @Failure 401 {object} dto.ErrorResponse // @Router /api/v1/client-managers/heartbeat [post] func (h *coreHandlers) clientManagerHeartbeat(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { writeMethodNotAllowed(w, http.MethodPost) return } request, err := decodeJSON[dto.ClientManagerHeartbeatRequest](r) if err != nil { writeDecodeError(w, err) return } result, err := h.core.AcceptClientManagerHeartbeat(request.ToDomain()) if err != nil { writeServiceError(w, err) return } writeJSON(w, http.StatusOK, dto.ClientManagerHeartbeatFromDomain(result)) }