Skip to content

Commit

Permalink
Fix issues with string/atom mix in changeset
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanIvanoff committed Jan 21, 2025
1 parent 062f109 commit f21f512
Show file tree
Hide file tree
Showing 19 changed files with 355 additions and 50 deletions.
2 changes: 1 addition & 1 deletion lib/sanbase/discord_bot/ai_server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ defmodule Sanbase.DiscordBot.AiServer do
end

# current version of bot
def answer(question, discord_metadata \\ %{}) do
def answer(question, discord_metadata) when is_map(discord_metadata) do
url = "#{ai_server_url()}/question"

route_blacklist =
Expand Down
4 changes: 3 additions & 1 deletion lib/sanbase/metric/registry/change_suggestion.ex
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ defmodule Sanbase.Metric.Registry.ChangeSuggestion do
# After change suggestion is applied, put the metric in a unverified state and mark
# is as not synced. Someone needs to manually verify the metric after it is tested.
# When the data is synced between stage and prod, the sync status will be updated.
# Note: Keep the keys as strings, not atoms, so the map is not mixed

# Convert all keys to strings so we don't get error if atom keys come from some caller
params = Map.new(params, fn {k, v} -> {to_string(k), v} end)
params = Map.merge(params, %{"is_verified" => false, "sync_status" => "not_synced"})

case Registry.changeset(registry, params) do
Expand Down
30 changes: 30 additions & 0 deletions lib/sanbase/metric/registry/permissions.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
defmodule Sanbase.Metric.Registry.Permissions do
def can?(:create, _) do
# Will depend on the user roles as well
deployment_env() == "stage" or (deployment_env() == "dev" and not aws_db_url?())
end

def can?(:edit, _) do
# Will depend on the user roles as well
deployment_env() == "stage" or (deployment_env() == "dev" and not aws_db_url?())
end

def can?(:start_sync, _) do
# Will depend on the user roles as well
deployment_env() == "stage" or (deployment_env() == "dev" and not aws_db_url?())
end

def can?(:apply_change_suggestions, _) do
# Will depend on the user roles
true
end

defp deployment_env() do
Sanbase.Utils.Config.module_get(Sanbase, :deployment_env)
end

defp aws_db_url?() do
db_url = System.get_env("DATABASE_URL")
is_binary(db_url) and db_url =~ "aws"
end
end
26 changes: 24 additions & 2 deletions lib/sanbase/metric/registry/sync.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,33 @@ defmodule Sanbase.Metric.Registry.Sync do
source of truth.
"""

alias Hex.Solver.Registry
alias Sanbase.Metric.Registry
alias Sanbase.Utils.Config

import Sanbase.Utils.ErrorHandling, only: [changeset_errors_string: 1]
require Logger

def by_uuid(uuid), do: Registry.SyncSchema.by_uuid(uuid)

def cancel_run(uuid) do
case Registry.SyncSchema.by_uuid(uuid) do
{:ok, sync} ->
case Registry.SyncSchema.update_status(sync, "cancelled", "Manually canceled") do
{:ok, sync} ->
{:ok, sync}

{:error, %Ecto.Changeset{} = changeset} ->
{:error, "Failed to cancel the sync. Error: #{changeset_errors_string(changeset)}"}
end

{:error, _} ->
{:error, "Sync not found"}
end
end

@doc ~s"""
TODO
Start a sync that will sync the not synced metrics from stage to prod
"""
@spec sync(list(non_neg_integer())) :: :ok
def sync(metric_registry_ids) when is_list(metric_registry_ids) do
Expand Down Expand Up @@ -55,6 +73,10 @@ defmodule Sanbase.Metric.Registry.Sync do
end
end

def last_syncs(limit) do
Registry.SyncSchema.last_syncs(limit)
end

# Private functions

defp send_sync_completed_confirmation(url) do
Expand Down Expand Up @@ -95,7 +117,7 @@ defmodule Sanbase.Metric.Registry.Sync do
end

defp start_sync(sync) do
url = get_sync_target_url() |> IO.inspect()
url = get_sync_target_url()

json = %{
"sync_uuid" => sync.uuid,
Expand Down
7 changes: 6 additions & 1 deletion lib/sanbase/metric/registry/sync_schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ defmodule Sanbase.Metric.Registry.SyncSchema do
def changeset(%__MODULE__{} = sync, attrs) do
sync
|> cast(attrs, [:uuid, :content, :status, :errors])
|> validate_inclusion(:status, ["scheduled", "executing", "completed", "failed"])
|> validate_inclusion(:status, ["scheduled", "executing", "completed", "failed", "cancelled"])
end

def last_syncs(limit) do
from(sync in __MODULE__, order_by: [desc: sync.id], limit: ^limit)
|> Sanbase.Repo.all()
end

def create(content) do
Expand Down
2 changes: 0 additions & 2 deletions lib/sanbase/transfers/erc20_transfers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ defmodule Sanbase.Transfers.Erc20Transfers do
alias Sanbase.ClickhouseRepo
alias Sanbase.Project

alias Sanbase.Utils.Config

defguard is_non_neg_integer(int) when is_integer(int) and int > 0

@spec top_wallet_transfers(
Expand Down
36 changes: 36 additions & 0 deletions lib/sanbase_web/components/available_metrics_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,42 @@ defmodule SanbaseWeb.AvailableMetricsComponents do

alias SanbaseWeb.CoreComponents

attr(:phx_click, :string, required: true)
attr(:display_text, :string, required: true)
attr(:class, :string, required: false, default: nil)
attr(:rest, :global, doc: "the arbitrary HTML attributes to add to the flash container")

def event_button(assigns) do
~H"""
<button
phx-click={@phx_click}
class={[
"phx-submit-loading:opacity-75 rounded-lg my-1 py-2 px-3 text-sm font-semibold leading-6 text-white",
@class
]}
{@rest}
>
{@display_text}
</button>
"""
end

attr :href, :string, required: true
attr :text, :string, required: true
attr :icon, :string, required: false, default: nil

def link_button(assigns) do
~H"""
<.link
href={@href}
class="text-gray-900 bg-white hover:bg-gray-100 border border-gray-200 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center gap-x-2"
>
<CoreComponents.icon :if={@icon} name={@icon} />
{@text}
</.link>
"""
end

@doc ~s"""
The styled button is used to link to documentation and
to link to the details page. Supports icons on the left side.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ defmodule SanbaseWeb.MetricRegistryChangeSuggestionsLive do
use SanbaseWeb, :live_view

