Rails 8.1 web-based management tool for SOLECTRUS Docker hosts. Removes the need to hand-edit compose.yaml / .env or run docker compose commands.
- Ruby 4.0, SQLite3
- Hotwire (Turbo + Stimulus in TypeScript), Vite, ViewComponent
- Tailwind CSS v4, ERB, daisyUI
- RSpec + Playwright, Bats
See docs/README.md for the full map. Key entry points: docs/product.md, docs/architecture/, docs/guides/development.md, docs/adr/, docs/todos.md.
Fetch on demand:
- daisyUI: https://daisyui.com/llms.txt
- SurveyJS: https://surveyjs.io/form-library/documentation/overview
- SOLECTRUS env var semantics: https://docs.solectrus.de/ — source of truth for
INFLUX_*,FORECAST_*,SENEC_*,MQTT_*,SHELLY_*,POWER_SPLITTER_*,WATCHTOWER_*defaults/ranges. Don't infer from existing HELIOS code; it may be wrong.
For non-trivial UI changes — new flows, complex interactions, anything where rendering or console errors aren't obvious from the diff — verify against the running dev UI at https://helios.localhost using the mcp__chrome-devtools__* tools.
Skip browser verification for trivial changes (typos, simple CSS tweaks, obvious copy edits) — it's slower and costs tokens.
Assume the dev server is already running (started by the user via bin/dev) — do not start it yourself.
After modifying code, always run the matching linter(s) and fix issues:
- Ruby (
.rb):bin/rubocop(use--autocorrect) - ERB (
.html.erb):bin/herb lint+bin/yarn erb:format(orerb:check) - TypeScript (
.ts):bin/yarn tsc+bin/yarn lint - JSON/YAML/Markdown/CSS:
bin/yarn prettier --write
Run bin/brakeman occasionally for security scans (not per-change).
In Claude Code sessions these run automatically at turn end via
.claude/hooks/ — no need to invoke them manually for edited files.
- Controllers: plural names (
SetupsController) - Routes: only the 7 RESTful actions; model custom actions as nested resources (e.g.
Services::StartsController#createinstead ofpost :start)
Use ViewComponents for reusable UI; prefer them over partials. Sidecar layout per component:
app/components/<name>/component.rb
app/components/<name>/component.html.erb
app/components/<name>/component_controller.ts # optional, co-located Stimulus controller
app/components/<name>/component.de.yml # optional, co-located i18n (per locale)
app/components/<name>/component.en.yml
HELIOS ships in German and English — every user-facing string must exist in both locales. Never hardcode UI text. App-wide keys live in config/locales/{de,en}.yml; component-local keys use the ViewComponent sidecar (app/components/<name>/component.{de,en}.yml).
- Bind mounts, not Docker volumes (ADR-0003)
- HELIOS writes only two external files:
compose.yamland.env - All app data lives in
config.yaml(ADR-0009); no Active Record tables - Preserve comments and unknown vars in
.env(comments incompose.yamlare not preserved)
- Ruby/request specs:
bin/rspec spec/<models|requests>/<file>_spec.rb - Frontend specs (Stimulus controllers, TS utils):
bin/yarn test(Vitest, inspec/frontend/) - Shell scripts:
bats --recursive spec/bats/ - Integration specs (
spec/integration/): slow, drive a real stack via Docker. Auto-tagged:integration; run bybin/ci(which setsCI) and on GitHub CI. A barebin/rspecskips them — run them alone withbin/rspec --tag integration. - Use real Docker, no mocking
- Specs run in parallel via
bin/turbo_tests(on CI and inbin/ci);bin/coveragethen collates a single SimpleCov report. A spec writing to a fixed disk path must scope it per process withTEST_ENV_NUMBER(e.g.tmp/stack#{ENV.fetch('TEST_ENV_NUMBER', nil)}), or it will clobber other processes. - Aim for high coverage, but don't chase 100% — write tests proportional to the code's complexity, no tests for trivial wiring. Focus on unit and request specs. The only system spec is
spec/system/smoke_spec.rb(Playwright); usually no need to touch it.