From dfc2a605f4b881bb52b112ecf8bd6df8cd5ad618 Mon Sep 17 00:00:00 2001
From: Quaternions <krakow20@gmail.com>
Date: Mon, 31 Mar 2025 14:44:26 -0700
Subject: [PATCH] submissions: prepare for separate mapfixes

---
 pkg/datastore/datastore.go             |  17 ++-
 pkg/datastore/gormstore/scripts.go     |   2 +-
 pkg/datastore/gormstore/submissions.go |  18 +--
 pkg/model/submission.go                |  38 +++---
 pkg/service/security.go                |  26 ++--
 pkg/service/service.go                 |   9 ++
 pkg/service/submissions.go             | 158 ++++++++++---------------
 pkg/service_internal/submissions.go    |  14 +--
 8 files changed, 129 insertions(+), 153 deletions(-)

diff --git a/pkg/datastore/datastore.go b/pkg/datastore/datastore.go
index eb7ca73..8a256b1 100644
--- a/pkg/datastore/datastore.go
+++ b/pkg/datastore/datastore.go
@@ -9,7 +9,16 @@ import (
 var (
 	ErrNotExist        = errors.New("resource does not exist")
 	ErroNoRowsAffected = errors.New("query did not affect any rows")
-	ErrInvalidSubmissionListSort = errors.New("invalid submission list sort parameter [1,2,3,4]")
+	ErrInvalidListSort = errors.New("invalid list sort parameter [1,2,3,4]")
+)
+
+type ListSort uint32
+const (
+	ListSortDisabled ListSort = 0
+	ListSortDisplayNameAscending ListSort = 1
+	ListSortDisplayNameDescending ListSort = 2
+	ListSortDateAscending ListSort = 3
+	ListSortDateDescending ListSort = 4
 )
 
 type Datastore interface {
@@ -23,10 +32,10 @@ type Submissions interface {
 	GetList(ctx context.Context, id []int64) ([]model.Submission, error)
 	Create(ctx context.Context, smap model.Submission) (model.Submission, error)
 	Update(ctx context.Context, id int64, values OptionalMap) error
-	IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.Status, values OptionalMap) error
-	IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.Status, values OptionalMap) (model.Submission, error)
+	IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.SubmissionStatus, values OptionalMap) error
+	IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.SubmissionStatus, values OptionalMap) (model.Submission, error)
 	Delete(ctx context.Context, id int64) error
