diff --git a/config/config.exs b/config/config.exs index 45ebd0d0..56b17a56 100644 --- a/config/config.exs +++ b/config/config.exs @@ -99,6 +99,14 @@ config :sentry, enable_source_code_context: true, root_source_code_paths: [File.cwd!()] +config :lotus, + ecto_repo: MusicLibrary.Repo, + default_repo: "main", + data_repos: %{ + "main" => MusicLibrary.Repo, + "background_jobs" => MusicLibrary.BackgroundRepo + } + # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{config_env()}.exs" diff --git a/lib/music_library_web/components/layouts/app.html.heex b/lib/music_library_web/components/layouts/app.html.heex index d4875f91..2adac50e 100644 --- a/lib/music_library_web/components/layouts/app.html.heex +++ b/lib/music_library_web/components/layouts/app.html.heex @@ -111,6 +111,15 @@ <.icon name="hero-cog" class="h-4 w-4 mr-2" aria-hidden="true" data-slot="icon" /> {gettext("Oban")} + <.dropdown_link href={~p"/dev/lotus"}> + <.icon + name="hero-table-cells" + class="h-4 w-4 mr-2" + aria-hidden="true" + data-slot="icon" + /> + {gettext("Lotus")} + <.dropdown_separator /> <.dropdown_link href={~p"/login"}> <.icon diff --git a/lib/music_library_web/router.ex b/lib/music_library_web/router.ex index 6d7d86d3..24281573 100644 --- a/lib/music_library_web/router.ex +++ b/lib/music_library_web/router.ex @@ -3,6 +3,7 @@ defmodule MusicLibraryWeb.Router do import MusicLibraryWeb.Auth, only: [require_logged_in: 2, require_api_token: 2] import Oban.Web.Router + import Lotus.Web.Router pipeline :browser do plug :accepts, ["html"] @@ -100,6 +101,8 @@ defmodule MusicLibraryWeb.Router do ecto_repos: [MusicLibrary.Repo, MusicLibrary.BackgroundRepo] oban_dashboard "/oban" + + lotus_dashboard("/lotus") end end end diff --git a/mix.exs b/mix.exs index 48aaccbe..93fbbd2d 100644 --- a/mix.exs +++ b/mix.exs @@ -110,6 +110,10 @@ defmodule MusicLibrary.MixProject do {:oban, "~> 2.20"}, {:oban_web, "~> 2.11"}, + # Data analysis + {:lotus_web, "~> 0.5.2"}, + {:lotus, "~> 0.9.2"}, + # Test tooling {:phoenix_test, "~> 0.8.0", only: :test}, {:lazy_html, ">= 0.1.0", only: :test}, diff --git a/mix.lock b/mix.lock index cc85ab0b..85c47d27 100644 --- a/mix.lock +++ b/mix.lock @@ -31,8 +31,11 @@ "lazy_html": {:hex, :lazy_html, "0.1.8", "677a8642e644eef8de98f3040e2520d42d0f0f8bd6c5cd49db36504e34dffe91", [:make, :mix], [{:cc_precompiler, "~> 0.1", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.9.0", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:fine, "~> 0.1.0", [hex: :fine, repo: "hexpm", optional: false]}], "hexpm", "0d8167d930b704feb94b41414ca7f5779dff9bca7fcf619fcef18de138f08736"}, "live_debugger": {:hex, :live_debugger, "0.4.2", "775c3a570ef3c44d27d261b3c1aae23ef35cac949a57f67b3e7b1aa1fb2707bc", [:mix], [{:igniter, ">= 0.5.40 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.7", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.20.8 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "5b24e37985f0424056a322a18dab4a5fb0f4e8ee4e55975985364e0b45d683b9"}, "live_toast": {:hex, :live_toast, "0.8.0", "d7e24801a9a966d8e48872767ac33c50fc14640ac5272128becfc534fabd99b7", [:mix], [{:ecto, ">= 3.11.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:gettext, ">= 0.26.2", [hex: :gettext, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.7.19", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_live_view, ">= 1.0.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "7e64435131b7731698908d59f7ba9f5092df8a3720814f26edf57e99d97a803c"}, + "lotus": {:hex, :lotus, "0.9.2", "6d440c1838ecdfa2cfc21a610c130407086e216b7f83e7415e78ebf547b100c3", [:mix], [{:ecto, "~> 3.10", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.21", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:myxql, "~> 0.8", [hex: :myxql, repo: "hexpm", optional: true]}, {:nimble_csv, "~> 1.2", [hex: :nimble_csv, repo: "hexpm", optional: false]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.20", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "38f1efd059bf27e0aa114b8391e843cd2724f920ddfbb30e38e72e267f669ea4"}, + "lotus_web": {:hex, :lotus_web, "0.5.2", "1023afec52529c3fa8d1051b7cf7c0b1bf71889dc6f13c640099a4c99af1c971", [:mix], [{:lotus, "~> 0.9.2", [hex: :lotus, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.7", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_ecto, "~> 4.5", [hex: :phoenix_ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_live_view, ">= 1.0.0 and < 1.2.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "439c16dbf1fccdeb8dba58de040e42c3d9dc3742fa8dbaae6014d4e07dc21ee4"}, "mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"}, "mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"}, + "nimble_csv": {:hex, :nimble_csv, "1.3.0", "b7f998dc62b222bce9596e46f028c7a5af04cb5dde6df2ea197c583227c54971", [:mix], [], "hexpm", "41ccdc18f7c8f8bb06e84164fc51635321e80d5a3b450761c4997d620925d619"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_ownership": {:hex, :nimble_ownership, "1.0.2", "fa8a6f2d8c592ad4d79b2ca617473c6aefd5869abfa02563a77682038bf916cf", [:mix], [], "hexpm", "098af64e1f6f8609c6672127cfe9e9590a5d3fcdd82bc17a377b8692fd81a879"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot index 32ae7484..e7dcdb2d 100644 --- a/priv/gettext/default.pot +++ b/priv/gettext/default.pot @@ -1488,3 +1488,8 @@ msgstr "" #, elixir-autogen, elixir-format msgid "Add a record instead" msgstr "" + +#: lib/music_library_web/components/layouts/app.html.heex +#, elixir-autogen, elixir-format +msgid "Lotus" +msgstr "" diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po index 9f624469..068c9665 100644 --- a/priv/gettext/en/LC_MESSAGES/default.po +++ b/priv/gettext/en/LC_MESSAGES/default.po @@ -1488,3 +1488,8 @@ msgstr "" #, elixir-autogen, elixir-format msgid "Add a record instead" msgstr "" + +#: lib/music_library_web/components/layouts/app.html.heex +#, elixir-autogen, elixir-format +msgid "Lotus" +msgstr "" diff --git a/priv/repo/migrations/20251022151150_create_lotus_tables.exs b/priv/repo/migrations/20251022151150_create_lotus_tables.exs new file mode 100644 index 00000000..42f21ae7 --- /dev/null +++ b/priv/repo/migrations/20251022151150_create_lotus_tables.exs @@ -0,0 +1,11 @@ +defmodule MusicLibrary.Repo.Migrations.CreateLotusTables do + use Ecto.Migration + + def up do + Lotus.Migrations.up() + end + + def down do + Lotus.Migrations.down() + end +end