一键导入
landing-page-contexts
Guide to Context module patterns in landing_page_backend — Ecto queries, dynamic query building, Ecto.Multi, and Outbox messaging.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Guide to Context module patterns in landing_page_backend — Ecto queries, dynamic query building, Ecto.Multi, and Outbox messaging.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Phoenix Channel patterns in landing_page_backend — real-time collaboration, WebSocket topics, broadcasting, and channel structure.
Guide to Phoenix Controller structure in landing_page_backend using FallbackController, tuple responses, and permission plugs.
Patterns for creating Oban background workers in landing_page_backend — queue configuration, job arguments, retry strategies, and dynamic query processing.
Custom Plug middleware patterns in landing_page_backend — authentication (JWT/Passport), authorization, permission checking, and rate limiting.
Guidelines for creating Ecto Schemas in landing_page_backend, including binary UUID primary keys, virtual fields, custom json/1 function, and multiple changeset patterns.
Vue 2 Options API patterns for the Landing Page editor — Vuex namespaced stores, Ant Design Vue components, mixins, computed getters/setters, and axios API calls.
| name | landing_page-contexts |
| description | Guide to Context module patterns in landing_page_backend — Ecto queries, dynamic query building, Ecto.Multi, and Outbox messaging. |
| metadata | {"author":"Vũ Lưu","version":"2026.03.30","source":"Source code landing_page_backend"} |
Context module conventions for business logic, queries, and transactions.
| Topic | Description | Reference |
|---|---|---|
| Query Building | Ecto.Query, from macros, select fields, dynamic queries | core-queries |
| Transactions & Outbox | Ecto.Multi transactions with Outbox messaging | core-multi-outbox |
defmodule LandingPage.Pages do
import Ecto.Query, warn: false
alias LandingPage.{Repo, Tools}
alias LandingPage.Pages.{Page, PageVersion, PagePublished}
alias LandingPage.Organizations.{PageRight, TeamPage}
alias LandingPage.Permissions.PageAccountPermission
@light_page_fields [
:id, :status, :html, :css, :head, :settings, :extra_script, :extra_css,
:inserted_at, :updated_at, :organization_id
]
# --- Simple query ---
def get_page(page_id) do
case Repo.get(Page, page_id) do
nil -> {:error, :not_found}
page -> {:ok, page}
end
end
# --- Query with preloads ---
def get_page_detail(%Page{} = page) do
page_id = Ecto.UUID.cast!(page.id)
query_shared = from pap in PageAccountPermission, preload: [:account]
query_pub = from pp in PagePublished, select: [:domain, :path, :status]
query = from p in Page,
where: p.id == ^page_id,
preload: [:owner, shared_accounts: ^query_shared, published: ^query_pub]
Repo.one(query)
end
# --- Optimized select ---
def get_page_by_custom_domain(host, path) do
query = from p in Page,
where: p.custom_domain == ^host and p.custom_path == ^path
and p.status == ^Enum.PageStatus.value(:active),
select: ^@light_page_fields
if res = Repo.one(query), do: {:ok, res}, else: {:error, :not_found}
end
# --- Dynamic query ---
def search_form_data(page_id, filters) do
dyn = dynamic([f], f.page_id == ^page_id)
dyn = if phone = filters["phone_number"] do
dynamic([f], ^dyn and f.phone_number == ^phone)
else
dyn
end
dyn = if status = filters["status"] do
dynamic([f], ^dyn and f.status == ^status)
else
dyn
end
from(f in PageFormData, where: ^dyn, order_by: [desc: :inserted_at])
|> Repo.all()
end
end