`
When building Lunilβa marketplace where founders buy and sell digital assets like SaaS products, websites, domains, and social channelsβthe hardest architectural problem wasn't escrow integration or database design.
It was trust.
In the digital asset space, fraud is rarely obvious spam like cheap pharma links. It's subtle:
Initially, every listing had to wait in an admin review queue. For sellers, waiting hours or days killed momentum. For us, manual verification didn't scale.
We needed a real-time moderation pipeline that evaluates submissions during form completion, gives actionable feedback instantly, and stops deceptive listings before they hit our database.
Here is how we designed and deployed this system using Next.js App Router, DeepSeek, and Zod structured outputs.
Most platforms push moderation to background workers (bullmq, Celery, etc.). But if a seller makes an honest typo in their revenue metric or pastes a broken verification link, discovering it via email 6 hours later creates a terrible user experience.
We aimed for a synchronous round-trip under 1.2 seconds:
plaintext
[Seller Submits Listing]
β
βΌ
βββββββββββββββββββββββββββ
β Next.js Route Handler β
ββββββββββββ¬βββββββββββββββ
β 1. Deterministic Sanitization (Regex / Honeypot)
βΌ
βββββββββββββββββββββββββββ
β DeepSeek Structured API β βββ Inconsistency & Fraud Detection
ββββββββββββ¬βββββββββββββββ
β 2. Typed JSON Response (Zod)
βΌ
βββββββββββββ
β Risk Tier β
βββββββ¬ββββββ
ββ Score < 0.25 βββΊ Instant Publish
ββ Score 0.25-0.70 βΊ Form Warning & Inline Correction
ββ Score > 0.70 βββΊ Blocked / Fraud Flag
We use Zod to guarantee strict type safety between the LLM output and our Next.js backend. The model is forced to return a JSON object adhering to this schema:
`typescript
// lib/moderation/schema.ts
import { z } from "zod";
export const ModerationResultSchema = z.object({
status: z.enum(["APPROVED", "NEEDS_REVISION", "REJECTED"]),
riskScore: z.number().min(0).max(1), // 0 = legit, 1 = malicious
issues: z.array(
z.object({
field: z.enum(["title", "description", "financials", "urls", "general"]),
severity: z.enum(["low", "medium", "critical"]),
message: z.string(),
suggestion: z.string().optional(),
})
),
metricConsistency: z.object({
revenueVsTrafficPlausible: z.boolean(),
valuationMultipleReasonable: z.boolean(),
notes: z.string().optional(),
}),
});
export type ModerationResult = z.infer;
`
Here is the core verification logic running inside a Next.js App Router API route (app/api/listings/verify/route.ts).
We use DeepSeek (deepseek-chat) with strict JSON output mode. DeepSeek offers exceptional reasoning on structured tabular data and financial metrics at a fraction of the cost of legacy models.
`typescript
// app/api/listings/verify/route.ts
import { NextResponse } from "next/server";
import { ModerationResultSchema } from "@/lib/moderation/schema";
const SYSTEM_PROMPT = `
You are a senior due diligence auditor for Lunil, a marketplace for buying and selling digital businesses (SaaS, content sites, domains).
Your task is to analyze listing data for fraud, inflated metrics, and policy violations.
Evaluate:
Always return valid JSON matching the exact schema requested. Be objective, strict on fraud, but forgiving of normal startup variances.
`;
export async function POST(req: Request) {
try {
const listingData = await req.json();
// 1. Quick deterministic heuristic checks
if (!listingData.title || !listingData.description) {
return NextResponse.json({ error: "Missing required fields" }, { status: 400 });
}
// 2. Query DeepSeek
const response = await fetch("https://api.deepseek.com/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.DEEPSEEK_API_KEY}`,
},
body: JSON.stringify({
model: "deepseek-chat",
response_format: { type: "json_object" },
messages: [
{ role: "system", content: SYSTEM_PROMPT },
{
role: "user",
content: `Analyze this listing submission:
Title: ${listingData.title}
Asset Type: ${listingData.type}
Asking Price: $${listingData.askingPrice}
Monthly Revenue: $${listingData.monthlyRevenue}
Monthly Profit: $${listingData.monthlyProfit}
Monthly Pageviews: ${listingData.pageviews}
Description:
${listingData.description}
URL / Proof: ${listingData.proofUrl || "None provided"}`,
},
],
temperature: 0.1, // Near-deterministic for evaluation
}),
});
if (!response.ok) {
throw new Error(`DeepSeek API error: ${response.statusText}`);
}
const rawData = await response.json();
const parsedContent = JSON.parse(rawData.choices[0].message.content);
// 3. Validate response structure with Zod
const validationResult = ModerationResultSchema.safeParse(parsedContent);
if (!validationResult.success) {
console.error("Schema mismatch:", validationResult.error);
// Fallback: send to manual review queue if AI output is malformed
return NextResponse.json({ status: "MANUAL_REVIEW" });
}
return NextResponse.json(validationResult.data);
} catch (error) {
console.error("Listing verification failed:", error);
return NextResponse.json({ error: "Verification unavailable" }, { status: 500 });
}
}
`
Running this in production on Lunil highlighted some subtle nuances:
Starter Project vs Established Cash-Flowing SaaS) into the system prompt. field: "financials"), the client UI immediately highlights the exact input in red with the AIβs explanation (e.g., While DeepSeek handles deep reasoning well in ~800ms, our long-term goal is to make listing moderation feel as instantaneous as form validation (< 150ms).
Generative LLMs are fundamentally System 2 thinkers: they predict tokens sequentially, consuming unnecessary computational overhead when all we truly need is a deterministic categorical status and risk score.
Through December, we are benchmarking Jev, a high-speed "System 1" model developed by TypeSafe AI.
Because System 1 architectures focus on fast, direct pattern recognition without multi-step autoregressive generation:
If the benchmark proves that Jev matches DeepSeekβs accuracy on financial anomaly detection, our production pipeline will evolve into a two-tier engine:
Automating trust on a digital asset marketplace doesn't require multi-million dollar ML budgets. A disciplined setup using Next.js App Router, Zod, and DeepSeek allows a lean team to deliver real-time fraud protection that protects buyers while keeping the seller onboarding frictionless.
If you are building marketplaces or UGC platforms, how are you handling metric validation and fraud detection? Are you sticking to deterministic queues, or moving toward hybrid real-time architectures?
Built with Next.js, DeepSeek, and deployed on Lunil.