chore: refactoring of Repo.get/get! usages
This commit is contained in:
@@ -83,9 +83,9 @@ _None._ All modules previously on the queue have been split; refresh the queue i
|
|||||||
|
|
||||||
## 7. Direct `Repo.get` in `BDS.Desktop.ShellLive`
|
## 7. Direct `Repo.get` in `BDS.Desktop.ShellLive`
|
||||||
|
|
||||||
**Status:** open. 10 call sites verified.
|
**Status:** ✅ done (2026-05-01). `Repo.get/2` and `Repo.get!/2` no longer appear in `BDS.Desktop.ShellLive` or its submodules. ShellLive entity reads now go through context APIs (`Posts.get_post/1`, `Posts.get_post!/1`, `Media.get_media/1`, `Templates.get_template/1`, `Scripts.get_script/1`, `AI.get_chat_conversation/1`, and `Settings.get_global_setting/1` / `put_global_setting/2`). Added a regression test that scans ShellLive source for direct `Repo.get` calls.
|
||||||
|
|
||||||
**Plan:** add the missing context functions (`Posts.get_post_with_translations/1`, etc.) and replace each `Repo.get(Schema, id)` with the context call.
|
**Rule:** ShellLive modules may use `Repo` for query-shaped read models where no context abstraction exists yet, but direct primary-key entity fetches belong in context modules.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -216,6 +216,8 @@ Most tests share the SQLite repo and named GenServers (`BDS.Tasks`, `BDS.Search`
|
|||||||
|
|
||||||
### 2026-05-01
|
### 2026-05-01
|
||||||
|
|
||||||
|
- **Direct `Repo.get` in `BDS.Desktop.ShellLive`**: added context helpers for primary-key reads (`Posts.get_post/1`, `Media.get_media/1`, `Templates.get_template/1`, `Scripts.get_script/1`, `AI.get_chat_conversation/1`) and introduced `BDS.Settings` for global editor settings. Replaced all ShellLive `Repo.get/2` and `Repo.get!/2` calls across the main shell, tab helpers, CLI sync, panel renderer, chat message build, code entity editor, post editor, media editor, overlay components, post metadata, and settings editor. Added a ShellLive regression test that scans source files to keep direct `Repo.get` calls out. Section 7 is closed.
|
||||||
|
|
||||||
- **God modules**:
|
- **God modules**:
|
||||||
- `BDS.Maintenance` 810 → 141 (83 %). Submodules under `lib/bds/maintenance/`: `Progress` (45), `FileScan` (158), `DiffComputation` (93), `DiffReports` (315), `Repair` (145). Coordinator keeps the 4 public entrypoints (`repair_metadata_diff/4`, `import_metadata_diff_orphans/3`, `rebuild_from_filesystem/3`, `metadata_diff/2`); submodules wired via `import only:`.
|
- `BDS.Maintenance` 810 → 141 (83 %). Submodules under `lib/bds/maintenance/`: `Progress` (45), `FileScan` (158), `DiffComputation` (93), `DiffReports` (315), `Repair` (145). Coordinator keeps the 4 public entrypoints (`repair_metadata_diff/4`, `import_metadata_diff_orphans/3`, `rebuild_from_filesystem/3`, `metadata_diff/2`); submodules wired via `import only:`.
|
||||||
- `BDS.Scripting.Capabilities` 1715 → 194 (89 %). Submodules: `Util` (301), `Posts` (270), `Media` (254), `Crud` (284), `Projects` (204), `AppShell` (134), `Bridges` (176). Public `for_project/2` preserved.
|
- `BDS.Scripting.Capabilities` 1715 → 194 (89 %). Submodules: `Util` (301), `Posts` (270), `Media` (254), `Crud` (284), `Projects` (204), `AppShell` (134), `Bridges` (176). Public `for_project/2` preserved.
|
||||||
|
|||||||
@@ -149,6 +149,9 @@ defmodule BDS.AI do
|
|||||||
@spec list_chat_conversations() :: [map()]
|
@spec list_chat_conversations() :: [map()]
|
||||||
defdelegate list_chat_conversations(), to: Chat
|
defdelegate list_chat_conversations(), to: Chat
|
||||||
|
|
||||||
|
@spec get_chat_conversation(String.t()) :: BDS.AI.ChatConversation.t() | nil
|
||||||
|
defdelegate get_chat_conversation(conversation_id), to: Chat
|
||||||
|
|
||||||
@spec available_chat_models(String.t() | nil) :: [map()]
|
@spec available_chat_models(String.t() | nil) :: [map()]
|
||||||
defdelegate available_chat_models(current_model \\ nil), to: Chat
|
defdelegate available_chat_models(current_model \\ nil), to: Chat
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,11 @@ defmodule BDS.AI.Chat do
|
|||||||
|> Enum.map(&format_conversation/1)
|
|> Enum.map(&format_conversation/1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec get_chat_conversation(String.t()) :: ChatConversation.t() | nil
|
||||||
|
def get_chat_conversation(conversation_id) when is_binary(conversation_id) do
|
||||||
|
Repo.get(ChatConversation, conversation_id)
|
||||||
|
end
|
||||||
|
|
||||||
@spec available_chat_models(String.t() | nil) :: [map()]
|
@spec available_chat_models(String.t() | nil) :: [map()]
|
||||||
def available_chat_models(current_model \\ nil) do
|
def available_chat_models(current_model \\ nil) do
|
||||||
endpoint_models = configured_chat_models()
|
endpoint_models = configured_chat_models()
|
||||||
|
|||||||
@@ -6,6 +6,15 @@ defmodule BDS.AI.ChatConversation do
|
|||||||
|
|
||||||
@primary_key {:id, :string, autogenerate: false}
|
@primary_key {:id, :string, autogenerate: false}
|
||||||
|
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
id: String.t(),
|
||||||
|
title: String.t() | nil,
|
||||||
|
model: String.t() | nil,
|
||||||
|
copilot_session_id: String.t() | nil,
|
||||||
|
created_at: integer() | nil,
|
||||||
|
updated_at: integer() | nil
|
||||||
|
}
|
||||||
|
|
||||||
schema "chat_conversations" do
|
schema "chat_conversations" do
|
||||||
field :title, :string
|
field :title, :string
|
||||||
field :model, :string
|
field :model, :string
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ defmodule BDS.Desktop.ShellLive do
|
|||||||
parse_integer: 1
|
parse_integer: 1
|
||||||
]
|
]
|
||||||
alias BDS.Projects
|
alias BDS.Projects
|
||||||
alias BDS.Repo
|
|
||||||
alias BDS.Templates
|
alias BDS.Templates
|
||||||
alias BDS.UI.{Commands, MenuBar, Session, Workbench}
|
alias BDS.UI.{Commands, MenuBar, Session, Workbench}
|
||||||
|
|
||||||
@@ -346,7 +345,7 @@ defmodule BDS.Desktop.ShellLive do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def handle_event("delete_sidebar_template", %{"id" => template_id}, socket) do
|
def handle_event("delete_sidebar_template", %{"id" => template_id}, socket) do
|
||||||
case Repo.get(Templates.Template, template_id) do
|
case Templates.get_template(template_id) do
|
||||||
%Templates.Template{project_id: project_id} when project_id == socket.assigns.projects.active_project_id ->
|
%Templates.Template{project_id: project_id} when project_id == socket.assigns.projects.active_project_id ->
|
||||||
case Templates.delete_template(template_id) do
|
case Templates.delete_template(template_id) do
|
||||||
{:ok, :deleted} ->
|
{:ok, :deleted} ->
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
defmodule BDS.Desktop.ShellLive.ChatEditor.MessageBuild do
|
defmodule BDS.Desktop.ShellLive.ChatEditor.MessageBuild do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
|
|
||||||
alias BDS.{AI, Repo}
|
alias BDS.AI
|
||||||
alias BDS.AI.ChatConversation
|
alias BDS.AI.ChatConversation
|
||||||
alias BDS.Desktop.ShellData
|
alias BDS.Desktop.ShellData
|
||||||
alias BDS.Desktop.ShellLive.ChatEditor.{ModelSelection, ToolSurfaces, ToolTracking}
|
alias BDS.Desktop.ShellLive.ChatEditor.{ModelSelection, ToolSurfaces, ToolTracking}
|
||||||
|
|
||||||
def build(%{current_tab: %{type: :chat, id: conversation_id}} = assigns) do
|
def build(%{current_tab: %{type: :chat, id: conversation_id}} = assigns) do
|
||||||
case Repo.get(ChatConversation, conversation_id) do
|
case AI.get_chat_conversation(conversation_id) do
|
||||||
nil ->
|
nil ->
|
||||||
nil
|
nil
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ defmodule BDS.Desktop.ShellLive.CliSync do
|
|||||||
|
|
||||||
import Phoenix.Component, only: [assign: 3]
|
import Phoenix.Component, only: [assign: 3]
|
||||||
|
|
||||||
alias BDS.Media.Media
|
alias BDS.{Media, Posts}
|
||||||
|
alias BDS.Media.Media, as: MediaRecord
|
||||||
alias BDS.Posts.Post
|
alias BDS.Posts.Post
|
||||||
alias BDS.Repo
|
|
||||||
alias BDS.UI.Workbench
|
alias BDS.UI.Workbench
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
@@ -78,8 +78,8 @@ defmodule BDS.Desktop.ShellLive.CliSync do
|
|||||||
|
|
||||||
defp maybe_refresh_tab_meta(socket, "post", post_id, action) when action in [:created, :updated] do
|
defp maybe_refresh_tab_meta(socket, "post", post_id, action) when action in [:created, :updated] do
|
||||||
maybe_put_tab_meta(socket, :post, post_id, fn ->
|
maybe_put_tab_meta(socket, :post, post_id, fn ->
|
||||||
case Repo.get(Post, post_id) do
|
case Posts.get_post(post_id) do
|
||||||
%Post{} = post -> %{title: post.title || post.slug || post.id, subtitle: Atom.to_string(post.status || :draft)}
|
%Post{} = post -> %{title: post.title || post.slug || post.id, subtitle: Atom.to_string(post.status)}
|
||||||
_other -> nil
|
_other -> nil
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
@@ -87,8 +87,8 @@ defmodule BDS.Desktop.ShellLive.CliSync do
|
|||||||
|
|
||||||
defp maybe_refresh_tab_meta(socket, "media", media_id, action) when action in [:created, :updated] do
|
defp maybe_refresh_tab_meta(socket, "media", media_id, action) when action in [:created, :updated] do
|
||||||
maybe_put_tab_meta(socket, :media, media_id, fn ->
|
maybe_put_tab_meta(socket, :media, media_id, fn ->
|
||||||
case Repo.get(Media, media_id) do
|
case Media.get_media(media_id) do
|
||||||
%Media{} = media -> %{title: media.title || media.filename || media.id, subtitle: media.filename || media.mime_type || "media"}
|
%MediaRecord{} = media -> %{title: media.title || media.filename || media.id, subtitle: media.filename || media.mime_type || "media"}
|
||||||
_other -> nil
|
_other -> nil
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ defmodule BDS.Desktop.ShellLive.CodeEntityEditor do
|
|||||||
use Phoenix.Component
|
use Phoenix.Component
|
||||||
|
|
||||||
alias BDS.Desktop.ShellData
|
alias BDS.Desktop.ShellData
|
||||||
alias BDS.{MCP, Repo, Scripts, Scripting, Templates}
|
alias BDS.{MCP, Scripts, Scripting, Templates}
|
||||||
alias BDS.Scripts.Script
|
alias BDS.Scripts.Script
|
||||||
alias BDS.Templates.Template
|
alias BDS.Templates.Template
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ defmodule BDS.Desktop.ShellLive.CodeEntityEditor do
|
|||||||
def save_script(socket, reload, append_output) do
|
def save_script(socket, reload, append_output) do
|
||||||
%{id: script_id} = socket.assigns.current_tab
|
%{id: script_id} = socket.assigns.current_tab
|
||||||
|
|
||||||
case Repo.get(Script, script_id) do
|
case Scripts.get_script(script_id) do
|
||||||
nil -> reload.(socket, socket.assigns.workbench)
|
nil -> reload.(socket, socket.assigns.workbench)
|
||||||
%Script{} = script ->
|
%Script{} = script ->
|
||||||
draft = current_script_draft(socket.assigns, script)
|
draft = current_script_draft(socket.assigns, script)
|
||||||
@@ -57,7 +57,7 @@ defmodule BDS.Desktop.ShellLive.CodeEntityEditor do
|
|||||||
def check_script(socket, reload, append_output) do
|
def check_script(socket, reload, append_output) do
|
||||||
%{id: script_id} = socket.assigns.current_tab
|
%{id: script_id} = socket.assigns.current_tab
|
||||||
|
|
||||||
case Repo.get(Script, script_id) do
|
case Scripts.get_script(script_id) do
|
||||||
nil -> reload.(socket, socket.assigns.workbench)
|
nil -> reload.(socket, socket.assigns.workbench)
|
||||||
%Script{} = script ->
|
%Script{} = script ->
|
||||||
case Scripting.validate(current_script_draft(socket.assigns, script)["content"] || "") do
|
case Scripting.validate(current_script_draft(socket.assigns, script)["content"] || "") do
|
||||||
@@ -70,7 +70,7 @@ defmodule BDS.Desktop.ShellLive.CodeEntityEditor do
|
|||||||
def run_script(socket, reload, append_output) do
|
def run_script(socket, reload, append_output) do
|
||||||
%{id: script_id} = socket.assigns.current_tab
|
%{id: script_id} = socket.assigns.current_tab
|
||||||
|
|
||||||
case Repo.get(Script, script_id) do
|
case Scripts.get_script(script_id) do
|
||||||
nil -> reload.(socket, socket.assigns.workbench)
|
nil -> reload.(socket, socket.assigns.workbench)
|
||||||
%Script{} = script ->
|
%Script{} = script ->
|
||||||
draft = current_script_draft(socket.assigns, script)
|
draft = current_script_draft(socket.assigns, script)
|
||||||
@@ -109,7 +109,7 @@ defmodule BDS.Desktop.ShellLive.CodeEntityEditor do
|
|||||||
def save_template(socket, reload, append_output) do
|
def save_template(socket, reload, append_output) do
|
||||||
%{id: template_id} = socket.assigns.current_tab
|
%{id: template_id} = socket.assigns.current_tab
|
||||||
|
|
||||||
case Repo.get(Template, template_id) do
|
case Templates.get_template(template_id) do
|
||||||
nil -> reload.(socket, socket.assigns.workbench)
|
nil -> reload.(socket, socket.assigns.workbench)
|
||||||
%Template{} = template ->
|
%Template{} = template ->
|
||||||
draft = current_template_draft(socket.assigns, template)
|
draft = current_template_draft(socket.assigns, template)
|
||||||
@@ -129,7 +129,7 @@ defmodule BDS.Desktop.ShellLive.CodeEntityEditor do
|
|||||||
def validate_template(socket, reload, append_output) do
|
def validate_template(socket, reload, append_output) do
|
||||||
%{id: template_id} = socket.assigns.current_tab
|
%{id: template_id} = socket.assigns.current_tab
|
||||||
|
|
||||||
case Repo.get(Template, template_id) do
|
case Templates.get_template(template_id) do
|
||||||
nil -> reload.(socket, socket.assigns.workbench)
|
nil -> reload.(socket, socket.assigns.workbench)
|
||||||
%Template{} = template ->
|
%Template{} = template ->
|
||||||
case MCP.validate_template(current_template_draft(socket.assigns, template)["content"] || "") do
|
case MCP.validate_template(current_template_draft(socket.assigns, template)["content"] || "") do
|
||||||
@@ -149,7 +149,7 @@ defmodule BDS.Desktop.ShellLive.CodeEntityEditor do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def build_script(%{current_tab: %{type: :scripts, id: script_id}} = assigns) do
|
def build_script(%{current_tab: %{type: :scripts, id: script_id}} = assigns) do
|
||||||
case Repo.get(Script, script_id) do
|
case Scripts.get_script(script_id) do
|
||||||
nil -> nil
|
nil -> nil
|
||||||
%Script{} = script ->
|
%Script{} = script ->
|
||||||
draft = current_script_draft(assigns, script)
|
draft = current_script_draft(assigns, script)
|
||||||
@@ -171,7 +171,7 @@ defmodule BDS.Desktop.ShellLive.CodeEntityEditor do
|
|||||||
def build_script(_assigns), do: nil
|
def build_script(_assigns), do: nil
|
||||||
|
|
||||||
def build_template(%{current_tab: %{type: :templates, id: template_id}} = assigns) do
|
def build_template(%{current_tab: %{type: :templates, id: template_id}} = assigns) do
|
||||||
case Repo.get(Template, template_id) do
|
case Templates.get_template(template_id) do
|
||||||
nil -> nil
|
nil -> nil
|
||||||
%Template{} = template ->
|
%Template{} = template ->
|
||||||
draft = current_template_draft(assigns, template)
|
draft = current_template_draft(assigns, template)
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ defmodule BDS.Desktop.ShellLive.MediaEditor do
|
|||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
alias BDS.Desktop.{FilePicker, ShellData}
|
alias BDS.Desktop.{FilePicker, ShellData}
|
||||||
alias BDS.{AI, I18n, Media, Repo}
|
alias BDS.{AI, I18n, Media}
|
||||||
alias BDS.Media.Media, as: MediaRecord
|
alias BDS.Media.Media, as: MediaRecord
|
||||||
alias BDS.Media.Translation
|
alias BDS.Media.Translation
|
||||||
alias BDS.Posts.Post
|
alias BDS.Posts.Post
|
||||||
|
alias BDS.Repo
|
||||||
alias BDS.UI.Workbench
|
alias BDS.UI.Workbench
|
||||||
|
|
||||||
embed_templates "media_editor_html/*"
|
embed_templates "media_editor_html/*"
|
||||||
@@ -23,7 +24,7 @@ defmodule BDS.Desktop.ShellLive.MediaEditor do
|
|||||||
def update(socket, params, reload) do
|
def update(socket, params, reload) do
|
||||||
case socket.assigns.current_tab do
|
case socket.assigns.current_tab do
|
||||||
%{type: :media, id: media_id} ->
|
%{type: :media, id: media_id} ->
|
||||||
case Repo.get(MediaRecord, media_id) do
|
case Media.get_media(media_id) do
|
||||||
nil ->
|
nil ->
|
||||||
socket
|
socket
|
||||||
|
|
||||||
@@ -38,7 +39,7 @@ defmodule BDS.Desktop.ShellLive.MediaEditor do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def persist_socket(socket, media_id, reload, append_output) do
|
def persist_socket(socket, media_id, reload, append_output) do
|
||||||
case Repo.get(MediaRecord, media_id) do
|
case Media.get_media(media_id) do
|
||||||
nil ->
|
nil ->
|
||||||
socket
|
socket
|
||||||
|
|
||||||
@@ -111,7 +112,7 @@ defmodule BDS.Desktop.ShellLive.MediaEditor do
|
|||||||
|> append_output.(translated("Detect Language"), translated("Automatic AI actions stay gated by airplane mode."), nil, "info")
|
|> append_output.(translated("Detect Language"), translated("Automatic AI actions stay gated by airplane mode."), nil, "info")
|
||||||
|> reload.(socket.assigns.workbench)
|
|> reload.(socket.assigns.workbench)
|
||||||
else
|
else
|
||||||
case Repo.get(MediaRecord, media_id) do
|
case Media.get_media(media_id) do
|
||||||
nil ->
|
nil ->
|
||||||
socket
|
socket
|
||||||
|
|
||||||
@@ -184,7 +185,7 @@ defmodule BDS.Desktop.ShellLive.MediaEditor do
|
|||||||
|
|
||||||
def apply_ai_suggestions(socket, media_id, fields, reload, append_output) do
|
def apply_ai_suggestions(socket, media_id, fields, reload, append_output) do
|
||||||
try do
|
try do
|
||||||
case Repo.get(MediaRecord, media_id) do
|
case Media.get_media(media_id) do
|
||||||
nil ->
|
nil ->
|
||||||
socket
|
socket
|
||||||
|
|
||||||
@@ -375,7 +376,7 @@ defmodule BDS.Desktop.ShellLive.MediaEditor do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def build(%{current_tab: %{type: :media, id: media_id}} = assigns) do
|
def build(%{current_tab: %{type: :media, id: media_id}} = assigns) do
|
||||||
case Repo.get(MediaRecord, media_id) do
|
case Media.get_media(media_id) do
|
||||||
nil ->
|
nil ->
|
||||||
nil
|
nil
|
||||||
|
|
||||||
@@ -468,7 +469,7 @@ defmodule BDS.Desktop.ShellLive.MediaEditor do
|
|||||||
"title" => media.title || "",
|
"title" => media.title || "",
|
||||||
"alt" => media.alt || "",
|
"alt" => media.alt || "",
|
||||||
"caption" => media.caption || "",
|
"caption" => media.caption || "",
|
||||||
"tags" => Enum.join(media.tags || [], ", "),
|
"tags" => Enum.join(media.tags, ", "),
|
||||||
"author" => media.author || "",
|
"author" => media.author || "",
|
||||||
"language" => media.language || ""
|
"language" => media.language || ""
|
||||||
}
|
}
|
||||||
@@ -567,4 +568,4 @@ defmodule BDS.Desktop.ShellLive.MediaEditor do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp reload_with_assigned_workbench(socket, reload), do: reload.(socket, socket.assigns.workbench)
|
defp reload_with_assigned_workbench(socket, reload), do: reload.(socket, socket.assigns.workbench)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ defmodule BDS.Desktop.ShellLive.OverlayComponents do
|
|||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
alias BDS.Desktop.ShellData
|
alias BDS.Desktop.ShellData
|
||||||
alias BDS.{I18n, Metadata, Repo}
|
alias BDS.{I18n, Media, Metadata, Posts, Repo}
|
||||||
alias BDS.Media.Media
|
alias BDS.Media.Media, as: MediaRecord
|
||||||
alias BDS.Media.Translation, as: MediaTranslation
|
alias BDS.Media.Translation, as: MediaTranslation
|
||||||
alias BDS.Posts.{Post, PostMedia, Translation}
|
alias BDS.Posts.{Post, PostMedia, Translation}
|
||||||
alias BDS.Tags.Tag
|
alias BDS.Tags.Tag
|
||||||
@@ -93,7 +93,7 @@ defmodule BDS.Desktop.ShellLive.OverlayComponents do
|
|||||||
|
|
||||||
defp media(project_id) do
|
defp media(project_id) do
|
||||||
Repo.all(
|
Repo.all(
|
||||||
from media in Media,
|
from media in MediaRecord,
|
||||||
where: media.project_id == ^project_id,
|
where: media.project_id == ^project_id,
|
||||||
order_by: [desc: media.updated_at, desc: media.created_at],
|
order_by: [desc: media.updated_at, desc: media.created_at],
|
||||||
select: %{id: media.id, title: media.title, original_name: media.original_name, mime_type: media.mime_type, alt: media.alt, caption: media.caption}
|
select: %{id: media.id, title: media.title, original_name: media.original_name, mime_type: media.mime_type, alt: media.alt, caption: media.caption}
|
||||||
@@ -155,7 +155,7 @@ defmodule BDS.Desktop.ShellLive.OverlayComponents do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp source_language(%{type: :post, id: post_id}, metadata) do
|
defp source_language(%{type: :post, id: post_id}, metadata) do
|
||||||
case Repo.get(Post, post_id) do
|
case Posts.get_post(post_id) do
|
||||||
%Post{language: language} when is_binary(language) and language != "" -> language
|
%Post{language: language} when is_binary(language) and language != "" -> language
|
||||||
_other -> metadata.main_language || "en"
|
_other -> metadata.main_language || "en"
|
||||||
end
|
end
|
||||||
@@ -164,8 +164,8 @@ defmodule BDS.Desktop.ShellLive.OverlayComponents do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp source_language(%{type: :media, id: media_id}, metadata) do
|
defp source_language(%{type: :media, id: media_id}, metadata) do
|
||||||
case Repo.get(Media, media_id) do
|
case Media.get_media(media_id) do
|
||||||
%Media{language: language} when is_binary(language) and language != "" -> language
|
%MediaRecord{language: language} when is_binary(language) and language != "" -> language
|
||||||
_other -> metadata.main_language || "en"
|
_other -> metadata.main_language || "en"
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
@@ -190,7 +190,7 @@ defmodule BDS.Desktop.ShellLive.OverlayComponents do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp ai_fields(%{type: :post, id: post_id}, title, subtitle, page_language) do
|
defp ai_fields(%{type: :post, id: post_id}, title, subtitle, page_language) do
|
||||||
case Repo.get(Post, post_id) do
|
case Posts.get_post(post_id) do
|
||||||
%Post{} = post ->
|
%Post{} = post ->
|
||||||
[
|
[
|
||||||
%{key: "title", label: ShellData.translate("Title", %{}, page_language), current_value: post.title || title, suggested_value: refine_title(post.title || title), locked: false},
|
%{key: "title", label: ShellData.translate("Title", %{}, page_language), current_value: post.title || title, suggested_value: refine_title(post.title || title), locked: false},
|
||||||
@@ -206,8 +206,8 @@ defmodule BDS.Desktop.ShellLive.OverlayComponents do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp ai_fields(%{type: :media, id: media_id}, title, _subtitle, page_language) do
|
defp ai_fields(%{type: :media, id: media_id}, title, _subtitle, page_language) do
|
||||||
case Repo.get(Media, media_id) do
|
case Media.get_media(media_id) do
|
||||||
%Media{} = media ->
|
%MediaRecord{} = media ->
|
||||||
[
|
[
|
||||||
%{key: "title", label: ShellData.translate("Title", %{}, page_language), current_value: media.title || title, suggested_value: refine_title(media.title || title), locked: false},
|
%{key: "title", label: ShellData.translate("Title", %{}, page_language), current_value: media.title || title, suggested_value: refine_title(media.title || title), locked: false},
|
||||||
%{key: "alt", label: ShellData.translate("Alt Text", %{}, page_language), current_value: media.alt || "", suggested_value: media.alt || title, locked: false},
|
%{key: "alt", label: ShellData.translate("Alt Text", %{}, page_language), current_value: media.alt || "", suggested_value: media.alt || title, locked: false},
|
||||||
@@ -225,8 +225,8 @@ defmodule BDS.Desktop.ShellLive.OverlayComponents do
|
|||||||
|
|
||||||
defp delete_details(%{type: :media, id: media_id}, page_language) do
|
defp delete_details(%{type: :media, id: media_id}, page_language) do
|
||||||
entity_name =
|
entity_name =
|
||||||
case Repo.get(Media, media_id) do
|
case Media.get_media(media_id) do
|
||||||
%Media{} = media -> media.title || media.original_name || media.id
|
%MediaRecord{} = media -> media.title || media.original_name || media.id
|
||||||
_other -> media_id
|
_other -> media_id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ defmodule BDS.Desktop.ShellLive.PanelRenderer do
|
|||||||
|
|
||||||
alias BDS.Desktop.ShellData
|
alias BDS.Desktop.ShellData
|
||||||
alias BDS.Git
|
alias BDS.Git
|
||||||
alias BDS.Media.Media
|
alias BDS.Media
|
||||||
|
alias BDS.Media.Media, as: MediaRecord
|
||||||
alias BDS.PostLinks
|
alias BDS.PostLinks
|
||||||
|
alias BDS.Posts
|
||||||
alias BDS.Posts.Post
|
alias BDS.Posts.Post
|
||||||
alias BDS.Repo
|
|
||||||
|
|
||||||
@doc "Render the active panel tab body."
|
@doc "Render the active panel tab body."
|
||||||
def render_panel_body(assigns) do
|
def render_panel_body(assigns) do
|
||||||
@@ -208,7 +209,7 @@ defmodule BDS.Desktop.ShellLive.PanelRenderer do
|
|||||||
|
|
||||||
defp related_posts(links, key) do
|
defp related_posts(links, key) do
|
||||||
Enum.map(links, fn link ->
|
Enum.map(links, fn link ->
|
||||||
case Repo.get(Post, Map.fetch!(link, key)) do
|
case Posts.get_post(Map.fetch!(link, key)) do
|
||||||
%Post{} = post -> %{id: post.id, title: post.title || post.slug || post.id, text: link.link_text || post.slug || post.id}
|
%Post{} = post -> %{id: post.id, title: post.title || post.slug || post.id, text: link.link_text || post.slug || post.id}
|
||||||
_other -> nil
|
_other -> nil
|
||||||
end
|
end
|
||||||
@@ -230,15 +231,15 @@ defmodule BDS.Desktop.ShellLive.PanelRenderer do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp git_history_target(%{type: :post, id: post_id}) do
|
defp git_history_target(%{type: :post, id: post_id}) do
|
||||||
case Repo.get(Post, post_id) do
|
case Posts.get_post(post_id) do
|
||||||
%Post{project_id: project_id, file_path: file_path} when file_path not in [nil, ""] -> {project_id, file_path}
|
%Post{project_id: project_id, file_path: file_path} when file_path not in [nil, ""] -> {project_id, file_path}
|
||||||
_other -> nil
|
_other -> nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp git_history_target(%{type: :media, id: media_id}) do
|
defp git_history_target(%{type: :media, id: media_id}) do
|
||||||
case Repo.get(Media, media_id) do
|
case Media.get_media(media_id) do
|
||||||
%Media{project_id: project_id, file_path: file_path} when file_path not in [nil, ""] -> {project_id, file_path}
|
%MediaRecord{project_id: project_id, file_path: file_path} when file_path not in [nil, ""] -> {project_id, file_path}
|
||||||
_other -> nil
|
_other -> nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
|
|
||||||
use Phoenix.Component
|
use Phoenix.Component
|
||||||
|
|
||||||
alias BDS.{AI, Posts, Preview, Repo}
|
alias BDS.{AI, Posts, Preview}
|
||||||
alias BDS.Desktop.ShellData
|
alias BDS.Desktop.ShellData
|
||||||
alias BDS.Desktop.ShellLive.PostEditor.{DraftManagement, ListValues, Persistence, PostMetadata}
|
alias BDS.Desktop.ShellLive.PostEditor.{DraftManagement, ListValues, Persistence, PostMetadata}
|
||||||
alias BDS.Posts.Post
|
alias BDS.Posts.Post
|
||||||
@@ -84,7 +84,7 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
def update(socket, params, reload) do
|
def update(socket, params, reload) do
|
||||||
case socket.assigns.current_tab do
|
case socket.assigns.current_tab do
|
||||||
%{type: :post, id: post_id} ->
|
%{type: :post, id: post_id} ->
|
||||||
case Repo.get(Post, post_id) do
|
case Posts.get_post(post_id) do
|
||||||
nil ->
|
nil ->
|
||||||
socket
|
socket
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def persist_socket(socket, post_id, action, reload, append_output) do
|
def persist_socket(socket, post_id, action, reload, append_output) do
|
||||||
case Repo.get(Post, post_id) do
|
case Posts.get_post(post_id) do
|
||||||
nil ->
|
nil ->
|
||||||
socket
|
socket
|
||||||
|
|
||||||
@@ -131,13 +131,13 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
case persist(post, draft, active_language, metadata, action) do
|
case persist(post, draft, active_language, metadata, action) do
|
||||||
{:ok, record} ->
|
{:ok, record} ->
|
||||||
workbench = Workbench.clear_dirty(socket.assigns.workbench, :post, post_id)
|
workbench = Workbench.clear_dirty(socket.assigns.workbench, :post, post_id)
|
||||||
normalized_form = persisted_form(Repo.get!(Post, post_id), metadata, active_language)
|
normalized_form = persisted_form(Posts.get_post!(post_id), metadata, active_language)
|
||||||
|
|
||||||
socket
|
socket
|
||||||
|> assign(:workbench, workbench)
|
|> assign(:workbench, workbench)
|
||||||
|> assign(:post_editor_drafts, put_nested_map(socket.assigns.post_editor_drafts, post_id, active_language, normalized_form))
|
|> assign(:post_editor_drafts, put_nested_map(socket.assigns.post_editor_drafts, post_id, active_language, normalized_form))
|
||||||
|> assign(:post_editor_save_states, Map.put(socket.assigns.post_editor_save_states, post_id, save_state_for_action(action)))
|
|> assign(:post_editor_save_states, Map.put(socket.assigns.post_editor_save_states, post_id, save_state_for_action(action)))
|
||||||
|> assign(:tab_meta, Map.put(socket.assigns.tab_meta, {:post, post_id}, %{title: record_title(record, Repo.get!(Post, post_id)), subtitle: Atom.to_string(record_status(record))}))
|
|> assign(:tab_meta, Map.put(socket.assigns.tab_meta, {:post, post_id}, %{title: record_title(record, Posts.get_post!(post_id)), subtitle: Atom.to_string(record_status(record))}))
|
||||||
|> reload.(workbench)
|
|> reload.(workbench)
|
||||||
|
|
||||||
{:error, reason} ->
|
{:error, reason} ->
|
||||||
@@ -149,7 +149,7 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def discard_socket(socket, post_id, reload, append_output) do
|
def discard_socket(socket, post_id, reload, append_output) do
|
||||||
case Repo.get(Post, post_id) do
|
case Posts.get_post(post_id) do
|
||||||
nil ->
|
nil ->
|
||||||
socket
|
socket
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
normalized_mode = normalize_mode(mode)
|
normalized_mode = normalize_mode(mode)
|
||||||
|
|
||||||
if normalized_mode == :preview do
|
if normalized_mode == :preview do
|
||||||
case Repo.get(Post, post_id) do
|
case Posts.get_post(post_id) do
|
||||||
%Post{} = post ->
|
%Post{} = post ->
|
||||||
_ = Preview.ensure_preview(post.project_id)
|
_ = Preview.ensure_preview(post.project_id)
|
||||||
|
|
||||||
@@ -250,7 +250,7 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
|> append_output.(translated("Detect Language"), translated("Automatic AI actions stay gated by airplane mode."), nil, "info")
|
|> append_output.(translated("Detect Language"), translated("Automatic AI actions stay gated by airplane mode."), nil, "info")
|
||||||
|> reload.(socket.assigns.workbench)
|
|> reload.(socket.assigns.workbench)
|
||||||
else
|
else
|
||||||
case Repo.get(Post, post_id) do
|
case Posts.get_post(post_id) do
|
||||||
nil ->
|
nil ->
|
||||||
socket
|
socket
|
||||||
|
|
||||||
@@ -318,7 +318,7 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def apply_ai_suggestions(socket, post_id, fields, reload, append_output) do
|
def apply_ai_suggestions(socket, post_id, fields, reload, append_output) do
|
||||||
case Repo.get(Post, post_id) do
|
case Posts.get_post(post_id) do
|
||||||
nil ->
|
nil ->
|
||||||
socket
|
socket
|
||||||
|
|
||||||
@@ -366,7 +366,7 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def add_list_value(socket, post_id, kind, value, reload) when kind in [:tags, :categories] do
|
def add_list_value(socket, post_id, kind, value, reload) when kind in [:tags, :categories] do
|
||||||
case Repo.get(Post, post_id) do
|
case Posts.get_post(post_id) do
|
||||||
nil ->
|
nil ->
|
||||||
socket
|
socket
|
||||||
|
|
||||||
@@ -399,7 +399,7 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def remove_list_value(socket, post_id, kind, value, reload) when kind in [:tags, :categories] do
|
def remove_list_value(socket, post_id, kind, value, reload) when kind in [:tags, :categories] do
|
||||||
case Repo.get(Post, post_id) do
|
case Posts.get_post(post_id) do
|
||||||
nil ->
|
nil ->
|
||||||
socket
|
socket
|
||||||
|
|
||||||
@@ -417,7 +417,7 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def build(%{current_tab: %{type: :post, id: post_id}} = assigns) do
|
def build(%{current_tab: %{type: :post, id: post_id}} = assigns) do
|
||||||
case Repo.get(Post, post_id) do
|
case Posts.get_post(post_id) do
|
||||||
nil ->
|
nil ->
|
||||||
nil
|
nil
|
||||||
|
|
||||||
@@ -446,7 +446,7 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
display_title: display_title(form["title"], post.slug, post.id),
|
display_title: display_title(form["title"], post.slug, post.id),
|
||||||
subtitle: nil,
|
subtitle: nil,
|
||||||
slug: post.slug || post.id,
|
slug: post.slug || post.id,
|
||||||
status: post.status || :draft,
|
status: post.status,
|
||||||
dirty?: Workbench.dirty?(assigns.workbench, :post, post.id),
|
dirty?: Workbench.dirty?(assigns.workbench, :post, post.id),
|
||||||
save_state: Map.get(assigns.post_editor_save_states, post.id, :idle),
|
save_state: Map.get(assigns.post_editor_save_states, post.id, :idle),
|
||||||
quick_actions_open?: Map.get(assigns.post_editor_quick_actions_open, post.id, false),
|
quick_actions_open?: Map.get(assigns.post_editor_quick_actions_open, post.id, false),
|
||||||
@@ -454,8 +454,8 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
excerpt_expanded: Map.get(expanded, :excerpt, false),
|
excerpt_expanded: Map.get(expanded, :excerpt, false),
|
||||||
mode: Map.get(assigns.post_editor_modes, post.id, :markdown),
|
mode: Map.get(assigns.post_editor_modes, post.id, :markdown),
|
||||||
editing_canonical?: editing_canonical_language?(translations, active_language, canonical_language),
|
editing_canonical?: editing_canonical_language?(translations, active_language, canonical_language),
|
||||||
can_publish?: (post.status || :draft) == :draft,
|
can_publish?: post.status == :draft,
|
||||||
can_delete?: (post.status || :draft) == :published,
|
can_delete?: post.status == :published,
|
||||||
has_published_version?: has_published_version?(post),
|
has_published_version?: has_published_version?(post),
|
||||||
discard_label: discard_label(post),
|
discard_label: discard_label(post),
|
||||||
discard_title: discard_title(post),
|
discard_title: discard_title(post),
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ defmodule BDS.Desktop.ShellLive.PostEditor.PostMetadata do
|
|||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
alias BDS.{I18n, Metadata, PostLinks, Posts, Preview, Repo, Templates}
|
alias BDS.{I18n, Media, Metadata, PostLinks, Posts, Preview, Repo, Templates}
|
||||||
alias BDS.Desktop.ShellData
|
alias BDS.Desktop.ShellData
|
||||||
alias BDS.Media.Media
|
alias BDS.Media.Media, as: MediaRecord
|
||||||
alias BDS.Posts.{Post, PostMedia}
|
alias BDS.Posts.{Post, PostMedia}
|
||||||
|
|
||||||
def project_metadata(nil), do: %{main_language: "en", blog_languages: []}
|
def project_metadata(nil), do: %{main_language: "en", blog_languages: []}
|
||||||
@@ -56,8 +56,8 @@ defmodule BDS.Desktop.ShellLive.PostEditor.PostMetadata do
|
|||||||
)
|
)
|
||||||
|
|
||||||
Enum.map(rows, fn {media_id, sort_order} ->
|
Enum.map(rows, fn {media_id, sort_order} ->
|
||||||
case Repo.get(Media, media_id) do
|
case Media.get_media(media_id) do
|
||||||
%Media{} = media ->
|
%MediaRecord{} = media ->
|
||||||
%{
|
%{
|
||||||
media_id: media.id,
|
media_id: media.id,
|
||||||
has_thumbnail: String.starts_with?(to_string(media.mime_type || ""), "image/"),
|
has_thumbnail: String.starts_with?(to_string(media.mime_type || ""), "image/"),
|
||||||
@@ -83,7 +83,7 @@ defmodule BDS.Desktop.ShellLive.PostEditor.PostMetadata do
|
|||||||
|
|
||||||
defp related_posts(links, key) do
|
defp related_posts(links, key) do
|
||||||
Enum.map(links, fn link ->
|
Enum.map(links, fn link ->
|
||||||
case Repo.get(Post, Map.fetch!(link, key)) do
|
case Posts.get_post(Map.fetch!(link, key)) do
|
||||||
%Post{} = post -> %{id: post.id, title: post.title || post.slug || post.id, text: link.link_text || post.slug || post.id}
|
%Post{} = post -> %{id: post.id, title: post.title || post.slug || post.id, text: link.link_text || post.slug || post.id}
|
||||||
_other -> nil
|
_other -> nil
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ defmodule BDS.Desktop.ShellLive.SettingsEditor.EditorSettings do
|
|||||||
|
|
||||||
use Phoenix.Component
|
use Phoenix.Component
|
||||||
|
|
||||||
alias BDS.Persistence
|
alias BDS.Settings
|
||||||
alias BDS.Repo
|
|
||||||
alias BDS.Settings.Setting
|
|
||||||
alias BDS.Desktop.ShellData
|
alias BDS.Desktop.ShellData
|
||||||
|
|
||||||
def editor_form do
|
def editor_form do
|
||||||
@@ -46,22 +44,11 @@ defmodule BDS.Desktop.ShellLive.SettingsEditor.EditorSettings do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def get_global_setting(key) do
|
def get_global_setting(key) do
|
||||||
case Repo.get(Setting, key) do
|
Settings.get_global_setting(key)
|
||||||
%Setting{value: value} -> value
|
|
||||||
_other -> nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def put_global_setting(key, value) do
|
def put_global_setting(key, value) do
|
||||||
setting = Repo.get(Setting, key) || %Setting{}
|
Settings.put_global_setting(key, value)
|
||||||
|
|
||||||
setting
|
|
||||||
|> Setting.changeset(%{key: key, value: to_string(value || ""), updated_at: Persistence.now_ms()})
|
|
||||||
|> Repo.insert_or_update()
|
|
||||||
|> case do
|
|
||||||
{:ok, _setting} -> :ok
|
|
||||||
{:error, reason} -> {:error, reason}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp editor_attrs(assigns) do
|
defp editor_attrs(assigns) do
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ defmodule BDS.Desktop.ShellLive.TabHelpers do
|
|||||||
@moduledoc false
|
@moduledoc false
|
||||||
|
|
||||||
alias BDS.Desktop.ShellData
|
alias BDS.Desktop.ShellData
|
||||||
alias BDS.Media.Media
|
alias BDS.{Media, Posts}
|
||||||
|
alias BDS.Media.Media, as: MediaRecord
|
||||||
alias BDS.Posts.Post
|
alias BDS.Posts.Post
|
||||||
alias BDS.Repo
|
|
||||||
alias BDS.UI.Registry
|
alias BDS.UI.Registry
|
||||||
|
|
||||||
def tab_title(nil, _tab_meta), do: translated("Dashboard")
|
def tab_title(nil, _tab_meta), do: translated("Dashboard")
|
||||||
@@ -59,29 +59,29 @@ defmodule BDS.Desktop.ShellLive.TabHelpers do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def post_title(post_id) do
|
def post_title(post_id) do
|
||||||
case Repo.get(Post, post_id) do
|
case Posts.get_post(post_id) do
|
||||||
%Post{} = post -> post.title || post.slug || post.id
|
%Post{} = post -> post.title || post.slug || post.id
|
||||||
_other -> "Post"
|
_other -> "Post"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def post_subtitle(post_id) do
|
def post_subtitle(post_id) do
|
||||||
case Repo.get(Post, post_id) do
|
case Posts.get_post(post_id) do
|
||||||
%Post{} = post -> post.slug || "draft"
|
%Post{} = post -> post.slug || "draft"
|
||||||
_other -> "draft"
|
_other -> "draft"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def media_title(media_id) do
|
def media_title(media_id) do
|
||||||
case Repo.get(Media, media_id) do
|
case Media.get_media(media_id) do
|
||||||
%Media{} = media -> media.title || media.filename || media.id
|
%MediaRecord{} = media -> media.title || media.filename || media.id
|
||||||
_other -> "Media"
|
_other -> "Media"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def media_subtitle(media_id) do
|
def media_subtitle(media_id) do
|
||||||
case Repo.get(Media, media_id) do
|
case Media.get_media(media_id) do
|
||||||
%Media{} = media -> media.filename || media.mime_type || "media"
|
%MediaRecord{} = media -> media.filename || media.mime_type || "media"
|
||||||
_other -> "media"
|
_other -> "media"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -115,6 +115,9 @@ defmodule BDS.Media do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec get_media(String.t()) :: Media.t() | nil
|
||||||
|
def get_media(media_id), do: Repo.get(Media, media_id)
|
||||||
|
|
||||||
@spec update_media(String.t(), attrs()) ::
|
@spec update_media(String.t(), attrs()) ::
|
||||||
{:ok, Media.t()} | {:error, :not_found | Ecto.Changeset.t()}
|
{:ok, Media.t()} | {:error, :not_found | Ecto.Changeset.t()}
|
||||||
def update_media(media_id, attrs) do
|
def update_media(media_id, attrs) do
|
||||||
|
|||||||
@@ -348,6 +348,9 @@ defmodule BDS.Posts do
|
|||||||
end
|
end
|
||||||
|
|
||||||
@spec get_post!(String.t()) :: Post.t()
|
@spec get_post!(String.t()) :: Post.t()
|
||||||
|
@spec get_post(String.t()) :: Post.t() | nil
|
||||||
|
def get_post(post_id), do: Repo.get(Post, post_id)
|
||||||
|
|
||||||
def get_post!(post_id), do: Repo.get!(Post, post_id)
|
def get_post!(post_id), do: Repo.get!(Post, post_id)
|
||||||
|
|
||||||
@spec get_post_translation!(String.t()) :: Translation.t()
|
@spec get_post_translation!(String.t()) :: Translation.t()
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ defmodule BDS.Scripts do
|
|||||||
|> Repo.insert()
|
|> Repo.insert()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec get_script(String.t()) :: Script.t() | nil
|
||||||
|
def get_script(script_id), do: Repo.get(Script, script_id)
|
||||||
|
|
||||||
def publish_script(script_id) do
|
def publish_script(script_id) do
|
||||||
case Repo.get(Script, script_id) do
|
case Repo.get(Script, script_id) do
|
||||||
nil ->
|
nil ->
|
||||||
|
|||||||
@@ -7,6 +7,23 @@ defmodule BDS.Scripts.Script do
|
|||||||
@primary_key {:id, :string, autogenerate: false}
|
@primary_key {:id, :string, autogenerate: false}
|
||||||
@foreign_key_type :string
|
@foreign_key_type :string
|
||||||
|
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
id: String.t(),
|
||||||
|
project_id: String.t(),
|
||||||
|
slug: String.t() | nil,
|
||||||
|
title: String.t() | nil,
|
||||||
|
kind: :macro | :utility | :transform | nil,
|
||||||
|
entrypoint: String.t() | nil,
|
||||||
|
enabled: boolean() | nil,
|
||||||
|
version: integer() | nil,
|
||||||
|
file_path: String.t() | nil,
|
||||||
|
status: :draft | :published | nil,
|
||||||
|
content: String.t() | nil,
|
||||||
|
created_at: integer() | nil,
|
||||||
|
updated_at: integer() | nil,
|
||||||
|
project: term()
|
||||||
|
}
|
||||||
|
|
||||||
schema "scripts" do
|
schema "scripts" do
|
||||||
field :slug, :string
|
field :slug, :string
|
||||||
field :title, :string
|
field :title, :string
|
||||||
|
|||||||
28
lib/bds/settings.ex
Normal file
28
lib/bds/settings.ex
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
defmodule BDS.Settings do
|
||||||
|
@moduledoc false
|
||||||
|
|
||||||
|
alias BDS.Persistence
|
||||||
|
alias BDS.Repo
|
||||||
|
alias BDS.Settings.Setting
|
||||||
|
|
||||||
|
@spec get_global_setting(String.t()) :: String.t() | nil
|
||||||
|
def get_global_setting(key) do
|
||||||
|
case Repo.get(Setting, key) do
|
||||||
|
%Setting{value: value} -> value
|
||||||
|
_other -> nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec put_global_setting(String.t(), term()) :: :ok | {:error, Ecto.Changeset.t()}
|
||||||
|
def put_global_setting(key, value) do
|
||||||
|
setting = Repo.get(Setting, key) || %Setting{}
|
||||||
|
|
||||||
|
setting
|
||||||
|
|> Setting.changeset(%{key: key, value: to_string(value || ""), updated_at: Persistence.now_ms()})
|
||||||
|
|> Repo.insert_or_update()
|
||||||
|
|> case do
|
||||||
|
{:ok, _setting} -> :ok
|
||||||
|
{:error, reason} -> {:error, reason}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -38,6 +38,9 @@ defmodule BDS.Templates do
|
|||||||
|> Repo.insert()
|
|> Repo.insert()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec get_template(String.t()) :: Template.t() | nil
|
||||||
|
def get_template(template_id), do: Repo.get(Template, template_id)
|
||||||
|
|
||||||
def publish_template(template_id) do
|
def publish_template(template_id) do
|
||||||
case Repo.get(Template, template_id) do
|
case Repo.get(Template, template_id) do
|
||||||
nil ->
|
nil ->
|
||||||
|
|||||||
@@ -7,6 +7,22 @@ defmodule BDS.Templates.Template do
|
|||||||
@primary_key {:id, :string, autogenerate: false}
|
@primary_key {:id, :string, autogenerate: false}
|
||||||
@foreign_key_type :string
|
@foreign_key_type :string
|
||||||
|
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
id: String.t(),
|
||||||
|
project_id: String.t(),
|
||||||
|
slug: String.t() | nil,
|
||||||
|
title: String.t() | nil,
|
||||||
|
kind: :post | :list | :not_found | :partial | nil,
|
||||||
|
enabled: boolean() | nil,
|
||||||
|
version: integer() | nil,
|
||||||
|
file_path: String.t() | nil,
|
||||||
|
status: :draft | :published | nil,
|
||||||
|
content: String.t() | nil,
|
||||||
|
created_at: integer() | nil,
|
||||||
|
updated_at: integer() | nil,
|
||||||
|
project: term()
|
||||||
|
}
|
||||||
|
|
||||||
schema "templates" do
|
schema "templates" do
|
||||||
field :slug, :string
|
field :slug, :string
|
||||||
field :title, :string
|
field :title, :string
|
||||||
|
|||||||
@@ -4,6 +4,29 @@ defmodule BDS.Desktop.ShellLiveTest do
|
|||||||
import Phoenix.ConnTest
|
import Phoenix.ConnTest
|
||||||
import Phoenix.LiveViewTest
|
import Phoenix.LiveViewTest
|
||||||
|
|
||||||
|
@shell_live_source_root Path.expand("../../../lib/bds/desktop/shell_live", __DIR__)
|
||||||
|
|
||||||
|
test "shell live modules use contexts instead of direct Repo.get calls" do
|
||||||
|
source_files =
|
||||||
|
[Path.expand("../../../lib/bds/desktop/shell_live.ex", __DIR__) |
|
||||||
|
Path.wildcard(Path.join(@shell_live_source_root, "**/*.ex"))]
|
||||||
|
|
||||||
|
offenders =
|
||||||
|
source_files
|
||||||
|
|> Enum.flat_map(fn path ->
|
||||||
|
path
|
||||||
|
|> File.read!()
|
||||||
|
|> String.split("\n")
|
||||||
|
|> Enum.with_index(1)
|
||||||
|
|> Enum.filter(fn {line, _line_number} ->
|
||||||
|
String.contains?(line, "Repo.get(") or String.contains?(line, "Repo.get!(")
|
||||||
|
end)
|
||||||
|
|> Enum.map(fn {_line, line_number} -> "#{Path.relative_to_cwd(path)}:#{line_number}" end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert offenders == []
|
||||||
|
end
|
||||||
|
|
||||||
alias BDS.Persistence
|
alias BDS.Persistence
|
||||||
alias BDS.AI
|
alias BDS.AI
|
||||||
alias BDS.CliSync.Watcher
|
alias BDS.CliSync.Watcher
|
||||||
|
|||||||
Reference in New Issue
Block a user