Files
akkounts/AGENTS.md
raucao 6279699c11
CI / Test (pull_request) Successful in 43s
Switch dev object storage from MinIO to Garage
MinIO no longer publishes prebuilt community images (quay.io returns
401, Docker Hub 404), so the dev setup cannot pull the image.

Use a single-node Garage instance instead, which auto-creates the
remotestorage bucket and a dev-key1 access key on first start, and
point liquor-cabinet at it.
2026-10-06 13:52:38 +00:00

4.5 KiB

AGENTS.md

Akkounts is a Rails 8 monolith for managing Kosmos/LDAP user accounts. It authenticates against an LDAP directory via Devise and integrates with ejabberd, Discourse, Mastodon, remoteStorage, Nostr, LNDHub, and BTCPay.

Development environment

Development runs in Docker Compose — run all commands against the web container. Start services: docker compose up (web, ldap, redis, garage, liquor-cabinet, strfry). The web service runs bin/dev (foreman: Puma + Tailwind CSS watcher) and embeds Solid Queue workers (SOLID_QUEUE_IN_PUMA=true).

First-time LDAP and database setup is automated: the ldap-init service creates the 389ds back-end, then the web entrypoint seeds LDAP and the databases on first start and runs db:prepare on every boot. Manual equivalents: docker compose exec ldap dsconf localhost backend create --suffix="dc=kosmos,dc=org" --be-name="dev" and docker compose run --rm web bin/rails ldap:setup.

Common commands (prefix with docker compose exec web)

  • bin/rspec — run the test suite (CI runs bundle exec rspec)
  • bin/rails db:prepare — create/migrate DB (also db:setup, db:migrate)
  • bin/rails ldap:setup — reset LDAP dir and seed dev entries
  • bin/rails css:build — build Tailwind CSS (auto-watched in dev)
  • bin/rails lndhub:generate_wallets, invitations:generate_for_all_users[N]
  • bin/jobs — Solid Queue CLI

Tests use the test env explicitly: docker compose exec -e RAILS_ENV=test web bin/rspec. There is no enforced linter — a bin/rubocop binstub exists but no .rubocop.yml (rubocop is a transitive gem, not in the Gemfile); CI does not lint.

Stack & conventions

  • Assets/views: ERB + ViewComponent (app/components/), Tailwind built via Bun + importmap (config/importmap.rb); pin JS deps with bin/importmap pin <pkg> --download.
  • Auth: Devise + devise_ldap_authenticatable; authentication_keys = [:cn], custom SSHA512 password builder, admin bind. Admin-only mounts (/jobs MissionControl, /flipper Flipper UI) are gated by authenticate :user, ->(u) { u.is_admin? }.
  • Services: app/services/ uses ApplicationService.call(**args) with namespaced *ManagerService bases (e.g. UserManagerService) and verb-named operations (UserManager::CreateAccount, NostrManager::PublishEvent, BtcpayManager::*).
  • Models: User is central; Setting uses rails-settings-cached with one concern per service in app/models/concerns/settings/. LNDHub models connect to a separate DB (LndhubBase establish_connection :lndhub). LDAP is accessed via LdapService/ LdapManagerService, not ActiveRecord.
  • Jobs: app/jobs/ inherit ApplicationJob < ActiveJob::Base; backend is Solid Queue (config.active_job.queue_adapter = :solid_queue, separate queue DB in prod). config/recurring.yml has no active scheduled jobs. Ignore config/sidekiq.yml — it's stale (sidekiq is not in the Gemfile; the README mention is outdated).
  • Config: env-var driven (.env.example/.env.development/.env.test); SERVICES constant is loaded from config/services.yml in config/initializers/service_details.rb. Custom LDAP schema attributes are applied from schemas/ldap/*.ldif by lib/tasks/ldap.rake.

Testing conventions (spec/)

spec/rails_helper.rb includes FactoryBot, Devise ControllerHelpers (controller specs), Warden Test::Helpers, DatabaseCleaner (transactional fixtures off), ViewComponent TestHelpers + Capybara matchers, and ActiveJob::TestHelper for type: :job.

  • Feature specs (spec/features/, type: :feature): Capybara rack-test driver (no JS). Log in with Warden: login_as user, scope: :user; stub admin with allow(Devise::LDAP::Adapter).to receive(:get_ldap_param).with(user.cn, :admin).and_return(["true"]).
  • Services (spec/services/) are tagged type: :model; exercise #call/service.send(:private) and assert on DB rows / enqueued_jobs.
  • Request/component/mailer/job/model/helper specs in matching spec/ subdirs. Fixtures live in spec/fixtures/; factories in spec/factories/.

Notes & gotchas

  • Generators (config/application.rb): ERB templates, RSpec, no stylesheets, factory_bot with _factory suffix dir spec/factories.
  • gitno/ and extras/strfry/ are scratch/infra (Deno Nostr relay policies) — not app code; ignore.
  • Don't add code comments unless asked (matches repo style); frozen_string_literal is inconsistent.
  • Default dev login: username admin / password admin is admin.