App Server of the DevCoop App.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CSDUMMI c37897f20e Group.tasks implemented with filter_tasks 7 months ago
.reuse Licensing information added to every file not in .gitignore 7 months ago
LICENSES mutation resolver for set_payment_info 7 months ago
graphql Mutations for membership have resolvers now 7 months ago
src Group.tasks implemented with filter_tasks 7 months ago
.env Licensing information added to every file not in .gitignore 7 months ago
.gitignore Licensing information added to every file not in .gitignore 7 months ago
.pre-commit-config.yaml Licensing information added to every file not in .gitignore 7 months ago Description of the different franchises 7 months ago
requirements.txt Licensing information added to every file not in .gitignore 7 months ago

FreeCoop - Free, fully online, digital Cooperatives

This Web App provides a forum for organizing digital cooperatives.


This web app provides a platform to organize groups. These groups can receive income for worker members do, they can distribute the income between their members or finance their own undertakings.

The groups elect a treasurer and several moderators to manage their finances and represent the group respectively.

What is a worker coop?

A worker coop, cooperative (dt. Genossenschaft) is a company owned and controlled by the people working in it and benefiting them.

FreeCoop provides a tool to organize these worker coops. Every FreeCoop group is controlled by it's members, who also receive payments for their work in the group from the group treasurer and can vote on accepting new members or removing old members upon the recommendation of their moderators.

Both the treasurer and moderators are elected by the members themselves. They can be reappointed at any point or impeached by a vote of the members.

The member's payment split into two parts:

  1. Bonus-like rewards for their own work as percentage of the income received for that work.
  2. A monthly payment.

The size of both of these, the bonus-like rewards and the monthly payments, are determined in annual votes by the members and the treasurer is responsible for paying the members according to these rules.

While FreeCoop does not provide payment methods itself, it calculates the payments a user ought to have received for them to verify against.


Voting happens in two stages:

  1. Proposal - any member can make a proposal to be put to a vote
  2. Voting - all members use alternative vote or instant run-off voting to select one of the proposal.

Votes in a group can happen because:

  1. A trial member needs to be accepted into the group
  2. A member wants to become or replace a moderator.
  3. A member wants to replace the treasurer.
  4. A member wants to impeach the treasurer. (Remove their authority, without appointing another member).
  5. The budget of the group (the payments to the group members) has to be decided upon.
  6. The moderators want to remove a member.
  7. A generic decision has to be made.

Except for reason 7, all of these cases have a direct effect in FreeCoop, like removing or appointing a moderator or treasurer, adding or removing a member. When a generic decision is proposed, the members just vote on several options for a text to be decided upon - without any direct impact on the group on FreeCoop.


Enfranchisment is split into a proposal and voting enfranchisment. The proposal franchise is any member / user able to propose and thus initiate a vote. The voting franchise is any member / user able to vote on proposals made for a vote.

Proposal Franchise

  1. A trial member or permanent member can propose the vote to accept them into the group.
  2. The Moderators can together propose a vote to remove a member from the group. But only after they themselves held an internal vote on the matter.
  3. For any other vote, all permanent members and all group appointees can initiate and propose any other vote.

Voting Franchise

Some of these votes have different franchises (people allowed to vote in them) than others:

  1. For candidacy, impeachment and any other appointment votes, the permanent members and appointees are the franchise.
  2. For budget votes, all permanent, trial and appointees are the franchise
  3. For the first vote to remove a member, the moderators only are the franchise.
  4. For any vote to accept a member and for the second removal vote all permanent members and appointees are the franchise.

Removing a member requires two votes:

  1. A vote among the moderators
  2. A vote among all permanent members and moderators and the treasurer (appointees).

The second vote only happens if the first vote was successful and the first vote by the moderators should prevent premature discussion of the removal member within the general membership.

Treasurer (dt. Schatzmeister)

The Treasurer is responsible for executing any payment the group is due to pay to either members or non-members and for ensuring any payment's the group is due to receive are indeed received.

There is only one Treasurer per group, because in matters of finance the group cannot make contradictory decisions or be unclear about responsibility. But because of the power that the Treasurer role brings with it, the Treasurer is elected by the members until they decide to replace them or impeach them.

In case of an impeachment, the Treasurer should be bared from accessing the finances of the group or receiving payments on behalf of the group. Until the group replaces them, no payments can be received by the group.

Moderators (dt. Vorstand)

The moderators (plural) are responsible for inviting new members into the group, who'll be trial members working for the group for the same compensation as any members but without voting rights until the members vote them into the group.

They are also responsible removing members by first voting amongst themselves to remove them and then initiating a vote among members of the group. This is to prevents members from having to vote on the continued membership of other members unless their elected moderators have not already discussed the matter and reached a decision. Otherwise members could threaten each other with removal and the stress of a removal vote could be used as a tool for coercion against less popular members.

Moderators are elected by declaring their candidacy either against another moderator or against no one.

After this declaration any other member may declare their candidacy for the same election within the proposal phase. If any of the candidates wins an absolute majority of votes in instant run-off voting, they replace the current moderator or a new moderator position is created.

For any moderator election the option "No winner" is always on the ballot. If it receives an absolute majority, the moderator position is either abolished or never established in the first place.

Through this process the number of moderators can grow and shrink in accordance with the needs of the members. The election of the treasurer is run similar to that of a moderator, except that the "No winner" option is not available - since a treasurer has to be determined for the group to remain operational.


FreeCoop offers the feature of receivng tasks from customers. These tasks can be anything. And upon receiving a task, a group member or members evaluate the proposed task and accept or decline the task after potential negotiations with the customer.

When a task is accepted, group members may assign themselves to the task as workers, complete the task and receive a reward as a percentage of the task's payment. When a task is completed both the workers and evaluators receive a percentage of the task's payment that is determined in the group's budget with the remainder going towards the group and paying the member's monthly fees and financing it's other undertakings.

This way tasks may develop into an easy way for a new group to finance itself without being provided with a lot of capital.

Installation (with Docker)

$ git clone
$ cd app-server
$ docker-compose up --build -d



Helping the development of this project is very much welcome.


The server is written using Flask in Python. The database is ORM is peewee and the underlying database is PostgreSQL in production and SQLite when testing.

The server provides a GraphQL API at /api/graphql. The schema files for this API are located in the graphql/ directory and the ariadne resolvers are located in the src/schema folder.

Directory structure

The src file contains all the Python code.

  • src/ contains the definition of the Flask object app with the /api/graphql route.
  • src/db/ contains the definiton of the database using peewee. This is also the file where access tokens, passwords and access controls are centrally implemented.
  • src/schema is the package containing all the GraphQL resolvers grouped according to the Objects (i.e. src/schema/ are the resolvers of the Query type, is for the Mutation type, etc.).
  • src/ is the file containing all custom exceptions that this project defines.


FreeCoop handles some very sensitive information, such as payment and transaction info, that must be kept private.

To ensure this, any access control is located in src/db/ as can_ functions on the User class and the generation and validation of access tokens is done as part of the AccessToken class.

Authors and acknowledgment

Show your appreciation to those who have contributed to the project.


This project is licensed under the AGPL v3 or later.

Project status