Phased scaffold for the news-platform project. This workspace contains initial infrastructure and three minimal Spring Boot service skeletons to start development incrementally.
Quick start
- Start infra services:
cd infrastructure
docker compose up -d
docker ps- Build a service and run locally with Maven:
cd news-fetcher-service
mvn spring-boot:runFiles added
infrastructure/docker-compose.ymlcommon-protos/prompt.protonews-fetcher-service/(skeleton)ai-refiner-service/(skeleton)notification-service/(skeleton)
Next steps: wire Kafka topics, implement fetcher logic (RSS), add AI integration in ai-refiner-service, add notification sinks.
LLM configuration & test
- Set an API key for the LLM provider (OpenAI-compatible) via environment variable
OPENAI_API_KEYor Spring propertyllm.api.keyinai-refiner-service/src/main/resources/application.yml. - Example run (requires infra from
infrastructure/docker-compose.yml):
# start infra (Kafka, Postgres, Redis)
cd infrastructure
docker compose up -d
# run services (example)
cd news-fetcher-service && mvn spring-boot:run
cd ../ai-refiner-service && mvn spring-boot:run
cd ../notification-service && mvn spring-boot:run- Quick manual refine test (POST to the test endpoint):
curl -X POST http://localhost:8082/api/refine/test \
-H "Content-Type: application/json" \
-d '{"title":"Test news","content":"This is a short news content to refine.","source":"unit-test"}'If an API key is not configured the refiner will fall back to a minimal summary using the raw content. Check the ai-refiner-service logs for warnings about missing API key or LLM errors.
OpenRouter (Java / Spring Boot)
-
OpenRouter is OpenAI-compatible; you can use it by pointing the refiner to the OpenRouter endpoint or providing an OpenRouter API key in env.
-
Recommended env vars / properties:
OPENROUTER_API_KEY— preferred environment variable for OpenRouter key.OPENROUTER_API_URL— optional custom base URL (defaults tohttps://openrouter.ai/api/v1/chat/completionswhen set).- Alternatively set Spring properties in
ai-refiner-service/src/main/resources/application.yml:
llm:
api:
url: ${LLM_API_URL:https://openrouter.ai/api/v1/chat/completions}
key: ${OPENROUTER_API_KEY:}
model: ${LLM_MODEL:google/gemini-2.5-flash}-
The
LlmClientinai-refiner-servicewill preferllm.api.key, thenOPENROUTER_API_KEY, thenOPENAI_API_KEY. -
Example PowerShell to run the refiner with OpenRouter (replace the placeholder with your real key — do not commit it):
$env:OPENROUTER_API_KEY = 'sk-REPLACE_WITH_YOUR_KEY'
cd ai-refiner-service
mvn spring-boot:run- Or set
OPENROUTER_API_URLif you need a different base URL.
Security note: Never commit API keys into source control. Use env vars, secret managers, or container secrets.
Feeds & end-to-end testing
-
Where the fetcher gets news: the
news-fetcher-servicereads RSS feed URLs fromnews-fetcher-service/src/main/resources/application.ymlunder thefeeds.urlsproperty. By default this workspace contains:Add more comma-separated feed URLs to that property to ingest additional sources.
-
How the fetcher runs: the fetcher polls feeds periodically using the
fetcher.pollIntervalMsand concurrency settings in the sameapplication.yml. It persists raw items and publishes them to Kafka topicnews.rawfor downstream processing. -
Full end-to-end test (recommended, requires Docker/Kafka):
- Start infra (Kafka, Postgres, Redis):
cd infrastructure docker compose up -d- Start services (fetcher, refiner, notification):
# in separate shells or use a process manager cd news-fetcher-service && mvn spring-boot:run cd ../ai-refiner-service && mvn spring-boot:run cd ../notification-service && mvn spring-boot:run
- Verify the fetcher publishes to Kafka: watch
news-fetcher-servicelogs for publish messages or use Kafka console consumer:
kafka-console-consumer --bootstrap-server localhost:9092 --topic news.raw --from-beginning
-
Verify
ai-refiner-serviceconsumesnews.rawand savesRefinedNewsrows; it will publish to topicnews.refined. -
Verify
notification-serviceprocessesnews.refinedmessages and delivers notifications (check logs or the configured Telegram sink).
-
Quick local test without Docker (what I used here):
- Run
ai-refiner-servicewith an in-memory H2 DB andOPENROUTER_API_KEYset as an environment variable, then call the test endpoint:
$env:OPENROUTER_API_KEY = 'sk-REPLACE_WITH_YOUR_KEY' $env:SPRING_DATASOURCE_URL = 'jdbc:h2:mem:newsdb;DB_CLOSE_DELAY=-1' cd ai-refiner-service mvn spring-boot:run curl -X POST http://localhost:8082/api/refine/test \ -H "Content-Type: application/json" \ -d '{"title":"Test news","content":"This is a short news content to refine.","source":"unit-test"}'
- Run
If you want, I can create a safe application-local.yml template (without secrets) and add it to .gitignore so you can drop keys locally without committing them.