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 }