SEARCH BUILD NOTES

AI search for messy marketplace queries.

ScoutLocal needed search that could understand vague natural-language queries like "vibey coffee spot" without ignoring real marketplace facts like location, hours, and merchant data. I designed a hybrid semantic + SQL search pattern so users could search naturally while the product stayed grounded.

Note: This is a build-notes page, not a public app demo. It focuses on the search architecture and product decisions behind the work.
Problem: Users do not search in database categories. They search in messy human language.
Approach: Semantic matching for intent, SQL filters for facts, and mobile-aware fetching for speed/cost control.
Outcome: A more forgiving search architecture that reduces dead ends without letting AI make things up.
Discuss a product build
Next.js 15 NestJS PostgreSQL Azure OpenAI Clerk
At a Glance:
  • Hybrid semantic + SQL search for messy queries
  • Geospatial fetching designed to reduce wasted map requests
  • Polymorphic schema + optimistic UI patterns
  • Clerk identity integration for merchant role separation.

This is the useful pattern: deterministic filters own facts, semantic matching helps with language, and the system falls back when signals are weak.

Built For

SaaS Product Teams

Needing better search/recommendations without hiring a full-time specialist or rebuilding the product from scratch.

Marketplaces

Dealing with overlapping entities (merchants, events) and heavy read-traffic.

Scaling Startups

Trying to scale past MVP without letting technical debt in search crush your velocity.

The Scenario & The Constraint

The Scenario: ScoutLocal's marketplace needed to accommodate "vague" human searches (e.g., "vibey coffee spot for reading") rather than strict SQL category dropdowns.

The Constraint: Existing relational search could not handle natural-language nuance on its own. A raw LLM call in the search path would add latency and risk inventing venues. The safer pattern was semantic matching for intent, then deterministic filters for facts.

The Pipeline & The Fallback

We built a Hybrid Search Engine. The pipeline extracts live merchant data, embeds semantic intent via Azure OpenAI on ingestion, and stores outputs in a pgvector index.

1. User Intent "Vibey coffee" → Vector Embedding
2. Semantic Match pgvector finds nearest neighbors
3. SQL Validate Prisma filters by location/hours

The Fallback: If the vector search returns results with a semantic confidence score below our tuned threshold, the engine automatically falls back to a strict SQL ILIKE search. This prevents the system from guessing and returns a deterministic empty state if required.

Efficiency Strategy

The Problem: Mobile maps typically drain battery and spike API costs by fetching data on every micro-movement.

Infrastructure Protection

  • API Cost Control: Scroll and pan events are debounced and bundled so accidental map jitter does not trigger unnecessary requests.

Universal Access

  • Device Agnostic: Targets 60fps scrolling performance on low-bandwidth networks, maximizing the addressable market.

Result: The architecture was designed and tested to lower map-related API costs and ensure smoother scrolling on mid-range devices once deployed.

Data Modeling

In the real world, entities rarely fit into neat boxes. A "Coffee Shop" might also be a "Coffee Roaster" (Maker). Instead of creating three separate accounts, we implemented a Polymorphic Schema.

Why this matters for scaling: Identity was managed via Clerk, decoupling user authentication from the polymorphic merchant schema to reduce architectural debt. This unified identity means you upload a product once and surface it across locations, brands, and events, without duplicate records.

UX Engineering: Optimistic State

Performance isn't just about server response times; it's about Perceived Latency. The solution employs an Optimistic UI pattern for high-frequency user actions.

The Strategy:
  • 1. UI updates instantly (0ms) when user clicks.
  • 2. API request processes in the background.
  • 3. If sync fails, UI self-heals automatically.

This keeps the interface feeling instant even when APIs are under load.

Implementation Spotlight

Below are the patterns used to keep vectors and entities in sync, avoiding "ghost" records and race conditions.

1. Backend: Atomic Integrity

api/embeddings/sync.service.ts

await prisma.$transaction(async (tx) => {
    // 1. Reserve Entity ID (Atomic)
    const record = await tx.embedding.create({ ... });

    // 2. External Vector Gen (Rollback on Fail)
    const vector = await openai.embeddings.create({ input: text });

    await tx.embedding.update({ ... });
});

2. Frontend: Optimistic UI

hooks/useSavedItems.ts

const toggleSave = useCallback(async (id) => {
    // 1. Zero Latency Update
    setSavedIds((prev) => new Set(prev).add(id));

    try {
        await api.post(`/user/saved/${id}`);
    } catch (err) {
        // 2. Self-Healing Rollback
        setSavedIds((prev) => { ... });
        toast.error("Sync failed");
    }
}, []);

3. Identity: Clerk Auth Guard

app/api/search/route.ts

export async function POST(req: Request) {
  const { userId } = auth(); // Clerk Identity
  if (!userId) return new Response("Unauthorized", { status: 401 });
  
  // Proceed with secure search/sync
  // Merchant isolation is enforced by userId
}

Build Package & Scope

The Build Package

A deployable product build package covering the hybrid retrieval engine, the Next.js storefront, and the Prisma sync pipelines. ScoutLocal retained ownership of the code and product direction.

The Scope

A build like this usually starts as a focused product sprint: search behavior, data model, ingestion path, UI states, and handoff notes before expanding the product surface.

Want this kind of search or product build?

Choose the right next step

MVP Build Path

If you are building a product with search, user accounts, data workflows, and launch constraints, start with the MVP path.

  • Product scope and user path
  • Data model and search requirements

Good fit if you already have a live product and real users searching, even if the current search is basic.

View MVP Build Path

Search or Workflow Sprint

$4,000-$8,000 / Fixed

A focused 2-4 week build for one search, routing, reporting, dashboard, or automation system wired into your existing tools.

  • One critical workflow mapped
  • Focused changes implemented
  • Simple checks/logs added

Good fit when the product already exists and one workflow or search surface needs a serious upgrade.

Discuss Build Sprint