A Symfony application for registering and browsing municipal initiatives and their contacts. It is a rebuild of the previous Drupal-based project database, focused on a friendlier interface for creating and getting an overview of initiatives.
The project follows the itk-dev
symfony Docker template and
runs on PHP 8.4 / Symfony 8.
- Dashboard with key figures and a status overview of all initiatives.
- List of initiatives with full-text search, faceted filters, column sorting, pagination and CSV export.
- Create and edit initiatives, including inline creation of contacts, free-tagging of tags, stakeholders and strategies, and image/file uploads.
- Contact management.
- Private file/image uploads, served only to signed-in users.
- Local username/password login with user administration for administrators.
- Bilingual interface (Danish and English).
- Docker and the itk-dev
itkdev-docker-composesetup. - Task (optional, but the commands below use it).
Start the containers and install everything (dependencies, database schema and development fixtures):
task installWithout Task:
docker compose up --detach
docker compose exec phpfpm composer install
docker compose exec phpfpm bin/console doctrine:migrations:migrate --no-interaction
docker compose exec phpfpm bin/console doctrine:fixtures:load --no-interactionThe site is served on the domain configured in .env
(COMPOSE_DOMAIN, e.g. https://itk-project-database.local.itkdev.dk).
The development fixtures create two users (password password for both):
admin@example.com— administratoreditor@example.com— editor
Create an administrator manually with:
task create-admin -- you@example.com "Your Name"The application uses a single, flat trust model: authentication is required for
everything (the firewall protects ^/), and every authenticated user is fully
trusted. Any signed-in user (ROLE_USER) can create, view, edit and delete any
initiative or contact, and can download any uploaded image or attachment by id.
The only elevated capability is user administration (/admin/**), which
requires ROLE_ADMIN.
This is intentional: the project database is an internal tool for a small,
trusted group of municipal editors, so per-record ownership or per-action
authorization would add complexity without a real security benefit. Uploaded
files are stored outside the web root and served only through the authenticated
MediaController, so they are never anonymously reachable — but they are not
restricted between authenticated users.
If a future requirement calls for restricting who may edit/delete a given record (or read a given file), introduce a Symfony Voter rather than loosening or working around the flat model.
task # list all tasks
task console -- <command> # run a Symfony console command
task coding-standards:fix # apply coding standards
task static-analysis # run PHPStan
task test # run the test suite
task ci # run everything CI runsThe controlled vocabularies (status, category, type, organisational anchoring,
endorsement author and funding) are modelled as PHP enums in src/Enum/ with
placeholder values. Adjust the enum cases and their translations
(translations/messages.*.yaml) to match the real domain values.