Ground News Austria lets users browse and search clustered news topics, open topic detail pages with related articles and generated summaries, compare coverage across left, center, and right-leaning Austrian publishers, follow links back to original articles, and manage a basic account with profile and history features. The frontend is implemented with Angular and reusable UI components, while the Spring Boot REST API exposes topic, search, authentication, user, and admin pipeline endpoints secured with JWT.
Articles are collected by Python scraper workers using a configurable source registry, stored as raw snapshots in MinIO, and moved through RabbitMQ as versioned pipeline events. Spring services persist data in PostgreSQL with Flyway migrations, use pgvector for semantic article clustering, Redis for repeated embedding/context cache lookups, Stanford CoreNLP for German entity extraction, and optional Ollama/Spring AI integration for topic summaries and contextual notes.
| Area | Technologies |
|---|---|
| Frontend | Angular 20, TypeScript, RxJS, Tailwind CSS, Angular Material/CDK, Cypress |
| Backend | Java 25, Spring Boot 3.5, Spring Security, Spring AMQP, Spring AI, Flyway, MapStruct |
| Data | PostgreSQL 17 with pgvector, Redis, MinIO |
| Messaging | RabbitMQ 4 with management UI and dead-letter queues |
| AI/NLP | Ollama, Spring AI, Stanford CoreNLP German models, embeddings |
| Scraping | Python workers, custom publisher scrapers, configurable source registry |
| Ops | Docker Compose, Kustomize/Kubernetes, Prometheus metrics, Testcontainers |
Copy the example environment file if you want to override defaults:
cp .env.example .envStart the core application:
docker compose up --buildUseful Docker Compose profiles:
| Command | What it starts |
|---|---|
docker compose up --build |
Frontend, backend, PostgreSQL, Redis, RabbitMQ, MinIO |
docker compose --profile pipeline up --build |
Core stack plus scraper worker |
docker compose --profile llm up --build |
Core stack plus Ollama |
docker compose --profile pipeline --profile llm up --build |
Full local pipeline |
Default local endpoints:
| Service | URL |
|---|---|
| Frontend | http://localhost:4200 |
| Backend API | http://localhost:8080 |
| OpenAPI UI | http://localhost:8080/swagger-ui/index.html |
| RabbitMQ Management | http://localhost:15672 |
| MinIO Console | http://localhost:9001 |
Run a smoke check after the stack is up:
./scripts/smoke-local.shStart the shared stack:
docker compose up database redis rabbitmq minio backendThen run the worker locally:
cd news_scraper
uv sync
uv run cli.py workerTrigger a crawl request for a configured source:
uv run cli.py publish-crawl derstandard --max-articles 5Fetch EventRegistry-backed articles into the same pipeline:
EVENTREGISTRY_API_KEY=... uv run cli.py newsapi --max-articles 100 --days-back 30Backend integration tests use Testcontainers and require Docker access.
./scripts/verify-backend.sh
./scripts/verify-frontend.sh
./scripts/verify-scraper.shKustomize manifests live in deployment/k8s.
For a local cluster:
docker compose build backend frontend
kubectl apply -k deployment/k8s/overlays/localThe Kubernetes manifests use development defaults. Replace secrets, image names, hostnames, CORS origins, resource settings, and LLM/runtime configuration before deploying to a hosted environment.