diff --git a/src/client/components/CandidateCard.tsx b/src/client/components/CandidateCard.tsx index 3ebc064..3e3d778 100644 --- a/src/client/components/CandidateCard.tsx +++ b/src/client/components/CandidateCard.tsx @@ -34,7 +34,7 @@ export function CandidateCard({ priceCents, categoryName, categoryIcon, - imageFilename, + imageFilename: _imageFilename, imageUrl, productUrl, threadId, diff --git a/src/client/components/ImageUpload.tsx b/src/client/components/ImageUpload.tsx index b0d2488..b3dd5c9 100644 --- a/src/client/components/ImageUpload.tsx +++ b/src/client/components/ImageUpload.tsx @@ -10,7 +10,11 @@ interface ImageUploadProps { const MAX_SIZE_BYTES = 5 * 1024 * 1024; // 5MB const ACCEPTED_TYPES = ["image/jpeg", "image/png", "image/webp"]; -export function ImageUpload({ value, imageUrl, onChange }: ImageUploadProps) { +export function ImageUpload({ + value: _value, + imageUrl, + onChange, +}: ImageUploadProps) { const [uploading, setUploading] = useState(false); const [error, setError] = useState(null); const [localPreview, setLocalPreview] = useState(null); diff --git a/src/client/components/ItemCard.tsx b/src/client/components/ItemCard.tsx index e27537d..4986b2a 100644 --- a/src/client/components/ItemCard.tsx +++ b/src/client/components/ItemCard.tsx @@ -16,6 +16,7 @@ interface ItemCardProps { imageFilename: string | null; imageUrl?: string | null; productUrl?: string | null; + brand?: string | null; onRemove?: () => void; classification?: string; onClassificationCycle?: () => void; @@ -29,9 +30,10 @@ export function ItemCard({ quantity, categoryName, categoryIcon, - imageFilename, + imageFilename: _imageFilename, imageUrl, productUrl, + brand, onRemove, classification, onClassificationCycle, @@ -177,9 +179,14 @@ export function ItemCard({ )}
+ {brand && ( +

+ {brand} +

+ )}

- {name} + {brand ? name.replace(`${brand} `, "") : name}

{quantity != null && quantity > 1 && ( diff --git a/src/db/dev-seed.ts b/src/db/dev-seed.ts index a521253..3c0fa77 100644 --- a/src/db/dev-seed.ts +++ b/src/db/dev-seed.ts @@ -6,12 +6,11 @@ import { and, eq } from "drizzle-orm"; import { DEV_CATEGORIES, DEV_GLOBAL_ITEMS, - DEV_SETUPS, DEV_SETTINGS, + DEV_SETUPS, DEV_TAG_ASSIGNMENTS, DEV_THREADS, DEV_USER_ITEMS, - categoryDisplayName, } from "./dev-seed-data.ts"; import { db } from "./index.ts"; import * as schema from "./schema.ts"; @@ -106,7 +105,10 @@ async function seedDevData(database: Db = db) { description: item.description, }) .returning(); - if (!inserted) throw new Error(`Failed to insert global item: ${item.brand} ${item.model}`); + if (!inserted) + throw new Error( + `Failed to insert global item: ${item.brand} ${item.model}`, + ); globalItemIds.push(inserted.id); newGlobalCount++; } @@ -185,7 +187,8 @@ async function seedDevData(database: Db = db) { userId, }) .returning(); - if (!thread) throw new Error(`Failed to insert thread: ${threadDef.name}`); + if (!thread) + throw new Error(`Failed to insert thread: ${threadDef.name}`); threadResults.push({ threadId: thread.id, threadDef }); } console.log(` ${threadResults.length} threads created.`); diff --git a/src/server/routes/items.ts b/src/server/routes/items.ts index 93247dd..cee42b2 100644 --- a/src/server/routes/items.ts +++ b/src/server/routes/items.ts @@ -114,5 +114,4 @@ app.delete("/:id", async (c) => { return c.json({ success: true }); }); - export { app as itemRoutes }; diff --git a/src/server/services/category.service.ts b/src/server/services/category.service.ts index b5705e6..08971e4 100644 --- a/src/server/services/category.service.ts +++ b/src/server/services/category.service.ts @@ -1,5 +1,5 @@ import { and, asc, eq } from "drizzle-orm"; -import { db as prodDb } from "../../db/index.ts"; +import type { db as prodDb } from "../../db/index.ts"; import { categories, items } from "../../db/schema.ts"; type Db = typeof prodDb; diff --git a/src/server/services/csv.service.ts b/src/server/services/csv.service.ts index d57cb08..d378253 100644 --- a/src/server/services/csv.service.ts +++ b/src/server/services/csv.service.ts @@ -1,4 +1,4 @@ -import { and, eq, sql } from "drizzle-orm"; +import { eq, sql } from "drizzle-orm"; import type { db as prodDb } from "../../db/index.ts"; import { categories, globalItems, items } from "../../db/schema.ts"; import { getOrCreateUncategorized } from "./category.service.ts"; diff --git a/src/server/services/global-item.service.ts b/src/server/services/global-item.service.ts index bb1f54f..de4152f 100644 --- a/src/server/services/global-item.service.ts +++ b/src/server/services/global-item.service.ts @@ -1,7 +1,7 @@ -import { and, count, eq, ilike, or, sql } from "drizzle-orm"; import type { SQL } from "drizzle-orm"; +import { and, count, eq, ilike, or, sql } from "drizzle-orm"; import { db as prodDb } from "../../db/index.ts"; -import { globalItemTags, globalItems, items, tags } from "../../db/schema.ts"; +import { globalItems, globalItemTags, items, tags } from "../../db/schema.ts"; type Db = typeof prodDb; @@ -22,10 +22,7 @@ export async function searchGlobalItems( const escaped = query.replace(/%/g, "\\%").replace(/_/g, "\\_"); const pattern = `%${escaped}%`; conditions.push( - or( - ilike(globalItems.brand, pattern), - ilike(globalItems.model, pattern), - )!, + or(ilike(globalItems.brand, pattern), ilike(globalItems.model, pattern))!, ); } @@ -59,10 +56,7 @@ export async function searchGlobalItems( * Get a single global item by ID with the count of user items referencing it * via items.globalItemId. */ -export async function getGlobalItemWithOwnerCount( - db: Db = prodDb, - id: number, -) { +export async function getGlobalItemWithOwnerCount(db: Db = prodDb, id: number) { const [item] = await db .select() .from(globalItems) diff --git a/src/server/services/thread.service.ts b/src/server/services/thread.service.ts index fcdfae4..2d36c3e 100644 --- a/src/server/services/thread.service.ts +++ b/src/server/services/thread.service.ts @@ -359,9 +359,7 @@ export async function resolveThread( .select() .from(globalItems) .where(eq(globalItems.id, candidate.globalItemId)); - const fallbackName = gi - ? `${gi.brand} ${gi.model}` - : candidate.name; + const fallbackName = gi ? `${gi.brand} ${gi.model}` : candidate.name; insertValues = { name: fallbackName, globalItemId: candidate.globalItemId, diff --git a/src/server/services/totals.service.ts b/src/server/services/totals.service.ts index 9ce9c38..1f830a2 100644 --- a/src/server/services/totals.service.ts +++ b/src/server/services/totals.service.ts @@ -1,4 +1,4 @@ -import { and, eq, sql } from "drizzle-orm"; +import { eq, sql } from "drizzle-orm"; import type { db as prodDb } from "../../db/index.ts"; import { categories, globalItems, items } from "../../db/schema.ts"; diff --git a/tests/routes/global-items.test.ts b/tests/routes/global-items.test.ts index a464a39..9af449a 100644 --- a/tests/routes/global-items.test.ts +++ b/tests/routes/global-items.test.ts @@ -1,8 +1,8 @@ import { beforeEach, describe, expect, it } from "bun:test"; import { Hono } from "hono"; import { - globalItemTags, globalItems, + globalItemTags, items, tags, } from "../../src/db/schema.ts"; @@ -102,9 +102,7 @@ describe("Global Item Routes", () => { .insert(globalItemTags) .values({ globalItemId: gi1.id, tagId: tag.id }); - const res = await app.request( - "/api/global-items?tags=ultralight", - ); + const res = await app.request("/api/global-items?tags=ultralight"); expect(res.status).toBe(200); const body = await res.json(); diff --git a/tests/routes/oauth.test.ts b/tests/routes/oauth.test.ts index 93cc957..640361b 100644 --- a/tests/routes/oauth.test.ts +++ b/tests/routes/oauth.test.ts @@ -2,7 +2,6 @@ import { beforeEach, describe, expect, it, mock } from "bun:test"; import { createHash, randomBytes } from "node:crypto"; import { Hono } from "hono"; import { oauthRoutes, wellKnownRoute } from "../../src/server/routes/oauth.ts"; -import { createApiKey } from "../../src/server/services/auth.service.ts"; import { createTestDb } from "../helpers/db.ts"; // Mock @hono/oidc-auth — must be before importing routes @@ -35,14 +34,14 @@ function generatePkce() { describe("OAuth Routes", () => { let app: Hono; - let db: Awaited>["db"]; - let userId: number; + let _db: Awaited>["db"]; + let _userId: number; beforeEach(async () => { const testApp = await createTestApp(); app = testApp.app; - db = testApp.db; - userId = testApp.userId; + _db = testApp.db; + _userId = testApp.userId; mockGetAuth.mockReset(); // Default: user is authenticated via OIDC mockGetAuth.mockReturnValue({ diff --git a/tests/routes/profiles.test.ts b/tests/routes/profiles.test.ts index cf3e506..f7071d6 100644 --- a/tests/routes/profiles.test.ts +++ b/tests/routes/profiles.test.ts @@ -3,13 +3,9 @@ import { zValidator } from "@hono/zod-validator"; import { eq } from "drizzle-orm"; import { Hono } from "hono"; import * as schema from "../../src/db/schema.ts"; -import { parseId } from "../../src/server/lib/params.ts"; import { profileRoutes } from "../../src/server/routes/profiles.ts"; import { setupRoutes } from "../../src/server/routes/setups.ts"; -import { - getPublicSetupWithItems, - updateProfile, -} from "../../src/server/services/profile.service.ts"; +import { updateProfile } from "../../src/server/services/profile.service.ts"; import { updateProfileSchema } from "../../src/shared/schemas.ts"; import { createTestDb } from "../helpers/db.ts"; diff --git a/tests/services/global-item.service.test.ts b/tests/services/global-item.service.test.ts index a808267..2b848ce 100644 --- a/tests/services/global-item.service.test.ts +++ b/tests/services/global-item.service.test.ts @@ -1,7 +1,7 @@ import { beforeEach, describe, expect, it } from "bun:test"; import { - globalItemTags, globalItems, + globalItemTags, items, tags, } from "../../src/db/schema.ts"; @@ -151,7 +151,7 @@ describe("Global Item Service", () => { brand: "Revelate Designs", model: "Terrapin System", }); - const gi2 = await insertGlobalItem(db, { + const _gi2 = await insertGlobalItem(db, { brand: "Apidura", model: "Handlebar Pack", }); @@ -205,9 +205,7 @@ describe("Global Item Service", () => { await tagGlobalItem(db, gi2.id, tag.id); // Both tagged bikepacking, but only one matches "terrapin" - const results = await searchGlobalItems(db, "terrapin", [ - "bikepacking", - ]); + const results = await searchGlobalItems(db, "terrapin", ["bikepacking"]); expect(results).toHaveLength(1); expect(results[0].model).toBe("Terrapin System"); }); diff --git a/tests/services/item.service.test.ts b/tests/services/item.service.test.ts index cf317cd..e38960b 100644 --- a/tests/services/item.service.test.ts +++ b/tests/services/item.service.test.ts @@ -180,10 +180,7 @@ describe("Item Service", () => { imageUrl?: string; }, ) { - const [row] = await testDb - .insert(globalItems) - .values(data) - .returning(); + const [row] = await testDb.insert(globalItems).values(data).returning(); return row; } diff --git a/tests/services/profile.service.test.ts b/tests/services/profile.service.test.ts index 96469d5..0cbc421 100644 --- a/tests/services/profile.service.test.ts +++ b/tests/services/profile.service.test.ts @@ -12,7 +12,7 @@ import { getSetupWithItems, updateSetup, } from "../../src/server/services/setup.service.ts"; -import { createSecondTestUser, createTestDb } from "../helpers/db.ts"; +import { createTestDb } from "../helpers/db.ts"; type Db = Awaited>["db"]; @@ -72,11 +72,11 @@ describe("Profile Service", () => { it("returns only public setups, not private ones", async () => { // Create one public and one private setup - const pub = await createSetup(db, userId, { + const _pub = await createSetup(db, userId, { name: "Public Setup", isPublic: true, }); - const priv = await createSetup(db, userId, { name: "Private Setup" }); + const _priv = await createSetup(db, userId, { name: "Private Setup" }); const profile = await getPublicProfile(db, userId); expect(profile).not.toBeNull(); diff --git a/tests/services/storage.service.test.ts b/tests/services/storage.service.test.ts index fd342ab..d7ef10a 100644 --- a/tests/services/storage.service.test.ts +++ b/tests/services/storage.service.test.ts @@ -1,4 +1,4 @@ -import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; +import { beforeEach, describe, expect, mock, test } from "bun:test"; // Mock the S3 client send method const mockSend = mock(() => Promise.resolve({})); diff --git a/tests/services/thread.service.test.ts b/tests/services/thread.service.test.ts index ca590a4..1bd2300 100644 --- a/tests/services/thread.service.test.ts +++ b/tests/services/thread.service.test.ts @@ -1,6 +1,5 @@ import { beforeEach, describe, expect, it } from "bun:test"; -import { globalItems, items } from "../../src/db/schema.ts"; -import { eq } from "drizzle-orm"; +import { globalItems } from "../../src/db/schema.ts"; import { createCandidate, createThread, @@ -629,10 +628,7 @@ describe("Thread Service", () => { imageUrl?: string; }, ) { - const [row] = await testDb - .insert(globalItems) - .values(data) - .returning(); + const [row] = await testDb.insert(globalItems).values(data).returning(); return row; }