mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 00:11:37 -06:00
feat(hardcover): add per-book sync controls and book sync scope
Introduce a per-book sync toggle in the book detail view that lets users include or exclude individual books from Hardcover sync. Add a book sync scope setting with two modes: - all_eligible: sync all books unless explicitly excluded (default) - selected_only: sync only books the user explicitly includes Extract sync eligibility logic into hardcover-sync-policy.ts for testability. The toggle handles unread books correctly: sync is skipped while the book is unread, but the user's inclusion intent is stored so sync activates automatically once reading starts. Closes #412
This commit is contained in:
@@ -1,10 +1,20 @@
|
||||
export type HardcoverSyncDisabledReason = "permission_denied" | "missing_token" | "user_disabled";
|
||||
export type HardcoverBookSyncMode = "all_eligible" | "selected_only";
|
||||
export type HardcoverBookSyncOverride = "included" | "excluded" | null;
|
||||
export type HardcoverBookSyncEffectiveReason =
|
||||
| HardcoverSyncDisabledReason
|
||||
| "global_disabled"
|
||||
| "not_selected"
|
||||
| "excluded"
|
||||
| "unread"
|
||||
| "unsupported_status";
|
||||
|
||||
export interface HardcoverSettings {
|
||||
tokenConfigured: boolean;
|
||||
enabled: boolean;
|
||||
effectiveEnabled: boolean;
|
||||
disabledReason: HardcoverSyncDisabledReason | null;
|
||||
bookSyncMode: HardcoverBookSyncMode;
|
||||
autoSyncOnStatusChange: boolean;
|
||||
autoSyncOnProgressUpdate: boolean;
|
||||
autoSyncOnRatingChange: boolean;
|
||||
@@ -15,6 +25,7 @@ export interface HardcoverSettings {
|
||||
export interface UpsertHardcoverSettingsPayload {
|
||||
apiToken?: string;
|
||||
enabled?: boolean;
|
||||
bookSyncMode?: HardcoverBookSyncMode;
|
||||
autoSyncOnStatusChange?: boolean;
|
||||
autoSyncOnProgressUpdate?: boolean;
|
||||
autoSyncOnRatingChange?: boolean;
|
||||
@@ -33,6 +44,25 @@ export interface HardcoverSyncPendingSummary {
|
||||
pendingBooks: number;
|
||||
}
|
||||
|
||||
export interface HardcoverBookSyncState {
|
||||
bookId: number;
|
||||
syncOverride: HardcoverBookSyncOverride;
|
||||
syncEnabled: boolean;
|
||||
canSyncNow: boolean;
|
||||
effectiveReason: HardcoverBookSyncEffectiveReason | null;
|
||||
lastSyncedAt: string | null;
|
||||
syncError: string | null;
|
||||
}
|
||||
|
||||
export interface UpdateHardcoverBookSyncPayload {
|
||||
syncEnabled: boolean;
|
||||
}
|
||||
|
||||
export interface HardcoverBookSyncNowResult {
|
||||
result: "synced" | "skipped" | "failed";
|
||||
state: HardcoverBookSyncState;
|
||||
}
|
||||
|
||||
export interface HardcoverActiveSyncStatus {
|
||||
runId: number;
|
||||
syncedBooks: number;
|
||||
|
||||
Reference in New Issue
Block a user