From ec27df1d0fece08216bb1e47c7ec62b144706f51 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Sat, 18 Apr 2026 16:16:27 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20manufacturers=20route=20=E2=80=94=20lis?= =?UTF-8?q?t,=20get,=20create?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- src/server/index.ts | 2 ++ src/server/routes/manufacturers.ts | 38 ++++++++++++++++++++++++++++++ src/shared/schemas.ts | 12 ++++++++++ 3 files changed, 52 insertions(+) create mode 100644 src/server/routes/manufacturers.ts diff --git a/src/server/index.ts b/src/server/index.ts index 6afc26d..0747281 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -18,6 +18,7 @@ import { communityPriceRoutes } from "./routes/community-prices.ts"; import { discoveryRoutes } from "./routes/discovery.ts"; import { exchangeRateRoutes } from "./routes/exchange-rates.ts"; import { globalItemRoutes } from "./routes/global-items.ts"; +import { manufacturerRoutes } from "./routes/manufacturers.ts"; import { imageRoutes } from "./routes/images.ts"; import { itemRoutes } from "./routes/items.ts"; import { marketPriceRoutes } from "./routes/market-prices.ts"; @@ -290,6 +291,7 @@ app.route("/api/users", profileRoutes); app.route("/api/setups", setupRoutes); app.route("/api/discovery", discoveryRoutes); app.route("/api/global-items", globalItemRoutes); +app.route("/api/manufacturers", manufacturerRoutes); app.route("/api/onboarding", onboardingRoutes); app.route("/api/tags", tagRoutes); app.route("/api/exchange-rates", exchangeRateRoutes); diff --git a/src/server/routes/manufacturers.ts b/src/server/routes/manufacturers.ts new file mode 100644 index 0000000..24b0875 --- /dev/null +++ b/src/server/routes/manufacturers.ts @@ -0,0 +1,38 @@ +import { zValidator } from "@hono/zod-validator"; +import { Hono } from "hono"; +import { createManufacturerSchema } from "../../shared/schemas.ts"; +import { + createManufacturer, + getManufacturerBySlug, + listManufacturers, +} from "../services/manufacturer.service.ts"; + +type Env = { Variables: { db?: any } }; + +const app = new Hono(); + +app.get("/", async (c) => { + const db = c.get("db"); + return c.json(await listManufacturers(db)); +}); + +app.get("/:slug", async (c) => { + const db = c.get("db"); + const slug = c.req.param("slug"); + const manufacturer = await getManufacturerBySlug(db, slug); + if (!manufacturer) return c.json({ error: "Manufacturer not found" }, 404); + return c.json(manufacturer); +}); + +app.post("/", zValidator("json", createManufacturerSchema), async (c) => { + const db = c.get("db"); + const data = c.req.valid("json"); + try { + const manufacturer = await createManufacturer(db, data); + return c.json(manufacturer, 201); + } catch { + return c.json({ error: "Manufacturer with this name or slug already exists" }, 409); + } +}); + +export { app as manufacturerRoutes }; diff --git a/src/shared/schemas.ts b/src/shared/schemas.ts index f75be8c..f6aabff 100644 --- a/src/shared/schemas.ts +++ b/src/shared/schemas.ts @@ -146,6 +146,18 @@ export const bulkUpsertGlobalItemsSchema = z.object({ items: z.array(upsertGlobalItemSchema).min(1).max(100), }); +export const createManufacturerSchema = z.object({ + name: z.string().min(1).max(200), + slug: z + .string() + .min(1) + .max(100) + .regex(/^[a-z0-9-]+$/, "Slug must be lowercase alphanumeric with hyphens"), + website: z.string().url(), + tier: z.number().int().min(1).max(3).optional(), + country: z.string().length(2).optional(), +}); + // Profile schemas export const updateProfileSchema = z.object({ displayName: z.string().max(100).optional(),