Add entry_id relationship links to Entries
- Introduce reusable EntryLink component - Use EntryLink in Releases and Label detail tables - Link both ID and title to /zxdb/entries/[id] for consistency Signed-off-by: Junie@MacOS
This commit is contained in:
@@ -20,6 +20,9 @@ import {
|
||||
availabletypes,
|
||||
currencies,
|
||||
roletypes,
|
||||
aliases,
|
||||
webrefs,
|
||||
websites,
|
||||
} from "@/server/schema/zxdb";
|
||||
|
||||
export interface SearchParams {
|
||||
@@ -219,6 +222,9 @@ export interface EntryDetail {
|
||||
year: number | null;
|
||||
}[];
|
||||
}[];
|
||||
// Additional relationships surfaced on the entry detail page
|
||||
aliases?: { releaseSeq: number; languageId: string; title: string }[];
|
||||
webrefs?: { link: string; languageId: string; website: { id: number; name: string; link?: string | null } }[];
|
||||
}
|
||||
|
||||
export async function getEntryById(id: number): Promise<EntryDetail | null> {
|
||||
@@ -411,6 +417,24 @@ export async function getEntryById(id: number): Promise<EntryDetail | null> {
|
||||
// Sort releases by sequence for stable UI order
|
||||
releasesData.sort((a, b) => a.releaseSeq - b.releaseSeq);
|
||||
|
||||
// Fetch extra relationships in parallel
|
||||
let aliasRows: { releaseSeq: number | string; languageId: string; title: string }[] = [];
|
||||
let webrefRows: { link: string; languageId: string; websiteId: number | string; websiteName: string; websiteLink: string | null }[] = [];
|
||||
try {
|
||||
aliasRows = await db
|
||||
.select({ releaseSeq: aliases.releaseSeq, languageId: aliases.languageId, title: aliases.title })
|
||||
.from(aliases)
|
||||
.where(eq(aliases.entryId, id));
|
||||
} catch {}
|
||||
try {
|
||||
const rows = await db
|
||||
.select({ link: webrefs.link, languageId: webrefs.languageId, websiteId: websites.id, websiteName: websites.name, websiteLink: websites.link })
|
||||
.from(webrefs)
|
||||
.innerJoin(websites, eq(websites.id, webrefs.websiteId))
|
||||
.where(eq(webrefs.entryId, id));
|
||||
webrefRows = rows as typeof webrefRows;
|
||||
} catch {}
|
||||
|
||||
return {
|
||||
id: base.id,
|
||||
title: base.title,
|
||||
@@ -453,6 +477,8 @@ export async function getEntryById(id: number): Promise<EntryDetail | null> {
|
||||
year: d.year != null ? Number(d.year) : null,
|
||||
releaseSeq: Number(d.releaseSeq),
|
||||
})),
|
||||
aliases: aliasRows.map((a) => ({ releaseSeq: Number(a.releaseSeq), languageId: a.languageId, title: a.title })),
|
||||
webrefs: webrefRows.map((w) => ({ link: w.link, languageId: w.languageId, website: { id: Number(w.websiteId), name: w.websiteName, link: w.websiteLink } })),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -143,6 +143,14 @@ export const hosts = mysqlTable("hosts", {
|
||||
magazineId: smallint("magazine_id"),
|
||||
});
|
||||
|
||||
// ---- Aliases (alternative titles per entry/release/language)
|
||||
export const aliases = mysqlTable("aliases", {
|
||||
entryId: int("entry_id").notNull(),
|
||||
releaseSeq: smallint("release_seq").notNull().default(0),
|
||||
languageId: char("language_id", { length: 2 }).notNull(),
|
||||
title: varchar("title", { length: 250 }).notNull(),
|
||||
});
|
||||
|
||||
// `releases` are identified by (entry_id, release_seq)
|
||||
export const releases = mysqlTable("releases", {
|
||||
entryId: int("entry_id").notNull(),
|
||||
@@ -184,6 +192,22 @@ export const downloads = mysqlTable("downloads", {
|
||||
comments: varchar("comments", { length: 250 }),
|
||||
});
|
||||
|
||||
// ---- Web references (external links tied to entries)
|
||||
export const webrefs = mysqlTable("webrefs", {
|
||||
entryId: int("entry_id").notNull(),
|
||||
link: varchar("link", { length: 200 }).notNull(),
|
||||
websiteId: tinyint("website_id").notNull(),
|
||||
languageId: char("language_id", { length: 2 }).notNull(),
|
||||
});
|
||||
|
||||
export const websites = mysqlTable("websites", {
|
||||
id: tinyint("id").notNull().primaryKey(),
|
||||
name: varchar("name", { length: 100 }).notNull(),
|
||||
comments: varchar("comments", { length: 100 }),
|
||||
link: varchar("link", { length: 100 }),
|
||||
linkMask: varchar("link_mask", { length: 100 }),
|
||||
});
|
||||
|
||||
// Roles relation (composite PK in DB)
|
||||
export const roles = mysqlTable("roles", {
|
||||
entryId: int("entry_id").notNull(),
|
||||
|
||||
Reference in New Issue
Block a user