alias SanbaseWeb.AdminFormsComponents
alias Sanbase.Metric.Registry.Permissions
alias Sanbase.Metric.Registry.ChangeSuggestion
alias SanbaseWeb.AvailableMetricsComponents

@impl true
def mount(_params, _session, socket) do
{:ok,
socket
|> assign(:rows, list_all_submissions())
|> assign(:form, to_form(%{}))}
|> assign(
page_title: "Metric Registry Change Requests",
rows: list_all_submissions(),
form: to_form(%{})
)}
end

@impl true
Expand Down Expand Up @@ -40,7 +44,11 @@ defmodule SanbaseWeb.MetricRegistryChangeSuggestionsLive do
<:col :let={row} label="Notes">{row.notes}</:col>
<:col :let={row} label="Submitted By">{row.submitted_by}</:col>
<:action :let={row}>
<.action_buttons form={@form} row={row} />
<.action_buttons
:if={Permissions.can?(:apply_change_suggestions, [])}
form={@form}
row={row}
/>
</:action>
</.table>
</div>
Expand All @@ -62,7 +70,6 @@ defmodule SanbaseWeb.MetricRegistryChangeSuggestionsLive do
class="flex flex-col lg:flex-row space-y-2 lg:space-y-0 md:space-x-2"
>
<input type="hidden" name="record_id" value={@row.id} />
<.action_button
value="approved"
text="Approve"
Expand Down
40 changes: 18 additions & 22 deletions lib/sanbase_web/live/metric_registry/metric_registry_index_live.ex
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
defmodule SanbaseWeb.MetricRegistryIndexLive do
use SanbaseWeb, :live_view

import SanbaseWeb.AvailableMetricsDescription
alias Sanbase.Metric.Registry.Permissions
alias SanbaseWeb.AvailableMetricsComponents

import SanbaseWeb.AvailableMetricsDescription

@impl true
def mount(_params, _session, socket) do
metrics = Sanbase.Metric.Registry.all()