-	List(ctx context.Context, filters OptionalMap, page model.Page, sort model.SubmissionListSort) ([]model.Submission, error)
+	List(ctx context.Context, filters OptionalMap, page model.Page, sort ListSort) ([]model.Submission, error)
 }
 
 type Scripts interface {
diff --git a/pkg/datastore/gormstore/scripts.go b/pkg/datastore/gormstore/scripts.go
index 1aa7f1f..600d107 100644
--- a/pkg/datastore/gormstore/scripts.go
+++ b/pkg/datastore/gormstore/scripts.go
@@ -53,7 +53,7 @@ func (env *Scripts) Update(ctx context.Context, id int64, values datastore.Optio
 }
 
 // the update can only occur if the status matches one of the provided values.
-func (env *Scripts) IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.Status, values datastore.OptionalMap) error {
+func (env *Scripts) IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.SubmissionStatus, values datastore.OptionalMap) error {
 	if err := env.db.Model(&model.Script{}).Where("id = ?", id).Where("status IN ?", statuses).Updates(values.Map()).Error; err != nil {
 		if err == gorm.ErrRecordNotFound {
 			return datastore.ErrNotExist
diff --git a/pkg/datastore/gormstore/submissions.go b/pkg/datastore/gormstore/submissions.go
index b7073ab..dc384c6 100644
--- a/pkg/datastore/gormstore/submissions.go
+++ b/pkg/datastore/gormstore/submissions.go
@@ -54,7 +54,7 @@ func (env *Submissions) Update(ctx context.Context, id int64, values datastore.O
 }
 
 // the update can only occur if the status matches one of the provided values.
-func (env *Submissions) IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.Status, values datastore.OptionalMap) error {
+func (env *Submissions) IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.SubmissionStatus, values datastore.OptionalMap) error {
 	if err := env.db.Model(&model.Submission{}).Where("id = ?", id).Where("status_id IN ?", statuses).Updates(values.Map()).Error; err != nil {
 		if err == gorm.ErrRecordNotFound {
 			return datastore.ErrNotExist
@@ -67,7 +67,7 @@ func (env *Submissions) IfStatusThenUpdate(ctx context.Context, id int64, status
 
 // the update can only occur if the status matches one of the provided values.
 // returns the updated value
-func (env *Submissions) IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.Status, values datastore.OptionalMap) (model.Submission, error) {
+func (env *Submissions) IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.SubmissionStatus, values datastore.OptionalMap) (model.Submission, error) {
 	var submission model.Submission
 	result := env.db.Model(&submission).
 		Clauses(clause.Returning{}).
@@ -99,29 +99,29 @@ func (env *Submissions) Delete(ctx context.Context, id int64) error {
 	return nil
 }
 
-func (env *Submissions) List(ctx context.Context, filters datastore.OptionalMap, page model.Page, sort model.SubmissionListSort) ([]model.Submission, error) {
+func (env *Submissions) List(ctx context.Context, filters datastore.OptionalMap, page model.Page, sort datastore.ListSort) ([]model.Submission, error) {
 	var maps []model.Submission
 
 	db := env.db
 
 	switch sort {
-	case model.SubmissionListSortDisabled:
+	case datastore.ListSortDisabled:
 		// No sort
 		break
-	case model.SubmissionListSortDisplayNameAscending:
+	case datastore.ListSortDisplayNameAscending:
 		db=db.Order("display_name ASC")
 		break
-	case model.SubmissionListSortDisplayNameDescending:
+	case datastore.ListSortDisplayNameDescending:
 		db=db.Order("display_name DESC")
 		break
-	case model.SubmissionListSortDateAscending:
+	case datastore.ListSortDateAscending:
 		db=db.Order("created_at ASC")
 		break
-	case model.SubmissionListSortDateDescending:
+	case datastore.ListSortDateDescending:
 		db=db.Order("created_at DESC")
 		break
 	default:
-		return nil, datastore.ErrInvalidSubmissionListSort
+		return nil, datastore.ErrInvalidListSort
 	}
 
 	if err := db.Where(filters.Map()).Offset(int((page.Number - 1) * page.Size)).Limit(int(page.Size)).Find(&maps).Error; err != nil {
diff --git a/pkg/model/submission.go b/pkg/model/submission.go
index 11f1775..aa2c708 100644
--- a/pkg/model/submission.go
+++ b/pkg/model/submission.go
@@ -2,34 +2,24 @@ package model
 
 import "time"
 
-type Status int32
+type SubmissionStatus int32
 
 const (
-	// Phase: Final Status
-	StatusReleased  Status = 9
-	StatusRejected  Status = 8
+	// Phase: Final SubmissionStatus
+	SubmissionStatusReleased  SubmissionStatus = 9
+	SubmissionStatusRejected  SubmissionStatus = 8
 
 	// Phase: Testing
-	StatusUploaded   Status = 7 // uploaded to the group, but pending release
-	StatusUploading  Status = 6
-	StatusValidated  Status = 5
-	StatusValidating Status = 4
-	StatusAccepted   Status = 3 // pending script review, can re-trigger validation
+	SubmissionStatusUploaded   SubmissionStatus = 7 // uploaded to the group, but pending release
+	SubmissionStatusUploading  SubmissionStatus = 6
+	SubmissionStatusValidated  SubmissionStatus = 5
+	SubmissionStatusValidating SubmissionStatus = 4
+	SubmissionStatusAccepted   SubmissionStatus = 3 // pending script review, can re-trigger validation
 
 	// Phase: Creation
-	StatusChangesRequested  Status = 2
-	StatusSubmitted         Status = 1
-	StatusUnderConstruction Status = 0
-)
-
-type SubmissionListSort uint32
-
-const (
-	SubmissionListSortDisabled SubmissionListSort = 0
-	SubmissionListSortDisplayNameAscending SubmissionListSort = 1
-	SubmissionListSortDisplayNameDescending SubmissionListSort = 2
-	SubmissionListSortDateAscending SubmissionListSort = 3
-	SubmissionListSortDateDescending SubmissionListSort = 4
+	SubmissionStatusChangesRequested  SubmissionStatus = 2
+	SubmissionStatusSubmitted         SubmissionStatus = 1
+	SubmissionStatusUnderConstruction SubmissionStatus = 0
 )
 
 type Submission struct {
@@ -45,7 +35,7 @@ type Submission struct {
 	ValidatedAssetID       int64
 	ValidatedAssetVersion  int64
 	Completed     bool   // Has this version of the map been completed at least once on maptest
-	TargetAssetID int64 // where to upload map fix.  if the TargetAssetID is 0, it's a new map.
-	StatusID      Status
+	UploadedAssetID        int64 // where to upload map fix.  if the TargetAssetID is 0, it's a new map.
+	StatusID      SubmissionStatus
 	StatusMessage string
 }
diff --git a/pkg/service/security.go b/pkg/service/security.go
index 9584672..8bc2efb 100644
--- a/pkg/service/security.go
+++ b/pkg/service/security.go
@@ -19,8 +19,8 @@ type Roles int32
 var (
 	RolesSubmissionRelease Roles = 1<<4
 	RolesScriptWrite Roles = 1<<3
-	RolesSubmissionUpload Roles = 1<<2
-	RolesSubmissionReview Roles = 1<<1
+	RolesMapUpload Roles = 1<<2
+	RolesMapReview Roles = 1<<1
 	RolesMapDownload Roles = 1<<0
 	RolesEmpty Roles = 0
 )
@@ -32,13 +32,13 @@ var (
 	RoleQuat GroupRole = 255
 	RoleItzaname GroupRole = 254
 	RoleStagingDeveloper GroupRole = 240
-	RolesAll Roles = RolesScriptWrite|RolesSubmissionRelease|RolesSubmissionUpload|RolesSubmissionReview|RolesMapDownload
+	RolesAll Roles = RolesScriptWrite|RolesSubmissionRelease|RolesMapUpload|RolesMapReview|RolesMapDownload
 	// has SubmissionUpload
 	RoleMapAdmin GroupRole = 128
-	RolesMapAdmin Roles = RolesSubmissionRelease|RolesSubmissionUpload|RolesSubmissionReview|RolesMapDownload
+	RolesMapAdmin Roles = RolesSubmissionRelease|RolesMapUpload|RolesMapReview|RolesMapDownload
 	// has SubmissionReview
 	RoleMapCouncil GroupRole = 64
-	RolesMapCouncil Roles = RolesSubmissionReview|RolesSubmissionUpload|RolesMapDownload
+	RolesMapCouncil Roles = RolesMapReview|RolesMapUpload|RolesMapDownload
 	// access to downloading maps
 	RoleMapAccess GroupRole = 32
 	RolesMapAccess Roles = RolesMapDownload
@@ -128,17 +128,23 @@ func (usr UserInfoHandle) GetRoles() (Roles, error) {
 }
 
 // RoleThumbnail
+func (usr UserInfoHandle) HasRoleMapfixUpload() (bool, error) {
+	return usr.hasRoles(RolesMapUpload)
+}
+func (usr UserInfoHandle) HasRoleMapfixReview() (bool, error) {
+	return usr.hasRoles(RolesMapReview)
+}
+func (usr UserInfoHandle) HasRoleMapDownload() (bool, error) {
+	return usr.hasRoles(RolesMapDownload)
+}
 func (usr UserInfoHandle) HasRoleSubmissionRelease() (bool, error) {
 	return usr.hasRoles(RolesSubmissionRelease)
 }
 func (usr UserInfoHandle) HasRoleSubmissionUpload() (bool, error) {
-	return usr.hasRoles(RolesSubmissionUpload)
+	return usr.hasRoles(RolesMapUpload)
 }
 func (usr UserInfoHandle) HasRoleSubmissionReview() (bool, error) {
-	return usr.hasRoles(RolesSubmissionReview)
-}
-func (usr UserInfoHandle) HasRoleMapDownload() (bool, error) {
-	return usr.hasRoles(RolesMapDownload)
+	return usr.hasRoles(RolesMapReview)
 }
 func (usr UserInfoHandle) HasRoleScriptWrite() (bool, error) {
 	return usr.hasRoles(RolesScriptWrite)
diff --git a/pkg/service/service.go b/pkg/service/service.go
index ac0c2f6..1815060 100644
--- a/pkg/service/service.go
+++ b/pkg/service/service.go
@@ -3,6 +3,7 @@ package service
 import (
 	"context"
 	"errors"
+	"fmt"
 
 	"git.itzana.me/strafesnet/go-grpc/maps"
 	"git.itzana.me/strafesnet/maps-service/pkg/api"
@@ -15,6 +16,14 @@ var (
 	ErrPermissionDenied = errors.New("Permission denied")
 	// ErrUserInfo user info is missing for some reason
 	ErrUserInfo = errors.New("Missing user info")
+	ErrDelayReset = errors.New("Please give the validator at least 10 seconds to operate before attempting to reset the status")
+	ErrPermissionDeniedNotSubmitter = fmt.Errorf("%w: You must be the submitter to perform this action", ErrPermissionDenied)
+	ErrPermissionDeniedNeedRoleSubmissionRelease = fmt.Errorf("%w: Need Role SubmissionRelease", ErrPermissionDenied)
+	ErrPermissionDeniedNeedRoleMapUpload = fmt.Errorf("%w: Need Role MapUpload", ErrPermissionDenied)
+	ErrPermissionDeniedNeedRoleMapReview = fmt.Errorf("%w: Need Role MapReview", ErrPermissionDenied)
+	ErrPermissionDeniedNeedRoleMapDownload = fmt.Errorf("%w: Need Role MapDownload", ErrPermissionDenied)
+	ErrPermissionDeniedNeedRoleScriptWrite = fmt.Errorf("%w: Need Role ScriptWrite", ErrPermissionDenied)
+	ErrPermissionDeniedNeedRoleMaptest = fmt.Errorf("%w: Need Role Maptest", ErrPermissionDenied)
 )
 
 type Service struct {
diff --git a/pkg/service/submissions.go b/pkg/service/submissions.go
index 94a76c1..8583675 100644
--- a/pkg/service/submissions.go
+++ b/pkg/service/submissions.go
@@ -15,45 +15,37 @@ import (
 
 var(
 	CreationPhaseSubmissionsLimit = 20
-	CreationPhaseSubmissionStatuses = []model.Status{
-		model.StatusChangesRequested,
-		model.StatusSubmitted,
-		model.StatusUnderConstruction,
+	CreationPhaseSubmissionStatuses = []model.SubmissionStatus{
+		model.SubmissionStatusChangesRequested,
+		model.SubmissionStatusSubmitted,
+		model.SubmissionStatusUnderConstruction,
 	}
 	// prevent two mapfixes with same asset id
-	ActiveSubmissionStatuses = []model.Status{
-		model.StatusUploading,
-		model.StatusValidated,
-		model.StatusValidating,
-		model.StatusAccepted,
-		model.StatusChangesRequested,
-		model.StatusSubmitted,
-		model.StatusUnderConstruction,
+	ActiveSubmissionStatuses = []model.SubmissionStatus{
+		model.SubmissionStatusUploading,
+		model.SubmissionStatusValidated,
+		model.SubmissionStatusValidating,
+		model.SubmissionStatusAccepted,
+		model.SubmissionStatusChangesRequested,
+		model.SubmissionStatusSubmitted,
+		model.SubmissionStatusUnderConstruction,
 	}
 	// limit mapfixes in the pipeline to one per target map
-	ActiveAcceptedSubmissionStatuses = []model.Status{
-		model.StatusUploading,
-		model.StatusValidated,
-		model.StatusValidating,
-		model.StatusAccepted,
+	ActiveAcceptedSubmissionStatuses = []model.SubmissionStatus{
+		model.SubmissionStatusUploading,
+		model.SubmissionStatusValidated,
+		model.SubmissionStatusValidating,
+		model.SubmissionStatusAccepted,
 	}
 )
 
 var (
 	ErrCreationPhaseSubmissionsLimit = errors.New("Active submissions limited to 20")
 	ErrActiveSubmissionSameAssetID = errors.New("There is an active submission with the same AssetID")
-	ErrActiveSubmissionSameTargetAssetID = errors.New("There is an active submission with the same TargetAssetID")
+	ErrUploadedAssetIDAlreadyExists = errors.New("The submission UploadedAssetID is already set")
 	ErrReleaseInvalidStatus = errors.New("Only submissions with Uploaded status can be released")
-	ErrReleaseNoTargetAssetID = errors.New("Only submissions with a TargetAssetID can be released")
+	ErrReleaseNoUploadedAssetID = errors.New("Only submissions with a UploadedAssetID can be released")
 	ErrAcceptOwnSubmission = fmt.Errorf("%w: You cannot accept your own submission as the submitter", ErrPermissionDenied)
-	ErrDelayReset = errors.New("Please give the validator at least 10 seconds to operate before attempting to reset the status")
-	ErrPermissionDeniedNotSubmitter = fmt.Errorf("%w: You must be the submitter to perform this action", ErrPermissionDenied)
-	ErrPermissionDeniedNeedRoleSubmissionRelease = fmt.Errorf("%w: Need Role SubmissionRelease", ErrPermissionDenied)
-	ErrPermissionDeniedNeedRoleSubmissionUpload = fmt.Errorf("%w: Need Role SubmissionUpload", ErrPermissionDenied)
-	ErrPermissionDeniedNeedRoleSubmissionReview = fmt.Errorf("%w: Need Role SubmissionReview", ErrPermissionDenied)
-	ErrPermissionDeniedNeedRoleMapDownload = fmt.Errorf("%w: Need Role MapDownload", ErrPermissionDenied)
-	ErrPermissionDeniedNeedRoleScriptWrite = fmt.Errorf("%w: Need Role ScriptWrite", ErrPermissionDenied)
-	ErrPermissionDeniedNeedRoleMaptest = fmt.Errorf("%w: Need Role Maptest", ErrPermissionDenied)
 )
 
 // POST /submissions
@@ -76,7 +68,7 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio
 		creation_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
 			Number: 1,
 			Size:   int32(CreationPhaseSubmissionsLimit),
-		},model.SubmissionListSortDisabled)
+		},datastore.ListSortDisabled)
 		if err != nil {
 			return nil, err
 		}
@@ -95,7 +87,7 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio
 		active_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
 			Number: 1,
 			Size:   1,
-		},model.SubmissionListSortDisabled)
+		},datastore.ListSortDisabled)
 		if err != nil {
 			return nil, err
 		}
@@ -113,8 +105,7 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio
 		AssetID:       request.AssetID,
 		AssetVersion:  request.AssetVersion,
 		Completed:     false,
-		TargetAssetID: request.TargetAssetID.Value,
-		StatusID:      model.StatusUnderConstruction,
+		StatusID:      model.SubmissionStatusUnderConstruction,
 	})
 	if err != nil {
 		return nil, err
@@ -145,7 +136,7 @@ func (svc *Service) GetSubmission(ctx context.Context, params api.GetSubmissionP
 		AssetID:       int64(submission.AssetID),
 		AssetVersion:  int64(submission.AssetVersion),
 		Completed:     submission.Completed,
-		TargetAssetID: api.NewOptInt64(int64(submission.TargetAssetID)),
+		UploadedAssetID: api.NewOptInt64(int64(submission.UploadedAssetID)),
 		StatusID:      int32(submission.StatusID),
 		StatusMessage: submission.StatusMessage,
 	}, nil
@@ -169,7 +160,7 @@ func (svc *Service) ListSubmissions(ctx context.Context, params api.ListSubmissi
 		filter.Add("game_id", params.GameID.Value)
 	}
 
-	sort := model.SubmissionListSort(params.Sort.Or(int32(model.SubmissionListSortDisabled)))
+	sort := datastore.ListSort(params.Sort.Or(int32(datastore.ListSortDisabled)))
 
 	items, err := svc.DB.Submissions().List(ctx, filter, model.Page{
 		Number: params.Page,
@@ -192,7 +183,7 @@ func (svc *Service) ListSubmissions(ctx context.Context, params api.ListSubmissi
 			AssetID:       int64(item.AssetID),
 			AssetVersion:  int64(item.AssetVersion),
 			Completed:     item.Completed,
-			TargetAssetID: api.NewOptInt64(int64(item.TargetAssetID)),
+			UploadedAssetID: api.NewOptInt64(int64(item.UploadedAssetID)),
 			StatusID:      int32(item.StatusID),
 		})
 	}
@@ -257,7 +248,7 @@ func (svc *Service) UpdateSubmissionModel(ctx context.Context, params api.Update
 	pmap.AddNotNil("asset_version", params.VersionID)
 	//always reset completed when model changes
 	pmap.Add("completed", false)
-	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusChangesRequested, model.StatusSubmitted, model.StatusUnderConstruction}, pmap)
+	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusChangesRequested, model.SubmissionStatusSubmitted, model.SubmissionStatusUnderConstruction}, pmap)
 }
 
 // ActionSubmissionReject invokes actionSubmissionReject operation.
@@ -277,13 +268,13 @@ func (svc *Service) ActionSubmissionReject(ctx context.Context, params api.Actio
 	}
 	// check if caller has required role
 	if !has_role {
-		return ErrPermissionDeniedNeedRoleSubmissionReview
+		return ErrPermissionDeniedNeedRoleMapReview
 	}
 
 	// transaction
 	smap := datastore.Optional()
-	smap.Add("status_id", model.StatusRejected)
-	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusSubmitted}, smap)
+	smap.Add("status_id", model.SubmissionStatusRejected)
+	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusSubmitted}, smap)
 }
 
 // ActionSubmissionRequestChanges invokes actionSubmissionRequestChanges operation.
