defmodule MedicalTranscription.Feedback do @moduledoc """ Context for managing user feedback on transcribed text and codes. """ alias MedicalTranscription.Feedback.CodeFeedback alias MedicalTranscription.Repo import Ecto.Query, only: [from: 2] import Pgvector.Ecto.Query, only: [cosine_distance: 2] def track_response(params) do changeset = CodeFeedback.changeset(%CodeFeedback{}, params) case Repo.insert(changeset) do {:ok, _code_feedback} -> {:ok, message_for_response(params)} {:error, changeset} -> {:error, Repo.collect_errors(changeset)} end end defp message_for_response(params) do action = if params["response"] == "true", do: "upvoted", else: "downvoted" "Successfully #{action} code" end @doc """ Given a portion of transcribed text, finds the most-relevant previous feedback for that transcribed text. The response from this previous feedback can then be used to modify the weight for the associated code when classifying this `text`. """ def find_related_feedback(search_vector, opts \\ []) do k = Keyword.get(opts, :num_results, 5) similarity_threshold = Keyword.get(opts, :similarity_threshold, 0.80) query = from f in CodeFeedback, order_by: cosine_distance(f.text_vector, ^search_vector), where: 1 - cosine_distance(f.text_vector, ^search_vector) > ^similarity_threshold, limit: ^k, select: %{ code_vector_id: f.code_vector_id, response: f.response, cosine_similarity: 1 - cosine_distance(f.text_vector, ^search_vector) } Repo.all(query) end end