{"id":45886689,"url":"https://github.com/andreas-vester/projectvote","last_synced_at":"2026-06-15T20:00:46.276Z","repository":{"id":322892555,"uuid":"1012690561","full_name":"andreas-vester/ProjectVote","owner":"andreas-vester","description":"ProjectVote is an open-source, containerized application designed to simplify the entire funding application lifecycle. It features secure proposal submission, token-based board   voting, and automated decision processing for various organizations.","archived":false,"fork":false,"pushed_at":"2026-06-11T20:38:00.000Z","size":495,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-11T22:12:49.081Z","etag":null,"topics":["application-management","associations","board-management","decision-making","docker","funding-management","open-source","organizations","voting-application"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andreas-vester.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-02T18:14:53.000Z","updated_at":"2026-06-11T20:38:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/andreas-vester/ProjectVote","commit_stats":null,"previous_names":["andreas-vester/projectvote"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/andreas-vester/ProjectVote","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreas-vester%2FProjectVote","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreas-vester%2FProjectVote/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreas-vester%2FProjectVote/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreas-vester%2FProjectVote/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andreas-vester","download_url":"https://codeload.github.com/andreas-vester/ProjectVote/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreas-vester%2FProjectVote/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34377983,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-15T02:00:07.085Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["application-management","associations","board-management","decision-making","docker","funding-management","open-source","organizations","voting-application"],"created_at":"2026-02-27T16:05:01.616Z","updated_at":"2026-06-15T20:00:46.269Z","avatar_url":"https://github.com/andreas-vester.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ProjectVote\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Build Status](https://github.com/andreas-vester/ProjectVote/actions/workflows/main.yml/badge.svg)](https://github.com/andreas-vester/ProjectVote/actions/workflows/main.yml)\n\nProjectVote is a funding application management system designed to streamline the process of submitting, reviewing, and deciding on project funding requests for associations and organizations.\n\n## Features\n\n-   **Application Submission:** User-friendly form for submitting new funding requests.\n-   **Token-Based Voting:** Secure, unique voting links for board members to review and cast votes.\n-   **Automated Decision Processing:** Automatic status updates and notifications based on board votes.\n-   **Application Archive:** A historical record of all funding applications and their outcomes.\n\n## Application Workflow\n\nHere's a high-level overview of how the application process works in ProjectVote:\n\n```mermaid\ngraph LR\n    A[Applicant] -- Submits Application --\u003e B(Application);\n    B -- Sent to --\u003e C{Board Members};\n    C -- Cast Votes --\u003e D(Voting Process);\n    D -- Decision --\u003e E{Automated Decision Processing};\n    E -- Result --\u003e F(Approved/Rejected);\n    F -- Sends Email to --\u003e H[Applicant];\n    F -- Sends Email to --\u003e I[Board Members];\n    F -- Stored in --\u003e G[Application Archive];\n```\n\n## Localization\n\nThe current user interface (GUI) of ProjectVote is primarily in German. We are keen to make the application accessible to a wider audience by supporting multiple languages.\n\nIf you are interested in contributing to the internationalization of ProjectVote, either by providing language packs or helping to implement a robust multilingual system, please refer to our [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to get involved. Your contributions would be highly valued!\n\n## Screenshots\n\n### Creating a new application\n![New application](/docs/images/readme_new_application.png)\n\n### Applications archive\n![Archive](/docs/images/readme_archive.png)\n\n\n## Automated Decision Processing\n\nThe system automatically determines the application's status as soon as a definitive decision can be reached, even if not all board members have cast their votes. This \"finish early\" mechanism is based on a dynamic majority threshold that adjusts with the number of abstentions.\n\nThe decision logic operates as follows:\n*   **Approval:** An application is approved if the number of 'approve' votes meets or exceeds the dynamic majority threshold. Additionally, an application is approved if the current 'approve' votes are greater than the sum of 'reject' votes and all remaining uncast votes, making rejection mathematically impossible.\n*   **Rejection:** An application is rejected if the number of 'reject' votes meets or exceeds the dynamic majority threshold. It is also rejected if it's impossible for 'approve' votes to reach the dynamic majority threshold, or if the 'reject' votes are greater than or equal to the sum of 'approve' votes and all remaining uncast votes, making approval mathematically impossible.\n*   **Tie-breaking:** In cases where all votes have been cast and there's a tie between 'approve' and 'reject' votes, the application is rejected. If all cast votes are abstentions, the application is also rejected.\n\nOnce a final decision (approved or rejected) is reached, email notifications are automatically sent to the applicant and all board members.\n\n## Getting Started\n\nThe recommended way to run ProjectVote is by using the pre-built Docker images from GitHub Container Registry.\n\n### Prerequisites\n\n- Docker\n- Docker Compose\n\n### Running the Application\n\n1.  **Create a `docker-compose.yml` file** with the following content:\n\n    ```yaml\n    services:\n      backend:\n        image: ghcr.io/andreas-vester/projectvote-backend:latest\n        ports:\n          - \"8008:8008\"\n        volumes:\n          - ./data:/app/data\n        env_file:\n          - .env\n        restart: unless-stopped\n\n      frontend:\n        image: ghcr.io/andreas-vester/projectvote-frontend:latest\n        ports:\n          - \"5173:80\"\n        depends_on:\n          - backend\n        restart: unless-stopped\n    ```\n\n2.  **Create a `.env` file** in the same directory by copying the example below. This file stores sensitive configurations, suchs as board member emails and email server settings.\n\n    \u003e **Note:** You can also download the example file from the [repository](https://github.com/andreas-vester/ProjectVote/blob/main/.env.example).\n\n3.  **Run the application** using Docker Compose:\n\n    ```bash\n    docker compose up -d\n    ```\n\n4.  **Access the application:**\n    - **Frontend:** [http://localhost:5173](http://localhost:5173)\n    - **Backend API:** [http://localhost:8008](http://localhost:8008)\n\nThe application should now be running. Docker Compose will pull the latest images from the GitHub Container Registry.\n\n## For Developers \u0026 Contributing\n\nWe welcome contributions to ProjectVote! If you're interested in fixing bugs, adding new features, or improving the documentation, please see our [CONTRIBUTING.md](CONTRIBUTING.md) file for details.\n\n## Configuration\n\nTo provide a clearer picture of the setup, here are the contents of the main configuration files.\n\n\n### Environment Variables (`.env`)\n\n```env\n# -----------------------------------------------------------------------------\n# Application URLs\n# -----------------------------------------------------------------------------\n# The public base URL of the frontend application.\n# Used for generating links in emails.\nFRONTEND_URL=http://your-production-domain.com\n\n# -----------------------------------------------------------------------------\n# Board Configuration\n# -----------------------------------------------------------------------------\n# Comma-separated list of board member email addresses\nBOARD_MEMBERS=board.member1@example.com,board.member2@example.com\n\n# -----------------------------------------------------------------------------\n# Database Configuration\n# -----------------------------------------------------------------------------\n# Set to False in production to prevent logging every SQL query.\nDB_ECHO=False\n\n# -----------------------------------------------------------------------------\n# Email Configuration (for fastapi-mail)\n# -----------------------------------------------------------------------------\n# Example for a real SMTP server (e.g., SendGrid, Mailgun)\nMAIL_DRIVER=smtp\nMAIL_SERVER=your-smtp-server.com\nMAIL_PORT=587\nMAIL_STARTTLS=True\nMAIL_SSL_TLS=False\nMAIL_USERNAME=your-smtp-username\nMAIL_PASSWORD=your-smtp-password\nMAIL_FROM=noreply@your-production-domain.com\nMAIL_FROM_NAME=\"ProjectVote\"\n```\n\n## Database\n\nThe application uses a SQLite database to store application data.\n\n### Location and Persistence\n\nThe database is stored in the `data` directory at the root of the project. This is achieved using a bind mount in `docker-compose.yml`, which maps the `./data` directory on your host machine to the `/app/data` directory inside the `backend` container.\n\nThis ensures the database file (`applications.db`) is directly accessible on your filesystem and persists across container restarts.\n\n### Accessing the Database\n\nSince the database file is on your host machine at `data/applications.db`, you can open it using any standard SQLite database tool. There is no need to connect to the running container.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreas-vester%2Fprojectvote","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandreas-vester%2Fprojectvote","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreas-vester%2Fprojectvote/lists"}