@@ -303,13 +294,13 @@ func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params a
 	}
 	// check if caller has required role
 	if !has_role {
-		return ErrPermissionDeniedNeedRoleSubmissionReview
+		return ErrPermissionDeniedNeedRoleMapReview
 	}
 
 	// transaction
 	smap := datastore.Optional()
-	smap.Add("status_id", model.StatusChangesRequested)
-	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidated, model.StatusAccepted, model.StatusSubmitted}, smap)
+	smap.Add("status_id", model.SubmissionStatusChangesRequested)
+	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidated, model.SubmissionStatusAccepted, model.SubmissionStatusSubmitted}, smap)
 }
 
 // ActionSubmissionRevoke invokes actionSubmissionRevoke operation.
@@ -340,8 +331,8 @@ func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.Actio
 
 	// transaction
 	smap := datastore.Optional()
-	smap.Add("status_id", model.StatusUnderConstruction)
-	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusSubmitted, model.StatusChangesRequested}, smap)
+	smap.Add("status_id", model.SubmissionStatusUnderConstruction)
+	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusSubmitted, model.SubmissionStatusChangesRequested}, smap)
 }
 
 // ActionSubmissionSubmit invokes actionSubmissionSubmit operation.
@@ -372,8 +363,8 @@ func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.Actio
 
 	// transaction
 	smap := datastore.Optional()
