-
Notifications
You must be signed in to change notification settings - Fork 0
/
solution_usecase.go
172 lines (146 loc) · 4.15 KB
/
solution_usecase.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package usecases
import (
"github.com/pkg/errors"
"github.com/thewizardplusplus/go-exercises-backend/entities"
"gorm.io/gorm"
)
// SolutionStorage ...
type SolutionStorage interface {
entities.SolutionGetter
GetSolutions(userID uint, taskID uint, pagination entities.Pagination) (
[]entities.Solution,
error,
)
CountSolutions(userID uint, taskID uint) (int64, error)
CreateSolution(taskID uint, solution entities.Solution) (id uint, err error)
UpdateSolution(id uint, solution entities.Solution) error
}
// SolutionQueue ...
type SolutionQueue interface {
EnqueueSolution(solution entities.Solution) error
}
// SolutionUsecase ...
type SolutionUsecase struct {
TaskGetter entities.TaskGetter
SolutionStorage SolutionStorage
SolutionRegister entities.SolutionRegister
SolutionQueue SolutionQueue
}
// GetSolutions ...
func (usecase SolutionUsecase) GetSolutions(
userID uint,
taskID uint,
pagination entities.Pagination,
) (
entities.SolutionGroup,
error,
) {
solutions, err :=
usecase.SolutionStorage.GetSolutions(userID, taskID, pagination)
if err != nil {
return entities.SolutionGroup{},
errors.Wrap(err, "unable to get the solutions")
}
solutionCount, err := usecase.SolutionStorage.CountSolutions(userID, taskID)
if err != nil {
return entities.SolutionGroup{},
errors.Wrap(err, "unable to count the solutions")
}
solutionGroup :=
entities.SolutionGroup{Solutions: solutions, TotalCount: solutionCount}
for index := range solutionGroup.Solutions {
solutionGroup.Solutions[index].User.PasswordHash = ""
}
return solutionGroup, nil
}
// GetSolution ...
func (usecase SolutionUsecase) GetSolution(
userID uint,
solutionID uint,
) (
entities.Solution,
error,
) {
if err := usecase.checkAccessToSolution(userID, solutionID); err != nil {
return entities.Solution{},
errors.Wrap(err, "unable to check access to the solution")
}
solution, err := usecase.SolutionStorage.GetSolution(solutionID)
if err != nil {
return entities.Solution{}, errors.Wrap(err, "unable to get the solution")
}
solution.User.PasswordHash = ""
return solution, nil
}
// CreateSolution ...
func (usecase SolutionUsecase) CreateSolution(
userID uint,
taskID uint,
solution entities.Solution,
) (
entities.Solution,
error,
) {
solution.UserID = userID
if err := solution.FormatCode(); err != nil {
return entities.Solution{}, errors.Wrap(err, "unable to format the code")
}
id, err := usecase.SolutionStorage.CreateSolution(taskID, solution)
if err != nil {
return entities.Solution{}, errors.Wrap(err, "unable to create the solution")
}
usecase.SolutionRegister.RegisterSolution(id)
idAsModel := entities.Solution{Model: gorm.Model{ID: id}}
return idAsModel, nil
}
// RegisterSolution ...
func (usecase SolutionUsecase) RegisterSolution(id uint) error {
solution, err := usecase.SolutionStorage.GetSolution(id)
if err != nil {
return errors.Wrap(err, "unable to get the solution")
}
task, err := usecase.TaskGetter.GetTask(
0, // user does not matter
solution.TaskID,
)
if err != nil {
return errors.Wrap(err, "unable to get the task")
}
solution.Task = task
if err := usecase.SolutionQueue.EnqueueSolution(solution); err != nil {
return errors.Wrap(err, "unable to enqueue the solution")
}
return nil
}
// RegisterSolutionResult ...
func (usecase SolutionUsecase) RegisterSolutionResult(
solution entities.Solution,
) error {
// update only these specific fields
solutionUpdate := entities.Solution{
IsCorrect: solution.IsCorrect,
Result: solution.Result,
}
err := usecase.SolutionStorage.UpdateSolution(solution.ID, solutionUpdate)
if err != nil {
return errors.Wrap(err, "unable to update the solution")
}
return nil
}
func (usecase SolutionUsecase) checkAccessToSolution(
userID uint,
solutionID uint,
) error {
solution, err := usecase.SolutionStorage.GetSolution(solutionID)
if err != nil {
return errors.Wrap(err, "unable to get the solution")
}
task, err := usecase.TaskGetter.GetTask(userID, solution.TaskID)
if err != nil {
return errors.Wrap(err, "unable to get the task")
}
if userID != solution.UserID && userID != task.UserID {
return entities.ErrManagerialAccessIsDenied
}
return nil
}