chore(25-02): apply biome formatter to task 1 and 2 files
This commit is contained in:
@@ -67,15 +67,15 @@ const GlobalItemsGlobalItemIdRoute = GlobalItemsGlobalItemIdRouteImport.update({
|
|||||||
getParentRoute: () => rootRouteImport,
|
getParentRoute: () => rootRouteImport,
|
||||||
} as any)
|
} as any)
|
||||||
const ThreadsThreadIdIndexRoute = ThreadsThreadIdIndexRouteImport.update({
|
const ThreadsThreadIdIndexRoute = ThreadsThreadIdIndexRouteImport.update({
|
||||||
id: '/',
|
id: '/threads/$threadId/',
|
||||||
path: '/',
|
path: '/threads/$threadId/',
|
||||||
getParentRoute: () => ThreadsThreadIdRoute,
|
getParentRoute: () => rootRouteImport,
|
||||||
} as any)
|
} as any)
|
||||||
const ThreadsThreadIdCandidatesCandidateIdRoute =
|
const ThreadsThreadIdCandidatesCandidateIdRoute =
|
||||||
ThreadsThreadIdCandidatesCandidateIdRouteImport.update({
|
ThreadsThreadIdCandidatesCandidateIdRouteImport.update({
|
||||||
id: '/candidates/$candidateId',
|
id: '/threads/$threadId/candidates/$candidateId',
|
||||||
path: '/candidates/$candidateId',
|
path: '/threads/$threadId/candidates/$candidateId',
|
||||||
getParentRoute: () => ThreadsThreadIdRoute,
|
getParentRoute: () => rootRouteImport,
|
||||||
} as any)
|
} as any)
|
||||||
|
|
||||||
export interface FileRoutesByFullPath {
|
export interface FileRoutesByFullPath {
|
||||||
@@ -170,6 +170,8 @@ export interface RootRouteChildren {
|
|||||||
UsersUserIdRoute: typeof UsersUserIdRoute
|
UsersUserIdRoute: typeof UsersUserIdRoute
|
||||||
CollectionIndexRoute: typeof CollectionIndexRoute
|
CollectionIndexRoute: typeof CollectionIndexRoute
|
||||||
GlobalItemsIndexRoute: typeof GlobalItemsIndexRoute
|
GlobalItemsIndexRoute: typeof GlobalItemsIndexRoute
|
||||||
|
ThreadsThreadIdIndexRoute: typeof ThreadsThreadIdIndexRoute
|
||||||
|
ThreadsThreadIdCandidatesCandidateIdRoute: typeof ThreadsThreadIdCandidatesCandidateIdRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module '@tanstack/react-router' {
|
declare module '@tanstack/react-router' {
|
||||||
@@ -239,17 +241,17 @@ declare module '@tanstack/react-router' {
|
|||||||
}
|
}
|
||||||
'/threads/$threadId/': {
|
'/threads/$threadId/': {
|
||||||
id: '/threads/$threadId/'
|
id: '/threads/$threadId/'
|
||||||
path: '/'
|
path: '/threads/$threadId'
|
||||||
fullPath: '/threads/$threadId/'
|
fullPath: '/threads/$threadId/'
|
||||||
preLoaderRoute: typeof ThreadsThreadIdIndexRouteImport
|
preLoaderRoute: typeof ThreadsThreadIdIndexRouteImport
|
||||||
parentRoute: typeof ThreadsThreadIdRoute
|
parentRoute: typeof rootRouteImport
|
||||||
}
|
}
|
||||||
'/threads/$threadId/candidates/$candidateId': {
|
'/threads/$threadId/candidates/$candidateId': {
|
||||||
id: '/threads/$threadId/candidates/$candidateId'
|
id: '/threads/$threadId/candidates/$candidateId'
|
||||||
path: '/candidates/$candidateId'
|
path: '/threads/$threadId/candidates/$candidateId'
|
||||||
fullPath: '/threads/$threadId/candidates/$candidateId'
|
fullPath: '/threads/$threadId/candidates/$candidateId'
|
||||||
preLoaderRoute: typeof ThreadsThreadIdCandidatesCandidateIdRouteImport
|
preLoaderRoute: typeof ThreadsThreadIdCandidatesCandidateIdRouteImport
|
||||||
parentRoute: typeof ThreadsThreadIdRoute
|
parentRoute: typeof rootRouteImport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -264,6 +266,9 @@ const rootRouteChildren: RootRouteChildren = {
|
|||||||
UsersUserIdRoute: UsersUserIdRoute,
|
UsersUserIdRoute: UsersUserIdRoute,
|
||||||
CollectionIndexRoute: CollectionIndexRoute,
|
CollectionIndexRoute: CollectionIndexRoute,
|
||||||
GlobalItemsIndexRoute: GlobalItemsIndexRoute,
|
GlobalItemsIndexRoute: GlobalItemsIndexRoute,
|
||||||
|
ThreadsThreadIdIndexRoute: ThreadsThreadIdIndexRoute,
|
||||||
|
ThreadsThreadIdCandidatesCandidateIdRoute:
|
||||||
|
ThreadsThreadIdCandidatesCandidateIdRoute,
|
||||||
}
|
}
|
||||||
export const routeTree = rootRouteImport
|
export const routeTree = rootRouteImport
|
||||||
._addFileChildren(rootRouteChildren)
|
._addFileChildren(rootRouteChildren)
|
||||||
|
|||||||
@@ -16,21 +16,43 @@ function textResult(data: unknown): ToolResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function errorResult(message: string): ToolResult {
|
function errorResult(message: string): ToolResult {
|
||||||
return { content: [{ type: "text", text: JSON.stringify({ error: message }) }] };
|
return {
|
||||||
|
content: [{ type: "text", text: JSON.stringify({ error: message }) }],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const catalogItemInputSchema = {
|
const catalogItemInputSchema = {
|
||||||
brand: z.string().describe("Brand or manufacturer name"),
|
brand: z.string().describe("Brand or manufacturer name"),
|
||||||
model: z.string().describe("Model name — combined with brand forms the unique identifier"),
|
model: z
|
||||||
category: z.string().optional().describe("Category name (e.g., 'Bags', 'Lights')"),
|
.string()
|
||||||
|
.describe("Model name — combined with brand forms the unique identifier"),
|
||||||
|
category: z
|
||||||
|
.string()
|
||||||
|
.optional()
|
||||||
|
.describe("Category name (e.g., 'Bags', 'Lights')"),
|
||||||
weightGrams: z.number().optional().describe("Weight in grams"),
|
weightGrams: z.number().optional().describe("Weight in grams"),
|
||||||
priceCents: z.number().optional().describe("MSRP price in cents (e.g., 9999 = $99.99)"),
|
priceCents: z
|
||||||
|
.number()
|
||||||
|
.optional()
|
||||||
|
.describe("MSRP price in cents (e.g., 9999 = $99.99)"),
|
||||||
imageUrl: z.string().optional().describe("URL to the product image"),
|
imageUrl: z.string().optional().describe("URL to the product image"),
|
||||||
description: z.string().optional().describe("Product description"),
|
description: z.string().optional().describe("Product description"),
|
||||||
sourceUrl: z.string().optional().describe("URL to the product page on manufacturer/retailer site"),
|
sourceUrl: z
|
||||||
imageCredit: z.string().optional().describe("Image credit — photographer or source name"),
|
.string()
|
||||||
imageSourceUrl: z.string().optional().describe("Original URL where the image was sourced from"),
|
.optional()
|
||||||
tags: z.array(z.string()).optional().describe("Tags for categorization (created automatically if new)"),
|
.describe("URL to the product page on manufacturer/retailer site"),
|
||||||
|
imageCredit: z
|
||||||
|
.string()
|
||||||
|
.optional()
|
||||||
|
.describe("Image credit — photographer or source name"),
|
||||||
|
imageSourceUrl: z
|
||||||
|
.string()
|
||||||
|
.optional()
|
||||||
|
.describe("Original URL where the image was sourced from"),
|
||||||
|
tags: z
|
||||||
|
.array(z.string())
|
||||||
|
.optional()
|
||||||
|
.describe("Tags for categorization (created automatically if new)"),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const catalogToolDefinitions = [
|
export const catalogToolDefinitions = [
|
||||||
|
|||||||
@@ -48,11 +48,15 @@ app.post("/", zValidator("json", upsertGlobalItemSchema), async (c) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Bulk upsert — per D-06, D-07, D-08
|
// Bulk upsert — per D-06, D-07, D-08
|
||||||
app.post("/bulk", zValidator("json", bulkUpsertGlobalItemsSchema), async (c) => {
|
app.post(
|
||||||
|
"/bulk",
|
||||||
|
zValidator("json", bulkUpsertGlobalItemsSchema),
|
||||||
|
async (c) => {
|
||||||
const db = c.get("db");
|
const db = c.get("db");
|
||||||
const { items } = c.req.valid("json");
|
const { items } = c.req.valid("json");
|
||||||
const result = await bulkUpsertGlobalItems(db, items);
|
const result = await bulkUpsertGlobalItems(db, items);
|
||||||
return c.json(result);
|
return c.json(result);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
export { app as globalItemRoutes };
|
export { app as globalItemRoutes };
|
||||||
|
|||||||
@@ -302,12 +302,17 @@ describe("MCP Catalog Tools", () => {
|
|||||||
model: "PocketRocket 2",
|
model: "PocketRocket 2",
|
||||||
sourceUrl: "https://www.cascadedesigns.com/msr/pocket-rocket-2",
|
sourceUrl: "https://www.cascadedesigns.com/msr/pocket-rocket-2",
|
||||||
imageCredit: "MSR Photography",
|
imageCredit: "MSR Photography",
|
||||||
imageSourceUrl: "https://cdn.cascadedesigns.com/images/pocket-rocket-2.jpg",
|
imageSourceUrl:
|
||||||
|
"https://cdn.cascadedesigns.com/images/pocket-rocket-2.jpg",
|
||||||
});
|
});
|
||||||
const data = parseResult(result);
|
const data = parseResult(result);
|
||||||
expect(data.sourceUrl).toBe("https://www.cascadedesigns.com/msr/pocket-rocket-2");
|
expect(data.sourceUrl).toBe(
|
||||||
|
"https://www.cascadedesigns.com/msr/pocket-rocket-2",
|
||||||
|
);
|
||||||
expect(data.imageCredit).toBe("MSR Photography");
|
expect(data.imageCredit).toBe("MSR Photography");
|
||||||
expect(data.imageSourceUrl).toBe("https://cdn.cascadedesigns.com/images/pocket-rocket-2.jpg");
|
expect(data.imageSourceUrl).toBe(
|
||||||
|
"https://cdn.cascadedesigns.com/images/pocket-rocket-2.jpg",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("bulk_upsert_catalog processes array and returns created/updated counts", async () => {
|
test("bulk_upsert_catalog processes array and returns created/updated counts", async () => {
|
||||||
@@ -333,7 +338,10 @@ describe("MCP Catalog Tools", () => {
|
|||||||
const tools = registerCatalogTools(db);
|
const tools = registerCatalogTools(db);
|
||||||
|
|
||||||
// Pre-create one item
|
// Pre-create one item
|
||||||
await tools.upsert_catalog_item({ brand: "Revelate Designs", model: "Terrapin System" });
|
await tools.upsert_catalog_item({
|
||||||
|
brand: "Revelate Designs",
|
||||||
|
model: "Terrapin System",
|
||||||
|
});
|
||||||
|
|
||||||
const result = await tools.bulk_upsert_catalog({
|
const result = await tools.bulk_upsert_catalog({
|
||||||
items: [
|
items: [
|
||||||
@@ -348,7 +356,9 @@ describe("MCP Catalog Tools", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("catalog tool definitions include attribution fields in inputSchema", () => {
|
test("catalog tool definitions include attribution fields in inputSchema", () => {
|
||||||
const { catalogToolDefinitions } = require("../../src/server/mcp/tools/catalog.ts");
|
const {
|
||||||
|
catalogToolDefinitions,
|
||||||
|
} = require("../../src/server/mcp/tools/catalog.ts");
|
||||||
const upsertDef = catalogToolDefinitions.find(
|
const upsertDef = catalogToolDefinitions.find(
|
||||||
(d: { name: string }) => d.name === "upsert_catalog_item",
|
(d: { name: string }) => d.name === "upsert_catalog_item",
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -116,7 +116,10 @@ describe("Global Item Routes", () => {
|
|||||||
const res = await app.request("/api/global-items", {
|
const res = await app.request("/api/global-items", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ brand: "Revelate Designs", model: "Terrapin System" }),
|
body: JSON.stringify({
|
||||||
|
brand: "Revelate Designs",
|
||||||
|
model: "Terrapin System",
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
expect(res.status).toBe(200);
|
expect(res.status).toBe(200);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user