-	smap.Add("status_id", model.StatusSubmitted)
-	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusUnderConstruction, model.StatusChangesRequested}, smap)
+	smap.Add("status_id", model.SubmissionStatusSubmitted)
+	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusUnderConstruction, model.SubmissionStatusChangesRequested}, smap)
 }
 
 // ActionSubmissionTriggerUpload invokes actionSubmissionTriggerUpload operation.
@@ -393,19 +384,19 @@ func (svc *Service) ActionSubmissionTriggerUpload(ctx context.Context, params ap
 	}
 	// check if caller has required role
 	if !has_role {
-		return ErrPermissionDeniedNeedRoleSubmissionUpload
+		return ErrPermissionDeniedNeedRoleMapUpload
 	}
 
 	// transaction
 	smap := datastore.Optional()
-	smap.Add("status_id", model.StatusUploading)
-	submission, err := svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.Status{model.StatusValidated}, smap)
+	smap.Add("status_id", model.SubmissionStatusUploading)
+	submission, err := svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidated}, smap)
 	if err != nil {
 		return err
 	}
 
 	// sentinel value because we are not using rust
-	if submission.TargetAssetID == 0 {
+	if submission.UploadedAssetID == 0 {
 		// this is a new map
 		upload_new_request := model.UploadNewRequest{
 			SubmissionID: submission.ID,
@@ -422,20 +413,8 @@ func (svc *Service) ActionSubmissionTriggerUpload(ctx context.Context, params ap
 
 		svc.Nats.Publish("maptest.submissions.uploadnew", []byte(j))
 	} else {
-		// this is a map fix
-		upload_fix_request := model.UploadFixRequest{
-			SubmissionID:  submission.ID,
-			ModelID:       submission.ValidatedAssetID,
-			ModelVersion:  submission.ValidatedAssetVersion,
-			TargetAssetID: submission.TargetAssetID,
-		}
-
-		j, err := json.Marshal(upload_fix_request)
-		if err != nil {
-			return err
-		}
-
-		svc.Nats.Publish("maptest.submissions.uploadfix", []byte(j))
+		// refuse to operate
+		return ErrUploadedAssetIDAlreadyExists
 	}
 
 	return nil
@@ -458,7 +437,7 @@ func (svc *Service) ActionSubmissionValidated(ctx context.Context, params api.Ac
 	}
 	// check if caller has required role
 	if !has_role {
-		return ErrPermissionDeniedNeedRoleSubmissionUpload
+		return ErrPermissionDeniedNeedRoleMapUpload
 	}
 
 	// check when submission was updated
@@ -473,8 +452,8 @@ func (svc *Service) ActionSubmissionValidated(ctx context.Context, params api.Ac
 
 	// transaction
 	smap := datastore.Optional()
-	smap.Add("status_id", model.StatusValidated)
-	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusUploading}, smap)
+	smap.Add("status_id", model.SubmissionStatusValidated)
+	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusUploading}, smap)
 }
 
 // ActionSubmissionTriggerValidate invokes actionSubmissionTriggerValidate operation.
