← work
system dossier

VellumHub

Recommendation backend shaped around local read models and zero sync ranking.

System Brief

A WebFlux gateway centralizes auth, routing, and Redis-backed rate limits. Domain services own their writes, Kafka carries state to projections, and recommendation-service ranks from local pgvector-backed models.

System Signals
01

Gateway is the single public ingress, with JWT enforcement and Redis rate-limit state.

02

Catalog owns current book-progress; engagement owns feedback and replicated reading history.

03

Recommendation-service consumes Kafka topics, retries failures into DLTs, and ranks over local `book_features` and `user_profiles`.

signal

Gateway controls ingress while Kafka-fed read models keep recommendation queries local.

Query Path0

synchronous service hops after recommendation-service receives the request

Service Topology5

gateway, user, catalog, engagement, and recommendation services

Ranking Core384d

LangChain4j embeddings stored in pgvector-backed book_features and user_profiles

Signal Path
gateway ingressdomain-owned writeskafka + retry dltlocal vector ranking
Architecture Board

Gateway protects the edge, user/catalog/engagement own their domains, Kafka carries state into projections with retry and DLT handling, and recommendation-service ranks from recommendation_db.

01gateway ingress
02domain-owned writes
03kafka + retry dlt
04local vector ranking
constraint

Product writes need immediate owner reads, while recommendation reads must avoid service chains.

result

Gateway controls ingress, owners write their domains, Kafka feeds projections, and recommendation reads from local pgvector state.

Architecture

Gateway handles the public edge, user-service owns identity and preference seeds, catalog-service owns books and current book-progress, and engagement-service owns feedback plus derived history. Kafka pushes book, progress, rating, reaction, and preference events into local projections; recommendation-service keeps book features, user profiles, and assembled recommendation state in recommendation_db, then ranks without synchronous fan-out.

Key Decisions
01

Event-carried projections over request-time fan-out

Request-time fan-out from the recommendation endpoint to catalog and engagement turns one read into a chain of availability requirements. Kafka projections move the coupling to the write side, so recommendation queries read from local state only.

02

Catalog-owned book progress over engagement-owned progress

Keeping book progress in engagement splits the write path from the screen that the user expects to refresh immediately. Catalog now writes and reads book progress canonically, while engagement consumes the same events to build chronological history.

03

Recommendation-service as local vector read model

Pulling ranking candidates from operational schemas ties recommendation latency to foreign table shape and query load. A dedicated read model lets recommendation-service store embeddings, profiles, interacted-book filters, and denormalized response data locally.

04

Gateway as single ingress over direct client-to-service access

Direct client access to every service duplicates authentication, rate limiting, and routing policy across multiple edges. Gateway-service centralizes those concerns and keeps the external surface smaller.