package projects import ( "errors" "strings" "gorm.io/gorm" "senlinai-agent/backend/internal/domain" ) type Service struct { db *gorm.DB } type Dashboard struct { ProjectID uint `json:"project_id"` PendingInboxCount int64 `json:"pending_inbox_count"` OpenTaskCount int64 `json:"open_task_count"` RecentNoteCount int64 `json:"recent_note_count"` RecentSessionCount int64 `json:"recent_session_count"` } func NewService(database *gorm.DB) *Service { return &Service{db: database} } func (s *Service) CreateProject(ownerID uint, name string, description string) (*domain.Project, error) { name = strings.TrimSpace(name) if name == "" { return nil, errors.New("project name is required") } project := &domain.Project{OwnerID: ownerID, Name: name, Description: description} return project, s.db.Create(project).Error } func (s *Service) ListProjects(ownerID uint) ([]domain.Project, error) { var projects []domain.Project err := s.db.Where("owner_id = ?", ownerID).Order("updated_at desc").Find(&projects).Error return projects, err } func (s *Service) CreateTag(projectID uint, name string) (*domain.Tag, error) { name = strings.TrimSpace(name) if name == "" { return nil, errors.New("tag name is required") } tag := &domain.Tag{ProjectID: projectID, Name: name} return tag, s.db.Create(tag).Error } func (s *Service) ListTags(projectID uint) ([]domain.Tag, error) { var tags []domain.Tag err := s.db.Where("project_id = ?", projectID).Order("name asc").Find(&tags).Error return tags, err } func (s *Service) Dashboard(ownerID uint, projectID uint) (Dashboard, error) { var project domain.Project if err := s.db.Where("id = ? AND owner_id = ?", projectID, ownerID).First(&project).Error; err != nil { return Dashboard{}, err } dashboard := Dashboard{ProjectID: projectID} if err := s.db.Model(&domain.InboxItem{}).Where("project_id = ? AND status = ?", projectID, "open").Count(&dashboard.PendingInboxCount).Error; err != nil { return dashboard, err } if err := s.db.Model(&domain.Task{}).Where("project_id = ? AND status <> ?", projectID, "done").Count(&dashboard.OpenTaskCount).Error; err != nil { return dashboard, err } if err := s.db.Model(&domain.Note{}).Where("project_id = ?", projectID).Count(&dashboard.RecentNoteCount).Error; err != nil { return dashboard, err } if err := s.db.Model(&domain.AISession{}).Where("project_id = ?", projectID).Count(&dashboard.RecentSessionCount).Error; err != nil { return dashboard, err } return dashboard, nil }