@@ -494,7 +473,7 @@ func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params
 	}
 	// check if caller has required role
 	if !has_role {
-		return ErrPermissionDeniedNeedRoleSubmissionReview
+		return ErrPermissionDeniedNeedRoleMapReview
 	}
 
 	// read submission (this could be done with a transaction WHERE clause)
@@ -512,27 +491,10 @@ func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params
 		return ErrAcceptOwnSubmission
 	}
 
-	// Check if an active submission with the same target asset id exists
-	if submission.TargetAssetID != 0 {
-		filter := datastore.Optional()
-		filter.Add("target_asset_id", submission.TargetAssetID)
-		filter.Add("status_id", ActiveAcceptedSubmissionStatuses)
-		active_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
-			Number: 1,
-			Size:   1,
-		},model.SubmissionListSortDisabled)
-		if err != nil {
-			return err
-		}
-		if len(active_submissions) != 0{
-			return ErrActiveSubmissionSameTargetAssetID
-		}
-	}
-
 	// transaction
 	smap := datastore.Optional()
-	smap.Add("status_id", model.StatusValidating)
-	submission, err = svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.Status{model.StatusSubmitted}, smap)
+	smap.Add("status_id", model.SubmissionStatusValidating)
+	submission, err = svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusSubmitted}, smap)
 	if err != nil {
 		return err
 	}
