CivicFlow is a municipal request-triage platform. Citizens submit issues such as broken streetlights, potholes, waste, or water leaks. A Java API stores each request, while a Python service assigns its category and priority.
flowchart LR
U["Citizen or API client"] --> A["Java Spring Boot API"]
A --> C["Python FastAPI classifier"]
A --> P[("PostgreSQL")]
- A client sends a request to the Java API.
- Java calls the Python classifier.
- Python returns a category and priority.
- Java stores the completed request in PostgreSQL.
| Area | Technology |
|---|---|
| Main API | Java 21, Spring Boot, Spring Data JPA |
| Classifier | Python 3.12, FastAPI, Pydantic |
| Database | PostgreSQL 16 |
| Local testing | H2 |
| Containers | Docker, Docker Compose |
| Orchestration | Kubernetes |
| Testing | Maven, JUnit, pytest |
| Automation | GitHub Actions |
| Version control | Git |
docker compose up --build -d
docker compose psCreate a request:
Invoke-RestMethod `
-Method Post `
-Uri "http://localhost:8080/api/requests" `
-ContentType "application/json" `
-Body (@{
description = "A dangerous pothole is blocking the road"
location = "Dortmund city centre"
} | ConvertTo-Json)Stop the platform:
docker compose down| Service | Method | Endpoint | Purpose |
|---|---|---|---|
| Java | POST | /api/requests |
Create and classify a request |
| Java | GET | /api/requests |
List all requests |
| Java | GET | /api/requests/{id} |
Find one request |
| Java | GET | /actuator/health |
API health |
| Python | POST | /classify |
Classify text |
| Python | GET | /health |
Classifier health |
| Python | GET | /docs |
Interactive API documentation |
The classifier is deliberately rule-based and explainable. It can later be replaced by a machine-learning model without changing the Java API’s responsibility.
Java:
cd api-java
.\mvnw.cmd testPython:
cd classifier-python
.\.venv\Scripts\python.exe -m pytestBuild the images and deploy them to Docker Desktop’s local Kubernetes cluster:
docker compose build
kubectl apply -f .\k8s
kubectl rollout status deployment/api -n civicflow --timeout=5m
kubectl get pods -n civicflowAccess the Java API:
kubectl port-forward service/api 8081:8080 -n civicflowThe API is then available at http://localhost:8081.
The password in k8s/00-platform.yml is only a local demonstration value. A real environment should inject credentials through a managed secret store.
The GitHub Actions workflow automatically:
- Runs the Python tests.
- Runs the Java tests.
- Builds both Docker images after the tests pass.
- Java owns request validation, persistence, and the public REST API.
- Python owns the classification logic and can evolve independently.
- PostgreSQL provides persistent storage.
- H2 keeps Java tests fast and independent.
- Docker Compose health checks control service startup.
- Kubernetes probes and resource limits improve reliability.
- Add authentication and role-based access.
- Manage database changes with Flyway.
- Add Java OpenAPI documentation.
- Add Prometheus and Grafana monitoring.
- Replace the rules with a trained classification model.
- Publish versioned images to a container registry.