Citizen participation platform for reporting and collaboratively managing urban issues in the Municipality of Turin.
Participium is a civic engagement platform that enables citizens to report urban issues (potholes, architectural barriers, waste, lighting malfunctions, etc.) directly to the Municipality of Turin. Citizens select a location on an interactive map, describe the problem, and attach photos. Municipal offices then validate, assign, and manage these reports through a complete lifecycle, keeping citizens informed at every step via in-app notifications.
- Citizen: Registers, submits reports, tracks report status, and configures notification preferences (in-app and Telegram).
- Administrator: Creates municipality user accounts and assigns roles. Can also manage external companies and external maintainers.
- Public Relations: Reviews incoming reports and approves or rejects them with explanations. Can assign reports to external companies.
- External Maintainer: Works for an external company contracted by the municipality. Can view and manage reports assigned to their company.
Technical Office Roles (receive assigned reports, update statuses, communicate with citizens, and resolve issues):
- Culture Events Tourism Sports
- Local Public Services
- Education Services
- Public Residential Housing
- Information Systems
- Municipal Building Maintenance
- Private Buildings
- Infrastructures
- Greenspaces and Animal Protection
- Waste Management
- Road Maintenance
- Civil Protection
- Water Supply – Drinking Water
- Architectural Barriers
- Sewer System
- Public Lighting
- Waste
- Road Signs and Traffic Lights
- Roads and Urban Furnishings
- Public Green Areas and Playgrounds
- Other
Reports progress through the following statuses:
- Pending Approval: Initial submission awaiting public relations review.
- Assigned: Approved and routed to the competent technical office.
- External Assigned: Assigned to an external company for handling.
- In Progress: Intervention scheduled or work started.
- Suspended: Temporarily halted, awaiting evaluation or resources.
- Resolved: Work completed, with optional closing comments.
- Rejected: Not accepted, with mandatory explanation.
For Docker setup (Recommended):
- Docker Desktop or Docker Engine + Docker Compose
- Git
For local setup:
- Node.js ≥ 18
- PostgreSQL ≥ 14
- MinIO (or S3-compatible storage)
- Git
The fastest way to run Participium is with Docker Compose, which handles all dependencies automatically.
git clone <repo-url>
cd participium
docker compose up --buildThis single command launches:
- PostgreSQL database
- MinIO object storage
- Backend API server
- Frontend development server
- Frontend: http://localhost:3000
- Backend API: http://localhost:4000
- MinIO Console: http://localhost:9001 (credentials in
docker-compose.yml) - Telegram Bot: Automatically started (requires
BOT_TOKENin.env)
Seeded automatically on startup:
| Role | Password | |
|---|---|---|
| Administrator | admin@participium.com | adminpass |
| Citizen | citizen@participium.com | citizenpass |
| Public Relations | pr@participium.com | prpass |
| Public Relations | techPR@participium.com | techpass |
| Municipal Building Maintenance | tech@participium.com | techpass |
| Culture Events Tourism Sports | culture@participium.com | techpass |
| Local Public Services | localpublic@participium.com | techpass |
| Education Services | education@participium.com | techpass |
| Public Residential Housing | residential@participium.com | techpass |
| Information Systems | infosys@participium.com | techpass |
| Private Buildings | privatebuild@participium.com | techpass |
| Greenspaces and Animal Protection | greenspaces@participium.com | techpass |
| Road Maintenance | road@participium.com | techpass |
| Civil Protection | civilprot@participium.com | techpass |
| Infrastructures | infra@participium.com | infrapass |
| Waste Management | waste@participium.com | wastepass |
Participium includes interactive API documentation via Swagger UI.
Access: http://localhost:3000/api-docs
The documentation is generated from docs/swagger.yaml and allows you to:
- Browse all available endpoints
- View request/response schemas
- Test API calls directly from the browser
- Understand authentication requirements
Participium includes a Telegram Bot that allows citizens to interact with the platform directly from Telegram, making it even easier to report issues and receive notifications.
- Link Account: Connect your Telegram account to your Participium citizen account using a secure one-time code
- Create Reports: Submit new reports with photos and location directly from Telegram
- Track Reports: View all your submitted reports and their current status
- Create a Telegram bot using @BotFather
- Get your bot token and username
- Add to
.envfile:
BOT_TOKEN=your_telegram_bot_token
BOT_USERNAME=your_bot_username- Restart services:
docker compose restart
cd client
npm test # Run once
npm run test:watch # Watch modeFrontend unit tests use Vitest + Testing Library for fast, user-centric testing.
cd client
npm install
npm run install:browsers # Install Playwright browsers (first time only)
npm run test:e2e-ui # Run all E2E UI tests
npm run test:e2e-ui:headed # Run with visible browser
npm run test:e2e-ui:debug # Debug mode
npm run test:e2e-ui:ui # Interactive UI mode
npm run test:e2e-ui:report # View HTML reportE2E UI tests use Playwright for automated browser testing, covering complete user workflows.
cd server
npm test # Run once
npm run test:watch # Watch mode
npm run test:coverage # With coverage reportBackend tests use Jest for unit and integration testing of services, controllers, and middleware.
npm run test:e2e # Backend E2E tests
npm run test:e2e-ui # Frontend E2E UI testsParticipium uses environment variables for configuration. When using Docker Compose, create a .env file in the project root:
# Database
POSTGRES_USER=participium
POSTGRES_PASSWORD=participium_password
POSTGRES_DB=participium
POSTGRES_PORT=5432
# MinIO Object Storage
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin
MINIO_PORT=9000
MINIO_CONSOLE_PORT=9001
MINIO_BUCKET_NAME=reports-photos
# Server
SERVER_PORT=4000
SESSION_SECRET=your-secret-key-change-in-production
# Email (SMTP)
SMTP_HOST=mail.gmx.com
SMTP_PORT=587
SMTP_USER=participium.turin@gmx.com
SMTP_PASS=your_smtp_password
SMTP_FROM_NAME=Participium
SMTP_FROM_ADDRESS=participium.turin@gmx.com
# Telegram Bot (optional)
BOT_TOKEN=your_telegram_bot_token
BOT_USERNAME=your_bot_username
# Client
CLIENT_PORT=3000Note: Default values are provided in docker-compose.yml. The .env file is optional but recommended for customization and production deployments.
Stack Overview:
- Frontend: React 18 + TypeScript + Vite + Leaflet/React-Leaflet
- Backend: Node.js + Express + TypeScript + TypeORM
- Database: PostgreSQL 14+
- Storage: MinIO (S3-compatible object storage)
Directory Structure:
participium/
├── client/ # React + Vite frontend
│ ├── src/
│ │ ├── api/ # API abstraction
│ │ ├── components/ # Reusable UI components
│ │ ├── features/ # Domain-specific feature modules
│ │ ├── hooks/ # Custom React hooks
│ │ ├── styles/ # CSS and style modules
│ │ ├── types/ # Frontend type definitions
│ │ ├── validators/ # Form validation logic
│ │ └── main.tsx
│ └── test/ # Frontend tests (Vitest + Playwright)
│
├── server/ # Express + TypeORM backend
│ ├── src/
│ │ ├── config/
│ │ ├── controllers/ # Request handling
│ │ ├── entities/ # TypeORM entity definitions
│ │ ├── interfaces/ # DTOs, type interfaces
│ │ ├── middlewares/ # Validation, uploads, error handling
│ │ ├── repositories/ # Data access layer
│ │ ├── routes/ # Express route definitions
│ │ ├── services/ # Business logic
│ │ └── index.ts # Server entry point
│ ├── seed/
│ │ └── seed.ts # Seed script for test data
│ └── test/ # Backend tests (Jest)
│
├── telegram-bot/ # Telegram bot integration
│ └── src/
│ ├── index.ts # Bot entry point
│ ├── apiClient.ts # Backend API integration
│ └── turinBoundaries.ts
│
├── shared/ # Shared TypeScript types
└── docs/ # API documentation (Swagger, Docker, etc.)
Participium uses Vite as its frontend build tool to provide a much faster and smoother development experience compared to older solutions like Create React App. Vite starts up quickly, updates the app instantly as developers make changes, and produces optimized builds for production. This means developers can work more efficiently, see their changes right away, and spend less time waiting—resulting in a better, more responsive platform for everyone.
Participium uses TypeScript throughout the entire project—on the frontend, backend, and for shared types—to ensure consistency, safety, and easier maintenance. By defining domain types in one place, the platform avoids errors and keeps data structures aligned across all parts of the application. TypeScript checks for mistakes before the code runs, making the platform more reliable and easier to update or expand. It also improves the developer experience, as the code is easier to understand and refactor, and serves as its own documentation.
Participium uses PostgreSQL as its main database because it is a powerful, open-source, and highly reliable relational database system. PostgreSQL is well-suited for applications that require strong data consistency, complex queries, and scalability. Its robust support for transactions and data integrity ensures that all report, user, and messaging data is stored safely and can be efficiently retrieved or updated as the platform grows. PostgreSQL is also widely supported in the developer community, making it a future-proof choice for long-term maintenance and enhancements.
Participium uses TypeORM as its Object-Relational Mapping (ORM) tool to ensure data is managed safely, efficiently, and in a way that supports future growth. TypeORM provides a powerful and flexible way to work with the database through TypeScript decorators and entities, making it easy to define and update the database structure while maintaining full type safety. It supports advanced features like migrations, repositories, and query builders, providing developers with fine-grained control over database operations. TypeORM's mature ecosystem and extensive documentation make it an excellent choice for enterprise-level applications that require reliability and scalability.
Photos are an important part of reporting urban issues, but storing images directly in the main database can make the platform slow and difficult to manage as it grows. To solve this, Participium uses MinIO, a specialized system for storing large files like photos. This approach keeps the platform fast and responsive, because the database only needs to keep track of the links to the images, not the images themselves. It also makes the platform more scalable and cost-effective, since MinIO is designed to handle large amounts of data efficiently. As a result, users can upload and view photos quickly, and the platform can easily grow to support more reports and images in the future.
The interactive map, built with the open-source libraries Leaflet and React-Leaflet, is a key part of the user experience. These libraries were chosen because they are free, widely used, and do not require any API keys or subscriptions, ensuring that the platform is accessible to everyone without hidden costs. The map uses open, community-maintained data and is designed to be fast, intuitive, and highly customizable for urban reporting needs. Even as the number of reports grows, the map remains clear and easy to navigate by automatically grouping nearby reports, so users can quickly explore and understand the distribution of issues across the city.
Participium includes a Telegram bot built with the Telegraf framework to provide citizens with an alternative, mobile-friendly way to interact with the platform. The bot offers a conversational interface that makes reporting urban issues quick and accessible directly from a messaging app that many citizens already use daily. The integration is designed to complement the web interface, not replace it, giving users flexibility in how they engage with the platform. The bot validates all inputs, enforces location boundaries (ensuring reports are within Turin), and provides real-time status updates through Telegram notifications. This multi-channel approach increases accessibility and encourages greater civic participation by meeting citizens where they are.
To contribute, simply open an issue on GitHub to discuss your idea or report a bug. Thank you!
See LICENSE file for details.