feat: manufacturer service with list, get, create
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
42
src/server/services/manufacturer.service.ts
Normal file
42
src/server/services/manufacturer.service.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { asc, eq } from "drizzle-orm";
|
||||
import { db as prodDb } from "../../db/index.ts";
|
||||
import { manufacturers } from "../../db/schema.ts";
|
||||
|
||||
type Db = typeof prodDb;
|
||||
|
||||
export type CreateManufacturerInput = {
|
||||
name: string;
|
||||
slug: string;
|
||||
website: string;
|
||||
tier?: number;
|
||||
country?: string;
|
||||
};
|
||||
|
||||
export async function listManufacturers(db: Db = prodDb) {
|
||||
return db.select().from(manufacturers).orderBy(asc(manufacturers.name));
|
||||
}
|
||||
|
||||
export async function getManufacturerBySlug(db: Db = prodDb, slug: string) {
|
||||
const [row] = await db
|
||||
.select()
|
||||
.from(manufacturers)
|
||||
.where(eq(manufacturers.slug, slug));
|
||||
return row ?? null;
|
||||
}
|
||||
|
||||
export async function createManufacturer(
|
||||
db: Db = prodDb,
|
||||
data: CreateManufacturerInput,
|
||||
) {
|
||||
const [row] = await db
|
||||
.insert(manufacturers)
|
||||
.values({
|
||||
name: data.name,
|
||||
slug: data.slug,
|
||||
website: data.website,
|
||||
tier: data.tier ?? 1,
|
||||
country: data.country ?? null,
|
||||
})
|
||||
.returning();
|
||||
return row!;
|
||||
}
|
||||
@@ -25,6 +25,8 @@ const TRUNCATE_TABLES = [
|
||||
"setups",
|
||||
"thread_candidates",
|
||||
"threads",
|
||||
"community_prices",
|
||||
"market_prices",
|
||||
"items",
|
||||
"global_item_tags",
|
||||
"global_items",
|
||||
@@ -35,6 +37,7 @@ const TRUNCATE_TABLES = [
|
||||
"api_keys",
|
||||
"settings",
|
||||
"categories",
|
||||
"manufacturers",
|
||||
"users",
|
||||
];
|
||||
|
||||
|
||||
72
tests/services/manufacturer.service.test.ts
Normal file
72
tests/services/manufacturer.service.test.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { beforeEach, describe, expect, it } from "bun:test";
|
||||
import { manufacturers } from "../../src/db/schema.ts";
|
||||
import {
|
||||
createManufacturer,
|
||||
getManufacturerBySlug,
|
||||
listManufacturers,
|
||||
} from "../../src/server/services/manufacturer.service.ts";
|
||||
import { createTestDb } from "../helpers/db.ts";
|
||||
|
||||
let db: Awaited<ReturnType<typeof createTestDb>>["db"];
|
||||
|
||||
beforeEach(async () => {
|
||||
({ db } = await createTestDb());
|
||||
});
|
||||
|
||||
describe("createManufacturer", () => {
|
||||
it("inserts a manufacturer and returns it", async () => {
|
||||
const result = await createManufacturer(db, {
|
||||
name: "Apidura",
|
||||
slug: "apidura",
|
||||
website: "https://apidura.com",
|
||||
tier: 1,
|
||||
country: "GB",
|
||||
});
|
||||
expect(result.id).toBeGreaterThan(0);
|
||||
expect(result.name).toBe("Apidura");
|
||||
expect(result.slug).toBe("apidura");
|
||||
expect(result.active).toBe(true);
|
||||
});
|
||||
|
||||
it("throws on duplicate slug", async () => {
|
||||
await createManufacturer(db, {
|
||||
name: "Apidura",
|
||||
slug: "apidura",
|
||||
website: "https://apidura.com",
|
||||
});
|
||||
await expect(
|
||||
createManufacturer(db, {
|
||||
name: "Apidura Copy",
|
||||
slug: "apidura",
|
||||
website: "https://other.com",
|
||||
}),
|
||||
).rejects.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("getManufacturerBySlug", () => {
|
||||
it("returns manufacturer when found", async () => {
|
||||
await createManufacturer(db, {
|
||||
name: "Revelate Designs",
|
||||
slug: "revelate-designs",
|
||||
website: "https://revelatedesigns.com",
|
||||
});
|
||||
const result = await getManufacturerBySlug(db, "revelate-designs");
|
||||
expect(result?.name).toBe("Revelate Designs");
|
||||
});
|
||||
|
||||
it("returns null when not found", async () => {
|
||||
const result = await getManufacturerBySlug(db, "nope");
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("listManufacturers", () => {
|
||||
it("returns all manufacturers ordered by name", async () => {
|
||||
await createManufacturer(db, { name: "Ortlieb", slug: "ortlieb", website: "https://ortlieb.com" });
|
||||
await createManufacturer(db, { name: "Apidura", slug: "apidura", website: "https://apidura.com" });
|
||||
const result = await listManufacturers(db);
|
||||
expect(result[0]?.name).toBe("Apidura");
|
||||
expect(result[1]?.name).toBe("Ortlieb");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user