work / mercala

Mercala

Agent-native multi-tenant e-commerce: merchants run their store by chatting, shoppers buy through a chat-first storefront.

Years
2026
Status
paused
Live
mercala-web.vercel.app
Source
hallelx2/mercala

What it is

A merchant types one sentence, “a blue serving bowl, £120, 12 in stock”, and the product exists, with a generated photograph. Shoppers describe what they want instead of filtering. The main interface is agents; the forms are there if you want them.

Read more

The backend is a Java 21 Spring Boot modular monolith with the agent and image generation carved out as services. Tenancy is enforced three times: RBAC, a Hibernate tenant filter, and Postgres row-level security. Search fuses BM25 from pg_search with pgvector by reciprocal rank fusion, in Postgres. Product events go through an outbox table and a relay onto Kafka.

Product photos come from a provider chain, Cloudflare Workers AI then Replicate then Pollinations, with format checked by magic bytes. Payments go through Stripe, Paystack or Flutterwave by tenant region. It deploys to AWS with Terraform and Ansible, authenticated by GitHub OIDC with no stored access keys.

Stack

  • Java 21
  • Spring Boot
  • Spring AI
  • Postgres
  • pg_search
  • pgvector
  • Kafka
  • Redis
  • ONNX
  • Stripe
  • Paystack
  • Flutterwave
  • Terraform
  • Ansible
  • AWS
  • Next.js

Counted

  • 100backend commits
    git rev-list, mercala
  • 26web commits
    git rev-list, mercala-web
  • 299 / 85Java files / test files
    repo count
  • M0–M7build phases shipped
    2026-06-06 → 07-03

How it works

The system as a machine on a bench. Hover or use the arrow keys to drive it.

chat
What the agent is acting on nowTenant bays: each lock opens for one tenant onlyLamps in chain order: cloudflare → replicate → pollinations → placeholderMercala as a shop counter: the agent's tool calls write only through its tenant's lock (a Hibernate filter plus Postgres row-level security), the outbox row commits with the product and a relay stamps it onto Kafka every 500 ms, image generation falls through 4 providers until one answers, and search fuses BM25 and 1536-dimension vector ranks by reciprocal rank fusion with k = 60.

The path through it

  1. ChatMerchant or shopper writes in the Next.js app, through the typed @mercala/sdk.
  2. mercala-coreIdentity, catalogue, inventory, cart, orders, payments, media. RBAC, then the tenant filter, then Postgres RLS.
  3. mercala-agentSpring AI tool calls against an OpenAI-compatible model create and update products.
  4. mercala-image-genCloudflare → Replicate → Pollinations → placeholder, first one that answers wins.
  5. SearchBM25 and vector results fused by reciprocal rank fusion, inside Postgres.
  6. Events and paymentsAn outbox table relayed to Kafka every 500 ms; a payment provider per tenant region.