Skip to content

Commit c250fc9

Browse files
authored
Merge pull request #1585 from ictsc/feature/download-answer-by-contestant
feat: Add a button for downloading answers by contestants
2 parents 6bde72d + 1832fe5 commit c250fc9

File tree

13 files changed

+421
-51
lines changed

13 files changed

+421
-51
lines changed

backend/pkg/proto/contestant/v1/answer.pb.go

Lines changed: 153 additions & 38 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/pkg/proto/contestant/v1/contestantv1connect/answer.connect.go

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/scoreserver/contestant/answer.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type AnswerServiceHandler struct {
2121
Enforcer *ScheduleEnforcer
2222

2323
ListEffect ListAnswersEffect
24+
GetEffect GetAnswerEffect
2425
SubmitEffect SubmitAnswerEffect
2526
}
2627

@@ -31,6 +32,7 @@ func newAnswerServiceHandler(enforcer *ScheduleEnforcer, repo *pg.Repository) *A
3132
Enforcer: enforcer,
3233

3334
ListEffect: repo,
35+
GetEffect: repo,
3436
SubmitEffect: struct {
3537
domain.TeamMemberGetter
3638
domain.ProblemReader
@@ -102,6 +104,57 @@ func (h *AnswerServiceHandler) ListAnswers(
102104
return connect.NewResponse(resp), nil
103105
}
104106

107+
type GetAnswerEffect interface {
108+
domain.TeamMemberGetter
109+
domain.AnswerReader
110+
}
111+
112+
func (h *AnswerServiceHandler) GetAnswer(
113+
ctx context.Context,
114+
req *connect.Request[contestantv1.GetAnswerRequest],
115+
) (*connect.Response[contestantv1.GetAnswerResponse], error) {
116+
userSess, err := session.UserSessionStore.Get(ctx)
117+
if err != nil {
118+
if errors.Is(err, domain.ErrNotFound) {
119+
return nil, connect.NewError(connect.CodeUnauthenticated, nil)
120+
}
121+
return nil, err
122+
}
123+
if err := h.Enforcer.Enforce(ctx, domain.PhaseInContest); err != nil {
124+
return nil, err
125+
}
126+
127+
teamMember, err := domain.UserID(userSess.UserID).TeamMember(ctx, h.ListEffect)
128+
if err != nil {
129+
return nil, err
130+
}
131+
132+
protoProblemCode := req.Msg.GetProblemCode()
133+
if protoProblemCode == "" {
134+
return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("problem_code is required"))
135+
}
136+
problemCode, err := domain.NewProblemCode(protoProblemCode)
137+
if err != nil {
138+
return nil, err
139+
}
140+
141+
answerDetail, err := domain.GetAnswerDetailForPublic(ctx, h.ListEffect, teamMember.Team().Code(), problemCode, req.Msg.Id)
142+
if err != nil {
143+
return nil, err
144+
}
145+
146+
protoAnswer, err := convertAnswerDetail(answerDetail)
147+
if err != nil {
148+
return nil, err
149+
}
150+
151+
resp := &contestantv1.GetAnswerResponse{
152+
Answer: protoAnswer,
153+
}
154+
155+
return connect.NewResponse(resp), nil
156+
}
157+
105158
type SubmitAnswerEffect interface {
106159
domain.TeamMemberGetter
107160
domain.ProblemReader

0 commit comments

Comments
 (0)