| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- package service
- import (
- "context"
- "encoding/json"
- "net/http"
- "cmr-backend/internal/apperr"
- "cmr-backend/internal/store/postgres"
- )
- type ResultService struct {
- store *postgres.Store
- }
- type SessionResultView struct {
- Session EntrySessionSummary `json:"session"`
- Result ResultSummaryPayload `json:"result"`
- }
- type ResultSummaryPayload struct {
- Status string `json:"status"`
- FinalDurationSec *int `json:"finalDurationSec,omitempty"`
- FinalScore *int `json:"finalScore,omitempty"`
- CompletedControls *int `json:"completedControls,omitempty"`
- TotalControls *int `json:"totalControls,omitempty"`
- DistanceMeters *float64 `json:"distanceMeters,omitempty"`
- AverageSpeedKmh *float64 `json:"averageSpeedKmh,omitempty"`
- MaxHeartRateBpm *int `json:"maxHeartRateBpm,omitempty"`
- Summary map[string]any `json:"summary,omitempty"`
- }
- func NewResultService(store *postgres.Store) *ResultService {
- return &ResultService{store: store}
- }
- func (s *ResultService) GetSessionResult(ctx context.Context, sessionPublicID, userID string) (*SessionResultView, error) {
- record, err := s.store.GetSessionResultByPublicID(ctx, sessionPublicID)
- if err != nil {
- return nil, err
- }
- if record == nil {
- return nil, apperr.New(http.StatusNotFound, "session_not_found", "session not found")
- }
- if userID != "" && record.UserID != userID {
- return nil, apperr.New(http.StatusForbidden, "session_forbidden", "session does not belong to current user")
- }
- return buildSessionResultView(record), nil
- }
- func (s *ResultService) ListMyResults(ctx context.Context, userID string, limit int) ([]SessionResultView, error) {
- if userID == "" {
- return nil, apperr.New(http.StatusUnauthorized, "unauthorized", "user is required")
- }
- records, err := s.store.ListSessionResultsByUserID(ctx, userID, limit)
- if err != nil {
- return nil, err
- }
- results := make([]SessionResultView, 0, len(records))
- for i := range records {
- results = append(results, *buildSessionResultView(&records[i]))
- }
- return results, nil
- }
- func buildSessionResultView(record *postgres.SessionResultRecord) *SessionResultView {
- view := &SessionResultView{
- Session: buildEntrySessionSummary(&record.Session),
- Result: ResultSummaryPayload{
- Status: record.Status,
- },
- }
- if record.Result != nil {
- view.Result.Status = record.Result.ResultStatus
- view.Result.FinalDurationSec = record.Result.FinalDurationSec
- view.Result.FinalScore = record.Result.FinalScore
- view.Result.CompletedControls = record.Result.CompletedControls
- view.Result.TotalControls = record.Result.TotalControls
- view.Result.DistanceMeters = record.Result.DistanceMeters
- view.Result.AverageSpeedKmh = record.Result.AverageSpeedKmh
- view.Result.MaxHeartRateBpm = record.Result.MaxHeartRateBpm
- if record.Result.SummaryJSON != "" {
- summary := map[string]any{}
- if err := json.Unmarshal([]byte(record.Result.SummaryJSON), &summary); err == nil && len(summary) > 0 {
- view.Result.Summary = summary
- }
- }
- }
- return view
- }
|