-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Feature Request: "Citizen Offers" & Mutual Aid Matching Workflow
Title: [Feature] Introduce Offer Model and "Collaboration Matching" for Citizen Proposals
🔍 Summary
Currently, Consul focuses on Democracy as a Demand (Proposals competing for votes to trigger government action). This feature introduces Democracy as Action (Mutual Aid).
We propose adding a new distinct entity called "Offers" (resources, skills, time) and a "Matching Workflow" that allows Citizens to pair existing Proposals (Asks) with Offers. This functions conceptually like a "dating app" for civic action, converting abstract proposals into executed projects through direct collaboration.
🙁 The Problem
- Uni-directional: Proposals currently rely entirely on institutional execution. Users can say "We need a garden," but cannot formally say "I have the timber and seeds to build it."
- Model Bloat: The
Proposalmodel is a "God Object" tied to voting logic, legislative thresholds, and complex state machines. Trying to shoehorn "volunteering" or "resource sharing" into the existingProposalmodel creates technical debt and conflicting logic (e.g., Offers shouldn't need 1% support to be valid). - Missed Potential: Many proposals fail to reach voting thresholds but could be solved immediately by the community if the resources were visible.
💡 Proposed Solution
1. New Core Model: Offer
Create a lightweight model distinct from Proposal.
- Purpose: Represents a resource, skill, or time commitment.
- Behavior: It does not use
acts_as_votable. It uses a "Claim/Match" lifecycle rather than a "Vote/Win" lifecycle. - Shared Traits: Inherits generic Consul modules (
Taggable,Geozonable,Notifiable,Commentable).
2. The "Match" Workflow (The Dating Mechanic)
A new join-model that links a Proposal (The Ask) to an Offer (The Resource).
- Discovery: A UI that suggests Offers to Proposal authors based on Tags and Geolocation.
- Handshake: A request system where a Proposal author can "Request" an Offer, or an Offer author can "Apply" to a Proposal.
- Collaboration: A private/semi-private space for the matched users to coordinate logistics.
🛠 Technical Implementation
A. Database Schema
We need a new offers table and a proposal_matches table.
# 1. The Offer Model (Lean, non-political)
create_table :offers do |t|
t.references :author, index: true
t.string :title
t.text :description
t.integer :geozone_id
t.integer :status, default: 0 # available, pending, claimed
t.timestamps
end
# 2. The Match Model (Stateful Relationship)
create_table :proposal_matches do |t|
t.references :proposal, null: false # The Need
t.references :offer, null: false # The Resource
t.string :status # pending, accepted, rejected, fulfilled
t.datetime :accepted_at
t.datetime :completed_at
t.timestamps
endB. Logic & Relations
- Proposals are conceptually treated as "Asks".
- Offers are "Resources".
- Matching Service: A service object (
MatchmakingService) that queriesActsAsTaggableOnto find overlapping tags between Proposals and Offers within the sameGeozone.
C. UX / UI Changes
- New Top-Level Section: "Collaborate" or "Marketplace" (alongside Debates/Proposals).
- Proposal Show Page:
- If User has relevant Offers: Show "I can help with this" button (links specific Offer).
- If User has no Offers: Show "Offer to help" button (creates new Offer).
- Offer Show Page: List of "Recommended Proposals" (Asks) that match the Offer's tags.
- Dashboard: A "My Matches" tab to manage incoming requests and active collaborations.
👤 User Stories
- As a Citizen (The Asker): I have posted a Proposal for "Clean up the River." I see a notification that a local business has "Offered" trash bags and gloves. I accept the match and we coordinate the date.
- As a Provider (The Offerer): I am a graphic designer. I create an Offer "Free Design Work for Civic Projects." I get 3 requests from different Proposals. I accept one regarding a new park signage and reject the others.
- As an Admin: I want to see which Proposals were "Community Fulfilled" (solved by Offers) vs "Institutionally Fulfilled" (voted on and executed by gov).
✅ Definition of Done
-
Offermodel created (including migration, model, controller). -
ProposalMatchmodel created. - UI for creating/editing Offers implemented.
- "Connect" button implemented on Proposal show page.
- Notification system hooked up to Match status changes (Pending -> Accepted).
- Unit tests for the Match lifecycle.