func CreatePostCreateIssueByAccident()

in pkg/server/meta/youtrack.go [76:220]


func CreatePostCreateIssueByAccident(metaDb *pgxpool.Pool) http.HandlerFunc {
	return func(writer http.ResponseWriter, request *http.Request) {
		response := CreateIssueResponse{}

		body := request.Body
		all, err := io.ReadAll(body)
		if err != nil {
			handleError(writer, "cannot read body", err, &response.Exceptions)
			_ = marshalAndWriteIssueResponse(writer, &response)
			return
		}

		defer body.Close()

		var params YoutrackCreateIssueRequest
		if err = json.Unmarshal(all, &params); err != nil {
			handleError(writer, "cannot unmarshal parameters", err, &response.Exceptions)
			_ = marshalAndWriteIssueResponse(writer, &response)
			return
		}

		relatedAccident, err := getAccidentById(request.Context(), metaDb, params.AccidentId)
		lowerKind := strings.ToLower(relatedAccident.Kind)

		if err != nil {
			handleError(writer, "cannot get accident", err, &response.Exceptions)
			_ = marshalAndWriteIssueResponse(writer, &response)
			return
		}

		affectedTest := relatedAccident.AffectedTest
		affectedMetric := params.AffectedMetric

		if strings.HasSuffix(affectedTest, affectedMetric) {
			affectedTest = strings.TrimSuffix(affectedTest, "/"+affectedMetric)
		}

		testHistoryUrl := ""
		if params.TestMethodName != nil && lowerKind == "exception" {
			testHistoryUrl, err = teamCityClient.getTestHistoryUrl(request.Context(), *params.TestMethodName)
		}

		if err != nil {
			logError("cannot get test history link", err, &response.Exceptions)
		}

		var commits *CommitRevisions
		if params.CurrentBuildId != nil {
			commits, err = teamCityClient.getChanges(request.Context(), strconv.Itoa(*params.CurrentBuildId))
			if err != nil {
				logError("cannot get commits from build", err, &response.Exceptions)
			}
		}

		descriptionData := GenerateDescriptionData{
			Kind:           lowerKind,
			AffectedTest:   affectedTest,
			AffectedMetric: affectedMetric,
			Delta:          params.Delta,
			StackTrace:     relatedAccident.Stacktrace,
			BuildLink:      params.BuildLink,
			Changes:        params.ChangesLink,
			DashboardLink:  params.DashboardLink,
			TestHistoryUrl: &testHistoryUrl,
			TestMethod:     params.TestMethodName,
			TestType:       params.TestType,
			Commits:        commits,
		}

		accessToken := request.Header.Get("X-Auth-Request-Access-Token")
		user, err := auth.FetchUserInfo(request.Context(), accessToken)
		if err != nil {
			slog.Warn("cannot fetch user info", "error", err)
		}

		userId, err := ytAuth.GetUser(request.Context(), user.Email)
		if err != nil {
			slog.Warn("error getting user id:", "error", err)
			userId = nil
		}
		issueInfo := CreateIssueInfo{
			Summary:     params.TicketLabel,
			Description: generateDescription(descriptionData),
			Project:     YoutrackProject{ID: params.ProjectId},
			Reporter:    userId,
			Visibility: Visibility{
				PermittedGroups: []auth.YTUser{{ID: "10-3"}},
				PermittedUsers:  []auth.YTUser{{ID: "11-1539792"}},
				Type:            "LimitedVisibility",
			},
			CustomFields: []CustomField{
				{
					Name: "Type",
					Type: "SingleEnumIssueCustomField",
					Value: struct {
						Name string `json:"name"`
					}{
						Name: "Performance Problem",
					},
				},
			},
		}

		setSubsystems(params, &issueInfo)

		projectsToSetVersionsFor := []string{
			"22-22",  // IJPL
			"22-619", // IDEA
			// 			"22-25",  // RUBY
			"22-414", // KTIJ
			"22-96",  // WEB,
		}

		if slices.Contains(projectsToSetVersionsFor, params.ProjectId) {
			latestAffectedVersion := getVersionFieldValue(params.ProjectId, "Affected versions", nil, request, response)
			baseVersion := strings.SplitN(latestAffectedVersion, " ", 2)[0]
			setVersionField("Affected versions", baseVersion, params, request, response, &issueInfo)
			setVersionField("Planned for", baseVersion, params, request, response, &issueInfo)
		}

		setPriority(params, &issueInfo)
		setTags(params, &issueInfo)

		issue, err := youtrackClient.CreateIssue(request.Context(), issueInfo)
		if err != nil {
			handleError(writer, "failed to create issue", err, &response.Exceptions)
			_ = marshalAndWriteIssueResponse(writer, &response)
			return
		}

		response.Issue = *issue

		err = marshalAndWriteIssueResponse(writer, &response)
		if err != nil {
			writer.WriteHeader(http.StatusInternalServerError)
			return
		}

		relatedAccident.Reason = fmt.Sprintf("%s: %s", issue.IDReadable, relatedAccident.Reason)
		err = updateAccidentReason(request.Context(), metaDb, relatedAccident)
		if err != nil {
			logError("unable to update accident reason", err, &response.Exceptions)
		}
	}
}