{:ok,
socket
|> assign(
page_title: "Metric Registry",
show_verified_changes_modal: false,
visible_metrics_ids: Enum.map(metrics, & &1.id),
metrics: metrics,
Expand Down Expand Up @@ -97,8 +100,15 @@ defmodule SanbaseWeb.MetricRegistryIndexLive do
popover_target="popover-metric-details"
popover_target_text={get_popover_text(%{key: "Metric Details"})}
>
<.action_button text="Show" href={~p"/admin2/metric_registry/show/#{row.id}"} />
<.action_button text="Edit" href={~p"/admin2/metric_registry/edit/#{row.id}"} />
<AvailableMetricsComponents.link_button
text="Show"
href={~p"/admin2/metric_registry/show/#{row.id}"}
/>
<AvailableMetricsComponents.link_button
:if={Permissions.can?(:edit, [])}
text="Edit"
href={~p"/admin2/metric_registry/edit/#{row.id}"}
/>
</:col>
</AvailableMetricsComponents.table_with_popover_th>
</div>
Expand Down Expand Up @@ -264,18 +274,20 @@ defmodule SanbaseWeb.MetricRegistryIndexLive do
~H"""
<div class="my-2">
<div>
<.action_button
<AvailableMetricsComponents.link_button
:if={Permissions.can?(:create, [])}
icon="hero-plus"
text="Create New Metric"
href={~p"/admin2/metric_registry/new"}
/>
<.action_button
<AvailableMetricsComponents.link_button
icon="hero-list-bullet"
text="See Change Suggestions"
href={~p"/admin2/metric_registry/change_suggestions"}
/>
<.action_button
<AvailableMetricsComponents.link_button
:if={Permissions.can?(:start_sync, [])}
icon="hero-arrow-path-rounded-square"
text="Sync Metrics"
href={~p"/admin2/metric_registry/sync"}
Expand Down Expand Up @@ -349,22 +361,6 @@ defmodule SanbaseWeb.MetricRegistryIndexLive do
"""
end

attr :href, :string, required: true
attr :text, :string, required: true
attr :icon, :string, required: false, default: nil

defp action_button(assigns) do
~H"""
<.link
href={@href}
class="text-gray-900 bg-white hover:bg-gray-100 border border-gray-200 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center gap-x-2"
>
<.icon :if={@icon} name={@icon} />
{@text}
</.link>
"""
end

attr :phx_click, :string, required: true
attr :text, :string, required: true
attr :count, :integer, required: false, default: nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ defmodule SanbaseWeb.MetricRegistryShowLive do
import SanbaseWeb.CoreComponents
import SanbaseWeb.AvailableMetricsDescription

alias Sanbase.Metric.Registry.Permissions
alias SanbaseWeb.AvailableMetricsComponents

@impl true
Expand Down Expand Up @@ -34,6 +35,7 @@ defmodule SanbaseWeb.MetricRegistryShowLive do
/>
<AvailableMetricsComponents.available_metrics_button
:if={Permissions.can?(:edit, [])}
text="Edit Metric"
href={~p"/admin2/metric_registry/edit/#{@metric_registry}"}
icon="hero-pencil-square"
Expand Down
50 changes: 37 additions & 13 deletions lib/sanbase_web/live/metric_registry/metric_registry_sync_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,7 @@ defmodule SanbaseWeb.MetricRegistrySyncLive do
alias SanbaseWeb.AvailableMetricsComponents
@impl true
def mount(_params, _session, socket) do
metrics = Sanbase.Metric.Registry.all()

syncable_metrics =
metrics
|> Enum.filter(&(&1.sync_status == "not_synced" and &1.is_verified == true))

not_syncable_metrics =
metrics
|> Enum.filter(&(&1.sync_status == "not_synced" and &1.is_verified == false))
{syncable_metrics, not_syncable_metrics} = get_syncs_data()

{:ok,
socket
Expand Down Expand Up @@ -42,7 +34,14 @@ defmodule SanbaseWeb.MetricRegistrySyncLive do
href={~p"/admin2/metric_registry"}
icon="hero-arrow-uturn-left"
/>
<AvailableMetricsComponents.available_metrics_button
text="List Sync Runs"
href={~p"/admin2/metric_registry/sync_runs"}
icon="hero-list-bullet"
/>
</div>
<div class="flex flex-col space-y-2 md:flex-row md:space-x-2 md:space-y-0">
<.phx_click_button
text="Select All"
Expand Down Expand Up @@ -109,11 +108,22 @@ defmodule SanbaseWeb.MetricRegistrySyncLive do
ids = socket.assigns.metric_ids_to_sync |> Enum.to_list()

case Sanbase.Metric.Registry.Sync.sync(ids) do
{:ok, data} -> {:ok, data}
{:error, error} -> {:error, error}
{:ok, data} ->
Process.sleep(5000)
{syncable_metrics, not_syncable_metrics} = get_syncs_data()

{:noreply,
socket
|> put_flash(:info, "Sucessfully initiated sync of #{length(ids)} metrics")
|> assign(
syncable_metrics: syncable_metrics,
non_syncable_metrics: not_syncable_metrics,
metric_ids_to_sync: Enum.map(syncable_metrics, & &1.id) |> MapSet.new()
)}

{:error, error} ->
{:noreply, socket |> put_flash(:error, "Error syncing metrics: #{error}")}
end

{:noreply, socket}
end

def handle_event("update_should_sync", %{"metric_registry_id" => id} = params, socket) do
Expand All @@ -138,6 +148,20 @@ defmodule SanbaseWeb.MetricRegistrySyncLive do
{:noreply, assign(socket, metric_ids_to_sync: MapSet.new())}
end

defp get_syncs_data() do
metrics = Sanbase.Metric.Registry.all()

syncable_metrics =
metrics
|> Enum.filter(&(&1.sync_status == "not_synced" and &1.is_verified == true))

not_syncable_metrics =
metrics
|> Enum.filter(&(&1.sync_status == "not_synced" and &1.is_verified == false))

{syncable_metrics, not_syncable_metrics}
end

defp metric_names(assigns) do
~H"""
<div class="flex flex-col">
Expand Down
Loading

0 comments on commit f21f512

Please sign in to comment.