Yimaru-BackEnd/internal/services/issue_reporting/service.go

114 lines
3.3 KiB
Go

package issuereporting
import (
"context"
"encoding/json"
"errors"
dbgen "Yimaru-Backend/gen/db"
"Yimaru-Backend/internal/domain"
"Yimaru-Backend/internal/repository"
)
type Service struct {
repo repository.ReportedIssueRepository
}
func New(repo repository.ReportedIssueRepository) *Service {
return &Service{repo: repo}
}
func (s *Service) CreateReportedIssue(ctx context.Context, issue domain.ReportedIssueReq, userID int64, role domain.Role) (domain.ReportedIssue, error) {
var metadata []byte
if issue.Metadata != nil {
var err error
metadata, err = json.Marshal(issue.Metadata)
if err != nil {
return domain.ReportedIssue{}, err
}
}
params := dbgen.CreateReportedIssueParams{
UserID: userID,
UserRole: string(role),
Subject: issue.Subject,
Description: issue.Description,
IssueType: string(issue.IssueType),
Metadata: metadata,
}
dbIssue, err := s.repo.CreateReportedIssue(ctx, params)
if err != nil {
return domain.ReportedIssue{}, err
}
return mapDBIssueToDomain(dbIssue), nil
}
func (s *Service) GetIssuesForUser(ctx context.Context, userID int64, limit, offset int) ([]domain.ReportedIssue, error) {
dbIssues, err := s.repo.ListReportedIssuesByUser(ctx, userID, int32(limit), int32(offset))
if err != nil {
return nil, err
}
return mapDBIssuesToDomain(dbIssues), nil
}
func (s *Service) GetAllIssues(ctx context.Context, limit, offset int) ([]domain.ReportedIssue, error) {
dbIssues, err := s.repo.ListReportedIssues(ctx, int32(limit), int32(offset))
if err != nil {
return nil, err
}
return mapDBIssuesToDomain(dbIssues), nil
}
func (s *Service) GetIssueByID(ctx context.Context, issueID int64) (domain.ReportedIssue, error) {
dbIssue, err := s.repo.GetReportedIssueByID(ctx, issueID)
if err != nil {
return domain.ReportedIssue{}, err
}
return mapDBIssueToDomain(dbIssue), nil
}
func (s *Service) UpdateIssueStatus(ctx context.Context, issueID int64, status string) error {
validStatuses := map[string]bool{"pending": true, "in_progress": true, "resolved": true, "rejected": true}
if !validStatuses[status] {
return errors.New("invalid status")
}
return s.repo.UpdateReportedIssueStatus(ctx, issueID, status)
}
func (s *Service) CountAllIssues(ctx context.Context) (int64, error) {
return s.repo.CountReportedIssues(ctx)
}
func (s *Service) CountIssuesByUser(ctx context.Context, userID int64) (int64, error) {
return s.repo.CountReportedIssuesByUser(ctx, userID)
}
func (s *Service) DeleteIssue(ctx context.Context, issueID int64) error {
return s.repo.DeleteReportedIssue(ctx, issueID)
}
func mapDBIssueToDomain(dbIssue dbgen.ReportedIssue) domain.ReportedIssue {
issue := domain.ReportedIssue{
ID: dbIssue.ID,
Subject: dbIssue.Subject,
Description: dbIssue.Description,
UserID: dbIssue.UserID,
UserRole: domain.Role(dbIssue.UserRole),
Status: domain.ReportedIssueStatus(dbIssue.Status),
IssueType: domain.ReportedIssueType(dbIssue.IssueType),
CreatedAt: dbIssue.CreatedAt.Time,
UpdatedAt: dbIssue.UpdatedAt.Time,
}
if len(dbIssue.Metadata) > 0 {
_ = json.Unmarshal(dbIssue.Metadata, &issue.Metadata)
}
return issue
}
func mapDBIssuesToDomain(dbIssues []dbgen.ReportedIssue) []domain.ReportedIssue {
issues := make([]domain.ReportedIssue, len(dbIssues))
for i, dbIssue := range dbIssues {
issues[i] = mapDBIssueToDomain(dbIssue)
}
return issues
}