68 lines
2.1 KiB
Go
68 lines
2.1 KiB
Go
package github
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
|
|
"github.com/kandev/kandev/internal/events"
|
|
"github.com/kandev/kandev/internal/events/bus"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
var ErrTaskPRNotFound = errors.New("github task PR not found")
|
|
|
|
// TaskPRDeletedEvent identifies one task-PR association removed from active
|
|
// task surfaces. The remote GitHub pull request is intentionally untouched.
|
|
type TaskPRDeletedEvent struct {
|
|
WorkspaceID string `json:"workspace_id"`
|
|
TaskID string `json:"task_id"`
|
|
AssociationID string `json:"association_id"`
|
|
}
|
|
|
|
// GetWorkspaceID lets the websocket broadcaster route the typed event to the
|
|
// owning workspace instead of treating it as an instance-wide notification.
|
|
func (e TaskPRDeletedEvent) GetWorkspaceID() string { return e.WorkspaceID }
|
|
|
|
// DetachTaskPR removes one association from active task views while retaining
|
|
// a durable tombstone that prevents background discovery from resurrecting it.
|
|
func (s *Service) DetachTaskPR(ctx context.Context, workspaceID, associationID string) (*TaskPR, error) {
|
|
if strings.TrimSpace(workspaceID) == "" || strings.TrimSpace(associationID) == "" {
|
|
return nil, ErrTaskPRNotFound
|
|
}
|
|
tp, err := s.store.GetTaskPRByID(ctx, associationID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if tp == nil || (tp.WorkspaceID != "" && tp.WorkspaceID != workspaceID) {
|
|
return nil, ErrTaskPRNotFound
|
|
}
|
|
if err := s.authorizeWorkspaceAccess(ctx, workspaceID); err != nil {
|
|
return nil, err
|
|
}
|
|
if tp.DetachedAt != nil {
|
|
return tp, nil
|
|
}
|
|
detached, transitioned, err := s.store.DetachTaskPR(ctx, associationID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if detached == nil {
|
|
return nil, ErrTaskPRNotFound
|
|
}
|
|
if !transitioned {
|
|
return detached, nil
|
|
}
|
|
if s.eventBus != nil {
|
|
event := bus.NewEvent(events.GitHubTaskPRDeleted, "github", &TaskPRDeletedEvent{
|
|
WorkspaceID: workspaceID,
|
|
TaskID: detached.TaskID,
|
|
AssociationID: detached.ID,
|
|
})
|
|
if err := s.eventBus.Publish(ctx, events.GitHubTaskPRDeleted, event); err != nil {
|
|
s.logger.Debug("failed to publish task PR deleted event", zap.Error(err))
|
|
}
|
|
}
|
|
return detached, nil
|
|
}
|