Files
akkounts/AGENTS.md
T
raucao 6cc35f07eb Remove more obsolete Devise code
The initializer was a no-op override after our Devise upgrade
2026-08-10 17:01:36 -06:00

4.3 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, minio, 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 setup (after creating the 389ds backend once): docker compose exec ldap dsconf localhost backend create --suffix="dc=kosmos,dc=org" --be_name="dev" then docker compose run 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.