# ConsulDemocracy — Cloudron Package

[ConsulDemocracy](https://github.com/consuldemocracy/consuldemocracy) — the
open-source citizen participation platform behind Madrid's Consul:
proposals with supports, participatory budgeting, debates, polls,
collaborative legislation, community voting. Rails 8 + PostgreSQL +
delayed_job; packaged **build-from-source** on `ruby:3.4.10-trixie`
(trimmed from upstream's dev Dockerfile — no Chromium, no sudo, fixed
non-root user, uid 1000).

## Authentication (auth gate: ✅ OIDC preferred)

Generic OpenID Connect is implemented in code via
`omniauth_openid_connect` (devise.rb:289-296, `name: :oidc`,
`discovery: true`), configured through `config/secrets.yml`
(`oidc_client_id` / `oidc_client_secret` / `oidc_issuer`). `start.sh`
regenerates secrets.yml on every boot with the Cloudron platform
provider values (`CLOUDRON_OIDC_*`).

- SSO redirect: `https://<app-domain>/users/auth/oidc/callback`
- The SSO button (`feature.oidc_login`, default off upstream) is
  auto-enabled on FIRST boot when the platform provider is present —
  after that it's yours to toggle in Admin → Settings → Features.
- Local login stays available alongside SSO.
- SAML is also supported (saml_* keys in secrets.yml) if an external
  IdP is preferred.

**First boot creates a local admin: `admin@consul.dev` / `12345678` —
log in and change that password immediately** (also update the account
email; it is the recovery path if OIDC is ever unavailable).

## Runtime layout

| Concern | How |
|---------|-----|
| Database | Cloudron `postgresql` addon; `db:create db:migrate db:seed` on first boot (marker `.db_seeded` in /app/data), `db:migrate` on later boots |
| Config | `config/database.yml` + `config/secrets.yml` are symlinks to generated files in `/app/data` — rewritten every boot (addon passwords rotate on restore/migration) |
| secret_key_base | Generated once (64 hex chars), persisted in `/app/data` |
| Background jobs | delayed_job worker backgrounded by start.sh, gated on the web port (starts only after migrations) |
| Cache | memcached inside the container (production `cache_store` is `mem_cache_store`/dalli, matching upstream's image) |
| Multitenancy | Off (`multitenancy: false`); single-tenant is the sane Cloudron default |
| force_ssl | Off at the app — Cloudron's proxy terminates TLS |

## Notes

- First boot takes several minutes (schema + seeds). The marker file
  makes subsequent boots fast.
- The seeds include default participation settings and the local admin;
  everything else (settings, tags, banners) is configured in the admin
  UI after login.
- Package pattern + verification details: repo `JOURNAL.md`, the
  ConsulDemocracy section.
