DEV Community

slawekluzny
slawekluzny

Posted on • Originally published at 24ad.info

The AI-Powered Classifieds Stack That Posts in Seconds

The AI-Powered Classifieds Stack That Posts in Seconds

Users can upload a photo to 24ad.info. AI assists with the listing details.

The ad goes live before any manual steps are complete. Here's how the stack works.

The Pipeline

1. Vision Processing (OpenRouter + Gemini 2.5 Flash)

When you upload photos:

// Simplified image analysis flow
const analysis = await openRouter.chat.completions.create({
  model: "google/gemini-2.5-flash",
  messages: [{
    role: "user",
    content: [
      { type: "image_url", url: uploadedImage },
      "Describe this item for a classified ad. Identify make/model, condition, and realistic price."
    ]
  }]
});
Enter fullscreen mode Exit fullscreen mode

Key observations:

  • Processes images quickly
  • Handles mixed content
  • Price suggestions draw on available data

2. Category Assignment

The system first tries keyword matching. If uncertain, it queries the classification options.

Two clever bits:

  1. Dormant category reactivation - Instead of creating duplicate categories, it finds and revives inactive ones
  2. Custom field generation - For categories like Cars, AI suggests relevant fields

3. Multilingual Output

Using the same call flow, translations are generated.

The response lands in our locales/ directory with i18n keys.

The Stack That Makes It Possible

Frontend

  • React 19 + Vite 7 - For the instant form updates
  • shadcn/ui - Pre-built components with Tailwind
  • wouter v3 - Lightweight routing (no React Router bloat)

Critical UX details:

  • File upload starts analysis during selection
  • Price/category suggestions appear as editable previews
  • Location auto-fills from browser geolocation or IP

Backend

  • tRPC v11 - Keeps frontend/backend types in sync
  • Drizzle ORM - For type-safe MySQL queries
  • Express 4 - Handles the traffic types:
    1. User requests (API/SSR)
    2. Googlebot HTML injection
    3. Health checks (/api/system-health)

Infrastructure

  • Caddy v2 - Wildcard subdomains with HSTS
  • PM2 cluster mode with 4 instances - load-balanced
  • MariaDB - Heavily indexed for search (title, location, price)
CREATE TABLE `posts` (
  `id` bigint AUTO_INCREMENT PRIMARY KEY,
  `title` varchar(191),
  `price` decimal(17,2),
  `country_code` varchar(2),
  `latitude` float,
  `longitude` float
  -- geolocation uses standard B-tree index on latitude/longitude
);
Enter fullscreen mode Exit fullscreen mode

Pain Points We Solved

1. AI Latency

Initial versions waited for all AI steps sequentially. Now:

  • Parallel processing - Fire all AI requests simultaneously
  • Fallback caching - Common items use template descriptions if needed

2. Location Handling

Early users saw unexpected placement. Fixed by:

  • Subdomain locking - Forces location based on subdomain
  • Clear labels - Shows target country

3. Spam Protection

Current defenses include:

  • AI content check - Flags suspicious patterns
  • IP/email blacklist - Shared across country subdomains
  • Stripe verification - Premium ads require validated payment

The Admin Toolkit

Moderators get bulk tools plus:

  • AI banner rotator - Generates event-specific graphics
  • Health monitor - Checks subsystems including font rendering and upload permissions

Performance

Median ad creation time is low. Category handling is accurate.

Lessons Learned

  1. AI isn't magic - Pricing suggestions benefit from additional rules.

  2. Condition detection - The AI spots visible details in photos.

  3. Speed matters - The entire process must fit within user attention.

Try it yourself: 24ad.info.

Top comments (0)