116 lines
4.8 KiB
Markdown
116 lines
4.8 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
Microwaveprop is a Phoenix 1.8 web application (Elixir ~> 1.15) with LiveView, PostgreSQL via Ecto, and Tailwind CSS v4 + daisyUI for styling. HTTP server is Bandit.
|
|
|
|
**All UI must be built with Phoenix LiveView.** Write idiomatic Elixir throughout. Phoenix uses esbuild for JS bundling — never run npm or use Node.js tooling.
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
# Initial setup (deps, DB, assets)
|
|
mix setup
|
|
|
|
# Run dev server (live reloads automatically, no restart needed)
|
|
mix phx.server
|
|
iex -S mix phx.server # with IEx shell
|
|
|
|
# Run all tests
|
|
mix test
|
|
|
|
# Run a single test file
|
|
mix test test/microwaveprop_web/controllers/page_controller_test.exs
|
|
|
|
# Run previously failed tests
|
|
mix test --failed
|
|
|
|
# Format code (runs Styler plugin automatically)
|
|
mix format
|
|
|
|
# Static analysis
|
|
mix credo
|
|
|
|
# Pre-commit check (compile with warnings-as-errors, unlock unused deps, format, test)
|
|
# Runs in test env
|
|
mix precommit
|
|
|
|
# Database
|
|
mix ecto.create
|
|
mix ecto.migrate
|
|
mix ecto.gen.migration migration_name_using_underscores
|
|
mix ecto.reset # drop + setup
|
|
|
|
# Assets
|
|
mix assets.build
|
|
mix assets.deploy # minified + digest
|
|
```
|
|
|
|
## Architecture
|
|
|
|
Standard Phoenix 1.8 structure:
|
|
|
|
- `lib/microwaveprop/` - Business logic (contexts, schemas, repo)
|
|
- `repo.ex` - Ecto PostgreSQL repository
|
|
- `application.ex` - OTP supervision tree
|
|
- `lib/microwaveprop_web/` - Web layer
|
|
- `router.ex` - Routes and pipelines. The `:browser` scope is aliased to `MicrowavepropWeb`
|
|
- `components/core_components.ex` - UI component library (flash, button, input, table, list, icon)
|
|
- `components/layouts.ex` - Layout components; `Layouts` is aliased in `microwaveprop_web.ex`
|
|
- `controllers/` - Traditional controllers
|
|
- `config/` - Environment configs (`dev.exs`, `test.exs`, `prod.exs`, `runtime.exs`)
|
|
- `assets/` - JS (esbuild, not npm) and CSS (Tailwind v4). Only `app.js` and `app.css` bundles are supported
|
|
- `test/support/` - `ConnCase` and `DataCase` test helpers
|
|
|
|
## Key Conventions (from AGENTS.md)
|
|
|
|
### Phoenix / LiveView
|
|
- LiveView templates must start with `<Layouts.app flash={@flash} ...>` wrapping all content
|
|
- Use `<.icon name="hero-x-mark" class="w-5 h-5"/>` for icons, never Heroicons modules
|
|
- Use `<.input>` from core_components for form inputs
|
|
- Use `to_form/2` for forms, never pass changesets directly to templates
|
|
- Use LiveView streams for collections, never `phx-update="append"`/`"prepend"`
|
|
- Avoid LiveComponents unless strongly justified
|
|
- LiveView names use `Live` suffix: `MicrowavepropWeb.ThingLive`
|
|
- Use `<.link navigate={...}>` / `<.link patch={...}>`, never `live_redirect`/`live_patch`
|
|
- Router scope aliases prefix automatically; don't add redundant aliases
|
|
|
|
### HEEx Templates
|
|
- Use `{...}` for attribute interpolation, `<%= %>` only for block constructs (if/for/cond) in tag bodies
|
|
- Class lists must use `[...]` syntax for conditional classes
|
|
- Use `<%!-- comment --%>` for HTML comments
|
|
- Use `phx-no-curly-interpolation` on tags containing literal curly braces
|
|
- Never use `<% Enum.each %>`, always use `<%= for item <- @collection do %>`
|
|
|
|
### JS / CSS
|
|
- Assets are bundled via esbuild and Tailwind mix tasks — never use npm, npx, or Node.js directly
|
|
- Tailwind v4: no `tailwind.config.js`, uses `@import "tailwindcss" source(none)` syntax in `app.css`
|
|
- Never use `@apply` in CSS
|
|
- No inline `<script>` tags; use colocated JS hooks (`:type={Phoenix.LiveView.ColocatedHook}`) with `.` prefix names
|
|
- Vendor deps must be imported into `app.js`/`app.css`, no external script `src` or link `href`
|
|
|
|
### Elixir
|
|
- Write idiomatic Elixir: use pattern matching, pipe operator, and the standard library
|
|
- Styler auto-formats on `mix format` (alias sorting, pipe chains, moduledoc enforcement, etc.)
|
|
- No index access on lists (`mylist[i]`); use `Enum.at/2`
|
|
- Bind results of `if`/`case`/`cond` blocks to variables (immutable rebinding)
|
|
- Never nest multiple modules in one file
|
|
- Use `struct.field` not `struct[:field]` (structs don't implement Access)
|
|
- Predicate functions: `thing?` not `is_thing` (reserve `is_` for guards)
|
|
- Use `Req` for HTTP requests, never httpoison/tesla/httpc
|
|
|
|
### Ecto
|
|
- Preload associations in queries when accessed in templates
|
|
- `field :name, :string` for both string and text columns
|
|
- Use `Ecto.Changeset.get_field/2` to access changeset fields
|
|
- Programmatic fields (e.g. `user_id`) must not be in `cast` calls
|
|
- Generate migrations with `mix ecto.gen.migration`
|
|
|
|
### Testing
|
|
- Use `start_supervised!/1` for process cleanup
|
|
- Use `Process.monitor/1` + `assert_receive {:DOWN, ...}` instead of `Process.sleep`
|
|
- Use `LazyHTML` selectors for DOM assertions, never raw HTML matching
|
|
- Test against element IDs defined in templates
|
|
- Debug with `LazyHTML.filter/2` + `IO.inspect` instead of raw HTML dumps
|