feat: review and dismiss duplicate books

Adds the per-library review screen, a muted note in the upload tray for a book
that may already be held, and the remote functions behind them. The tray note
is deliberately weaker than the file-level one, which means something stronger.
This commit is contained in:
2026-08-15 21:55:20 -04:00
parent 5047277845
commit fc6b97bf38
8 changed files with 465 additions and 12 deletions
+22
View File
@@ -15,6 +15,27 @@ export type BookProgress = components['schemas']['BookProgressRead'];
export type DuplicateFile = components['schemas']['DuplicateFileRead'];
export type BooksUploadResult = components['schemas']['BooksUploadResult'];
/**
* A stored book that may be the same book as another one.
*
* Weaker than `DuplicateFile`, and deliberately so: that one means the library holds
* these exact bytes, this one means the metadata agrees. A second edition and a
* translation both look like this, so nothing is ever refused on the strength of it.
*/
export type DuplicateBook = components['schemas']['DuplicateBookRead'];
/** A book that was imported, together with what it might be a second copy of. */
export type PossibleDuplicate = components['schemas']['PossibleDuplicateRead'];
/** Books the library holds that all look like copies of one book. */
export type DuplicateBookGroup = components['schemas']['DuplicateBookGroupRead'];
/** Mirrors DuplicateDismissal in backend/src/chitai/schemas/book.py */
export const duplicateDismissalSchema = z.object({
book_a_id: z.coerce.number(),
book_b_id: z.coerce.number()
});
export const bookQuerySchema = commonQuerySchema.extend({
libraries: stringArrayCoerce,
authors: stringArrayCoerce,
@@ -106,4 +127,5 @@ export type BookQuery = z.infer<typeof bookQuerySchema>;
export type BookEditMetadata = z.infer<typeof editBookMetadataSchema>;
export type DeleteBook = z.infer<typeof deleteBooksSchema>;
export type DeleteBookFiles = z.infer<typeof deleteBookFilesSchema>;
export type DuplicateDismissal = z.infer<typeof duplicateDismissalSchema>;
export type UpdateBookProgress = z.infer<typeof updateBookProgressSchema>;