chore: govern product planning api logging
This commit is contained in:
parent
37ed4b83b2
commit
f4d272c7ff
@ -6,8 +6,11 @@ import {
|
|||||||
normalizeEnhanceProKreaConfig,
|
normalizeEnhanceProKreaConfig,
|
||||||
sanitizeEnhanceProKreaConfigForClient,
|
sanitizeEnhanceProKreaConfigForClient,
|
||||||
} from "@/lib/enhance-pro/config";
|
} from "@/lib/enhance-pro/config";
|
||||||
|
import { createLogger } from "@/lib/observability/logger";
|
||||||
import { normalizeEnhanceProPointsPricingConfig } from "@/lib/points/config";
|
import { normalizeEnhanceProPointsPricingConfig } from "@/lib/points/config";
|
||||||
|
|
||||||
|
const logger = createLogger("enhance-pro-config-api");
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
try {
|
try {
|
||||||
const session = await auth();
|
const session = await auth();
|
||||||
@ -31,7 +34,7 @@ export async function GET() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[Enhance Pro Config] 获取配置失败:", error);
|
logger.error("config_fetch_failed", error);
|
||||||
return NextResponse.json({ error: "获取图像增强 Pro 配置失败" }, { status: 500 });
|
return NextResponse.json({ error: "获取图像增强 Pro 配置失败" }, { status: 500 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { generateText } from "ai";
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { inlineVisionImages } from "@/lib/ai/vision-inline";
|
import { inlineVisionImages } from "@/lib/ai/vision-inline";
|
||||||
|
import { createLogger } from "@/lib/observability/logger";
|
||||||
import {
|
import {
|
||||||
PRODUCT_PLANNING_ADVANCED_DISABLED,
|
PRODUCT_PLANNING_ADVANCED_DISABLED,
|
||||||
PRODUCT_PLANNING_ADVANCED_DISABLED_MESSAGE,
|
PRODUCT_PLANNING_ADVANCED_DISABLED_MESSAGE,
|
||||||
@ -17,6 +18,8 @@ import type { ProductPlanningAnalyzeResponse } from "@/lib/product-planning/type
|
|||||||
export const runtime = "nodejs";
|
export const runtime = "nodejs";
|
||||||
export const maxDuration = 120;
|
export const maxDuration = 120;
|
||||||
|
|
||||||
|
const logger = createLogger("product-planning-analyze-image-api");
|
||||||
|
|
||||||
const requestSchema = z.object({
|
const requestSchema = z.object({
|
||||||
itemId: z.string().trim().min(1),
|
itemId: z.string().trim().min(1),
|
||||||
imageUrl: z.string().trim().url(),
|
imageUrl: z.string().trim().url(),
|
||||||
@ -119,7 +122,7 @@ export async function POST(request: NextRequest) {
|
|||||||
markdown: text,
|
markdown: text,
|
||||||
} satisfies ProductPlanningAnalyzeResponse);
|
} satisfies ProductPlanningAnalyzeResponse);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[ProductPlanning][AnalyzeImage] request failed:", error);
|
logger.error("request_failed", error);
|
||||||
return jsonError(502, "图片分析失败");
|
return jsonError(502, "图片分析失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { generateText } from "ai";
|
import { generateText } from "ai";
|
||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { createLogger } from "@/lib/observability/logger";
|
||||||
import { buildProductPlanningSkuAnalyzePrompt } from "@/lib/product-planning/analyze";
|
import { buildProductPlanningSkuAnalyzePrompt } from "@/lib/product-planning/analyze";
|
||||||
import {
|
import {
|
||||||
PRODUCT_PLANNING_ADVANCED_DISABLED,
|
PRODUCT_PLANNING_ADVANCED_DISABLED,
|
||||||
@ -20,6 +21,8 @@ import type {
|
|||||||
export const runtime = "nodejs";
|
export const runtime = "nodejs";
|
||||||
export const maxDuration = 120;
|
export const maxDuration = 120;
|
||||||
|
|
||||||
|
const logger = createLogger("product-planning-analyze-sku-api");
|
||||||
|
|
||||||
const requestSchema = z.object({
|
const requestSchema = z.object({
|
||||||
itemId: z.string().trim().min(1),
|
itemId: z.string().trim().min(1),
|
||||||
title: z.string().trim().optional(),
|
title: z.string().trim().optional(),
|
||||||
@ -86,7 +89,7 @@ export async function POST(request: NextRequest) {
|
|||||||
markdown: text,
|
markdown: text,
|
||||||
} satisfies ProductPlanningAnalyzeResponse);
|
} satisfies ProductPlanningAnalyzeResponse);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[ProductPlanning][AnalyzeSku] request failed:", error);
|
logger.error("request_failed", error);
|
||||||
return jsonError(502, "SKU 卖点分析失败");
|
return jsonError(502, "SKU 卖点分析失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { generateText } from "ai";
|
import { generateText } from "ai";
|
||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { createLogger } from "@/lib/observability/logger";
|
||||||
import { buildProductPlanningAnalyzePrompt } from "@/lib/product-planning/analyze";
|
import { buildProductPlanningAnalyzePrompt } from "@/lib/product-planning/analyze";
|
||||||
import { resolveProductPlanningTextModel } from "@/lib/product-planning/model-runtime";
|
import { resolveProductPlanningTextModel } from "@/lib/product-planning/model-runtime";
|
||||||
import {
|
import {
|
||||||
@ -16,6 +17,8 @@ import type {
|
|||||||
export const runtime = "nodejs";
|
export const runtime = "nodejs";
|
||||||
export const maxDuration = 120;
|
export const maxDuration = 120;
|
||||||
|
|
||||||
|
const logger = createLogger("product-planning-analyze-api");
|
||||||
|
|
||||||
const requestSchema = z.union([
|
const requestSchema = z.union([
|
||||||
z.object({
|
z.object({
|
||||||
kind: z.literal("review"),
|
kind: z.literal("review"),
|
||||||
@ -101,7 +104,7 @@ export async function POST(request: NextRequest) {
|
|||||||
};
|
};
|
||||||
return NextResponse.json(payload);
|
return NextResponse.json(payload);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[ProductPlanning][Analyze] request failed:", error);
|
logger.error("request_failed", error);
|
||||||
return jsonError(502, "AI 分析失败");
|
return jsonError(502, "AI 分析失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
import { createLogger } from "@/lib/observability/logger";
|
||||||
import {
|
import {
|
||||||
PRODUCT_PLANNING_ADVANCED_DISABLED,
|
PRODUCT_PLANNING_ADVANCED_DISABLED,
|
||||||
PRODUCT_PLANNING_ADVANCED_DISABLED_MESSAGE,
|
PRODUCT_PLANNING_ADVANCED_DISABLED_MESSAGE,
|
||||||
@ -18,6 +19,8 @@ import type {
|
|||||||
|
|
||||||
export const runtime = "nodejs";
|
export const runtime = "nodejs";
|
||||||
|
|
||||||
|
const logger = createLogger("product-planning-keyword-insight-api");
|
||||||
|
|
||||||
function jsonError(status: number, keyword: string, error: string) {
|
function jsonError(status: number, keyword: string, error: string) {
|
||||||
const payload: ProductPlanningKeywordInsightResponse = {
|
const payload: ProductPlanningKeywordInsightResponse = {
|
||||||
success: false,
|
success: false,
|
||||||
@ -135,7 +138,7 @@ export async function GET(request: NextRequest) {
|
|||||||
groups: normalizeGroups(data?.items?.magic),
|
groups: normalizeGroups(data?.items?.magic),
|
||||||
} satisfies ProductPlanningKeywordInsightResponse);
|
} satisfies ProductPlanningKeywordInsightResponse);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[ProductPlanning][KeywordInsight] request failed:", error);
|
logger.error("request_failed", error);
|
||||||
return jsonError(502, keyword, "关键词洞察接口调用失败");
|
return jsonError(502, keyword, "关键词洞察接口调用失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
import { createLogger } from "@/lib/observability/logger";
|
||||||
import {
|
import {
|
||||||
PRODUCT_PLANNING_ADVANCED_DISABLED,
|
PRODUCT_PLANNING_ADVANCED_DISABLED,
|
||||||
PRODUCT_PLANNING_ADVANCED_DISABLED_MESSAGE,
|
PRODUCT_PLANNING_ADVANCED_DISABLED_MESSAGE,
|
||||||
@ -14,6 +15,8 @@ import type { ProductPlanningTaobaoItemResponse } from "@/lib/product-planning/t
|
|||||||
|
|
||||||
export const runtime = "nodejs";
|
export const runtime = "nodejs";
|
||||||
|
|
||||||
|
const logger = createLogger("product-planning-taobao-item-api");
|
||||||
|
|
||||||
function jsonError(status: number, error: string) {
|
function jsonError(status: number, error: string) {
|
||||||
const payload: ProductPlanningTaobaoItemResponse = {
|
const payload: ProductPlanningTaobaoItemResponse = {
|
||||||
success: false,
|
success: false,
|
||||||
@ -48,7 +51,7 @@ export async function GET(request: NextRequest) {
|
|||||||
item,
|
item,
|
||||||
} satisfies ProductPlanningTaobaoItemResponse);
|
} satisfies ProductPlanningTaobaoItemResponse);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[ProductPlanning][TaobaoItem] request failed:", error);
|
logger.error("request_failed", error);
|
||||||
return jsonError(502, error instanceof Error ? error.message : "淘宝商品详情接口调用失败");
|
return jsonError(502, error instanceof Error ? error.message : "淘宝商品详情接口调用失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
import { createLogger } from "@/lib/observability/logger";
|
||||||
import {
|
import {
|
||||||
PRODUCT_PLANNING_ADVANCED_DISABLED,
|
PRODUCT_PLANNING_ADVANCED_DISABLED,
|
||||||
PRODUCT_PLANNING_ADVANCED_DISABLED_MESSAGE,
|
PRODUCT_PLANNING_ADVANCED_DISABLED_MESSAGE,
|
||||||
@ -14,6 +15,8 @@ import type { ProductPlanningMonthSaleResponse } from "@/lib/product-planning/ty
|
|||||||
|
|
||||||
export const runtime = "nodejs";
|
export const runtime = "nodejs";
|
||||||
|
|
||||||
|
const logger = createLogger("product-planning-month-sale-api");
|
||||||
|
|
||||||
function jsonError(status: number, itemId: string, error: string) {
|
function jsonError(status: number, itemId: string, error: string) {
|
||||||
const payload: ProductPlanningMonthSaleResponse = {
|
const payload: ProductPlanningMonthSaleResponse = {
|
||||||
success: false,
|
success: false,
|
||||||
@ -57,7 +60,7 @@ export async function GET(request: NextRequest) {
|
|||||||
raw: null,
|
raw: null,
|
||||||
} satisfies ProductPlanningMonthSaleResponse);
|
} satisfies ProductPlanningMonthSaleResponse);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[ProductPlanning][MonthSale] request failed:", error);
|
logger.error("request_failed", error);
|
||||||
return jsonError(502, itemId, error instanceof Error ? error.message : "月销量接口调用失败");
|
return jsonError(502, itemId, error instanceof Error ? error.message : "月销量接口调用失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { createLogger } from "@/lib/observability/logger";
|
||||||
import { getResolvedProductPlanningApiConfig } from "@/lib/product-planning/server-config";
|
import { getResolvedProductPlanningApiConfig } from "@/lib/product-planning/server-config";
|
||||||
import {
|
import {
|
||||||
isProductPlanningEnabled,
|
isProductPlanningEnabled,
|
||||||
@ -11,6 +12,8 @@ import { normalizeText, truncateText, uniqueBy } from "@/lib/product-planning/ut
|
|||||||
|
|
||||||
export const runtime = "nodejs";
|
export const runtime = "nodejs";
|
||||||
|
|
||||||
|
const logger = createLogger("product-planning-taobao-qa-api");
|
||||||
|
|
||||||
const requestSchema = z.object({
|
const requestSchema = z.object({
|
||||||
itemId: z.string().trim().min(1),
|
itemId: z.string().trim().min(1),
|
||||||
page: z.number().int().min(1).max(20).default(1),
|
page: z.number().int().min(1).max(20).default(1),
|
||||||
@ -164,7 +167,7 @@ export async function POST(request: NextRequest) {
|
|||||||
|
|
||||||
return NextResponse.json(payload);
|
return NextResponse.json(payload);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[ProductPlanning][QA] request failed:", error);
|
logger.error("request_failed", error);
|
||||||
return jsonError(502, "问大家接口调用失败");
|
return jsonError(502, "问大家接口调用失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
import { createLogger } from "@/lib/observability/logger";
|
||||||
import type { ProductPlanningRowsResponse, TaobaoReviewRow } from "@/lib/product-planning/types";
|
import type { ProductPlanningRowsResponse, TaobaoReviewRow } from "@/lib/product-planning/types";
|
||||||
import { getResolvedProductPlanningApiConfig } from "@/lib/product-planning/server-config";
|
import { getResolvedProductPlanningApiConfig } from "@/lib/product-planning/server-config";
|
||||||
import {
|
import {
|
||||||
@ -10,6 +11,8 @@ import { ensureHttpsUrl } from "@/lib/product-planning/utils";
|
|||||||
|
|
||||||
export const runtime = "nodejs";
|
export const runtime = "nodejs";
|
||||||
|
|
||||||
|
const logger = createLogger("product-planning-taobao-reviews-api");
|
||||||
|
|
||||||
function normalizeMediaUrl(value: unknown) {
|
function normalizeMediaUrl(value: unknown) {
|
||||||
if (typeof value === "string") {
|
if (typeof value === "string") {
|
||||||
return ensureHttpsUrl(value);
|
return ensureHttpsUrl(value);
|
||||||
@ -103,7 +106,7 @@ export async function GET(request: NextRequest) {
|
|||||||
|
|
||||||
return NextResponse.json(payload);
|
return NextResponse.json(payload);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[ProductPlanning][Reviews] request failed:", error);
|
logger.error("request_failed", error);
|
||||||
return jsonError(502, "淘宝评价接口调用失败");
|
return jsonError(502, "淘宝评价接口调用失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,6 +35,15 @@ const files = [
|
|||||||
"app/api/scene-fusion/route.ts",
|
"app/api/scene-fusion/route.ts",
|
||||||
"app/api/angle-edit/route.ts",
|
"app/api/angle-edit/route.ts",
|
||||||
"app/api/layer-split/route.ts",
|
"app/api/layer-split/route.ts",
|
||||||
|
"app/api/enhance/pro/config/route.ts",
|
||||||
|
"app/api/product-planning/analyze-image/route.ts",
|
||||||
|
"app/api/product-planning/analyze-sku/route.ts",
|
||||||
|
"app/api/product-planning/analyze/route.ts",
|
||||||
|
"app/api/product-planning/keyword-insight/route.ts",
|
||||||
|
"app/api/product-planning/taobao/item/route.ts",
|
||||||
|
"app/api/product-planning/taobao/month-sale/route.ts",
|
||||||
|
"app/api/product-planning/taobao/qa/route.ts",
|
||||||
|
"app/api/product-planning/taobao/reviews/route.ts",
|
||||||
"app/api/pick-object/route.ts",
|
"app/api/pick-object/route.ts",
|
||||||
"app/api/canvas/world/upload/route.ts",
|
"app/api/canvas/world/upload/route.ts",
|
||||||
"app/api/canvas/3d/tasks/route.ts",
|
"app/api/canvas/3d/tasks/route.ts",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user