Products: carry the IMVU parent's image and categories
CI / test (push) Successful in 49s

Revisions with an IMVU parent store its public info (image, category path, gender)
from IMVU's product API, looked up after registering and in a periodic pass.
Product views gain parent, image and categories; GET /products takes category and
limit. The website shows the image on cards and product pages.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
dhkatzandClaude Opus 5.5 committed 2026-10-30 01:03:02 -07:00
1 parent d57674d90c
commit 6668b55117
15 files changed
+2026 -29

No files matched your search

+1 -1
View File
@@ -11,7 +11,7 @@ import { fileURLToPath } from "node:url";
import * as schema from "./schema";
export { schema };
export type { FileEntry } from "./schema";
export type { FileEntry, ParentInfo } from "./schema";
export * from "drizzle-orm";
const migrationsFolder = fileURLToPath(new URL("../drizzle", import.meta.url));
+10
View File
@@ -226,6 +226,15 @@ export const audit = pgTable(
export type FileEntry = { name: string; sha256: string; size: number };
/** The public info of the IMVU product a revision derives from (IMVU's API), when it was looked up. */
export type ParentInfo = {
found: boolean; // false: IMVU shows no such product publicly
image: string | null; // https, on *.imvu.com
categories: { id: number; name: string }[]; // outermost first
gender: string; // "female", "male" or ""
checkedAt: string; // ISO time
};
// The hub's own signing keys (Ed25519) for the tokens catalogs and proxies check. The newest is used.
export const signingKey = pgTable("signing_key", {
id: text("id").primaryKey(), // the JWK's kid
@@ -283,6 +292,7 @@ export const productRevision = pgTable(
files: jsonb("files").$type<FileEntry[]>().notNull(),
rating: text("rating").notNull(),
parent: bigint("parent", { mode: "number" }).notNull().default(0), // the IMVU product it derives from
parentInfo: jsonb("parent_info").$type<ParentInfo>(), // null until looked up (parent > 0)
notes: text("notes").notNull().default(""),
token: text("token").notNull(), // the hub's t5de-revision token
uploadedBy: text("uploaded_by").references(() => user.id, { onDelete: "set null" }),