- PLpgSQL 99.5%
- Java 0.3%
- TypeScript 0.2%
|
All checks were successful
Build and Deploy / build (push) Successful in 1m8s
|
||
|---|---|---|
| .forgejo/workflows | ||
| backend | ||
| data | ||
| docs | ||
| frontend | ||
| infra | ||
| sample-data | ||
| .gitignore | ||
| FILELIST.txt | ||
| pom.xml | ||
| README.md | ||
Council Monitor
Starter web application for structured publication and analysis of approved municipal council meeting minutes.
Stack
- PostgreSQL
- Java 21
- Jakarta EE 10
- TomEE 10
- JAX-RS REST APIs
- JPA / OpenJPA
- Lombok
- MapStruct
- Angular 22 (standalone components)
Project structure
backend/Jakarta EE WARfrontend/Angular frontendinfra/local PostgreSQL environmentsample-data/example import formatdocs/data model and API documentation
Quick start
1. Start PostgreSQL
cd infra
docker compose up -d
Default values:
- Host:
localhost - Port:
5432 - Database:
council_monitor - User:
council_monitor - Password:
council_monitor
2. Build backend
cd backend
mvn clean package
The WAR is created as backend/target/council-monitor.war and can be deployed to TomEE 10.
The JNDI datasource is jdbc/CouncilMonitorDS. An example TomEE configuration is available in backend/tomee.xml.example.
3. Start frontend
Angular 22 requires Node.js ^22.22.3, ^24.15.0 or >=26.0.0.
cd frontend
npm install
npm start
By default, the frontend expects the API under /api and uses a development proxy to http://localhost:8080/council-monitor/api.
Data model
Core structure:
Meeting -> AgendaItem -> Motion -> PersonVote
Additional entities:
PersonPartyMandateSpeechSourceDocument
Every individual vote stores a sourceType so the origin of the reconstructed vote remains transparent:
EXPLICIT– person explicitly named in the minutesFRACTION_DERIVED– derived from a documented party-group voteUNANIMOUS_DERIVED– derived from unanimity plus documented attendanceMANUAL_CONFIRMED– manually verified
Import workflow
Recommended flow:
- approved meeting minutes as OCR/text
- extraction into the JSON format in
sample-data/meeting-import.example.json - manual plausibility check
- import through
POST /api/import/meetings - presentation in the Angular frontend
Agenda item search
The application provides a separate research page under /topics. It searches agenda-item titles using case-insensitive contains matching and supports council-period filters for 2015-2021, 2021-2027, or all. Each result links directly to the corresponding agenda item in the meeting's voting monitor.
Notes
This repository is intentionally structured as a solid starter. Authentication, role management, automated OCR/LLM import, full-text search, and additional analytics can be added later.