2024-11-26 23:30:58 +00:00
|
|
|
package service
|
2024-11-26 23:28:48 +00:00
|
|
|
|
|
|
|
import (
|
2024-11-27 23:38:17 +00:00
|
|
|
"time"
|
2024-11-28 02:19:19 +00:00
|
|
|
"errors"
|
2024-11-26 23:28:48 +00:00
|
|
|
"context"
|
|
|
|
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
2024-11-27 23:38:17 +00:00
|
|
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
2024-11-28 00:38:22 +00:00
|
|
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
2024-11-26 23:28:48 +00:00
|
|
|
)
|
|
|
|
|
2024-11-28 02:19:19 +00:00
|
|
|
var (
|
|
|
|
// ErrInvalidSourceStatus current submission status cannot change to destination status
|
|
|
|
ErrInvalidSourceStatus = errors.New("Invalid source status")
|
|
|
|
// ErrPermissionDenied caller does not have the required role
|
|
|
|
ErrPermissionDenied = errors.New("Permission denied")
|
|
|
|
)
|
|
|
|
|
2024-11-26 23:28:48 +00:00
|
|
|
// POST /submissions
|
2024-11-27 23:38:17 +00:00
|
|
|
func (svc *Service) CreateSubmission(ctx context.Context, request api.OptSubmissionCreate) (*api.ID, error) {
|
|
|
|
submission, err := svc.DB.Submissions().Create(ctx, model.Submission{
|
|
|
|
ID: 0,
|
|
|
|
DisplayName: request.Value.DisplayName.Value,
|
|
|
|
Creator: request.Value.Creator.Value,
|
|
|
|
GameID: request.Value.GameID.Value,
|
|
|
|
Date: time.Now(),
|
|
|
|
Submitter: request.Value.Submitter.Value,
|
|
|
|
AssetID: request.Value.AssetID.Value,
|
|
|
|
AssetVersion: request.Value.AssetVersion.Value,
|
|
|
|
Completed: false,
|
|
|
|
TargetAssetID: request.Value.TargetAssetID.Value,
|
2024-11-28 01:59:29 +00:00
|
|
|
StatusID: model.StatusUnderConstruction,
|
2024-11-27 23:38:17 +00:00
|
|
|
})
|
|
|
|
if err != nil{
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &api.ID{
|
|
|
|
ID:api.NewOptInt64(submission.ID),
|
|
|
|
}, nil
|
2024-11-26 23:28:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetSubmission implements getSubmission operation.
|
|
|
|
//
|
|
|
|
// Retrieve map with ID.
|
|
|
|
//
|
|
|
|
// GET /submissions/{SubmissionID}
|
2024-11-26 23:30:58 +00:00
|
|
|
func (svc *Service) GetSubmission(ctx context.Context, params api.GetSubmissionParams) (*api.Submission, error) {
|
2024-11-26 23:55:56 +00:00
|
|
|
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
|
|
|
if err != nil{
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &api.Submission{
|
|
|
|
ID: api.NewOptInt64(submission.ID),
|
|
|
|
DisplayName: api.NewOptString(submission.DisplayName),
|
|
|
|
Creator: api.NewOptString(submission.Creator),
|
|
|
|
GameID: api.NewOptInt32(submission.GameID),
|
|
|
|
Date: api.NewOptInt64(submission.Date.Unix()),
|
|
|
|
Submitter: api.NewOptInt64(submission.Submitter),
|
|
|
|
AssetID: api.NewOptInt64(submission.AssetID),
|
|
|
|
AssetVersion: api.NewOptInt64(submission.AssetVersion),
|
|
|
|
Completed: api.NewOptBool(submission.Completed),
|
|
|
|
TargetAssetID: api.NewOptInt64(submission.TargetAssetID),
|
2024-11-28 01:27:22 +00:00
|
|
|
StatusID: api.NewOptInt32(int32(submission.StatusID)),
|
2024-11-26 23:55:56 +00:00
|
|
|
}, nil
|
2024-11-26 23:28:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ListSubmissions implements listSubmissions operation.
|
|
|
|
//
|
|
|
|
// Get list of submissions.
|
|
|
|
//
|
|
|
|
// GET /submissions
|
2024-11-28 00:38:22 +00:00
|
|
|
func (svc *Service) ListSubmissions(ctx context.Context, request api.ListSubmissionsParams) ([]api.Submission, error) {
|
|
|
|
filter := datastore.Optional()
|
|
|
|
//fmt.Println(request)
|
|
|
|
if request.Filter.IsSet() {
|
|
|
|
filter.AddNotNil("display_name", request.Filter.Value.DisplayName)
|
|
|
|
filter.AddNotNil("creator", request.Filter.Value.Creator)
|
|
|
|
filter.AddNotNil("game_id", request.Filter.Value.GameID)
|
|
|
|
}
|
|
|
|
|
|
|
|
items, err := svc.DB.Submissions().List(ctx, filter, model.Page{
|
|
|
|
Number: request.Page.GetPage(),
|
|
|
|
Size: request.Page.GetLimit(),
|
|
|
|
})
|
|
|
|
if err != nil{
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var resp []api.Submission
|
|
|
|
for i := 0; i < len(items); i++ {
|
|
|
|
resp = append(resp, api.Submission{
|
|
|
|
ID: api.NewOptInt64(items[i].ID),
|
|
|
|
DisplayName: api.NewOptString(items[i].DisplayName),
|
|
|
|
Creator: api.NewOptString(items[i].Creator),
|
|
|
|
GameID: api.NewOptInt32(items[i].GameID),
|
|
|
|
Date: api.NewOptInt64(items[i].Date.Unix()),
|
|
|
|
Submitter: api.NewOptInt64(items[i].Submitter),
|
|
|
|
AssetID: api.NewOptInt64(items[i].AssetID),
|
|
|
|
AssetVersion: api.NewOptInt64(items[i].AssetVersion),
|
|
|
|
Completed: api.NewOptBool(items[i].Completed),
|
|
|
|
TargetAssetID: api.NewOptInt64(items[i].TargetAssetID),
|
2024-11-28 01:27:22 +00:00
|
|
|
StatusID: api.NewOptInt32(int32(items[i].StatusID)),
|
2024-11-28 00:38:22 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
return resp, nil
|
2024-11-26 23:28:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// PatchSubmissionCompleted implements patchSubmissionCompleted operation.
|
|
|
|
//
|
|
|
|
// Retrieve map with ID.
|
|
|
|
//
|
|
|
|
// PATCH /submissions/{SubmissionID}/completed
|
2024-11-26 23:30:58 +00:00
|
|
|
func (svc *Service) PatchSubmissionCompleted(ctx context.Context, params api.PatchSubmissionCompletedParams) error {
|
2024-11-28 01:27:40 +00:00
|
|
|
// check if caller has MaptestGame role (request must originate from a maptest roblox game)
|
2024-11-28 00:44:50 +00:00
|
|
|
pmap := datastore.Optional()
|
2024-11-28 01:22:59 +00:00
|
|
|
pmap.Add("completed", true)
|
2024-11-28 00:44:50 +00:00
|
|
|
err := svc.DB.Submissions().Update(ctx, params.SubmissionID, pmap)
|
|
|
|
return err
|
2024-11-26 23:28:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// PatchSubmissionModel implements patchSubmissionModel operation.
|
|
|
|
//
|
|
|
|
// Update model following role restrictions.
|
|
|
|
//
|
|
|
|
// PATCH /submissions/{SubmissionID}/model
|
2024-11-26 23:30:58 +00:00
|
|
|
func (svc *Service) PatchSubmissionModel(ctx context.Context, params api.PatchSubmissionModelParams) error {
|
2024-11-28 01:27:40 +00:00
|
|
|
// check if caller has Submitter role
|
2024-11-28 03:06:19 +00:00
|
|
|
// if !CALLER_ROLES.INCLUDES(ROLE_SUBMITTER){
|
|
|
|
// return ErrPermissionDenied
|
|
|
|
// }
|
2024-11-28 01:27:40 +00:00
|
|
|
// check if Status is ChangesRequested|Submitted|UnderConstruction
|
2024-11-28 00:44:50 +00:00
|
|
|
pmap := datastore.Optional()
|
|
|
|
pmap.AddNotNil("asset_id", params.ModelID)
|
|
|
|
pmap.AddNotNil("asset_version", params.VersionID)
|
2024-11-28 01:27:44 +00:00
|
|
|
//always reset completed when model changes
|
|
|
|
pmap.Add("completed",false)
|
2024-11-28 03:04:24 +00:00
|
|
|
err := svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusChangesRequested,model.StatusSubmitted,model.StatusUnderConstruction}, pmap)
|
2024-11-28 00:44:50 +00:00
|
|
|
return err
|
2024-11-26 23:28:48 +00:00
|
|
|
}
|
|
|
|
|
2024-11-28 01:46:54 +00:00
|
|
|
// ActionSubmissionPublish invokes actionSubmissionPublish operation.
|
2024-11-26 23:28:48 +00:00
|
|
|
//
|
2024-11-28 01:46:54 +00:00
|
|
|
// Role Validator changes status from Publishing -> Published.
|
2024-11-26 23:28:48 +00:00
|
|
|
//
|
2024-11-28 01:46:54 +00:00
|
|
|
// PATCH /submissions/{SubmissionID}/status/publish
|
|
|
|
func (svc *Service) ActionSubmissionPublish(ctx context.Context, params api.ActionSubmissionPublishParams) error {
|
2024-11-28 02:19:19 +00:00
|
|
|
// check if caller has required role
|
|
|
|
// if !CALLER_ROLES.INCLUDES(ROLE_VALIDATOR){
|
|
|
|
// return ErrPermissionDenied
|
|
|
|
// }
|
2024-11-28 02:57:42 +00:00
|
|
|
// transaction
|
2024-11-28 02:19:19 +00:00
|
|
|
smap := datastore.Optional()
|
|
|
|
smap.Add("status_id",model.StatusPublished)
|
2024-11-28 02:57:42 +00:00
|
|
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusPublishing}, smap)
|
2024-11-28 01:46:54 +00:00
|
|
|
}
|
|
|
|
// ActionSubmissionReject invokes actionSubmissionReject operation.
|
|
|
|
//
|
|
|
|
// Role Reviewer changes status from Submitted -> Rejected.
|
|
|
|
//
|
|
|
|
// PATCH /submissions/{SubmissionID}/status/reject
|
|
|
|
func (svc *Service) ActionSubmissionReject(ctx context.Context, params api.ActionSubmissionRejectParams) error {
|
2024-11-28 02:19:19 +00:00
|
|
|
// check if caller has required role
|
|
|
|
// if !CALLER_ROLES.INCLUDES(ROLE_Reviewer){
|
|
|
|
// return ErrPermissionDenied
|
|
|
|
// }
|
2024-11-28 02:57:42 +00:00
|
|
|
// transaction
|
2024-11-28 02:19:19 +00:00
|
|
|
smap := datastore.Optional()
|
|
|
|
smap.Add("status_id",model.StatusRejected)
|
2024-11-28 02:57:42 +00:00
|
|
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusSubmitted}, smap)
|
2024-11-28 01:46:54 +00:00
|
|
|
}
|
|
|
|
// ActionSubmissionRequestChanges invokes actionSubmissionRequestChanges operation.
|
|
|
|
//
|
|
|
|
// Role Reviewer changes status from Validated|Accepted|Submitted -> ChangesRequested.
|
|
|
|
//
|
|
|
|
// PATCH /submissions/{SubmissionID}/status/request-changes
|
|
|
|
func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params api.ActionSubmissionRequestChangesParams) error {
|
2024-11-28 02:19:19 +00:00
|
|
|
// check if caller has required role
|
|
|
|
// if !CALLER_ROLES.INCLUDES(ROLE_Reviewer){
|
|
|
|
// return ErrPermissionDenied
|
|
|
|
// }
|
2024-11-28 02:57:42 +00:00
|
|
|
// transaction
|
2024-11-28 02:19:19 +00:00
|
|
|
smap := datastore.Optional()
|
|
|
|
smap.Add("status_id",model.StatusChangesRequested)
|
2024-11-28 02:57:42 +00:00
|
|
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidated,model.StatusAccepted,model.StatusSubmitted}, smap)
|
2024-11-28 01:46:54 +00:00
|
|
|
}
|
|
|
|
// ActionSubmissionRevoke invokes actionSubmissionRevoke operation.
|
|
|
|
//
|
|
|
|
// Role Submitter changes status from Submitted|ChangesRequested -> UnderConstruction.
|
|
|
|
//
|
|
|
|
// PATCH /submissions/{SubmissionID}/status/revoke
|
|
|
|
func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.ActionSubmissionRevokeParams) error {
|
2024-11-28 02:19:19 +00:00
|
|
|
// check if caller has required role
|
|
|
|
// if !CALLER_ROLES.INCLUDES(ROLE_Submitter){
|
|
|
|
// return ErrPermissionDenied
|
|
|
|
// }
|
2024-11-28 02:57:42 +00:00
|
|
|
// transaction
|
2024-11-28 02:19:19 +00:00
|
|
|
smap := datastore.Optional()
|
|
|
|
smap.Add("status_id",model.StatusUnderConstruction)
|
2024-11-28 02:57:42 +00:00
|
|
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusSubmitted,model.StatusChangesRequested}, smap)
|
2024-11-28 01:46:54 +00:00
|
|
|
}
|
|
|
|
// ActionSubmissionSubmit invokes actionSubmissionSubmit operation.
|
|
|
|
//
|
|
|
|
// Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitted.
|
|
|
|
//
|
|
|
|
// PATCH /submissions/{SubmissionID}/status/submit
|
|
|
|
func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.ActionSubmissionSubmitParams) error {
|
2024-11-28 02:19:19 +00:00
|
|
|
// check if caller has required role
|
|
|
|
// if !CALLER_ROLES.INCLUDES(ROLE_Submitter){
|
|
|
|
// return ErrPermissionDenied
|
|
|
|
// }
|
2024-11-28 02:57:42 +00:00
|
|
|
// transaction
|
2024-11-28 02:19:19 +00:00
|
|
|
smap := datastore.Optional()
|
|
|
|
smap.Add("status_id",model.StatusSubmitted)
|
2024-11-28 02:57:42 +00:00
|
|
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusUnderConstruction,model.StatusChangesRequested}, smap)
|
2024-11-28 01:46:54 +00:00
|
|
|
}
|
|
|
|
// ActionSubmissionTriggerPublish invokes actionSubmissionTriggerPublish operation.
|
|
|
|
//
|
|
|
|
// Role Admin changes status from Validated -> Publishing.
|
|
|
|
//
|
|
|
|
// PATCH /submissions/{SubmissionID}/status/trigger-publish
|
|
|
|
func (svc *Service) ActionSubmissionTriggerPublish(ctx context.Context, params api.ActionSubmissionTriggerPublishParams) error {
|
2024-11-28 02:19:19 +00:00
|
|
|
// check if caller has required role
|
|
|
|
// if !CALLER_ROLES.INCLUDES(ROLE_Admin){
|
|
|
|
// return ErrPermissionDenied
|
|
|
|
// }
|
2024-11-28 02:57:42 +00:00
|
|
|
// transaction
|
2024-11-28 02:19:19 +00:00
|
|
|
smap := datastore.Optional()
|
|
|
|
smap.Add("status_id",model.StatusPublishing)
|
2024-11-28 02:57:42 +00:00
|
|
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidated}, smap)
|
2024-11-28 01:46:54 +00:00
|
|
|
}
|
|
|
|
// ActionSubmissionTriggerValidate invokes actionSubmissionTriggerValidate operation.
|
|
|
|
//
|
|
|
|
// Role Reviewer triggers validation and changes status from Submitted|Accepted -> Validating.
|
|
|
|
//
|
|
|
|
// PATCH /submissions/{SubmissionID}/status/trigger-validate
|
|
|
|
func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params api.ActionSubmissionTriggerValidateParams) error {
|
2024-11-28 02:19:19 +00:00
|
|
|
// check if caller has required role
|
|
|
|
// if !CALLER_ROLES.INCLUDES(ROLE_Reviewer){
|
|
|
|
// return ErrPermissionDenied
|
|
|
|
// }
|
2024-11-28 02:57:42 +00:00
|
|
|
// transaction
|
2024-11-28 02:19:19 +00:00
|
|
|
smap := datastore.Optional()
|
|
|
|
smap.Add("status_id",model.StatusValidating)
|
2024-11-28 02:57:42 +00:00
|
|
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusSubmitted,model.StatusAccepted}, smap)
|
2024-11-28 01:46:54 +00:00
|
|
|
}
|
|
|
|
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
|
|
|
|
//
|
|
|
|
// Role Validator changes status from Validating -> Validated.
|
|
|
|
//
|
|
|
|
// PATCH /submissions/{SubmissionID}/status/validate
|
|
|
|
func (svc *Service) ActionSubmissionValidate(ctx context.Context, params api.ActionSubmissionValidateParams) error {
|
2024-11-28 02:19:19 +00:00
|
|
|
// check if caller has required role
|
|
|
|
// if !CALLER_ROLES.INCLUDES(ROLE_VALIDATOR){
|
|
|
|
// return ErrPermissionDenied
|
|
|
|
// }
|
2024-11-28 02:57:42 +00:00
|
|
|
// transaction
|
2024-11-28 02:19:19 +00:00
|
|
|
smap := datastore.Optional()
|
|
|
|
smap.Add("status_id",model.StatusValidated)
|
2024-11-28 02:57:42 +00:00
|
|
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidating}, smap)
|
2024-11-26 23:28:48 +00:00
|
|
|
}
|