package tasks import ( "errors" "fmt" "gorm.io/gorm" "senlinai-agent/backend/internal/models" ) type Service struct { } type LinkedObject struct { ObjectType string `json:"object_type"` ObjectID uint `json:"object_id"` } func NewService() *Service { return &Service{} } func (s *Service) Assign(taskID uint, assigneeID uint) error { return models.DBService.Transaction(func(tx *gorm.DB) error { var task models.SenlinAgentTask if err := tx.First(&task, taskID).Error; err != nil { return err } if err := tx.Model(&task).Update("assignee_id", assigneeID).Error; err != nil { return err } return tx.Create(&models.SenlinAgentProjectEvent{ ProjectID: task.ProjectID, ActorID: task.CreatedBy, EventType: "task_assigned", EntityType: "task", EntityID: task.ID, Summary: fmt.Sprintf("Task assigned to user %d", assigneeID), }).Error }) } func (s *Service) ShareObject(taskID uint, objectType string, objectID uint) error { if objectType != "note" && objectType != "source" { return errors.New("unsupported shared object type") } return models.DBService.Transaction(func(tx *gorm.DB) error { var task models.SenlinAgentTask if err := tx.First(&task, taskID).Error; err != nil { return err } if err := ensureSharedObjectInProject(tx, task.ProjectID, objectType, objectID); err != nil { return err } if err := tx.Create(&models.SenlinAgentTaskShare{TaskID: taskID, ObjectType: objectType, ObjectID: objectID}).Error; err != nil { return err } return tx.Create(&models.SenlinAgentProjectEvent{ ProjectID: task.ProjectID, ActorID: task.CreatedBy, EventType: "task_object_shared", EntityType: "task", EntityID: task.ID, Summary: fmt.Sprintf("Shared %s %d with task", objectType, objectID), }).Error }) } func (s *Service) VisibleLinkedObjects(taskID uint, viewerID uint) ([]LinkedObject, error) { var task models.SenlinAgentTask if err := models.DBService.First(&task, taskID).Error; err != nil { return nil, err } if task.AssigneeID == nil || *task.AssigneeID != viewerID { return []LinkedObject{}, nil } var shares []models.SenlinAgentTaskShare if err := models.DBService.Where("task_id = ?", taskID).Find(&shares).Error; err != nil { return nil, err } objects := make([]LinkedObject, 0, len(shares)) for _, share := range shares { objects = append(objects, LinkedObject{ObjectType: share.ObjectType, ObjectID: share.ObjectID}) } return objects, nil } func ensureSharedObjectInProject(tx *gorm.DB, projectID uint, objectType string, objectID uint) error { switch objectType { case "note": var count int64 if err := tx.Model(&models.SenlinAgentNote{}).Where("id = ? AND project_id = ?", objectID, projectID).Count(&count).Error; err != nil { return err } if count == 0 { return errors.New("shared object not found in task project") } case "source": var count int64 if err := tx.Model(&models.SenlinAgentSource{}).Where("id = ? AND project_id = ?", objectID, projectID).Count(&count).Error; err != nil { return err } if count == 0 { return errors.New("shared object not found in task project") } } return nil }