public async Task <IActionResult> CreateProjectFeature(Guid organizationId, Guid projectId, [FromBody] ProjectFeaturePostRp projectFeatureRp)
        {
            if (!ModelState.IsValid)
            {
                return(this.BadRequest(ModelState));
            }

            await _projectFeatureService.CreateProjectFeature(organizationId, projectId, projectFeatureRp);

            if (_domainManagerService.HasNotFounds())
            {
                return(this.NotFound(_domainManagerService.GetNotFounds()));
            }

            if (_domainManagerService.HasForbidden())
            {
                return(this.Forbidden(_domainManagerService.GetForbidden()));
            }

            if (_domainManagerService.HasConflicts())
            {
                return(this.Conflict(_domainManagerService.GetConflicts()));
            }

            return(this.Ok(new { FeatureId = await _domainManagerService.GetResult <Guid>("FeatureId") }));
        }
        public async Task CreateProjectFeature(Guid organizationId, Guid projectId, ProjectFeaturePostRp resource)
        {
            string loggedUserId = _identityService.GetUserId();

            DomainModels.User user = await _userRepository.GetUser(loggedUserId);

            DomainModels.Organization organization = user.FindOrganizationById(organizationId);
            if (organization == null)
            {
                await _domainManagerService.AddNotFound($"The organzation with id {organizationId} does not exists.");

                return;
            }

            DomainModels.Project project = user.FindProjectById(projectId);
            if (project == null)
            {
                await _domainManagerService.AddNotFound($"The project with id {projectId} does not exists.");

                return;
            }

            DomainModels.PipelineRole role = user.GetRoleInProject(projectId);
            if (role != DomainModels.PipelineRole.ProjectAdmin)
            {
                await _domainManagerService.AddForbidden($"You are not authorized to create features in this project.");

                return;
            }

            if (project.Status != DomainModels.EntityStatus.Active)
            {
                await _domainManagerService.AddConflict($"The project with id {projectId} must be in status Active to add a new feature.");

                return;
            }

            if (resource.Services.Length == 0)
            {
                await _domainManagerService.AddConflict($"At least one pipe must be included in the feature.");

                return;
            }

            var preparingServices = project.GetPreparingServices();

            if (preparingServices.Any())
            {
                await _domainManagerService.AddConflict($"The project with id {projectId} has pipes in status Preparing. All services must be in status Active to create a new feature");

                return;
            }

            DomainModels.ProjectFeature existingFeature = project.GetFeatureByName(resource.Name);
            if (existingFeature != null)
            {
                await _domainManagerService.AddConflict($"The feature name {resource.Name} has already been taken.");

                return;
            }

            DomainModels.ProjectFeature newFeature = user.CreateProjectFeature(organizationId, projectId, resource.Name, resource.Description);

            //services asociated (TODO: services on demand)
            List <ProjectFeatureServiceCreatedEvent> @events = new List <ProjectFeatureServiceCreatedEvent>();

            foreach (var item in resource.Services)
            {
                DomainModels.ProjectService projectService = project.GetServiceById(item);
                if (projectService == null)
                {
                    await _domainManagerService.AddConflict($"The pipe id {item} does not exists.");

                    return;
                }

                var variables = projectService.Environments.First(x => x.ProjectEnvironment.Type == EnvironmentType.Root).Variables;

                newFeature.AddService(item, variables);

                var serviceCredential = this._cloudCredentialService.ProjectServiceCredentialResolver(project, projectService);

                @events.Add(new ProjectFeatureServiceCreatedEvent(_correlationId)
                {
                    ServiceId                  = item,
                    ServiceExternalId          = projectService.ProjectServiceExternalId,
                    ServiceExternalUrl         = projectService.ProjectServiceExternalUrl,
                    ServiceName                = projectService.Name,
                    InternalServiceName        = projectService.InternalName,
                    ServiceTemplateUrl         = serviceCredential.BranchUrl,
                    ReleaseStageId             = projectService.ReleaseStageId,
                    AgentPoolId                = project.AgentPoolId,
                    OrganizationId             = organization.OrganizationId,
                    ProjectId                  = project.ProjectId,
                    FeatureId                  = newFeature.ProjectFeatureId,
                    ProjectExternalId          = serviceCredential.ProjectExternalId,
                    ProjectExternalEndpointId  = project.ProjectExternalEndpointId,
                    ProjectExternalGitEndpoint = project.ProjectExternalGitEndpoint,
                    ProjectVSTSFakeName        = project.ProjectVSTSFakeName,
                    ProjectVSTSFakeId          = project.ProjectVSTSFakeId,
                    OrganizationName           = organization.Name,
                    ProjectName                = serviceCredential.ProjectName,
                    FeatureName                = newFeature.Name,
                    CMSType                = serviceCredential.CMSType,
                    CMSAccountId           = serviceCredential.AccountId,
                    CMSAccountName         = serviceCredential.AccountName,
                    CMSAccessId            = serviceCredential.AccessId,
                    CMSAccessSecret        = serviceCredential.AccessSecret,
                    CMSAccessToken         = serviceCredential.AccessToken,
                    CPSType                = project.OrganizationCPS.Type,
                    CPSAccessId            = _dataProtectorService.Unprotect(project.OrganizationCPS.AccessId),
                    CPSAccessName          = _dataProtectorService.Unprotect(project.OrganizationCPS.AccessName),
                    CPSAccessSecret        = _dataProtectorService.Unprotect(project.OrganizationCPS.AccessSecret),
                    CPSAccessRegion        = _dataProtectorService.Unprotect(project.OrganizationCPS.AccessRegion),
                    TemplateAccess         = projectService.ProjectServiceTemplate.TemplateAccess,
                    IsImported             = projectService.IsImported,
                    NeedCredentials        = projectService.ProjectServiceTemplate.NeedCredentials,
                    RepositoryCMSType      = serviceCredential.CMSType,
                    RepositoryAccessId     = serviceCredential.AccessId,
                    RepositoryAccessSecret = serviceCredential.AccessSecret,
                    RepositoryAccessToken  = serviceCredential.AccessToken,
                    UserId = loggedUserId
                });
            }

            _userRepository.Update(user);

            await _userRepository.SaveChanges();

            await _domainManagerService.AddResult("FeatureId", newFeature.ProjectFeatureId);

            //send events
            foreach (var @event in @events)
            {
                await _eventBusService.Publish(queueName : "ProjectFeatureServiceCreatedEvent", @event : @event);
            }
        }