The Mallnline Algorithm is the driving force behind personalized discovery across the platform. Instead of a chronological feed or static storefront index, the algorithm curates products, services, and content based on a combination of global trending signals and personalized social graph connections.
This engine powers the Lobby discovery tab, intelligent auto-complete, and contextual item ranking across all vertical Malets.
Architecture Overview
The system bridges three primary services to deliver a low-latency, personalized experience:
intelligence(Rust): The offline computation engine that aggregates signals (Murchases, views, Wishlist adds) into a unifiedtrendingScore.nodes(NestJS): The social graph provider, maintaining the unidirectional Follow relationships between Visitors and Malets.search(NestJS / Meilisearch): The real-time indexing and retrieval engine that applies custom ranking rules and executesforYouFeedqueries.
Signal Computation
The intelligence Rust service runs a scheduled background batch job to calculate a deterministic trendingScore for all indexable items.
By default, this job runs on a 4-hour cycle. The frequency is fully configurable per-environment via the TRENDING_CRON_SCHEDULE environment variable in the intelligence service (default: 0 0 */4 * * *). Set it in the service's .env file โ no code changes required.
| Variable | Default | Where to set |
|---|---|---|
TRENDING_CRON_SCHEDULE |
0 0 */4 * * * (every 4 hours) |
apps/intelligence/.env |
MEILISEARCH_HOST |
http://localhost:7700 |
apps/intelligence/.env |
MEILISEARCH_API_KEY |
masterKey |
apps/intelligence/.env |
The current formula weights high-intent actions heavier than passive ones:
Trending Score = (Purchases ร 3) + (Wishlist Adds ร 2) + (Views ร 1)
Once computed, the service batches updates and pushes them directly to the Meilisearch REST API via the items index. It then emits a trending_scores_updated TCP event, signaling the NestJS search subgraph to synchronize any dependent caching or state. This follows the same event-driven sync pattern used for item_upserted and item_deleted events.
Personalization Engine
The search subgraph exposes the forYouFeed GraphQL query, which acts as the primary entry point for personalized discovery.
The algorithm operates in two primary modes defined by the SearchMode enum:
SearchMode.PERSONALIZED: Activated when an authenticated Visitor provides a list of followedmaletIds(sourced from the Follow system). The engine heavily boosts or filters results to prioritize content from Malets the Visitor explicitly follows, ordered secondarily bytrendingScoreandindexedAtto keep the feed fresh.SearchMode.TRENDING: The fallback mode for anonymous Visitors or authenticated Visitors who do not follow any Malets. This mode ranks the entire platform catalog globally, strictly bytrendingScore:desc.
Meilisearch Custom Ranking
To support this without massive runtime performance hits, Meilisearch's custom ranking rules are configured to use trendingScore as a primary tiebreaker:
// search/src/meilisearch/meilisearch.service.ts
const rankingRules = [
'words',
'typo',
'proximity',
'attribute',
'sort',
'exactness',
'trendingScore:desc', // Injected platform-wide ranking signal
'indexedAt:desc'
];
The Lobby Integration
The frontend SvelteKit application utilizes the forYouFeed query inside the main /lobby route. The ForYouFeed.svelte component renders a dynamic, horizontally scrolling carousel of cards.
Cards in this feed are visually enhanced with dynamic badging โ displaying the item's precise trending score (e.g., "๐ฅ 42") and the Malet's handle (e.g., m|luminara). This visual feedback reinforces the "Virtual Mall" culture, allowing Visitors to immediately understand why an item is being recommended to them.
Cross-Service Data Flow
โโโโโโโโโโโโโโโโ trending_scores_updated โโโโโโโโโโโโโโโโ
โ intelligence โ โโโโโโโโโโโ TCP โโโโโโโโโโโโโโโธ โ search โ
โ (Rust cron) โ โ (NestJS) โ
โโโโโโโโฌโโโโโโโโ โโโโโโโโฌโโโโโโโโ
โ HTTP PUT /indexes/items/documents โ forYouFeed query
โผ โผ
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โ Meilisearch โ โโโโ search query โโโโโโโโโโโโ โ Frontend โ
โ (items index)โ โ (SvelteKit) โ
โโโโโโโโโโโโโโโโ โโโโโโโโฌโโโโโโโโ
โ followStore.getFollowedIds()
โผ
โโโโโโโโโโโโโโโโ
โ nodes โ
โ (Follow API) โ
โโโโโโโโโโโโโโโโ
Related
- Universal Search Index โ How items and blogs are indexed in Meilisearch
- Social Graph โ Architecture of the Follow system that drives personalization
- Search Engine Administration โ Managing synonyms, reconciliation, and custom ranking configuration
- Handle System & Sigil Taxonomy โ The
m|handlebadges displayed on feed cards - User Guide: Personalized Discovery โ End-user support article explaining the "For You" feed