This file supplements CLAUDE.md with Phoenix/Elixir coding conventions specific to this project.
When conflicts exist, CLAUDE.md takes precedence.
- Do NOT wrap templates with
<Layouts.app>— auto-layout vialive_sessionhandles this; wrapping causes duplicate flash IDs - Use DaisyUI component classes (
btn,card,badge,modal, etc.) — this is the project's UI library - This project uses
@current_user(NOTcurrent_scope) for the authenticated user assign - Tailwind CSS v3 configuration is used (NOT v4 import syntax)
- Use
Reqfor all HTTP requests — never use:httpoison,:tesla, or:httpc - Use
mix precommitafter all changes to run compile, format, and test checks - Use
/bin/zshfor shell commands when running tools
- Never nest multiple modules in the same file
- Never use
String.to_atom/1on user input — useString.to_existing_atom/1only on trusted input - Predicate functions end with
?(e.g.can_edit_article?/2), reserveis_prefix for guards - Use
Ecto.Changeset.get_field/2to access changeset fields, not map access syntax - Fields set programmatically (e.g.
user_id) must not appear incastcalls - Always
import Ecto.Querywhen writing queries
- Always use
~Hsigil or.html.heexfiles — never~E - Use
{@assign}for interpolation in tag attributes and bodies - Use
<%= ... %>only for block constructs (if,for,case,cond) - Use the
<.icon name="hero-..." />component for all icons - Use the
<.input>component fromcore_components.exfor form inputs - Always wrap user-visible text in
gettext()— never bare English strings - HEEx comments:
<%!-- comment --%>
- Never use deprecated
live_redirect/live_patch— use<.link navigate={...}>/<.link patch={...}> - Use
push_navigate/push_patchin LiveView code - Use
phx-trigger-actionpattern for session writes (POST to controllers) - Use LiveView streams for collections to avoid memory issues
- Always provide unique DOM IDs on forms, buttons, and key elements
- Avoid LiveComponents unless there is a strong need
- Use
start_supervised!/1for process cleanup between tests - Avoid
Process.sleep/1— useProcess.monitor/1+assert_receive {:DOWN, ...}or:sys.get_state/1 - Test against element IDs and structure, not raw HTML text
- Use
Phoenix.LiveViewTestfunctions:element/2,has_element?/2,render_submit/2,render_change/2