From c93698628bc3e019341b2dab834121dbafc4e77d Mon Sep 17 00:00:00 2001 From: Clay Benson Date: Wed, 13 Nov 2024 10:24:46 -0500 Subject: [PATCH] [NOREF] Split create milestone mutation (#1517) * feat: Split single resolver for creating milestones into 2 resolvers for creating custom and common milestones * Update postman collection and code comments * Missed comment --- MINT.postman_collection.json | 12 +- cmd/dbseed/mto.go | 16 +- migrations/V182__Add_MTO_Common_Milestone.sql | 4 +- pkg/graph/generated/generated.go | 215 +++++++++++++++--- pkg/graph/resolvers/mto_milestone.go | 41 +++- .../resolvers/mto_milestone.resolvers.go | 13 +- pkg/graph/schema/types/mto_milestone.graphql | 4 +- pkg/storage/mto_milestone.go | 8 + src/gql/generated/graphql.ts | 15 +- 9 files changed, 269 insertions(+), 59 deletions(-) diff --git a/MINT.postman_collection.json b/MINT.postman_collection.json index 3e81f3a911..015250cece 100644 --- a/MINT.postman_collection.json +++ b/MINT.postman_collection.json @@ -2996,13 +2996,13 @@ "name": "Milestones", "item": [ { - "name": "NewMTOMilestone", + "name": "NewMTOMilestone (Custom)", "event": [ { "listen": "test", "script": { "exec": [ - "let responseData = pm.response.json().data.createMTOMilestone", + "let responseData = pm.response.json().data.createMTOMilestoneCustom", "", "mtoMilestoneID = responseData.id", "", @@ -3020,7 +3020,7 @@ "body": { "mode": "graphql", "graphql": { - "query": "mutation NewMTOMilestone {\ncreateMTOMilestone(modelPlanID: \"{{modelPlanID}}\",\nname: \"Uncategorized milestone\"\n# commonMilestoneKey: MILESTONE_A\n# ,mtoCategoryID: \"{{mtoCategoryID}}\"\n# ,mtoCategoryID: \"{{mtoSubcategoryID}}\"\n) {\n id\n name\n addedFromMilestoneLibrary\n facilitatedBy\n needBy\n status\n riskIndicator\n # isDraftMilestone\n mtoCategoryID\n key\n\n # commonMilestone\n # solutions\n # category\n # subCategory\n }\n}", + "query": "mutation NewMTOMilestone {\n createMTOMilestoneCustom(modelPlanID: \"{{modelPlanID}}\",\n name: \"Uncategorized milestone\"\n # mtoCategoryID: \"\"\n) {\n id\n name\n addedFromMilestoneLibrary\n facilitatedBy\n needBy\n status\n riskIndicator\n # isDraftMilestone\n mtoCategoryID\n key\n\n # commonMilestone\n # solutions\n # category\n # subCategory\n }\n}", "variables": "" } }, @@ -3034,13 +3034,13 @@ "response": [] }, { - "name": "NewMTOMilestone From Common Milestone", + "name": "NewMTOMilestone (Common)", "event": [ { "listen": "test", "script": { "exec": [ - "let responseData = pm.response.json().data.createMTOMilestone", + "let responseData = pm.response.json().data.createMTOMilestoneCommon", "", "mtoMilestoneID = responseData.id", "", @@ -3058,7 +3058,7 @@ "body": { "mode": "graphql", "graphql": { - "query": "mutation NewMTOMilestone {\ncreateMTOMilestone(modelPlanID: \"{{modelPlanID}}\",\n# name: \"Uncategorized commonMilestone \"\ncommonMilestoneKey: MILESTONE_A\n# ,mtoCategoryID: \"{{mtoCategoryID}}\"\n# ,mtoCategoryID: \"{{mtoSubcategoryID}}\"\n) {\n id\n name\n key\n addedFromMilestoneLibrary\n facilitatedBy\n needBy\n status\n riskIndicator\n # isDraftMilestone\n mtoCategoryID\n\n # commonMilestone\n # solutions\n # category\n # subCategory\n }\n}", + "query": "mutation NewMTOMilestone {\n createMTOMilestoneCommon(modelPlanID: \"{{modelPlanID}}\",\n commonMilestoneKey: MILESTONE_A\n) {\n id\n name\n key\n addedFromMilestoneLibrary\n facilitatedBy\n needBy\n status\n riskIndicator\n # isDraftMilestone\n mtoCategoryID\n\n # commonMilestone\n # solutions\n # category\n # subCategory\n }\n}", "variables": "" } }, diff --git a/cmd/dbseed/mto.go b/cmd/dbseed/mto.go index aa674208f9..a18a08ebb2 100644 --- a/cmd/dbseed/mto.go +++ b/cmd/dbseed/mto.go @@ -4,7 +4,6 @@ import ( "github.com/google/uuid" "github.com/cms-enterprise/mint-app/pkg/graph/resolvers" - "github.com/cms-enterprise/mint-app/pkg/helpers" "github.com/cms-enterprise/mint-app/pkg/models" ) @@ -19,7 +18,8 @@ func (s *Seeder) seedModelPlanWithMTOData( princ := s.getTestPrincipalByUsername(euaID) // Make uncategorized Milestone from Common milestone library - _, err := resolvers.MTOMilestoneCreate(s.Config.Context, s.Config.Logger, princ, s.Config.Store, nil, helpers.PointerTo(models.MTOCommonMilestoneKeyMilestoneA), plan.ID, nil) + // TODO: This likely won't be uncategorized anymore once common milestones also create categories as needed + _, err := resolvers.MTOMilestoneCreateCommon(s.Config.Context, s.Config.Logger, princ, s.Config.Store, plan.ID, models.MTOCommonMilestoneKeyMilestoneA) if err != nil { panic(err) } @@ -62,29 +62,29 @@ func (s *Seeder) seedModelPlanWithMTOData( } // Make milestones to go under the categories - _, err = resolvers.MTOMilestoneCreate(s.Config.Context, s.Config.Logger, princ, s.Config.Store, helpers.PointerTo("Milestone"+cat1Name), nil, plan.ID, &category1.ID) + _, err = resolvers.MTOMilestoneCreateCustom(s.Config.Context, s.Config.Logger, princ, s.Config.Store, "Milestone"+cat1Name, plan.ID, &category1.ID) if err != nil { panic(err) } - _, err = resolvers.MTOMilestoneCreate(s.Config.Context, s.Config.Logger, princ, s.Config.Store, helpers.PointerTo("Milestone"+cat1SubAName), nil, plan.ID, &category1SubA.ID) + _, err = resolvers.MTOMilestoneCreateCustom(s.Config.Context, s.Config.Logger, princ, s.Config.Store, "Milestone"+cat1SubAName, plan.ID, &category1SubA.ID) if err != nil { panic(err) } - _, err = resolvers.MTOMilestoneCreate(s.Config.Context, s.Config.Logger, princ, s.Config.Store, helpers.PointerTo("Milestone"+cat1SubBName), nil, plan.ID, &category1SubB.ID) + _, err = resolvers.MTOMilestoneCreateCustom(s.Config.Context, s.Config.Logger, princ, s.Config.Store, "Milestone"+cat1SubBName, plan.ID, &category1SubB.ID) if err != nil { panic(err) } // Make milestones to go under the categories - _, err = resolvers.MTOMilestoneCreate(s.Config.Context, s.Config.Logger, princ, s.Config.Store, helpers.PointerTo("Milestone"+cat2Name), nil, plan.ID, &category2.ID) + _, err = resolvers.MTOMilestoneCreateCustom(s.Config.Context, s.Config.Logger, princ, s.Config.Store, "Milestone"+cat2Name, plan.ID, &category2.ID) if err != nil { panic(err) } - _, err = resolvers.MTOMilestoneCreate(s.Config.Context, s.Config.Logger, princ, s.Config.Store, helpers.PointerTo("Milestone"+cat2SubAName), nil, plan.ID, &category2SubA.ID) + _, err = resolvers.MTOMilestoneCreateCustom(s.Config.Context, s.Config.Logger, princ, s.Config.Store, "Milestone"+cat2SubAName, plan.ID, &category2SubA.ID) if err != nil { panic(err) } - _, err = resolvers.MTOMilestoneCreate(s.Config.Context, s.Config.Logger, princ, s.Config.Store, helpers.PointerTo("Milestone"+cat2SubBName), nil, plan.ID, &category2SubB.ID) + _, err = resolvers.MTOMilestoneCreateCustom(s.Config.Context, s.Config.Logger, princ, s.Config.Store, "Milestone"+cat2SubBName, plan.ID, &category2SubB.ID) if err != nil { panic(err) } diff --git a/migrations/V182__Add_MTO_Common_Milestone.sql b/migrations/V182__Add_MTO_Common_Milestone.sql index 25e4da1a15..d4b70cbe56 100644 --- a/migrations/V182__Add_MTO_Common_Milestone.sql +++ b/migrations/V182__Add_MTO_Common_Milestone.sql @@ -7,8 +7,8 @@ CREATE TABLE mto_common_milestone ( key MTO_COMMON_MILESTONE_KEY NOT NULL PRIMARY KEY, name ZERO_STRING NOT NULL, - category_name ZERO_STRING NOT NULL, - sub_category_name ZERO_STRING NOT NULL, + category_name ZERO_STRING NOT NULL, -- TODO: Revisit if this should be NOT NULL + sub_category_name ZERO_STRING NOT NULL, -- TODO: Revisit if this should be NOT NULL, and if common milestones _actually_ have subCategories description ZERO_STRING NOT NULL, -- TODO (mto) is this needed? facilitated_by_role MTO_FACILITATOR NOT NULL ); diff --git a/pkg/graph/generated/generated.go b/pkg/graph/generated/generated.go index a7ffdabd29..e1cc201a96 100644 --- a/pkg/graph/generated/generated.go +++ b/pkg/graph/generated/generated.go @@ -514,7 +514,8 @@ type ComplexityRoot struct { AgreeToNda func(childComplexity int, agree bool) int CreateDiscussionReply func(childComplexity int, input model.DiscussionReplyCreateInput) int CreateMTOCategory func(childComplexity int, modelPlanID uuid.UUID, name string, parentID *uuid.UUID) int - CreateMTOMilestone func(childComplexity int, modelPlanID uuid.UUID, name *string, commonMilestoneKey *models.MTOCommonMilestoneKey, mtoCategoryID *uuid.UUID) int + CreateMTOMilestoneCommon func(childComplexity int, modelPlanID uuid.UUID, commonMilestoneKey models.MTOCommonMilestoneKey) int + CreateMTOMilestoneCustom func(childComplexity int, modelPlanID uuid.UUID, name string, mtoCategoryID *uuid.UUID) int CreateModelPlan func(childComplexity int, modelName string) int CreateOperationalSolution func(childComplexity int, operationalNeedID uuid.UUID, solutionType *models.OperationalSolutionKey, changes map[string]interface{}) int CreateOperationalSolutionSubtasks func(childComplexity int, solutionID uuid.UUID, inputs []*model.CreateOperationalSolutionSubtaskInput) int @@ -2346,7 +2347,8 @@ type MutationResolver interface { ShareModelPlan(ctx context.Context, modelPlanID uuid.UUID, viewFilter *models.ModelViewFilter, usernames []string, optionalMessage *string) (bool, error) CreateMTOCategory(ctx context.Context, modelPlanID uuid.UUID, name string, parentID *uuid.UUID) (*models.MTOCategory, error) UpdateMTOCategory(ctx context.Context, id uuid.UUID, name string) (*models.MTOCategory, error) - CreateMTOMilestone(ctx context.Context, modelPlanID uuid.UUID, name *string, commonMilestoneKey *models.MTOCommonMilestoneKey, mtoCategoryID *uuid.UUID) (*models.MTOMilestone, error) + CreateMTOMilestoneCustom(ctx context.Context, modelPlanID uuid.UUID, name string, mtoCategoryID *uuid.UUID) (*models.MTOMilestone, error) + CreateMTOMilestoneCommon(ctx context.Context, modelPlanID uuid.UUID, commonMilestoneKey models.MTOCommonMilestoneKey) (*models.MTOMilestone, error) UpdateMTOMilestone(ctx context.Context, id uuid.UUID, changes map[string]interface{}) (*models.MTOMilestone, error) AgreeToNda(ctx context.Context, agree bool) (*model.NDAInfo, error) AddOrUpdateCustomOperationalNeed(ctx context.Context, modelPlanID uuid.UUID, customNeedType string, needed bool) (*models.OperationalNeed, error) @@ -4750,17 +4752,29 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.CreateMTOCategory(childComplexity, args["modelPlanID"].(uuid.UUID), args["name"].(string), args["parentID"].(*uuid.UUID)), true - case "Mutation.createMTOMilestone": - if e.complexity.Mutation.CreateMTOMilestone == nil { + case "Mutation.createMTOMilestoneCommon": + if e.complexity.Mutation.CreateMTOMilestoneCommon == nil { break } - args, err := ec.field_Mutation_createMTOMilestone_args(context.TODO(), rawArgs) + args, err := ec.field_Mutation_createMTOMilestoneCommon_args(context.TODO(), rawArgs) if err != nil { return 0, false } - return e.complexity.Mutation.CreateMTOMilestone(childComplexity, args["modelPlanID"].(uuid.UUID), args["name"].(*string), args["commonMilestoneKey"].(*models.MTOCommonMilestoneKey), args["mtoCategoryID"].(*uuid.UUID)), true + return e.complexity.Mutation.CreateMTOMilestoneCommon(childComplexity, args["modelPlanID"].(uuid.UUID), args["commonMilestoneKey"].(models.MTOCommonMilestoneKey)), true + + case "Mutation.createMTOMilestoneCustom": + if e.complexity.Mutation.CreateMTOMilestoneCustom == nil { + break + } + + args, err := ec.field_Mutation_createMTOMilestoneCustom_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.CreateMTOMilestoneCustom(childComplexity, args["modelPlanID"].(uuid.UUID), args["name"].(string), args["mtoCategoryID"].(*uuid.UUID)), true case "Mutation.createModelPlan": if e.complexity.Mutation.CreateModelPlan == nil { @@ -16691,7 +16705,9 @@ input MTOMilestoneChanges @goModel(model: "map[string]interface{}") { } extend type Mutation { - createMTOMilestone(modelPlanID: UUID!, name: String, commonMilestoneKey: MTOCommonMilestoneKey, mtoCategoryID: UUID): MTOMilestone! + createMTOMilestoneCustom(modelPlanID: UUID!, name: String!, mtoCategoryID: UUID): MTOMilestone! + @hasRole(role: MINT_USER) + createMTOMilestoneCommon(modelPlanID: UUID!, commonMilestoneKey: MTOCommonMilestoneKey!): MTOMilestone! @hasRole(role: MINT_USER) updateMTOMilestone(id: UUID!, changes: MTOMilestoneChanges!): MTOMilestone! @hasRole(role: MINT_USER) @@ -20901,7 +20917,7 @@ func (ec *executionContext) field_Mutation_createMTOCategory_args(ctx context.Co return args, nil } -func (ec *executionContext) field_Mutation_createMTOMilestone_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { +func (ec *executionContext) field_Mutation_createMTOMilestoneCommon_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} var arg0 uuid.UUID @@ -20913,33 +20929,48 @@ func (ec *executionContext) field_Mutation_createMTOMilestone_args(ctx context.C } } args["modelPlanID"] = arg0 - var arg1 *string - if tmp, ok := rawArgs["name"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) - arg1, err = ec.unmarshalOString2ᚖstring(ctx, tmp) + var arg1 models.MTOCommonMilestoneKey + if tmp, ok := rawArgs["commonMilestoneKey"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("commonMilestoneKey")) + arg1, err = ec.unmarshalNMTOCommonMilestoneKey2githubᚗcomᚋcmsᚑenterpriseᚋmintᚑappᚋpkgᚋmodelsᚐMTOCommonMilestoneKey(ctx, tmp) if err != nil { return nil, err } } - args["name"] = arg1 - var arg2 *models.MTOCommonMilestoneKey - if tmp, ok := rawArgs["commonMilestoneKey"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("commonMilestoneKey")) - arg2, err = ec.unmarshalOMTOCommonMilestoneKey2ᚖgithubᚗcomᚋcmsᚑenterpriseᚋmintᚑappᚋpkgᚋmodelsᚐMTOCommonMilestoneKey(ctx, tmp) + args["commonMilestoneKey"] = arg1 + return args, nil +} + +func (ec *executionContext) field_Mutation_createMTOMilestoneCustom_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 uuid.UUID + if tmp, ok := rawArgs["modelPlanID"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("modelPlanID")) + arg0, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, tmp) + if err != nil { + return nil, err + } + } + args["modelPlanID"] = arg0 + var arg1 string + if tmp, ok := rawArgs["name"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + arg1, err = ec.unmarshalNString2string(ctx, tmp) if err != nil { return nil, err } } - args["commonMilestoneKey"] = arg2 - var arg3 *uuid.UUID + args["name"] = arg1 + var arg2 *uuid.UUID if tmp, ok := rawArgs["mtoCategoryID"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("mtoCategoryID")) - arg3, err = ec.unmarshalOUUID2ᚖgithubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, tmp) + arg2, err = ec.unmarshalOUUID2ᚖgithubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, tmp) if err != nil { return nil, err } } - args["mtoCategoryID"] = arg3 + args["mtoCategoryID"] = arg2 return args, nil } @@ -38732,8 +38763,129 @@ func (ec *executionContext) fieldContext_Mutation_updateMTOCategory(ctx context. return fc, nil } -func (ec *executionContext) _Mutation_createMTOMilestone(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Mutation_createMTOMilestone(ctx, field) +func (ec *executionContext) _Mutation_createMTOMilestoneCustom(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_createMTOMilestoneCustom(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().CreateMTOMilestoneCustom(rctx, fc.Args["modelPlanID"].(uuid.UUID), fc.Args["name"].(string), fc.Args["mtoCategoryID"].(*uuid.UUID)) + } + directive1 := func(ctx context.Context) (interface{}, error) { + role, err := ec.unmarshalNRole2githubᚗcomᚋcmsᚑenterpriseᚋmintᚑappᚋpkgᚋgraphᚋmodelᚐRole(ctx, "MINT_USER") + if err != nil { + return nil, err + } + if ec.directives.HasRole == nil { + return nil, errors.New("directive hasRole is not implemented") + } + return ec.directives.HasRole(ctx, nil, directive0, role) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(*models.MTOMilestone); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/cms-enterprise/mint-app/pkg/models.MTOMilestone`, tmp) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*models.MTOMilestone) + fc.Result = res + return ec.marshalNMTOMilestone2ᚖgithubᚗcomᚋcmsᚑenterpriseᚋmintᚑappᚋpkgᚋmodelsᚐMTOMilestone(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_createMTOMilestoneCustom(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_MTOMilestone_id(ctx, field) + case "name": + return ec.fieldContext_MTOMilestone_name(ctx, field) + case "key": + return ec.fieldContext_MTOMilestone_key(ctx, field) + case "mtoCategoryID": + return ec.fieldContext_MTOMilestone_mtoCategoryID(ctx, field) + case "facilitatedBy": + return ec.fieldContext_MTOMilestone_facilitatedBy(ctx, field) + case "needBy": + return ec.fieldContext_MTOMilestone_needBy(ctx, field) + case "status": + return ec.fieldContext_MTOMilestone_status(ctx, field) + case "riskIndicator": + return ec.fieldContext_MTOMilestone_riskIndicator(ctx, field) + case "isDraft": + return ec.fieldContext_MTOMilestone_isDraft(ctx, field) + case "createdBy": + return ec.fieldContext_MTOMilestone_createdBy(ctx, field) + case "createdByUserAccount": + return ec.fieldContext_MTOMilestone_createdByUserAccount(ctx, field) + case "createdDts": + return ec.fieldContext_MTOMilestone_createdDts(ctx, field) + case "modifiedBy": + return ec.fieldContext_MTOMilestone_modifiedBy(ctx, field) + case "modifiedByUserAccount": + return ec.fieldContext_MTOMilestone_modifiedByUserAccount(ctx, field) + case "modifiedDts": + return ec.fieldContext_MTOMilestone_modifiedDts(ctx, field) + case "addedFromMilestoneLibrary": + return ec.fieldContext_MTOMilestone_addedFromMilestoneLibrary(ctx, field) + case "commonMilestone": + return ec.fieldContext_MTOMilestone_commonMilestone(ctx, field) + case "solutions": + return ec.fieldContext_MTOMilestone_solutions(ctx, field) + case "category": + return ec.fieldContext_MTOMilestone_category(ctx, field) + case "subCategory": + return ec.fieldContext_MTOMilestone_subCategory(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type MTOMilestone", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Mutation_createMTOMilestoneCustom_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_createMTOMilestoneCommon(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_createMTOMilestoneCommon(ctx, field) if err != nil { return graphql.Null } @@ -38747,7 +38899,7 @@ func (ec *executionContext) _Mutation_createMTOMilestone(ctx context.Context, fi resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { directive0 := func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().CreateMTOMilestone(rctx, fc.Args["modelPlanID"].(uuid.UUID), fc.Args["name"].(*string), fc.Args["commonMilestoneKey"].(*models.MTOCommonMilestoneKey), fc.Args["mtoCategoryID"].(*uuid.UUID)) + return ec.resolvers.Mutation().CreateMTOMilestoneCommon(rctx, fc.Args["modelPlanID"].(uuid.UUID), fc.Args["commonMilestoneKey"].(models.MTOCommonMilestoneKey)) } directive1 := func(ctx context.Context) (interface{}, error) { role, err := ec.unmarshalNRole2githubᚗcomᚋcmsᚑenterpriseᚋmintᚑappᚋpkgᚋgraphᚋmodelᚐRole(ctx, "MINT_USER") @@ -38787,7 +38939,7 @@ func (ec *executionContext) _Mutation_createMTOMilestone(ctx context.Context, fi return ec.marshalNMTOMilestone2ᚖgithubᚗcomᚋcmsᚑenterpriseᚋmintᚑappᚋpkgᚋmodelsᚐMTOMilestone(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Mutation_createMTOMilestone(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Mutation_createMTOMilestoneCommon(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Mutation", Field: field, @@ -38846,7 +38998,7 @@ func (ec *executionContext) fieldContext_Mutation_createMTOMilestone(ctx context } }() ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Mutation_createMTOMilestone_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + if fc.Args, err = ec.field_Mutation_createMTOMilestoneCommon_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) return fc, err } @@ -135701,9 +135853,16 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { out.Invalids++ } - case "createMTOMilestone": + case "createMTOMilestoneCustom": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_createMTOMilestoneCustom(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "createMTOMilestoneCommon": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { - return ec._Mutation_createMTOMilestone(ctx, field) + return ec._Mutation_createMTOMilestoneCommon(ctx, field) }) if out.Values[i] == graphql.Null { out.Invalids++ diff --git a/pkg/graph/resolvers/mto_milestone.go b/pkg/graph/resolvers/mto_milestone.go index 7debc30466..8faa450a80 100644 --- a/pkg/graph/resolvers/mto_milestone.go +++ b/pkg/graph/resolvers/mto_milestone.go @@ -13,10 +13,9 @@ import ( "github.com/cms-enterprise/mint-app/pkg/storage/loaders" ) -// MTOMilestoneCreate uses the provided information to create a new mto Milestone -func MTOMilestoneCreate(ctx context.Context, logger *zap.Logger, principal authentication.Principal, store *storage.Store, - name *string, - commonMilestoneKey *models.MTOCommonMilestoneKey, +// MTOMilestoneCreateCustom uses the provided information to create a new Custom MTO Milestone +func MTOMilestoneCreateCustom(ctx context.Context, logger *zap.Logger, principal authentication.Principal, store *storage.Store, + name string, modelPlanID uuid.UUID, mtoCategoryID *uuid.UUID, ) (*models.MTOMilestone, error) { @@ -24,13 +23,41 @@ func MTOMilestoneCreate(ctx context.Context, logger *zap.Logger, principal authe if principalAccount == nil { return nil, fmt.Errorf("principal doesn't have an account, username %s", principal.String()) } - Milestone := models.NewMTOMilestone(principalAccount.ID, name, commonMilestoneKey, modelPlanID, mtoCategoryID) - err := BaseStructPreCreate(logger, Milestone, principal, store, true) + // A custom milestone never has a CommonMilestoneKey, so pass in `nil` + milestone := models.NewMTOMilestone(principalAccount.ID, &name, nil, modelPlanID, mtoCategoryID) + + err := BaseStructPreCreate(logger, milestone, principal, store, true) + if err != nil { + return nil, err + } + return storage.MTOMilestoneCreate(store, logger, milestone) +} + +// MTOMilestoneCreateCommon uses the provided information to create a new Custom MTO Milestone +func MTOMilestoneCreateCommon(ctx context.Context, logger *zap.Logger, principal authentication.Principal, store *storage.Store, + modelPlanID uuid.UUID, + commonMilestoneKey models.MTOCommonMilestoneKey, +) (*models.MTOMilestone, error) { + principalAccount := principal.Account() + if principalAccount == nil { + return nil, fmt.Errorf("principal doesn't have an account, username %s", principal.String()) + } + + // TODO Build a query (loader? transaction?) to do the following + // 1) Find the Common Milestone object in the DB + // 2) Determine if a Category Exists for this Model Plan that has the same name as the one configured for the Common Milestone + // 3) If not, create that new category + + // A common milestone never has a name (since it comes from the Common Milestone itself), so pass in `nil` + // TODO: Update category ID based on query from above + milestone := models.NewMTOMilestone(principalAccount.ID, nil, &commonMilestoneKey, modelPlanID, nil) + + err := BaseStructPreCreate(logger, milestone, principal, store, true) if err != nil { return nil, err } - return storage.MTOMilestoneCreate(store, logger, Milestone) + return storage.MTOMilestoneCreate(store, logger, milestone) } // MTOMilestoneUpdate updates the name of MTOMilestone or SubMilestone diff --git a/pkg/graph/resolvers/mto_milestone.resolvers.go b/pkg/graph/resolvers/mto_milestone.resolvers.go index 432c0ea651..d47a6c9ecd 100644 --- a/pkg/graph/resolvers/mto_milestone.resolvers.go +++ b/pkg/graph/resolvers/mto_milestone.resolvers.go @@ -40,11 +40,18 @@ func (r *mTOMilestoneResolver) SubCategory(ctx context.Context, obj *models.MTOM panic(fmt.Errorf("not implemented: SubCategory - subCategory")) } -// CreateMTOMilestone is the resolver for the createMTOMilestone field. -func (r *mutationResolver) CreateMTOMilestone(ctx context.Context, modelPlanID uuid.UUID, name *string, commonMilestoneKey *models.MTOCommonMilestoneKey, mtoCategoryID *uuid.UUID) (*models.MTOMilestone, error) { +// CreateMTOMilestoneCustom is the resolver for the createMTOMilestoneCustom field. +func (r *mutationResolver) CreateMTOMilestoneCustom(ctx context.Context, modelPlanID uuid.UUID, name string, mtoCategoryID *uuid.UUID) (*models.MTOMilestone, error) { principal := appcontext.Principal(ctx) logger := appcontext.ZLogger(ctx) - return MTOMilestoneCreate(ctx, logger, principal, r.store, name, commonMilestoneKey, modelPlanID, mtoCategoryID) + return MTOMilestoneCreateCustom(ctx, logger, principal, r.store, name, modelPlanID, mtoCategoryID) +} + +// CreateMTOMilestoneCommon is the resolver for the createMTOMilestoneCommon field. +func (r *mutationResolver) CreateMTOMilestoneCommon(ctx context.Context, modelPlanID uuid.UUID, commonMilestoneKey models.MTOCommonMilestoneKey) (*models.MTOMilestone, error) { + principal := appcontext.Principal(ctx) + logger := appcontext.ZLogger(ctx) + return MTOMilestoneCreateCommon(ctx, logger, principal, r.store, modelPlanID, commonMilestoneKey) } // UpdateMTOMilestone is the resolver for the updateMTOMilestone field. diff --git a/pkg/graph/schema/types/mto_milestone.graphql b/pkg/graph/schema/types/mto_milestone.graphql index f97b7ffbe2..a514195d0f 100644 --- a/pkg/graph/schema/types/mto_milestone.graphql +++ b/pkg/graph/schema/types/mto_milestone.graphql @@ -59,7 +59,9 @@ input MTOMilestoneChanges @goModel(model: "map[string]interface{}") { } extend type Mutation { - createMTOMilestone(modelPlanID: UUID!, name: String, commonMilestoneKey: MTOCommonMilestoneKey, mtoCategoryID: UUID): MTOMilestone! + createMTOMilestoneCustom(modelPlanID: UUID!, name: String!, mtoCategoryID: UUID): MTOMilestone! + @hasRole(role: MINT_USER) + createMTOMilestoneCommon(modelPlanID: UUID!, commonMilestoneKey: MTOCommonMilestoneKey!): MTOMilestone! @hasRole(role: MINT_USER) updateMTOMilestone(id: UUID!, changes: MTOMilestoneChanges!): MTOMilestone! @hasRole(role: MINT_USER) diff --git a/pkg/storage/mto_milestone.go b/pkg/storage/mto_milestone.go index 84f3dafa1b..e30bdfcf2a 100644 --- a/pkg/storage/mto_milestone.go +++ b/pkg/storage/mto_milestone.go @@ -47,6 +47,10 @@ func MTOMilestoneGetByModelPlanIDAndCategoryIDLoader(np sqlutils.NamedPreparer, } // MTOMilestoneCreate creates a new MTOMilestone in the database +// +// NOTE: This method is used for creating both Custom and Library-sourced (Common) milestones. It WILL return an error +// if you try to create one that has both custom info (like a `name`) and a CommonMilestoneKey +// This is controlled not by application code, but by constraints initially added in this migration: migrations/V185__Add_MTO_Milestone.sql func MTOMilestoneCreate(np sqlutils.NamedPreparer, _ *zap.Logger, MTOMilestone *models.MTOMilestone) (*models.MTOMilestone, error) { if MTOMilestone.ID == uuid.Nil { MTOMilestone.ID = uuid.New() @@ -60,6 +64,10 @@ func MTOMilestoneCreate(np sqlutils.NamedPreparer, _ *zap.Logger, MTOMilestone * } // MTOMilestoneUpdate updates a new MTOMilestone in the database +// +// NOTE: This method is used for updating both Custom and Library-sourced (Common) milestones. It WILL return an error +// if you try to update one that has both custom info (like a `name`) and a CommonMilestoneKey +// This is controlled not by application code, but by constraints initially added in this migration: migrations/V185__Add_MTO_Milestone.sql func MTOMilestoneUpdate(np sqlutils.NamedPreparer, _ *zap.Logger, MTOMilestone *models.MTOMilestone) (*models.MTOMilestone, error) { returned, procErr := sqlutils.GetProcedure[models.MTOMilestone](np, sqlqueries.MTOMilestone.Update, MTOMilestone) if procErr != nil { diff --git a/src/gql/generated/graphql.ts b/src/gql/generated/graphql.ts index 4748959ade..288c5212be 100644 --- a/src/gql/generated/graphql.ts +++ b/src/gql/generated/graphql.ts @@ -1092,7 +1092,8 @@ export type Mutation = { * Note, the parent must belong to the same model plan, or this will return an error */ createMTOCategory: MtoCategory; - createMTOMilestone: MtoMilestone; + createMTOMilestoneCommon: MtoMilestone; + createMTOMilestoneCustom: MtoMilestone; createModelPlan: ModelPlan; createOperationalSolution: OperationalSolution; createOperationalSolutionSubtasks?: Maybe>; @@ -1187,11 +1188,17 @@ export type MutationCreateMtoCategoryArgs = { /** Mutations definition for the schema */ -export type MutationCreateMtoMilestoneArgs = { - commonMilestoneKey?: InputMaybe; +export type MutationCreateMtoMilestoneCommonArgs = { + commonMilestoneKey: MtoCommonMilestoneKey; + modelPlanID: Scalars['UUID']['input']; +}; + + +/** Mutations definition for the schema */ +export type MutationCreateMtoMilestoneCustomArgs = { modelPlanID: Scalars['UUID']['input']; mtoCategoryID?: InputMaybe; - name?: InputMaybe; + name: Scalars['String']['input']; };