mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-14 10:48:09 +02:00
feat: implement AI Copilot for product analysis, featuring dedicated API, business logic, UI components, and comprehensive documentation.
This commit is contained in:
1 parent
7a6b515db7
commit
1c03403e9a
8 files changed
+229
-11
No files matched your search
@@ -2,6 +2,9 @@ import { NextRequest, NextResponse } from "next/server";
|
||||
import { getSavedDatabaseConfig } from "@/features/settings/actions";
|
||||
import { OpenRouterClient } from "@/features/ai-copilot/data/open-router-client";
|
||||
import { ProductAnalysisInput } from "@/features/ai-copilot/models/ai-analysis.types";
|
||||
import { db } from "@/db";
|
||||
import { aiSupplierContext } from "@/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
const config = await getSavedDatabaseConfig();
|
||||
@@ -16,6 +19,21 @@ export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const body: ProductAnalysisInput = await req.json();
|
||||
|
||||
// Inject supplier context if available
|
||||
if (body.codeFournisseur) {
|
||||
try {
|
||||
const contextRecord = await db.select()
|
||||
.from(aiSupplierContext)
|
||||
.where(eq(aiSupplierContext.codeFournisseur, body.codeFournisseur))
|
||||
.limit(1);
|
||||
if (contextRecord.length > 0 && contextRecord[0].context) {
|
||||
body.supplierContext = contextRecord[0].context;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("[AI] Failed to fetch supplier context:", err);
|
||||
}
|
||||
}
|
||||
|
||||
const client = new OpenRouterClient({ apiKey, model });
|
||||
const result = await client.analyzeProduct(body);
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { db } from "@/db";
|
||||
import { aiSupplierContext } from "@/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const codeFournisseur = searchParams.get("fournisseur");
|
||||
|
||||
if (!codeFournisseur) {
|
||||
return NextResponse.json({ error: "Fournisseur manquant" }, { status: 400 });
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await db.select()
|
||||
.from(aiSupplierContext)
|
||||
.where(eq(aiSupplierContext.codeFournisseur, codeFournisseur))
|
||||
.limit(1);
|
||||
|
||||
return NextResponse.json({ context: result[0]?.context || "" });
|
||||
} catch (error) {
|
||||
console.error("Error fetching AI context:", error);
|
||||
// Fallback en cas d'erreur de BDD ou si la table n'est pas encore créée
|
||||
return NextResponse.json({ context: "" });
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
const { codeFournisseur, context } = body;
|
||||
|
||||
if (!codeFournisseur) {
|
||||
return NextResponse.json({ error: "Fournisseur manquant" }, { status: 400 });
|
||||
}
|
||||
|
||||
await db.insert(aiSupplierContext)
|
||||
.values({
|
||||
codeFournisseur,
|
||||
context: context || "",
|
||||
updatedAt: new Date()
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: aiSupplierContext.codeFournisseur,
|
||||
set: {
|
||||
context: context || "",
|
||||
updatedAt: new Date()
|
||||
}
|
||||
});
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (error) {
|
||||
console.error("Error saving AI context:", error);
|
||||
return NextResponse.json({ error: "Erreur lors de la sauvegarde" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user