# Intelligent Aggregator Platform

Ask the catalogue a question, get a real answer.

A catalogue of B2B software where buyers ask a question in plain English and get an answer back from the live listings, instead of clicking through category pages.

## Tags

Next.js, TypeScript, Supabase, OpenAI, Tailwind CSS, Zod, Drizzle

![Aggregator platform listing B2B software vendors](https://lxbpjvrr41.ufs.sh/f/6KZjuRTQYJxHHJ76tUspOSZHF573cwrDvLBxKTg1AnaMC9ej)

## At a glance

- **Role:** Full-stack engineer
- **Timeline:** Jul 2023 - Nov 2024
- **Scope:** Database design, rendering, search, AI agent
- **Client:** Not named publicly

## Rendering and routing

Three rendering modes share one site. Listing and vendor pages are pre-rendered at build time so they load instantly and crawl cleanly. Incremental regeneration refreshes those pages in the background when the underlying rows change, so nobody waits for a rebuild. Pages that depend on a live query are server-rendered on request.

Routes are generated from the database, and so are the sitemaps and URL structure. Caching sits in layers in front of PostgreSQL, so repeat traffic on popular pages keeps database load low.

![Aggregator vendor listing page, generated from database rows](https://lxbpjvrr41.ufs.sh/f/6KZjuRTQYJxHWuTynaDgiNo7yhMxmQELI80UGnuVqPHDF1k6)

## The AI layer

Two pieces sit on top of the same schema.

Semantic search runs on pgvector. Embeddings live next to the product columns, so one query can rank by meaning and filter by category at the same time.

The agent handles the questions a filter cannot answer. It reads the question, chooses the queries, calls PostgreSQL through tool calling, and returns a report built from the current data.

![Aggregator search: a plain-English question answered from the live listings](https://lxbpjvrr41.ufs.sh/f/6KZjuRTQYJxHy1sX130hWqEK6jXl0V1uGNen82tHZd9J7mDo)

## Interface and data

### On the page

- **Empty states** tell users why there is nothing here and what to do next
- **CTA placement** was A/B tested rather than argued about
- **WCAG compliance**, so keyboard and screen reader users get the same catalogue
- **Vendor profiles** detailed enough to make an informed decision
- **Ads** placed off the reading path, so they do not fight the product

### Behind it

- **Zod schemas** validate data at every boundary
- **Supabase Storage** serves images, compressed on the way in
- **Drizzle** keeps queries type-safe against the same schema the app types come from
- **Feedback channels** built into the product, so problems get reported instead of guessed at

## Stack

Next.js and TypeScript on the front, Tailwind and shadcn/ui for the interface. Drizzle over Supabase PostgreSQL with pgvector for storage and search. OpenAI for query understanding and embeddings. Deployed on Vercel.

## Links

- Project page: https://andrey-markin.com/projects/aggregator
- All projects: https://andrey-markin.com/projects.md
- Contact: https://andrey-markin.com/#contact
