Skip to content

Latest commit

 

History

History
195 lines (150 loc) · 7.39 KB

File metadata and controls

195 lines (150 loc) · 7.39 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Lightning is an open source workflow platform for governments and non-profits to move health and survey data between systems. It's built on Elixir/Phoenix with PostgreSQL, featuring React components and real-time collaborative editing via Yjs CRDTs.

Common Commands

Setup & Running

./bin/bootstrap              # Initial setup (run once, or when switching branches)
iex -S mix phx.server        # Run development server
mix verify                   # Run all code quality checks before committing

Elixir Testing

mix test                               # Run all tests (don't use -v flag)
mix test path/to/test.exs              # Run single file
mix test path/to/test.exs:42           # Run test at specific line

Frontend (always cd into assets/ first)

cd assets
npm test                     # Run unit tests once
npm run test:watch           # Run tests in watch mode
npm run test:e2e             # Run E2E tests
npm run test:e2e:ui          # E2E with interactive UI
npm run lint                 # Lint TypeScript
npx tsc --noEmit --project ./tsconfig.browser.json  # Type check

Code Quality

mix format                   # Format Elixir code (before committing)
mix credo --strict --all     # Static analysis
mix dialyzer                 # Type checking
mix sobelow                  # Security analysis

Database

mix ecto.migrate                              # Run migrations
mix ecto.reset                                # Drop and recreate database
mix ecto.gen.migration short_descriptive_name # Generate migration

Important Notes:

  • Phoenix auto-builds assets; use mix esbuild default or Tidewave MCP to check for build errors
  • For JS/TS issues, prefer mcp__ide__getDiagnostics over tsc
  • Never commit the .context directory (symlink to shared folder)

Architecture Overview

Key Contexts (lib/lightning/)

  • Workflows - DAGs with jobs, triggers, edges (lib/lightning/workflows.ex)
  • Jobs - JavaScript execution units with NPM adaptors
  • Accounts - User management, authentication
  • Projects - Main organizational unit
  • Credentials - External service authentication (encrypted)
  • Runs / WorkOrders - Workflow execution management
  • Collections - Key-value data store

Workflows Architecture

Workflows are directed acyclic graphs (DAGs):

  • Triggers: Webhook, Cron, or Kafka initiation
  • Jobs: JavaScript code executed with NPM adaptors
  • Edges: Flow control with conditions (:always, :on_job_success, :on_job_failure, :js_expression)

Key features:

  • Snapshot system with lock_version optimistic locking
  • Real-time collaborative editing via Yjs CRDTs
  • Presence system for edit priority

Collaborative Editor (assets/js/collaborative-editor/)

Real-time multi-user workflow editing using:

  • Yjs - CRDT for conflict-free collaborative editing
  • y-phoenix-channel - Yjs sync over Phoenix Channels
  • Y_ex - Elixir Yjs bindings (see .claude/guidelines/yex-guidelines.md)

Y.Doc transactions have non-obvious deadlock hazards on the BEAM. See .claude/guidelines/yex-guidelines.md §Transaction Deadlock Rules before writing any server-side Y.Doc code.

Store Architecture (see .claude/guidelines/store-structure.md):

  • SessionStore - Y.Doc, connection state, sync status
  • WorkflowStore - Jobs, triggers, edges, positions (Y.Doc backed)
  • AwarenessStore - User presence, cursors, selections
  • SessionContextStore - User, project, permissions (Phoenix Channel)
  • AdaptorStore / CredentialStore - Reference data

All stores use useSyncExternalStore + Immer and integrate with Redux DevTools in development.

Database

  • PostgreSQL with Ecto ORM
  • Dev: postgres://postgres:postgres@localhost:5432/lightning_dev
  • Test: lightning_test, no manual setup step; the test alias at mix.exs:227 runs ecto.create --quiet and ecto.migrate --quiet before the suite
  • Schemas alongside contexts in lib/lightning/

Development Guidelines

Elixir/Phoenix

  • Use {} brace syntax in HEEx templates
  • warnings_as_errors: true - code must compile without warnings

Before writing or reviewing any supervisor, GenServer, or named process, see .claude/guidelines/testable-supervision-trees.md. Don't bake name: __MODULE__ into a process or resolve collaborators from global state — it forces the test suite serial.

React/TypeScript

  • On the ReactComponent hook, props arrive as the element's raw attribute names: data-prefixed kebab-case, not camelCase
  • Use cn() utility from #/utils/cn for conditional CSS classes
  • Use heroicons via Tailwind: className="hero-check-micro h-4 w-4"
  • See .claude/guidelines/toast-notifications.md for notification patterns

Testing

  • Backend: ExUnit with ExMachina factories
  • Frontend: Vitest (see .claude/guidelines/testing-essentials.md)
  • E2E: Playwright (see .claude/guidelines/e2e-testing.md)
  • Assertion grouping and test file length: see .claude/guidelines/testing-essentials.md

Worker System

External Node.js workers (@openfn/ws-worker) execute JavaScript jobs:

  • WebSocket communication with JWT authentication
  • Two-layer security: Worker Token + Run Token
  • Generate keys: mix lightning.gen_worker_keys
  • Required ENVs: WORKER_RUNS_PRIVATE_KEY, WORKER_SECRET, WORKER_LIGHTNING_PUBLIC_KEY

Available Agents

Claude Code injects every agent's name and description each session, so the roster is not restated here; the agent files themselves are in .claude/agents/. Command files (create-plan.md, implement-plan.md, research-codebase.md) cross-ref this section rather than repeating it.

One convention that no agent file carries: dispatch web-search-researcher on request, not by default.

Guidelines Reference

These files cite implementation as file:line rather than copying it, so read the source at the citation instead of trusting a transcription.

  • .claude/guidelines/store-structure.md - store responsibilities in the collaborative editor; where new state belongs
  • .claude/guidelines/yex-guidelines.md - Yex (Yjs/Elixir) usage rules
  • .claude/guidelines/testable-supervision-trees.md - naming and wiring OTP processes so tests can address them and still run async: true
  • .claude/guidelines/toast-notifications.md - notification patterns
  • .claude/guidelines/testing-essentials.md - Vitest unit testing, and the entry point for:
    • .claude/guidelines/testing/react-patterns.md - React Testing Library
    • .claude/guidelines/testing/vitest-advanced.md - fixtures and test data
    • .claude/guidelines/testing/collaborative-editor.md - Y.Doc and Phoenix channel mocks
  • .claude/guidelines/e2e-testing.md - Playwright E2E, and the entry point for:
    • .claude/guidelines/e2e/phoenix-liveview.md - driving LiveView pages; the canonical wait patterns
    • .claude/guidelines/e2e/page-objects.md - Page Object Model structure
    • .claude/guidelines/e2e/collaborative-testing.md - multi-user collaborative features

.claude/rules/logging.md (Logger levels, Sentry noise) and .claude/rules/ui-patterns.md (button variants, Tailwind conventions) are not in that list because they are not read on request: each declares a paths: glob and loads by itself when you work on a file it matches.