@@ -576,13 +538,13 @@ func (svc *Service) ActionSubmissionRetryValidate(ctx context.Context, params ap
 	}
 	// check if caller has required role
 	if !has_role {
-		return ErrPermissionDeniedNeedRoleSubmissionReview
+		return ErrPermissionDeniedNeedRoleMapReview
 	}
 
 	// transaction
 	smap := datastore.Optional()
-	smap.Add("status_id", model.StatusValidating)
-	submission, err := svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.Status{model.StatusAccepted}, smap)
+	smap.Add("status_id", model.SubmissionStatusValidating)
+	submission, err := svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusAccepted}, smap)
 	if err != nil {
 		return err
 	}
@@ -626,7 +588,7 @@ func (svc *Service) ActionSubmissionAccepted(ctx context.Context, params api.Act
 	}
 	// check if caller has required role
 	if !has_role {
-		return ErrPermissionDeniedNeedRoleSubmissionReview
+		return ErrPermissionDeniedNeedRoleMapReview
 	}
 
 	// check when submission was updated
@@ -641,9 +603,9 @@ func (svc *Service) ActionSubmissionAccepted(ctx context.Context, params api.Act
 
 	// transaction
 	smap := datastore.Optional()
-	smap.Add("status_id", model.StatusAccepted)
+	smap.Add("status_id", model.SubmissionStatusAccepted)
 	smap.Add("status_message", "Manually forced reset")
-	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidating}, smap)
+	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidating}, smap)
 }
 
 // ReleaseSubmissions invokes releaseSubmissions operation.
