chore(api)!: added new fields to contract
This commit is contained in:
@@ -32,6 +32,7 @@ message Task {
|
|||||||
int32 max_points = 6;
|
int32 max_points = 6;
|
||||||
int32 max_attempts = 7;
|
int32 max_attempts = 7;
|
||||||
TaskType type = 8;
|
TaskType type = 8;
|
||||||
|
string answer_url = 11;
|
||||||
google.protobuf.Timestamp created_at = 9;
|
google.protobuf.Timestamp created_at = 9;
|
||||||
google.protobuf.Timestamp updated_at = 10;
|
google.protobuf.Timestamp updated_at = 10;
|
||||||
}
|
}
|
||||||
@@ -39,7 +40,8 @@ message Task {
|
|||||||
message TaskAttachment {
|
message TaskAttachment {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
string file_url = 2;
|
string file_url = 2;
|
||||||
bool is_public = 3;
|
string mountpoint = 3;
|
||||||
|
bool is_public = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetTaskRequest {
|
message GetTaskRequest {
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ type TaskRequest struct {
|
|||||||
InCompetitionPosition int32 `json:"in_competition_position" validate:"required"`
|
InCompetitionPosition int32 `json:"in_competition_position" validate:"required"`
|
||||||
MaxPoints int32 `json:"max_points,omitempty"`
|
MaxPoints int32 `json:"max_points,omitempty"`
|
||||||
MaxAttempts int32 `json:"max_attempts,omitempty"`
|
MaxAttempts int32 `json:"max_attempts,omitempty"`
|
||||||
|
AnswerURL string `json:"answer_url,omitempty"`
|
||||||
Type string `json:"type" validate:"required,oneof=input checker review"`
|
Type string `json:"type" validate:"required,oneof=input checker review"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,6 +80,7 @@ type TaskResponse struct {
|
|||||||
InCompetitionPosition int32 `json:"in_competition_position"`
|
InCompetitionPosition int32 `json:"in_competition_position"`
|
||||||
MaxPoints int32 `json:"max_points,omitempty"`
|
MaxPoints int32 `json:"max_points,omitempty"`
|
||||||
MaxAttempts int32 `json:"max_attempts,omitempty"`
|
MaxAttempts int32 `json:"max_attempts,omitempty"`
|
||||||
|
AnswerURL string `json:"answer_url,omitempty"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
@@ -89,9 +91,10 @@ type ListTasksResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TaskAttachmentResponse struct {
|
type TaskAttachmentResponse struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
FileURL string `json:"file_url"`
|
FileURL string `json:"file_url"`
|
||||||
IsPublic bool `json:"is_public"`
|
Mountpoint string `json:"mountpoint,omitempty"`
|
||||||
|
IsPublic bool `json:"is_public"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubmissionResponse struct {
|
type SubmissionResponse struct {
|
||||||
|
|||||||
@@ -49,12 +49,22 @@ func TaskProtoToHTTP(t *taskpb.Task) *domain.TaskResponse {
|
|||||||
InCompetitionPosition: t.InCompetitionPosition,
|
InCompetitionPosition: t.InCompetitionPosition,
|
||||||
MaxPoints: t.MaxPoints,
|
MaxPoints: t.MaxPoints,
|
||||||
MaxAttempts: t.MaxAttempts,
|
MaxAttempts: t.MaxAttempts,
|
||||||
|
AnswerURL: t.AnswerUrl,
|
||||||
Type: TaskTypeToString(t.Type),
|
Type: TaskTypeToString(t.Type),
|
||||||
CreatedAt: t.CreatedAt.AsTime(),
|
CreatedAt: t.CreatedAt.AsTime(),
|
||||||
UpdatedAt: t.UpdatedAt.AsTime(),
|
UpdatedAt: t.UpdatedAt.AsTime(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TaskAttachmentProtoToHTTP(a *taskpb.TaskAttachment) *domain.TaskAttachmentResponse {
|
||||||
|
return &domain.TaskAttachmentResponse{
|
||||||
|
ID: a.Id,
|
||||||
|
FileURL: a.FileUrl,
|
||||||
|
Mountpoint: a.Mountpoint,
|
||||||
|
IsPublic: a.IsPublic,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func SubmissionProtoToHTTP(s *subpb.Submission) *domain.SubmissionResponse {
|
func SubmissionProtoToHTTP(s *subpb.Submission) *domain.SubmissionResponse {
|
||||||
return &domain.SubmissionResponse{
|
return &domain.SubmissionResponse{
|
||||||
ID: s.Id,
|
ID: s.Id,
|
||||||
@@ -150,6 +160,7 @@ func TaskHTTPToProto(req *domain.TaskRequest) *taskpb.Task {
|
|||||||
InCompetitionPosition: req.InCompetitionPosition,
|
InCompetitionPosition: req.InCompetitionPosition,
|
||||||
MaxPoints: req.MaxPoints,
|
MaxPoints: req.MaxPoints,
|
||||||
MaxAttempts: req.MaxAttempts,
|
MaxAttempts: req.MaxAttempts,
|
||||||
|
AnswerUrl: req.AnswerURL,
|
||||||
Type: StringToTaskType(req.Type),
|
Type: StringToTaskType(req.Type),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ func NewTaskRepository(db *sqlx.DB) *TaskRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *TaskRepository) CreateTask(ctx context.Context, t *task.Task) (*task.Task, error) {
|
func (r *TaskRepository) CreateTask(ctx context.Context, t *task.Task) (*task.Task, error) {
|
||||||
query := `INSERT INTO tasks (competition_id, title, description, in_competition_position, max_points, max_attempts, type)
|
query := `INSERT INTO tasks (competition_id, title, description, in_competition_position, max_points, max_attempts, type, answer_url)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id, created_at, updated_at`
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id, created_at, updated_at`
|
||||||
|
|
||||||
var createdTask task.Task
|
var createdTask task.Task
|
||||||
err := r.db.QueryRowxContext(ctx, query, t.CompetitionId, t.Title, t.Description, t.InCompetitionPosition, t.MaxPoints, t.MaxAttempts, t.Type).
|
err := r.db.QueryRowxContext(ctx, query, t.CompetitionId, t.Title, t.Description, t.InCompetitionPosition, t.MaxPoints, t.MaxAttempts, t.Type, t.AnswerUrl).
|
||||||
StructScan(&createdTask)
|
StructScan(&createdTask)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -33,6 +33,7 @@ func (r *TaskRepository) CreateTask(ctx context.Context, t *task.Task) (*task.Ta
|
|||||||
createdTask.MaxPoints = t.MaxPoints
|
createdTask.MaxPoints = t.MaxPoints
|
||||||
createdTask.MaxAttempts = t.MaxAttempts
|
createdTask.MaxAttempts = t.MaxAttempts
|
||||||
createdTask.Type = t.Type
|
createdTask.Type = t.Type
|
||||||
|
createdTask.AnswerUrl = t.AnswerUrl
|
||||||
return &createdTask, nil
|
return &createdTask, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,11 +44,11 @@ func (r *TaskRepository) GetTask(ctx context.Context, id string) (*task.Task, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *TaskRepository) EditTask(ctx context.Context, t *task.Task) (*task.Task, error) {
|
func (r *TaskRepository) EditTask(ctx context.Context, t *task.Task) (*task.Task, error) {
|
||||||
query := `UPDATE tasks SET title = $1, description = $2, in_competition_position = $3, max_points = $4, max_attempts = $5, type = $6, updated_at = now()
|
query := `UPDATE tasks SET title = $1, description = $2, in_competition_position = $3, max_points = $4, max_attempts = $5, type = $6, answer_url = $7, updated_at = now()
|
||||||
WHERE id = $7 RETURNING updated_at`
|
WHERE id = $8 RETURNING updated_at`
|
||||||
|
|
||||||
var updatedTask task.Task
|
var updatedTask task.Task
|
||||||
err := r.db.QueryRowxContext(ctx, query, t.Title, t.Description, t.InCompetitionPosition, t.MaxPoints, t.MaxAttempts, t.Type, t.Id).
|
err := r.db.QueryRowxContext(ctx, query, t.Title, t.Description, t.InCompetitionPosition, t.MaxPoints, t.MaxAttempts, t.Type, t.AnswerUrl, t.Id).
|
||||||
StructScan(&updatedTask)
|
StructScan(&updatedTask)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ func TestTaskService(t *testing.T) {
|
|||||||
InCompetitionPosition: 1,
|
InCompetitionPosition: 1,
|
||||||
MaxPoints: 100,
|
MaxPoints: 100,
|
||||||
MaxAttempts: 10,
|
MaxAttempts: 10,
|
||||||
|
AnswerUrl: "https://example.com/answer",
|
||||||
Type: pb.TaskType_TASK_TYPE_INPUT,
|
Type: pb.TaskType_TASK_TYPE_INPUT,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,6 +52,7 @@ func TestTaskService(t *testing.T) {
|
|||||||
InCompetitionPosition: 1,
|
InCompetitionPosition: 1,
|
||||||
MaxPoints: 100,
|
MaxPoints: 100,
|
||||||
MaxAttempts: 10,
|
MaxAttempts: 10,
|
||||||
|
AnswerUrl: "https://example.com/answer",
|
||||||
Type: pb.TaskType_TASK_TYPE_INPUT,
|
Type: pb.TaskType_TASK_TYPE_INPUT,
|
||||||
CreatedAt: timestamppb.Now(),
|
CreatedAt: timestamppb.Now(),
|
||||||
UpdatedAt: timestamppb.Now(),
|
UpdatedAt: timestamppb.Now(),
|
||||||
@@ -72,6 +74,7 @@ func TestTaskService(t *testing.T) {
|
|||||||
InCompetitionPosition: 1,
|
InCompetitionPosition: 1,
|
||||||
MaxPoints: 150,
|
MaxPoints: 150,
|
||||||
MaxAttempts: 5,
|
MaxAttempts: 5,
|
||||||
|
AnswerUrl: "https://example.com/answer-updated",
|
||||||
Type: pb.TaskType_TASK_TYPE_CHECKER,
|
Type: pb.TaskType_TASK_TYPE_CHECKER,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,8 +115,8 @@ func TestTaskService(t *testing.T) {
|
|||||||
showPrivate := true
|
showPrivate := true
|
||||||
req := &pb.GetTaskAttachmentsRequest{TaskId: taskID, ShowPrivate: &showPrivate}
|
req := &pb.GetTaskAttachmentsRequest{TaskId: taskID, ShowPrivate: &showPrivate}
|
||||||
expectedAttachments := []*pb.TaskAttachment{
|
expectedAttachments := []*pb.TaskAttachment{
|
||||||
{Id: "att1", FileUrl: "url1", IsPublic: true},
|
{Id: "att1", FileUrl: "url1", Mountpoint: "mp1", IsPublic: true},
|
||||||
{Id: "att2", FileUrl: "url2", IsPublic: false},
|
{Id: "att2", FileUrl: "url2", Mountpoint: "mp2", IsPublic: false},
|
||||||
}
|
}
|
||||||
|
|
||||||
mockRepo.EXPECT().GetTaskAttachments(ctx, taskID, showPrivate).Return(expectedAttachments, nil)
|
mockRepo.EXPECT().GetTaskAttachments(ctx, taskID, showPrivate).Return(expectedAttachments, nil)
|
||||||
@@ -128,7 +131,7 @@ func TestTaskService(t *testing.T) {
|
|||||||
showPrivate := false
|
showPrivate := false
|
||||||
req := &pb.GetTaskAttachmentsRequest{TaskId: taskID, ShowPrivate: &showPrivate}
|
req := &pb.GetTaskAttachmentsRequest{TaskId: taskID, ShowPrivate: &showPrivate}
|
||||||
expectedAttachments := []*pb.TaskAttachment{
|
expectedAttachments := []*pb.TaskAttachment{
|
||||||
{Id: "att1", FileUrl: "url1", IsPublic: true},
|
{Id: "att1", FileUrl: "url1", Mountpoint: "mp1", IsPublic: true},
|
||||||
}
|
}
|
||||||
|
|
||||||
mockRepo.EXPECT().GetTaskAttachments(ctx, taskID, showPrivate).Return(expectedAttachments, nil)
|
mockRepo.EXPECT().GetTaskAttachments(ctx, taskID, showPrivate).Return(expectedAttachments, nil)
|
||||||
|
|||||||
+27
-6
@@ -85,6 +85,7 @@ type Task struct {
|
|||||||
MaxPoints int32 `protobuf:"varint,6,opt,name=max_points,json=maxPoints,proto3" json:"max_points,omitempty"`
|
MaxPoints int32 `protobuf:"varint,6,opt,name=max_points,json=maxPoints,proto3" json:"max_points,omitempty"`
|
||||||
MaxAttempts int32 `protobuf:"varint,7,opt,name=max_attempts,json=maxAttempts,proto3" json:"max_attempts,omitempty"`
|
MaxAttempts int32 `protobuf:"varint,7,opt,name=max_attempts,json=maxAttempts,proto3" json:"max_attempts,omitempty"`
|
||||||
Type TaskType `protobuf:"varint,8,opt,name=type,proto3,enum=task.TaskType" json:"type,omitempty"`
|
Type TaskType `protobuf:"varint,8,opt,name=type,proto3,enum=task.TaskType" json:"type,omitempty"`
|
||||||
|
AnswerUrl string `protobuf:"bytes,11,opt,name=answer_url,json=answerUrl,proto3" json:"answer_url,omitempty"`
|
||||||
CreatedAt *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
CreatedAt *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||||
UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
|
UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
@@ -177,6 +178,13 @@ func (x *Task) GetType() TaskType {
|
|||||||
return TaskType_TASK_TYPE_UNSPECIFIED
|
return TaskType_TASK_TYPE_UNSPECIFIED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *Task) GetAnswerUrl() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.AnswerUrl
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func (x *Task) GetCreatedAt() *timestamppb.Timestamp {
|
func (x *Task) GetCreatedAt() *timestamppb.Timestamp {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.CreatedAt
|
return x.CreatedAt
|
||||||
@@ -195,7 +203,8 @@ type TaskAttachment struct {
|
|||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||||
FileUrl string `protobuf:"bytes,2,opt,name=file_url,json=fileUrl,proto3" json:"file_url,omitempty"`
|
FileUrl string `protobuf:"bytes,2,opt,name=file_url,json=fileUrl,proto3" json:"file_url,omitempty"`
|
||||||
IsPublic bool `protobuf:"varint,3,opt,name=is_public,json=isPublic,proto3" json:"is_public,omitempty"`
|
Mountpoint string `protobuf:"bytes,3,opt,name=mountpoint,proto3" json:"mountpoint,omitempty"`
|
||||||
|
IsPublic bool `protobuf:"varint,4,opt,name=is_public,json=isPublic,proto3" json:"is_public,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
@@ -244,6 +253,13 @@ func (x *TaskAttachment) GetFileUrl() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *TaskAttachment) GetMountpoint() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Mountpoint
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func (x *TaskAttachment) GetIsPublic() bool {
|
func (x *TaskAttachment) GetIsPublic() bool {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.IsPublic
|
return x.IsPublic
|
||||||
@@ -527,7 +543,7 @@ var File_api_proto_task_proto protoreflect.FileDescriptor
|
|||||||
|
|
||||||
const file_api_proto_task_proto_rawDesc = "" +
|
const file_api_proto_task_proto_rawDesc = "" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"\x14api/proto/task.proto\x12\x04task\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1bgoogle/protobuf/empty.proto\"\x89\x03\n" +
|
"\x14api/proto/task.proto\x12\x04task\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1bgoogle/protobuf/empty.proto\"\xa8\x03\n" +
|
||||||
"\x04Task\x12\x0e\n" +
|
"\x04Task\x12\x0e\n" +
|
||||||
"\x02id\x18\x01 \x01(\tR\x02id\x12%\n" +
|
"\x02id\x18\x01 \x01(\tR\x02id\x12%\n" +
|
||||||
"\x0ecompetition_id\x18\x02 \x01(\tR\rcompetitionId\x12\x14\n" +
|
"\x0ecompetition_id\x18\x02 \x01(\tR\rcompetitionId\x12\x14\n" +
|
||||||
@@ -537,16 +553,21 @@ const file_api_proto_task_proto_rawDesc = "" +
|
|||||||
"\n" +
|
"\n" +
|
||||||
"max_points\x18\x06 \x01(\x05R\tmaxPoints\x12!\n" +
|
"max_points\x18\x06 \x01(\x05R\tmaxPoints\x12!\n" +
|
||||||
"\fmax_attempts\x18\a \x01(\x05R\vmaxAttempts\x12\"\n" +
|
"\fmax_attempts\x18\a \x01(\x05R\vmaxAttempts\x12\"\n" +
|
||||||
"\x04type\x18\b \x01(\x0e2\x0e.task.TaskTypeR\x04type\x129\n" +
|
"\x04type\x18\b \x01(\x0e2\x0e.task.TaskTypeR\x04type\x12\x1d\n" +
|
||||||
|
"\n" +
|
||||||
|
"answer_url\x18\v \x01(\tR\tanswerUrl\x129\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"created_at\x18\t \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" +
|
"created_at\x18\t \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"updated_at\x18\n" +
|
"updated_at\x18\n" +
|
||||||
" \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\"X\n" +
|
" \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\"x\n" +
|
||||||
"\x0eTaskAttachment\x12\x0e\n" +
|
"\x0eTaskAttachment\x12\x0e\n" +
|
||||||
"\x02id\x18\x01 \x01(\tR\x02id\x12\x19\n" +
|
"\x02id\x18\x01 \x01(\tR\x02id\x12\x19\n" +
|
||||||
"\bfile_url\x18\x02 \x01(\tR\afileUrl\x12\x1b\n" +
|
"\bfile_url\x18\x02 \x01(\tR\afileUrl\x12\x1e\n" +
|
||||||
"\tis_public\x18\x03 \x01(\bR\bisPublic\")\n" +
|
"\n" +
|
||||||
|
"mountpoint\x18\x03 \x01(\tR\n" +
|
||||||
|
"mountpoint\x12\x1b\n" +
|
||||||
|
"\tis_public\x18\x04 \x01(\bR\bisPublic\")\n" +
|
||||||
"\x0eGetTaskRequest\x12\x17\n" +
|
"\x0eGetTaskRequest\x12\x17\n" +
|
||||||
"\atask_id\x18\x01 \x01(\tR\x06taskId\",\n" +
|
"\atask_id\x18\x01 \x01(\tR\x06taskId\",\n" +
|
||||||
"\x11DeleteTaskRequest\x12\x17\n" +
|
"\x11DeleteTaskRequest\x12\x17\n" +
|
||||||
|
|||||||
Reference in New Issue
Block a user