reading: split the book tracker into books, papers and articles (kind column + migration classifying 20 papers), segmented tabs with counts, article cards that open the link, owner + add link with server-side unfurl, kind switch on detail pages, /trackers/reading alias
All checks were successful
Deploy production / deploy (push) Successful in 1m8s
All checks were successful
Deploy production / deploy (push) Successful in 1m8s
This commit is contained in:
@@ -34,10 +34,15 @@ export const bookReadingStatus = booksSchema.enum('reading_status', [
|
||||
'abandoned'
|
||||
]);
|
||||
|
||||
// What a work is: a book, a scientific paper, or a web article / link on the reading list.
|
||||
// Articles have no files; they live at `url` and are opened externally.
|
||||
export const bookKind = booksSchema.enum('kind', ['book', 'paper', 'article']);
|
||||
|
||||
export const bookWorks = booksSchema.table(
|
||||
'works',
|
||||
{
|
||||
id: id(),
|
||||
kind: bookKind('kind').notNull().default('book'),
|
||||
title: text('title').notNull(),
|
||||
subtitle: text('subtitle'),
|
||||
authors: text('authors').array().notNull().default([]),
|
||||
@@ -61,9 +66,18 @@ export const bookWorks = booksSchema.table(
|
||||
metadataSource: text('metadata_source'), // 'openlibrary' | 'googlebooks' | 'libgen' | 'manual'
|
||||
metadataFetchedAt: timestamptz('metadata_fetched_at'),
|
||||
notes: text('notes'),
|
||||
// Articles and papers on the web: canonical link, site name and publish date. The excerpt
|
||||
// goes in `description` and the og:image in `cover_url`.
|
||||
url: text('url'),
|
||||
siteName: text('site_name'),
|
||||
publishedAt: timestamptz('published_at'),
|
||||
...timestamps
|
||||
},
|
||||
(t) => [
|
||||
uniqueIndex('works_url_key')
|
||||
.on(t.url)
|
||||
.where(sql`${t.url} is not null`),
|
||||
index('works_kind_idx').on(t.kind),
|
||||
uniqueIndex('works_isbn13_key')
|
||||
.on(t.isbn13)
|
||||
.where(sql`${t.isbn13} is not null`),
|
||||
@@ -206,4 +220,5 @@ export type BookShelf = typeof bookShelves.$inferSelect;
|
||||
export type BookProgress = typeof bookProgress.$inferSelect;
|
||||
export type BookNote = typeof bookNotes.$inferSelect;
|
||||
export type BookSession = typeof bookSessions.$inferSelect;
|
||||
export type BookKind = (typeof bookKind.enumValues)[number];
|
||||
export type BookReadingStatus = (typeof bookReadingStatus.enumValues)[number];
|
||||
|
||||
Reference in New Issue
Block a user