@@ -679,11 +641,11 @@ func (svc *Service) ReleaseSubmissions(ctx context.Context, request []api.Releas
 
 	// check each submission to make sure it is ready to release
 	for _,submission := range submissions{
-		if submission.StatusID != model.StatusUploaded{
+		if submission.StatusID != model.SubmissionStatusUploaded{
 			return ErrReleaseInvalidStatus
 		}
-		if submission.TargetAssetID == 0{
-			return ErrReleaseNoTargetAssetID
+		if submission.UploadedAssetID == 0{
+			return ErrReleaseNoUploadedAssetID
 		}
 	}
 
@@ -691,7 +653,7 @@ func (svc *Service) ReleaseSubmissions(ctx context.Context, request []api.Releas
 		date := request[i].Date.Unix()
 		// create each map with go-grpc
 		_, err := svc.Client.Create(ctx, &maps.MapRequest{
-			ID:          submission.TargetAssetID,
+			ID:          submission.UploadedAssetID,
 			DisplayName: &submission.DisplayName,
 			Creator:     &submission.Creator,
 			GameID:      &submission.GameID,
@@ -703,8 +665,8 @@ func (svc *Service) ReleaseSubmissions(ctx context.Context, request []api.Releas
 
 		// update each status to Released
 		smap := datastore.Optional()
-		smap.Add("status_id", model.StatusReleased)
-		err = svc.DB.Submissions().IfStatusThenUpdate(ctx, submission.ID, []model.Status{model.StatusUploaded}, smap)
+		smap.Add("status_id", model.SubmissionStatusReleased)
+		err = svc.DB.Submissions().IfStatusThenUpdate(ctx, submission.ID, []model.SubmissionStatus{model.SubmissionStatusUploaded}, smap)
 		if err != nil {
 			return err
 		}
diff --git a/pkg/service_internal/submissions.go b/pkg/service_internal/submissions.go
index 0d3a33a..93b6daf 100644
--- a/pkg/service_internal/submissions.go
+++ b/pkg/service_internal/submissions.go
@@ -20,7 +20,7 @@ func (svc *Service) UpdateSubmissionValidatedModel(ctx context.Context, params i
 	pmap.AddNotNil("validated_asset_version", params.ValidatedModelVersion)
 	// DO NOT reset completed when validated model is updated
 	// pmap.Add("completed", false)
-	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidating}, pmap)
+	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidating}, pmap)
 }
 
 // ActionSubmissionValidate invokes actionSubmissionValidate operation.
@@ -33,8 +33,8 @@ func (svc *Service) ActionSubmissionValidated(ctx context.Context, params intern
 
 	// transaction
 	smap := datastore.Optional()
-	smap.Add("status_id", model.StatusValidated)
-	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidating}, smap)
+	smap.Add("status_id", model.SubmissionStatusValidated)
+	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidating}, smap)
 }
 
 // ActionSubmissionAccepted implements actionSubmissionAccepted operation.
@@ -47,9 +47,9 @@ func (svc *Service) ActionSubmissionAccepted(ctx context.Context, params interna
 
 	// transaction
 	smap := datastore.Optional()
-	smap.Add("status_id", model.StatusAccepted)
+	smap.Add("status_id", model.SubmissionStatusAccepted)
 	smap.Add("status_message", params.StatusMessage)
-	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidating}, smap)
+	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidating}, smap)
 }
 
 // ActionSubmissionUploaded implements actionSubmissionUploaded operation.
@@ -62,9 +62,9 @@ func (svc *Service) ActionSubmissionUploaded(ctx context.Context, params interna
 
 	// transaction
 	smap := datastore.Optional()
-	smap.Add("status_id", model.StatusUploaded)
+	smap.Add("status_id", model.SubmissionStatusUploaded)
 	if params.TargetAssetID.IsSet() {
 		smap.AddNotNil("target_asset_id", params.TargetAssetID.Value)
 	}
-	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusUploading}, smap)
+	return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusUploading}, smap)
 }