Skip to content

Latest commit

 

History

History
77 lines (55 loc) · 5.94 KB

CODING_STANDARDS.md

File metadata and controls

77 lines (55 loc) · 5.94 KB

Coding Standards

Backpex's own idioms for the library code in lib/, assets/js/, guides/ and the tests. mix lint already enforces formatting and Credo in strict mode with every check that .credo.exs leaves on; this file holds what the linters cannot see. Where an upstream rule linked below disagrees with this file, this file wins.

Extension points

  • Fields, filters, metrics and adapters describe data or return conditions and expressions; the adapter places them in the query it builds. Examples: c:Backpex.Field.search_condition/3 returns a dynamic, the :select field option is a dynamic, c:Backpex.Metric.data/2 returns the data from the assigns. A new option or callback takes this shape: it receives values or assigns and returns a condition, an expression or data.
  • These still receive the adapter's query and return it changed: c:Backpex.Filter.query/4, c:Backpex.Metric.query/3, the item_query option of Backpex.Adapters.Ecto and the options_query option of BelongsTo, HasMany and HasManyThrough. They are the old shape; new code follows the one above.
  • Options are a NimbleOptions schema in @config_schema, defined above @moduledoc, rendered into it with #{NimbleOptions.docs(@config_schema)} and passed to use Backpex.Field, config_schema: @config_schema (adapters: use Backpex.Adapter), which validates the configuration against it. The options of use Backpex.LiveResource live in @options_schema in lib/backpex/live_resource.ex.

Public API and docs

  • A public function without @doc false is API. Public functions that only other Backpex modules call get @doc false (e.g. Backpex.__/2, validate_config!/2).
  • CI builds the docs with mix docs --warnings-as-errors, which mix lint leaves out (mix ci runs it): every reference in @doc, @moduledoc and the guides must resolve. A new guide goes into extras in mix.exs.

Breaking changes

Backpex is 0.x: when the cleaner design breaks the API, take the cleaner design. A breaking PR gets the breaking-change label and a section in the upgrade guide of the next minor version. @version in mix.exs is the latest release; if guides/upgrading/v<next>.md does not exist yet, create it with the "Bump Your Deps" section of the previous guide and add it to the top of the upgrade guides in extras in mix.exs. Each section names the change in its heading, says why it changed and shows the code users change, as in guides/upgrading/v0.23.md.

Translations

Wrap every user-facing string in Backpex.__/2, with the LiveResource as second argument when one is in scope (@live_resource, socket.assigns.live_resource). Interpolate with a tuple: Backpex.__({"New %{resource}", %{resource: name}}, live_resource). Then run mix gettext.extract to update priv/gettext/backpex.pot; CI checks it with mix gettext.extract --check-up-to-date.

Styling

Build on the components in lib/backpex/html/, compose daisyUI components with Tailwind utilities, and use theme colors (primary, base-content, …). Look up daisyUI and Tailwind in the Context7 MCP.

Accessibility

Required for every markup change. integration_test/e2e/a11y_test.exs audits every view of the test app's LiveResources: list a new fixture there, and audit other new UI states with assert_a11y/1 from Backpex.E2ECase.

JavaScript hooks

Solve interaction in HEEx and LiveView first; a phx-hook is for behaviour that needs the client. Hooks live in assets/js/hooks/_<name>.js and are exported from assets/js/hooks/index.js as Backpex<Name>. After any change in assets/js, follow CONTRIBUTING.md › JavaScript.

Tests

  • CONTRIBUTING.md › Testing has the commands, the test app and its fixtures.
  • A bug fix starts with a test that fails on develop for that reason, in the existing test module of the area; then the fix. A purely visual fix (spacing, colour, alignment) shows before/after screenshots in the PR instead of a test.
  • Test at the lowest layer that fails: test/ when the logic runs without a LiveView or the database, integration_test/ when it needs them, :e2e only for what needs a browser (hooks, keyboard, accessibility, themes).
  • Browser tests (Backpex.E2ECase) run on PhoenixTest.Playwright; read deps/phoenix_test_playwright/usage-rules.md before writing one. The generated block below cannot link it, since the package is a test-only dependency.
  • Library tests live in parallel directories, e.g. test/html/ (Backpex.HTML.FormTest) and test/backpex/html/ (Backpex.HTML.LayoutTest). Run grep -rn "defmodule <Name>" test integration_test before adding a test file and extend the module that exists: a second module of the same name makes mix test fail depending on load order.

Upstream package rules

Generated by mix usage_rules.sync from the usage_rules: config in mix.exs: change the config, never the block. Read a package's file before working in its area: Ecto, HEEx, LiveView or the router (phoenix:*), the installer task in lib/mix/ (igniter), Sobelow findings (sobelow).

phoenix:ecto usage

phoenix:ecto usage rules

phoenix:html usage

phoenix:html usage rules

phoenix:liveview usage

phoenix:liveview usage rules

phoenix:phoenix usage

phoenix:phoenix usage rules

igniter usage

A code generation and project patching framework

igniter usage rules

sobelow usage

Security-focused static analysis for Elixir & the Phoenix framework

sobelow usage rules