1. Overview
Brasil Participativo is the Brazilian federal government's citizen-participation
platform, built on Decidim 0.32.1 and operated as a multi-tenant
SaaS: a single deployment serves many organizations, each isolated in its own
PostgreSQL schema via the decidim-apartment integration gem
(participa-gem). Authentication is federated through the national
GovBR login via omniauth-govbr.
Every customization ships as a self-contained Decidim engine — one gem per
component, no fork of decidim-core. This document is both the
internal map of that ecosystem and the material we share with the Decidim
developer community, since upstream feature proposals are currently closed on
MetaDecidim. Each feature that looks generalizable is explicitly marked as an
upstream candidate in its own README.
Gemfile (decidim 0.32.1) and per-module compatibility
commits (e.g. chore: upgrade for Decidim 0.32 compatibility).
2. Module inventory
Complete list of custom modules loaded by the host application. Official Decidim space modules (initiatives, conferences, elections) are used at 0.32.1 without modification and are omitted from the detail sections.
| Module | Kind | What it does | Source / branch |
|---|---|---|---|
decidim-govbr | local engine | GovBR identity integration, organization theming, homepage content blocks, participatory-process admin extensions | in-repo |
decidim-chatbot | local engine | Scripted chatbot serving participants on WhatsApp (SERPRO broker) | in-repo |
decidim-apartment | infra gem | Multi-tenancy via schema-per-tenant (Apartment gem integration) | GitLab · v0.1.0-rc |
decidim-participatory_texts | component engine | Participatory texts rebuilt on a Paragraph model | GitLab · main |
decidim-questionnaires | override gem | Project-specific overrides on the decidim-forms engine | GitLab · main |
decidim-bp_proposals | override gem | Per-step comment control on proposals and collaborative drafts | GitLab · main |
decidim-bp_meetings | override gem | Per-step creation, comments and attachments on meetings | GitLab · main |
decidim-bp_comments | override gem | Official replies, 2-level threads, edit window, restricted reports | GitLab · main |
decidim-government_spaces | component engine | Organ/Sector hierarchy scoping participatory-process administration | GitLab · main |
decidim-categories | component engine | Hierarchical categories with soft delete, scoped per participatory space | GitLab · main |
decidim-extra_home_blocks | opt-in enhancement | Settings extensions on core homepage content blocks | GitLab · main |
decidim-extra_blocks | component engine | Layout-based content blocks (CTA, Hero, Fast Proposal, …) | GitLab · main |
decidim-community_templates | fork | Community templates (upstream: decidim-ice), bumped to 0.32 | GitLab · core/bump-32 |
decidim-toggle | third-party | Register organization settings tabs for Decidim modules | octree · main |
decidim-ephemeral_participation | third-party | Participation without registration (graphed from Decidim Barcelona) | octree · main |
omniauth-govbr | auth strategy | OmniAuth strategy for the national GovBR login | GitHub · main |
In-repository engines
local decidim-govbr
Holds everything specific to operating inside the Brazilian government
ecosystem: GovBR user logic, organization color theming
(Decidim::Govbr::Colors), homepage content blocks
(Decidim::Govbr::Homepage::ContentBlocks, including a blog/news
cell), participatory-process admin extensions (form validations, metadata,
automatic step activation with duplication handling), and organization
creation extensions for the system panel.
local decidim-chatbot
"Scripted chatbot that serves participants on messaging apps such as WhatsApp." Ships its own admin engine (brokers, script publishing, editable texts), a YAML-defined conversation flow with a state machine, and a WhatsApp broker backed by SERPRO, the federal government's messaging provider. Detailed in Section 4.
Lappis custom modules (gitlab.com/lappis-unb/decidimbr)
decidim-bp_meetings upstream candidate
- per_step_creation — step-scoped control of participant event creation (generalizable; upstream candidate).
- per_step_comments — step-scoped "citizen can comment" control; deliberately hides the core's vestigial global/step comment settings from the admin form.
- per_step_attachments — step-scoped attachments, including citizen upload on the meeting form, which exists in no core version (ref: decidim/decidim#5726).
Documented breaking change: creation_enabled_for_participants
semantics move from global to step-scoped, with per-step default
false — admins must re-enable creation per step.
decidim-bp_proposals
- per_step_comments — step-scoped comment gating applied to both
ProposalandCollaborativeDraft, with defaulttrueso existing organizations see no behavior change.
Step-scoped proposal creation itself is not reimplemented here — the
core manifest already provides :step.creation_enabled on 0.32.
decidim-bp_comments
- Official replies — citizens comment at the base level; only administrative profiles reply. Two-level tree; admin replies are badged "Resposta Oficial".
- Edit window + moderation — regular authors edit/delete their own comment for 5 minutes; global admins delete anything; report button restricted to admin/moderator.
Wiring: config.to_prepare prepends on Permissions, CommentForm, CommentCell and DeleteComment.
decidim-government_spaces
Scopes participatory-process administration to a two-level government
hierarchy — Organ → Sector. Organization admins build the
hierarchy and invite scoped admins; a scoped admin manages only processes
reachable through their memberships and can do everything a native process
admin can except delete. Scoped admins are never admin: true,
and access is computed live from memberships, so revoking a membership
instantly revokes access.
decidim-categories
- Own data model (
decidim_categories_categories) with infinite hierarchy viaparent_id, scoped per participatory space. - Soft delete ("trash") via
deleted_at— historical relationships survive deletion. - Business rules injected into Proposals and Meetings forms/commands: category selection is mandatory, only leaf nodes selectable, sibling subcategories mutually exclusive.
- UI injection via Deface; backend injection via concerns +
prependon form objects and commands.
decidim-questionnaires
Applies concern-based overrides (commands, controllers, forms, helpers,
models) inside Decidim::Questionnaires::Engine#to_prepare, plus
Deface view overrides and view-path mirroring to win the ActionView lookup.
Explicitly tracks the 0.32 renames (Answer → Response,
add_documents → …). This is the established pattern any new
form module would follow (see Section 6).
decidim-participatory_texts
A from-scratch engine for participatory texts, introducing a Paragraph model as its base structure. Recent work covers visible links and safe deletion, and comment-export fixes. Detailed in Section 5.
decidim-extra_home_blocks
Instead of re-registering (which the core registry forbids), the module
mutates the already-registered manifest in an after:
initializer: swaps the cell for a subclass, adds a settings form cell and
new settings, keeping the core's default behavior. Cells inherit core views
so upstream markup changes keep applying. Example feature: the process
"extra data" block gains a timeline_display setting rendering
an inline, expanded step timeline in place of the core's modal button.
decidim-extra_blocks
Admins pick a layout from a gallery (CTA, Hero, Fast Proposal, …), freeze it on the block, then edit layout-specific settings; participants see a cached, mobile-first section.
Forks and third-party modules
fork decidim-community_templates
Decidim-ICE's community-templates module, bumped to Decidim 0.32 so the platform can import participatory-process templates.
third-party decidim-toggle & decidim-ephemeral_participation
decidim-toggle — registers organization settings tabs for Decidim modules (one form, one command, one read API per gem), giving the chatbot and other modules a standard settings surface. decidim-ephemeral_participation — lets citizens participate without registration, graphed from Decidim Barcelona; provisional by design until the equivalent lands in core.
infra decidim-apartment (participa-gem)
Integration of the Apartment gem (ros-apartment 3.4) for Decidim: one PostgreSQL schema per organization/tenant, with default configurations for distributed Decidim deployments. This is what turns the single deployment into a SaaS.
3. Customization approach
Four patterns recur across the ecosystem — all aimed at staying mergeable with upstream:
-
One engine per component, one file per feature. Each
customization gem targets a single core component (meetings, proposals,
comments). Inside it, every feature lives in
lib/decidim/bp_*/features/<feature>.rbwith a header explaining the reason and linking the originating requirement — so an upstream port is a copy-paste plus a PR description. -
prepend+config.to_prepare, never fork. Behavior changes ride on concerns prepended onto core classes at boot (permissions, forms, commands, cells). No core file is edited; upgrades re-apply cleanly. - Deface and view-path mirroring for markup. Small UI injections use Deface overrides; wholesale view replacements mirror the Decidim path so ActionView lookup resolves the engine's copy.
-
Manifest mutation over re-registration. For content blocks,
the already-registered core manifest is mutated in an
after:initializer (the registry raises on duplicate names), subclassing the cell so upstream view inheritance is preserved.
per_step_creation) or deliberately Brazil-specific (hiding the
core's vestigial settings from the admin form). This makes the docset usable
as a proposal backlog now that MetaDecidim's feature-suggestion channel is
closed.
4. Deep dive — multi-channel participation (WhatsApp)
Participation over WhatsApp is implemented by the decidim-chatbot
engine, in this repository. The module's own summary: "Scripted chatbot
that serves participants on messaging apps such as WhatsApp." It depends
on decidim-admin, decidim-core and
decidim-proposals at the host Decidim version.
4.1 Architecture
- Broker layer — pluggable messaging providers under
lib/decidim/chatbot/brokers/. The production broker isSerproWhatsapp, targeting SERPRO's WhatsApp API, the federal government's sanctioned messaging channel. Admin UI includes broker toggles, settings and broker tests. - Conversation layer — a fixed script transcribed from the product team's "Textos BP Genérico" document (
config/flows/general_script.yml). The script is a YAML state machine: states carry steps, fallbacks,if_empty/requires_votetransitions, and escalation notices (reminder on the second consecutive miss, silence from the third; media handled separately). Admins edit only message variables; structural changes go through code review, deploy, andbin/rails chatbot:validate, which checks structure and WhatsApp message limits. - Runtime — inbound messages are processed asynchronously (
ProcessInboxJobon Sidekiq), rendered through a template/renderer pair, and answered through the broker. A terminal simulator and printer support development and script review without a phone. - Identity — when the conversation needs an authenticated action, the bot issues a one-time identification page link (
IdentifyController), valid for 1 hour, one send per issue; GovBR login completes on the site. - Multi-tenancy — tenant-aware (
lib/decidim/chatbot/tenant.rb), so each organization in the SaaS runs its own script instance and broker configuration.
4.2 Participation features
- Voting by chat — participants pick a proposal by name; the saved vote is a first-class state variable (
vote,ranking) shared between site and chat. - Live ranking — the bot can report the top-3 across site and chat votes.
- Directed to the site — when an action requires the web app, the script routes the citizen to
site_urlor the identification flow. - Phone lock — per-phone constraints prevent duplicate/abuse flows.
5. Deep dive — participatory texts
decidim-participatory_texts is a from-scratch engine for
participatory texts rather than an override of the core component. Its
foundational commit introduces the gem structure and a
Paragraph model as the document's base unit; the
main branch carries an explicit chore: upgrade for Decidim
0.32 compatibility commit, anchoring the module to the 0.32.x line.
- Paragraph-centric model — documents decompose into paragraphs, the granularity at which citizens comment and interact.
- Visible links and safe deletion — the most recent feature work (visible links; safe paragraph deletion).
- Comment export fixes — export includes corrected for comments.
The module complements the chatbot flow: long-form normative documents are the content type most often pushed to WhatsApp audiences, and paragraph-level granularity is what makes chat-based voting and ranking (Section 4) workable for real consultations.
6. Roadmap — new form module
The pattern is already proven in-repo by decidim-questionnaires:
- Live on top of the core forms engine (
decidim-forms) rather than forking it — no new component manifest unless the product needs one. - Wire behavior via concerns included in
Engine#to_prepare; keep view changes in Deface overrides or mirrored view paths. - Track core renames per Decidim version (0.32 renamed
Answer→Responseacross the questionnaire surface). - Document each feature with its originating requirement and upstream candidacy, so the module can double as a proposal backlog.
7. References
- gitlab.com/lappis-unb/decidimbr/components-brasil-participativo/decidim-participatory_text
- …/decidim-module-questionnaires
- …/decidim-bp_proposals
- …/decidim-bp_meetings
- …/decidim-bp_comments
- …/decidim-government-spaces
- …/decidim-categories
- …/decidim-extra_home_blocks
- …/decidim-extra-blocks
- …/decidim-bp_templates
- gitlab.com/lappis-unb/decidimbr/infra/participa-gem
- git.octree.ch/decidim/vocacity/decidim-modules/decidim-toggle
- git.octree.ch/decidim/vocacity/decidim-modules/decidim-ephemeral_participation
- github.com/decidim-ice/decidim-module-community_templates (upstream of the community_templates fork)
- decidim/decidim#5726 — upstream issue explaining why citizen attachment upload on meetings is not in core
- MetaDecidim bug-report proposal example — the publication format this document complements