feat(10-01): add pros/cons columns through backend

- Add pros/cons nullable TEXT columns to threadCandidates schema
- Generate and apply Drizzle migration (0004_soft_synch.sql)
- Mirror pros/cons columns in test helper CREATE TABLE
- createCandidate: pass pros/cons to values() object
- updateCandidate: add pros/cons to Partial type
- getThreadWithCandidates: include pros/cons in select projection
- createCandidateSchema: add optional pros/cons string fields
This commit is contained in:
2026-03-16 21:32:38 +01:00
parent 719f7082da
commit 7a64a1887d
4 changed files with 12 additions and 0 deletions

View File

@@ -59,6 +59,8 @@ export const threadCandidates = sqliteTable("thread_candidates", {
productUrl: text("product_url"), productUrl: text("product_url"),
imageFilename: text("image_filename"), imageFilename: text("image_filename"),
status: text("status").notNull().default("researching"), status: text("status").notNull().default("researching"),
pros: text("pros"),
cons: text("cons"),
createdAt: integer("created_at", { mode: "timestamp" }) createdAt: integer("created_at", { mode: "timestamp" })
.notNull() .notNull()
.$defaultFn(() => new Date()), .$defaultFn(() => new Date()),

View File

@@ -73,6 +73,8 @@ export function getThreadWithCandidates(db: Db = prodDb, threadId: number) {
productUrl: threadCandidates.productUrl, productUrl: threadCandidates.productUrl,
imageFilename: threadCandidates.imageFilename, imageFilename: threadCandidates.imageFilename,
status: threadCandidates.status, status: threadCandidates.status,
pros: threadCandidates.pros,
cons: threadCandidates.cons,
createdAt: threadCandidates.createdAt, createdAt: threadCandidates.createdAt,
updatedAt: threadCandidates.updatedAt, updatedAt: threadCandidates.updatedAt,
categoryName: categories.name, categoryName: categories.name,
@@ -151,6 +153,8 @@ export function createCandidate(
productUrl: data.productUrl ?? null, productUrl: data.productUrl ?? null,
imageFilename: data.imageFilename ?? null, imageFilename: data.imageFilename ?? null,
status: data.status ?? "researching", status: data.status ?? "researching",
pros: data.pros ?? null,
cons: data.cons ?? null,
}) })
.returning() .returning()
.get(); .get();
@@ -168,6 +172,8 @@ export function updateCandidate(
productUrl: string; productUrl: string;
imageFilename: string; imageFilename: string;
status: "researching" | "ordered" | "arrived"; status: "researching" | "ordered" | "arrived";
pros: string;
cons: string;
}>, }>,
) { ) {
const existing = db const existing = db

View File

@@ -53,6 +53,8 @@ export const createCandidateSchema = z.object({
productUrl: z.string().url().optional().or(z.literal("")), productUrl: z.string().url().optional().or(z.literal("")),
imageFilename: z.string().optional(), imageFilename: z.string().optional(),
status: candidateStatusSchema.optional(), status: candidateStatusSchema.optional(),
pros: z.string().optional(),
cons: z.string().optional(),
}); });
export const updateCandidateSchema = createCandidateSchema.partial(); export const updateCandidateSchema = createCandidateSchema.partial();

View File

@@ -55,6 +55,8 @@ export function createTestDb() {
product_url TEXT, product_url TEXT,
image_filename TEXT, image_filename TEXT,
status TEXT NOT NULL DEFAULT 'researching', status TEXT NOT NULL DEFAULT 'researching',
pros TEXT,
cons TEXT,
created_at INTEGER NOT NULL DEFAULT (unixepoch()), created_at INTEGER NOT NULL DEFAULT (unixepoch()),
updated_at INTEGER NOT NULL DEFAULT (unixepoch()) updated_at INTEGER NOT NULL DEFAULT (unixepoch())
) )