A personal media tracker built on the AT Protocol opnshelf.xyz
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add account deletion background jobs

Replace the dedicated Trakt import job table with a shared
background job model and worker.

Queue PDS-backed account deletions, expose deletion status
polling in the API, and surface progress/failure states in
web and mobile settings.

+3121 -3064
+6 -2
apps/mobile/app/auth/complete.tsx
··· 2 2 import { useQueryClient } from "@tanstack/react-query"; 3 3 import { useLocalSearchParams, useRouter } from "expo-router"; 4 4 import { usePostHog } from "posthog-react-native"; 5 - import { useEffect } from "react"; 5 + import { useEffect, useRef } from "react"; 6 6 import { ActivityIndicator, Image, Text, View } from "react-native"; 7 7 import { useToast } from "@/contexts/toast"; 8 8 import { saveSessionToken } from "@/lib/api"; ··· 14 14 const { session } = params; 15 15 const { showToast } = useToast(); 16 16 const posthog = usePostHog(); 17 + 18 + const hasStarted = useRef(false); 17 19 18 20 useEffect(() => { 21 + if (hasStarted.current) return; 22 + hasStarted.current = true; 23 + 19 24 async function completeAuth() { 20 25 try { 21 26 if (session) { ··· 27 32 staleTime: 0, 28 33 }); 29 34 30 - // Identify the user in PostHog after successful login 31 35 if (user) { 32 36 posthog.identify(user.did, { 33 37 $set: {
+1 -1
apps/mobile/app/login.tsx
··· 64 64 const completeAuthSession = async (authUrl: string) => { 65 65 const result = await WebBrowser.openAuthSessionAsync( 66 66 authUrl, 67 - "opnshelf://auth/callback", 67 + "opnshelf://auth/complete", 68 68 ); 69 69 70 70 if (result.type !== "success") {
+4 -1
apps/mobile/app/onboarding.tsx
··· 40 40 createAvatarUploadFile, 41 41 getAvatarUploadErrorMessage, 42 42 type ReactNativeUploadFile, 43 + reactNativeFileFormData, 43 44 toMultipartUploadValue, 44 45 validateAvatarAsset, 45 46 } from "@/lib/avatar-upload"; ··· 164 165 }); 165 166 const uploadAvatarMutation = useMutation({ 166 167 mutationKey: ["users", "profile", "avatar", "upload"], 167 - ...usersControllerUploadMyAvatarMutation(), 168 + ...usersControllerUploadMyAvatarMutation({ 169 + bodySerializer: reactNativeFileFormData, 170 + }), 168 171 onError: (error) => { 169 172 setAvatarErrorMessage( 170 173 getAvatarUploadErrorMessage(error, "Could not upload profile photo"),
+61 -2
apps/mobile/app/settings.tsx
··· 1 1 import { 2 + type AccountDeletionJobDto, 2 3 authControllerMeOptions, 4 + isActiveAccountDeletionStatus, 3 5 usersControllerDeleteMyAccountMutation, 4 6 usersControllerDeleteMyAvatarMutation, 7 + usersControllerGetMyAccountDeletionOptions, 5 8 usersControllerGetMySettingsOptions, 6 9 usersControllerGetPublicProfileOptions, 7 10 usersControllerUpdateMyProfileMutation, ··· 30 33 createAvatarUploadFile, 31 34 getAvatarUploadErrorMessage, 32 35 type ReactNativeUploadFile, 36 + reactNativeFileFormData, 33 37 toMultipartUploadValue, 34 38 validateAvatarAsset, 35 39 } from "@/lib/avatar-upload"; ··· 63 67 64 68 const [showTimezoneModal, setShowTimezoneModal] = useState(false); 65 69 const [showDeleteModal, setShowDeleteModal] = useState(false); 70 + const [deletionJobId, setDeletionJobId] = useState<string | null>(null); 66 71 const [timezone, setTimezone] = useState<string>("UTC"); 67 72 const [is24Hour, setIs24Hour] = useState<boolean>(true); 68 73 const [displayName, setDisplayName] = useState(""); ··· 111 116 }, 112 117 }); 113 118 119 + const deletionJobQuery = useQuery({ 120 + ...usersControllerGetMyAccountDeletionOptions(), 121 + enabled: !!deletionJobId, 122 + refetchInterval: (query) => { 123 + const job = query.state.data; 124 + if (!job || !isActiveAccountDeletionStatus(job.status)) { 125 + return false; 126 + } 127 + return 2_000; 128 + }, 129 + }); 130 + 131 + const handleDeletionComplete = useCallback(async () => { 132 + if (user?.did) { 133 + await clearDismissedTraktImportJobIds(user.did); 134 + } 135 + showToast("Account deleted", "success"); 136 + posthog.capture("account_deleted", { deleted_pds_data: true }); 137 + posthog.reset(); 138 + setShowDeleteModal(false); 139 + setDeletionJobId(null); 140 + await logout(); 141 + router.replace("/"); 142 + }, [user?.did, showToast, posthog, logout, router]); 143 + 144 + useEffect(() => { 145 + const job = deletionJobQuery.data; 146 + if (job?.status === "completed") { 147 + void handleDeletionComplete(); 148 + } 149 + }, [ 150 + deletionJobQuery.data?.status, 151 + handleDeletionComplete, 152 + deletionJobQuery.data, 153 + ]); 154 + 155 + useEffect(() => { 156 + if (deletionJobQuery.error && deletionJobId) { 157 + void handleDeletionComplete(); 158 + } 159 + }, [deletionJobQuery.error, deletionJobId, handleDeletionComplete]); 160 + 114 161 const deleteAccountMutation = useMutation({ 115 162 mutationKey: ["users", "account", "delete"], 116 163 ...usersControllerDeleteMyAccountMutation(), 117 - onSuccess: async (_, variables) => { 164 + onSuccess: async (data, variables) => { 165 + const job = data as AccountDeletionJobDto | undefined; 166 + if (job?.id) { 167 + setDeletionJobId(job.id); 168 + return; 169 + } 170 + 118 171 if (user?.did) { 119 172 await clearDismissedTraktImportJobIds(user.did); 120 173 } ··· 146 199 147 200 const uploadAvatarMutation = useMutation({ 148 201 mutationKey: ["users", "profile", "avatar", "upload"], 149 - ...usersControllerUploadMyAvatarMutation(), 202 + ...usersControllerUploadMyAvatarMutation({ 203 + bodySerializer: reactNativeFileFormData, 204 + }), 150 205 onSuccess: async (updatedProfile) => { 151 206 setSelectedAvatarFile(null); 152 207 setAvatarErrorMessage(null); ··· 370 425 <DeleteAccountModal 371 426 visible={showDeleteModal} 372 427 isDeleting={deleteAccountMutation.isPending} 428 + deletionJob={deletionJobQuery.data} 373 429 onClose={() => setShowDeleteModal(false)} 374 430 onConfirm={handleConfirmDelete} 431 + onRetry={() => { 432 + setDeletionJobId(null); 433 + }} 375 434 /> 376 435 </SafeAreaView> 377 436 );
+205 -68
apps/mobile/components/settings/DeleteAccountModal.tsx
··· 1 - import { Trash2 } from "lucide-react-native"; 1 + import { 2 + getAccountDeletionProgress, 3 + getAccountDeletionStepLabel, 4 + type AccountDeletionJobDto, 5 + } from "@opnshelf/api"; 6 + import { Loader2, Trash2 } from "lucide-react-native"; 2 7 import { useEffect, useMemo, useState } from "react"; 3 8 import { Modal, StyleSheet, Text, View } from "react-native"; 4 9 import { Button } from "@/components/ui/Button"; ··· 10 15 interface DeleteAccountModalProps { 11 16 visible: boolean; 12 17 isDeleting: boolean; 18 + deletionJob: AccountDeletionJobDto | null | undefined; 13 19 onClose: () => void; 14 20 onConfirm: (deletePDSData: boolean) => void; 21 + onRetry: () => void; 15 22 } 16 23 17 24 export function DeleteAccountModal({ 18 25 visible, 19 26 isDeleting, 27 + deletionJob, 20 28 onClose, 21 29 onConfirm, 30 + onRetry, 22 31 }: DeleteAccountModalProps) { 23 32 const { colors } = useTheme(); 24 33 const styles = useMemo(() => createStyles(colors), [colors]); 25 34 const [deletePDSData, setDeletePDSData] = useState(false); 26 35 36 + const isInProgress = 37 + deletionJob?.status === "queued" || deletionJob?.status === "running"; 38 + const isFailed = deletionJob?.status === "failed"; 39 + 27 40 useEffect(() => { 28 - if (visible) { 41 + if (visible && !isInProgress && !isFailed) { 29 42 setDeletePDSData(false); 30 43 } 31 - }, [visible]); 44 + }, [visible, isInProgress, isFailed]); 45 + 46 + const progress = deletionJob 47 + ? getAccountDeletionProgress(deletionJob) 48 + : null; 49 + const stepLabel = deletionJob 50 + ? getAccountDeletionStepLabel(deletionJob.currentStep) 51 + : "Preparing…"; 32 52 33 53 return ( 34 54 <Modal 35 55 visible={visible} 36 56 animationType="fade" 37 57 transparent 38 - onRequestClose={onClose} 58 + onRequestClose={isInProgress ? undefined : onClose} 39 59 > 40 60 <View style={styles.modalOverlay}> 41 61 <View style={styles.deleteModalContent}> 42 - <View style={styles.deleteModalIcon}> 43 - <Trash2 size={32} color={colors.error} /> 44 - </View> 45 - <Text style={styles.deleteModalTitle}>Delete Account</Text> 46 - <Text style={styles.deleteModalDescription}> 47 - Are you sure you want to delete your account? This action cannot be 48 - undone. 49 - </Text> 50 - 51 - <View style={styles.deleteDataBox}> 52 - <Text style={styles.deleteDataBoxTitle}>What happens to your data:</Text> 53 - <View style={styles.deleteDataItem}> 54 - <Text style={styles.deleteDataCheck}>✓</Text> 55 - <Text style={styles.deleteDataText}> 56 - Your OpnShelf account and settings will be deleted 62 + {isInProgress || isFailed ? ( 63 + <> 64 + <View style={styles.deleteModalIcon}> 65 + {isFailed ? ( 66 + <Trash2 size={32} color={colors.error} /> 67 + ) : ( 68 + <Loader2 size={32} color={colors.primary} /> 69 + )} 70 + </View> 71 + <Text style={styles.deleteModalTitle}> 72 + {isFailed ? "Deletion Failed" : "Deleting Account…"} 57 73 </Text> 58 - </View> 59 - <View style={styles.deleteDataItem}> 60 - <Text style={styles.deleteDataCheck}>✓</Text> 61 - <Text style={styles.deleteDataText}>Your local session will be cleared</Text> 62 - </View> 63 - </View> 74 + <Text style={styles.deleteModalDescription}> 75 + {isFailed 76 + ? "Something went wrong while deleting your account." 77 + : "Please keep the app open. Your data is being removed."} 78 + </Text> 64 79 65 - <View style={styles.pdsSwitchRow}> 66 - <Text style={styles.pdsSwitchLabel}> 67 - Also delete my OpnShelf data from my PDS 68 - </Text> 69 - <Switch 70 - value={deletePDSData} 71 - onValueChange={setDeletePDSData} 72 - disabled={isDeleting} 73 - /> 74 - </View> 80 + {!isFailed && ( 81 + <View style={styles.progressContainer}> 82 + <View style={styles.progressLabelRow}> 83 + <Text style={styles.progressLabel}>{stepLabel}</Text> 84 + {progress !== null && ( 85 + <Text style={styles.progressPercent}> 86 + {progress}% 87 + </Text> 88 + )} 89 + </View> 90 + <View style={styles.progressBarBg}> 91 + <View 92 + style={[ 93 + styles.progressBarFill, 94 + { 95 + width: `${progress ?? 0}%`, 96 + backgroundColor: colors.primary, 97 + }, 98 + ]} 99 + /> 100 + </View> 101 + {deletionJob && deletionJob.totalRecords > 0 && ( 102 + <Text style={styles.progressDetail}> 103 + {deletionJob.deletedRecords} of{" "} 104 + {deletionJob.totalRecords} records deleted 105 + </Text> 106 + )} 107 + </View> 108 + )} 75 109 76 - {deletePDSData ? ( 77 - <View style={styles.deleteWarningBox}> 78 - <Text style={styles.deleteWarningText}> 79 - Your OpnShelf data, including watch history, follows, lists, 80 - and list items, will be permanently deleted from your personal 81 - data server. This cannot be recovered. 82 - </Text> 83 - </View> 110 + {isFailed && ( 111 + <> 112 + <View style={styles.deleteWarningBox}> 113 + <Text style={styles.deleteWarningText}> 114 + {deletionJob?.lastError ?? 115 + "Account deletion failed. Please try again or contact support."} 116 + </Text> 117 + </View> 118 + <View style={styles.deleteModalButtons}> 119 + <Button 120 + variant="outlined" 121 + onPress={onClose} 122 + style={styles.deleteModalButton} 123 + > 124 + <Text style={styles.deleteModalButtonText}>Close</Text> 125 + </Button> 126 + <Button 127 + variant="filled" 128 + onPress={onRetry} 129 + style={styles.deleteModalButton} 130 + > 131 + Retry 132 + </Button> 133 + </View> 134 + </> 135 + )} 136 + </> 84 137 ) : ( 85 - <View style={styles.deleteInfoBox}> 86 - <Text style={styles.deleteInfoText}> 87 - Your OpnShelf data will remain on your PDS. You can use another 88 - app or re-authorize OpnShelf later to access it. 138 + <> 139 + <View style={styles.deleteModalIcon}> 140 + <Trash2 size={32} color={colors.error} /> 141 + </View> 142 + <Text style={styles.deleteModalTitle}>Delete Account</Text> 143 + <Text style={styles.deleteModalDescription}> 144 + Are you sure you want to delete your account? This action 145 + cannot be undone. 89 146 </Text> 90 - </View> 91 - )} 92 147 93 - <View style={styles.deleteModalButtons}> 94 - <Button 95 - variant="outlined" 96 - onPress={onClose} 97 - disabled={isDeleting} 98 - style={styles.deleteModalButton} 99 - > 100 - <Text style={styles.deleteModalButtonText}>Cancel</Text> 101 - </Button> 102 - <Button 103 - variant="filled" 104 - onPress={() => onConfirm(deletePDSData)} 105 - isLoading={isDeleting} 106 - disabled={isDeleting} 107 - style={styles.deleteModalButton} 108 - > 109 - Delete Account 110 - </Button> 111 - </View> 148 + <View style={styles.deleteDataBox}> 149 + <Text style={styles.deleteDataBoxTitle}> 150 + What happens to your data: 151 + </Text> 152 + <View style={styles.deleteDataItem}> 153 + <Text style={styles.deleteDataCheck}>✓</Text> 154 + <Text style={styles.deleteDataText}> 155 + Your OpnShelf account and settings will be deleted 156 + </Text> 157 + </View> 158 + <View style={styles.deleteDataItem}> 159 + <Text style={styles.deleteDataCheck}>✓</Text> 160 + <Text style={styles.deleteDataText}> 161 + Your local session will be cleared 162 + </Text> 163 + </View> 164 + </View> 165 + 166 + <View style={styles.pdsSwitchRow}> 167 + <Text style={styles.pdsSwitchLabel}> 168 + Also delete my OpnShelf data from my PDS 169 + </Text> 170 + <Switch 171 + value={deletePDSData} 172 + onValueChange={setDeletePDSData} 173 + disabled={isDeleting} 174 + /> 175 + </View> 176 + 177 + {deletePDSData ? ( 178 + <View style={styles.deleteWarningBox}> 179 + <Text style={styles.deleteWarningText}> 180 + Your OpnShelf data, including watch history, follows, lists, 181 + and list items, will be permanently deleted from your 182 + personal data server. This cannot be recovered. 183 + </Text> 184 + </View> 185 + ) : ( 186 + <View style={styles.deleteInfoBox}> 187 + <Text style={styles.deleteInfoText}> 188 + Your OpnShelf data will remain on your PDS. You can use 189 + another app or re-authorize OpnShelf later to access it. 190 + </Text> 191 + </View> 192 + )} 193 + 194 + <View style={styles.deleteModalButtons}> 195 + <Button 196 + variant="outlined" 197 + onPress={onClose} 198 + disabled={isDeleting} 199 + style={styles.deleteModalButton} 200 + > 201 + <Text style={styles.deleteModalButtonText}>Cancel</Text> 202 + </Button> 203 + <Button 204 + variant="filled" 205 + onPress={() => onConfirm(deletePDSData)} 206 + isLoading={isDeleting} 207 + disabled={isDeleting} 208 + style={styles.deleteModalButton} 209 + > 210 + Delete Account 211 + </Button> 212 + </View> 213 + </> 214 + )} 112 215 </View> 113 216 </View> 114 217 </Modal> ··· 239 342 color: colors.text, 240 343 fontSize: 14, 241 344 fontWeight: "500", 345 + }, 346 + progressContainer: { 347 + width: "100%", 348 + marginBottom: spacing.md, 349 + gap: spacing.xs, 350 + }, 351 + progressLabelRow: { 352 + flexDirection: "row", 353 + justifyContent: "space-between", 354 + alignItems: "center", 355 + }, 356 + progressLabel: { 357 + fontSize: 13, 358 + color: colors.textMuted, 359 + }, 360 + progressPercent: { 361 + fontSize: 13, 362 + fontWeight: "600", 363 + fontVariant: ["tabular-nums"], 364 + color: colors.primary, 365 + }, 366 + progressBarBg: { 367 + height: 6, 368 + borderRadius: 3, 369 + backgroundColor: `${colors.primary}20`, 370 + overflow: "hidden", 371 + }, 372 + progressBarFill: { 373 + height: "100%", 374 + borderRadius: 3, 375 + }, 376 + progressDetail: { 377 + fontSize: 12, 378 + color: colors.textMuted, 242 379 }, 243 380 });
+24 -24
apps/mobile/components/ui/m3/M3Snackbar.tsx
··· 24 24 25 25 function SnackbarItemComponent({ item, onDismiss }: { item: SnackbarItem; onDismiss: () => void }) { 26 26 const { colors } = useTheme(); 27 - const slideAnim = useRef(new Animated.Value(100)).current; 27 + const slideAnim = useRef(new Animated.Value(-100)).current; 28 28 const opacityAnim = useRef(new Animated.Value(0)).current; 29 29 const panAnim = useRef(new Animated.Value(0)).current; 30 30 ··· 53 53 const panResponder = useRef( 54 54 PanResponder.create({ 55 55 onStartShouldSetPanResponder: () => true, 56 - onPanResponderMove: (_, gestureState) => { 57 - if (gestureState.dy > 0) { 58 - panAnim.setValue(gestureState.dy); 59 - } 60 - }, 61 - onPanResponderRelease: (_, gestureState) => { 62 - if (gestureState.dy > 50) { 63 - Animated.timing(panAnim, { 64 - toValue: 200, 56 + onPanResponderMove: (_, gestureState) => { 57 + if (gestureState.dy < 0) { 58 + panAnim.setValue(gestureState.dy); 59 + } 60 + }, 61 + onPanResponderRelease: (_, gestureState) => { 62 + if (gestureState.dy < -50) { 63 + Animated.timing(panAnim, { 64 + toValue: -200, 65 65 duration: 150, 66 66 useNativeDriver: false, 67 67 }).start(onDismiss); ··· 94 94 useEffect(() => { 95 95 const timer = setTimeout(() => { 96 96 Animated.parallel([ 97 - Animated.timing(slideAnim, { 98 - toValue: 100, 99 - duration: 200, 100 - useNativeDriver: false, 101 - }), 102 - Animated.timing(opacityAnim, { 103 - toValue: 0, 104 - duration: 200, 105 - useNativeDriver: false, 106 - }), 107 - ]).start(onDismiss); 97 + Animated.timing(slideAnim, { 98 + toValue: -100, 99 + duration: 200, 100 + useNativeDriver: false, 101 + }), 102 + Animated.timing(opacityAnim, { 103 + toValue: 0, 104 + duration: 200, 105 + useNativeDriver: false, 106 + }), 107 + ]).start(onDismiss); 108 108 }, 4000); 109 109 return () => clearTimeout(timer); 110 110 }, [onDismiss, slideAnim, opacityAnim]); ··· 152 152 <SnackbarContext.Provider value={{ showSnackbar }}> 153 153 {children} 154 154 <View 155 - style={[styles.container, { bottom: insets.bottom + 16 }]} 155 + style={[styles.container, { top: insets.top + 16 }]} 156 156 pointerEvents="box-none" 157 157 > 158 158 {snackbars.map((snackbar) => ( ··· 189 189 alignItems: "center", 190 190 paddingHorizontal: 16, 191 191 paddingVertical: 14, 192 - marginBottom: 8, 192 + marginTop: 8, 193 193 borderRadius: m3BorderRadius.extraSmall, 194 - minWidth: SCREEN_WIDTH * 0.8, 194 + minWidth: SCREEN_WIDTH * 0.92, 195 195 maxWidth: SCREEN_WIDTH - 32, 196 196 shadowColor: "#000", 197 197 shadowOffset: { width: 0, height: 3 },
+1 -1
apps/mobile/contexts/auth.tsx
··· 92 92 const loginUrl = getLoginUrl(handle, undefined, "mobile"); 93 93 const result = await WebBrowser.openAuthSessionAsync( 94 94 loginUrl, 95 - "opnshelf://auth/callback" 95 + "opnshelf://auth/complete" 96 96 ); 97 97 98 98 if (result.type === "success") {
+33
apps/mobile/lib/avatar-upload.ts
··· 65 65 return file as unknown as Blob; 66 66 } 67 67 68 + function isReactNativeFile(value: unknown): value is ReactNativeUploadFile { 69 + return ( 70 + typeof value === "object" && 71 + value !== null && 72 + "uri" in value && 73 + "name" in value && 74 + "type" in value && 75 + typeof (value as Record<string, unknown>).uri === "string" 76 + ); 77 + } 78 + 79 + /** 80 + * Body serializer that handles React Native file objects ({ uri, name, type }) 81 + * which RN's FormData accepts natively but the generated serializer misses 82 + * because they aren't Blob instances. 83 + */ 84 + export const reactNativeFileFormData = ( 85 + body: Record<string, unknown>, 86 + ): FormData => { 87 + const data = new FormData(); 88 + for (const [key, value] of Object.entries(body)) { 89 + if (value === undefined || value === null) continue; 90 + if (isReactNativeFile(value) || value instanceof Blob) { 91 + data.append(key, value as unknown as Blob); 92 + } else if (typeof value === "string") { 93 + data.append(key, value); 94 + } else { 95 + data.append(key, JSON.stringify(value)); 96 + } 97 + } 98 + return data; 99 + }; 100 + 68 101 export function getAvatarUploadErrorMessage( 69 102 error: unknown, 70 103 fallback: string,
+3 -2
apps/mobile/lib/trakt-import-dismissal.ts
··· 1 1 import * as SecureStore from "expo-secure-store"; 2 2 3 - const STORAGE_KEY_PREFIX = "opnshelf_trakt_import_dismissed_jobs:"; 3 + const STORAGE_KEY_PREFIX = "opnshelf_trakt_import_dismissed_jobs."; 4 4 const MAX_STORED_JOB_IDS = 25; 5 5 6 6 function getStorageKey(userDid: string): string { 7 - return `${STORAGE_KEY_PREFIX}${userDid}`; 7 + const sanitized = userDid.replace(/[^a-zA-Z0-9._-]/g, "_"); 8 + return `${STORAGE_KEY_PREFIX}${sanitized}`; 8 9 } 9 10 10 11 function parseStoredJobIds(rawValue: string | null): string[] {
+299 -101
apps/web/src/routes/profile.$handle.settings.tsx
··· 1 1 import { 2 + type AccountDeletionJobDto, 2 3 authControllerMeOptions, 3 4 authControllerMeQueryKey, 5 + getAccountDeletionProgress, 6 + getAccountDeletionStepLabel, 7 + isActiveAccountDeletionStatus, 4 8 usersControllerDeleteMyAccountMutation, 5 9 usersControllerDeleteMyAvatarMutation, 10 + usersControllerGetMyAccountDeletionOptions, 6 11 usersControllerGetMySettingsOptions, 7 12 usersControllerGetPublicProfileOptions, 8 13 usersControllerUpdateMyProfileMutation, ··· 22 27 Trash2, 23 28 User, 24 29 } from "lucide-react"; 25 - import { type ChangeEvent, useEffect, useId, useRef, useState } from "react"; 30 + import { 31 + type ChangeEvent, 32 + useCallback, 33 + useEffect, 34 + useId, 35 + useRef, 36 + useState, 37 + } from "react"; 26 38 import { toast } from "sonner"; 27 39 import { AuthLoadingState } from "@/components/AuthLoadingState"; 28 40 import { useTheme } from "@/components/theme-provider"; ··· 35 47 DialogTitle, 36 48 } from "@/components/ui/dialog"; 37 49 import { Label } from "@/components/ui/label"; 38 - import { LoadingButton } from "@/components/ui/loading-button"; 39 50 import { M3Button } from "@/components/ui/m3-button"; 40 51 import { 41 52 M3Card, ··· 142 153 const [is24Hour, setIs24Hour] = useState<boolean>(true); 143 154 const [showDeleteDialog, setShowDeleteDialog] = useState(false); 144 155 const [deletePDSData, setDeletePDSData] = useState(false); 156 + const [deletionJobId, setDeletionJobId] = useState<string | null>(null); 145 157 const [displayName, setDisplayName] = useState(""); 146 158 const [selectedAvatarFile, setSelectedAvatarFile] = useState<File | null>( 147 159 null, ··· 189 201 }, 190 202 }); 191 203 204 + const deletionJobQuery = useQuery({ 205 + ...usersControllerGetMyAccountDeletionOptions(), 206 + enabled: !!deletionJobId, 207 + refetchInterval: (query) => { 208 + const job = query.state.data; 209 + if (!job || !isActiveAccountDeletionStatus(job.status)) { 210 + return false; 211 + } 212 + return 2_000; 213 + }, 214 + }); 215 + 216 + const handleDeletionComplete = useCallback(async () => { 217 + if (user?.did) { 218 + clearDismissedTraktImportJobIds(user.did); 219 + } 220 + posthog.capture("account_deleted", { deleted_pds_data: true }); 221 + posthog.reset(); 222 + setShowDeleteDialog(false); 223 + setDeletionJobId(null); 224 + toast.success("Account deleted"); 225 + await publishSignedOutAuthState(queryClient); 226 + router.navigate({ to: "/" }); 227 + }, [user?.did, posthog, queryClient, router]); 228 + 229 + useEffect(() => { 230 + const job = deletionJobQuery.data; 231 + if (!job) { 232 + return; 233 + } 234 + 235 + if (job.status === "completed") { 236 + handleDeletionComplete(); 237 + } 238 + }, [ 239 + deletionJobQuery.data?.status, 240 + deletionJobQuery.data, 241 + handleDeletionComplete, 242 + ]); 243 + 244 + useEffect(() => { 245 + if (deletionJobQuery.error && deletionJobId) { 246 + handleDeletionComplete(); 247 + } 248 + }, [deletionJobQuery.error, deletionJobId, handleDeletionComplete]); 249 + 192 250 const deleteAccountMutation = useMutation({ 193 251 mutationKey: ["users", "account", "delete"], 194 252 ...usersControllerDeleteMyAccountMutation(), 195 - onSuccess: async () => { 253 + onSuccess: async (data) => { 254 + const job = data as AccountDeletionJobDto | undefined; 255 + if (job?.id) { 256 + setDeletionJobId(job.id); 257 + return; 258 + } 259 + 196 260 if (user?.did) { 197 261 clearDismissedTraktImportJobIds(user.did); 198 262 } 199 263 posthog.capture("account_deleted", { 200 - deleted_pds_data: deletePDSData, 264 + deleted_pds_data: false, 201 265 }); 202 266 posthog.reset(); 203 267 setShowDeleteDialog(false); ··· 685 749 </M3Card> 686 750 687 751 {/* Delete Account Dialog */} 688 - <Dialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}> 689 - <DialogContent className="bg-(--md-sys-color-surface-container) border-(--md-sys-color-outline)"> 690 - <DialogHeader> 691 - <DialogTitle className="flex items-center gap-2 text-(--md-sys-color-on-surface)"> 692 - <AlertTriangle className="w-5 h-5 text-(--md-sys-color-error)" /> 693 - Delete Account 694 - </DialogTitle> 695 - <DialogDescription className="text-(--md-sys-color-on-surface-variant)"> 696 - Are you sure you want to delete your account? This action cannot 697 - be undone. 698 - </DialogDescription> 699 - </DialogHeader> 700 - 701 - <div className="space-y-4 py-4"> 702 - <div 703 - className="p-4 rounded-lg border" 704 - style={{ 705 - backgroundColor: "var(--md-sys-color-surface-container-lowest)", 706 - borderColor: "var(--md-sys-color-outline-variant)", 752 + <Dialog 753 + open={showDeleteDialog} 754 + onOpenChange={deletionJobId ? undefined : setShowDeleteDialog} 755 + > 756 + <DialogContent 757 + className="bg-(--md-sys-color-surface-container) border-(--md-sys-color-outline)" 758 + onInteractOutside={ 759 + deletionJobId ? (e) => e.preventDefault() : undefined 760 + } 761 + > 762 + {deletionJobId ? ( 763 + <DeletionProgressView 764 + job={deletionJobQuery.data} 765 + error={ 766 + deletionJobQuery.data?.status === "failed" 767 + ? deletionJobQuery.data.lastError 768 + : undefined 769 + } 770 + onRetry={() => { 771 + setDeletionJobId(null); 772 + setDeletePDSData(true); 707 773 }} 708 - > 709 - <p className="md-body-medium text-(--md-sys-color-on-surface-variant) mb-3"> 710 - What happens to your data: 774 + seedColor={seedColor} 775 + /> 776 + ) : ( 777 + <> 778 + <DialogHeader> 779 + <DialogTitle className="flex items-center gap-2 text-(--md-sys-color-on-surface)"> 780 + <AlertTriangle className="w-5 h-5 text-(--md-sys-color-error)" /> 781 + Delete Account 782 + </DialogTitle> 783 + <DialogDescription className="text-(--md-sys-color-on-surface-variant)"> 784 + Are you sure you want to delete your account? This action 785 + cannot be undone. 786 + </DialogDescription> 787 + </DialogHeader> 788 + 789 + <div className="space-y-4 py-4"> 790 + <div 791 + className="p-4 rounded-lg border" 792 + style={{ 793 + backgroundColor: 794 + "var(--md-sys-color-surface-container-lowest)", 795 + borderColor: "var(--md-sys-color-outline-variant)", 796 + }} 797 + > 798 + <p className="md-body-medium text-(--md-sys-color-on-surface-variant) mb-3"> 799 + What happens to your data: 800 + </p> 801 + <div className="space-y-2 text-sm"> 802 + <p className="flex items-start gap-2 text-(--md-sys-color-on-surface)"> 803 + <span style={{ color: seedColor }}>✓</span> 804 + Your OpnShelf account and settings will be deleted 805 + </p> 806 + <p className="flex items-start gap-2 text-(--md-sys-color-on-surface)"> 807 + <span style={{ color: seedColor }}>✓</span> 808 + Your local session will be cleared 809 + </p> 810 + </div> 811 + </div> 812 + 813 + <div 814 + className="flex items-center gap-3 p-4 rounded-lg border" 815 + style={{ 816 + backgroundColor: 817 + "var(--md-sys-color-surface-container-lowest)", 818 + borderColor: "var(--md-sys-color-outline-variant)", 819 + }} 820 + > 821 + <input 822 + type="checkbox" 823 + id={deletePdsId} 824 + checked={deletePDSData} 825 + onChange={(e) => setDeletePDSData(e.target.checked)} 826 + className="w-4 h-4 rounded border-(--md-sys-color-outline) bg-(--md-sys-color-surface-container) accent-(--md-sys-color-primary)" 827 + /> 828 + <Label 829 + htmlFor={deletePdsId} 830 + className="md-body-medium cursor-pointer text-(--md-sys-color-on-surface)" 831 + > 832 + Also delete my OpnShelf data from my PDS 833 + </Label> 834 + </div> 835 + 836 + {deletePDSData ? ( 837 + <div 838 + className="p-3 rounded-lg border" 839 + style={{ 840 + backgroundColor: "rgba(var(--md-sys-color-error), 0.1)", 841 + borderColor: "rgba(var(--md-sys-color-error), 0.2)", 842 + }} 843 + > 844 + <p className="md-body-medium text-(--md-sys-color-error)"> 845 + Your OpnShelf data, including watch history, follows, 846 + lists, and list items, will be permanently deleted from 847 + your personal data server. This cannot be recovered. 848 + </p> 849 + </div> 850 + ) : ( 851 + <div 852 + className="p-3 rounded-lg" 853 + style={{ 854 + backgroundColor: "var(--md-sys-color-surface-container)", 855 + }} 856 + > 857 + <p className="md-body-medium text-(--md-sys-color-on-surface-variant)"> 858 + Your OpnShelf data will remain on your PDS. You can use 859 + another app or re-authorize OpnShelf later to access it. 860 + </p> 861 + </div> 862 + )} 863 + </div> 864 + 865 + <DialogFooter className="gap-2"> 866 + <M3Button 867 + variant="outlined" 868 + onClick={() => setShowDeleteDialog(false)} 869 + disabled={deleteAccountMutation.isPending} 870 + > 871 + Cancel 872 + </M3Button> 873 + <M3Button 874 + variant="filled" 875 + className="bg-(--md-sys-color-error) text-(--md-sys-color-on-error) hover:brightness-110 active:brightness-95" 876 + onClick={() => 877 + deleteAccountMutation.mutate({ 878 + body: { deletePDSData }, 879 + }) 880 + } 881 + disabled={deleteAccountMutation.isPending} 882 + > 883 + {deleteAccountMutation.isPending && ( 884 + <Loader2 className="h-4 w-4 animate-spin" /> 885 + )} 886 + {deleteAccountMutation.isPending 887 + ? "Deleting…" 888 + : "Delete Account"} 889 + </M3Button> 890 + </DialogFooter> 891 + </> 892 + )} 893 + </DialogContent> 894 + </Dialog> 895 + </div> 896 + ); 897 + } 898 + 899 + function DeletionProgressView({ 900 + job, 901 + error, 902 + onRetry, 903 + seedColor, 904 + }: { 905 + job: AccountDeletionJobDto | null | undefined; 906 + error: string | undefined; 907 + onRetry: () => void; 908 + seedColor: string; 909 + }) { 910 + const progress = job ? getAccountDeletionProgress(job) : null; 911 + const stepLabel = job 912 + ? getAccountDeletionStepLabel(job.currentStep) 913 + : "Preparing…"; 914 + const isFailed = job?.status === "failed"; 915 + 916 + return ( 917 + <div className="space-y-6 py-2"> 918 + <DialogHeader> 919 + <DialogTitle className="flex items-center gap-2 text-(--md-sys-color-on-surface)"> 920 + {isFailed ? ( 921 + <AlertTriangle className="h-5 w-5 text-(--md-sys-color-error)" /> 922 + ) : ( 923 + <Loader2 924 + className="h-5 w-5 animate-spin" 925 + style={{ color: seedColor }} 926 + /> 927 + )} 928 + {isFailed ? "Deletion Failed" : "Deleting Account…"} 929 + </DialogTitle> 930 + <DialogDescription className="text-(--md-sys-color-on-surface-variant)"> 931 + {isFailed 932 + ? "Something went wrong while deleting your account." 933 + : "Please keep this page open. Your data is being removed."} 934 + </DialogDescription> 935 + </DialogHeader> 936 + 937 + {!isFailed && ( 938 + <div className="space-y-3"> 939 + <div className="space-y-1.5"> 940 + <div className="flex items-center justify-between"> 941 + <p className="md-body-medium text-(--md-sys-color-on-surface-variant)"> 942 + {stepLabel} 711 943 </p> 712 - <div className="space-y-2 text-sm"> 713 - <p className="flex items-start gap-2 text-(--md-sys-color-on-surface)"> 714 - <span style={{ color: seedColor }}>✓</span> 715 - Your OpnShelf account and settings will be deleted 716 - </p> 717 - <p className="flex items-start gap-2 text-(--md-sys-color-on-surface)"> 718 - <span style={{ color: seedColor }}>✓</span> 719 - Your local session will be cleared 944 + {progress !== null && ( 945 + <p 946 + className="md-label-medium font-mono" 947 + style={{ color: seedColor }} 948 + > 949 + {progress}% 720 950 </p> 721 - </div> 951 + )} 722 952 </div> 723 - 724 953 <div 725 - className="flex items-center gap-3 p-4 rounded-lg border" 954 + className="h-2 w-full overflow-hidden rounded-full" 726 955 style={{ 727 - backgroundColor: "var(--md-sys-color-surface-container-lowest)", 728 - borderColor: "var(--md-sys-color-outline-variant)", 956 + backgroundColor: 957 + "var(--md-sys-color-surface-container-highest)", 729 958 }} 730 959 > 731 - <input 732 - type="checkbox" 733 - id={deletePdsId} 734 - checked={deletePDSData} 735 - onChange={(e) => setDeletePDSData(e.target.checked)} 736 - className="w-4 h-4 rounded border-(--md-sys-color-outline) bg-(--md-sys-color-surface-container) accent-(--md-sys-color-primary)" 737 - /> 738 - <Label 739 - htmlFor={deletePdsId} 740 - className="md-body-medium cursor-pointer text-(--md-sys-color-on-surface)" 741 - > 742 - Also delete my OpnShelf data from my PDS 743 - </Label> 744 - </div> 745 - 746 - {deletePDSData ? ( 747 960 <div 748 - className="p-3 rounded-lg border" 749 - style={{ 750 - backgroundColor: "rgba(var(--md-sys-color-error), 0.1)", 751 - borderColor: "rgba(var(--md-sys-color-error), 0.2)", 752 - }} 753 - > 754 - <p className="md-body-medium text-(--md-sys-color-error)"> 755 - Your OpnShelf data, including watch history, follows, lists, 756 - and list items, will be permanently deleted from your personal 757 - data server. This cannot be recovered. 758 - </p> 759 - </div> 760 - ) : ( 761 - <div 762 - className="p-3 rounded-lg" 961 + className="h-full rounded-full transition-all duration-300 ease-out" 763 962 style={{ 764 - backgroundColor: "var(--md-sys-color-surface-container)", 963 + width: `${progress ?? 0}%`, 964 + backgroundColor: seedColor, 765 965 }} 766 - > 767 - <p className="md-body-medium text-(--md-sys-color-on-surface-variant)"> 768 - Your OpnShelf data will remain on your PDS. You can use 769 - another app or re-authorize OpnShelf later to access it. 770 - </p> 771 - </div> 772 - )} 966 + /> 967 + </div> 773 968 </div> 969 + {job && job.totalRecords > 0 && ( 970 + <p className="md-body-small text-(--md-sys-color-on-surface-variant)"> 971 + {job.deletedRecords} of {job.totalRecords} records deleted 972 + </p> 973 + )} 974 + </div> 975 + )} 774 976 775 - <DialogFooter className="gap-2"> 776 - <M3Button 777 - variant="outlined" 778 - onClick={() => setShowDeleteDialog(false)} 779 - disabled={deleteAccountMutation.isPending} 780 - > 781 - Cancel 782 - </M3Button> 783 - <LoadingButton 784 - variant="destructive" 785 - onClick={() => 786 - deleteAccountMutation.mutate({ 787 - body: { deletePDSData }, 788 - }) 789 - } 790 - disabled={deleteAccountMutation.isPending} 791 - isLoading={deleteAccountMutation.isPending} 792 - > 793 - Delete Account 794 - </LoadingButton> 795 - </DialogFooter> 796 - </DialogContent> 797 - </Dialog> 977 + {isFailed && ( 978 + <div className="space-y-4"> 979 + <div 980 + className="rounded-lg border p-3" 981 + style={{ 982 + backgroundColor: "rgba(var(--md-sys-color-error), 0.1)", 983 + borderColor: "rgba(var(--md-sys-color-error), 0.2)", 984 + }} 985 + > 986 + <p className="md-body-medium text-(--md-sys-color-error)"> 987 + {error ?? 988 + "Account deletion failed. Please try again or contact support."} 989 + </p> 990 + </div> 991 + <M3Button variant="filled" onClick={onRetry} className="w-full"> 992 + Retry 993 + </M3Button> 994 + </div> 995 + )} 798 996 </div> 799 997 ); 800 998 }
+57
backend/prisma/migrations/20260327120000_replace_trakt_import_job_with_background_job/migration.sql
··· 1 + -- CreateTable 2 + CREATE TABLE "BackgroundJob" ( 3 + "id" TEXT NOT NULL, 4 + "type" TEXT NOT NULL, 5 + "userDid" TEXT NOT NULL, 6 + "status" TEXT NOT NULL DEFAULT 'queued', 7 + "data" JSONB NOT NULL DEFAULT '{}', 8 + "nextRunAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, 9 + "lastError" TEXT, 10 + "startedAt" TIMESTAMP(3), 11 + "completedAt" TIMESTAMP(3), 12 + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, 13 + "updatedAt" TIMESTAMP(3) NOT NULL, 14 + 15 + CONSTRAINT "BackgroundJob_pkey" PRIMARY KEY ("id") 16 + ); 17 + 18 + -- Migrate TraktImportJob data into BackgroundJob 19 + INSERT INTO "BackgroundJob" ("id", "type", "userDid", "status", "data", "nextRunAt", "lastError", "startedAt", "completedAt", "createdAt", "updatedAt") 20 + SELECT 21 + "id", 22 + 'trakt_import', 23 + "userDid", 24 + "status"::text, 25 + jsonb_build_object( 26 + 'traktUsername', "traktUsername", 27 + 'currentPage', "currentPage", 28 + 'totalPages', "totalPages", 29 + 'sourceCount', "sourceCount", 30 + 'normalizedCount', "normalizedCount", 31 + 'importedCount', "importedCount", 32 + 'skippedCount', "skippedCount", 33 + 'failedCount', "failedCount", 34 + 'profileUsername', "profileUsername", 35 + 'profileSlug', "profileSlug", 36 + 'profileName', "profileName", 37 + 'profileAvatarUrl', "profileAvatarUrl" 38 + ), 39 + "nextRunAt", 40 + "lastError", 41 + "startedAt", 42 + "completedAt", 43 + "createdAt", 44 + "updatedAt" 45 + FROM "TraktImportJob"; 46 + 47 + -- DropTable 48 + DROP TABLE "TraktImportJob"; 49 + 50 + -- DropEnum 51 + DROP TYPE "TraktImportJobStatus"; 52 + 53 + -- CreateIndex 54 + CREATE INDEX "BackgroundJob_type_status_nextRunAt_idx" ON "BackgroundJob"("type", "status", "nextRunAt"); 55 + 56 + -- CreateIndex 57 + CREATE INDEX "BackgroundJob_userDid_type_idx" ON "BackgroundJob"("userDid", "type");
+14 -34
backend/prisma/schema.prisma
··· 28 28 29 29 trackedMovies TrackedMovie[] 30 30 trackedEpisodes TrackedEpisode[] 31 - traktImportJobs TraktImportJob[] 32 31 lists List[] 33 32 following Follow[] @relation("UserFollowing") 34 33 followers Follow[] @relation("UserFollowers") ··· 59 58 show 60 59 } 61 60 62 - enum TraktImportJobStatus { 63 - queued 64 - running 65 - waiting_retry 66 - completed 67 - failed 68 - } 69 61 70 62 // OAuth session storage for @atproto/oauth-client-node sessionStore 71 63 // No FK to User because the OAuth library stores session before we create the User ··· 89 81 @@index([expiresAt]) 90 82 } 91 83 92 - model TraktImportJob { 93 - id String @id @default(cuid()) 94 - userDid String 95 - user User @relation(fields: [userDid], references: [did], onDelete: Cascade) 96 - traktUsername String 97 - status TraktImportJobStatus @default(queued) 98 - currentPage Int @default(1) 99 - totalPages Int? 100 - sourceCount Int @default(0) 101 - normalizedCount Int @default(0) 102 - importedCount Int @default(0) 103 - skippedCount Int @default(0) 104 - failedCount Int @default(0) 105 - nextRunAt DateTime @default(now()) 106 - lastError String? 107 - profileUsername String? 108 - profileSlug String? 109 - profileName String? 110 - profileAvatarUrl String? 111 - startedAt DateTime? 112 - completedAt DateTime? 113 - createdAt DateTime @default(now()) 114 - updatedAt DateTime @updatedAt 84 + model BackgroundJob { 85 + id String @id @default(cuid()) 86 + type String 87 + userDid String 88 + status String @default("queued") 89 + data Json @default("{}") 90 + nextRunAt DateTime @default(now()) 91 + lastError String? 92 + startedAt DateTime? 93 + completedAt DateTime? 94 + createdAt DateTime @default(now()) 95 + updatedAt DateTime @updatedAt 115 96 116 - @@index([userDid, status]) 117 - @@index([status, nextRunAt]) 118 - @@index([userDid, createdAt]) 97 + @@index([type, status, nextRunAt]) 98 + @@index([userDid, type]) 119 99 } 120 100 121 101 model Movie {
+2 -2
backend/src/generated/browser.ts
··· 38 38 */ 39 39 export type AuthState = Prisma.AuthStateModel 40 40 /** 41 - * Model TraktImportJob 41 + * Model BackgroundJob 42 42 * 43 43 */ 44 - export type TraktImportJob = Prisma.TraktImportJobModel 44 + export type BackgroundJob = Prisma.BackgroundJobModel 45 45 /** 46 46 * Model Movie 47 47 *
+2 -2
backend/src/generated/client.ts
··· 58 58 */ 59 59 export type AuthState = Prisma.AuthStateModel 60 60 /** 61 - * Model TraktImportJob 61 + * Model BackgroundJob 62 62 * 63 63 */ 64 - export type TraktImportJob = Prisma.TraktImportJobModel 64 + export type BackgroundJob = Prisma.BackgroundJobModel 65 65 /** 66 66 * Model Movie 67 67 *
+137 -96
backend/src/generated/commonInputTypes.ts
··· 135 135 _max?: Prisma.NestedDateTimeFilter<$PrismaModel> 136 136 } 137 137 138 - export type EnumTraktImportJobStatusFilter<$PrismaModel = never> = { 139 - equals?: $Enums.TraktImportJobStatus | Prisma.EnumTraktImportJobStatusFieldRefInput<$PrismaModel> 140 - in?: $Enums.TraktImportJobStatus[] | Prisma.ListEnumTraktImportJobStatusFieldRefInput<$PrismaModel> 141 - notIn?: $Enums.TraktImportJobStatus[] | Prisma.ListEnumTraktImportJobStatusFieldRefInput<$PrismaModel> 142 - not?: Prisma.NestedEnumTraktImportJobStatusFilter<$PrismaModel> | $Enums.TraktImportJobStatus 143 - } 138 + export type JsonFilter<$PrismaModel = never> = 139 + | Prisma.PatchUndefined< 140 + Prisma.Either<Required<JsonFilterBase<$PrismaModel>>, Exclude<keyof Required<JsonFilterBase<$PrismaModel>>, 'path'>>, 141 + Required<JsonFilterBase<$PrismaModel>> 142 + > 143 + | Prisma.OptionalFlat<Omit<Required<JsonFilterBase<$PrismaModel>>, 'path'>> 144 144 145 - export type IntFilter<$PrismaModel = never> = { 146 - equals?: number | Prisma.IntFieldRefInput<$PrismaModel> 147 - in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> 148 - notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> 149 - lt?: number | Prisma.IntFieldRefInput<$PrismaModel> 150 - lte?: number | Prisma.IntFieldRefInput<$PrismaModel> 151 - gt?: number | Prisma.IntFieldRefInput<$PrismaModel> 152 - gte?: number | Prisma.IntFieldRefInput<$PrismaModel> 153 - not?: Prisma.NestedIntFilter<$PrismaModel> | number 145 + export type JsonFilterBase<$PrismaModel = never> = { 146 + equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter 147 + path?: string[] 148 + mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel> 149 + string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel> 150 + string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel> 151 + string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel> 152 + array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null 153 + array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null 154 + array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null 155 + lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 156 + lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 157 + gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 158 + gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 159 + not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter 154 160 } 155 161 156 - export type IntNullableFilter<$PrismaModel = never> = { 157 - equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null 158 - in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null 159 - notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null 160 - lt?: number | Prisma.IntFieldRefInput<$PrismaModel> 161 - lte?: number | Prisma.IntFieldRefInput<$PrismaModel> 162 - gt?: number | Prisma.IntFieldRefInput<$PrismaModel> 163 - gte?: number | Prisma.IntFieldRefInput<$PrismaModel> 164 - not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null 165 - } 162 + export type JsonWithAggregatesFilter<$PrismaModel = never> = 163 + | Prisma.PatchUndefined< 164 + Prisma.Either<Required<JsonWithAggregatesFilterBase<$PrismaModel>>, Exclude<keyof Required<JsonWithAggregatesFilterBase<$PrismaModel>>, 'path'>>, 165 + Required<JsonWithAggregatesFilterBase<$PrismaModel>> 166 + > 167 + | Prisma.OptionalFlat<Omit<Required<JsonWithAggregatesFilterBase<$PrismaModel>>, 'path'>> 166 168 167 - export type EnumTraktImportJobStatusWithAggregatesFilter<$PrismaModel = never> = { 168 - equals?: $Enums.TraktImportJobStatus | Prisma.EnumTraktImportJobStatusFieldRefInput<$PrismaModel> 169 - in?: $Enums.TraktImportJobStatus[] | Prisma.ListEnumTraktImportJobStatusFieldRefInput<$PrismaModel> 170 - notIn?: $Enums.TraktImportJobStatus[] | Prisma.ListEnumTraktImportJobStatusFieldRefInput<$PrismaModel> 171 - not?: Prisma.NestedEnumTraktImportJobStatusWithAggregatesFilter<$PrismaModel> | $Enums.TraktImportJobStatus 169 + export type JsonWithAggregatesFilterBase<$PrismaModel = never> = { 170 + equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter 171 + path?: string[] 172 + mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel> 173 + string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel> 174 + string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel> 175 + string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel> 176 + array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null 177 + array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null 178 + array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null 179 + lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 180 + lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 181 + gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 182 + gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 183 + not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter 172 184 _count?: Prisma.NestedIntFilter<$PrismaModel> 173 - _min?: Prisma.NestedEnumTraktImportJobStatusFilter<$PrismaModel> 174 - _max?: Prisma.NestedEnumTraktImportJobStatusFilter<$PrismaModel> 175 - } 176 - 177 - export type IntWithAggregatesFilter<$PrismaModel = never> = { 178 - equals?: number | Prisma.IntFieldRefInput<$PrismaModel> 179 - in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> 180 - notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> 181 - lt?: number | Prisma.IntFieldRefInput<$PrismaModel> 182 - lte?: number | Prisma.IntFieldRefInput<$PrismaModel> 183 - gt?: number | Prisma.IntFieldRefInput<$PrismaModel> 184 - gte?: number | Prisma.IntFieldRefInput<$PrismaModel> 185 - not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number 186 - _count?: Prisma.NestedIntFilter<$PrismaModel> 187 - _avg?: Prisma.NestedFloatFilter<$PrismaModel> 188 - _sum?: Prisma.NestedIntFilter<$PrismaModel> 189 - _min?: Prisma.NestedIntFilter<$PrismaModel> 190 - _max?: Prisma.NestedIntFilter<$PrismaModel> 185 + _min?: Prisma.NestedJsonFilter<$PrismaModel> 186 + _max?: Prisma.NestedJsonFilter<$PrismaModel> 191 187 } 192 188 193 - export type IntNullableWithAggregatesFilter<$PrismaModel = never> = { 189 + export type IntNullableFilter<$PrismaModel = never> = { 194 190 equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null 195 191 in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null 196 192 notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null ··· 198 194 lte?: number | Prisma.IntFieldRefInput<$PrismaModel> 199 195 gt?: number | Prisma.IntFieldRefInput<$PrismaModel> 200 196 gte?: number | Prisma.IntFieldRefInput<$PrismaModel> 201 - not?: Prisma.NestedIntNullableWithAggregatesFilter<$PrismaModel> | number | null 202 - _count?: Prisma.NestedIntNullableFilter<$PrismaModel> 203 - _avg?: Prisma.NestedFloatNullableFilter<$PrismaModel> 204 - _sum?: Prisma.NestedIntNullableFilter<$PrismaModel> 205 - _min?: Prisma.NestedIntNullableFilter<$PrismaModel> 206 - _max?: Prisma.NestedIntNullableFilter<$PrismaModel> 197 + not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null 207 198 } 208 199 209 200 export type JsonNullableFilter<$PrismaModel = never> = ··· 228 219 gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 229 220 gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 230 221 not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter 222 + } 223 + 224 + export type IntNullableWithAggregatesFilter<$PrismaModel = never> = { 225 + equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null 226 + in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null 227 + notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null 228 + lt?: number | Prisma.IntFieldRefInput<$PrismaModel> 229 + lte?: number | Prisma.IntFieldRefInput<$PrismaModel> 230 + gt?: number | Prisma.IntFieldRefInput<$PrismaModel> 231 + gte?: number | Prisma.IntFieldRefInput<$PrismaModel> 232 + not?: Prisma.NestedIntNullableWithAggregatesFilter<$PrismaModel> | number | null 233 + _count?: Prisma.NestedIntNullableFilter<$PrismaModel> 234 + _avg?: Prisma.NestedFloatNullableFilter<$PrismaModel> 235 + _sum?: Prisma.NestedIntNullableFilter<$PrismaModel> 236 + _min?: Prisma.NestedIntNullableFilter<$PrismaModel> 237 + _max?: Prisma.NestedIntNullableFilter<$PrismaModel> 231 238 } 232 239 233 240 export type JsonNullableWithAggregatesFilter<$PrismaModel = never> = ··· 257 264 _max?: Prisma.NestedJsonNullableFilter<$PrismaModel> 258 265 } 259 266 267 + export type IntFilter<$PrismaModel = never> = { 268 + equals?: number | Prisma.IntFieldRefInput<$PrismaModel> 269 + in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> 270 + notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> 271 + lt?: number | Prisma.IntFieldRefInput<$PrismaModel> 272 + lte?: number | Prisma.IntFieldRefInput<$PrismaModel> 273 + gt?: number | Prisma.IntFieldRefInput<$PrismaModel> 274 + gte?: number | Prisma.IntFieldRefInput<$PrismaModel> 275 + not?: Prisma.NestedIntFilter<$PrismaModel> | number 276 + } 277 + 278 + export type IntWithAggregatesFilter<$PrismaModel = never> = { 279 + equals?: number | Prisma.IntFieldRefInput<$PrismaModel> 280 + in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> 281 + notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> 282 + lt?: number | Prisma.IntFieldRefInput<$PrismaModel> 283 + lte?: number | Prisma.IntFieldRefInput<$PrismaModel> 284 + gt?: number | Prisma.IntFieldRefInput<$PrismaModel> 285 + gte?: number | Prisma.IntFieldRefInput<$PrismaModel> 286 + not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number 287 + _count?: Prisma.NestedIntFilter<$PrismaModel> 288 + _avg?: Prisma.NestedFloatFilter<$PrismaModel> 289 + _sum?: Prisma.NestedIntFilter<$PrismaModel> 290 + _min?: Prisma.NestedIntFilter<$PrismaModel> 291 + _max?: Prisma.NestedIntFilter<$PrismaModel> 292 + } 293 + 260 294 export type BoolFilter<$PrismaModel = never> = { 261 295 equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel> 262 296 not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean ··· 421 455 _max?: Prisma.NestedDateTimeFilter<$PrismaModel> 422 456 } 423 457 424 - export type NestedEnumTraktImportJobStatusFilter<$PrismaModel = never> = { 425 - equals?: $Enums.TraktImportJobStatus | Prisma.EnumTraktImportJobStatusFieldRefInput<$PrismaModel> 426 - in?: $Enums.TraktImportJobStatus[] | Prisma.ListEnumTraktImportJobStatusFieldRefInput<$PrismaModel> 427 - notIn?: $Enums.TraktImportJobStatus[] | Prisma.ListEnumTraktImportJobStatusFieldRefInput<$PrismaModel> 428 - not?: Prisma.NestedEnumTraktImportJobStatusFilter<$PrismaModel> | $Enums.TraktImportJobStatus 429 - } 430 - 431 - export type NestedEnumTraktImportJobStatusWithAggregatesFilter<$PrismaModel = never> = { 432 - equals?: $Enums.TraktImportJobStatus | Prisma.EnumTraktImportJobStatusFieldRefInput<$PrismaModel> 433 - in?: $Enums.TraktImportJobStatus[] | Prisma.ListEnumTraktImportJobStatusFieldRefInput<$PrismaModel> 434 - notIn?: $Enums.TraktImportJobStatus[] | Prisma.ListEnumTraktImportJobStatusFieldRefInput<$PrismaModel> 435 - not?: Prisma.NestedEnumTraktImportJobStatusWithAggregatesFilter<$PrismaModel> | $Enums.TraktImportJobStatus 436 - _count?: Prisma.NestedIntFilter<$PrismaModel> 437 - _min?: Prisma.NestedEnumTraktImportJobStatusFilter<$PrismaModel> 438 - _max?: Prisma.NestedEnumTraktImportJobStatusFilter<$PrismaModel> 439 - } 440 - 441 - export type NestedIntWithAggregatesFilter<$PrismaModel = never> = { 442 - equals?: number | Prisma.IntFieldRefInput<$PrismaModel> 443 - in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> 444 - notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> 445 - lt?: number | Prisma.IntFieldRefInput<$PrismaModel> 446 - lte?: number | Prisma.IntFieldRefInput<$PrismaModel> 447 - gt?: number | Prisma.IntFieldRefInput<$PrismaModel> 448 - gte?: number | Prisma.IntFieldRefInput<$PrismaModel> 449 - not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number 450 - _count?: Prisma.NestedIntFilter<$PrismaModel> 451 - _avg?: Prisma.NestedFloatFilter<$PrismaModel> 452 - _sum?: Prisma.NestedIntFilter<$PrismaModel> 453 - _min?: Prisma.NestedIntFilter<$PrismaModel> 454 - _max?: Prisma.NestedIntFilter<$PrismaModel> 455 - } 458 + export type NestedJsonFilter<$PrismaModel = never> = 459 + | Prisma.PatchUndefined< 460 + Prisma.Either<Required<NestedJsonFilterBase<$PrismaModel>>, Exclude<keyof Required<NestedJsonFilterBase<$PrismaModel>>, 'path'>>, 461 + Required<NestedJsonFilterBase<$PrismaModel>> 462 + > 463 + | Prisma.OptionalFlat<Omit<Required<NestedJsonFilterBase<$PrismaModel>>, 'path'>> 456 464 457 - export type NestedFloatFilter<$PrismaModel = never> = { 458 - equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> 459 - in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> 460 - notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> 461 - lt?: number | Prisma.FloatFieldRefInput<$PrismaModel> 462 - lte?: number | Prisma.FloatFieldRefInput<$PrismaModel> 463 - gt?: number | Prisma.FloatFieldRefInput<$PrismaModel> 464 - gte?: number | Prisma.FloatFieldRefInput<$PrismaModel> 465 - not?: Prisma.NestedFloatFilter<$PrismaModel> | number 465 + export type NestedJsonFilterBase<$PrismaModel = never> = { 466 + equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter 467 + path?: string[] 468 + mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel> 469 + string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel> 470 + string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel> 471 + string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel> 472 + array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null 473 + array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null 474 + array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null 475 + lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 476 + lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 477 + gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 478 + gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 479 + not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter 466 480 } 467 481 468 482 export type NestedIntNullableWithAggregatesFilter<$PrismaModel = never> = { ··· 514 528 gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 515 529 gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> 516 530 not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter 531 + } 532 + 533 + export type NestedIntWithAggregatesFilter<$PrismaModel = never> = { 534 + equals?: number | Prisma.IntFieldRefInput<$PrismaModel> 535 + in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> 536 + notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> 537 + lt?: number | Prisma.IntFieldRefInput<$PrismaModel> 538 + lte?: number | Prisma.IntFieldRefInput<$PrismaModel> 539 + gt?: number | Prisma.IntFieldRefInput<$PrismaModel> 540 + gte?: number | Prisma.IntFieldRefInput<$PrismaModel> 541 + not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number 542 + _count?: Prisma.NestedIntFilter<$PrismaModel> 543 + _avg?: Prisma.NestedFloatFilter<$PrismaModel> 544 + _sum?: Prisma.NestedIntFilter<$PrismaModel> 545 + _min?: Prisma.NestedIntFilter<$PrismaModel> 546 + _max?: Prisma.NestedIntFilter<$PrismaModel> 547 + } 548 + 549 + export type NestedFloatFilter<$PrismaModel = never> = { 550 + equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> 551 + in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> 552 + notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> 553 + lt?: number | Prisma.FloatFieldRefInput<$PrismaModel> 554 + lte?: number | Prisma.FloatFieldRefInput<$PrismaModel> 555 + gt?: number | Prisma.FloatFieldRefInput<$PrismaModel> 556 + gte?: number | Prisma.FloatFieldRefInput<$PrismaModel> 557 + not?: Prisma.NestedFloatFilter<$PrismaModel> | number 517 558 } 518 559 519 560 export type NestedBoolFilter<$PrismaModel = never> = {
-11
backend/src/generated/enums.ts
··· 15 15 } as const 16 16 17 17 export type MediaType = (typeof MediaType)[keyof typeof MediaType] 18 - 19 - 20 - export const TraktImportJobStatus = { 21 - queued: 'queued', 22 - running: 'running', 23 - waiting_retry: 'waiting_retry', 24 - completed: 'completed', 25 - failed: 'failed' 26 - } as const 27 - 28 - export type TraktImportJobStatus = (typeof TraktImportJobStatus)[keyof typeof TraktImportJobStatus]
+6 -6
backend/src/generated/internal/class.ts
··· 20 20 "clientVersion": "7.3.0", 21 21 "engineVersion": "9d6ad21cbbceab97458517b147a6a09ff43aa735", 22 22 "activeProvider": "postgresql", 23 - "inlineSchema": "generator client {\n provider = \"prisma-client\"\n output = \"../src/generated\"\n moduleFormat = \"cjs\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nmodel User {\n did String @id\n handle String @unique\n displayName String?\n avatar String?\n profileRkey String?\n profileUri String?\n profileCid String?\n profileDisplayName String?\n profileAvatarCid String?\n profileAvatarMimeType String?\n profileUpdatedAt DateTime?\n timezone String @default(\"UTC\")\n timeFormat String @default(\"24h\")\n onboardingCompletedAt DateTime?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n trackedMovies TrackedMovie[]\n trackedEpisodes TrackedEpisode[]\n traktImportJobs TraktImportJob[]\n lists List[]\n following Follow[] @relation(\"UserFollowing\")\n followers Follow[] @relation(\"UserFollowers\")\n\n @@index([handle])\n @@index([profileAvatarCid])\n}\n\nmodel Follow {\n followerDid String\n followingDid String\n rkey String?\n uri String?\n cid String?\n createdAt DateTime @default(now())\n\n follower User @relation(\"UserFollowing\", fields: [followerDid], references: [did], onDelete: Cascade)\n following User @relation(\"UserFollowers\", fields: [followingDid], references: [did], onDelete: Cascade)\n\n @@id([followerDid, followingDid])\n @@index([followerDid, createdAt])\n @@index([followingDid, createdAt])\n @@index([followerDid, rkey])\n}\n\nenum MediaType {\n movie\n show\n}\n\nenum TraktImportJobStatus {\n queued\n running\n waiting_retry\n completed\n failed\n}\n\n// OAuth session storage for @atproto/oauth-client-node sessionStore\n// No FK to User because the OAuth library stores session before we create the User\n// Cookie stores opaque id (not DID) for session lookup\nmodel AuthSession {\n id String @id @default(cuid())\n userDid String @unique\n sessionData String // JSON-serialized session from the library\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([updatedAt])\n}\n\nmodel AuthState {\n key String @id\n stateData String\n expiresAt DateTime\n createdAt DateTime @default(now())\n\n @@index([expiresAt])\n}\n\nmodel TraktImportJob {\n id String @id @default(cuid())\n userDid String\n user User @relation(fields: [userDid], references: [did], onDelete: Cascade)\n traktUsername String\n status TraktImportJobStatus @default(queued)\n currentPage Int @default(1)\n totalPages Int?\n sourceCount Int @default(0)\n normalizedCount Int @default(0)\n importedCount Int @default(0)\n skippedCount Int @default(0)\n failedCount Int @default(0)\n nextRunAt DateTime @default(now())\n lastError String?\n profileUsername String?\n profileSlug String?\n profileName String?\n profileAvatarUrl String?\n startedAt DateTime?\n completedAt DateTime?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([userDid, status])\n @@index([status, nextRunAt])\n @@index([userDid, createdAt])\n}\n\nmodel Movie {\n movieId String @id\n title String\n posterPath String?\n backdropPath String?\n releaseYear Int?\n releaseDate DateTime?\n overview String?\n colors Json? // { primary, secondary, accent, muted }\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n trackedBy TrackedMovie[]\n listItems ListItem[]\n\n @@index([title])\n}\n\nmodel Show {\n showId String @id\n title String\n posterPath String?\n backdropPath String?\n firstAirYear Int?\n firstAirDate DateTime?\n overview String?\n colors Json?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n trackedBy TrackedEpisode[]\n listItems ListItem[]\n seasons Season[]\n\n @@index([title])\n}\n\nmodel Season {\n id String @id @default(cuid())\n tmdbId Int @unique\n showId String\n show Show @relation(fields: [showId], references: [showId], onDelete: Cascade)\n seasonNumber Int\n name String\n posterPath String?\n airDate DateTime?\n episodeCount Int?\n\n episodes Episode[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@unique([showId, seasonNumber])\n @@index([showId])\n}\n\nmodel Episode {\n id String @id @default(cuid())\n tmdbId Int @unique\n seasonId String\n season Season @relation(fields: [seasonId], references: [id], onDelete: Cascade)\n showId String\n episodeNumber Int\n seasonNumber Int\n name String\n airDate DateTime?\n overview String?\n stillPath String?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@unique([showId, seasonNumber, episodeNumber])\n @@index([seasonId])\n @@index([showId])\n @@index([airDate])\n}\n\nmodel TrackedMovie {\n id String @id @default(cuid())\n rkey String @unique\n uri String\n cid String\n\n userDid String\n user User @relation(fields: [userDid], references: [did], onDelete: Cascade)\n\n movieId String\n movie Movie @relation(fields: [movieId], references: [movieId], onDelete: Cascade)\n\n status String @default(\"watched\")\n watchedDate DateTime?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([userDid])\n @@index([movieId])\n @@index([status])\n @@index([createdAt])\n @@index([watchedDate])\n @@index([uri])\n @@index([cid])\n}\n\nmodel TrackedEpisode {\n id String @id @default(cuid())\n rkey String @unique\n uri String\n cid String\n\n userDid String\n user User @relation(fields: [userDid], references: [did], onDelete: Cascade)\n\n showId String\n show Show @relation(fields: [showId], references: [showId], onDelete: Cascade)\n\n seasonNumber Int\n episodeNumber Int\n status String @default(\"watched\")\n watchedDate DateTime?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([userDid])\n @@index([showId])\n @@index([seasonNumber])\n @@index([episodeNumber])\n @@index([status])\n @@index([createdAt])\n @@index([watchedDate])\n @@index([uri])\n @@index([cid])\n}\n\nmodel List {\n id String @id @default(cuid())\n rkey String @unique\n uri String\n cid String?\n\n userDid String\n user User @relation(fields: [userDid], references: [did], onDelete: Cascade)\n\n name String\n description String?\n slug String\n isDefault Boolean @default(false)\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n items ListItem[]\n\n @@unique([userDid, slug])\n @@index([userDid])\n @@index([isDefault])\n}\n\nmodel ListItem {\n id String @id @default(cuid())\n rkey String @unique\n uri String\n cid String?\n\n listId String\n list List @relation(fields: [listId], references: [id], onDelete: Cascade)\n\n mediaType MediaType\n mediaId String\n movieId String?\n movie Movie? @relation(fields: [movieId], references: [movieId], onDelete: Cascade)\n showId String?\n show Show? @relation(fields: [showId], references: [showId], onDelete: Cascade)\n\n notes String?\n position Int @default(0)\n\n createdAt DateTime @default(now())\n\n @@unique([listId, mediaType, mediaId])\n @@index([listId])\n @@index([mediaType, mediaId])\n}\n", 23 + "inlineSchema": "generator client {\n provider = \"prisma-client\"\n output = \"../src/generated\"\n moduleFormat = \"cjs\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nmodel User {\n did String @id\n handle String @unique\n displayName String?\n avatar String?\n profileRkey String?\n profileUri String?\n profileCid String?\n profileDisplayName String?\n profileAvatarCid String?\n profileAvatarMimeType String?\n profileUpdatedAt DateTime?\n timezone String @default(\"UTC\")\n timeFormat String @default(\"24h\")\n onboardingCompletedAt DateTime?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n trackedMovies TrackedMovie[]\n trackedEpisodes TrackedEpisode[]\n lists List[]\n following Follow[] @relation(\"UserFollowing\")\n followers Follow[] @relation(\"UserFollowers\")\n\n @@index([handle])\n @@index([profileAvatarCid])\n}\n\nmodel Follow {\n followerDid String\n followingDid String\n rkey String?\n uri String?\n cid String?\n createdAt DateTime @default(now())\n\n follower User @relation(\"UserFollowing\", fields: [followerDid], references: [did], onDelete: Cascade)\n following User @relation(\"UserFollowers\", fields: [followingDid], references: [did], onDelete: Cascade)\n\n @@id([followerDid, followingDid])\n @@index([followerDid, createdAt])\n @@index([followingDid, createdAt])\n @@index([followerDid, rkey])\n}\n\nenum MediaType {\n movie\n show\n}\n\n// OAuth session storage for @atproto/oauth-client-node sessionStore\n// No FK to User because the OAuth library stores session before we create the User\n// Cookie stores opaque id (not DID) for session lookup\nmodel AuthSession {\n id String @id @default(cuid())\n userDid String @unique\n sessionData String // JSON-serialized session from the library\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([updatedAt])\n}\n\nmodel AuthState {\n key String @id\n stateData String\n expiresAt DateTime\n createdAt DateTime @default(now())\n\n @@index([expiresAt])\n}\n\nmodel BackgroundJob {\n id String @id @default(cuid())\n type String\n userDid String\n status String @default(\"queued\")\n data Json @default(\"{}\")\n nextRunAt DateTime @default(now())\n lastError String?\n startedAt DateTime?\n completedAt DateTime?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([type, status, nextRunAt])\n @@index([userDid, type])\n}\n\nmodel Movie {\n movieId String @id\n title String\n posterPath String?\n backdropPath String?\n releaseYear Int?\n releaseDate DateTime?\n overview String?\n colors Json? // { primary, secondary, accent, muted }\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n trackedBy TrackedMovie[]\n listItems ListItem[]\n\n @@index([title])\n}\n\nmodel Show {\n showId String @id\n title String\n posterPath String?\n backdropPath String?\n firstAirYear Int?\n firstAirDate DateTime?\n overview String?\n colors Json?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n trackedBy TrackedEpisode[]\n listItems ListItem[]\n seasons Season[]\n\n @@index([title])\n}\n\nmodel Season {\n id String @id @default(cuid())\n tmdbId Int @unique\n showId String\n show Show @relation(fields: [showId], references: [showId], onDelete: Cascade)\n seasonNumber Int\n name String\n posterPath String?\n airDate DateTime?\n episodeCount Int?\n\n episodes Episode[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@unique([showId, seasonNumber])\n @@index([showId])\n}\n\nmodel Episode {\n id String @id @default(cuid())\n tmdbId Int @unique\n seasonId String\n season Season @relation(fields: [seasonId], references: [id], onDelete: Cascade)\n showId String\n episodeNumber Int\n seasonNumber Int\n name String\n airDate DateTime?\n overview String?\n stillPath String?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@unique([showId, seasonNumber, episodeNumber])\n @@index([seasonId])\n @@index([showId])\n @@index([airDate])\n}\n\nmodel TrackedMovie {\n id String @id @default(cuid())\n rkey String @unique\n uri String\n cid String\n\n userDid String\n user User @relation(fields: [userDid], references: [did], onDelete: Cascade)\n\n movieId String\n movie Movie @relation(fields: [movieId], references: [movieId], onDelete: Cascade)\n\n status String @default(\"watched\")\n watchedDate DateTime?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([userDid])\n @@index([movieId])\n @@index([status])\n @@index([createdAt])\n @@index([watchedDate])\n @@index([uri])\n @@index([cid])\n}\n\nmodel TrackedEpisode {\n id String @id @default(cuid())\n rkey String @unique\n uri String\n cid String\n\n userDid String\n user User @relation(fields: [userDid], references: [did], onDelete: Cascade)\n\n showId String\n show Show @relation(fields: [showId], references: [showId], onDelete: Cascade)\n\n seasonNumber Int\n episodeNumber Int\n status String @default(\"watched\")\n watchedDate DateTime?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([userDid])\n @@index([showId])\n @@index([seasonNumber])\n @@index([episodeNumber])\n @@index([status])\n @@index([createdAt])\n @@index([watchedDate])\n @@index([uri])\n @@index([cid])\n}\n\nmodel List {\n id String @id @default(cuid())\n rkey String @unique\n uri String\n cid String?\n\n userDid String\n user User @relation(fields: [userDid], references: [did], onDelete: Cascade)\n\n name String\n description String?\n slug String\n isDefault Boolean @default(false)\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n items ListItem[]\n\n @@unique([userDid, slug])\n @@index([userDid])\n @@index([isDefault])\n}\n\nmodel ListItem {\n id String @id @default(cuid())\n rkey String @unique\n uri String\n cid String?\n\n listId String\n list List @relation(fields: [listId], references: [id], onDelete: Cascade)\n\n mediaType MediaType\n mediaId String\n movieId String?\n movie Movie? @relation(fields: [movieId], references: [movieId], onDelete: Cascade)\n showId String?\n show Show? @relation(fields: [showId], references: [showId], onDelete: Cascade)\n\n notes String?\n position Int @default(0)\n\n createdAt DateTime @default(now())\n\n @@unique([listId, mediaType, mediaId])\n @@index([listId])\n @@index([mediaType, mediaId])\n}\n", 24 24 "runtimeDataModel": { 25 25 "models": {}, 26 26 "enums": {}, ··· 28 28 } 29 29 } 30 30 31 - config.runtimeDataModel = JSON.parse("{\"models\":{\"User\":{\"fields\":[{\"name\":\"did\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"handle\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"displayName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"avatar\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileRkey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileUri\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileCid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileDisplayName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileAvatarCid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileAvatarMimeType\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileUpdatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"timezone\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"timeFormat\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"onboardingCompletedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"trackedMovies\",\"kind\":\"object\",\"type\":\"TrackedMovie\",\"relationName\":\"TrackedMovieToUser\"},{\"name\":\"trackedEpisodes\",\"kind\":\"object\",\"type\":\"TrackedEpisode\",\"relationName\":\"TrackedEpisodeToUser\"},{\"name\":\"traktImportJobs\",\"kind\":\"object\",\"type\":\"TraktImportJob\",\"relationName\":\"TraktImportJobToUser\"},{\"name\":\"lists\",\"kind\":\"object\",\"type\":\"List\",\"relationName\":\"ListToUser\"},{\"name\":\"following\",\"kind\":\"object\",\"type\":\"Follow\",\"relationName\":\"UserFollowing\"},{\"name\":\"followers\",\"kind\":\"object\",\"type\":\"Follow\",\"relationName\":\"UserFollowers\"}],\"dbName\":null},\"Follow\":{\"fields\":[{\"name\":\"followerDid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"followingDid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rkey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"uri\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"follower\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"UserFollowing\"},{\"name\":\"following\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"UserFollowers\"}],\"dbName\":null},\"AuthSession\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userDid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sessionData\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"AuthState\":{\"fields\":[{\"name\":\"key\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"stateData\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"expiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"TraktImportJob\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userDid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"TraktImportJobToUser\"},{\"name\":\"traktUsername\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"status\",\"kind\":\"enum\",\"type\":\"TraktImportJobStatus\"},{\"name\":\"currentPage\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"totalPages\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"sourceCount\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"normalizedCount\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"importedCount\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"skippedCount\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"failedCount\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"nextRunAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"lastError\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileUsername\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileSlug\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileAvatarUrl\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"startedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"completedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Movie\":{\"fields\":[{\"name\":\"movieId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"posterPath\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"backdropPath\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"releaseYear\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"releaseDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"overview\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"colors\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"trackedBy\",\"kind\":\"object\",\"type\":\"TrackedMovie\",\"relationName\":\"MovieToTrackedMovie\"},{\"name\":\"listItems\",\"kind\":\"object\",\"type\":\"ListItem\",\"relationName\":\"ListItemToMovie\"}],\"dbName\":null},\"Show\":{\"fields\":[{\"name\":\"showId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"posterPath\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"backdropPath\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"firstAirYear\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"firstAirDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"overview\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"colors\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"trackedBy\",\"kind\":\"object\",\"type\":\"TrackedEpisode\",\"relationName\":\"ShowToTrackedEpisode\"},{\"name\":\"listItems\",\"kind\":\"object\",\"type\":\"ListItem\",\"relationName\":\"ListItemToShow\"},{\"name\":\"seasons\",\"kind\":\"object\",\"type\":\"Season\",\"relationName\":\"SeasonToShow\"}],\"dbName\":null},\"Season\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"tmdbId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"showId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"show\",\"kind\":\"object\",\"type\":\"Show\",\"relationName\":\"SeasonToShow\"},{\"name\":\"seasonNumber\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"posterPath\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"airDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"episodeCount\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"episodes\",\"kind\":\"object\",\"type\":\"Episode\",\"relationName\":\"EpisodeToSeason\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Episode\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"tmdbId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"seasonId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"season\",\"kind\":\"object\",\"type\":\"Season\",\"relationName\":\"EpisodeToSeason\"},{\"name\":\"showId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"episodeNumber\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"seasonNumber\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"airDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"overview\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"stillPath\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"TrackedMovie\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rkey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"uri\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userDid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"TrackedMovieToUser\"},{\"name\":\"movieId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"movie\",\"kind\":\"object\",\"type\":\"Movie\",\"relationName\":\"MovieToTrackedMovie\"},{\"name\":\"status\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"watchedDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"TrackedEpisode\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rkey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"uri\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userDid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"TrackedEpisodeToUser\"},{\"name\":\"showId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"show\",\"kind\":\"object\",\"type\":\"Show\",\"relationName\":\"ShowToTrackedEpisode\"},{\"name\":\"seasonNumber\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"episodeNumber\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"status\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"watchedDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"List\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rkey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"uri\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userDid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ListToUser\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"slug\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"isDefault\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"items\",\"kind\":\"object\",\"type\":\"ListItem\",\"relationName\":\"ListToListItem\"}],\"dbName\":null},\"ListItem\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rkey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"uri\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"listId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"list\",\"kind\":\"object\",\"type\":\"List\",\"relationName\":\"ListToListItem\"},{\"name\":\"mediaType\",\"kind\":\"enum\",\"type\":\"MediaType\"},{\"name\":\"mediaId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"movieId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"movie\",\"kind\":\"object\",\"type\":\"Movie\",\"relationName\":\"ListItemToMovie\"},{\"name\":\"showId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"show\",\"kind\":\"object\",\"type\":\"Show\",\"relationName\":\"ListItemToShow\"},{\"name\":\"notes\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"position\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") 31 + config.runtimeDataModel = JSON.parse("{\"models\":{\"User\":{\"fields\":[{\"name\":\"did\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"handle\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"displayName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"avatar\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileRkey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileUri\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileCid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileDisplayName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileAvatarCid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileAvatarMimeType\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profileUpdatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"timezone\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"timeFormat\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"onboardingCompletedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"trackedMovies\",\"kind\":\"object\",\"type\":\"TrackedMovie\",\"relationName\":\"TrackedMovieToUser\"},{\"name\":\"trackedEpisodes\",\"kind\":\"object\",\"type\":\"TrackedEpisode\",\"relationName\":\"TrackedEpisodeToUser\"},{\"name\":\"lists\",\"kind\":\"object\",\"type\":\"List\",\"relationName\":\"ListToUser\"},{\"name\":\"following\",\"kind\":\"object\",\"type\":\"Follow\",\"relationName\":\"UserFollowing\"},{\"name\":\"followers\",\"kind\":\"object\",\"type\":\"Follow\",\"relationName\":\"UserFollowers\"}],\"dbName\":null},\"Follow\":{\"fields\":[{\"name\":\"followerDid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"followingDid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rkey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"uri\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"follower\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"UserFollowing\"},{\"name\":\"following\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"UserFollowers\"}],\"dbName\":null},\"AuthSession\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userDid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sessionData\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"AuthState\":{\"fields\":[{\"name\":\"key\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"stateData\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"expiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"BackgroundJob\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"type\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userDid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"status\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"data\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"nextRunAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"lastError\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"startedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"completedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Movie\":{\"fields\":[{\"name\":\"movieId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"posterPath\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"backdropPath\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"releaseYear\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"releaseDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"overview\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"colors\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"trackedBy\",\"kind\":\"object\",\"type\":\"TrackedMovie\",\"relationName\":\"MovieToTrackedMovie\"},{\"name\":\"listItems\",\"kind\":\"object\",\"type\":\"ListItem\",\"relationName\":\"ListItemToMovie\"}],\"dbName\":null},\"Show\":{\"fields\":[{\"name\":\"showId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"posterPath\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"backdropPath\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"firstAirYear\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"firstAirDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"overview\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"colors\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"trackedBy\",\"kind\":\"object\",\"type\":\"TrackedEpisode\",\"relationName\":\"ShowToTrackedEpisode\"},{\"name\":\"listItems\",\"kind\":\"object\",\"type\":\"ListItem\",\"relationName\":\"ListItemToShow\"},{\"name\":\"seasons\",\"kind\":\"object\",\"type\":\"Season\",\"relationName\":\"SeasonToShow\"}],\"dbName\":null},\"Season\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"tmdbId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"showId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"show\",\"kind\":\"object\",\"type\":\"Show\",\"relationName\":\"SeasonToShow\"},{\"name\":\"seasonNumber\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"posterPath\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"airDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"episodeCount\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"episodes\",\"kind\":\"object\",\"type\":\"Episode\",\"relationName\":\"EpisodeToSeason\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Episode\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"tmdbId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"seasonId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"season\",\"kind\":\"object\",\"type\":\"Season\",\"relationName\":\"EpisodeToSeason\"},{\"name\":\"showId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"episodeNumber\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"seasonNumber\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"airDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"overview\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"stillPath\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"TrackedMovie\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rkey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"uri\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userDid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"TrackedMovieToUser\"},{\"name\":\"movieId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"movie\",\"kind\":\"object\",\"type\":\"Movie\",\"relationName\":\"MovieToTrackedMovie\"},{\"name\":\"status\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"watchedDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"TrackedEpisode\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rkey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"uri\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userDid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"TrackedEpisodeToUser\"},{\"name\":\"showId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"show\",\"kind\":\"object\",\"type\":\"Show\",\"relationName\":\"ShowToTrackedEpisode\"},{\"name\":\"seasonNumber\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"episodeNumber\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"status\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"watchedDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"List\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rkey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"uri\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userDid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ListToUser\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"slug\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"isDefault\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"items\",\"kind\":\"object\",\"type\":\"ListItem\",\"relationName\":\"ListToListItem\"}],\"dbName\":null},\"ListItem\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rkey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"uri\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"listId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"list\",\"kind\":\"object\",\"type\":\"List\",\"relationName\":\"ListToListItem\"},{\"name\":\"mediaType\",\"kind\":\"enum\",\"type\":\"MediaType\"},{\"name\":\"mediaId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"movieId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"movie\",\"kind\":\"object\",\"type\":\"Movie\",\"relationName\":\"ListItemToMovie\"},{\"name\":\"showId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"show\",\"kind\":\"object\",\"type\":\"Show\",\"relationName\":\"ListItemToShow\"},{\"name\":\"notes\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"position\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") 32 32 33 33 async function decodeBase64AsWasm(wasmBase64: string): Promise<WebAssembly.Module> { 34 34 const { Buffer } = await import('node:buffer') ··· 217 217 get authState(): Prisma.AuthStateDelegate<ExtArgs, { omit: OmitOpts }>; 218 218 219 219 /** 220 - * `prisma.traktImportJob`: Exposes CRUD operations for the **TraktImportJob** model. 220 + * `prisma.backgroundJob`: Exposes CRUD operations for the **BackgroundJob** model. 221 221 * Example usage: 222 222 * ```ts 223 - * // Fetch zero or more TraktImportJobs 224 - * const traktImportJobs = await prisma.traktImportJob.findMany() 223 + * // Fetch zero or more BackgroundJobs 224 + * const backgroundJobs = await prisma.backgroundJob.findMany() 225 225 * ``` 226 226 */ 227 - get traktImportJob(): Prisma.TraktImportJobDelegate<ExtArgs, { omit: OmitOpts }>; 227 + get backgroundJob(): Prisma.BackgroundJobDelegate<ExtArgs, { omit: OmitOpts }>; 228 228 229 229 /** 230 230 * `prisma.movie`: Exposes CRUD operations for the **Movie** model.
+52 -69
backend/src/generated/internal/prismaNamespace.ts
··· 388 388 Follow: 'Follow', 389 389 AuthSession: 'AuthSession', 390 390 AuthState: 'AuthState', 391 - TraktImportJob: 'TraktImportJob', 391 + BackgroundJob: 'BackgroundJob', 392 392 Movie: 'Movie', 393 393 Show: 'Show', 394 394 Season: 'Season', ··· 412 412 omit: GlobalOmitOptions 413 413 } 414 414 meta: { 415 - modelProps: "user" | "follow" | "authSession" | "authState" | "traktImportJob" | "movie" | "show" | "season" | "episode" | "trackedMovie" | "trackedEpisode" | "list" | "listItem" 415 + modelProps: "user" | "follow" | "authSession" | "authState" | "backgroundJob" | "movie" | "show" | "season" | "episode" | "trackedMovie" | "trackedEpisode" | "list" | "listItem" 416 416 txIsolationLevel: TransactionIsolationLevel 417 417 } 418 418 model: { ··· 712 712 } 713 713 } 714 714 } 715 - TraktImportJob: { 716 - payload: Prisma.$TraktImportJobPayload<ExtArgs> 717 - fields: Prisma.TraktImportJobFieldRefs 715 + BackgroundJob: { 716 + payload: Prisma.$BackgroundJobPayload<ExtArgs> 717 + fields: Prisma.BackgroundJobFieldRefs 718 718 operations: { 719 719 findUnique: { 720 - args: Prisma.TraktImportJobFindUniqueArgs<ExtArgs> 721 - result: runtime.Types.Utils.PayloadToResult<Prisma.$TraktImportJobPayload> | null 720 + args: Prisma.BackgroundJobFindUniqueArgs<ExtArgs> 721 + result: runtime.Types.Utils.PayloadToResult<Prisma.$BackgroundJobPayload> | null 722 722 } 723 723 findUniqueOrThrow: { 724 - args: Prisma.TraktImportJobFindUniqueOrThrowArgs<ExtArgs> 725 - result: runtime.Types.Utils.PayloadToResult<Prisma.$TraktImportJobPayload> 724 + args: Prisma.BackgroundJobFindUniqueOrThrowArgs<ExtArgs> 725 + result: runtime.Types.Utils.PayloadToResult<Prisma.$BackgroundJobPayload> 726 726 } 727 727 findFirst: { 728 - args: Prisma.TraktImportJobFindFirstArgs<ExtArgs> 729 - result: runtime.Types.Utils.PayloadToResult<Prisma.$TraktImportJobPayload> | null 728 + args: Prisma.BackgroundJobFindFirstArgs<ExtArgs> 729 + result: runtime.Types.Utils.PayloadToResult<Prisma.$BackgroundJobPayload> | null 730 730 } 731 731 findFirstOrThrow: { 732 - args: Prisma.TraktImportJobFindFirstOrThrowArgs<ExtArgs> 733 - result: runtime.Types.Utils.PayloadToResult<Prisma.$TraktImportJobPayload> 732 + args: Prisma.BackgroundJobFindFirstOrThrowArgs<ExtArgs> 733 + result: runtime.Types.Utils.PayloadToResult<Prisma.$BackgroundJobPayload> 734 734 } 735 735 findMany: { 736 - args: Prisma.TraktImportJobFindManyArgs<ExtArgs> 737 - result: runtime.Types.Utils.PayloadToResult<Prisma.$TraktImportJobPayload>[] 736 + args: Prisma.BackgroundJobFindManyArgs<ExtArgs> 737 + result: runtime.Types.Utils.PayloadToResult<Prisma.$BackgroundJobPayload>[] 738 738 } 739 739 create: { 740 - args: Prisma.TraktImportJobCreateArgs<ExtArgs> 741 - result: runtime.Types.Utils.PayloadToResult<Prisma.$TraktImportJobPayload> 740 + args: Prisma.BackgroundJobCreateArgs<ExtArgs> 741 + result: runtime.Types.Utils.PayloadToResult<Prisma.$BackgroundJobPayload> 742 742 } 743 743 createMany: { 744 - args: Prisma.TraktImportJobCreateManyArgs<ExtArgs> 744 + args: Prisma.BackgroundJobCreateManyArgs<ExtArgs> 745 745 result: BatchPayload 746 746 } 747 747 createManyAndReturn: { 748 - args: Prisma.TraktImportJobCreateManyAndReturnArgs<ExtArgs> 749 - result: runtime.Types.Utils.PayloadToResult<Prisma.$TraktImportJobPayload>[] 748 + args: Prisma.BackgroundJobCreateManyAndReturnArgs<ExtArgs> 749 + result: runtime.Types.Utils.PayloadToResult<Prisma.$BackgroundJobPayload>[] 750 750 } 751 751 delete: { 752 - args: Prisma.TraktImportJobDeleteArgs<ExtArgs> 753 - result: runtime.Types.Utils.PayloadToResult<Prisma.$TraktImportJobPayload> 752 + args: Prisma.BackgroundJobDeleteArgs<ExtArgs> 753 + result: runtime.Types.Utils.PayloadToResult<Prisma.$BackgroundJobPayload> 754 754 } 755 755 update: { 756 - args: Prisma.TraktImportJobUpdateArgs<ExtArgs> 757 - result: runtime.Types.Utils.PayloadToResult<Prisma.$TraktImportJobPayload> 756 + args: Prisma.BackgroundJobUpdateArgs<ExtArgs> 757 + result: runtime.Types.Utils.PayloadToResult<Prisma.$BackgroundJobPayload> 758 758 } 759 759 deleteMany: { 760 - args: Prisma.TraktImportJobDeleteManyArgs<ExtArgs> 760 + args: Prisma.BackgroundJobDeleteManyArgs<ExtArgs> 761 761 result: BatchPayload 762 762 } 763 763 updateMany: { 764 - args: Prisma.TraktImportJobUpdateManyArgs<ExtArgs> 764 + args: Prisma.BackgroundJobUpdateManyArgs<ExtArgs> 765 765 result: BatchPayload 766 766 } 767 767 updateManyAndReturn: { 768 - args: Prisma.TraktImportJobUpdateManyAndReturnArgs<ExtArgs> 769 - result: runtime.Types.Utils.PayloadToResult<Prisma.$TraktImportJobPayload>[] 768 + args: Prisma.BackgroundJobUpdateManyAndReturnArgs<ExtArgs> 769 + result: runtime.Types.Utils.PayloadToResult<Prisma.$BackgroundJobPayload>[] 770 770 } 771 771 upsert: { 772 - args: Prisma.TraktImportJobUpsertArgs<ExtArgs> 773 - result: runtime.Types.Utils.PayloadToResult<Prisma.$TraktImportJobPayload> 772 + args: Prisma.BackgroundJobUpsertArgs<ExtArgs> 773 + result: runtime.Types.Utils.PayloadToResult<Prisma.$BackgroundJobPayload> 774 774 } 775 775 aggregate: { 776 - args: Prisma.TraktImportJobAggregateArgs<ExtArgs> 777 - result: runtime.Types.Utils.Optional<Prisma.AggregateTraktImportJob> 776 + args: Prisma.BackgroundJobAggregateArgs<ExtArgs> 777 + result: runtime.Types.Utils.Optional<Prisma.AggregateBackgroundJob> 778 778 } 779 779 groupBy: { 780 - args: Prisma.TraktImportJobGroupByArgs<ExtArgs> 781 - result: runtime.Types.Utils.Optional<Prisma.TraktImportJobGroupByOutputType>[] 780 + args: Prisma.BackgroundJobGroupByArgs<ExtArgs> 781 + result: runtime.Types.Utils.Optional<Prisma.BackgroundJobGroupByOutputType>[] 782 782 } 783 783 count: { 784 - args: Prisma.TraktImportJobCountArgs<ExtArgs> 785 - result: runtime.Types.Utils.Optional<Prisma.TraktImportJobCountAggregateOutputType> | number 784 + args: Prisma.BackgroundJobCountArgs<ExtArgs> 785 + result: runtime.Types.Utils.Optional<Prisma.BackgroundJobCountAggregateOutputType> | number 786 786 } 787 787 } 788 788 } ··· 1472 1472 export type AuthStateScalarFieldEnum = (typeof AuthStateScalarFieldEnum)[keyof typeof AuthStateScalarFieldEnum] 1473 1473 1474 1474 1475 - export const TraktImportJobScalarFieldEnum = { 1475 + export const BackgroundJobScalarFieldEnum = { 1476 1476 id: 'id', 1477 + type: 'type', 1477 1478 userDid: 'userDid', 1478 - traktUsername: 'traktUsername', 1479 1479 status: 'status', 1480 - currentPage: 'currentPage', 1481 - totalPages: 'totalPages', 1482 - sourceCount: 'sourceCount', 1483 - normalizedCount: 'normalizedCount', 1484 - importedCount: 'importedCount', 1485 - skippedCount: 'skippedCount', 1486 - failedCount: 'failedCount', 1480 + data: 'data', 1487 1481 nextRunAt: 'nextRunAt', 1488 1482 lastError: 'lastError', 1489 - profileUsername: 'profileUsername', 1490 - profileSlug: 'profileSlug', 1491 - profileName: 'profileName', 1492 - profileAvatarUrl: 'profileAvatarUrl', 1493 1483 startedAt: 'startedAt', 1494 1484 completedAt: 'completedAt', 1495 1485 createdAt: 'createdAt', 1496 1486 updatedAt: 'updatedAt' 1497 1487 } as const 1498 1488 1499 - export type TraktImportJobScalarFieldEnum = (typeof TraktImportJobScalarFieldEnum)[keyof typeof TraktImportJobScalarFieldEnum] 1489 + export type BackgroundJobScalarFieldEnum = (typeof BackgroundJobScalarFieldEnum)[keyof typeof BackgroundJobScalarFieldEnum] 1500 1490 1501 1491 1502 1492 export const MovieScalarFieldEnum = { ··· 1640 1630 } as const 1641 1631 1642 1632 export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder] 1633 + 1634 + 1635 + export const JsonNullValueInput = { 1636 + JsonNull: JsonNull 1637 + } as const 1638 + 1639 + export type JsonNullValueInput = (typeof JsonNullValueInput)[keyof typeof JsonNullValueInput] 1643 1640 1644 1641 1645 1642 export const NullableJsonNullValueInput = { ··· 1710 1707 1711 1708 1712 1709 /** 1713 - * Reference to a field of type 'TraktImportJobStatus' 1710 + * Reference to a field of type 'Json' 1714 1711 */ 1715 - export type EnumTraktImportJobStatusFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'TraktImportJobStatus'> 1712 + export type JsonFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Json'> 1716 1713 1717 1714 1718 1715 1719 1716 /** 1720 - * Reference to a field of type 'TraktImportJobStatus[]' 1717 + * Reference to a field of type 'QueryMode' 1721 1718 */ 1722 - export type ListEnumTraktImportJobStatusFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'TraktImportJobStatus[]'> 1719 + export type EnumQueryModeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'QueryMode'> 1723 1720 1724 1721 1725 1722 ··· 1734 1731 * Reference to a field of type 'Int[]' 1735 1732 */ 1736 1733 export type ListIntFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Int[]'> 1737 - 1738 - 1739 - 1740 - /** 1741 - * Reference to a field of type 'Json' 1742 - */ 1743 - export type JsonFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Json'> 1744 - 1745 - 1746 - 1747 - /** 1748 - * Reference to a field of type 'QueryMode' 1749 - */ 1750 - export type EnumQueryModeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'QueryMode'> 1751 1734 1752 1735 1753 1736 ··· 1884 1867 follow?: Prisma.FollowOmit 1885 1868 authSession?: Prisma.AuthSessionOmit 1886 1869 authState?: Prisma.AuthStateOmit 1887 - traktImportJob?: Prisma.TraktImportJobOmit 1870 + backgroundJob?: Prisma.BackgroundJobOmit 1888 1871 movie?: Prisma.MovieOmit 1889 1872 show?: Prisma.ShowOmit 1890 1873 season?: Prisma.SeasonOmit
+12 -15
backend/src/generated/internal/prismaNamespaceBrowser.ts
··· 55 55 Follow: 'Follow', 56 56 AuthSession: 'AuthSession', 57 57 AuthState: 'AuthState', 58 - TraktImportJob: 'TraktImportJob', 58 + BackgroundJob: 'BackgroundJob', 59 59 Movie: 'Movie', 60 60 Show: 'Show', 61 61 Season: 'Season', ··· 137 137 export type AuthStateScalarFieldEnum = (typeof AuthStateScalarFieldEnum)[keyof typeof AuthStateScalarFieldEnum] 138 138 139 139 140 - export const TraktImportJobScalarFieldEnum = { 140 + export const BackgroundJobScalarFieldEnum = { 141 141 id: 'id', 142 + type: 'type', 142 143 userDid: 'userDid', 143 - traktUsername: 'traktUsername', 144 144 status: 'status', 145 - currentPage: 'currentPage', 146 - totalPages: 'totalPages', 147 - sourceCount: 'sourceCount', 148 - normalizedCount: 'normalizedCount', 149 - importedCount: 'importedCount', 150 - skippedCount: 'skippedCount', 151 - failedCount: 'failedCount', 145 + data: 'data', 152 146 nextRunAt: 'nextRunAt', 153 147 lastError: 'lastError', 154 - profileUsername: 'profileUsername', 155 - profileSlug: 'profileSlug', 156 - profileName: 'profileName', 157 - profileAvatarUrl: 'profileAvatarUrl', 158 148 startedAt: 'startedAt', 159 149 completedAt: 'completedAt', 160 150 createdAt: 'createdAt', 161 151 updatedAt: 'updatedAt' 162 152 } as const 163 153 164 - export type TraktImportJobScalarFieldEnum = (typeof TraktImportJobScalarFieldEnum)[keyof typeof TraktImportJobScalarFieldEnum] 154 + export type BackgroundJobScalarFieldEnum = (typeof BackgroundJobScalarFieldEnum)[keyof typeof BackgroundJobScalarFieldEnum] 165 155 166 156 167 157 export const MovieScalarFieldEnum = { ··· 305 295 } as const 306 296 307 297 export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder] 298 + 299 + 300 + export const JsonNullValueInput = { 301 + JsonNull: JsonNull 302 + } as const 303 + 304 + export type JsonNullValueInput = (typeof JsonNullValueInput)[keyof typeof JsonNullValueInput] 308 305 309 306 310 307 export const NullableJsonNullValueInput = {
+1 -1
backend/src/generated/models.ts
··· 12 12 export type * from './models/Follow.js' 13 13 export type * from './models/AuthSession.js' 14 14 export type * from './models/AuthState.js' 15 - export type * from './models/TraktImportJob.js' 15 + export type * from './models/BackgroundJob.js' 16 16 export type * from './models/Movie.js' 17 17 export type * from './models/Show.js' 18 18 export type * from './models/Season.js'
+1306
backend/src/generated/models/BackgroundJob.ts
··· 1 + 2 + /* !!! This is code generated by Prisma. Do not edit directly. !!! */ 3 + /* eslint-disable */ 4 + // biome-ignore-all lint: generated file 5 + // @ts-nocheck 6 + /* 7 + * This file exports the `BackgroundJob` model and its related types. 8 + * 9 + * 🟢 You can import this file directly. 10 + */ 11 + import type * as runtime from "@prisma/client/runtime/client" 12 + import type * as $Enums from "../enums.js" 13 + import type * as Prisma from "../internal/prismaNamespace.js" 14 + 15 + /** 16 + * Model BackgroundJob 17 + * 18 + */ 19 + export type BackgroundJobModel = runtime.Types.Result.DefaultSelection<Prisma.$BackgroundJobPayload> 20 + 21 + export type AggregateBackgroundJob = { 22 + _count: BackgroundJobCountAggregateOutputType | null 23 + _min: BackgroundJobMinAggregateOutputType | null 24 + _max: BackgroundJobMaxAggregateOutputType | null 25 + } 26 + 27 + export type BackgroundJobMinAggregateOutputType = { 28 + id: string | null 29 + type: string | null 30 + userDid: string | null 31 + status: string | null 32 + nextRunAt: Date | null 33 + lastError: string | null 34 + startedAt: Date | null 35 + completedAt: Date | null 36 + createdAt: Date | null 37 + updatedAt: Date | null 38 + } 39 + 40 + export type BackgroundJobMaxAggregateOutputType = { 41 + id: string | null 42 + type: string | null 43 + userDid: string | null 44 + status: string | null 45 + nextRunAt: Date | null 46 + lastError: string | null 47 + startedAt: Date | null 48 + completedAt: Date | null 49 + createdAt: Date | null 50 + updatedAt: Date | null 51 + } 52 + 53 + export type BackgroundJobCountAggregateOutputType = { 54 + id: number 55 + type: number 56 + userDid: number 57 + status: number 58 + data: number 59 + nextRunAt: number 60 + lastError: number 61 + startedAt: number 62 + completedAt: number 63 + createdAt: number 64 + updatedAt: number 65 + _all: number 66 + } 67 + 68 + 69 + export type BackgroundJobMinAggregateInputType = { 70 + id?: true 71 + type?: true 72 + userDid?: true 73 + status?: true 74 + nextRunAt?: true 75 + lastError?: true 76 + startedAt?: true 77 + completedAt?: true 78 + createdAt?: true 79 + updatedAt?: true 80 + } 81 + 82 + export type BackgroundJobMaxAggregateInputType = { 83 + id?: true 84 + type?: true 85 + userDid?: true 86 + status?: true 87 + nextRunAt?: true 88 + lastError?: true 89 + startedAt?: true 90 + completedAt?: true 91 + createdAt?: true 92 + updatedAt?: true 93 + } 94 + 95 + export type BackgroundJobCountAggregateInputType = { 96 + id?: true 97 + type?: true 98 + userDid?: true 99 + status?: true 100 + data?: true 101 + nextRunAt?: true 102 + lastError?: true 103 + startedAt?: true 104 + completedAt?: true 105 + createdAt?: true 106 + updatedAt?: true 107 + _all?: true 108 + } 109 + 110 + export type BackgroundJobAggregateArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 111 + /** 112 + * Filter which BackgroundJob to aggregate. 113 + */ 114 + where?: Prisma.BackgroundJobWhereInput 115 + /** 116 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} 117 + * 118 + * Determine the order of BackgroundJobs to fetch. 119 + */ 120 + orderBy?: Prisma.BackgroundJobOrderByWithRelationInput | Prisma.BackgroundJobOrderByWithRelationInput[] 121 + /** 122 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} 123 + * 124 + * Sets the start position 125 + */ 126 + cursor?: Prisma.BackgroundJobWhereUniqueInput 127 + /** 128 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 129 + * 130 + * Take `±n` BackgroundJobs from the position of the cursor. 131 + */ 132 + take?: number 133 + /** 134 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 135 + * 136 + * Skip the first `n` BackgroundJobs. 137 + */ 138 + skip?: number 139 + /** 140 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} 141 + * 142 + * Count returned BackgroundJobs 143 + **/ 144 + _count?: true | BackgroundJobCountAggregateInputType 145 + /** 146 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} 147 + * 148 + * Select which fields to find the minimum value 149 + **/ 150 + _min?: BackgroundJobMinAggregateInputType 151 + /** 152 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} 153 + * 154 + * Select which fields to find the maximum value 155 + **/ 156 + _max?: BackgroundJobMaxAggregateInputType 157 + } 158 + 159 + export type GetBackgroundJobAggregateType<T extends BackgroundJobAggregateArgs> = { 160 + [P in keyof T & keyof AggregateBackgroundJob]: P extends '_count' | 'count' 161 + ? T[P] extends true 162 + ? number 163 + : Prisma.GetScalarType<T[P], AggregateBackgroundJob[P]> 164 + : Prisma.GetScalarType<T[P], AggregateBackgroundJob[P]> 165 + } 166 + 167 + 168 + 169 + 170 + export type BackgroundJobGroupByArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 171 + where?: Prisma.BackgroundJobWhereInput 172 + orderBy?: Prisma.BackgroundJobOrderByWithAggregationInput | Prisma.BackgroundJobOrderByWithAggregationInput[] 173 + by: Prisma.BackgroundJobScalarFieldEnum[] | Prisma.BackgroundJobScalarFieldEnum 174 + having?: Prisma.BackgroundJobScalarWhereWithAggregatesInput 175 + take?: number 176 + skip?: number 177 + _count?: BackgroundJobCountAggregateInputType | true 178 + _min?: BackgroundJobMinAggregateInputType 179 + _max?: BackgroundJobMaxAggregateInputType 180 + } 181 + 182 + export type BackgroundJobGroupByOutputType = { 183 + id: string 184 + type: string 185 + userDid: string 186 + status: string 187 + data: runtime.JsonValue 188 + nextRunAt: Date 189 + lastError: string | null 190 + startedAt: Date | null 191 + completedAt: Date | null 192 + createdAt: Date 193 + updatedAt: Date 194 + _count: BackgroundJobCountAggregateOutputType | null 195 + _min: BackgroundJobMinAggregateOutputType | null 196 + _max: BackgroundJobMaxAggregateOutputType | null 197 + } 198 + 199 + type GetBackgroundJobGroupByPayload<T extends BackgroundJobGroupByArgs> = Prisma.PrismaPromise< 200 + Array< 201 + Prisma.PickEnumerable<BackgroundJobGroupByOutputType, T['by']> & 202 + { 203 + [P in ((keyof T) & (keyof BackgroundJobGroupByOutputType))]: P extends '_count' 204 + ? T[P] extends boolean 205 + ? number 206 + : Prisma.GetScalarType<T[P], BackgroundJobGroupByOutputType[P]> 207 + : Prisma.GetScalarType<T[P], BackgroundJobGroupByOutputType[P]> 208 + } 209 + > 210 + > 211 + 212 + 213 + 214 + export type BackgroundJobWhereInput = { 215 + AND?: Prisma.BackgroundJobWhereInput | Prisma.BackgroundJobWhereInput[] 216 + OR?: Prisma.BackgroundJobWhereInput[] 217 + NOT?: Prisma.BackgroundJobWhereInput | Prisma.BackgroundJobWhereInput[] 218 + id?: Prisma.StringFilter<"BackgroundJob"> | string 219 + type?: Prisma.StringFilter<"BackgroundJob"> | string 220 + userDid?: Prisma.StringFilter<"BackgroundJob"> | string 221 + status?: Prisma.StringFilter<"BackgroundJob"> | string 222 + data?: Prisma.JsonFilter<"BackgroundJob"> 223 + nextRunAt?: Prisma.DateTimeFilter<"BackgroundJob"> | Date | string 224 + lastError?: Prisma.StringNullableFilter<"BackgroundJob"> | string | null 225 + startedAt?: Prisma.DateTimeNullableFilter<"BackgroundJob"> | Date | string | null 226 + completedAt?: Prisma.DateTimeNullableFilter<"BackgroundJob"> | Date | string | null 227 + createdAt?: Prisma.DateTimeFilter<"BackgroundJob"> | Date | string 228 + updatedAt?: Prisma.DateTimeFilter<"BackgroundJob"> | Date | string 229 + } 230 + 231 + export type BackgroundJobOrderByWithRelationInput = { 232 + id?: Prisma.SortOrder 233 + type?: Prisma.SortOrder 234 + userDid?: Prisma.SortOrder 235 + status?: Prisma.SortOrder 236 + data?: Prisma.SortOrder 237 + nextRunAt?: Prisma.SortOrder 238 + lastError?: Prisma.SortOrderInput | Prisma.SortOrder 239 + startedAt?: Prisma.SortOrderInput | Prisma.SortOrder 240 + completedAt?: Prisma.SortOrderInput | Prisma.SortOrder 241 + createdAt?: Prisma.SortOrder 242 + updatedAt?: Prisma.SortOrder 243 + } 244 + 245 + export type BackgroundJobWhereUniqueInput = Prisma.AtLeast<{ 246 + id?: string 247 + AND?: Prisma.BackgroundJobWhereInput | Prisma.BackgroundJobWhereInput[] 248 + OR?: Prisma.BackgroundJobWhereInput[] 249 + NOT?: Prisma.BackgroundJobWhereInput | Prisma.BackgroundJobWhereInput[] 250 + type?: Prisma.StringFilter<"BackgroundJob"> | string 251 + userDid?: Prisma.StringFilter<"BackgroundJob"> | string 252 + status?: Prisma.StringFilter<"BackgroundJob"> | string 253 + data?: Prisma.JsonFilter<"BackgroundJob"> 254 + nextRunAt?: Prisma.DateTimeFilter<"BackgroundJob"> | Date | string 255 + lastError?: Prisma.StringNullableFilter<"BackgroundJob"> | string | null 256 + startedAt?: Prisma.DateTimeNullableFilter<"BackgroundJob"> | Date | string | null 257 + completedAt?: Prisma.DateTimeNullableFilter<"BackgroundJob"> | Date | string | null 258 + createdAt?: Prisma.DateTimeFilter<"BackgroundJob"> | Date | string 259 + updatedAt?: Prisma.DateTimeFilter<"BackgroundJob"> | Date | string 260 + }, "id"> 261 + 262 + export type BackgroundJobOrderByWithAggregationInput = { 263 + id?: Prisma.SortOrder 264 + type?: Prisma.SortOrder 265 + userDid?: Prisma.SortOrder 266 + status?: Prisma.SortOrder 267 + data?: Prisma.SortOrder 268 + nextRunAt?: Prisma.SortOrder 269 + lastError?: Prisma.SortOrderInput | Prisma.SortOrder 270 + startedAt?: Prisma.SortOrderInput | Prisma.SortOrder 271 + completedAt?: Prisma.SortOrderInput | Prisma.SortOrder 272 + createdAt?: Prisma.SortOrder 273 + updatedAt?: Prisma.SortOrder 274 + _count?: Prisma.BackgroundJobCountOrderByAggregateInput 275 + _max?: Prisma.BackgroundJobMaxOrderByAggregateInput 276 + _min?: Prisma.BackgroundJobMinOrderByAggregateInput 277 + } 278 + 279 + export type BackgroundJobScalarWhereWithAggregatesInput = { 280 + AND?: Prisma.BackgroundJobScalarWhereWithAggregatesInput | Prisma.BackgroundJobScalarWhereWithAggregatesInput[] 281 + OR?: Prisma.BackgroundJobScalarWhereWithAggregatesInput[] 282 + NOT?: Prisma.BackgroundJobScalarWhereWithAggregatesInput | Prisma.BackgroundJobScalarWhereWithAggregatesInput[] 283 + id?: Prisma.StringWithAggregatesFilter<"BackgroundJob"> | string 284 + type?: Prisma.StringWithAggregatesFilter<"BackgroundJob"> | string 285 + userDid?: Prisma.StringWithAggregatesFilter<"BackgroundJob"> | string 286 + status?: Prisma.StringWithAggregatesFilter<"BackgroundJob"> | string 287 + data?: Prisma.JsonWithAggregatesFilter<"BackgroundJob"> 288 + nextRunAt?: Prisma.DateTimeWithAggregatesFilter<"BackgroundJob"> | Date | string 289 + lastError?: Prisma.StringNullableWithAggregatesFilter<"BackgroundJob"> | string | null 290 + startedAt?: Prisma.DateTimeNullableWithAggregatesFilter<"BackgroundJob"> | Date | string | null 291 + completedAt?: Prisma.DateTimeNullableWithAggregatesFilter<"BackgroundJob"> | Date | string | null 292 + createdAt?: Prisma.DateTimeWithAggregatesFilter<"BackgroundJob"> | Date | string 293 + updatedAt?: Prisma.DateTimeWithAggregatesFilter<"BackgroundJob"> | Date | string 294 + } 295 + 296 + export type BackgroundJobCreateInput = { 297 + id?: string 298 + type: string 299 + userDid: string 300 + status?: string 301 + data?: Prisma.JsonNullValueInput | runtime.InputJsonValue 302 + nextRunAt?: Date | string 303 + lastError?: string | null 304 + startedAt?: Date | string | null 305 + completedAt?: Date | string | null 306 + createdAt?: Date | string 307 + updatedAt?: Date | string 308 + } 309 + 310 + export type BackgroundJobUncheckedCreateInput = { 311 + id?: string 312 + type: string 313 + userDid: string 314 + status?: string 315 + data?: Prisma.JsonNullValueInput | runtime.InputJsonValue 316 + nextRunAt?: Date | string 317 + lastError?: string | null 318 + startedAt?: Date | string | null 319 + completedAt?: Date | string | null 320 + createdAt?: Date | string 321 + updatedAt?: Date | string 322 + } 323 + 324 + export type BackgroundJobUpdateInput = { 325 + id?: Prisma.StringFieldUpdateOperationsInput | string 326 + type?: Prisma.StringFieldUpdateOperationsInput | string 327 + userDid?: Prisma.StringFieldUpdateOperationsInput | string 328 + status?: Prisma.StringFieldUpdateOperationsInput | string 329 + data?: Prisma.JsonNullValueInput | runtime.InputJsonValue 330 + nextRunAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 331 + lastError?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 332 + startedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 333 + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 334 + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 335 + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 336 + } 337 + 338 + export type BackgroundJobUncheckedUpdateInput = { 339 + id?: Prisma.StringFieldUpdateOperationsInput | string 340 + type?: Prisma.StringFieldUpdateOperationsInput | string 341 + userDid?: Prisma.StringFieldUpdateOperationsInput | string 342 + status?: Prisma.StringFieldUpdateOperationsInput | string 343 + data?: Prisma.JsonNullValueInput | runtime.InputJsonValue 344 + nextRunAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 345 + lastError?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 346 + startedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 347 + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 348 + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 349 + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 350 + } 351 + 352 + export type BackgroundJobCreateManyInput = { 353 + id?: string 354 + type: string 355 + userDid: string 356 + status?: string 357 + data?: Prisma.JsonNullValueInput | runtime.InputJsonValue 358 + nextRunAt?: Date | string 359 + lastError?: string | null 360 + startedAt?: Date | string | null 361 + completedAt?: Date | string | null 362 + createdAt?: Date | string 363 + updatedAt?: Date | string 364 + } 365 + 366 + export type BackgroundJobUpdateManyMutationInput = { 367 + id?: Prisma.StringFieldUpdateOperationsInput | string 368 + type?: Prisma.StringFieldUpdateOperationsInput | string 369 + userDid?: Prisma.StringFieldUpdateOperationsInput | string 370 + status?: Prisma.StringFieldUpdateOperationsInput | string 371 + data?: Prisma.JsonNullValueInput | runtime.InputJsonValue 372 + nextRunAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 373 + lastError?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 374 + startedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 375 + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 376 + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 377 + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 378 + } 379 + 380 + export type BackgroundJobUncheckedUpdateManyInput = { 381 + id?: Prisma.StringFieldUpdateOperationsInput | string 382 + type?: Prisma.StringFieldUpdateOperationsInput | string 383 + userDid?: Prisma.StringFieldUpdateOperationsInput | string 384 + status?: Prisma.StringFieldUpdateOperationsInput | string 385 + data?: Prisma.JsonNullValueInput | runtime.InputJsonValue 386 + nextRunAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 387 + lastError?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 388 + startedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 389 + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 390 + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 391 + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 392 + } 393 + 394 + export type BackgroundJobCountOrderByAggregateInput = { 395 + id?: Prisma.SortOrder 396 + type?: Prisma.SortOrder 397 + userDid?: Prisma.SortOrder 398 + status?: Prisma.SortOrder 399 + data?: Prisma.SortOrder 400 + nextRunAt?: Prisma.SortOrder 401 + lastError?: Prisma.SortOrder 402 + startedAt?: Prisma.SortOrder 403 + completedAt?: Prisma.SortOrder 404 + createdAt?: Prisma.SortOrder 405 + updatedAt?: Prisma.SortOrder 406 + } 407 + 408 + export type BackgroundJobMaxOrderByAggregateInput = { 409 + id?: Prisma.SortOrder 410 + type?: Prisma.SortOrder 411 + userDid?: Prisma.SortOrder 412 + status?: Prisma.SortOrder 413 + nextRunAt?: Prisma.SortOrder 414 + lastError?: Prisma.SortOrder 415 + startedAt?: Prisma.SortOrder 416 + completedAt?: Prisma.SortOrder 417 + createdAt?: Prisma.SortOrder 418 + updatedAt?: Prisma.SortOrder 419 + } 420 + 421 + export type BackgroundJobMinOrderByAggregateInput = { 422 + id?: Prisma.SortOrder 423 + type?: Prisma.SortOrder 424 + userDid?: Prisma.SortOrder 425 + status?: Prisma.SortOrder 426 + nextRunAt?: Prisma.SortOrder 427 + lastError?: Prisma.SortOrder 428 + startedAt?: Prisma.SortOrder 429 + completedAt?: Prisma.SortOrder 430 + createdAt?: Prisma.SortOrder 431 + updatedAt?: Prisma.SortOrder 432 + } 433 + 434 + 435 + 436 + export type BackgroundJobSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{ 437 + id?: boolean 438 + type?: boolean 439 + userDid?: boolean 440 + status?: boolean 441 + data?: boolean 442 + nextRunAt?: boolean 443 + lastError?: boolean 444 + startedAt?: boolean 445 + completedAt?: boolean 446 + createdAt?: boolean 447 + updatedAt?: boolean 448 + }, ExtArgs["result"]["backgroundJob"]> 449 + 450 + export type BackgroundJobSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{ 451 + id?: boolean 452 + type?: boolean 453 + userDid?: boolean 454 + status?: boolean 455 + data?: boolean 456 + nextRunAt?: boolean 457 + lastError?: boolean 458 + startedAt?: boolean 459 + completedAt?: boolean 460 + createdAt?: boolean 461 + updatedAt?: boolean 462 + }, ExtArgs["result"]["backgroundJob"]> 463 + 464 + export type BackgroundJobSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{ 465 + id?: boolean 466 + type?: boolean 467 + userDid?: boolean 468 + status?: boolean 469 + data?: boolean 470 + nextRunAt?: boolean 471 + lastError?: boolean 472 + startedAt?: boolean 473 + completedAt?: boolean 474 + createdAt?: boolean 475 + updatedAt?: boolean 476 + }, ExtArgs["result"]["backgroundJob"]> 477 + 478 + export type BackgroundJobSelectScalar = { 479 + id?: boolean 480 + type?: boolean 481 + userDid?: boolean 482 + status?: boolean 483 + data?: boolean 484 + nextRunAt?: boolean 485 + lastError?: boolean 486 + startedAt?: boolean 487 + completedAt?: boolean 488 + createdAt?: boolean 489 + updatedAt?: boolean 490 + } 491 + 492 + export type BackgroundJobOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "type" | "userDid" | "status" | "data" | "nextRunAt" | "lastError" | "startedAt" | "completedAt" | "createdAt" | "updatedAt", ExtArgs["result"]["backgroundJob"]> 493 + 494 + export type $BackgroundJobPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 495 + name: "BackgroundJob" 496 + objects: {} 497 + scalars: runtime.Types.Extensions.GetPayloadResult<{ 498 + id: string 499 + type: string 500 + userDid: string 501 + status: string 502 + data: runtime.JsonValue 503 + nextRunAt: Date 504 + lastError: string | null 505 + startedAt: Date | null 506 + completedAt: Date | null 507 + createdAt: Date 508 + updatedAt: Date 509 + }, ExtArgs["result"]["backgroundJob"]> 510 + composites: {} 511 + } 512 + 513 + export type BackgroundJobGetPayload<S extends boolean | null | undefined | BackgroundJobDefaultArgs> = runtime.Types.Result.GetResult<Prisma.$BackgroundJobPayload, S> 514 + 515 + export type BackgroundJobCountArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = 516 + Omit<BackgroundJobFindManyArgs, 'select' | 'include' | 'distinct' | 'omit'> & { 517 + select?: BackgroundJobCountAggregateInputType | true 518 + } 519 + 520 + export interface BackgroundJobDelegate<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs, GlobalOmitOptions = {}> { 521 + [K: symbol]: { types: Prisma.TypeMap<ExtArgs>['model']['BackgroundJob'], meta: { name: 'BackgroundJob' } } 522 + /** 523 + * Find zero or one BackgroundJob that matches the filter. 524 + * @param {BackgroundJobFindUniqueArgs} args - Arguments to find a BackgroundJob 525 + * @example 526 + * // Get one BackgroundJob 527 + * const backgroundJob = await prisma.backgroundJob.findUnique({ 528 + * where: { 529 + * // ... provide filter here 530 + * } 531 + * }) 532 + */ 533 + findUnique<T extends BackgroundJobFindUniqueArgs>(args: Prisma.SelectSubset<T, BackgroundJobFindUniqueArgs<ExtArgs>>): Prisma.Prisma__BackgroundJobClient<runtime.Types.Result.GetResult<Prisma.$BackgroundJobPayload<ExtArgs>, T, "findUnique", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> 534 + 535 + /** 536 + * Find one BackgroundJob that matches the filter or throw an error with `error.code='P2025'` 537 + * if no matches were found. 538 + * @param {BackgroundJobFindUniqueOrThrowArgs} args - Arguments to find a BackgroundJob 539 + * @example 540 + * // Get one BackgroundJob 541 + * const backgroundJob = await prisma.backgroundJob.findUniqueOrThrow({ 542 + * where: { 543 + * // ... provide filter here 544 + * } 545 + * }) 546 + */ 547 + findUniqueOrThrow<T extends BackgroundJobFindUniqueOrThrowArgs>(args: Prisma.SelectSubset<T, BackgroundJobFindUniqueOrThrowArgs<ExtArgs>>): Prisma.Prisma__BackgroundJobClient<runtime.Types.Result.GetResult<Prisma.$BackgroundJobPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> 548 + 549 + /** 550 + * Find the first BackgroundJob that matches the filter. 551 + * Note, that providing `undefined` is treated as the value not being there. 552 + * Read more here: https://pris.ly/d/null-undefined 553 + * @param {BackgroundJobFindFirstArgs} args - Arguments to find a BackgroundJob 554 + * @example 555 + * // Get one BackgroundJob 556 + * const backgroundJob = await prisma.backgroundJob.findFirst({ 557 + * where: { 558 + * // ... provide filter here 559 + * } 560 + * }) 561 + */ 562 + findFirst<T extends BackgroundJobFindFirstArgs>(args?: Prisma.SelectSubset<T, BackgroundJobFindFirstArgs<ExtArgs>>): Prisma.Prisma__BackgroundJobClient<runtime.Types.Result.GetResult<Prisma.$BackgroundJobPayload<ExtArgs>, T, "findFirst", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> 563 + 564 + /** 565 + * Find the first BackgroundJob that matches the filter or 566 + * throw `PrismaKnownClientError` with `P2025` code if no matches were found. 567 + * Note, that providing `undefined` is treated as the value not being there. 568 + * Read more here: https://pris.ly/d/null-undefined 569 + * @param {BackgroundJobFindFirstOrThrowArgs} args - Arguments to find a BackgroundJob 570 + * @example 571 + * // Get one BackgroundJob 572 + * const backgroundJob = await prisma.backgroundJob.findFirstOrThrow({ 573 + * where: { 574 + * // ... provide filter here 575 + * } 576 + * }) 577 + */ 578 + findFirstOrThrow<T extends BackgroundJobFindFirstOrThrowArgs>(args?: Prisma.SelectSubset<T, BackgroundJobFindFirstOrThrowArgs<ExtArgs>>): Prisma.Prisma__BackgroundJobClient<runtime.Types.Result.GetResult<Prisma.$BackgroundJobPayload<ExtArgs>, T, "findFirstOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> 579 + 580 + /** 581 + * Find zero or more BackgroundJobs that matches the filter. 582 + * Note, that providing `undefined` is treated as the value not being there. 583 + * Read more here: https://pris.ly/d/null-undefined 584 + * @param {BackgroundJobFindManyArgs} args - Arguments to filter and select certain fields only. 585 + * @example 586 + * // Get all BackgroundJobs 587 + * const backgroundJobs = await prisma.backgroundJob.findMany() 588 + * 589 + * // Get first 10 BackgroundJobs 590 + * const backgroundJobs = await prisma.backgroundJob.findMany({ take: 10 }) 591 + * 592 + * // Only select the `id` 593 + * const backgroundJobWithIdOnly = await prisma.backgroundJob.findMany({ select: { id: true } }) 594 + * 595 + */ 596 + findMany<T extends BackgroundJobFindManyArgs>(args?: Prisma.SelectSubset<T, BackgroundJobFindManyArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$BackgroundJobPayload<ExtArgs>, T, "findMany", GlobalOmitOptions>> 597 + 598 + /** 599 + * Create a BackgroundJob. 600 + * @param {BackgroundJobCreateArgs} args - Arguments to create a BackgroundJob. 601 + * @example 602 + * // Create one BackgroundJob 603 + * const BackgroundJob = await prisma.backgroundJob.create({ 604 + * data: { 605 + * // ... data to create a BackgroundJob 606 + * } 607 + * }) 608 + * 609 + */ 610 + create<T extends BackgroundJobCreateArgs>(args: Prisma.SelectSubset<T, BackgroundJobCreateArgs<ExtArgs>>): Prisma.Prisma__BackgroundJobClient<runtime.Types.Result.GetResult<Prisma.$BackgroundJobPayload<ExtArgs>, T, "create", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> 611 + 612 + /** 613 + * Create many BackgroundJobs. 614 + * @param {BackgroundJobCreateManyArgs} args - Arguments to create many BackgroundJobs. 615 + * @example 616 + * // Create many BackgroundJobs 617 + * const backgroundJob = await prisma.backgroundJob.createMany({ 618 + * data: [ 619 + * // ... provide data here 620 + * ] 621 + * }) 622 + * 623 + */ 624 + createMany<T extends BackgroundJobCreateManyArgs>(args?: Prisma.SelectSubset<T, BackgroundJobCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload> 625 + 626 + /** 627 + * Create many BackgroundJobs and returns the data saved in the database. 628 + * @param {BackgroundJobCreateManyAndReturnArgs} args - Arguments to create many BackgroundJobs. 629 + * @example 630 + * // Create many BackgroundJobs 631 + * const backgroundJob = await prisma.backgroundJob.createManyAndReturn({ 632 + * data: [ 633 + * // ... provide data here 634 + * ] 635 + * }) 636 + * 637 + * // Create many BackgroundJobs and only return the `id` 638 + * const backgroundJobWithIdOnly = await prisma.backgroundJob.createManyAndReturn({ 639 + * select: { id: true }, 640 + * data: [ 641 + * // ... provide data here 642 + * ] 643 + * }) 644 + * Note, that providing `undefined` is treated as the value not being there. 645 + * Read more here: https://pris.ly/d/null-undefined 646 + * 647 + */ 648 + createManyAndReturn<T extends BackgroundJobCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, BackgroundJobCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$BackgroundJobPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>> 649 + 650 + /** 651 + * Delete a BackgroundJob. 652 + * @param {BackgroundJobDeleteArgs} args - Arguments to delete one BackgroundJob. 653 + * @example 654 + * // Delete one BackgroundJob 655 + * const BackgroundJob = await prisma.backgroundJob.delete({ 656 + * where: { 657 + * // ... filter to delete one BackgroundJob 658 + * } 659 + * }) 660 + * 661 + */ 662 + delete<T extends BackgroundJobDeleteArgs>(args: Prisma.SelectSubset<T, BackgroundJobDeleteArgs<ExtArgs>>): Prisma.Prisma__BackgroundJobClient<runtime.Types.Result.GetResult<Prisma.$BackgroundJobPayload<ExtArgs>, T, "delete", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> 663 + 664 + /** 665 + * Update one BackgroundJob. 666 + * @param {BackgroundJobUpdateArgs} args - Arguments to update one BackgroundJob. 667 + * @example 668 + * // Update one BackgroundJob 669 + * const backgroundJob = await prisma.backgroundJob.update({ 670 + * where: { 671 + * // ... provide filter here 672 + * }, 673 + * data: { 674 + * // ... provide data here 675 + * } 676 + * }) 677 + * 678 + */ 679 + update<T extends BackgroundJobUpdateArgs>(args: Prisma.SelectSubset<T, BackgroundJobUpdateArgs<ExtArgs>>): Prisma.Prisma__BackgroundJobClient<runtime.Types.Result.GetResult<Prisma.$BackgroundJobPayload<ExtArgs>, T, "update", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> 680 + 681 + /** 682 + * Delete zero or more BackgroundJobs. 683 + * @param {BackgroundJobDeleteManyArgs} args - Arguments to filter BackgroundJobs to delete. 684 + * @example 685 + * // Delete a few BackgroundJobs 686 + * const { count } = await prisma.backgroundJob.deleteMany({ 687 + * where: { 688 + * // ... provide filter here 689 + * } 690 + * }) 691 + * 692 + */ 693 + deleteMany<T extends BackgroundJobDeleteManyArgs>(args?: Prisma.SelectSubset<T, BackgroundJobDeleteManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload> 694 + 695 + /** 696 + * Update zero or more BackgroundJobs. 697 + * Note, that providing `undefined` is treated as the value not being there. 698 + * Read more here: https://pris.ly/d/null-undefined 699 + * @param {BackgroundJobUpdateManyArgs} args - Arguments to update one or more rows. 700 + * @example 701 + * // Update many BackgroundJobs 702 + * const backgroundJob = await prisma.backgroundJob.updateMany({ 703 + * where: { 704 + * // ... provide filter here 705 + * }, 706 + * data: { 707 + * // ... provide data here 708 + * } 709 + * }) 710 + * 711 + */ 712 + updateMany<T extends BackgroundJobUpdateManyArgs>(args: Prisma.SelectSubset<T, BackgroundJobUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload> 713 + 714 + /** 715 + * Update zero or more BackgroundJobs and returns the data updated in the database. 716 + * @param {BackgroundJobUpdateManyAndReturnArgs} args - Arguments to update many BackgroundJobs. 717 + * @example 718 + * // Update many BackgroundJobs 719 + * const backgroundJob = await prisma.backgroundJob.updateManyAndReturn({ 720 + * where: { 721 + * // ... provide filter here 722 + * }, 723 + * data: [ 724 + * // ... provide data here 725 + * ] 726 + * }) 727 + * 728 + * // Update zero or more BackgroundJobs and only return the `id` 729 + * const backgroundJobWithIdOnly = await prisma.backgroundJob.updateManyAndReturn({ 730 + * select: { id: true }, 731 + * where: { 732 + * // ... provide filter here 733 + * }, 734 + * data: [ 735 + * // ... provide data here 736 + * ] 737 + * }) 738 + * Note, that providing `undefined` is treated as the value not being there. 739 + * Read more here: https://pris.ly/d/null-undefined 740 + * 741 + */ 742 + updateManyAndReturn<T extends BackgroundJobUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, BackgroundJobUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$BackgroundJobPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>> 743 + 744 + /** 745 + * Create or update one BackgroundJob. 746 + * @param {BackgroundJobUpsertArgs} args - Arguments to update or create a BackgroundJob. 747 + * @example 748 + * // Update or create a BackgroundJob 749 + * const backgroundJob = await prisma.backgroundJob.upsert({ 750 + * create: { 751 + * // ... data to create a BackgroundJob 752 + * }, 753 + * update: { 754 + * // ... in case it already exists, update 755 + * }, 756 + * where: { 757 + * // ... the filter for the BackgroundJob we want to update 758 + * } 759 + * }) 760 + */ 761 + upsert<T extends BackgroundJobUpsertArgs>(args: Prisma.SelectSubset<T, BackgroundJobUpsertArgs<ExtArgs>>): Prisma.Prisma__BackgroundJobClient<runtime.Types.Result.GetResult<Prisma.$BackgroundJobPayload<ExtArgs>, T, "upsert", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> 762 + 763 + 764 + /** 765 + * Count the number of BackgroundJobs. 766 + * Note, that providing `undefined` is treated as the value not being there. 767 + * Read more here: https://pris.ly/d/null-undefined 768 + * @param {BackgroundJobCountArgs} args - Arguments to filter BackgroundJobs to count. 769 + * @example 770 + * // Count the number of BackgroundJobs 771 + * const count = await prisma.backgroundJob.count({ 772 + * where: { 773 + * // ... the filter for the BackgroundJobs we want to count 774 + * } 775 + * }) 776 + **/ 777 + count<T extends BackgroundJobCountArgs>( 778 + args?: Prisma.Subset<T, BackgroundJobCountArgs>, 779 + ): Prisma.PrismaPromise< 780 + T extends runtime.Types.Utils.Record<'select', any> 781 + ? T['select'] extends true 782 + ? number 783 + : Prisma.GetScalarType<T['select'], BackgroundJobCountAggregateOutputType> 784 + : number 785 + > 786 + 787 + /** 788 + * Allows you to perform aggregations operations on a BackgroundJob. 789 + * Note, that providing `undefined` is treated as the value not being there. 790 + * Read more here: https://pris.ly/d/null-undefined 791 + * @param {BackgroundJobAggregateArgs} args - Select which aggregations you would like to apply and on what fields. 792 + * @example 793 + * // Ordered by age ascending 794 + * // Where email contains prisma.io 795 + * // Limited to the 10 users 796 + * const aggregations = await prisma.user.aggregate({ 797 + * _avg: { 798 + * age: true, 799 + * }, 800 + * where: { 801 + * email: { 802 + * contains: "prisma.io", 803 + * }, 804 + * }, 805 + * orderBy: { 806 + * age: "asc", 807 + * }, 808 + * take: 10, 809 + * }) 810 + **/ 811 + aggregate<T extends BackgroundJobAggregateArgs>(args: Prisma.Subset<T, BackgroundJobAggregateArgs>): Prisma.PrismaPromise<GetBackgroundJobAggregateType<T>> 812 + 813 + /** 814 + * Group by BackgroundJob. 815 + * Note, that providing `undefined` is treated as the value not being there. 816 + * Read more here: https://pris.ly/d/null-undefined 817 + * @param {BackgroundJobGroupByArgs} args - Group by arguments. 818 + * @example 819 + * // Group by city, order by createdAt, get count 820 + * const result = await prisma.user.groupBy({ 821 + * by: ['city', 'createdAt'], 822 + * orderBy: { 823 + * createdAt: true 824 + * }, 825 + * _count: { 826 + * _all: true 827 + * }, 828 + * }) 829 + * 830 + **/ 831 + groupBy< 832 + T extends BackgroundJobGroupByArgs, 833 + HasSelectOrTake extends Prisma.Or< 834 + Prisma.Extends<'skip', Prisma.Keys<T>>, 835 + Prisma.Extends<'take', Prisma.Keys<T>> 836 + >, 837 + OrderByArg extends Prisma.True extends HasSelectOrTake 838 + ? { orderBy: BackgroundJobGroupByArgs['orderBy'] } 839 + : { orderBy?: BackgroundJobGroupByArgs['orderBy'] }, 840 + OrderFields extends Prisma.ExcludeUnderscoreKeys<Prisma.Keys<Prisma.MaybeTupleToUnion<T['orderBy']>>>, 841 + ByFields extends Prisma.MaybeTupleToUnion<T['by']>, 842 + ByValid extends Prisma.Has<ByFields, OrderFields>, 843 + HavingFields extends Prisma.GetHavingFields<T['having']>, 844 + HavingValid extends Prisma.Has<ByFields, HavingFields>, 845 + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, 846 + InputErrors extends ByEmpty extends Prisma.True 847 + ? `Error: "by" must not be empty.` 848 + : HavingValid extends Prisma.False 849 + ? { 850 + [P in HavingFields]: P extends ByFields 851 + ? never 852 + : P extends string 853 + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` 854 + : [ 855 + Error, 856 + 'Field ', 857 + P, 858 + ` in "having" needs to be provided in "by"`, 859 + ] 860 + }[HavingFields] 861 + : 'take' extends Prisma.Keys<T> 862 + ? 'orderBy' extends Prisma.Keys<T> 863 + ? ByValid extends Prisma.True 864 + ? {} 865 + : { 866 + [P in OrderFields]: P extends ByFields 867 + ? never 868 + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 869 + }[OrderFields] 870 + : 'Error: If you provide "take", you also need to provide "orderBy"' 871 + : 'skip' extends Prisma.Keys<T> 872 + ? 'orderBy' extends Prisma.Keys<T> 873 + ? ByValid extends Prisma.True 874 + ? {} 875 + : { 876 + [P in OrderFields]: P extends ByFields 877 + ? never 878 + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 879 + }[OrderFields] 880 + : 'Error: If you provide "skip", you also need to provide "orderBy"' 881 + : ByValid extends Prisma.True 882 + ? {} 883 + : { 884 + [P in OrderFields]: P extends ByFields 885 + ? never 886 + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 887 + }[OrderFields] 888 + >(args: Prisma.SubsetIntersection<T, BackgroundJobGroupByArgs, OrderByArg> & InputErrors): {} extends InputErrors ? GetBackgroundJobGroupByPayload<T> : Prisma.PrismaPromise<InputErrors> 889 + /** 890 + * Fields of the BackgroundJob model 891 + */ 892 + readonly fields: BackgroundJobFieldRefs; 893 + } 894 + 895 + /** 896 + * The delegate class that acts as a "Promise-like" for BackgroundJob. 897 + * Why is this prefixed with `Prisma__`? 898 + * Because we want to prevent naming conflicts as mentioned in 899 + * https://github.com/prisma/prisma-client-js/issues/707 900 + */ 901 + export interface Prisma__BackgroundJobClient<T, Null = never, ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs, GlobalOmitOptions = {}> extends Prisma.PrismaPromise<T> { 902 + readonly [Symbol.toStringTag]: "PrismaPromise" 903 + /** 904 + * Attaches callbacks for the resolution and/or rejection of the Promise. 905 + * @param onfulfilled The callback to execute when the Promise is resolved. 906 + * @param onrejected The callback to execute when the Promise is rejected. 907 + * @returns A Promise for the completion of which ever callback is executed. 908 + */ 909 + then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): runtime.Types.Utils.JsPromise<TResult1 | TResult2> 910 + /** 911 + * Attaches a callback for only the rejection of the Promise. 912 + * @param onrejected The callback to execute when the Promise is rejected. 913 + * @returns A Promise for the completion of the callback. 914 + */ 915 + catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): runtime.Types.Utils.JsPromise<T | TResult> 916 + /** 917 + * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The 918 + * resolved value cannot be modified from the callback. 919 + * @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected). 920 + * @returns A Promise for the completion of the callback. 921 + */ 922 + finally(onfinally?: (() => void) | undefined | null): runtime.Types.Utils.JsPromise<T> 923 + } 924 + 925 + 926 + 927 + 928 + /** 929 + * Fields of the BackgroundJob model 930 + */ 931 + export interface BackgroundJobFieldRefs { 932 + readonly id: Prisma.FieldRef<"BackgroundJob", 'String'> 933 + readonly type: Prisma.FieldRef<"BackgroundJob", 'String'> 934 + readonly userDid: Prisma.FieldRef<"BackgroundJob", 'String'> 935 + readonly status: Prisma.FieldRef<"BackgroundJob", 'String'> 936 + readonly data: Prisma.FieldRef<"BackgroundJob", 'Json'> 937 + readonly nextRunAt: Prisma.FieldRef<"BackgroundJob", 'DateTime'> 938 + readonly lastError: Prisma.FieldRef<"BackgroundJob", 'String'> 939 + readonly startedAt: Prisma.FieldRef<"BackgroundJob", 'DateTime'> 940 + readonly completedAt: Prisma.FieldRef<"BackgroundJob", 'DateTime'> 941 + readonly createdAt: Prisma.FieldRef<"BackgroundJob", 'DateTime'> 942 + readonly updatedAt: Prisma.FieldRef<"BackgroundJob", 'DateTime'> 943 + } 944 + 945 + 946 + // Custom InputTypes 947 + /** 948 + * BackgroundJob findUnique 949 + */ 950 + export type BackgroundJobFindUniqueArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 951 + /** 952 + * Select specific fields to fetch from the BackgroundJob 953 + */ 954 + select?: Prisma.BackgroundJobSelect<ExtArgs> | null 955 + /** 956 + * Omit specific fields from the BackgroundJob 957 + */ 958 + omit?: Prisma.BackgroundJobOmit<ExtArgs> | null 959 + /** 960 + * Filter, which BackgroundJob to fetch. 961 + */ 962 + where: Prisma.BackgroundJobWhereUniqueInput 963 + } 964 + 965 + /** 966 + * BackgroundJob findUniqueOrThrow 967 + */ 968 + export type BackgroundJobFindUniqueOrThrowArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 969 + /** 970 + * Select specific fields to fetch from the BackgroundJob 971 + */ 972 + select?: Prisma.BackgroundJobSelect<ExtArgs> | null 973 + /** 974 + * Omit specific fields from the BackgroundJob 975 + */ 976 + omit?: Prisma.BackgroundJobOmit<ExtArgs> | null 977 + /** 978 + * Filter, which BackgroundJob to fetch. 979 + */ 980 + where: Prisma.BackgroundJobWhereUniqueInput 981 + } 982 + 983 + /** 984 + * BackgroundJob findFirst 985 + */ 986 + export type BackgroundJobFindFirstArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 987 + /** 988 + * Select specific fields to fetch from the BackgroundJob 989 + */ 990 + select?: Prisma.BackgroundJobSelect<ExtArgs> | null 991 + /** 992 + * Omit specific fields from the BackgroundJob 993 + */ 994 + omit?: Prisma.BackgroundJobOmit<ExtArgs> | null 995 + /** 996 + * Filter, which BackgroundJob to fetch. 997 + */ 998 + where?: Prisma.BackgroundJobWhereInput 999 + /** 1000 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} 1001 + * 1002 + * Determine the order of BackgroundJobs to fetch. 1003 + */ 1004 + orderBy?: Prisma.BackgroundJobOrderByWithRelationInput | Prisma.BackgroundJobOrderByWithRelationInput[] 1005 + /** 1006 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} 1007 + * 1008 + * Sets the position for searching for BackgroundJobs. 1009 + */ 1010 + cursor?: Prisma.BackgroundJobWhereUniqueInput 1011 + /** 1012 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 1013 + * 1014 + * Take `±n` BackgroundJobs from the position of the cursor. 1015 + */ 1016 + take?: number 1017 + /** 1018 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 1019 + * 1020 + * Skip the first `n` BackgroundJobs. 1021 + */ 1022 + skip?: number 1023 + /** 1024 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} 1025 + * 1026 + * Filter by unique combinations of BackgroundJobs. 1027 + */ 1028 + distinct?: Prisma.BackgroundJobScalarFieldEnum | Prisma.BackgroundJobScalarFieldEnum[] 1029 + } 1030 + 1031 + /** 1032 + * BackgroundJob findFirstOrThrow 1033 + */ 1034 + export type BackgroundJobFindFirstOrThrowArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1035 + /** 1036 + * Select specific fields to fetch from the BackgroundJob 1037 + */ 1038 + select?: Prisma.BackgroundJobSelect<ExtArgs> | null 1039 + /** 1040 + * Omit specific fields from the BackgroundJob 1041 + */ 1042 + omit?: Prisma.BackgroundJobOmit<ExtArgs> | null 1043 + /** 1044 + * Filter, which BackgroundJob to fetch. 1045 + */ 1046 + where?: Prisma.BackgroundJobWhereInput 1047 + /** 1048 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} 1049 + * 1050 + * Determine the order of BackgroundJobs to fetch. 1051 + */ 1052 + orderBy?: Prisma.BackgroundJobOrderByWithRelationInput | Prisma.BackgroundJobOrderByWithRelationInput[] 1053 + /** 1054 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} 1055 + * 1056 + * Sets the position for searching for BackgroundJobs. 1057 + */ 1058 + cursor?: Prisma.BackgroundJobWhereUniqueInput 1059 + /** 1060 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 1061 + * 1062 + * Take `±n` BackgroundJobs from the position of the cursor. 1063 + */ 1064 + take?: number 1065 + /** 1066 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 1067 + * 1068 + * Skip the first `n` BackgroundJobs. 1069 + */ 1070 + skip?: number 1071 + /** 1072 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} 1073 + * 1074 + * Filter by unique combinations of BackgroundJobs. 1075 + */ 1076 + distinct?: Prisma.BackgroundJobScalarFieldEnum | Prisma.BackgroundJobScalarFieldEnum[] 1077 + } 1078 + 1079 + /** 1080 + * BackgroundJob findMany 1081 + */ 1082 + export type BackgroundJobFindManyArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1083 + /** 1084 + * Select specific fields to fetch from the BackgroundJob 1085 + */ 1086 + select?: Prisma.BackgroundJobSelect<ExtArgs> | null 1087 + /** 1088 + * Omit specific fields from the BackgroundJob 1089 + */ 1090 + omit?: Prisma.BackgroundJobOmit<ExtArgs> | null 1091 + /** 1092 + * Filter, which BackgroundJobs to fetch. 1093 + */ 1094 + where?: Prisma.BackgroundJobWhereInput 1095 + /** 1096 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} 1097 + * 1098 + * Determine the order of BackgroundJobs to fetch. 1099 + */ 1100 + orderBy?: Prisma.BackgroundJobOrderByWithRelationInput | Prisma.BackgroundJobOrderByWithRelationInput[] 1101 + /** 1102 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} 1103 + * 1104 + * Sets the position for listing BackgroundJobs. 1105 + */ 1106 + cursor?: Prisma.BackgroundJobWhereUniqueInput 1107 + /** 1108 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 1109 + * 1110 + * Take `±n` BackgroundJobs from the position of the cursor. 1111 + */ 1112 + take?: number 1113 + /** 1114 + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 1115 + * 1116 + * Skip the first `n` BackgroundJobs. 1117 + */ 1118 + skip?: number 1119 + distinct?: Prisma.BackgroundJobScalarFieldEnum | Prisma.BackgroundJobScalarFieldEnum[] 1120 + } 1121 + 1122 + /** 1123 + * BackgroundJob create 1124 + */ 1125 + export type BackgroundJobCreateArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1126 + /** 1127 + * Select specific fields to fetch from the BackgroundJob 1128 + */ 1129 + select?: Prisma.BackgroundJobSelect<ExtArgs> | null 1130 + /** 1131 + * Omit specific fields from the BackgroundJob 1132 + */ 1133 + omit?: Prisma.BackgroundJobOmit<ExtArgs> | null 1134 + /** 1135 + * The data needed to create a BackgroundJob. 1136 + */ 1137 + data: Prisma.XOR<Prisma.BackgroundJobCreateInput, Prisma.BackgroundJobUncheckedCreateInput> 1138 + } 1139 + 1140 + /** 1141 + * BackgroundJob createMany 1142 + */ 1143 + export type BackgroundJobCreateManyArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1144 + /** 1145 + * The data used to create many BackgroundJobs. 1146 + */ 1147 + data: Prisma.BackgroundJobCreateManyInput | Prisma.BackgroundJobCreateManyInput[] 1148 + skipDuplicates?: boolean 1149 + } 1150 + 1151 + /** 1152 + * BackgroundJob createManyAndReturn 1153 + */ 1154 + export type BackgroundJobCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1155 + /** 1156 + * Select specific fields to fetch from the BackgroundJob 1157 + */ 1158 + select?: Prisma.BackgroundJobSelectCreateManyAndReturn<ExtArgs> | null 1159 + /** 1160 + * Omit specific fields from the BackgroundJob 1161 + */ 1162 + omit?: Prisma.BackgroundJobOmit<ExtArgs> | null 1163 + /** 1164 + * The data used to create many BackgroundJobs. 1165 + */ 1166 + data: Prisma.BackgroundJobCreateManyInput | Prisma.BackgroundJobCreateManyInput[] 1167 + skipDuplicates?: boolean 1168 + } 1169 + 1170 + /** 1171 + * BackgroundJob update 1172 + */ 1173 + export type BackgroundJobUpdateArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1174 + /** 1175 + * Select specific fields to fetch from the BackgroundJob 1176 + */ 1177 + select?: Prisma.BackgroundJobSelect<ExtArgs> | null 1178 + /** 1179 + * Omit specific fields from the BackgroundJob 1180 + */ 1181 + omit?: Prisma.BackgroundJobOmit<ExtArgs> | null 1182 + /** 1183 + * The data needed to update a BackgroundJob. 1184 + */ 1185 + data: Prisma.XOR<Prisma.BackgroundJobUpdateInput, Prisma.BackgroundJobUncheckedUpdateInput> 1186 + /** 1187 + * Choose, which BackgroundJob to update. 1188 + */ 1189 + where: Prisma.BackgroundJobWhereUniqueInput 1190 + } 1191 + 1192 + /** 1193 + * BackgroundJob updateMany 1194 + */ 1195 + export type BackgroundJobUpdateManyArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1196 + /** 1197 + * The data used to update BackgroundJobs. 1198 + */ 1199 + data: Prisma.XOR<Prisma.BackgroundJobUpdateManyMutationInput, Prisma.BackgroundJobUncheckedUpdateManyInput> 1200 + /** 1201 + * Filter which BackgroundJobs to update 1202 + */ 1203 + where?: Prisma.BackgroundJobWhereInput 1204 + /** 1205 + * Limit how many BackgroundJobs to update. 1206 + */ 1207 + limit?: number 1208 + } 1209 + 1210 + /** 1211 + * BackgroundJob updateManyAndReturn 1212 + */ 1213 + export type BackgroundJobUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1214 + /** 1215 + * Select specific fields to fetch from the BackgroundJob 1216 + */ 1217 + select?: Prisma.BackgroundJobSelectUpdateManyAndReturn<ExtArgs> | null 1218 + /** 1219 + * Omit specific fields from the BackgroundJob 1220 + */ 1221 + omit?: Prisma.BackgroundJobOmit<ExtArgs> | null 1222 + /** 1223 + * The data used to update BackgroundJobs. 1224 + */ 1225 + data: Prisma.XOR<Prisma.BackgroundJobUpdateManyMutationInput, Prisma.BackgroundJobUncheckedUpdateManyInput> 1226 + /** 1227 + * Filter which BackgroundJobs to update 1228 + */ 1229 + where?: Prisma.BackgroundJobWhereInput 1230 + /** 1231 + * Limit how many BackgroundJobs to update. 1232 + */ 1233 + limit?: number 1234 + } 1235 + 1236 + /** 1237 + * BackgroundJob upsert 1238 + */ 1239 + export type BackgroundJobUpsertArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1240 + /** 1241 + * Select specific fields to fetch from the BackgroundJob 1242 + */ 1243 + select?: Prisma.BackgroundJobSelect<ExtArgs> | null 1244 + /** 1245 + * Omit specific fields from the BackgroundJob 1246 + */ 1247 + omit?: Prisma.BackgroundJobOmit<ExtArgs> | null 1248 + /** 1249 + * The filter to search for the BackgroundJob to update in case it exists. 1250 + */ 1251 + where: Prisma.BackgroundJobWhereUniqueInput 1252 + /** 1253 + * In case the BackgroundJob found by the `where` argument doesn't exist, create a new BackgroundJob with this data. 1254 + */ 1255 + create: Prisma.XOR<Prisma.BackgroundJobCreateInput, Prisma.BackgroundJobUncheckedCreateInput> 1256 + /** 1257 + * In case the BackgroundJob was found with the provided `where` argument, update it with this data. 1258 + */ 1259 + update: Prisma.XOR<Prisma.BackgroundJobUpdateInput, Prisma.BackgroundJobUncheckedUpdateInput> 1260 + } 1261 + 1262 + /** 1263 + * BackgroundJob delete 1264 + */ 1265 + export type BackgroundJobDeleteArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1266 + /** 1267 + * Select specific fields to fetch from the BackgroundJob 1268 + */ 1269 + select?: Prisma.BackgroundJobSelect<ExtArgs> | null 1270 + /** 1271 + * Omit specific fields from the BackgroundJob 1272 + */ 1273 + omit?: Prisma.BackgroundJobOmit<ExtArgs> | null 1274 + /** 1275 + * Filter which BackgroundJob to delete. 1276 + */ 1277 + where: Prisma.BackgroundJobWhereUniqueInput 1278 + } 1279 + 1280 + /** 1281 + * BackgroundJob deleteMany 1282 + */ 1283 + export type BackgroundJobDeleteManyArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1284 + /** 1285 + * Filter which BackgroundJobs to delete 1286 + */ 1287 + where?: Prisma.BackgroundJobWhereInput 1288 + /** 1289 + * Limit how many BackgroundJobs to delete. 1290 + */ 1291 + limit?: number 1292 + } 1293 + 1294 + /** 1295 + * BackgroundJob without action 1296 + */ 1297 + export type BackgroundJobDefaultArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1298 + /** 1299 + * Select specific fields to fetch from the BackgroundJob 1300 + */ 1301 + select?: Prisma.BackgroundJobSelect<ExtArgs> | null 1302 + /** 1303 + * Omit specific fields from the BackgroundJob 1304 + */ 1305 + omit?: Prisma.BackgroundJobOmit<ExtArgs> | null 1306 + }
+8
backend/src/generated/models/Movie.ts
··· 477 477 isNot?: Prisma.MovieWhereInput | null 478 478 } 479 479 480 + export type NullableIntFieldUpdateOperationsInput = { 481 + set?: number | null 482 + increment?: number 483 + decrement?: number 484 + multiply?: number 485 + divide?: number 486 + } 487 + 480 488 export type MovieCreateNestedOneWithoutTrackedByInput = { 481 489 create?: Prisma.XOR<Prisma.MovieCreateWithoutTrackedByInput, Prisma.MovieUncheckedCreateWithoutTrackedByInput> 482 490 connectOrCreate?: Prisma.MovieCreateOrConnectWithoutTrackedByInput
+8
backend/src/generated/models/Season.ts
··· 543 543 deleteMany?: Prisma.SeasonScalarWhereInput | Prisma.SeasonScalarWhereInput[] 544 544 } 545 545 546 + export type IntFieldUpdateOperationsInput = { 547 + set?: number 548 + increment?: number 549 + decrement?: number 550 + multiply?: number 551 + divide?: number 552 + } 553 + 546 554 export type SeasonCreateNestedOneWithoutEpisodesInput = { 547 555 create?: Prisma.XOR<Prisma.SeasonCreateWithoutEpisodesInput, Prisma.SeasonUncheckedCreateWithoutEpisodesInput> 548 556 connectOrCreate?: Prisma.SeasonCreateOrConnectWithoutEpisodesInput
-2000
backend/src/generated/models/TraktImportJob.ts
··· 1 - 2 - /* !!! This is code generated by Prisma. Do not edit directly. !!! */ 3 - /* eslint-disable */ 4 - // biome-ignore-all lint: generated file 5 - // @ts-nocheck 6 - /* 7 - * This file exports the `TraktImportJob` model and its related types. 8 - * 9 - * 🟢 You can import this file directly. 10 - */ 11 - import type * as runtime from "@prisma/client/runtime/client" 12 - import type * as $Enums from "../enums.js" 13 - import type * as Prisma from "../internal/prismaNamespace.js" 14 - 15 - /** 16 - * Model TraktImportJob 17 - * 18 - */ 19 - export type TraktImportJobModel = runtime.Types.Result.DefaultSelection<Prisma.$TraktImportJobPayload> 20 - 21 - export type AggregateTraktImportJob = { 22 - _count: TraktImportJobCountAggregateOutputType | null 23 - _avg: TraktImportJobAvgAggregateOutputType | null 24 - _sum: TraktImportJobSumAggregateOutputType | null 25 - _min: TraktImportJobMinAggregateOutputType | null 26 - _max: TraktImportJobMaxAggregateOutputType | null 27 - } 28 - 29 - export type TraktImportJobAvgAggregateOutputType = { 30 - currentPage: number | null 31 - totalPages: number | null 32 - sourceCount: number | null 33 - normalizedCount: number | null 34 - importedCount: number | null 35 - skippedCount: number | null 36 - failedCount: number | null 37 - } 38 - 39 - export type TraktImportJobSumAggregateOutputType = { 40 - currentPage: number | null 41 - totalPages: number | null 42 - sourceCount: number | null 43 - normalizedCount: number | null 44 - importedCount: number | null 45 - skippedCount: number | null 46 - failedCount: number | null 47 - } 48 - 49 - export type TraktImportJobMinAggregateOutputType = { 50 - id: string | null 51 - userDid: string | null 52 - traktUsername: string | null 53 - status: $Enums.TraktImportJobStatus | null 54 - currentPage: number | null 55 - totalPages: number | null 56 - sourceCount: number | null 57 - normalizedCount: number | null 58 - importedCount: number | null 59 - skippedCount: number | null 60 - failedCount: number | null 61 - nextRunAt: Date | null 62 - lastError: string | null 63 - profileUsername: string | null 64 - profileSlug: string | null 65 - profileName: string | null 66 - profileAvatarUrl: string | null 67 - startedAt: Date | null 68 - completedAt: Date | null 69 - createdAt: Date | null 70 - updatedAt: Date | null 71 - } 72 - 73 - export type TraktImportJobMaxAggregateOutputType = { 74 - id: string | null 75 - userDid: string | null 76 - traktUsername: string | null 77 - status: $Enums.TraktImportJobStatus | null 78 - currentPage: number | null 79 - totalPages: number | null 80 - sourceCount: number | null 81 - normalizedCount: number | null 82 - importedCount: number | null 83 - skippedCount: number | null 84 - failedCount: number | null 85 - nextRunAt: Date | null 86 - lastError: string | null 87 - profileUsername: string | null 88 - profileSlug: string | null 89 - profileName: string | null 90 - profileAvatarUrl: string | null 91 - startedAt: Date | null 92 - completedAt: Date | null 93 - createdAt: Date | null 94 - updatedAt: Date | null 95 - } 96 - 97 - export type TraktImportJobCountAggregateOutputType = { 98 - id: number 99 - userDid: number 100 - traktUsername: number 101 - status: number 102 - currentPage: number 103 - totalPages: number 104 - sourceCount: number 105 - normalizedCount: number 106 - importedCount: number 107 - skippedCount: number 108 - failedCount: number 109 - nextRunAt: number 110 - lastError: number 111 - profileUsername: number 112 - profileSlug: number 113 - profileName: number 114 - profileAvatarUrl: number 115 - startedAt: number 116 - completedAt: number 117 - createdAt: number 118 - updatedAt: number 119 - _all: number 120 - } 121 - 122 - 123 - export type TraktImportJobAvgAggregateInputType = { 124 - currentPage?: true 125 - totalPages?: true 126 - sourceCount?: true 127 - normalizedCount?: true 128 - importedCount?: true 129 - skippedCount?: true 130 - failedCount?: true 131 - } 132 - 133 - export type TraktImportJobSumAggregateInputType = { 134 - currentPage?: true 135 - totalPages?: true 136 - sourceCount?: true 137 - normalizedCount?: true 138 - importedCount?: true 139 - skippedCount?: true 140 - failedCount?: true 141 - } 142 - 143 - export type TraktImportJobMinAggregateInputType = { 144 - id?: true 145 - userDid?: true 146 - traktUsername?: true 147 - status?: true 148 - currentPage?: true 149 - totalPages?: true 150 - sourceCount?: true 151 - normalizedCount?: true 152 - importedCount?: true 153 - skippedCount?: true 154 - failedCount?: true 155 - nextRunAt?: true 156 - lastError?: true 157 - profileUsername?: true 158 - profileSlug?: true 159 - profileName?: true 160 - profileAvatarUrl?: true 161 - startedAt?: true 162 - completedAt?: true 163 - createdAt?: true 164 - updatedAt?: true 165 - } 166 - 167 - export type TraktImportJobMaxAggregateInputType = { 168 - id?: true 169 - userDid?: true 170 - traktUsername?: true 171 - status?: true 172 - currentPage?: true 173 - totalPages?: true 174 - sourceCount?: true 175 - normalizedCount?: true 176 - importedCount?: true 177 - skippedCount?: true 178 - failedCount?: true 179 - nextRunAt?: true 180 - lastError?: true 181 - profileUsername?: true 182 - profileSlug?: true 183 - profileName?: true 184 - profileAvatarUrl?: true 185 - startedAt?: true 186 - completedAt?: true 187 - createdAt?: true 188 - updatedAt?: true 189 - } 190 - 191 - export type TraktImportJobCountAggregateInputType = { 192 - id?: true 193 - userDid?: true 194 - traktUsername?: true 195 - status?: true 196 - currentPage?: true 197 - totalPages?: true 198 - sourceCount?: true 199 - normalizedCount?: true 200 - importedCount?: true 201 - skippedCount?: true 202 - failedCount?: true 203 - nextRunAt?: true 204 - lastError?: true 205 - profileUsername?: true 206 - profileSlug?: true 207 - profileName?: true 208 - profileAvatarUrl?: true 209 - startedAt?: true 210 - completedAt?: true 211 - createdAt?: true 212 - updatedAt?: true 213 - _all?: true 214 - } 215 - 216 - export type TraktImportJobAggregateArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 217 - /** 218 - * Filter which TraktImportJob to aggregate. 219 - */ 220 - where?: Prisma.TraktImportJobWhereInput 221 - /** 222 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} 223 - * 224 - * Determine the order of TraktImportJobs to fetch. 225 - */ 226 - orderBy?: Prisma.TraktImportJobOrderByWithRelationInput | Prisma.TraktImportJobOrderByWithRelationInput[] 227 - /** 228 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} 229 - * 230 - * Sets the start position 231 - */ 232 - cursor?: Prisma.TraktImportJobWhereUniqueInput 233 - /** 234 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 235 - * 236 - * Take `±n` TraktImportJobs from the position of the cursor. 237 - */ 238 - take?: number 239 - /** 240 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 241 - * 242 - * Skip the first `n` TraktImportJobs. 243 - */ 244 - skip?: number 245 - /** 246 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} 247 - * 248 - * Count returned TraktImportJobs 249 - **/ 250 - _count?: true | TraktImportJobCountAggregateInputType 251 - /** 252 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} 253 - * 254 - * Select which fields to average 255 - **/ 256 - _avg?: TraktImportJobAvgAggregateInputType 257 - /** 258 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} 259 - * 260 - * Select which fields to sum 261 - **/ 262 - _sum?: TraktImportJobSumAggregateInputType 263 - /** 264 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} 265 - * 266 - * Select which fields to find the minimum value 267 - **/ 268 - _min?: TraktImportJobMinAggregateInputType 269 - /** 270 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} 271 - * 272 - * Select which fields to find the maximum value 273 - **/ 274 - _max?: TraktImportJobMaxAggregateInputType 275 - } 276 - 277 - export type GetTraktImportJobAggregateType<T extends TraktImportJobAggregateArgs> = { 278 - [P in keyof T & keyof AggregateTraktImportJob]: P extends '_count' | 'count' 279 - ? T[P] extends true 280 - ? number 281 - : Prisma.GetScalarType<T[P], AggregateTraktImportJob[P]> 282 - : Prisma.GetScalarType<T[P], AggregateTraktImportJob[P]> 283 - } 284 - 285 - 286 - 287 - 288 - export type TraktImportJobGroupByArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 289 - where?: Prisma.TraktImportJobWhereInput 290 - orderBy?: Prisma.TraktImportJobOrderByWithAggregationInput | Prisma.TraktImportJobOrderByWithAggregationInput[] 291 - by: Prisma.TraktImportJobScalarFieldEnum[] | Prisma.TraktImportJobScalarFieldEnum 292 - having?: Prisma.TraktImportJobScalarWhereWithAggregatesInput 293 - take?: number 294 - skip?: number 295 - _count?: TraktImportJobCountAggregateInputType | true 296 - _avg?: TraktImportJobAvgAggregateInputType 297 - _sum?: TraktImportJobSumAggregateInputType 298 - _min?: TraktImportJobMinAggregateInputType 299 - _max?: TraktImportJobMaxAggregateInputType 300 - } 301 - 302 - export type TraktImportJobGroupByOutputType = { 303 - id: string 304 - userDid: string 305 - traktUsername: string 306 - status: $Enums.TraktImportJobStatus 307 - currentPage: number 308 - totalPages: number | null 309 - sourceCount: number 310 - normalizedCount: number 311 - importedCount: number 312 - skippedCount: number 313 - failedCount: number 314 - nextRunAt: Date 315 - lastError: string | null 316 - profileUsername: string | null 317 - profileSlug: string | null 318 - profileName: string | null 319 - profileAvatarUrl: string | null 320 - startedAt: Date | null 321 - completedAt: Date | null 322 - createdAt: Date 323 - updatedAt: Date 324 - _count: TraktImportJobCountAggregateOutputType | null 325 - _avg: TraktImportJobAvgAggregateOutputType | null 326 - _sum: TraktImportJobSumAggregateOutputType | null 327 - _min: TraktImportJobMinAggregateOutputType | null 328 - _max: TraktImportJobMaxAggregateOutputType | null 329 - } 330 - 331 - type GetTraktImportJobGroupByPayload<T extends TraktImportJobGroupByArgs> = Prisma.PrismaPromise< 332 - Array< 333 - Prisma.PickEnumerable<TraktImportJobGroupByOutputType, T['by']> & 334 - { 335 - [P in ((keyof T) & (keyof TraktImportJobGroupByOutputType))]: P extends '_count' 336 - ? T[P] extends boolean 337 - ? number 338 - : Prisma.GetScalarType<T[P], TraktImportJobGroupByOutputType[P]> 339 - : Prisma.GetScalarType<T[P], TraktImportJobGroupByOutputType[P]> 340 - } 341 - > 342 - > 343 - 344 - 345 - 346 - export type TraktImportJobWhereInput = { 347 - AND?: Prisma.TraktImportJobWhereInput | Prisma.TraktImportJobWhereInput[] 348 - OR?: Prisma.TraktImportJobWhereInput[] 349 - NOT?: Prisma.TraktImportJobWhereInput | Prisma.TraktImportJobWhereInput[] 350 - id?: Prisma.StringFilter<"TraktImportJob"> | string 351 - userDid?: Prisma.StringFilter<"TraktImportJob"> | string 352 - traktUsername?: Prisma.StringFilter<"TraktImportJob"> | string 353 - status?: Prisma.EnumTraktImportJobStatusFilter<"TraktImportJob"> | $Enums.TraktImportJobStatus 354 - currentPage?: Prisma.IntFilter<"TraktImportJob"> | number 355 - totalPages?: Prisma.IntNullableFilter<"TraktImportJob"> | number | null 356 - sourceCount?: Prisma.IntFilter<"TraktImportJob"> | number 357 - normalizedCount?: Prisma.IntFilter<"TraktImportJob"> | number 358 - importedCount?: Prisma.IntFilter<"TraktImportJob"> | number 359 - skippedCount?: Prisma.IntFilter<"TraktImportJob"> | number 360 - failedCount?: Prisma.IntFilter<"TraktImportJob"> | number 361 - nextRunAt?: Prisma.DateTimeFilter<"TraktImportJob"> | Date | string 362 - lastError?: Prisma.StringNullableFilter<"TraktImportJob"> | string | null 363 - profileUsername?: Prisma.StringNullableFilter<"TraktImportJob"> | string | null 364 - profileSlug?: Prisma.StringNullableFilter<"TraktImportJob"> | string | null 365 - profileName?: Prisma.StringNullableFilter<"TraktImportJob"> | string | null 366 - profileAvatarUrl?: Prisma.StringNullableFilter<"TraktImportJob"> | string | null 367 - startedAt?: Prisma.DateTimeNullableFilter<"TraktImportJob"> | Date | string | null 368 - completedAt?: Prisma.DateTimeNullableFilter<"TraktImportJob"> | Date | string | null 369 - createdAt?: Prisma.DateTimeFilter<"TraktImportJob"> | Date | string 370 - updatedAt?: Prisma.DateTimeFilter<"TraktImportJob"> | Date | string 371 - user?: Prisma.XOR<Prisma.UserScalarRelationFilter, Prisma.UserWhereInput> 372 - } 373 - 374 - export type TraktImportJobOrderByWithRelationInput = { 375 - id?: Prisma.SortOrder 376 - userDid?: Prisma.SortOrder 377 - traktUsername?: Prisma.SortOrder 378 - status?: Prisma.SortOrder 379 - currentPage?: Prisma.SortOrder 380 - totalPages?: Prisma.SortOrderInput | Prisma.SortOrder 381 - sourceCount?: Prisma.SortOrder 382 - normalizedCount?: Prisma.SortOrder 383 - importedCount?: Prisma.SortOrder 384 - skippedCount?: Prisma.SortOrder 385 - failedCount?: Prisma.SortOrder 386 - nextRunAt?: Prisma.SortOrder 387 - lastError?: Prisma.SortOrderInput | Prisma.SortOrder 388 - profileUsername?: Prisma.SortOrderInput | Prisma.SortOrder 389 - profileSlug?: Prisma.SortOrderInput | Prisma.SortOrder 390 - profileName?: Prisma.SortOrderInput | Prisma.SortOrder 391 - profileAvatarUrl?: Prisma.SortOrderInput | Prisma.SortOrder 392 - startedAt?: Prisma.SortOrderInput | Prisma.SortOrder 393 - completedAt?: Prisma.SortOrderInput | Prisma.SortOrder 394 - createdAt?: Prisma.SortOrder 395 - updatedAt?: Prisma.SortOrder 396 - user?: Prisma.UserOrderByWithRelationInput 397 - } 398 - 399 - export type TraktImportJobWhereUniqueInput = Prisma.AtLeast<{ 400 - id?: string 401 - AND?: Prisma.TraktImportJobWhereInput | Prisma.TraktImportJobWhereInput[] 402 - OR?: Prisma.TraktImportJobWhereInput[] 403 - NOT?: Prisma.TraktImportJobWhereInput | Prisma.TraktImportJobWhereInput[] 404 - userDid?: Prisma.StringFilter<"TraktImportJob"> | string 405 - traktUsername?: Prisma.StringFilter<"TraktImportJob"> | string 406 - status?: Prisma.EnumTraktImportJobStatusFilter<"TraktImportJob"> | $Enums.TraktImportJobStatus 407 - currentPage?: Prisma.IntFilter<"TraktImportJob"> | number 408 - totalPages?: Prisma.IntNullableFilter<"TraktImportJob"> | number | null 409 - sourceCount?: Prisma.IntFilter<"TraktImportJob"> | number 410 - normalizedCount?: Prisma.IntFilter<"TraktImportJob"> | number 411 - importedCount?: Prisma.IntFilter<"TraktImportJob"> | number 412 - skippedCount?: Prisma.IntFilter<"TraktImportJob"> | number 413 - failedCount?: Prisma.IntFilter<"TraktImportJob"> | number 414 - nextRunAt?: Prisma.DateTimeFilter<"TraktImportJob"> | Date | string 415 - lastError?: Prisma.StringNullableFilter<"TraktImportJob"> | string | null 416 - profileUsername?: Prisma.StringNullableFilter<"TraktImportJob"> | string | null 417 - profileSlug?: Prisma.StringNullableFilter<"TraktImportJob"> | string | null 418 - profileName?: Prisma.StringNullableFilter<"TraktImportJob"> | string | null 419 - profileAvatarUrl?: Prisma.StringNullableFilter<"TraktImportJob"> | string | null 420 - startedAt?: Prisma.DateTimeNullableFilter<"TraktImportJob"> | Date | string | null 421 - completedAt?: Prisma.DateTimeNullableFilter<"TraktImportJob"> | Date | string | null 422 - createdAt?: Prisma.DateTimeFilter<"TraktImportJob"> | Date | string 423 - updatedAt?: Prisma.DateTimeFilter<"TraktImportJob"> | Date | string 424 - user?: Prisma.XOR<Prisma.UserScalarRelationFilter, Prisma.UserWhereInput> 425 - }, "id"> 426 - 427 - export type TraktImportJobOrderByWithAggregationInput = { 428 - id?: Prisma.SortOrder 429 - userDid?: Prisma.SortOrder 430 - traktUsername?: Prisma.SortOrder 431 - status?: Prisma.SortOrder 432 - currentPage?: Prisma.SortOrder 433 - totalPages?: Prisma.SortOrderInput | Prisma.SortOrder 434 - sourceCount?: Prisma.SortOrder 435 - normalizedCount?: Prisma.SortOrder 436 - importedCount?: Prisma.SortOrder 437 - skippedCount?: Prisma.SortOrder 438 - failedCount?: Prisma.SortOrder 439 - nextRunAt?: Prisma.SortOrder 440 - lastError?: Prisma.SortOrderInput | Prisma.SortOrder 441 - profileUsername?: Prisma.SortOrderInput | Prisma.SortOrder 442 - profileSlug?: Prisma.SortOrderInput | Prisma.SortOrder 443 - profileName?: Prisma.SortOrderInput | Prisma.SortOrder 444 - profileAvatarUrl?: Prisma.SortOrderInput | Prisma.SortOrder 445 - startedAt?: Prisma.SortOrderInput | Prisma.SortOrder 446 - completedAt?: Prisma.SortOrderInput | Prisma.SortOrder 447 - createdAt?: Prisma.SortOrder 448 - updatedAt?: Prisma.SortOrder 449 - _count?: Prisma.TraktImportJobCountOrderByAggregateInput 450 - _avg?: Prisma.TraktImportJobAvgOrderByAggregateInput 451 - _max?: Prisma.TraktImportJobMaxOrderByAggregateInput 452 - _min?: Prisma.TraktImportJobMinOrderByAggregateInput 453 - _sum?: Prisma.TraktImportJobSumOrderByAggregateInput 454 - } 455 - 456 - export type TraktImportJobScalarWhereWithAggregatesInput = { 457 - AND?: Prisma.TraktImportJobScalarWhereWithAggregatesInput | Prisma.TraktImportJobScalarWhereWithAggregatesInput[] 458 - OR?: Prisma.TraktImportJobScalarWhereWithAggregatesInput[] 459 - NOT?: Prisma.TraktImportJobScalarWhereWithAggregatesInput | Prisma.TraktImportJobScalarWhereWithAggregatesInput[] 460 - id?: Prisma.StringWithAggregatesFilter<"TraktImportJob"> | string 461 - userDid?: Prisma.StringWithAggregatesFilter<"TraktImportJob"> | string 462 - traktUsername?: Prisma.StringWithAggregatesFilter<"TraktImportJob"> | string 463 - status?: Prisma.EnumTraktImportJobStatusWithAggregatesFilter<"TraktImportJob"> | $Enums.TraktImportJobStatus 464 - currentPage?: Prisma.IntWithAggregatesFilter<"TraktImportJob"> | number 465 - totalPages?: Prisma.IntNullableWithAggregatesFilter<"TraktImportJob"> | number | null 466 - sourceCount?: Prisma.IntWithAggregatesFilter<"TraktImportJob"> | number 467 - normalizedCount?: Prisma.IntWithAggregatesFilter<"TraktImportJob"> | number 468 - importedCount?: Prisma.IntWithAggregatesFilter<"TraktImportJob"> | number 469 - skippedCount?: Prisma.IntWithAggregatesFilter<"TraktImportJob"> | number 470 - failedCount?: Prisma.IntWithAggregatesFilter<"TraktImportJob"> | number 471 - nextRunAt?: Prisma.DateTimeWithAggregatesFilter<"TraktImportJob"> | Date | string 472 - lastError?: Prisma.StringNullableWithAggregatesFilter<"TraktImportJob"> | string | null 473 - profileUsername?: Prisma.StringNullableWithAggregatesFilter<"TraktImportJob"> | string | null 474 - profileSlug?: Prisma.StringNullableWithAggregatesFilter<"TraktImportJob"> | string | null 475 - profileName?: Prisma.StringNullableWithAggregatesFilter<"TraktImportJob"> | string | null 476 - profileAvatarUrl?: Prisma.StringNullableWithAggregatesFilter<"TraktImportJob"> | string | null 477 - startedAt?: Prisma.DateTimeNullableWithAggregatesFilter<"TraktImportJob"> | Date | string | null 478 - completedAt?: Prisma.DateTimeNullableWithAggregatesFilter<"TraktImportJob"> | Date | string | null 479 - createdAt?: Prisma.DateTimeWithAggregatesFilter<"TraktImportJob"> | Date | string 480 - updatedAt?: Prisma.DateTimeWithAggregatesFilter<"TraktImportJob"> | Date | string 481 - } 482 - 483 - export type TraktImportJobCreateInput = { 484 - id?: string 485 - traktUsername: string 486 - status?: $Enums.TraktImportJobStatus 487 - currentPage?: number 488 - totalPages?: number | null 489 - sourceCount?: number 490 - normalizedCount?: number 491 - importedCount?: number 492 - skippedCount?: number 493 - failedCount?: number 494 - nextRunAt?: Date | string 495 - lastError?: string | null 496 - profileUsername?: string | null 497 - profileSlug?: string | null 498 - profileName?: string | null 499 - profileAvatarUrl?: string | null 500 - startedAt?: Date | string | null 501 - completedAt?: Date | string | null 502 - createdAt?: Date | string 503 - updatedAt?: Date | string 504 - user: Prisma.UserCreateNestedOneWithoutTraktImportJobsInput 505 - } 506 - 507 - export type TraktImportJobUncheckedCreateInput = { 508 - id?: string 509 - userDid: string 510 - traktUsername: string 511 - status?: $Enums.TraktImportJobStatus 512 - currentPage?: number 513 - totalPages?: number | null 514 - sourceCount?: number 515 - normalizedCount?: number 516 - importedCount?: number 517 - skippedCount?: number 518 - failedCount?: number 519 - nextRunAt?: Date | string 520 - lastError?: string | null 521 - profileUsername?: string | null 522 - profileSlug?: string | null 523 - profileName?: string | null 524 - profileAvatarUrl?: string | null 525 - startedAt?: Date | string | null 526 - completedAt?: Date | string | null 527 - createdAt?: Date | string 528 - updatedAt?: Date | string 529 - } 530 - 531 - export type TraktImportJobUpdateInput = { 532 - id?: Prisma.StringFieldUpdateOperationsInput | string 533 - traktUsername?: Prisma.StringFieldUpdateOperationsInput | string 534 - status?: Prisma.EnumTraktImportJobStatusFieldUpdateOperationsInput | $Enums.TraktImportJobStatus 535 - currentPage?: Prisma.IntFieldUpdateOperationsInput | number 536 - totalPages?: Prisma.NullableIntFieldUpdateOperationsInput | number | null 537 - sourceCount?: Prisma.IntFieldUpdateOperationsInput | number 538 - normalizedCount?: Prisma.IntFieldUpdateOperationsInput | number 539 - importedCount?: Prisma.IntFieldUpdateOperationsInput | number 540 - skippedCount?: Prisma.IntFieldUpdateOperationsInput | number 541 - failedCount?: Prisma.IntFieldUpdateOperationsInput | number 542 - nextRunAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 543 - lastError?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 544 - profileUsername?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 545 - profileSlug?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 546 - profileName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 547 - profileAvatarUrl?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 548 - startedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 549 - completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 550 - createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 551 - updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 552 - user?: Prisma.UserUpdateOneRequiredWithoutTraktImportJobsNestedInput 553 - } 554 - 555 - export type TraktImportJobUncheckedUpdateInput = { 556 - id?: Prisma.StringFieldUpdateOperationsInput | string 557 - userDid?: Prisma.StringFieldUpdateOperationsInput | string 558 - traktUsername?: Prisma.StringFieldUpdateOperationsInput | string 559 - status?: Prisma.EnumTraktImportJobStatusFieldUpdateOperationsInput | $Enums.TraktImportJobStatus 560 - currentPage?: Prisma.IntFieldUpdateOperationsInput | number 561 - totalPages?: Prisma.NullableIntFieldUpdateOperationsInput | number | null 562 - sourceCount?: Prisma.IntFieldUpdateOperationsInput | number 563 - normalizedCount?: Prisma.IntFieldUpdateOperationsInput | number 564 - importedCount?: Prisma.IntFieldUpdateOperationsInput | number 565 - skippedCount?: Prisma.IntFieldUpdateOperationsInput | number 566 - failedCount?: Prisma.IntFieldUpdateOperationsInput | number 567 - nextRunAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 568 - lastError?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 569 - profileUsername?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 570 - profileSlug?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 571 - profileName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 572 - profileAvatarUrl?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 573 - startedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 574 - completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 575 - createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 576 - updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 577 - } 578 - 579 - export type TraktImportJobCreateManyInput = { 580 - id?: string 581 - userDid: string 582 - traktUsername: string 583 - status?: $Enums.TraktImportJobStatus 584 - currentPage?: number 585 - totalPages?: number | null 586 - sourceCount?: number 587 - normalizedCount?: number 588 - importedCount?: number 589 - skippedCount?: number 590 - failedCount?: number 591 - nextRunAt?: Date | string 592 - lastError?: string | null 593 - profileUsername?: string | null 594 - profileSlug?: string | null 595 - profileName?: string | null 596 - profileAvatarUrl?: string | null 597 - startedAt?: Date | string | null 598 - completedAt?: Date | string | null 599 - createdAt?: Date | string 600 - updatedAt?: Date | string 601 - } 602 - 603 - export type TraktImportJobUpdateManyMutationInput = { 604 - id?: Prisma.StringFieldUpdateOperationsInput | string 605 - traktUsername?: Prisma.StringFieldUpdateOperationsInput | string 606 - status?: Prisma.EnumTraktImportJobStatusFieldUpdateOperationsInput | $Enums.TraktImportJobStatus 607 - currentPage?: Prisma.IntFieldUpdateOperationsInput | number 608 - totalPages?: Prisma.NullableIntFieldUpdateOperationsInput | number | null 609 - sourceCount?: Prisma.IntFieldUpdateOperationsInput | number 610 - normalizedCount?: Prisma.IntFieldUpdateOperationsInput | number 611 - importedCount?: Prisma.IntFieldUpdateOperationsInput | number 612 - skippedCount?: Prisma.IntFieldUpdateOperationsInput | number 613 - failedCount?: Prisma.IntFieldUpdateOperationsInput | number 614 - nextRunAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 615 - lastError?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 616 - profileUsername?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 617 - profileSlug?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 618 - profileName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 619 - profileAvatarUrl?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 620 - startedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 621 - completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 622 - createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 623 - updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 624 - } 625 - 626 - export type TraktImportJobUncheckedUpdateManyInput = { 627 - id?: Prisma.StringFieldUpdateOperationsInput | string 628 - userDid?: Prisma.StringFieldUpdateOperationsInput | string 629 - traktUsername?: Prisma.StringFieldUpdateOperationsInput | string 630 - status?: Prisma.EnumTraktImportJobStatusFieldUpdateOperationsInput | $Enums.TraktImportJobStatus 631 - currentPage?: Prisma.IntFieldUpdateOperationsInput | number 632 - totalPages?: Prisma.NullableIntFieldUpdateOperationsInput | number | null 633 - sourceCount?: Prisma.IntFieldUpdateOperationsInput | number 634 - normalizedCount?: Prisma.IntFieldUpdateOperationsInput | number 635 - importedCount?: Prisma.IntFieldUpdateOperationsInput | number 636 - skippedCount?: Prisma.IntFieldUpdateOperationsInput | number 637 - failedCount?: Prisma.IntFieldUpdateOperationsInput | number 638 - nextRunAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 639 - lastError?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 640 - profileUsername?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 641 - profileSlug?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 642 - profileName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 643 - profileAvatarUrl?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 644 - startedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 645 - completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 646 - createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 647 - updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 648 - } 649 - 650 - export type TraktImportJobListRelationFilter = { 651 - every?: Prisma.TraktImportJobWhereInput 652 - some?: Prisma.TraktImportJobWhereInput 653 - none?: Prisma.TraktImportJobWhereInput 654 - } 655 - 656 - export type TraktImportJobOrderByRelationAggregateInput = { 657 - _count?: Prisma.SortOrder 658 - } 659 - 660 - export type TraktImportJobCountOrderByAggregateInput = { 661 - id?: Prisma.SortOrder 662 - userDid?: Prisma.SortOrder 663 - traktUsername?: Prisma.SortOrder 664 - status?: Prisma.SortOrder 665 - currentPage?: Prisma.SortOrder 666 - totalPages?: Prisma.SortOrder 667 - sourceCount?: Prisma.SortOrder 668 - normalizedCount?: Prisma.SortOrder 669 - importedCount?: Prisma.SortOrder 670 - skippedCount?: Prisma.SortOrder 671 - failedCount?: Prisma.SortOrder 672 - nextRunAt?: Prisma.SortOrder 673 - lastError?: Prisma.SortOrder 674 - profileUsername?: Prisma.SortOrder 675 - profileSlug?: Prisma.SortOrder 676 - profileName?: Prisma.SortOrder 677 - profileAvatarUrl?: Prisma.SortOrder 678 - startedAt?: Prisma.SortOrder 679 - completedAt?: Prisma.SortOrder 680 - createdAt?: Prisma.SortOrder 681 - updatedAt?: Prisma.SortOrder 682 - } 683 - 684 - export type TraktImportJobAvgOrderByAggregateInput = { 685 - currentPage?: Prisma.SortOrder 686 - totalPages?: Prisma.SortOrder 687 - sourceCount?: Prisma.SortOrder 688 - normalizedCount?: Prisma.SortOrder 689 - importedCount?: Prisma.SortOrder 690 - skippedCount?: Prisma.SortOrder 691 - failedCount?: Prisma.SortOrder 692 - } 693 - 694 - export type TraktImportJobMaxOrderByAggregateInput = { 695 - id?: Prisma.SortOrder 696 - userDid?: Prisma.SortOrder 697 - traktUsername?: Prisma.SortOrder 698 - status?: Prisma.SortOrder 699 - currentPage?: Prisma.SortOrder 700 - totalPages?: Prisma.SortOrder 701 - sourceCount?: Prisma.SortOrder 702 - normalizedCount?: Prisma.SortOrder 703 - importedCount?: Prisma.SortOrder 704 - skippedCount?: Prisma.SortOrder 705 - failedCount?: Prisma.SortOrder 706 - nextRunAt?: Prisma.SortOrder 707 - lastError?: Prisma.SortOrder 708 - profileUsername?: Prisma.SortOrder 709 - profileSlug?: Prisma.SortOrder 710 - profileName?: Prisma.SortOrder 711 - profileAvatarUrl?: Prisma.SortOrder 712 - startedAt?: Prisma.SortOrder 713 - completedAt?: Prisma.SortOrder 714 - createdAt?: Prisma.SortOrder 715 - updatedAt?: Prisma.SortOrder 716 - } 717 - 718 - export type TraktImportJobMinOrderByAggregateInput = { 719 - id?: Prisma.SortOrder 720 - userDid?: Prisma.SortOrder 721 - traktUsername?: Prisma.SortOrder 722 - status?: Prisma.SortOrder 723 - currentPage?: Prisma.SortOrder 724 - totalPages?: Prisma.SortOrder 725 - sourceCount?: Prisma.SortOrder 726 - normalizedCount?: Prisma.SortOrder 727 - importedCount?: Prisma.SortOrder 728 - skippedCount?: Prisma.SortOrder 729 - failedCount?: Prisma.SortOrder 730 - nextRunAt?: Prisma.SortOrder 731 - lastError?: Prisma.SortOrder 732 - profileUsername?: Prisma.SortOrder 733 - profileSlug?: Prisma.SortOrder 734 - profileName?: Prisma.SortOrder 735 - profileAvatarUrl?: Prisma.SortOrder 736 - startedAt?: Prisma.SortOrder 737 - completedAt?: Prisma.SortOrder 738 - createdAt?: Prisma.SortOrder 739 - updatedAt?: Prisma.SortOrder 740 - } 741 - 742 - export type TraktImportJobSumOrderByAggregateInput = { 743 - currentPage?: Prisma.SortOrder 744 - totalPages?: Prisma.SortOrder 745 - sourceCount?: Prisma.SortOrder 746 - normalizedCount?: Prisma.SortOrder 747 - importedCount?: Prisma.SortOrder 748 - skippedCount?: Prisma.SortOrder 749 - failedCount?: Prisma.SortOrder 750 - } 751 - 752 - export type TraktImportJobCreateNestedManyWithoutUserInput = { 753 - create?: Prisma.XOR<Prisma.TraktImportJobCreateWithoutUserInput, Prisma.TraktImportJobUncheckedCreateWithoutUserInput> | Prisma.TraktImportJobCreateWithoutUserInput[] | Prisma.TraktImportJobUncheckedCreateWithoutUserInput[] 754 - connectOrCreate?: Prisma.TraktImportJobCreateOrConnectWithoutUserInput | Prisma.TraktImportJobCreateOrConnectWithoutUserInput[] 755 - createMany?: Prisma.TraktImportJobCreateManyUserInputEnvelope 756 - connect?: Prisma.TraktImportJobWhereUniqueInput | Prisma.TraktImportJobWhereUniqueInput[] 757 - } 758 - 759 - export type TraktImportJobUncheckedCreateNestedManyWithoutUserInput = { 760 - create?: Prisma.XOR<Prisma.TraktImportJobCreateWithoutUserInput, Prisma.TraktImportJobUncheckedCreateWithoutUserInput> | Prisma.TraktImportJobCreateWithoutUserInput[] | Prisma.TraktImportJobUncheckedCreateWithoutUserInput[] 761 - connectOrCreate?: Prisma.TraktImportJobCreateOrConnectWithoutUserInput | Prisma.TraktImportJobCreateOrConnectWithoutUserInput[] 762 - createMany?: Prisma.TraktImportJobCreateManyUserInputEnvelope 763 - connect?: Prisma.TraktImportJobWhereUniqueInput | Prisma.TraktImportJobWhereUniqueInput[] 764 - } 765 - 766 - export type TraktImportJobUpdateManyWithoutUserNestedInput = { 767 - create?: Prisma.XOR<Prisma.TraktImportJobCreateWithoutUserInput, Prisma.TraktImportJobUncheckedCreateWithoutUserInput> | Prisma.TraktImportJobCreateWithoutUserInput[] | Prisma.TraktImportJobUncheckedCreateWithoutUserInput[] 768 - connectOrCreate?: Prisma.TraktImportJobCreateOrConnectWithoutUserInput | Prisma.TraktImportJobCreateOrConnectWithoutUserInput[] 769 - upsert?: Prisma.TraktImportJobUpsertWithWhereUniqueWithoutUserInput | Prisma.TraktImportJobUpsertWithWhereUniqueWithoutUserInput[] 770 - createMany?: Prisma.TraktImportJobCreateManyUserInputEnvelope 771 - set?: Prisma.TraktImportJobWhereUniqueInput | Prisma.TraktImportJobWhereUniqueInput[] 772 - disconnect?: Prisma.TraktImportJobWhereUniqueInput | Prisma.TraktImportJobWhereUniqueInput[] 773 - delete?: Prisma.TraktImportJobWhereUniqueInput | Prisma.TraktImportJobWhereUniqueInput[] 774 - connect?: Prisma.TraktImportJobWhereUniqueInput | Prisma.TraktImportJobWhereUniqueInput[] 775 - update?: Prisma.TraktImportJobUpdateWithWhereUniqueWithoutUserInput | Prisma.TraktImportJobUpdateWithWhereUniqueWithoutUserInput[] 776 - updateMany?: Prisma.TraktImportJobUpdateManyWithWhereWithoutUserInput | Prisma.TraktImportJobUpdateManyWithWhereWithoutUserInput[] 777 - deleteMany?: Prisma.TraktImportJobScalarWhereInput | Prisma.TraktImportJobScalarWhereInput[] 778 - } 779 - 780 - export type TraktImportJobUncheckedUpdateManyWithoutUserNestedInput = { 781 - create?: Prisma.XOR<Prisma.TraktImportJobCreateWithoutUserInput, Prisma.TraktImportJobUncheckedCreateWithoutUserInput> | Prisma.TraktImportJobCreateWithoutUserInput[] | Prisma.TraktImportJobUncheckedCreateWithoutUserInput[] 782 - connectOrCreate?: Prisma.TraktImportJobCreateOrConnectWithoutUserInput | Prisma.TraktImportJobCreateOrConnectWithoutUserInput[] 783 - upsert?: Prisma.TraktImportJobUpsertWithWhereUniqueWithoutUserInput | Prisma.TraktImportJobUpsertWithWhereUniqueWithoutUserInput[] 784 - createMany?: Prisma.TraktImportJobCreateManyUserInputEnvelope 785 - set?: Prisma.TraktImportJobWhereUniqueInput | Prisma.TraktImportJobWhereUniqueInput[] 786 - disconnect?: Prisma.TraktImportJobWhereUniqueInput | Prisma.TraktImportJobWhereUniqueInput[] 787 - delete?: Prisma.TraktImportJobWhereUniqueInput | Prisma.TraktImportJobWhereUniqueInput[] 788 - connect?: Prisma.TraktImportJobWhereUniqueInput | Prisma.TraktImportJobWhereUniqueInput[] 789 - update?: Prisma.TraktImportJobUpdateWithWhereUniqueWithoutUserInput | Prisma.TraktImportJobUpdateWithWhereUniqueWithoutUserInput[] 790 - updateMany?: Prisma.TraktImportJobUpdateManyWithWhereWithoutUserInput | Prisma.TraktImportJobUpdateManyWithWhereWithoutUserInput[] 791 - deleteMany?: Prisma.TraktImportJobScalarWhereInput | Prisma.TraktImportJobScalarWhereInput[] 792 - } 793 - 794 - export type EnumTraktImportJobStatusFieldUpdateOperationsInput = { 795 - set?: $Enums.TraktImportJobStatus 796 - } 797 - 798 - export type IntFieldUpdateOperationsInput = { 799 - set?: number 800 - increment?: number 801 - decrement?: number 802 - multiply?: number 803 - divide?: number 804 - } 805 - 806 - export type NullableIntFieldUpdateOperationsInput = { 807 - set?: number | null 808 - increment?: number 809 - decrement?: number 810 - multiply?: number 811 - divide?: number 812 - } 813 - 814 - export type TraktImportJobCreateWithoutUserInput = { 815 - id?: string 816 - traktUsername: string 817 - status?: $Enums.TraktImportJobStatus 818 - currentPage?: number 819 - totalPages?: number | null 820 - sourceCount?: number 821 - normalizedCount?: number 822 - importedCount?: number 823 - skippedCount?: number 824 - failedCount?: number 825 - nextRunAt?: Date | string 826 - lastError?: string | null 827 - profileUsername?: string | null 828 - profileSlug?: string | null 829 - profileName?: string | null 830 - profileAvatarUrl?: string | null 831 - startedAt?: Date | string | null 832 - completedAt?: Date | string | null 833 - createdAt?: Date | string 834 - updatedAt?: Date | string 835 - } 836 - 837 - export type TraktImportJobUncheckedCreateWithoutUserInput = { 838 - id?: string 839 - traktUsername: string 840 - status?: $Enums.TraktImportJobStatus 841 - currentPage?: number 842 - totalPages?: number | null 843 - sourceCount?: number 844 - normalizedCount?: number 845 - importedCount?: number 846 - skippedCount?: number 847 - failedCount?: number 848 - nextRunAt?: Date | string 849 - lastError?: string | null 850 - profileUsername?: string | null 851 - profileSlug?: string | null 852 - profileName?: string | null 853 - profileAvatarUrl?: string | null 854 - startedAt?: Date | string | null 855 - completedAt?: Date | string | null 856 - createdAt?: Date | string 857 - updatedAt?: Date | string 858 - } 859 - 860 - export type TraktImportJobCreateOrConnectWithoutUserInput = { 861 - where: Prisma.TraktImportJobWhereUniqueInput 862 - create: Prisma.XOR<Prisma.TraktImportJobCreateWithoutUserInput, Prisma.TraktImportJobUncheckedCreateWithoutUserInput> 863 - } 864 - 865 - export type TraktImportJobCreateManyUserInputEnvelope = { 866 - data: Prisma.TraktImportJobCreateManyUserInput | Prisma.TraktImportJobCreateManyUserInput[] 867 - skipDuplicates?: boolean 868 - } 869 - 870 - export type TraktImportJobUpsertWithWhereUniqueWithoutUserInput = { 871 - where: Prisma.TraktImportJobWhereUniqueInput 872 - update: Prisma.XOR<Prisma.TraktImportJobUpdateWithoutUserInput, Prisma.TraktImportJobUncheckedUpdateWithoutUserInput> 873 - create: Prisma.XOR<Prisma.TraktImportJobCreateWithoutUserInput, Prisma.TraktImportJobUncheckedCreateWithoutUserInput> 874 - } 875 - 876 - export type TraktImportJobUpdateWithWhereUniqueWithoutUserInput = { 877 - where: Prisma.TraktImportJobWhereUniqueInput 878 - data: Prisma.XOR<Prisma.TraktImportJobUpdateWithoutUserInput, Prisma.TraktImportJobUncheckedUpdateWithoutUserInput> 879 - } 880 - 881 - export type TraktImportJobUpdateManyWithWhereWithoutUserInput = { 882 - where: Prisma.TraktImportJobScalarWhereInput 883 - data: Prisma.XOR<Prisma.TraktImportJobUpdateManyMutationInput, Prisma.TraktImportJobUncheckedUpdateManyWithoutUserInput> 884 - } 885 - 886 - export type TraktImportJobScalarWhereInput = { 887 - AND?: Prisma.TraktImportJobScalarWhereInput | Prisma.TraktImportJobScalarWhereInput[] 888 - OR?: Prisma.TraktImportJobScalarWhereInput[] 889 - NOT?: Prisma.TraktImportJobScalarWhereInput | Prisma.TraktImportJobScalarWhereInput[] 890 - id?: Prisma.StringFilter<"TraktImportJob"> | string 891 - userDid?: Prisma.StringFilter<"TraktImportJob"> | string 892 - traktUsername?: Prisma.StringFilter<"TraktImportJob"> | string 893 - status?: Prisma.EnumTraktImportJobStatusFilter<"TraktImportJob"> | $Enums.TraktImportJobStatus 894 - currentPage?: Prisma.IntFilter<"TraktImportJob"> | number 895 - totalPages?: Prisma.IntNullableFilter<"TraktImportJob"> | number | null 896 - sourceCount?: Prisma.IntFilter<"TraktImportJob"> | number 897 - normalizedCount?: Prisma.IntFilter<"TraktImportJob"> | number 898 - importedCount?: Prisma.IntFilter<"TraktImportJob"> | number 899 - skippedCount?: Prisma.IntFilter<"TraktImportJob"> | number 900 - failedCount?: Prisma.IntFilter<"TraktImportJob"> | number 901 - nextRunAt?: Prisma.DateTimeFilter<"TraktImportJob"> | Date | string 902 - lastError?: Prisma.StringNullableFilter<"TraktImportJob"> | string | null 903 - profileUsername?: Prisma.StringNullableFilter<"TraktImportJob"> | string | null 904 - profileSlug?: Prisma.StringNullableFilter<"TraktImportJob"> | string | null 905 - profileName?: Prisma.StringNullableFilter<"TraktImportJob"> | string | null 906 - profileAvatarUrl?: Prisma.StringNullableFilter<"TraktImportJob"> | string | null 907 - startedAt?: Prisma.DateTimeNullableFilter<"TraktImportJob"> | Date | string | null 908 - completedAt?: Prisma.DateTimeNullableFilter<"TraktImportJob"> | Date | string | null 909 - createdAt?: Prisma.DateTimeFilter<"TraktImportJob"> | Date | string 910 - updatedAt?: Prisma.DateTimeFilter<"TraktImportJob"> | Date | string 911 - } 912 - 913 - export type TraktImportJobCreateManyUserInput = { 914 - id?: string 915 - traktUsername: string 916 - status?: $Enums.TraktImportJobStatus 917 - currentPage?: number 918 - totalPages?: number | null 919 - sourceCount?: number 920 - normalizedCount?: number 921 - importedCount?: number 922 - skippedCount?: number 923 - failedCount?: number 924 - nextRunAt?: Date | string 925 - lastError?: string | null 926 - profileUsername?: string | null 927 - profileSlug?: string | null 928 - profileName?: string | null 929 - profileAvatarUrl?: string | null 930 - startedAt?: Date | string | null 931 - completedAt?: Date | string | null 932 - createdAt?: Date | string 933 - updatedAt?: Date | string 934 - } 935 - 936 - export type TraktImportJobUpdateWithoutUserInput = { 937 - id?: Prisma.StringFieldUpdateOperationsInput | string 938 - traktUsername?: Prisma.StringFieldUpdateOperationsInput | string 939 - status?: Prisma.EnumTraktImportJobStatusFieldUpdateOperationsInput | $Enums.TraktImportJobStatus 940 - currentPage?: Prisma.IntFieldUpdateOperationsInput | number 941 - totalPages?: Prisma.NullableIntFieldUpdateOperationsInput | number | null 942 - sourceCount?: Prisma.IntFieldUpdateOperationsInput | number 943 - normalizedCount?: Prisma.IntFieldUpdateOperationsInput | number 944 - importedCount?: Prisma.IntFieldUpdateOperationsInput | number 945 - skippedCount?: Prisma.IntFieldUpdateOperationsInput | number 946 - failedCount?: Prisma.IntFieldUpdateOperationsInput | number 947 - nextRunAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 948 - lastError?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 949 - profileUsername?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 950 - profileSlug?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 951 - profileName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 952 - profileAvatarUrl?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 953 - startedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 954 - completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 955 - createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 956 - updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 957 - } 958 - 959 - export type TraktImportJobUncheckedUpdateWithoutUserInput = { 960 - id?: Prisma.StringFieldUpdateOperationsInput | string 961 - traktUsername?: Prisma.StringFieldUpdateOperationsInput | string 962 - status?: Prisma.EnumTraktImportJobStatusFieldUpdateOperationsInput | $Enums.TraktImportJobStatus 963 - currentPage?: Prisma.IntFieldUpdateOperationsInput | number 964 - totalPages?: Prisma.NullableIntFieldUpdateOperationsInput | number | null 965 - sourceCount?: Prisma.IntFieldUpdateOperationsInput | number 966 - normalizedCount?: Prisma.IntFieldUpdateOperationsInput | number 967 - importedCount?: Prisma.IntFieldUpdateOperationsInput | number 968 - skippedCount?: Prisma.IntFieldUpdateOperationsInput | number 969 - failedCount?: Prisma.IntFieldUpdateOperationsInput | number 970 - nextRunAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 971 - lastError?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 972 - profileUsername?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 973 - profileSlug?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 974 - profileName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 975 - profileAvatarUrl?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 976 - startedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 977 - completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 978 - createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 979 - updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 980 - } 981 - 982 - export type TraktImportJobUncheckedUpdateManyWithoutUserInput = { 983 - id?: Prisma.StringFieldUpdateOperationsInput | string 984 - traktUsername?: Prisma.StringFieldUpdateOperationsInput | string 985 - status?: Prisma.EnumTraktImportJobStatusFieldUpdateOperationsInput | $Enums.TraktImportJobStatus 986 - currentPage?: Prisma.IntFieldUpdateOperationsInput | number 987 - totalPages?: Prisma.NullableIntFieldUpdateOperationsInput | number | null 988 - sourceCount?: Prisma.IntFieldUpdateOperationsInput | number 989 - normalizedCount?: Prisma.IntFieldUpdateOperationsInput | number 990 - importedCount?: Prisma.IntFieldUpdateOperationsInput | number 991 - skippedCount?: Prisma.IntFieldUpdateOperationsInput | number 992 - failedCount?: Prisma.IntFieldUpdateOperationsInput | number 993 - nextRunAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 994 - lastError?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 995 - profileUsername?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 996 - profileSlug?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 997 - profileName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 998 - profileAvatarUrl?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 999 - startedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 1000 - completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 1001 - createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1002 - updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1003 - } 1004 - 1005 - 1006 - 1007 - export type TraktImportJobSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{ 1008 - id?: boolean 1009 - userDid?: boolean 1010 - traktUsername?: boolean 1011 - status?: boolean 1012 - currentPage?: boolean 1013 - totalPages?: boolean 1014 - sourceCount?: boolean 1015 - normalizedCount?: boolean 1016 - importedCount?: boolean 1017 - skippedCount?: boolean 1018 - failedCount?: boolean 1019 - nextRunAt?: boolean 1020 - lastError?: boolean 1021 - profileUsername?: boolean 1022 - profileSlug?: boolean 1023 - profileName?: boolean 1024 - profileAvatarUrl?: boolean 1025 - startedAt?: boolean 1026 - completedAt?: boolean 1027 - createdAt?: boolean 1028 - updatedAt?: boolean 1029 - user?: boolean | Prisma.UserDefaultArgs<ExtArgs> 1030 - }, ExtArgs["result"]["traktImportJob"]> 1031 - 1032 - export type TraktImportJobSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{ 1033 - id?: boolean 1034 - userDid?: boolean 1035 - traktUsername?: boolean 1036 - status?: boolean 1037 - currentPage?: boolean 1038 - totalPages?: boolean 1039 - sourceCount?: boolean 1040 - normalizedCount?: boolean 1041 - importedCount?: boolean 1042 - skippedCount?: boolean 1043 - failedCount?: boolean 1044 - nextRunAt?: boolean 1045 - lastError?: boolean 1046 - profileUsername?: boolean 1047 - profileSlug?: boolean 1048 - profileName?: boolean 1049 - profileAvatarUrl?: boolean 1050 - startedAt?: boolean 1051 - completedAt?: boolean 1052 - createdAt?: boolean 1053 - updatedAt?: boolean 1054 - user?: boolean | Prisma.UserDefaultArgs<ExtArgs> 1055 - }, ExtArgs["result"]["traktImportJob"]> 1056 - 1057 - export type TraktImportJobSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{ 1058 - id?: boolean 1059 - userDid?: boolean 1060 - traktUsername?: boolean 1061 - status?: boolean 1062 - currentPage?: boolean 1063 - totalPages?: boolean 1064 - sourceCount?: boolean 1065 - normalizedCount?: boolean 1066 - importedCount?: boolean 1067 - skippedCount?: boolean 1068 - failedCount?: boolean 1069 - nextRunAt?: boolean 1070 - lastError?: boolean 1071 - profileUsername?: boolean 1072 - profileSlug?: boolean 1073 - profileName?: boolean 1074 - profileAvatarUrl?: boolean 1075 - startedAt?: boolean 1076 - completedAt?: boolean 1077 - createdAt?: boolean 1078 - updatedAt?: boolean 1079 - user?: boolean | Prisma.UserDefaultArgs<ExtArgs> 1080 - }, ExtArgs["result"]["traktImportJob"]> 1081 - 1082 - export type TraktImportJobSelectScalar = { 1083 - id?: boolean 1084 - userDid?: boolean 1085 - traktUsername?: boolean 1086 - status?: boolean 1087 - currentPage?: boolean 1088 - totalPages?: boolean 1089 - sourceCount?: boolean 1090 - normalizedCount?: boolean 1091 - importedCount?: boolean 1092 - skippedCount?: boolean 1093 - failedCount?: boolean 1094 - nextRunAt?: boolean 1095 - lastError?: boolean 1096 - profileUsername?: boolean 1097 - profileSlug?: boolean 1098 - profileName?: boolean 1099 - profileAvatarUrl?: boolean 1100 - startedAt?: boolean 1101 - completedAt?: boolean 1102 - createdAt?: boolean 1103 - updatedAt?: boolean 1104 - } 1105 - 1106 - export type TraktImportJobOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "userDid" | "traktUsername" | "status" | "currentPage" | "totalPages" | "sourceCount" | "normalizedCount" | "importedCount" | "skippedCount" | "failedCount" | "nextRunAt" | "lastError" | "profileUsername" | "profileSlug" | "profileName" | "profileAvatarUrl" | "startedAt" | "completedAt" | "createdAt" | "updatedAt", ExtArgs["result"]["traktImportJob"]> 1107 - export type TraktImportJobInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1108 - user?: boolean | Prisma.UserDefaultArgs<ExtArgs> 1109 - } 1110 - export type TraktImportJobIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1111 - user?: boolean | Prisma.UserDefaultArgs<ExtArgs> 1112 - } 1113 - export type TraktImportJobIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1114 - user?: boolean | Prisma.UserDefaultArgs<ExtArgs> 1115 - } 1116 - 1117 - export type $TraktImportJobPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1118 - name: "TraktImportJob" 1119 - objects: { 1120 - user: Prisma.$UserPayload<ExtArgs> 1121 - } 1122 - scalars: runtime.Types.Extensions.GetPayloadResult<{ 1123 - id: string 1124 - userDid: string 1125 - traktUsername: string 1126 - status: $Enums.TraktImportJobStatus 1127 - currentPage: number 1128 - totalPages: number | null 1129 - sourceCount: number 1130 - normalizedCount: number 1131 - importedCount: number 1132 - skippedCount: number 1133 - failedCount: number 1134 - nextRunAt: Date 1135 - lastError: string | null 1136 - profileUsername: string | null 1137 - profileSlug: string | null 1138 - profileName: string | null 1139 - profileAvatarUrl: string | null 1140 - startedAt: Date | null 1141 - completedAt: Date | null 1142 - createdAt: Date 1143 - updatedAt: Date 1144 - }, ExtArgs["result"]["traktImportJob"]> 1145 - composites: {} 1146 - } 1147 - 1148 - export type TraktImportJobGetPayload<S extends boolean | null | undefined | TraktImportJobDefaultArgs> = runtime.Types.Result.GetResult<Prisma.$TraktImportJobPayload, S> 1149 - 1150 - export type TraktImportJobCountArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = 1151 - Omit<TraktImportJobFindManyArgs, 'select' | 'include' | 'distinct' | 'omit'> & { 1152 - select?: TraktImportJobCountAggregateInputType | true 1153 - } 1154 - 1155 - export interface TraktImportJobDelegate<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs, GlobalOmitOptions = {}> { 1156 - [K: symbol]: { types: Prisma.TypeMap<ExtArgs>['model']['TraktImportJob'], meta: { name: 'TraktImportJob' } } 1157 - /** 1158 - * Find zero or one TraktImportJob that matches the filter. 1159 - * @param {TraktImportJobFindUniqueArgs} args - Arguments to find a TraktImportJob 1160 - * @example 1161 - * // Get one TraktImportJob 1162 - * const traktImportJob = await prisma.traktImportJob.findUnique({ 1163 - * where: { 1164 - * // ... provide filter here 1165 - * } 1166 - * }) 1167 - */ 1168 - findUnique<T extends TraktImportJobFindUniqueArgs>(args: Prisma.SelectSubset<T, TraktImportJobFindUniqueArgs<ExtArgs>>): Prisma.Prisma__TraktImportJobClient<runtime.Types.Result.GetResult<Prisma.$TraktImportJobPayload<ExtArgs>, T, "findUnique", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> 1169 - 1170 - /** 1171 - * Find one TraktImportJob that matches the filter or throw an error with `error.code='P2025'` 1172 - * if no matches were found. 1173 - * @param {TraktImportJobFindUniqueOrThrowArgs} args - Arguments to find a TraktImportJob 1174 - * @example 1175 - * // Get one TraktImportJob 1176 - * const traktImportJob = await prisma.traktImportJob.findUniqueOrThrow({ 1177 - * where: { 1178 - * // ... provide filter here 1179 - * } 1180 - * }) 1181 - */ 1182 - findUniqueOrThrow<T extends TraktImportJobFindUniqueOrThrowArgs>(args: Prisma.SelectSubset<T, TraktImportJobFindUniqueOrThrowArgs<ExtArgs>>): Prisma.Prisma__TraktImportJobClient<runtime.Types.Result.GetResult<Prisma.$TraktImportJobPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> 1183 - 1184 - /** 1185 - * Find the first TraktImportJob that matches the filter. 1186 - * Note, that providing `undefined` is treated as the value not being there. 1187 - * Read more here: https://pris.ly/d/null-undefined 1188 - * @param {TraktImportJobFindFirstArgs} args - Arguments to find a TraktImportJob 1189 - * @example 1190 - * // Get one TraktImportJob 1191 - * const traktImportJob = await prisma.traktImportJob.findFirst({ 1192 - * where: { 1193 - * // ... provide filter here 1194 - * } 1195 - * }) 1196 - */ 1197 - findFirst<T extends TraktImportJobFindFirstArgs>(args?: Prisma.SelectSubset<T, TraktImportJobFindFirstArgs<ExtArgs>>): Prisma.Prisma__TraktImportJobClient<runtime.Types.Result.GetResult<Prisma.$TraktImportJobPayload<ExtArgs>, T, "findFirst", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> 1198 - 1199 - /** 1200 - * Find the first TraktImportJob that matches the filter or 1201 - * throw `PrismaKnownClientError` with `P2025` code if no matches were found. 1202 - * Note, that providing `undefined` is treated as the value not being there. 1203 - * Read more here: https://pris.ly/d/null-undefined 1204 - * @param {TraktImportJobFindFirstOrThrowArgs} args - Arguments to find a TraktImportJob 1205 - * @example 1206 - * // Get one TraktImportJob 1207 - * const traktImportJob = await prisma.traktImportJob.findFirstOrThrow({ 1208 - * where: { 1209 - * // ... provide filter here 1210 - * } 1211 - * }) 1212 - */ 1213 - findFirstOrThrow<T extends TraktImportJobFindFirstOrThrowArgs>(args?: Prisma.SelectSubset<T, TraktImportJobFindFirstOrThrowArgs<ExtArgs>>): Prisma.Prisma__TraktImportJobClient<runtime.Types.Result.GetResult<Prisma.$TraktImportJobPayload<ExtArgs>, T, "findFirstOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> 1214 - 1215 - /** 1216 - * Find zero or more TraktImportJobs that matches the filter. 1217 - * Note, that providing `undefined` is treated as the value not being there. 1218 - * Read more here: https://pris.ly/d/null-undefined 1219 - * @param {TraktImportJobFindManyArgs} args - Arguments to filter and select certain fields only. 1220 - * @example 1221 - * // Get all TraktImportJobs 1222 - * const traktImportJobs = await prisma.traktImportJob.findMany() 1223 - * 1224 - * // Get first 10 TraktImportJobs 1225 - * const traktImportJobs = await prisma.traktImportJob.findMany({ take: 10 }) 1226 - * 1227 - * // Only select the `id` 1228 - * const traktImportJobWithIdOnly = await prisma.traktImportJob.findMany({ select: { id: true } }) 1229 - * 1230 - */ 1231 - findMany<T extends TraktImportJobFindManyArgs>(args?: Prisma.SelectSubset<T, TraktImportJobFindManyArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$TraktImportJobPayload<ExtArgs>, T, "findMany", GlobalOmitOptions>> 1232 - 1233 - /** 1234 - * Create a TraktImportJob. 1235 - * @param {TraktImportJobCreateArgs} args - Arguments to create a TraktImportJob. 1236 - * @example 1237 - * // Create one TraktImportJob 1238 - * const TraktImportJob = await prisma.traktImportJob.create({ 1239 - * data: { 1240 - * // ... data to create a TraktImportJob 1241 - * } 1242 - * }) 1243 - * 1244 - */ 1245 - create<T extends TraktImportJobCreateArgs>(args: Prisma.SelectSubset<T, TraktImportJobCreateArgs<ExtArgs>>): Prisma.Prisma__TraktImportJobClient<runtime.Types.Result.GetResult<Prisma.$TraktImportJobPayload<ExtArgs>, T, "create", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> 1246 - 1247 - /** 1248 - * Create many TraktImportJobs. 1249 - * @param {TraktImportJobCreateManyArgs} args - Arguments to create many TraktImportJobs. 1250 - * @example 1251 - * // Create many TraktImportJobs 1252 - * const traktImportJob = await prisma.traktImportJob.createMany({ 1253 - * data: [ 1254 - * // ... provide data here 1255 - * ] 1256 - * }) 1257 - * 1258 - */ 1259 - createMany<T extends TraktImportJobCreateManyArgs>(args?: Prisma.SelectSubset<T, TraktImportJobCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload> 1260 - 1261 - /** 1262 - * Create many TraktImportJobs and returns the data saved in the database. 1263 - * @param {TraktImportJobCreateManyAndReturnArgs} args - Arguments to create many TraktImportJobs. 1264 - * @example 1265 - * // Create many TraktImportJobs 1266 - * const traktImportJob = await prisma.traktImportJob.createManyAndReturn({ 1267 - * data: [ 1268 - * // ... provide data here 1269 - * ] 1270 - * }) 1271 - * 1272 - * // Create many TraktImportJobs and only return the `id` 1273 - * const traktImportJobWithIdOnly = await prisma.traktImportJob.createManyAndReturn({ 1274 - * select: { id: true }, 1275 - * data: [ 1276 - * // ... provide data here 1277 - * ] 1278 - * }) 1279 - * Note, that providing `undefined` is treated as the value not being there. 1280 - * Read more here: https://pris.ly/d/null-undefined 1281 - * 1282 - */ 1283 - createManyAndReturn<T extends TraktImportJobCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, TraktImportJobCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$TraktImportJobPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>> 1284 - 1285 - /** 1286 - * Delete a TraktImportJob. 1287 - * @param {TraktImportJobDeleteArgs} args - Arguments to delete one TraktImportJob. 1288 - * @example 1289 - * // Delete one TraktImportJob 1290 - * const TraktImportJob = await prisma.traktImportJob.delete({ 1291 - * where: { 1292 - * // ... filter to delete one TraktImportJob 1293 - * } 1294 - * }) 1295 - * 1296 - */ 1297 - delete<T extends TraktImportJobDeleteArgs>(args: Prisma.SelectSubset<T, TraktImportJobDeleteArgs<ExtArgs>>): Prisma.Prisma__TraktImportJobClient<runtime.Types.Result.GetResult<Prisma.$TraktImportJobPayload<ExtArgs>, T, "delete", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> 1298 - 1299 - /** 1300 - * Update one TraktImportJob. 1301 - * @param {TraktImportJobUpdateArgs} args - Arguments to update one TraktImportJob. 1302 - * @example 1303 - * // Update one TraktImportJob 1304 - * const traktImportJob = await prisma.traktImportJob.update({ 1305 - * where: { 1306 - * // ... provide filter here 1307 - * }, 1308 - * data: { 1309 - * // ... provide data here 1310 - * } 1311 - * }) 1312 - * 1313 - */ 1314 - update<T extends TraktImportJobUpdateArgs>(args: Prisma.SelectSubset<T, TraktImportJobUpdateArgs<ExtArgs>>): Prisma.Prisma__TraktImportJobClient<runtime.Types.Result.GetResult<Prisma.$TraktImportJobPayload<ExtArgs>, T, "update", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> 1315 - 1316 - /** 1317 - * Delete zero or more TraktImportJobs. 1318 - * @param {TraktImportJobDeleteManyArgs} args - Arguments to filter TraktImportJobs to delete. 1319 - * @example 1320 - * // Delete a few TraktImportJobs 1321 - * const { count } = await prisma.traktImportJob.deleteMany({ 1322 - * where: { 1323 - * // ... provide filter here 1324 - * } 1325 - * }) 1326 - * 1327 - */ 1328 - deleteMany<T extends TraktImportJobDeleteManyArgs>(args?: Prisma.SelectSubset<T, TraktImportJobDeleteManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload> 1329 - 1330 - /** 1331 - * Update zero or more TraktImportJobs. 1332 - * Note, that providing `undefined` is treated as the value not being there. 1333 - * Read more here: https://pris.ly/d/null-undefined 1334 - * @param {TraktImportJobUpdateManyArgs} args - Arguments to update one or more rows. 1335 - * @example 1336 - * // Update many TraktImportJobs 1337 - * const traktImportJob = await prisma.traktImportJob.updateMany({ 1338 - * where: { 1339 - * // ... provide filter here 1340 - * }, 1341 - * data: { 1342 - * // ... provide data here 1343 - * } 1344 - * }) 1345 - * 1346 - */ 1347 - updateMany<T extends TraktImportJobUpdateManyArgs>(args: Prisma.SelectSubset<T, TraktImportJobUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload> 1348 - 1349 - /** 1350 - * Update zero or more TraktImportJobs and returns the data updated in the database. 1351 - * @param {TraktImportJobUpdateManyAndReturnArgs} args - Arguments to update many TraktImportJobs. 1352 - * @example 1353 - * // Update many TraktImportJobs 1354 - * const traktImportJob = await prisma.traktImportJob.updateManyAndReturn({ 1355 - * where: { 1356 - * // ... provide filter here 1357 - * }, 1358 - * data: [ 1359 - * // ... provide data here 1360 - * ] 1361 - * }) 1362 - * 1363 - * // Update zero or more TraktImportJobs and only return the `id` 1364 - * const traktImportJobWithIdOnly = await prisma.traktImportJob.updateManyAndReturn({ 1365 - * select: { id: true }, 1366 - * where: { 1367 - * // ... provide filter here 1368 - * }, 1369 - * data: [ 1370 - * // ... provide data here 1371 - * ] 1372 - * }) 1373 - * Note, that providing `undefined` is treated as the value not being there. 1374 - * Read more here: https://pris.ly/d/null-undefined 1375 - * 1376 - */ 1377 - updateManyAndReturn<T extends TraktImportJobUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, TraktImportJobUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$TraktImportJobPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>> 1378 - 1379 - /** 1380 - * Create or update one TraktImportJob. 1381 - * @param {TraktImportJobUpsertArgs} args - Arguments to update or create a TraktImportJob. 1382 - * @example 1383 - * // Update or create a TraktImportJob 1384 - * const traktImportJob = await prisma.traktImportJob.upsert({ 1385 - * create: { 1386 - * // ... data to create a TraktImportJob 1387 - * }, 1388 - * update: { 1389 - * // ... in case it already exists, update 1390 - * }, 1391 - * where: { 1392 - * // ... the filter for the TraktImportJob we want to update 1393 - * } 1394 - * }) 1395 - */ 1396 - upsert<T extends TraktImportJobUpsertArgs>(args: Prisma.SelectSubset<T, TraktImportJobUpsertArgs<ExtArgs>>): Prisma.Prisma__TraktImportJobClient<runtime.Types.Result.GetResult<Prisma.$TraktImportJobPayload<ExtArgs>, T, "upsert", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> 1397 - 1398 - 1399 - /** 1400 - * Count the number of TraktImportJobs. 1401 - * Note, that providing `undefined` is treated as the value not being there. 1402 - * Read more here: https://pris.ly/d/null-undefined 1403 - * @param {TraktImportJobCountArgs} args - Arguments to filter TraktImportJobs to count. 1404 - * @example 1405 - * // Count the number of TraktImportJobs 1406 - * const count = await prisma.traktImportJob.count({ 1407 - * where: { 1408 - * // ... the filter for the TraktImportJobs we want to count 1409 - * } 1410 - * }) 1411 - **/ 1412 - count<T extends TraktImportJobCountArgs>( 1413 - args?: Prisma.Subset<T, TraktImportJobCountArgs>, 1414 - ): Prisma.PrismaPromise< 1415 - T extends runtime.Types.Utils.Record<'select', any> 1416 - ? T['select'] extends true 1417 - ? number 1418 - : Prisma.GetScalarType<T['select'], TraktImportJobCountAggregateOutputType> 1419 - : number 1420 - > 1421 - 1422 - /** 1423 - * Allows you to perform aggregations operations on a TraktImportJob. 1424 - * Note, that providing `undefined` is treated as the value not being there. 1425 - * Read more here: https://pris.ly/d/null-undefined 1426 - * @param {TraktImportJobAggregateArgs} args - Select which aggregations you would like to apply and on what fields. 1427 - * @example 1428 - * // Ordered by age ascending 1429 - * // Where email contains prisma.io 1430 - * // Limited to the 10 users 1431 - * const aggregations = await prisma.user.aggregate({ 1432 - * _avg: { 1433 - * age: true, 1434 - * }, 1435 - * where: { 1436 - * email: { 1437 - * contains: "prisma.io", 1438 - * }, 1439 - * }, 1440 - * orderBy: { 1441 - * age: "asc", 1442 - * }, 1443 - * take: 10, 1444 - * }) 1445 - **/ 1446 - aggregate<T extends TraktImportJobAggregateArgs>(args: Prisma.Subset<T, TraktImportJobAggregateArgs>): Prisma.PrismaPromise<GetTraktImportJobAggregateType<T>> 1447 - 1448 - /** 1449 - * Group by TraktImportJob. 1450 - * Note, that providing `undefined` is treated as the value not being there. 1451 - * Read more here: https://pris.ly/d/null-undefined 1452 - * @param {TraktImportJobGroupByArgs} args - Group by arguments. 1453 - * @example 1454 - * // Group by city, order by createdAt, get count 1455 - * const result = await prisma.user.groupBy({ 1456 - * by: ['city', 'createdAt'], 1457 - * orderBy: { 1458 - * createdAt: true 1459 - * }, 1460 - * _count: { 1461 - * _all: true 1462 - * }, 1463 - * }) 1464 - * 1465 - **/ 1466 - groupBy< 1467 - T extends TraktImportJobGroupByArgs, 1468 - HasSelectOrTake extends Prisma.Or< 1469 - Prisma.Extends<'skip', Prisma.Keys<T>>, 1470 - Prisma.Extends<'take', Prisma.Keys<T>> 1471 - >, 1472 - OrderByArg extends Prisma.True extends HasSelectOrTake 1473 - ? { orderBy: TraktImportJobGroupByArgs['orderBy'] } 1474 - : { orderBy?: TraktImportJobGroupByArgs['orderBy'] }, 1475 - OrderFields extends Prisma.ExcludeUnderscoreKeys<Prisma.Keys<Prisma.MaybeTupleToUnion<T['orderBy']>>>, 1476 - ByFields extends Prisma.MaybeTupleToUnion<T['by']>, 1477 - ByValid extends Prisma.Has<ByFields, OrderFields>, 1478 - HavingFields extends Prisma.GetHavingFields<T['having']>, 1479 - HavingValid extends Prisma.Has<ByFields, HavingFields>, 1480 - ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, 1481 - InputErrors extends ByEmpty extends Prisma.True 1482 - ? `Error: "by" must not be empty.` 1483 - : HavingValid extends Prisma.False 1484 - ? { 1485 - [P in HavingFields]: P extends ByFields 1486 - ? never 1487 - : P extends string 1488 - ? `Error: Field "${P}" used in "having" needs to be provided in "by".` 1489 - : [ 1490 - Error, 1491 - 'Field ', 1492 - P, 1493 - ` in "having" needs to be provided in "by"`, 1494 - ] 1495 - }[HavingFields] 1496 - : 'take' extends Prisma.Keys<T> 1497 - ? 'orderBy' extends Prisma.Keys<T> 1498 - ? ByValid extends Prisma.True 1499 - ? {} 1500 - : { 1501 - [P in OrderFields]: P extends ByFields 1502 - ? never 1503 - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 1504 - }[OrderFields] 1505 - : 'Error: If you provide "take", you also need to provide "orderBy"' 1506 - : 'skip' extends Prisma.Keys<T> 1507 - ? 'orderBy' extends Prisma.Keys<T> 1508 - ? ByValid extends Prisma.True 1509 - ? {} 1510 - : { 1511 - [P in OrderFields]: P extends ByFields 1512 - ? never 1513 - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 1514 - }[OrderFields] 1515 - : 'Error: If you provide "skip", you also need to provide "orderBy"' 1516 - : ByValid extends Prisma.True 1517 - ? {} 1518 - : { 1519 - [P in OrderFields]: P extends ByFields 1520 - ? never 1521 - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` 1522 - }[OrderFields] 1523 - >(args: Prisma.SubsetIntersection<T, TraktImportJobGroupByArgs, OrderByArg> & InputErrors): {} extends InputErrors ? GetTraktImportJobGroupByPayload<T> : Prisma.PrismaPromise<InputErrors> 1524 - /** 1525 - * Fields of the TraktImportJob model 1526 - */ 1527 - readonly fields: TraktImportJobFieldRefs; 1528 - } 1529 - 1530 - /** 1531 - * The delegate class that acts as a "Promise-like" for TraktImportJob. 1532 - * Why is this prefixed with `Prisma__`? 1533 - * Because we want to prevent naming conflicts as mentioned in 1534 - * https://github.com/prisma/prisma-client-js/issues/707 1535 - */ 1536 - export interface Prisma__TraktImportJobClient<T, Null = never, ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs, GlobalOmitOptions = {}> extends Prisma.PrismaPromise<T> { 1537 - readonly [Symbol.toStringTag]: "PrismaPromise" 1538 - user<T extends Prisma.UserDefaultArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.UserDefaultArgs<ExtArgs>>): Prisma.Prisma__UserClient<runtime.Types.Result.GetResult<Prisma.$UserPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | Null, Null, ExtArgs, GlobalOmitOptions> 1539 - /** 1540 - * Attaches callbacks for the resolution and/or rejection of the Promise. 1541 - * @param onfulfilled The callback to execute when the Promise is resolved. 1542 - * @param onrejected The callback to execute when the Promise is rejected. 1543 - * @returns A Promise for the completion of which ever callback is executed. 1544 - */ 1545 - then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): runtime.Types.Utils.JsPromise<TResult1 | TResult2> 1546 - /** 1547 - * Attaches a callback for only the rejection of the Promise. 1548 - * @param onrejected The callback to execute when the Promise is rejected. 1549 - * @returns A Promise for the completion of the callback. 1550 - */ 1551 - catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): runtime.Types.Utils.JsPromise<T | TResult> 1552 - /** 1553 - * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The 1554 - * resolved value cannot be modified from the callback. 1555 - * @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected). 1556 - * @returns A Promise for the completion of the callback. 1557 - */ 1558 - finally(onfinally?: (() => void) | undefined | null): runtime.Types.Utils.JsPromise<T> 1559 - } 1560 - 1561 - 1562 - 1563 - 1564 - /** 1565 - * Fields of the TraktImportJob model 1566 - */ 1567 - export interface TraktImportJobFieldRefs { 1568 - readonly id: Prisma.FieldRef<"TraktImportJob", 'String'> 1569 - readonly userDid: Prisma.FieldRef<"TraktImportJob", 'String'> 1570 - readonly traktUsername: Prisma.FieldRef<"TraktImportJob", 'String'> 1571 - readonly status: Prisma.FieldRef<"TraktImportJob", 'TraktImportJobStatus'> 1572 - readonly currentPage: Prisma.FieldRef<"TraktImportJob", 'Int'> 1573 - readonly totalPages: Prisma.FieldRef<"TraktImportJob", 'Int'> 1574 - readonly sourceCount: Prisma.FieldRef<"TraktImportJob", 'Int'> 1575 - readonly normalizedCount: Prisma.FieldRef<"TraktImportJob", 'Int'> 1576 - readonly importedCount: Prisma.FieldRef<"TraktImportJob", 'Int'> 1577 - readonly skippedCount: Prisma.FieldRef<"TraktImportJob", 'Int'> 1578 - readonly failedCount: Prisma.FieldRef<"TraktImportJob", 'Int'> 1579 - readonly nextRunAt: Prisma.FieldRef<"TraktImportJob", 'DateTime'> 1580 - readonly lastError: Prisma.FieldRef<"TraktImportJob", 'String'> 1581 - readonly profileUsername: Prisma.FieldRef<"TraktImportJob", 'String'> 1582 - readonly profileSlug: Prisma.FieldRef<"TraktImportJob", 'String'> 1583 - readonly profileName: Prisma.FieldRef<"TraktImportJob", 'String'> 1584 - readonly profileAvatarUrl: Prisma.FieldRef<"TraktImportJob", 'String'> 1585 - readonly startedAt: Prisma.FieldRef<"TraktImportJob", 'DateTime'> 1586 - readonly completedAt: Prisma.FieldRef<"TraktImportJob", 'DateTime'> 1587 - readonly createdAt: Prisma.FieldRef<"TraktImportJob", 'DateTime'> 1588 - readonly updatedAt: Prisma.FieldRef<"TraktImportJob", 'DateTime'> 1589 - } 1590 - 1591 - 1592 - // Custom InputTypes 1593 - /** 1594 - * TraktImportJob findUnique 1595 - */ 1596 - export type TraktImportJobFindUniqueArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1597 - /** 1598 - * Select specific fields to fetch from the TraktImportJob 1599 - */ 1600 - select?: Prisma.TraktImportJobSelect<ExtArgs> | null 1601 - /** 1602 - * Omit specific fields from the TraktImportJob 1603 - */ 1604 - omit?: Prisma.TraktImportJobOmit<ExtArgs> | null 1605 - /** 1606 - * Choose, which related nodes to fetch as well 1607 - */ 1608 - include?: Prisma.TraktImportJobInclude<ExtArgs> | null 1609 - /** 1610 - * Filter, which TraktImportJob to fetch. 1611 - */ 1612 - where: Prisma.TraktImportJobWhereUniqueInput 1613 - } 1614 - 1615 - /** 1616 - * TraktImportJob findUniqueOrThrow 1617 - */ 1618 - export type TraktImportJobFindUniqueOrThrowArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1619 - /** 1620 - * Select specific fields to fetch from the TraktImportJob 1621 - */ 1622 - select?: Prisma.TraktImportJobSelect<ExtArgs> | null 1623 - /** 1624 - * Omit specific fields from the TraktImportJob 1625 - */ 1626 - omit?: Prisma.TraktImportJobOmit<ExtArgs> | null 1627 - /** 1628 - * Choose, which related nodes to fetch as well 1629 - */ 1630 - include?: Prisma.TraktImportJobInclude<ExtArgs> | null 1631 - /** 1632 - * Filter, which TraktImportJob to fetch. 1633 - */ 1634 - where: Prisma.TraktImportJobWhereUniqueInput 1635 - } 1636 - 1637 - /** 1638 - * TraktImportJob findFirst 1639 - */ 1640 - export type TraktImportJobFindFirstArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1641 - /** 1642 - * Select specific fields to fetch from the TraktImportJob 1643 - */ 1644 - select?: Prisma.TraktImportJobSelect<ExtArgs> | null 1645 - /** 1646 - * Omit specific fields from the TraktImportJob 1647 - */ 1648 - omit?: Prisma.TraktImportJobOmit<ExtArgs> | null 1649 - /** 1650 - * Choose, which related nodes to fetch as well 1651 - */ 1652 - include?: Prisma.TraktImportJobInclude<ExtArgs> | null 1653 - /** 1654 - * Filter, which TraktImportJob to fetch. 1655 - */ 1656 - where?: Prisma.TraktImportJobWhereInput 1657 - /** 1658 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} 1659 - * 1660 - * Determine the order of TraktImportJobs to fetch. 1661 - */ 1662 - orderBy?: Prisma.TraktImportJobOrderByWithRelationInput | Prisma.TraktImportJobOrderByWithRelationInput[] 1663 - /** 1664 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} 1665 - * 1666 - * Sets the position for searching for TraktImportJobs. 1667 - */ 1668 - cursor?: Prisma.TraktImportJobWhereUniqueInput 1669 - /** 1670 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 1671 - * 1672 - * Take `±n` TraktImportJobs from the position of the cursor. 1673 - */ 1674 - take?: number 1675 - /** 1676 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 1677 - * 1678 - * Skip the first `n` TraktImportJobs. 1679 - */ 1680 - skip?: number 1681 - /** 1682 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} 1683 - * 1684 - * Filter by unique combinations of TraktImportJobs. 1685 - */ 1686 - distinct?: Prisma.TraktImportJobScalarFieldEnum | Prisma.TraktImportJobScalarFieldEnum[] 1687 - } 1688 - 1689 - /** 1690 - * TraktImportJob findFirstOrThrow 1691 - */ 1692 - export type TraktImportJobFindFirstOrThrowArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1693 - /** 1694 - * Select specific fields to fetch from the TraktImportJob 1695 - */ 1696 - select?: Prisma.TraktImportJobSelect<ExtArgs> | null 1697 - /** 1698 - * Omit specific fields from the TraktImportJob 1699 - */ 1700 - omit?: Prisma.TraktImportJobOmit<ExtArgs> | null 1701 - /** 1702 - * Choose, which related nodes to fetch as well 1703 - */ 1704 - include?: Prisma.TraktImportJobInclude<ExtArgs> | null 1705 - /** 1706 - * Filter, which TraktImportJob to fetch. 1707 - */ 1708 - where?: Prisma.TraktImportJobWhereInput 1709 - /** 1710 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} 1711 - * 1712 - * Determine the order of TraktImportJobs to fetch. 1713 - */ 1714 - orderBy?: Prisma.TraktImportJobOrderByWithRelationInput | Prisma.TraktImportJobOrderByWithRelationInput[] 1715 - /** 1716 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} 1717 - * 1718 - * Sets the position for searching for TraktImportJobs. 1719 - */ 1720 - cursor?: Prisma.TraktImportJobWhereUniqueInput 1721 - /** 1722 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 1723 - * 1724 - * Take `±n` TraktImportJobs from the position of the cursor. 1725 - */ 1726 - take?: number 1727 - /** 1728 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 1729 - * 1730 - * Skip the first `n` TraktImportJobs. 1731 - */ 1732 - skip?: number 1733 - /** 1734 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} 1735 - * 1736 - * Filter by unique combinations of TraktImportJobs. 1737 - */ 1738 - distinct?: Prisma.TraktImportJobScalarFieldEnum | Prisma.TraktImportJobScalarFieldEnum[] 1739 - } 1740 - 1741 - /** 1742 - * TraktImportJob findMany 1743 - */ 1744 - export type TraktImportJobFindManyArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1745 - /** 1746 - * Select specific fields to fetch from the TraktImportJob 1747 - */ 1748 - select?: Prisma.TraktImportJobSelect<ExtArgs> | null 1749 - /** 1750 - * Omit specific fields from the TraktImportJob 1751 - */ 1752 - omit?: Prisma.TraktImportJobOmit<ExtArgs> | null 1753 - /** 1754 - * Choose, which related nodes to fetch as well 1755 - */ 1756 - include?: Prisma.TraktImportJobInclude<ExtArgs> | null 1757 - /** 1758 - * Filter, which TraktImportJobs to fetch. 1759 - */ 1760 - where?: Prisma.TraktImportJobWhereInput 1761 - /** 1762 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} 1763 - * 1764 - * Determine the order of TraktImportJobs to fetch. 1765 - */ 1766 - orderBy?: Prisma.TraktImportJobOrderByWithRelationInput | Prisma.TraktImportJobOrderByWithRelationInput[] 1767 - /** 1768 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} 1769 - * 1770 - * Sets the position for listing TraktImportJobs. 1771 - */ 1772 - cursor?: Prisma.TraktImportJobWhereUniqueInput 1773 - /** 1774 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 1775 - * 1776 - * Take `±n` TraktImportJobs from the position of the cursor. 1777 - */ 1778 - take?: number 1779 - /** 1780 - * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} 1781 - * 1782 - * Skip the first `n` TraktImportJobs. 1783 - */ 1784 - skip?: number 1785 - distinct?: Prisma.TraktImportJobScalarFieldEnum | Prisma.TraktImportJobScalarFieldEnum[] 1786 - } 1787 - 1788 - /** 1789 - * TraktImportJob create 1790 - */ 1791 - export type TraktImportJobCreateArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1792 - /** 1793 - * Select specific fields to fetch from the TraktImportJob 1794 - */ 1795 - select?: Prisma.TraktImportJobSelect<ExtArgs> | null 1796 - /** 1797 - * Omit specific fields from the TraktImportJob 1798 - */ 1799 - omit?: Prisma.TraktImportJobOmit<ExtArgs> | null 1800 - /** 1801 - * Choose, which related nodes to fetch as well 1802 - */ 1803 - include?: Prisma.TraktImportJobInclude<ExtArgs> | null 1804 - /** 1805 - * The data needed to create a TraktImportJob. 1806 - */ 1807 - data: Prisma.XOR<Prisma.TraktImportJobCreateInput, Prisma.TraktImportJobUncheckedCreateInput> 1808 - } 1809 - 1810 - /** 1811 - * TraktImportJob createMany 1812 - */ 1813 - export type TraktImportJobCreateManyArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1814 - /** 1815 - * The data used to create many TraktImportJobs. 1816 - */ 1817 - data: Prisma.TraktImportJobCreateManyInput | Prisma.TraktImportJobCreateManyInput[] 1818 - skipDuplicates?: boolean 1819 - } 1820 - 1821 - /** 1822 - * TraktImportJob createManyAndReturn 1823 - */ 1824 - export type TraktImportJobCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1825 - /** 1826 - * Select specific fields to fetch from the TraktImportJob 1827 - */ 1828 - select?: Prisma.TraktImportJobSelectCreateManyAndReturn<ExtArgs> | null 1829 - /** 1830 - * Omit specific fields from the TraktImportJob 1831 - */ 1832 - omit?: Prisma.TraktImportJobOmit<ExtArgs> | null 1833 - /** 1834 - * The data used to create many TraktImportJobs. 1835 - */ 1836 - data: Prisma.TraktImportJobCreateManyInput | Prisma.TraktImportJobCreateManyInput[] 1837 - skipDuplicates?: boolean 1838 - /** 1839 - * Choose, which related nodes to fetch as well 1840 - */ 1841 - include?: Prisma.TraktImportJobIncludeCreateManyAndReturn<ExtArgs> | null 1842 - } 1843 - 1844 - /** 1845 - * TraktImportJob update 1846 - */ 1847 - export type TraktImportJobUpdateArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1848 - /** 1849 - * Select specific fields to fetch from the TraktImportJob 1850 - */ 1851 - select?: Prisma.TraktImportJobSelect<ExtArgs> | null 1852 - /** 1853 - * Omit specific fields from the TraktImportJob 1854 - */ 1855 - omit?: Prisma.TraktImportJobOmit<ExtArgs> | null 1856 - /** 1857 - * Choose, which related nodes to fetch as well 1858 - */ 1859 - include?: Prisma.TraktImportJobInclude<ExtArgs> | null 1860 - /** 1861 - * The data needed to update a TraktImportJob. 1862 - */ 1863 - data: Prisma.XOR<Prisma.TraktImportJobUpdateInput, Prisma.TraktImportJobUncheckedUpdateInput> 1864 - /** 1865 - * Choose, which TraktImportJob to update. 1866 - */ 1867 - where: Prisma.TraktImportJobWhereUniqueInput 1868 - } 1869 - 1870 - /** 1871 - * TraktImportJob updateMany 1872 - */ 1873 - export type TraktImportJobUpdateManyArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1874 - /** 1875 - * The data used to update TraktImportJobs. 1876 - */ 1877 - data: Prisma.XOR<Prisma.TraktImportJobUpdateManyMutationInput, Prisma.TraktImportJobUncheckedUpdateManyInput> 1878 - /** 1879 - * Filter which TraktImportJobs to update 1880 - */ 1881 - where?: Prisma.TraktImportJobWhereInput 1882 - /** 1883 - * Limit how many TraktImportJobs to update. 1884 - */ 1885 - limit?: number 1886 - } 1887 - 1888 - /** 1889 - * TraktImportJob updateManyAndReturn 1890 - */ 1891 - export type TraktImportJobUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1892 - /** 1893 - * Select specific fields to fetch from the TraktImportJob 1894 - */ 1895 - select?: Prisma.TraktImportJobSelectUpdateManyAndReturn<ExtArgs> | null 1896 - /** 1897 - * Omit specific fields from the TraktImportJob 1898 - */ 1899 - omit?: Prisma.TraktImportJobOmit<ExtArgs> | null 1900 - /** 1901 - * The data used to update TraktImportJobs. 1902 - */ 1903 - data: Prisma.XOR<Prisma.TraktImportJobUpdateManyMutationInput, Prisma.TraktImportJobUncheckedUpdateManyInput> 1904 - /** 1905 - * Filter which TraktImportJobs to update 1906 - */ 1907 - where?: Prisma.TraktImportJobWhereInput 1908 - /** 1909 - * Limit how many TraktImportJobs to update. 1910 - */ 1911 - limit?: number 1912 - /** 1913 - * Choose, which related nodes to fetch as well 1914 - */ 1915 - include?: Prisma.TraktImportJobIncludeUpdateManyAndReturn<ExtArgs> | null 1916 - } 1917 - 1918 - /** 1919 - * TraktImportJob upsert 1920 - */ 1921 - export type TraktImportJobUpsertArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1922 - /** 1923 - * Select specific fields to fetch from the TraktImportJob 1924 - */ 1925 - select?: Prisma.TraktImportJobSelect<ExtArgs> | null 1926 - /** 1927 - * Omit specific fields from the TraktImportJob 1928 - */ 1929 - omit?: Prisma.TraktImportJobOmit<ExtArgs> | null 1930 - /** 1931 - * Choose, which related nodes to fetch as well 1932 - */ 1933 - include?: Prisma.TraktImportJobInclude<ExtArgs> | null 1934 - /** 1935 - * The filter to search for the TraktImportJob to update in case it exists. 1936 - */ 1937 - where: Prisma.TraktImportJobWhereUniqueInput 1938 - /** 1939 - * In case the TraktImportJob found by the `where` argument doesn't exist, create a new TraktImportJob with this data. 1940 - */ 1941 - create: Prisma.XOR<Prisma.TraktImportJobCreateInput, Prisma.TraktImportJobUncheckedCreateInput> 1942 - /** 1943 - * In case the TraktImportJob was found with the provided `where` argument, update it with this data. 1944 - */ 1945 - update: Prisma.XOR<Prisma.TraktImportJobUpdateInput, Prisma.TraktImportJobUncheckedUpdateInput> 1946 - } 1947 - 1948 - /** 1949 - * TraktImportJob delete 1950 - */ 1951 - export type TraktImportJobDeleteArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1952 - /** 1953 - * Select specific fields to fetch from the TraktImportJob 1954 - */ 1955 - select?: Prisma.TraktImportJobSelect<ExtArgs> | null 1956 - /** 1957 - * Omit specific fields from the TraktImportJob 1958 - */ 1959 - omit?: Prisma.TraktImportJobOmit<ExtArgs> | null 1960 - /** 1961 - * Choose, which related nodes to fetch as well 1962 - */ 1963 - include?: Prisma.TraktImportJobInclude<ExtArgs> | null 1964 - /** 1965 - * Filter which TraktImportJob to delete. 1966 - */ 1967 - where: Prisma.TraktImportJobWhereUniqueInput 1968 - } 1969 - 1970 - /** 1971 - * TraktImportJob deleteMany 1972 - */ 1973 - export type TraktImportJobDeleteManyArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1974 - /** 1975 - * Filter which TraktImportJobs to delete 1976 - */ 1977 - where?: Prisma.TraktImportJobWhereInput 1978 - /** 1979 - * Limit how many TraktImportJobs to delete. 1980 - */ 1981 - limit?: number 1982 - } 1983 - 1984 - /** 1985 - * TraktImportJob without action 1986 - */ 1987 - export type TraktImportJobDefaultArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1988 - /** 1989 - * Select specific fields to fetch from the TraktImportJob 1990 - */ 1991 - select?: Prisma.TraktImportJobSelect<ExtArgs> | null 1992 - /** 1993 - * Omit specific fields from the TraktImportJob 1994 - */ 1995 - omit?: Prisma.TraktImportJobOmit<ExtArgs> | null 1996 - /** 1997 - * Choose, which related nodes to fetch as well 1998 - */ 1999 - include?: Prisma.TraktImportJobInclude<ExtArgs> | null 2000 - }
-190
backend/src/generated/models/User.ts
··· 272 272 updatedAt?: Prisma.DateTimeFilter<"User"> | Date | string 273 273 trackedMovies?: Prisma.TrackedMovieListRelationFilter 274 274 trackedEpisodes?: Prisma.TrackedEpisodeListRelationFilter 275 - traktImportJobs?: Prisma.TraktImportJobListRelationFilter 276 275 lists?: Prisma.ListListRelationFilter 277 276 following?: Prisma.FollowListRelationFilter 278 277 followers?: Prisma.FollowListRelationFilter ··· 297 296 updatedAt?: Prisma.SortOrder 298 297 trackedMovies?: Prisma.TrackedMovieOrderByRelationAggregateInput 299 298 trackedEpisodes?: Prisma.TrackedEpisodeOrderByRelationAggregateInput 300 - traktImportJobs?: Prisma.TraktImportJobOrderByRelationAggregateInput 301 299 lists?: Prisma.ListOrderByRelationAggregateInput 302 300 following?: Prisma.FollowOrderByRelationAggregateInput 303 301 followers?: Prisma.FollowOrderByRelationAggregateInput ··· 325 323 updatedAt?: Prisma.DateTimeFilter<"User"> | Date | string 326 324 trackedMovies?: Prisma.TrackedMovieListRelationFilter 327 325 trackedEpisodes?: Prisma.TrackedEpisodeListRelationFilter 328 - traktImportJobs?: Prisma.TraktImportJobListRelationFilter 329 326 lists?: Prisma.ListListRelationFilter 330 327 following?: Prisma.FollowListRelationFilter 331 328 followers?: Prisma.FollowListRelationFilter ··· 394 391 updatedAt?: Date | string 395 392 trackedMovies?: Prisma.TrackedMovieCreateNestedManyWithoutUserInput 396 393 trackedEpisodes?: Prisma.TrackedEpisodeCreateNestedManyWithoutUserInput 397 - traktImportJobs?: Prisma.TraktImportJobCreateNestedManyWithoutUserInput 398 394 lists?: Prisma.ListCreateNestedManyWithoutUserInput 399 395 following?: Prisma.FollowCreateNestedManyWithoutFollowerInput 400 396 followers?: Prisma.FollowCreateNestedManyWithoutFollowingInput ··· 419 415 updatedAt?: Date | string 420 416 trackedMovies?: Prisma.TrackedMovieUncheckedCreateNestedManyWithoutUserInput 421 417 trackedEpisodes?: Prisma.TrackedEpisodeUncheckedCreateNestedManyWithoutUserInput 422 - traktImportJobs?: Prisma.TraktImportJobUncheckedCreateNestedManyWithoutUserInput 423 418 lists?: Prisma.ListUncheckedCreateNestedManyWithoutUserInput 424 419 following?: Prisma.FollowUncheckedCreateNestedManyWithoutFollowerInput 425 420 followers?: Prisma.FollowUncheckedCreateNestedManyWithoutFollowingInput ··· 444 439 updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 445 440 trackedMovies?: Prisma.TrackedMovieUpdateManyWithoutUserNestedInput 446 441 trackedEpisodes?: Prisma.TrackedEpisodeUpdateManyWithoutUserNestedInput 447 - traktImportJobs?: Prisma.TraktImportJobUpdateManyWithoutUserNestedInput 448 442 lists?: Prisma.ListUpdateManyWithoutUserNestedInput 449 443 following?: Prisma.FollowUpdateManyWithoutFollowerNestedInput 450 444 followers?: Prisma.FollowUpdateManyWithoutFollowingNestedInput ··· 469 463 updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 470 464 trackedMovies?: Prisma.TrackedMovieUncheckedUpdateManyWithoutUserNestedInput 471 465 trackedEpisodes?: Prisma.TrackedEpisodeUncheckedUpdateManyWithoutUserNestedInput 472 - traktImportJobs?: Prisma.TraktImportJobUncheckedUpdateManyWithoutUserNestedInput 473 466 lists?: Prisma.ListUncheckedUpdateManyWithoutUserNestedInput 474 467 following?: Prisma.FollowUncheckedUpdateManyWithoutFollowerNestedInput 475 468 followers?: Prisma.FollowUncheckedUpdateManyWithoutFollowingNestedInput ··· 638 631 update?: Prisma.XOR<Prisma.XOR<Prisma.UserUpdateToOneWithWhereWithoutFollowersInput, Prisma.UserUpdateWithoutFollowersInput>, Prisma.UserUncheckedUpdateWithoutFollowersInput> 639 632 } 640 633 641 - export type UserCreateNestedOneWithoutTraktImportJobsInput = { 642 - create?: Prisma.XOR<Prisma.UserCreateWithoutTraktImportJobsInput, Prisma.UserUncheckedCreateWithoutTraktImportJobsInput> 643 - connectOrCreate?: Prisma.UserCreateOrConnectWithoutTraktImportJobsInput 644 - connect?: Prisma.UserWhereUniqueInput 645 - } 646 - 647 - export type UserUpdateOneRequiredWithoutTraktImportJobsNestedInput = { 648 - create?: Prisma.XOR<Prisma.UserCreateWithoutTraktImportJobsInput, Prisma.UserUncheckedCreateWithoutTraktImportJobsInput> 649 - connectOrCreate?: Prisma.UserCreateOrConnectWithoutTraktImportJobsInput 650 - upsert?: Prisma.UserUpsertWithoutTraktImportJobsInput 651 - connect?: Prisma.UserWhereUniqueInput 652 - update?: Prisma.XOR<Prisma.XOR<Prisma.UserUpdateToOneWithWhereWithoutTraktImportJobsInput, Prisma.UserUpdateWithoutTraktImportJobsInput>, Prisma.UserUncheckedUpdateWithoutTraktImportJobsInput> 653 - } 654 - 655 634 export type UserCreateNestedOneWithoutTrackedMoviesInput = { 656 635 create?: Prisma.XOR<Prisma.UserCreateWithoutTrackedMoviesInput, Prisma.UserUncheckedCreateWithoutTrackedMoviesInput> 657 636 connectOrCreate?: Prisma.UserCreateOrConnectWithoutTrackedMoviesInput ··· 713 692 updatedAt?: Date | string 714 693 trackedMovies?: Prisma.TrackedMovieCreateNestedManyWithoutUserInput 715 694 trackedEpisodes?: Prisma.TrackedEpisodeCreateNestedManyWithoutUserInput 716 - traktImportJobs?: Prisma.TraktImportJobCreateNestedManyWithoutUserInput 717 695 lists?: Prisma.ListCreateNestedManyWithoutUserInput 718 696 followers?: Prisma.FollowCreateNestedManyWithoutFollowingInput 719 697 } ··· 737 715 updatedAt?: Date | string 738 716 trackedMovies?: Prisma.TrackedMovieUncheckedCreateNestedManyWithoutUserInput 739 717 trackedEpisodes?: Prisma.TrackedEpisodeUncheckedCreateNestedManyWithoutUserInput 740 - traktImportJobs?: Prisma.TraktImportJobUncheckedCreateNestedManyWithoutUserInput 741 718 lists?: Prisma.ListUncheckedCreateNestedManyWithoutUserInput 742 719 followers?: Prisma.FollowUncheckedCreateNestedManyWithoutFollowingInput 743 720 } ··· 766 743 updatedAt?: Date | string 767 744 trackedMovies?: Prisma.TrackedMovieCreateNestedManyWithoutUserInput 768 745 trackedEpisodes?: Prisma.TrackedEpisodeCreateNestedManyWithoutUserInput 769 - traktImportJobs?: Prisma.TraktImportJobCreateNestedManyWithoutUserInput 770 746 lists?: Prisma.ListCreateNestedManyWithoutUserInput 771 747 following?: Prisma.FollowCreateNestedManyWithoutFollowerInput 772 748 } ··· 790 766 updatedAt?: Date | string 791 767 trackedMovies?: Prisma.TrackedMovieUncheckedCreateNestedManyWithoutUserInput 792 768 trackedEpisodes?: Prisma.TrackedEpisodeUncheckedCreateNestedManyWithoutUserInput 793 - traktImportJobs?: Prisma.TraktImportJobUncheckedCreateNestedManyWithoutUserInput 794 769 lists?: Prisma.ListUncheckedCreateNestedManyWithoutUserInput 795 770 following?: Prisma.FollowUncheckedCreateNestedManyWithoutFollowerInput 796 771 } ··· 830 805 updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 831 806 trackedMovies?: Prisma.TrackedMovieUpdateManyWithoutUserNestedInput 832 807 trackedEpisodes?: Prisma.TrackedEpisodeUpdateManyWithoutUserNestedInput 833 - traktImportJobs?: Prisma.TraktImportJobUpdateManyWithoutUserNestedInput 834 808 lists?: Prisma.ListUpdateManyWithoutUserNestedInput 835 809 followers?: Prisma.FollowUpdateManyWithoutFollowingNestedInput 836 810 } ··· 854 828 updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 855 829 trackedMovies?: Prisma.TrackedMovieUncheckedUpdateManyWithoutUserNestedInput 856 830 trackedEpisodes?: Prisma.TrackedEpisodeUncheckedUpdateManyWithoutUserNestedInput 857 - traktImportJobs?: Prisma.TraktImportJobUncheckedUpdateManyWithoutUserNestedInput 858 831 lists?: Prisma.ListUncheckedUpdateManyWithoutUserNestedInput 859 832 followers?: Prisma.FollowUncheckedUpdateManyWithoutFollowingNestedInput 860 833 } ··· 889 862 updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 890 863 trackedMovies?: Prisma.TrackedMovieUpdateManyWithoutUserNestedInput 891 864 trackedEpisodes?: Prisma.TrackedEpisodeUpdateManyWithoutUserNestedInput 892 - traktImportJobs?: Prisma.TraktImportJobUpdateManyWithoutUserNestedInput 893 865 lists?: Prisma.ListUpdateManyWithoutUserNestedInput 894 866 following?: Prisma.FollowUpdateManyWithoutFollowerNestedInput 895 867 } ··· 913 885 updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 914 886 trackedMovies?: Prisma.TrackedMovieUncheckedUpdateManyWithoutUserNestedInput 915 887 trackedEpisodes?: Prisma.TrackedEpisodeUncheckedUpdateManyWithoutUserNestedInput 916 - traktImportJobs?: Prisma.TraktImportJobUncheckedUpdateManyWithoutUserNestedInput 917 888 lists?: Prisma.ListUncheckedUpdateManyWithoutUserNestedInput 918 889 following?: Prisma.FollowUncheckedUpdateManyWithoutFollowerNestedInput 919 890 } 920 891 921 - export type UserCreateWithoutTraktImportJobsInput = { 922 - did: string 923 - handle: string 924 - displayName?: string | null 925 - avatar?: string | null 926 - profileRkey?: string | null 927 - profileUri?: string | null 928 - profileCid?: string | null 929 - profileDisplayName?: string | null 930 - profileAvatarCid?: string | null 931 - profileAvatarMimeType?: string | null 932 - profileUpdatedAt?: Date | string | null 933 - timezone?: string 934 - timeFormat?: string 935 - onboardingCompletedAt?: Date | string | null 936 - createdAt?: Date | string 937 - updatedAt?: Date | string 938 - trackedMovies?: Prisma.TrackedMovieCreateNestedManyWithoutUserInput 939 - trackedEpisodes?: Prisma.TrackedEpisodeCreateNestedManyWithoutUserInput 940 - lists?: Prisma.ListCreateNestedManyWithoutUserInput 941 - following?: Prisma.FollowCreateNestedManyWithoutFollowerInput 942 - followers?: Prisma.FollowCreateNestedManyWithoutFollowingInput 943 - } 944 - 945 - export type UserUncheckedCreateWithoutTraktImportJobsInput = { 946 - did: string 947 - handle: string 948 - displayName?: string | null 949 - avatar?: string | null 950 - profileRkey?: string | null 951 - profileUri?: string | null 952 - profileCid?: string | null 953 - profileDisplayName?: string | null 954 - profileAvatarCid?: string | null 955 - profileAvatarMimeType?: string | null 956 - profileUpdatedAt?: Date | string | null 957 - timezone?: string 958 - timeFormat?: string 959 - onboardingCompletedAt?: Date | string | null 960 - createdAt?: Date | string 961 - updatedAt?: Date | string 962 - trackedMovies?: Prisma.TrackedMovieUncheckedCreateNestedManyWithoutUserInput 963 - trackedEpisodes?: Prisma.TrackedEpisodeUncheckedCreateNestedManyWithoutUserInput 964 - lists?: Prisma.ListUncheckedCreateNestedManyWithoutUserInput 965 - following?: Prisma.FollowUncheckedCreateNestedManyWithoutFollowerInput 966 - followers?: Prisma.FollowUncheckedCreateNestedManyWithoutFollowingInput 967 - } 968 - 969 - export type UserCreateOrConnectWithoutTraktImportJobsInput = { 970 - where: Prisma.UserWhereUniqueInput 971 - create: Prisma.XOR<Prisma.UserCreateWithoutTraktImportJobsInput, Prisma.UserUncheckedCreateWithoutTraktImportJobsInput> 972 - } 973 - 974 - export type UserUpsertWithoutTraktImportJobsInput = { 975 - update: Prisma.XOR<Prisma.UserUpdateWithoutTraktImportJobsInput, Prisma.UserUncheckedUpdateWithoutTraktImportJobsInput> 976 - create: Prisma.XOR<Prisma.UserCreateWithoutTraktImportJobsInput, Prisma.UserUncheckedCreateWithoutTraktImportJobsInput> 977 - where?: Prisma.UserWhereInput 978 - } 979 - 980 - export type UserUpdateToOneWithWhereWithoutTraktImportJobsInput = { 981 - where?: Prisma.UserWhereInput 982 - data: Prisma.XOR<Prisma.UserUpdateWithoutTraktImportJobsInput, Prisma.UserUncheckedUpdateWithoutTraktImportJobsInput> 983 - } 984 - 985 - export type UserUpdateWithoutTraktImportJobsInput = { 986 - did?: Prisma.StringFieldUpdateOperationsInput | string 987 - handle?: Prisma.StringFieldUpdateOperationsInput | string 988 - displayName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 989 - avatar?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 990 - profileRkey?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 991 - profileUri?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 992 - profileCid?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 993 - profileDisplayName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 994 - profileAvatarCid?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 995 - profileAvatarMimeType?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 996 - profileUpdatedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 997 - timezone?: Prisma.StringFieldUpdateOperationsInput | string 998 - timeFormat?: Prisma.StringFieldUpdateOperationsInput | string 999 - onboardingCompletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 1000 - createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1001 - updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1002 - trackedMovies?: Prisma.TrackedMovieUpdateManyWithoutUserNestedInput 1003 - trackedEpisodes?: Prisma.TrackedEpisodeUpdateManyWithoutUserNestedInput 1004 - lists?: Prisma.ListUpdateManyWithoutUserNestedInput 1005 - following?: Prisma.FollowUpdateManyWithoutFollowerNestedInput 1006 - followers?: Prisma.FollowUpdateManyWithoutFollowingNestedInput 1007 - } 1008 - 1009 - export type UserUncheckedUpdateWithoutTraktImportJobsInput = { 1010 - did?: Prisma.StringFieldUpdateOperationsInput | string 1011 - handle?: Prisma.StringFieldUpdateOperationsInput | string 1012 - displayName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 1013 - avatar?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 1014 - profileRkey?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 1015 - profileUri?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 1016 - profileCid?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 1017 - profileDisplayName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 1018 - profileAvatarCid?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 1019 - profileAvatarMimeType?: Prisma.NullableStringFieldUpdateOperationsInput | string | null 1020 - profileUpdatedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 1021 - timezone?: Prisma.StringFieldUpdateOperationsInput | string 1022 - timeFormat?: Prisma.StringFieldUpdateOperationsInput | string 1023 - onboardingCompletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null 1024 - createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1025 - updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1026 - trackedMovies?: Prisma.TrackedMovieUncheckedUpdateManyWithoutUserNestedInput 1027 - trackedEpisodes?: Prisma.TrackedEpisodeUncheckedUpdateManyWithoutUserNestedInput 1028 - lists?: Prisma.ListUncheckedUpdateManyWithoutUserNestedInput 1029 - following?: Prisma.FollowUncheckedUpdateManyWithoutFollowerNestedInput 1030 - followers?: Prisma.FollowUncheckedUpdateManyWithoutFollowingNestedInput 1031 - } 1032 - 1033 892 export type UserCreateWithoutTrackedMoviesInput = { 1034 893 did: string 1035 894 handle: string ··· 1048 907 createdAt?: Date | string 1049 908 updatedAt?: Date | string 1050 909 trackedEpisodes?: Prisma.TrackedEpisodeCreateNestedManyWithoutUserInput 1051 - traktImportJobs?: Prisma.TraktImportJobCreateNestedManyWithoutUserInput 1052 910 lists?: Prisma.ListCreateNestedManyWithoutUserInput 1053 911 following?: Prisma.FollowCreateNestedManyWithoutFollowerInput 1054 912 followers?: Prisma.FollowCreateNestedManyWithoutFollowingInput ··· 1072 930 createdAt?: Date | string 1073 931 updatedAt?: Date | string 1074 932 trackedEpisodes?: Prisma.TrackedEpisodeUncheckedCreateNestedManyWithoutUserInput 1075 - traktImportJobs?: Prisma.TraktImportJobUncheckedCreateNestedManyWithoutUserInput 1076 933 lists?: Prisma.ListUncheckedCreateNestedManyWithoutUserInput 1077 934 following?: Prisma.FollowUncheckedCreateNestedManyWithoutFollowerInput 1078 935 followers?: Prisma.FollowUncheckedCreateNestedManyWithoutFollowingInput ··· 1112 969 createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1113 970 updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1114 971 trackedEpisodes?: Prisma.TrackedEpisodeUpdateManyWithoutUserNestedInput 1115 - traktImportJobs?: Prisma.TraktImportJobUpdateManyWithoutUserNestedInput 1116 972 lists?: Prisma.ListUpdateManyWithoutUserNestedInput 1117 973 following?: Prisma.FollowUpdateManyWithoutFollowerNestedInput 1118 974 followers?: Prisma.FollowUpdateManyWithoutFollowingNestedInput ··· 1136 992 createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1137 993 updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1138 994 trackedEpisodes?: Prisma.TrackedEpisodeUncheckedUpdateManyWithoutUserNestedInput 1139 - traktImportJobs?: Prisma.TraktImportJobUncheckedUpdateManyWithoutUserNestedInput 1140 995 lists?: Prisma.ListUncheckedUpdateManyWithoutUserNestedInput 1141 996 following?: Prisma.FollowUncheckedUpdateManyWithoutFollowerNestedInput 1142 997 followers?: Prisma.FollowUncheckedUpdateManyWithoutFollowingNestedInput ··· 1160 1015 createdAt?: Date | string 1161 1016 updatedAt?: Date | string 1162 1017 trackedMovies?: Prisma.TrackedMovieCreateNestedManyWithoutUserInput 1163 - traktImportJobs?: Prisma.TraktImportJobCreateNestedManyWithoutUserInput 1164 1018 lists?: Prisma.ListCreateNestedManyWithoutUserInput 1165 1019 following?: Prisma.FollowCreateNestedManyWithoutFollowerInput 1166 1020 followers?: Prisma.FollowCreateNestedManyWithoutFollowingInput ··· 1184 1038 createdAt?: Date | string 1185 1039 updatedAt?: Date | string 1186 1040 trackedMovies?: Prisma.TrackedMovieUncheckedCreateNestedManyWithoutUserInput 1187 - traktImportJobs?: Prisma.TraktImportJobUncheckedCreateNestedManyWithoutUserInput 1188 1041 lists?: Prisma.ListUncheckedCreateNestedManyWithoutUserInput 1189 1042 following?: Prisma.FollowUncheckedCreateNestedManyWithoutFollowerInput 1190 1043 followers?: Prisma.FollowUncheckedCreateNestedManyWithoutFollowingInput ··· 1224 1077 createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1225 1078 updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1226 1079 trackedMovies?: Prisma.TrackedMovieUpdateManyWithoutUserNestedInput 1227 - traktImportJobs?: Prisma.TraktImportJobUpdateManyWithoutUserNestedInput 1228 1080 lists?: Prisma.ListUpdateManyWithoutUserNestedInput 1229 1081 following?: Prisma.FollowUpdateManyWithoutFollowerNestedInput 1230 1082 followers?: Prisma.FollowUpdateManyWithoutFollowingNestedInput ··· 1248 1100 createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1249 1101 updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1250 1102 trackedMovies?: Prisma.TrackedMovieUncheckedUpdateManyWithoutUserNestedInput 1251 - traktImportJobs?: Prisma.TraktImportJobUncheckedUpdateManyWithoutUserNestedInput 1252 1103 lists?: Prisma.ListUncheckedUpdateManyWithoutUserNestedInput 1253 1104 following?: Prisma.FollowUncheckedUpdateManyWithoutFollowerNestedInput 1254 1105 followers?: Prisma.FollowUncheckedUpdateManyWithoutFollowingNestedInput ··· 1273 1124 updatedAt?: Date | string 1274 1125 trackedMovies?: Prisma.TrackedMovieCreateNestedManyWithoutUserInput 1275 1126 trackedEpisodes?: Prisma.TrackedEpisodeCreateNestedManyWithoutUserInput 1276 - traktImportJobs?: Prisma.TraktImportJobCreateNestedManyWithoutUserInput 1277 1127 following?: Prisma.FollowCreateNestedManyWithoutFollowerInput 1278 1128 followers?: Prisma.FollowCreateNestedManyWithoutFollowingInput 1279 1129 } ··· 1297 1147 updatedAt?: Date | string 1298 1148 trackedMovies?: Prisma.TrackedMovieUncheckedCreateNestedManyWithoutUserInput 1299 1149 trackedEpisodes?: Prisma.TrackedEpisodeUncheckedCreateNestedManyWithoutUserInput 1300 - traktImportJobs?: Prisma.TraktImportJobUncheckedCreateNestedManyWithoutUserInput 1301 1150 following?: Prisma.FollowUncheckedCreateNestedManyWithoutFollowerInput 1302 1151 followers?: Prisma.FollowUncheckedCreateNestedManyWithoutFollowingInput 1303 1152 } ··· 1337 1186 updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1338 1187 trackedMovies?: Prisma.TrackedMovieUpdateManyWithoutUserNestedInput 1339 1188 trackedEpisodes?: Prisma.TrackedEpisodeUpdateManyWithoutUserNestedInput 1340 - traktImportJobs?: Prisma.TraktImportJobUpdateManyWithoutUserNestedInput 1341 1189 following?: Prisma.FollowUpdateManyWithoutFollowerNestedInput 1342 1190 followers?: Prisma.FollowUpdateManyWithoutFollowingNestedInput 1343 1191 } ··· 1361 1209 updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string 1362 1210 trackedMovies?: Prisma.TrackedMovieUncheckedUpdateManyWithoutUserNestedInput 1363 1211 trackedEpisodes?: Prisma.TrackedEpisodeUncheckedUpdateManyWithoutUserNestedInput 1364 - traktImportJobs?: Prisma.TraktImportJobUncheckedUpdateManyWithoutUserNestedInput 1365 1212 following?: Prisma.FollowUncheckedUpdateManyWithoutFollowerNestedInput 1366 1213 followers?: Prisma.FollowUncheckedUpdateManyWithoutFollowingNestedInput 1367 1214 } ··· 1374 1221 export type UserCountOutputType = { 1375 1222 trackedMovies: number 1376 1223 trackedEpisodes: number 1377 - traktImportJobs: number 1378 1224 lists: number 1379 1225 following: number 1380 1226 followers: number ··· 1383 1229 export type UserCountOutputTypeSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1384 1230 trackedMovies?: boolean | UserCountOutputTypeCountTrackedMoviesArgs 1385 1231 trackedEpisodes?: boolean | UserCountOutputTypeCountTrackedEpisodesArgs 1386 - traktImportJobs?: boolean | UserCountOutputTypeCountTraktImportJobsArgs 1387 1232 lists?: boolean | UserCountOutputTypeCountListsArgs 1388 1233 following?: boolean | UserCountOutputTypeCountFollowingArgs 1389 1234 followers?: boolean | UserCountOutputTypeCountFollowersArgs ··· 1416 1261 /** 1417 1262 * UserCountOutputType without action 1418 1263 */ 1419 - export type UserCountOutputTypeCountTraktImportJobsArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1420 - where?: Prisma.TraktImportJobWhereInput 1421 - } 1422 - 1423 - /** 1424 - * UserCountOutputType without action 1425 - */ 1426 1264 export type UserCountOutputTypeCountListsArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1427 1265 where?: Prisma.ListWhereInput 1428 1266 } ··· 1461 1299 updatedAt?: boolean 1462 1300 trackedMovies?: boolean | Prisma.User$trackedMoviesArgs<ExtArgs> 1463 1301 trackedEpisodes?: boolean | Prisma.User$trackedEpisodesArgs<ExtArgs> 1464 - traktImportJobs?: boolean | Prisma.User$traktImportJobsArgs<ExtArgs> 1465 1302 lists?: boolean | Prisma.User$listsArgs<ExtArgs> 1466 1303 following?: boolean | Prisma.User$followingArgs<ExtArgs> 1467 1304 followers?: boolean | Prisma.User$followersArgs<ExtArgs> ··· 1529 1366 export type UserInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 1530 1367 trackedMovies?: boolean | Prisma.User$trackedMoviesArgs<ExtArgs> 1531 1368 trackedEpisodes?: boolean | Prisma.User$trackedEpisodesArgs<ExtArgs> 1532 - traktImportJobs?: boolean | Prisma.User$traktImportJobsArgs<ExtArgs> 1533 1369 lists?: boolean | Prisma.User$listsArgs<ExtArgs> 1534 1370 following?: boolean | Prisma.User$followingArgs<ExtArgs> 1535 1371 followers?: boolean | Prisma.User$followersArgs<ExtArgs> ··· 1543 1379 objects: { 1544 1380 trackedMovies: Prisma.$TrackedMoviePayload<ExtArgs>[] 1545 1381 trackedEpisodes: Prisma.$TrackedEpisodePayload<ExtArgs>[] 1546 - traktImportJobs: Prisma.$TraktImportJobPayload<ExtArgs>[] 1547 1382 lists: Prisma.$ListPayload<ExtArgs>[] 1548 1383 following: Prisma.$FollowPayload<ExtArgs>[] 1549 1384 followers: Prisma.$FollowPayload<ExtArgs>[] ··· 1961 1796 readonly [Symbol.toStringTag]: "PrismaPromise" 1962 1797 trackedMovies<T extends Prisma.User$trackedMoviesArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.User$trackedMoviesArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$TrackedMoviePayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null> 1963 1798 trackedEpisodes<T extends Prisma.User$trackedEpisodesArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.User$trackedEpisodesArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$TrackedEpisodePayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null> 1964 - traktImportJobs<T extends Prisma.User$traktImportJobsArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.User$traktImportJobsArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$TraktImportJobPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null> 1965 1799 lists<T extends Prisma.User$listsArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.User$listsArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ListPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null> 1966 1800 following<T extends Prisma.User$followingArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.User$followingArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$FollowPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null> 1967 1801 followers<T extends Prisma.User$followersArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.User$followersArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$FollowPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null> ··· 2443 2277 take?: number 2444 2278 skip?: number 2445 2279 distinct?: Prisma.TrackedEpisodeScalarFieldEnum | Prisma.TrackedEpisodeScalarFieldEnum[] 2446 - } 2447 - 2448 - /** 2449 - * User.traktImportJobs 2450 - */ 2451 - export type User$traktImportJobsArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { 2452 - /** 2453 - * Select specific fields to fetch from the TraktImportJob 2454 - */ 2455 - select?: Prisma.TraktImportJobSelect<ExtArgs> | null 2456 - /** 2457 - * Omit specific fields from the TraktImportJob 2458 - */ 2459 - omit?: Prisma.TraktImportJobOmit<ExtArgs> | null 2460 - /** 2461 - * Choose, which related nodes to fetch as well 2462 - */ 2463 - include?: Prisma.TraktImportJobInclude<ExtArgs> | null 2464 - where?: Prisma.TraktImportJobWhereInput 2465 - orderBy?: Prisma.TraktImportJobOrderByWithRelationInput | Prisma.TraktImportJobOrderByWithRelationInput[] 2466 - cursor?: Prisma.TraktImportJobWhereUniqueInput 2467 - take?: number 2468 - skip?: number 2469 - distinct?: Prisma.TraktImportJobScalarFieldEnum | Prisma.TraktImportJobScalarFieldEnum[] 2470 2280 } 2471 2281 2472 2282 /**
+87
backend/src/users/background-job-data.ts
··· 1 + export const TRAKT_IMPORT_JOB_TYPE = "trakt_import" as const; 2 + export const ACCOUNT_DELETION_JOB_TYPE = "account_deletion" as const; 3 + 4 + export type BackgroundJobType = 5 + | typeof TRAKT_IMPORT_JOB_TYPE 6 + | typeof ACCOUNT_DELETION_JOB_TYPE; 7 + 8 + export type TraktImportJobData = { 9 + traktUsername: string; 10 + currentPage: number; 11 + totalPages: number | null; 12 + sourceCount: number; 13 + normalizedCount: number; 14 + importedCount: number; 15 + skippedCount: number; 16 + failedCount: number; 17 + profileUsername?: string; 18 + profileSlug?: string; 19 + profileName?: string; 20 + profileAvatarUrl?: string; 21 + }; 22 + 23 + export type AccountDeletionJobData = { 24 + deletePdsData: boolean; 25 + totalRecords: number; 26 + deletedRecords: number; 27 + currentStep?: string; 28 + }; 29 + 30 + export function parseTraktImportData(json: unknown): TraktImportJobData { 31 + const data = json as Record<string, unknown>; 32 + return { 33 + traktUsername: String(data.traktUsername ?? ""), 34 + currentPage: Number(data.currentPage ?? 1), 35 + totalPages: data.totalPages != null ? Number(data.totalPages) : null, 36 + sourceCount: Number(data.sourceCount ?? 0), 37 + normalizedCount: Number(data.normalizedCount ?? 0), 38 + importedCount: Number(data.importedCount ?? 0), 39 + skippedCount: Number(data.skippedCount ?? 0), 40 + failedCount: Number(data.failedCount ?? 0), 41 + profileUsername: data.profileUsername 42 + ? String(data.profileUsername) 43 + : undefined, 44 + profileSlug: data.profileSlug ? String(data.profileSlug) : undefined, 45 + profileName: data.profileName ? String(data.profileName) : undefined, 46 + profileAvatarUrl: data.profileAvatarUrl 47 + ? String(data.profileAvatarUrl) 48 + : undefined, 49 + }; 50 + } 51 + 52 + export function parseAccountDeletionData( 53 + json: unknown, 54 + ): AccountDeletionJobData { 55 + const data = json as Record<string, unknown>; 56 + return { 57 + deletePdsData: Boolean(data.deletePdsData ?? false), 58 + totalRecords: Number(data.totalRecords ?? 0), 59 + deletedRecords: Number(data.deletedRecords ?? 0), 60 + currentStep: data.currentStep ? String(data.currentStep) : undefined, 61 + }; 62 + } 63 + 64 + export function buildTraktImportData( 65 + partial: Partial<TraktImportJobData> & { traktUsername: string }, 66 + ): TraktImportJobData { 67 + return { 68 + currentPage: 1, 69 + totalPages: null, 70 + sourceCount: 0, 71 + normalizedCount: 0, 72 + importedCount: 0, 73 + skippedCount: 0, 74 + failedCount: 0, 75 + ...partial, 76 + }; 77 + } 78 + 79 + export function buildAccountDeletionData( 80 + partial: Partial<AccountDeletionJobData> & { deletePdsData: boolean }, 81 + ): AccountDeletionJobData { 82 + return { 83 + totalRecords: 0, 84 + deletedRecords: 0, 85 + ...partial, 86 + }; 87 + }
+26 -1
backend/src/users/dto/user-settings.dto.ts
··· 1 - import { ApiProperty } from "@nestjs/swagger"; 1 + import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; 2 2 import { IsBoolean, IsIn, IsOptional, IsString } from "class-validator"; 3 3 4 4 export class UpdateUserSettingsDto { ··· 30 30 @IsBoolean() 31 31 @IsOptional() 32 32 deletePDSData?: boolean; 33 + } 34 + 35 + export class AccountDeletionJobDto { 36 + @ApiProperty() 37 + id!: string; 38 + 39 + @ApiProperty({ 40 + enum: ["queued", "running", "completed", "failed"], 41 + }) 42 + status!: string; 43 + 44 + @ApiProperty() 45 + totalRecords!: number; 46 + 47 + @ApiProperty() 48 + deletedRecords!: number; 49 + 50 + @ApiPropertyOptional() 51 + currentStep?: string; 52 + 53 + @ApiPropertyOptional() 54 + lastError?: string; 55 + 56 + @ApiProperty() 57 + createdAt!: string; 33 58 } 34 59 35 60 export class UserSettingsDto {
+72 -47
backend/src/users/import-history.service.spec.ts
··· 9 9 let service: ImportHistoryService; 10 10 11 11 function buildTraktImportJob(overrides: Record<string, unknown> = {}) { 12 + const { 13 + traktUsername = "alice", 14 + currentPage = 1, 15 + totalPages = null, 16 + sourceCount = 0, 17 + normalizedCount = 0, 18 + importedCount = 0, 19 + skippedCount = 0, 20 + failedCount = 0, 21 + profileUsername = "alice", 22 + profileSlug = "alice", 23 + profileName = "Alice Example", 24 + profileAvatarUrl = "https://example.com/avatar.jpg", 25 + ...rest 26 + } = overrides; 12 27 return { 13 28 id: "job-1", 29 + type: "trakt_import", 14 30 userDid: "did:plc:abc", 15 - traktUsername: "alice", 16 31 status: "queued", 17 - currentPage: 1, 18 - totalPages: null, 19 - sourceCount: 0, 20 - normalizedCount: 0, 21 - importedCount: 0, 22 - skippedCount: 0, 23 - failedCount: 0, 32 + data: { 33 + traktUsername, 34 + currentPage, 35 + totalPages, 36 + sourceCount, 37 + normalizedCount, 38 + importedCount, 39 + skippedCount, 40 + failedCount, 41 + profileUsername, 42 + profileSlug, 43 + profileName, 44 + profileAvatarUrl, 45 + }, 24 46 nextRunAt: new Date("2026-03-23T18:00:00.000Z"), 25 47 lastError: null, 26 - profileUsername: "alice", 27 - profileSlug: "alice", 28 - profileName: "Alice Example", 29 - profileAvatarUrl: "https://example.com/avatar.jpg", 30 48 startedAt: null, 31 49 completedAt: null, 32 50 createdAt: new Date("2026-03-23T18:00:00.000Z"), 33 51 updatedAt: new Date("2026-03-23T18:00:00.000Z"), 34 - ...overrides, 52 + ...rest, 35 53 }; 36 54 } 37 55 ··· 45 63 authSession: { 46 64 findUnique: jest.fn(), 47 65 }, 48 - traktImportJob: { 66 + backgroundJob: { 49 67 findFirst: jest.fn(), 50 68 findUnique: jest.fn(), 51 69 create: jest.fn(), ··· 91 109 }); 92 110 93 111 it("starts a new background Trakt import with preview data", async () => { 94 - prisma.traktImportJob.findFirst = jest.fn().mockResolvedValue(null); 95 - prisma.traktImportJob.create = jest 112 + prisma.backgroundJob.findFirst = jest.fn().mockResolvedValue(null); 113 + prisma.backgroundJob.create = jest 96 114 .fn() 97 115 .mockResolvedValue(buildTraktImportJob()); 98 116 ··· 146 164 status: "queued", 147 165 }, 148 166 }); 149 - expect(prisma.traktImportJob.create).toHaveBeenCalledWith( 167 + expect(prisma.backgroundJob.create).toHaveBeenCalledWith( 150 168 expect.objectContaining({ 151 169 data: expect.objectContaining({ 170 + type: "trakt_import", 152 171 userDid: "did:plc:abc", 153 - traktUsername: "alice", 154 - profileUsername: "alice", 172 + data: expect.objectContaining({ 173 + traktUsername: "alice", 174 + profileUsername: "alice", 175 + }), 155 176 }), 156 177 }), 157 178 ); 158 179 }); 159 180 160 181 it("reuses an existing active Trakt import job", async () => { 161 - prisma.traktImportJob.findFirst = jest.fn().mockResolvedValue( 182 + prisma.backgroundJob.findFirst = jest.fn().mockResolvedValue( 162 183 buildTraktImportJob({ 163 184 status: "running", 164 185 currentPage: 2, ··· 195 216 status: "running", 196 217 }, 197 218 }); 198 - expect(prisma.traktImportJob.create).not.toHaveBeenCalled(); 219 + expect(prisma.backgroundJob.create).not.toHaveBeenCalled(); 199 220 }); 200 221 201 222 it("moves a job to waiting_retry when Trakt returns 429", async () => { 202 223 const job = buildTraktImportJob({ profileAvatarUrl: null }); 203 - prisma.traktImportJob.findFirst = jest.fn().mockResolvedValue(job); 204 - prisma.traktImportJob.findUnique = jest.fn().mockResolvedValue(job); 205 - prisma.traktImportJob.update = jest.fn().mockResolvedValue(job); 224 + prisma.backgroundJob.findFirst = jest.fn().mockResolvedValue(job); 225 + prisma.backgroundJob.findUnique = jest.fn().mockResolvedValue(job); 226 + prisma.backgroundJob.update = jest.fn().mockResolvedValue(job); 206 227 (authService.restore as jest.Mock).mockResolvedValue({ 207 228 did: "did:plc:abc", 208 229 }); ··· 218 239 219 240 await service.processNextTraktImportJob(); 220 241 221 - expect(prisma.traktImportJob.update).toHaveBeenLastCalledWith( 242 + expect(prisma.backgroundJob.update).toHaveBeenLastCalledWith( 222 243 expect.objectContaining({ 223 244 where: { id: "job-1" }, 224 245 data: expect.objectContaining({ ··· 231 252 232 253 it("processes a Trakt job page and marks the job completed", async () => { 233 254 const job = buildTraktImportJob({ profileAvatarUrl: null }); 234 - prisma.traktImportJob.findFirst = jest.fn().mockResolvedValue(job); 235 - prisma.traktImportJob.findUnique = jest.fn().mockResolvedValue(job); 236 - prisma.traktImportJob.update = jest.fn().mockResolvedValue(job); 255 + prisma.backgroundJob.findFirst = jest.fn().mockResolvedValue(job); 256 + prisma.backgroundJob.findUnique = jest.fn().mockResolvedValue(job); 257 + prisma.backgroundJob.update = jest.fn().mockResolvedValue(job); 237 258 (authService.restore as jest.Mock).mockResolvedValue({ 238 259 did: "did:plc:abc", 239 260 }); ··· 276 297 "329865", 277 298 "2026-03-22T12:00:00.000Z", 278 299 ); 279 - expect(prisma.traktImportJob.update).toHaveBeenLastCalledWith( 300 + expect(prisma.backgroundJob.update).toHaveBeenLastCalledWith( 280 301 expect.objectContaining({ 281 302 where: { id: "job-1" }, 282 303 data: expect.objectContaining({ 283 304 status: "completed", 284 - importedCount: 1, 285 - normalizedCount: 1, 286 - sourceCount: 1, 305 + data: expect.objectContaining({ 306 + importedCount: 1, 307 + normalizedCount: 1, 308 + sourceCount: 1, 309 + }), 287 310 lastError: null, 288 311 }), 289 312 }), ··· 292 315 293 316 it("keeps a Trakt job running when Trakt reports more pages after a short page", async () => { 294 317 const job = buildTraktImportJob({ profileAvatarUrl: null }); 295 - prisma.traktImportJob.findFirst = jest.fn().mockResolvedValue(job); 296 - prisma.traktImportJob.findUnique = jest.fn().mockResolvedValue(job); 297 - prisma.traktImportJob.update = jest.fn().mockResolvedValue(job); 318 + prisma.backgroundJob.findFirst = jest.fn().mockResolvedValue(job); 319 + prisma.backgroundJob.findUnique = jest.fn().mockResolvedValue(job); 320 + prisma.backgroundJob.update = jest.fn().mockResolvedValue(job); 298 321 (authService.restore as jest.Mock).mockResolvedValue({ 299 322 did: "did:plc:abc", 300 323 }); ··· 328 351 329 352 await service.processNextTraktImportJob(); 330 353 331 - expect(prisma.traktImportJob.update).toHaveBeenLastCalledWith( 354 + expect(prisma.backgroundJob.update).toHaveBeenLastCalledWith( 332 355 expect.objectContaining({ 333 356 where: { id: "job-1" }, 334 357 data: expect.objectContaining({ 335 358 status: "running", 336 - currentPage: 2, 337 - totalPages: 61, 338 - importedCount: 99, 339 - normalizedCount: 99, 340 - sourceCount: 99, 359 + data: expect.objectContaining({ 360 + currentPage: 2, 361 + totalPages: 61, 362 + importedCount: 99, 363 + normalizedCount: 99, 364 + sourceCount: 99, 365 + }), 341 366 completedAt: null, 342 367 }), 343 368 }), ··· 345 370 }); 346 371 347 372 it("prefers the newest active job over recent terminal jobs", async () => { 348 - prisma.traktImportJob.findFirst = jest.fn().mockResolvedValue( 373 + prisma.backgroundJob.findFirst = jest.fn().mockResolvedValue( 349 374 buildTraktImportJob({ 350 375 status: "running", 351 376 currentPage: 3, ··· 363 388 importedCount: 42, 364 389 }); 365 390 366 - expect(prisma.traktImportJob.findFirst).toHaveBeenCalledTimes(1); 367 - expect(prisma.traktImportJob.findFirst).toHaveBeenCalledWith( 391 + expect(prisma.backgroundJob.findFirst).toHaveBeenCalledTimes(1); 392 + expect(prisma.backgroundJob.findFirst).toHaveBeenCalledWith( 368 393 expect.objectContaining({ 369 394 where: expect.objectContaining({ 370 395 userDid: "did:plc:abc", ··· 376 401 }); 377 402 378 403 it("returns the newest recent terminal job using terminal-aware ordering", async () => { 379 - prisma.traktImportJob.findFirst = jest 404 + prisma.backgroundJob.findFirst = jest 380 405 .fn() 381 406 .mockResolvedValueOnce(null) 382 407 .mockResolvedValueOnce( ··· 396 421 importedCount: 199, 397 422 }); 398 423 399 - expect(prisma.traktImportJob.findFirst).toHaveBeenNthCalledWith( 424 + expect(prisma.backgroundJob.findFirst).toHaveBeenNthCalledWith( 400 425 2, 401 426 expect.objectContaining({ 402 427 where: expect.objectContaining({ ··· 416 441 }); 417 442 418 443 it("keeps completed jobs completed when they include item-level failures", async () => { 419 - prisma.traktImportJob.findFirst = jest 444 + prisma.backgroundJob.findFirst = jest 420 445 .fn() 421 446 .mockResolvedValueOnce(null) 422 447 .mockResolvedValueOnce(
+74 -51
backend/src/users/import-history.service.ts
··· 25 25 TraktPublicProfileDto, 26 26 } from "./dto/import-history.dto"; 27 27 import type { AuthService } from "../auth/auth.service"; 28 + import { 29 + TRAKT_IMPORT_JOB_TYPE, 30 + buildTraktImportData, 31 + parseTraktImportData, 32 + type TraktImportJobData, 33 + } from "./background-job-data"; 28 34 29 35 interface ATSession { 30 36 did: string; ··· 79 85 | "completed" 80 86 | "failed"; 81 87 82 - type TraktImportJobRecord = Awaited< 83 - ReturnType<PrismaService["traktImportJob"]["findFirst"]> 88 + type BackgroundJobRecord = Awaited< 89 + ReturnType<PrismaService["backgroundJob"]["findFirst"]> 84 90 >; 85 91 86 92 const TRAKT_HISTORY_PAGE_SIZE = 100; ··· 208 214 }); 209 215 210 216 if (existingJob) { 211 - const existingProfile = this.buildProfileFromJob(existingJob); 217 + const existingData = parseTraktImportData(existingJob.data); 218 + const existingProfile = this.buildProfileFromJobData(existingData); 212 219 const preview = await this.fetchTraktPreview( 213 - existingJob.traktUsername, 220 + existingData.traktUsername, 214 221 ).catch((error: unknown) => { 215 222 this.logger.warn( 216 223 `Unable to refresh Trakt preview for existing job ${existingJob.id}: ${this.getErrorMessage(error)}`, ··· 231 238 } 232 239 233 240 const preview = await this.fetchTraktPreview(normalizedUsername); 234 - const job = await this.prisma.traktImportJob.create({ 241 + const job = await this.prisma.backgroundJob.create({ 235 242 data: { 243 + type: TRAKT_IMPORT_JOB_TYPE, 236 244 userDid, 237 - traktUsername: normalizedUsername, 238 245 status: "queued", 239 246 nextRunAt: new Date(), 240 - profileUsername: preview.profile.username, 241 - profileSlug: preview.profile.slug, 242 - profileName: preview.profile.name, 243 - profileAvatarUrl: preview.profile.avatarUrl, 247 + data: buildTraktImportData({ 248 + traktUsername: normalizedUsername, 249 + profileUsername: preview.profile.username, 250 + profileSlug: preview.profile.slug, 251 + profileName: preview.profile.name, 252 + profileAvatarUrl: preview.profile.avatarUrl, 253 + }), 244 254 }, 245 255 }); 246 256 ··· 265 275 return this.mapTraktImportJob(activeJob); 266 276 } 267 277 268 - const recentTerminalJob = await this.prisma.traktImportJob.findFirst({ 278 + const recentTerminalJob = await this.prisma.backgroundJob.findFirst({ 269 279 where: { 280 + type: TRAKT_IMPORT_JOB_TYPE, 270 281 userDid, 271 282 status: { in: ["completed", "failed"] }, 272 283 updatedAt: { ··· 284 295 } 285 296 286 297 async processNextTraktImportJob(): Promise<void> { 287 - const job = await this.prisma.traktImportJob.findFirst({ 298 + const job = await this.prisma.backgroundJob.findFirst({ 288 299 where: { 300 + type: TRAKT_IMPORT_JOB_TYPE, 289 301 status: { in: ACTIVE_TRAKT_JOB_STATUSES }, 290 302 nextRunAt: { lte: new Date() }, 291 303 }, ··· 411 423 } 412 424 413 425 private async processTraktImportJob(jobId: string): Promise<void> { 414 - const job = await this.prisma.traktImportJob.findUnique({ 426 + const job = await this.prisma.backgroundJob.findUnique({ 415 427 where: { id: jobId }, 416 428 }); 417 429 if (!job) { ··· 424 436 ) { 425 437 return; 426 438 } 439 + 440 + const jobData = parseTraktImportData(job.data); 427 441 428 442 const session = await this.restoreImportSession(job.userDid); 429 443 if (!session) { ··· 434 448 return; 435 449 } 436 450 437 - await this.prisma.traktImportJob.update({ 451 + await this.prisma.backgroundJob.update({ 438 452 where: { id: job.id }, 439 453 data: { 440 454 status: "running", ··· 445 459 446 460 try { 447 461 const pageResult = await this.fetchTraktHistoryPage( 448 - job.traktUsername, 449 - job.currentPage, 462 + jobData.traktUsername, 463 + jobData.currentPage, 450 464 ); 451 465 const totalPages = 452 - pageResult.pageCount ?? job.totalPages ?? job.currentPage; 466 + pageResult.pageCount ?? jobData.totalPages ?? jobData.currentPage; 453 467 const normalized = this.normalizeTraktPage( 454 468 pageResult.payload, 455 - job.sourceCount + 1, 469 + jobData.sourceCount + 1, 456 470 ); 457 471 const importResult = await this.importNormalizedItems( 458 472 job.userDid, 459 473 session, 460 474 normalized.items, 461 475 ); 462 - const nextPage = job.currentPage + 1; 476 + const nextPage = jobData.currentPage + 1; 463 477 const hasKnownTotalPages = 464 478 Number.isInteger(totalPages) && totalPages >= 1; 465 479 const isComplete = ··· 468 482 ? nextPage > totalPages 469 483 : pageResult.payload.length < TRAKT_HISTORY_PAGE_SIZE); 470 484 471 - await this.prisma.traktImportJob.update({ 485 + const updatedData: TraktImportJobData = { 486 + ...jobData, 487 + currentPage: isComplete ? jobData.currentPage : nextPage, 488 + totalPages, 489 + sourceCount: jobData.sourceCount + pageResult.payload.length, 490 + normalizedCount: jobData.normalizedCount + normalized.items.length, 491 + importedCount: jobData.importedCount + importResult.imported, 492 + skippedCount: 493 + jobData.skippedCount + 494 + normalized.skipped.length + 495 + importResult.skipped, 496 + failedCount: jobData.failedCount + importResult.failed, 497 + }; 498 + 499 + await this.prisma.backgroundJob.update({ 472 500 where: { id: job.id }, 473 501 data: { 474 502 status: isComplete ? "completed" : "running", 475 - currentPage: isComplete ? job.currentPage : nextPage, 476 - totalPages, 477 - sourceCount: job.sourceCount + pageResult.payload.length, 478 - normalizedCount: job.normalizedCount + normalized.items.length, 479 - importedCount: job.importedCount + importResult.imported, 480 - skippedCount: 481 - job.skippedCount + normalized.skipped.length + importResult.skipped, 482 - failedCount: job.failedCount + importResult.failed, 503 + data: updatedData, 483 504 lastError: null, 484 505 nextRunAt: isComplete 485 506 ? new Date() ··· 495 516 this.logger.warn( 496 517 `Trakt rate limit reached for job ${job.id}. Retrying in ${retryAfterSeconds}s.`, 497 518 ); 498 - await this.prisma.traktImportJob.update({ 519 + await this.prisma.backgroundJob.update({ 499 520 where: { id: job.id }, 500 521 data: { 501 522 status: "waiting_retry", ··· 519 540 jobId: string, 520 541 message?: string, 521 542 ): Promise<void> { 522 - await this.prisma.traktImportJob.update({ 543 + await this.prisma.backgroundJob.update({ 523 544 where: { id: jobId }, 524 545 data: { 525 546 status: "failed", ··· 1001 1022 userDid: string, 1002 1023 options: { statuses: TraktJobStatus[]; recentSince?: Date }, 1003 1024 ) { 1004 - return this.prisma.traktImportJob.findFirst({ 1025 + return this.prisma.backgroundJob.findFirst({ 1005 1026 where: { 1027 + type: TRAKT_IMPORT_JOB_TYPE, 1006 1028 userDid, 1007 1029 status: { in: options.statuses }, 1008 1030 ...(options.recentSince ··· 1018 1040 } 1019 1041 1020 1042 private mapTraktImportJob( 1021 - job: NonNullable<TraktImportJobRecord>, 1043 + job: NonNullable<BackgroundJobRecord>, 1022 1044 ): TraktImportJobDto { 1045 + const jobData = parseTraktImportData(job.data); 1023 1046 return { 1024 1047 id: job.id, 1025 - traktUsername: job.traktUsername, 1026 - status: job.status, 1027 - currentPage: job.currentPage, 1028 - totalPages: job.totalPages ?? undefined, 1029 - sourceCount: job.sourceCount, 1030 - normalizedCount: job.normalizedCount, 1031 - importedCount: job.importedCount, 1032 - skippedCount: job.skippedCount, 1033 - failedCount: job.failedCount, 1048 + traktUsername: jobData.traktUsername, 1049 + status: job.status as TraktImportJobDto["status"], 1050 + currentPage: jobData.currentPage, 1051 + totalPages: jobData.totalPages ?? undefined, 1052 + sourceCount: jobData.sourceCount, 1053 + normalizedCount: jobData.normalizedCount, 1054 + importedCount: jobData.importedCount, 1055 + skippedCount: jobData.skippedCount, 1056 + failedCount: jobData.failedCount, 1034 1057 nextRunAt: job.nextRunAt.toISOString(), 1035 1058 lastError: job.lastError ?? undefined, 1036 - profileUsername: job.profileUsername ?? undefined, 1037 - profileSlug: job.profileSlug ?? undefined, 1038 - profileName: job.profileName ?? undefined, 1039 - profileAvatarUrl: job.profileAvatarUrl ?? undefined, 1059 + profileUsername: jobData.profileUsername, 1060 + profileSlug: jobData.profileSlug, 1061 + profileName: jobData.profileName, 1062 + profileAvatarUrl: jobData.profileAvatarUrl, 1040 1063 startedAt: job.startedAt?.toISOString(), 1041 1064 completedAt: job.completedAt?.toISOString(), 1042 1065 createdAt: job.createdAt.toISOString(), ··· 1044 1067 }; 1045 1068 } 1046 1069 1047 - private buildProfileFromJob( 1048 - job: NonNullable<TraktImportJobRecord>, 1070 + private buildProfileFromJobData( 1071 + jobData: TraktImportJobData, 1049 1072 ): TraktPublicProfileDto { 1050 1073 return { 1051 - username: job.profileUsername ?? job.traktUsername, 1052 - slug: job.profileSlug ?? job.traktUsername, 1053 - name: job.profileName ?? undefined, 1074 + username: jobData.profileUsername ?? jobData.traktUsername, 1075 + slug: jobData.profileSlug ?? jobData.traktUsername, 1076 + name: jobData.profileName, 1054 1077 isPrivate: false, 1055 1078 isVip: false, 1056 - avatarUrl: job.profileAvatarUrl ?? undefined, 1079 + avatarUrl: jobData.profileAvatarUrl, 1057 1080 }; 1058 1081 } 1059 1082
+11 -4
backend/src/users/trakt-import-worker.service.ts backend/src/users/background-job-worker.service.ts
··· 5 5 type OnModuleInit, 6 6 } from "@nestjs/common"; 7 7 import { ImportHistoryService } from "./import-history.service"; 8 + import { UserDeletionService } from "./user-deletion.service"; 8 9 9 10 const WORKER_POLL_INTERVAL_MS = 2_000; 10 11 11 12 @Injectable() 12 - export class TraktImportWorkerService implements OnModuleInit, OnModuleDestroy { 13 - private readonly logger = new Logger(TraktImportWorkerService.name); 13 + export class BackgroundJobWorkerService 14 + implements OnModuleInit, OnModuleDestroy 15 + { 16 + private readonly logger = new Logger(BackgroundJobWorkerService.name); 14 17 private timer: NodeJS.Timeout | null = null; 15 18 private isProcessing = false; 16 19 17 - constructor(private readonly importHistoryService: ImportHistoryService) {} 20 + constructor( 21 + private readonly importHistoryService: ImportHistoryService, 22 + private readonly userDeletionService: UserDeletionService, 23 + ) {} 18 24 19 25 onModuleInit() { 20 26 this.timer = setInterval(() => { ··· 37 43 this.isProcessing = true; 38 44 try { 39 45 await this.importHistoryService.processNextTraktImportJob(); 46 + await this.userDeletionService.processNextDeletionJob(); 40 47 } catch (error) { 41 48 this.logger.error( 42 - `Trakt import worker tick failed: ${error instanceof Error ? error.message : String(error)}`, 49 + `Background job worker tick failed: ${error instanceof Error ? error.message : String(error)}`, 43 50 ); 44 51 } finally { 45 52 this.isProcessing = false;
+74 -185
backend/src/users/user-deletion.service.spec.ts
··· 1 - import { BadGatewayException, NotFoundException } from "@nestjs/common"; 1 + import { ConflictException, NotFoundException } from "@nestjs/common"; 2 2 3 - const mockListRecords = jest.fn(); 4 3 const mockDeleteRecord = jest.fn(); 4 + const mockListRecords = jest.fn(); 5 5 6 6 jest.mock("@atproto/api", () => ({ 7 7 Agent: jest.fn().mockImplementation(() => ({ ··· 17 17 })); 18 18 19 19 import { PrismaService } from "../prisma/prisma.service"; 20 + import type { AuthService } from "../auth/auth.service"; 20 21 import { UserDeletionService } from "./user-deletion.service"; 21 22 22 23 describe("UserDeletionService", () => { ··· 29 30 }, 30 31 trackedMovie: { 31 32 findMany: jest.fn(), 33 + count: jest.fn(), 32 34 }, 33 35 trackedEpisode: { 34 36 findMany: jest.fn(), 37 + count: jest.fn(), 35 38 }, 36 39 follow: { 37 40 findMany: jest.fn(), 41 + count: jest.fn(), 38 42 }, 39 - listItem: { 40 - findMany: jest.fn(), 41 - }, 42 - list: { 43 - findMany: jest.fn(), 43 + backgroundJob: { 44 + findFirst: jest.fn(), 45 + findUnique: jest.fn(), 46 + create: jest.fn(), 47 + update: jest.fn(), 44 48 }, 45 49 } as unknown as PrismaService; 46 50 51 + const authService = { 52 + restore: jest.fn(), 53 + } as unknown as AuthService; 54 + 47 55 beforeEach(() => { 48 56 jest.clearAllMocks(); 49 57 ··· 52 60 .mockResolvedValue({ did: "did:plc:test" }); 53 61 prisma.user.delete = jest.fn().mockResolvedValue(undefined); 54 62 prisma.trackedMovie.findMany = jest.fn().mockResolvedValue([]); 63 + prisma.trackedMovie.count = jest.fn().mockResolvedValue(0); 55 64 prisma.trackedEpisode.findMany = jest.fn().mockResolvedValue([]); 65 + prisma.trackedEpisode.count = jest.fn().mockResolvedValue(0); 56 66 prisma.follow.findMany = jest.fn().mockResolvedValue([]); 57 - prisma.listItem.findMany = jest.fn().mockResolvedValue([]); 58 - prisma.list.findMany = jest.fn().mockResolvedValue([]); 67 + prisma.follow.count = jest.fn().mockResolvedValue(0); 68 + prisma.backgroundJob.findFirst = jest.fn().mockResolvedValue(null); 69 + prisma.backgroundJob.create = jest.fn().mockResolvedValue({ 70 + id: "job-1", 71 + type: "account_deletion", 72 + userDid: "did:plc:test", 73 + status: "queued", 74 + data: { deletePdsData: true, totalRecords: 1, deletedRecords: 0 }, 75 + createdAt: new Date(), 76 + }); 59 77 60 - service = new UserDeletionService(prisma); 78 + mockListRecords.mockResolvedValue({ data: { records: [] } }); 79 + mockDeleteRecord.mockResolvedValue(undefined); 80 + 81 + service = new UserDeletionService(prisma, authService); 61 82 }); 62 83 63 - it("deletes all repo list items and lists, including favorites missing from Prisma", async () => { 64 - mockListRecords 65 - .mockResolvedValueOnce({ 66 - data: { 67 - records: [ 68 - { 69 - uri: "at://did:plc:test/xyz.opnshelf.listItem/list-item-1", 70 - cid: "cid-1", 71 - value: {}, 72 - }, 73 - { 74 - uri: "at://did:plc:test/xyz.opnshelf.listItem/list-item-2", 75 - cid: "cid-2", 76 - value: {}, 77 - }, 78 - ], 79 - cursor: "cursor-2", 80 - }, 81 - }) 82 - .mockResolvedValueOnce({ 83 - data: { 84 - records: [ 85 - { 86 - uri: "at://did:plc:test/xyz.opnshelf.listItem/list-item-3", 87 - cid: "cid-3", 88 - value: {}, 89 - }, 90 - ], 91 - }, 92 - }) 93 - .mockResolvedValueOnce({ 94 - data: { 95 - records: [ 96 - { 97 - uri: "at://did:plc:test/xyz.opnshelf.list/favorites", 98 - cid: "cid-4", 99 - value: {}, 100 - }, 101 - { 102 - uri: "at://did:plc:test/xyz.opnshelf.list/custom-list", 103 - cid: "cid-5", 104 - value: {}, 105 - }, 106 - ], 107 - }, 84 + describe("deleteUserSync", () => { 85 + it("deletes a user without PDS cleanup", async () => { 86 + await service.deleteUserSync("did:plc:test"); 87 + 88 + expect(prisma.user.delete).toHaveBeenCalledWith({ 89 + where: { did: "did:plc:test" }, 108 90 }); 91 + }); 109 92 110 - await service.deleteUser("did:plc:test", { did: "did:plc:test" }, true); 93 + it("throws when user not found", async () => { 94 + prisma.user.findUnique = jest.fn().mockResolvedValue(null); 111 95 112 - expect(mockListRecords).toHaveBeenNthCalledWith(1, { 113 - repo: "did:plc:test", 114 - collection: "xyz.opnshelf.listItem", 115 - limit: 100, 116 - cursor: undefined, 117 - }); 118 - expect(mockListRecords).toHaveBeenNthCalledWith(2, { 119 - repo: "did:plc:test", 120 - collection: "xyz.opnshelf.listItem", 121 - limit: 100, 122 - cursor: "cursor-2", 123 - }); 124 - expect(mockListRecords).toHaveBeenNthCalledWith(3, { 125 - repo: "did:plc:test", 126 - collection: "xyz.opnshelf.list", 127 - limit: 100, 128 - cursor: undefined, 129 - }); 130 - expect(mockDeleteRecord.mock.calls).toEqual([ 131 - [ 132 - { 133 - repo: "did:plc:test", 134 - collection: "xyz.opnshelf.listItem", 135 - rkey: "list-item-1", 136 - }, 137 - ], 138 - [ 139 - { 140 - repo: "did:plc:test", 141 - collection: "xyz.opnshelf.listItem", 142 - rkey: "list-item-2", 143 - }, 144 - ], 145 - [ 146 - { 147 - repo: "did:plc:test", 148 - collection: "xyz.opnshelf.listItem", 149 - rkey: "list-item-3", 150 - }, 151 - ], 152 - [ 153 - { 154 - repo: "did:plc:test", 155 - collection: "xyz.opnshelf.list", 156 - rkey: "favorites", 157 - }, 158 - ], 159 - [ 160 - { 161 - repo: "did:plc:test", 162 - collection: "xyz.opnshelf.list", 163 - rkey: "custom-list", 164 - }, 165 - ], 166 - [ 167 - { 168 - repo: "did:plc:test", 169 - collection: "xyz.opnshelf.profile", 170 - rkey: "self", 171 - }, 172 - ], 173 - ]); 174 - expect(prisma.listItem.findMany).not.toHaveBeenCalled(); 175 - expect(prisma.list.findMany).not.toHaveBeenCalled(); 176 - expect(prisma.user.delete).toHaveBeenCalledWith({ 177 - where: { did: "did:plc:test" }, 96 + await expect(service.deleteUserSync("did:plc:missing")).rejects.toThrow( 97 + NotFoundException, 98 + ); 178 99 }); 179 100 }); 180 101 181 - it("aborts account deletion when listing repo records fails", async () => { 182 - mockListRecords.mockRejectedValueOnce(new Error("PDS unavailable")); 102 + describe("createDeletionJob", () => { 103 + it("creates a deletion job with record counts", async () => { 104 + prisma.trackedMovie.count = jest.fn().mockResolvedValue(5); 105 + prisma.trackedEpisode.count = jest.fn().mockResolvedValue(10); 106 + prisma.follow.count = jest.fn().mockResolvedValue(3); 183 107 184 - await expect( 185 - service.deleteUser("did:plc:test", { did: "did:plc:test" }, true), 186 - ).rejects.toThrow(BadGatewayException); 187 - expect(prisma.user.delete).not.toHaveBeenCalled(); 188 - }); 108 + await service.createDeletionJob("did:plc:test", true); 189 109 190 - it("aborts account deletion when deleting a repo list record fails", async () => { 191 - mockListRecords 192 - .mockResolvedValueOnce({ 193 - data: { records: [] }, 194 - }) 195 - .mockResolvedValueOnce({ 196 - data: { 197 - records: [ 198 - { 199 - uri: "at://did:plc:test/xyz.opnshelf.list/favorites", 200 - cid: "cid-1", 201 - value: {}, 202 - }, 203 - ], 204 - }, 110 + expect(prisma.backgroundJob.create).toHaveBeenCalledWith({ 111 + data: expect.objectContaining({ 112 + type: "account_deletion", 113 + userDid: "did:plc:test", 114 + status: "queued", 115 + data: expect.objectContaining({ 116 + deletePdsData: true, 117 + totalRecords: 19, 118 + deletedRecords: 0, 119 + }), 120 + }), 205 121 }); 206 - mockDeleteRecord.mockRejectedValueOnce({ 207 - status: 500, 208 - error: "InternalError", 209 122 }); 210 123 211 - await expect( 212 - service.deleteUser("did:plc:test", { did: "did:plc:test" }, true), 213 - ).rejects.toThrow(BadGatewayException); 214 - expect(prisma.user.delete).not.toHaveBeenCalled(); 215 - }); 216 - 217 - it("treats already-missing repo records as deleted", async () => { 218 - mockListRecords 219 - .mockResolvedValueOnce({ 220 - data: { records: [] }, 221 - }) 222 - .mockResolvedValueOnce({ 223 - data: { 224 - records: [ 225 - { 226 - uri: "at://did:plc:test/xyz.opnshelf.list/favorites", 227 - cid: "cid-1", 228 - value: {}, 229 - }, 230 - ], 231 - }, 232 - }); 233 - mockDeleteRecord.mockRejectedValueOnce({ 234 - status: 404, 235 - error: "RecordNotFound", 236 - message: "RecordNotFound", 237 - }); 124 + it("throws when user not found", async () => { 125 + prisma.user.findUnique = jest.fn().mockResolvedValue(null); 238 126 239 - await expect( 240 - service.deleteUser("did:plc:test", { did: "did:plc:test" }, true), 241 - ).resolves.toBeUndefined(); 242 - expect(prisma.user.delete).toHaveBeenCalledWith({ 243 - where: { did: "did:plc:test" }, 127 + await expect( 128 + service.createDeletionJob("did:plc:missing", true), 129 + ).rejects.toThrow(NotFoundException); 244 130 }); 245 - }); 246 131 247 - it("throws when deleting a missing user", async () => { 248 - prisma.user.findUnique = jest.fn().mockResolvedValue(null); 132 + it("rejects when a deletion is already in progress", async () => { 133 + prisma.backgroundJob.findFirst = jest.fn().mockResolvedValue({ 134 + id: "existing-job", 135 + status: "running", 136 + }); 249 137 250 - await expect( 251 - service.deleteUser("did:plc:missing", { did: "did:plc:missing" }, false), 252 - ).rejects.toThrow(NotFoundException); 138 + await expect( 139 + service.createDeletionJob("did:plc:test", true), 140 + ).rejects.toThrow(ConflictException); 141 + }); 253 142 }); 254 143 });
+227 -75
backend/src/users/user-deletion.service.ts
··· 1 1 import { Agent } from "@atproto/api"; 2 2 import { 3 - BadGatewayException, 3 + ConflictException, 4 + Inject, 4 5 Injectable, 5 6 Logger, 6 7 NotFoundException, ··· 12 13 import { $nsid as MOVIE_COLLECTION } from "../lexicons/xyz/opnshelf/movie"; 13 14 import { $nsid as PROFILE_COLLECTION } from "../lexicons/xyz/opnshelf/profile.defs"; 14 15 import { PrismaService } from "../prisma/prisma.service"; 16 + import { AUTH_SERVICE } from "../auth/auth.tokens"; 17 + import type { AuthService } from "../auth/auth.service"; 18 + import { 19 + ACCOUNT_DELETION_JOB_TYPE, 20 + buildAccountDeletionData, 21 + parseAccountDeletionData, 22 + type AccountDeletionJobData, 23 + } from "./background-job-data"; 15 24 16 25 interface ATSession { 17 26 did: string; 18 27 } 19 28 20 - const PDS_DELETION_FAILURE_MESSAGE = 21 - "Failed to delete OpnShelf data from your PDS. Your account was not deleted."; 22 29 const RECORDS_PAGE_SIZE = 100; 30 + const ACTIVE_DELETION_STATUSES = ["queued", "running"]; 23 31 24 32 @Injectable() 25 33 export class UserDeletionService { 26 34 private readonly logger = new Logger(UserDeletionService.name); 27 35 28 - constructor(private readonly prisma: PrismaService) {} 36 + constructor( 37 + private readonly prisma: PrismaService, 38 + @Inject(AUTH_SERVICE) 39 + private readonly authService: Pick<AuthService, "restore">, 40 + ) {} 29 41 30 - async deleteUser( 31 - did: string, 32 - session: ATSession, 33 - deletePDSData: boolean, 34 - ): Promise<void> { 42 + async deleteUserSync(did: string): Promise<void> { 35 43 const user = await this.prisma.user.findUnique({ 36 44 where: { did }, 37 45 }); ··· 40 48 throw new NotFoundException("User not found"); 41 49 } 42 50 43 - if (deletePDSData) { 44 - await this.deletePdsRecords(did, session); 51 + await this.prisma.user.delete({ 52 + where: { did }, 53 + }); 54 + } 55 + 56 + async createDeletionJob(did: string, deletePdsData: boolean) { 57 + const user = await this.prisma.user.findUnique({ 58 + where: { did }, 59 + }); 60 + 61 + if (!user) { 62 + throw new NotFoundException("User not found"); 45 63 } 46 64 47 - await this.prisma.user.delete({ 48 - where: { did }, 65 + const existingJob = await this.prisma.backgroundJob.findFirst({ 66 + where: { 67 + type: ACCOUNT_DELETION_JOB_TYPE, 68 + userDid: did, 69 + status: { in: ACTIVE_DELETION_STATUSES }, 70 + }, 71 + }); 72 + 73 + if (existingJob) { 74 + throw new ConflictException("An account deletion is already in progress"); 75 + } 76 + 77 + const [movieCount, episodeCount, followCount] = await Promise.all([ 78 + this.prisma.trackedMovie.count({ where: { userDid: did } }), 79 + this.prisma.trackedEpisode.count({ where: { userDid: did } }), 80 + this.prisma.follow.count({ 81 + where: { followerDid: did, rkey: { not: null } }, 82 + }), 83 + ]); 84 + 85 + // +1 for profile record, list items and lists are counted dynamically 86 + const totalRecords = movieCount + episodeCount + followCount + 1; 87 + 88 + return this.prisma.backgroundJob.create({ 89 + data: { 90 + type: ACCOUNT_DELETION_JOB_TYPE, 91 + userDid: did, 92 + status: "queued", 93 + data: buildAccountDeletionData({ 94 + deletePdsData, 95 + totalRecords, 96 + }), 97 + }, 98 + }); 99 + } 100 + 101 + async getCurrentDeletionJob(userDid: string) { 102 + return this.prisma.backgroundJob.findFirst({ 103 + where: { 104 + type: ACCOUNT_DELETION_JOB_TYPE, 105 + userDid, 106 + }, 107 + orderBy: [{ createdAt: "desc" }], 49 108 }); 50 109 } 51 110 52 - private async deletePdsRecords(did: string, session: ATSession) { 111 + async processNextDeletionJob(): Promise<void> { 112 + const job = await this.prisma.backgroundJob.findFirst({ 113 + where: { 114 + type: ACCOUNT_DELETION_JOB_TYPE, 115 + status: { in: ACTIVE_DELETION_STATUSES }, 116 + nextRunAt: { lte: new Date() }, 117 + }, 118 + orderBy: [{ nextRunAt: "asc" }, { createdAt: "asc" }], 119 + }); 120 + 121 + if (!job) { 122 + return; 123 + } 124 + 125 + await this.processDeletionJob(job.id); 126 + } 127 + 128 + private async processDeletionJob(jobId: string): Promise<void> { 129 + const job = await this.prisma.backgroundJob.findUnique({ 130 + where: { id: jobId }, 131 + }); 132 + if (!job || job.status === "completed" || job.status === "failed") { 133 + return; 134 + } 135 + 136 + const jobData = parseAccountDeletionData(job.data); 137 + 138 + await this.prisma.backgroundJob.update({ 139 + where: { id: job.id }, 140 + data: { 141 + status: "running", 142 + startedAt: job.startedAt ?? new Date(), 143 + lastError: null, 144 + }, 145 + }); 146 + 147 + try { 148 + if (jobData.deletePdsData) { 149 + await this.deletePdsRecordsWithProgress(job.id, job.userDid, jobData); 150 + } 151 + 152 + await this.updateJobData(job.id, jobData, { currentStep: "db_cleanup" }); 153 + 154 + await this.prisma.user.delete({ where: { did: job.userDid } }); 155 + 156 + await this.prisma.backgroundJob.update({ 157 + where: { id: job.id }, 158 + data: { 159 + status: "completed", 160 + completedAt: new Date(), 161 + data: { ...jobData, currentStep: "completed" }, 162 + }, 163 + }); 164 + } catch (error) { 165 + const message = error instanceof Error ? error.message : String(error); 166 + this.logger.error( 167 + `Account deletion job ${job.id} failed: ${message}`, 168 + error instanceof Error ? error.stack : undefined, 169 + ); 170 + await this.prisma.backgroundJob.update({ 171 + where: { id: job.id }, 172 + data: { 173 + status: "failed", 174 + lastError: message, 175 + completedAt: new Date(), 176 + }, 177 + }); 178 + } 179 + } 180 + 181 + private async deletePdsRecordsWithProgress( 182 + jobId: string, 183 + userDid: string, 184 + jobData: AccountDeletionJobData, 185 + ): Promise<void> { 186 + const session = await this.restoreSession(userDid); 187 + if (!session) { 188 + throw new Error( 189 + "Your sign-in session expired. Could not delete PDS data.", 190 + ); 191 + } 192 + 53 193 const agent = new Agent( 54 194 session as unknown as ConstructorParameters<typeof Agent>[0], 55 195 ); 56 196 197 + await this.updateJobData(jobId, jobData, { currentStep: "movies" }); 57 198 const trackedMovies = await this.prisma.trackedMovie.findMany({ 58 - where: { userDid: did }, 199 + where: { userDid }, 59 200 }); 60 - 61 201 for (const tracked of trackedMovies) { 62 202 await this.tryDeleteRecord( 63 203 agent, 64 204 session.did, 65 205 MOVIE_COLLECTION, 66 206 tracked.rkey, 67 - `Failed to delete record ${tracked.rkey} from PDS`, 207 + `Failed to delete movie record ${tracked.rkey} from PDS`, 68 208 ); 209 + jobData.deletedRecords++; 210 + await this.updateJobData(jobId, jobData); 69 211 } 70 212 213 + await this.updateJobData(jobId, jobData, { currentStep: "episodes" }); 71 214 const trackedEpisodes = await this.prisma.trackedEpisode.findMany({ 72 - where: { userDid: did }, 215 + where: { userDid }, 73 216 }); 74 - 75 217 for (const tracked of trackedEpisodes) { 76 218 await this.tryDeleteRecord( 77 219 agent, ··· 80 222 tracked.rkey, 81 223 `Failed to delete episode record ${tracked.rkey} from PDS`, 82 224 ); 225 + jobData.deletedRecords++; 226 + await this.updateJobData(jobId, jobData); 83 227 } 84 228 229 + await this.updateJobData(jobId, jobData, { currentStep: "follows" }); 85 230 const follows = await this.prisma.follow.findMany({ 86 - where: { followerDid: did, rkey: { not: null } }, 231 + where: { followerDid: userDid, rkey: { not: null } }, 87 232 select: { rkey: true }, 88 233 }); 89 - 90 234 for (const follow of follows) { 91 235 if (!follow.rkey) { 92 236 continue; 93 237 } 94 - 95 238 await this.tryDeleteRecord( 96 239 agent, 97 240 session.did, ··· 99 242 follow.rkey, 100 243 `Failed to delete follow ${follow.rkey} from PDS`, 101 244 ); 245 + jobData.deletedRecords++; 246 + await this.updateJobData(jobId, jobData); 102 247 } 103 248 104 - await this.deleteRepoCollectionRecords( 249 + await this.updateJobData(jobId, jobData, { currentStep: "list_items" }); 250 + const listItemRkeys = await this.listRepoRecordKeys( 105 251 agent, 106 252 session.did, 107 253 LIST_ITEM_COLLECTION, 108 - did, 109 254 ); 110 - await this.deleteRepoCollectionRecords( 255 + jobData.totalRecords += listItemRkeys.length; 256 + await this.updateJobData(jobId, jobData); 257 + for (const rkey of listItemRkeys) { 258 + await this.tryDeleteRecord( 259 + agent, 260 + session.did, 261 + LIST_ITEM_COLLECTION, 262 + rkey, 263 + `Failed to delete list item ${rkey} from PDS`, 264 + ); 265 + jobData.deletedRecords++; 266 + await this.updateJobData(jobId, jobData); 267 + } 268 + 269 + await this.updateJobData(jobId, jobData, { currentStep: "lists" }); 270 + const listRkeys = await this.listRepoRecordKeys( 111 271 agent, 112 272 session.did, 113 273 LIST_COLLECTION, 114 - did, 115 274 ); 275 + jobData.totalRecords += listRkeys.length; 276 + await this.updateJobData(jobId, jobData); 277 + for (const rkey of listRkeys) { 278 + await this.tryDeleteRecord( 279 + agent, 280 + session.did, 281 + LIST_COLLECTION, 282 + rkey, 283 + `Failed to delete list ${rkey} from PDS`, 284 + ); 285 + jobData.deletedRecords++; 286 + await this.updateJobData(jobId, jobData); 287 + } 288 + 289 + await this.updateJobData(jobId, jobData, { currentStep: "profile" }); 116 290 await this.tryDeleteRecord( 117 291 agent, 118 292 session.did, ··· 120 294 "self", 121 295 "Failed to delete profile record from PDS", 122 296 ); 297 + jobData.deletedRecords++; 298 + await this.updateJobData(jobId, jobData); 299 + } 300 + 301 + private async updateJobData( 302 + jobId: string, 303 + jobData: AccountDeletionJobData, 304 + overrides?: Partial<AccountDeletionJobData>, 305 + ): Promise<void> { 306 + if (overrides) { 307 + Object.assign(jobData, overrides); 308 + } 309 + await this.prisma.backgroundJob.update({ 310 + where: { id: jobId }, 311 + data: { data: { ...jobData } }, 312 + }); 123 313 } 124 314 125 315 private async tryDeleteRecord( ··· 136 326 rkey, 137 327 }); 138 328 } catch (error) { 329 + if (this.isRecordMissingError(error)) { 330 + return; 331 + } 139 332 this.logger.warn(`${warnPrefix}: ${error}`); 140 333 } 141 334 } 142 335 143 - private async deleteRepoCollectionRecords( 144 - agent: Agent, 145 - repoDid: string, 146 - collection: string, 147 - userDid: string, 148 - ): Promise<void> { 149 - const rkeys = await this.listRepoRecordKeys( 150 - agent, 151 - repoDid, 152 - collection, 153 - userDid, 154 - ); 155 - 156 - for (const rkey of rkeys) { 157 - await this.deleteRepoRecordOrThrow( 158 - agent, 159 - repoDid, 160 - collection, 161 - rkey, 162 - userDid, 163 - ); 164 - } 165 - } 166 - 167 336 private async listRepoRecordKeys( 168 337 agent: Agent, 169 338 repoDid: string, 170 339 collection: string, 171 - userDid: string, 172 340 ): Promise<string[]> { 173 341 const rkeys: string[] = []; 174 342 let cursor: string | undefined; ··· 189 357 cursor = response.data.cursor; 190 358 } while (cursor); 191 359 } catch (error) { 192 - this.logger.error( 193 - `Failed to list ${collection} records from PDS for user ${userDid}`, 194 - error, 360 + this.logger.warn( 361 + `Failed to list ${collection} records from PDS for user ${repoDid}: ${error}`, 195 362 ); 196 - throw new BadGatewayException(PDS_DELETION_FAILURE_MESSAGE); 197 363 } 198 364 199 365 return rkeys; ··· 213 379 return uri.slice(prefix.length); 214 380 } 215 381 216 - private async deleteRepoRecordOrThrow( 217 - agent: Agent, 218 - repoDid: string, 219 - collection: string, 220 - rkey: string, 221 - userDid: string, 222 - ): Promise<void> { 382 + private async restoreSession(userDid: string): Promise<ATSession | null> { 223 383 try { 224 - await agent.com.atproto.repo.deleteRecord({ 225 - repo: repoDid, 226 - collection, 227 - rkey, 228 - }); 384 + const session = await this.authService.restore(userDid); 385 + return session ? (session as unknown as ATSession) : null; 229 386 } catch (error) { 230 - if (this.isRecordMissingError(error)) { 231 - return; 232 - } 233 - 234 - this.logger.error( 235 - `Failed to delete ${collection} record ${rkey} from PDS for user ${userDid}`, 236 - error, 387 + this.logger.warn( 388 + `Failed to restore auth session for ${userDid}: ${error instanceof Error ? error.message : String(error)}`, 237 389 ); 238 - throw new BadGatewayException(PDS_DELETION_FAILURE_MESSAGE); 390 + return null; 239 391 } 240 392 } 241 393
+44 -20
backend/src/users/users.controller.spec.ts
··· 1 - import { BadGatewayException, BadRequestException } from "@nestjs/common"; 1 + import { BadRequestException } from "@nestjs/common"; 2 2 import { Test, type TestingModule } from "@nestjs/testing"; 3 3 import type { AuthenticatedRequest } from "../auth/types"; 4 4 ··· 38 38 uploadUserAvatar: jest.fn(), 39 39 deleteUserAvatar: jest.fn(), 40 40 streamUserAvatar: jest.fn(), 41 - deleteUser: jest.fn(), 41 + deleteUserSync: jest.fn(), 42 + createDeletionJob: jest.fn(), 43 + getCurrentDeletionJob: jest.fn(), 42 44 }; 43 45 44 46 beforeEach(async () => { ··· 353 355 ).resolves.toMatchObject({ imported: 1, skipped: 0, failed: 0 }); 354 356 }); 355 357 356 - it("deletes the current account and forwards the PDS deletion flag", async () => { 357 - usersService.deleteUser.mockResolvedValue(undefined); 358 + it("deletes the current account synchronously when PDS deletion is not requested", async () => { 359 + usersService.deleteUserSync.mockResolvedValue(undefined); 358 360 359 361 const req = { 360 362 user: { did: "did:plc:abc", session: { did: "did:plc:abc" } }, 361 363 } as AuthenticatedRequest; 364 + const res = { status: jest.fn() } as unknown as import("express").Response; 362 365 363 - await expect( 364 - controller.deleteMyAccount({ deletePDSData: true }, req), 365 - ).resolves.toBeUndefined(); 366 - expect(usersService.deleteUser).toHaveBeenCalledWith( 367 - "did:plc:abc", 368 - { did: "did:plc:abc" }, 369 - true, 366 + const result = await controller.deleteMyAccount( 367 + { deletePDSData: false }, 368 + req, 369 + res, 370 370 ); 371 + expect(result).toBeUndefined(); 372 + expect(usersService.deleteUserSync).toHaveBeenCalledWith("did:plc:abc"); 373 + expect(res.status).toHaveBeenCalledWith(204); 371 374 }); 372 375 373 - it("propagates delete-account PDS cleanup failures", async () => { 374 - usersService.deleteUser.mockRejectedValue( 375 - new BadGatewayException( 376 - "Failed to delete OpnShelf data from your PDS. Your account was not deleted.", 377 - ), 378 - ); 376 + it("creates an async deletion job when PDS deletion is requested", async () => { 377 + const mockJob = { 378 + id: "job-1", 379 + status: "queued", 380 + data: { 381 + deletePdsData: true, 382 + totalRecords: 10, 383 + deletedRecords: 0, 384 + }, 385 + lastError: null, 386 + createdAt: new Date("2026-03-27T12:00:00.000Z"), 387 + }; 388 + usersService.createDeletionJob.mockResolvedValue(mockJob); 379 389 380 390 const req = { 381 391 user: { did: "did:plc:abc", session: { did: "did:plc:abc" } }, 382 392 } as AuthenticatedRequest; 393 + const res = { status: jest.fn() } as unknown as import("express").Response; 383 394 384 - await expect( 385 - controller.deleteMyAccount({ deletePDSData: true }, req), 386 - ).rejects.toThrow(BadGatewayException); 395 + const result = await controller.deleteMyAccount( 396 + { deletePDSData: true }, 397 + req, 398 + res, 399 + ); 400 + expect(result).toMatchObject({ 401 + id: "job-1", 402 + status: "queued", 403 + totalRecords: 10, 404 + deletedRecords: 0, 405 + }); 406 + expect(usersService.createDeletionJob).toHaveBeenCalledWith( 407 + "did:plc:abc", 408 + true, 409 + ); 410 + expect(res.status).toHaveBeenCalledWith(200); 387 411 }); 388 412 389 413 it("rejects import when session is missing", async () => {
+73 -17
backend/src/users/users.controller.ts
··· 4 4 Controller, 5 5 Delete, 6 6 Get, 7 + HttpCode, 8 + HttpStatus, 7 9 Query, 8 10 Param, 9 11 Patch, ··· 38 40 TraktImportJobDto, 39 41 } from "./dto/import-history.dto"; 40 42 import { 43 + AccountDeletionJobDto, 41 44 DeleteUserAccountDto, 42 45 PublicUserProfileDto, 43 46 UpdateUserProfileDto, ··· 45 48 UserProfileDto, 46 49 UserSettingsDto, 47 50 } from "./dto/user-settings.dto"; 51 + import { parseAccountDeletionData } from "./background-job-data"; 48 52 import { UsersService } from "./users.service"; 49 53 import type { ATSession } from "../movies/movies.service"; 50 54 ··· 206 210 return this.usersService.deleteUserAvatar(did, session); 207 211 } 208 212 209 - /** 210 - * Delete current user's account 211 - */ 212 213 @Delete("me/account") 213 214 @UseGuards(AuthGuard) 215 + @HttpCode(HttpStatus.OK) 214 216 @ApiOperation({ summary: "Delete current user's account" }) 215 - @ApiResponse({ status: 204, description: "Account deleted successfully" }) 217 + @ApiResponse({ 218 + status: 200, 219 + type: AccountDeletionJobDto, 220 + description: "PDS deletion requested; returns a job to poll for progress", 221 + }) 222 + @ApiResponse({ 223 + status: 204, 224 + description: "Account deleted immediately (no PDS deletion)", 225 + }) 216 226 @ApiResponse({ status: 401, description: "Not authenticated" }) 217 227 @ApiResponse({ 218 - status: 502, 219 - description: 220 - "Failed to delete OpnShelf data from the user's PDS, so the account was not deleted", 228 + status: 409, 229 + description: "Account deletion already in progress", 221 230 }) 222 231 async deleteMyAccount( 223 232 @Body() dto: DeleteUserAccountDto, 224 233 @Req() req: AuthenticatedRequest, 225 - ): Promise<void> { 234 + @Res({ passthrough: true }) res: Response, 235 + ): Promise<AccountDeletionJobDto | undefined> { 226 236 const did = req.user?.did; 227 237 if (!did) { 228 - throw new Error("User not found in request"); 238 + throw new BadRequestException("User not found in request"); 229 239 } 230 240 231 - const session = req.user?.session as ATSession | undefined; 232 - if (!session || !session.did) { 233 - throw new Error("Session not found in request"); 241 + const deletePDSData = dto.deletePDSData ?? false; 242 + 243 + if (!deletePDSData) { 244 + await this.usersService.deleteUserSync(did); 245 + res.status(HttpStatus.NO_CONTENT); 246 + return; 234 247 } 235 248 236 - await this.usersService.deleteUser( 237 - did, 238 - session, 239 - dto.deletePDSData ?? false, 240 - ); 249 + const job = await this.usersService.createDeletionJob(did, true); 250 + const jobData = parseAccountDeletionData(job.data); 251 + 252 + res.status(HttpStatus.OK); 253 + return { 254 + id: job.id, 255 + status: job.status, 256 + totalRecords: jobData.totalRecords, 257 + deletedRecords: jobData.deletedRecords, 258 + currentStep: jobData.currentStep, 259 + lastError: job.lastError ?? undefined, 260 + createdAt: job.createdAt.toISOString(), 261 + }; 262 + } 263 + 264 + @Get("me/account-deletion") 265 + @UseGuards(AuthGuard) 266 + @ApiOperation({ summary: "Get current account deletion job status" }) 267 + @ApiResponse({ 268 + status: 200, 269 + type: AccountDeletionJobDto, 270 + description: 271 + "Current or most recent account deletion job, or null when none exists", 272 + }) 273 + @ApiResponse({ status: 401, description: "Not authenticated" }) 274 + async getMyAccountDeletion( 275 + @Req() req: AuthenticatedRequest, 276 + ): Promise<AccountDeletionJobDto | null> { 277 + const did = req.user?.did; 278 + if (!did) { 279 + throw new BadRequestException("User not found in request"); 280 + } 281 + 282 + const job = await this.usersService.getCurrentDeletionJob(did); 283 + if (!job) { 284 + return null; 285 + } 286 + 287 + const jobData = parseAccountDeletionData(job.data); 288 + return { 289 + id: job.id, 290 + status: job.status, 291 + totalRecords: jobData.totalRecords, 292 + deletedRecords: jobData.deletedRecords, 293 + currentStep: jobData.currentStep, 294 + lastError: job.lastError ?? undefined, 295 + createdAt: job.createdAt.toISOString(), 296 + }; 241 297 } 242 298 243 299 @Post("me/onboarding/complete")
+2 -2
backend/src/users/users.module.ts
··· 5 5 import { MoviesModule } from "../movies/movies.module"; 6 6 import { PrismaModule } from "../prisma/prisma.module"; 7 7 import { ShowsModule } from "../shows/shows.module"; 8 + import { BackgroundJobWorkerService } from "./background-job-worker.service"; 8 9 import { ImportHistoryService } from "./import-history.service"; 9 10 import { ProfileService } from "./profile.service"; 10 - import { TraktImportWorkerService } from "./trakt-import-worker.service"; 11 11 import { UserDeletionService } from "./user-deletion.service"; 12 12 import { UsersController } from "./users.controller"; 13 13 import { UsersService } from "./users.service"; ··· 25 25 providers: [ 26 26 UsersService, 27 27 ImportHistoryService, 28 - TraktImportWorkerService, 28 + BackgroundJobWorkerService, 29 29 UserDeletionService, 30 30 ProfileService, 31 31 ],
+19 -14
backend/src/users/users.service.spec.ts
··· 87 87 } as unknown as ConfigService; 88 88 89 89 const userDeletionService = { 90 - deleteUser: jest.fn(), 90 + deleteUserSync: jest.fn(), 91 + createDeletionJob: jest.fn(), 92 + getCurrentDeletionJob: jest.fn(), 91 93 } as unknown as UserDeletionService; 92 94 93 95 const profileService = { ··· 385 387 }); 386 388 }); 387 389 388 - it("delegates account deletion with the PDS deletion flag", async () => { 389 - (userDeletionService.deleteUser as jest.Mock).mockResolvedValue(undefined); 390 + it("delegates synchronous account deletion", async () => { 391 + (userDeletionService.deleteUserSync as jest.Mock).mockResolvedValue( 392 + undefined, 393 + ); 390 394 391 395 await expect( 392 - service.deleteUser("did:plc:123", { did: "did:plc:123" }, true), 396 + service.deleteUserSync("did:plc:123"), 393 397 ).resolves.toBeUndefined(); 394 - expect(userDeletionService.deleteUser).toHaveBeenCalledWith( 398 + expect(userDeletionService.deleteUserSync).toHaveBeenCalledWith( 395 399 "did:plc:123", 396 - { did: "did:plc:123" }, 397 - true, 398 400 ); 399 401 }); 400 402 401 - it("propagates account deletion failures from PDS cleanup", async () => { 402 - (userDeletionService.deleteUser as jest.Mock).mockRejectedValue( 403 - new BadGatewayException( 404 - "Failed to delete OpnShelf data from your PDS. Your account was not deleted.", 405 - ), 403 + it("delegates async deletion job creation", async () => { 404 + const mockJob = { id: "job-1", status: "queued" }; 405 + (userDeletionService.createDeletionJob as jest.Mock).mockResolvedValue( 406 + mockJob, 406 407 ); 407 408 408 409 await expect( 409 - service.deleteUser("did:plc:123", { did: "did:plc:123" }, true), 410 - ).rejects.toThrow(BadGatewayException); 410 + service.createDeletionJob("did:plc:123", true), 411 + ).resolves.toEqual(mockJob); 412 + expect(userDeletionService.createDeletionJob).toHaveBeenCalledWith( 413 + "did:plc:123", 414 + true, 415 + ); 411 416 }); 412 417 413 418 it("imports Bluesky follows with pagination and creates only missing local follows", async () => {
+10 -12
backend/src/users/users.service.ts
··· 386 386 ); 387 387 } 388 388 389 - /** 390 - * Delete user account 391 - * @param did - User's DID 392 - * @param session - AT Protocol session for PDS operations 393 - * @param deletePDSData - Whether to delete data from user's PDS 394 - */ 395 - async deleteUser( 396 - did: string, 397 - session: ATSession, 398 - deletePDSData: boolean, 399 - ): Promise<void> { 400 - await this.userDeletionService.deleteUser(did, session, deletePDSData); 389 + async deleteUserSync(did: string): Promise<void> { 390 + await this.userDeletionService.deleteUserSync(did); 391 + } 392 + 393 + async createDeletionJob(did: string, deletePDSData: boolean) { 394 + return this.userDeletionService.createDeletionJob(did, deletePDSData); 395 + } 396 + 397 + async getCurrentDeletionJob(userDid: string) { 398 + return this.userDeletionService.getCurrentDeletionJob(userDid); 401 399 } 402 400 403 401 private async fetchBlueskyFollowDids(actorDid: string): Promise<string[]> {
+84
packages/api/src/account-deletion-status.ts
··· 1 + const ACTIVE_ACCOUNT_DELETION_STATUSES = ["queued", "running"] as const; 2 + const TERMINAL_ACCOUNT_DELETION_STATUSES = ["completed", "failed"] as const; 3 + 4 + export type AccountDeletionStatusJob = { 5 + status: string; 6 + totalRecords: number; 7 + deletedRecords: number; 8 + currentStep?: string; 9 + lastError?: string; 10 + }; 11 + 12 + const STEP_LABELS: Record<string, string> = { 13 + movies: "Deleting movies…", 14 + episodes: "Deleting episodes…", 15 + follows: "Deleting follows…", 16 + list_items: "Deleting list items…", 17 + lists: "Deleting lists…", 18 + profile: "Deleting profile…", 19 + db_cleanup: "Cleaning up account data…", 20 + completed: "Deletion complete", 21 + }; 22 + 23 + export function isActiveAccountDeletionStatus(status: string): boolean { 24 + return (ACTIVE_ACCOUNT_DELETION_STATUSES as readonly string[]).includes( 25 + status, 26 + ); 27 + } 28 + 29 + export function isTerminalAccountDeletionStatus(status: string): boolean { 30 + return (TERMINAL_ACCOUNT_DELETION_STATUSES as readonly string[]).includes( 31 + status, 32 + ); 33 + } 34 + 35 + export function getAccountDeletionStepLabel( 36 + step: string | undefined, 37 + ): string { 38 + if (!step) { 39 + return "Preparing…"; 40 + } 41 + return STEP_LABELS[step] ?? "Processing…"; 42 + } 43 + 44 + export function getAccountDeletionProgress( 45 + job: AccountDeletionStatusJob, 46 + ): number | null { 47 + if (job.status === "completed") { 48 + return 100; 49 + } 50 + 51 + if (job.status === "queued") { 52 + return 0; 53 + } 54 + 55 + if (job.totalRecords > 0) { 56 + return Math.max( 57 + 0, 58 + Math.min( 59 + 99, 60 + Math.round((job.deletedRecords / job.totalRecords) * 100), 61 + ), 62 + ); 63 + } 64 + 65 + return null; 66 + } 67 + 68 + export function getAccountDeletionStatusMessage( 69 + job: AccountDeletionStatusJob, 70 + ): string { 71 + if (job.status === "queued") { 72 + return "Queued for deletion…"; 73 + } 74 + if (job.status === "failed") { 75 + return ( 76 + job.lastError ?? 77 + "Account deletion failed. Please try again or contact support." 78 + ); 79 + } 80 + if (job.status === "completed") { 81 + return "Your account has been deleted."; 82 + } 83 + return getAccountDeletionStepLabel(job.currentStep); 84 + }
+20 -2
packages/api/src/generated/@tanstack/react-query.gen.ts
··· 3 3 import { type DefaultError, type InfiniteData, infiniteQueryOptions, queryOptions, type UseMutationOptions } from '@tanstack/react-query'; 4 4 5 5 import { client } from '../client.gen'; 6 - import { authControllerBlueskyProfileStatus, authControllerCallback, authControllerGetClientMetadata, authControllerLogin, authControllerLogout, authControllerMe, authControllerSignup, authControllerSuggestions, listsControllerAddItemToList, listsControllerCreateList, listsControllerDeleteList, listsControllerGetList, listsControllerGetListsForItem, listsControllerGetPublicUserList, listsControllerGetPublicUserLists, listsControllerGetUserLists, listsControllerRemoveItemFromList, listsControllerUpdateList, moviesControllerDeleteWatchHistoryEntry, moviesControllerDiscoverMovies, moviesControllerGetMovie, moviesControllerGetMovieDetails, moviesControllerGetMovieWatchHistory, moviesControllerGetUserMovies, moviesControllerGetUserMoviesPaginated, moviesControllerMarkWatched, moviesControllerSearchMovies, moviesControllerUnmarkWatched, type Options, searchControllerDiscoverAll, searchControllerSearchAll, shelfControllerGetUserActivitySummary, shelfControllerGetUserShelf, showsControllerDeleteEpisodeWatchHistoryEntry, showsControllerDiscoverShows, showsControllerGetEpisodeDetails, showsControllerGetLocalEpisodes, showsControllerGetLocalSeasons, showsControllerGetSeasonDetails, showsControllerGetShow, showsControllerGetShowDetails, showsControllerGetShowWatchHistory, showsControllerGetUserEpisodesPaginated, showsControllerGetUserReleaseCalendar, showsControllerGetUserShows, showsControllerGetUserUpNext, showsControllerMarkSeasonWatched, showsControllerMarkShowWatched, showsControllerMarkWatched, showsControllerSearchShows, showsControllerUnmarkWatched, socialControllerFollow, socialControllerGetFeed, socialControllerGetFollowers, socialControllerGetFollowing, socialControllerGetRelationship, socialControllerGetWatchers, socialControllerSearchPeople, socialControllerUnfollow, usersControllerCompleteOnboarding, usersControllerDeleteMyAccount, usersControllerDeleteMyAvatar, usersControllerFetchMyTraktPublicHistory, usersControllerGetAvatar, usersControllerGetMyCurrentTraktImport, usersControllerGetMySettings, usersControllerGetPublicProfile, usersControllerImportMyBlueskyFollows, usersControllerImportMyHistory, usersControllerStartMyTraktImport, usersControllerUpdateMyProfile, usersControllerUpdateMySettings, usersControllerUploadMyAvatar } from '../sdk.gen'; 7 - import type { AuthControllerBlueskyProfileStatusData, AuthControllerBlueskyProfileStatusResponse, AuthControllerCallbackData, AuthControllerGetClientMetadataData, AuthControllerLoginData, AuthControllerLogoutData, AuthControllerMeData, AuthControllerMeResponse, AuthControllerSignupData, AuthControllerSuggestionsData, ListsControllerAddItemToListData, ListsControllerCreateListData, ListsControllerCreateListResponse, ListsControllerDeleteListData, ListsControllerGetListData, ListsControllerGetListResponse, ListsControllerGetListsForItemData, ListsControllerGetListsForItemResponse, ListsControllerGetPublicUserListData, ListsControllerGetPublicUserListResponse, ListsControllerGetPublicUserListsData, ListsControllerGetPublicUserListsResponse, ListsControllerGetUserListsData, ListsControllerGetUserListsResponse, ListsControllerRemoveItemFromListData, ListsControllerUpdateListData, ListsControllerUpdateListResponse, MoviesControllerDeleteWatchHistoryEntryData, MoviesControllerDeleteWatchHistoryEntryResponse, MoviesControllerDiscoverMoviesData, MoviesControllerDiscoverMoviesResponse, MoviesControllerGetMovieData, MoviesControllerGetMovieDetailsData, MoviesControllerGetMovieDetailsResponse, MoviesControllerGetMovieResponse, MoviesControllerGetMovieWatchHistoryData, MoviesControllerGetMovieWatchHistoryResponse, MoviesControllerGetUserMoviesData, MoviesControllerGetUserMoviesPaginatedData, MoviesControllerGetUserMoviesPaginatedResponse, MoviesControllerGetUserMoviesResponse, MoviesControllerMarkWatchedData, MoviesControllerMarkWatchedResponse, MoviesControllerSearchMoviesData, MoviesControllerSearchMoviesResponse, MoviesControllerUnmarkWatchedData, MoviesControllerUnmarkWatchedResponse, SearchControllerDiscoverAllData, SearchControllerDiscoverAllResponse, SearchControllerSearchAllData, SearchControllerSearchAllResponse, ShelfControllerGetUserActivitySummaryData, ShelfControllerGetUserActivitySummaryResponse, ShelfControllerGetUserShelfData, ShelfControllerGetUserShelfResponse, ShowsControllerDeleteEpisodeWatchHistoryEntryData, ShowsControllerDeleteEpisodeWatchHistoryEntryResponse, ShowsControllerDiscoverShowsData, ShowsControllerDiscoverShowsResponse, ShowsControllerGetEpisodeDetailsData, ShowsControllerGetEpisodeDetailsResponse, ShowsControllerGetLocalEpisodesData, ShowsControllerGetLocalEpisodesResponse, ShowsControllerGetLocalSeasonsData, ShowsControllerGetLocalSeasonsResponse, ShowsControllerGetSeasonDetailsData, ShowsControllerGetSeasonDetailsResponse, ShowsControllerGetShowData, ShowsControllerGetShowDetailsData, ShowsControllerGetShowDetailsResponse, ShowsControllerGetShowResponse, ShowsControllerGetShowWatchHistoryData, ShowsControllerGetShowWatchHistoryResponse, ShowsControllerGetUserEpisodesPaginatedData, ShowsControllerGetUserEpisodesPaginatedResponse, ShowsControllerGetUserReleaseCalendarData, ShowsControllerGetUserReleaseCalendarResponse, ShowsControllerGetUserShowsData, ShowsControllerGetUserShowsResponse, ShowsControllerGetUserUpNextData, ShowsControllerGetUserUpNextResponse, ShowsControllerMarkSeasonWatchedData, ShowsControllerMarkSeasonWatchedResponse, ShowsControllerMarkShowWatchedData, ShowsControllerMarkShowWatchedResponse, ShowsControllerMarkWatchedData, ShowsControllerMarkWatchedResponse, ShowsControllerSearchShowsData, ShowsControllerSearchShowsResponse, ShowsControllerUnmarkWatchedData, ShowsControllerUnmarkWatchedResponse, SocialControllerFollowData, SocialControllerFollowResponse, SocialControllerGetFeedData, SocialControllerGetFeedResponse, SocialControllerGetFollowersData, SocialControllerGetFollowersResponse, SocialControllerGetFollowingData, SocialControllerGetFollowingResponse, SocialControllerGetRelationshipData, SocialControllerGetRelationshipResponse, SocialControllerGetWatchersData, SocialControllerGetWatchersResponse, SocialControllerSearchPeopleData, SocialControllerSearchPeopleResponse, SocialControllerUnfollowData, SocialControllerUnfollowResponse, UsersControllerCompleteOnboardingData, UsersControllerCompleteOnboardingResponse, UsersControllerDeleteMyAccountData, UsersControllerDeleteMyAccountResponse, UsersControllerDeleteMyAvatarData, UsersControllerDeleteMyAvatarResponse, UsersControllerFetchMyTraktPublicHistoryData, UsersControllerFetchMyTraktPublicHistoryResponse, UsersControllerGetAvatarData, UsersControllerGetMyCurrentTraktImportData, UsersControllerGetMyCurrentTraktImportResponse, UsersControllerGetMySettingsData, UsersControllerGetMySettingsResponse, UsersControllerGetPublicProfileData, UsersControllerGetPublicProfileResponse, UsersControllerImportMyBlueskyFollowsData, UsersControllerImportMyBlueskyFollowsResponse, UsersControllerImportMyHistoryData, UsersControllerImportMyHistoryResponse, UsersControllerStartMyTraktImportData, UsersControllerStartMyTraktImportResponse, UsersControllerUpdateMyProfileData, UsersControllerUpdateMyProfileResponse, UsersControllerUpdateMySettingsData, UsersControllerUpdateMySettingsResponse, UsersControllerUploadMyAvatarData, UsersControllerUploadMyAvatarResponse } from '../types.gen'; 6 + import { authControllerBlueskyProfileStatus, authControllerCallback, authControllerGetClientMetadata, authControllerLogin, authControllerLogout, authControllerMe, authControllerSignup, authControllerSuggestions, listsControllerAddItemToList, listsControllerCreateList, listsControllerDeleteList, listsControllerGetList, listsControllerGetListsForItem, listsControllerGetPublicUserList, listsControllerGetPublicUserLists, listsControllerGetUserLists, listsControllerRemoveItemFromList, listsControllerUpdateList, moviesControllerDeleteWatchHistoryEntry, moviesControllerDiscoverMovies, moviesControllerGetMovie, moviesControllerGetMovieDetails, moviesControllerGetMovieWatchHistory, moviesControllerGetUserMovies, moviesControllerGetUserMoviesPaginated, moviesControllerMarkWatched, moviesControllerSearchMovies, moviesControllerUnmarkWatched, type Options, searchControllerDiscoverAll, searchControllerSearchAll, shelfControllerGetUserActivitySummary, shelfControllerGetUserShelf, showsControllerDeleteEpisodeWatchHistoryEntry, showsControllerDiscoverShows, showsControllerGetEpisodeDetails, showsControllerGetLocalEpisodes, showsControllerGetLocalSeasons, showsControllerGetSeasonDetails, showsControllerGetShow, showsControllerGetShowDetails, showsControllerGetShowWatchHistory, showsControllerGetUserEpisodesPaginated, showsControllerGetUserReleaseCalendar, showsControllerGetUserShows, showsControllerGetUserUpNext, showsControllerMarkSeasonWatched, showsControllerMarkShowWatched, showsControllerMarkWatched, showsControllerSearchShows, showsControllerUnmarkWatched, socialControllerFollow, socialControllerGetFeed, socialControllerGetFollowers, socialControllerGetFollowing, socialControllerGetRelationship, socialControllerGetWatchers, socialControllerSearchPeople, socialControllerUnfollow, usersControllerCompleteOnboarding, usersControllerDeleteMyAccount, usersControllerDeleteMyAvatar, usersControllerFetchMyTraktPublicHistory, usersControllerGetAvatar, usersControllerGetMyCurrentTraktImport, usersControllerGetMySettings, usersControllerGetPublicProfile, usersControllerImportMyBlueskyFollows, usersControllerImportMyHistory, usersControllerStartMyTraktImport, usersControllerUpdateMyProfile, usersControllerUpdateMySettings, usersControllerUploadMyAvatar, usersControllerGetMyAccountDeletion } from '../sdk.gen'; 7 + import type { AuthControllerBlueskyProfileStatusData, AuthControllerBlueskyProfileStatusResponse, AuthControllerCallbackData, AuthControllerGetClientMetadataData, AuthControllerLoginData, AuthControllerLogoutData, AuthControllerMeData, AuthControllerMeResponse, AuthControllerSignupData, AuthControllerSuggestionsData, ListsControllerAddItemToListData, ListsControllerCreateListData, ListsControllerCreateListResponse, ListsControllerDeleteListData, ListsControllerGetListData, ListsControllerGetListResponse, ListsControllerGetListsForItemData, ListsControllerGetListsForItemResponse, ListsControllerGetPublicUserListData, ListsControllerGetPublicUserListResponse, ListsControllerGetPublicUserListsData, ListsControllerGetPublicUserListsResponse, ListsControllerGetUserListsData, ListsControllerGetUserListsResponse, ListsControllerRemoveItemFromListData, ListsControllerUpdateListData, ListsControllerUpdateListResponse, MoviesControllerDeleteWatchHistoryEntryData, MoviesControllerDeleteWatchHistoryEntryResponse, MoviesControllerDiscoverMoviesData, MoviesControllerDiscoverMoviesResponse, MoviesControllerGetMovieData, MoviesControllerGetMovieDetailsData, MoviesControllerGetMovieDetailsResponse, MoviesControllerGetMovieResponse, MoviesControllerGetMovieWatchHistoryData, MoviesControllerGetMovieWatchHistoryResponse, MoviesControllerGetUserMoviesData, MoviesControllerGetUserMoviesPaginatedData, MoviesControllerGetUserMoviesPaginatedResponse, MoviesControllerGetUserMoviesResponse, MoviesControllerMarkWatchedData, MoviesControllerMarkWatchedResponse, MoviesControllerSearchMoviesData, MoviesControllerSearchMoviesResponse, MoviesControllerUnmarkWatchedData, MoviesControllerUnmarkWatchedResponse, SearchControllerDiscoverAllData, SearchControllerDiscoverAllResponse, SearchControllerSearchAllData, SearchControllerSearchAllResponse, ShelfControllerGetUserActivitySummaryData, ShelfControllerGetUserActivitySummaryResponse, ShelfControllerGetUserShelfData, ShelfControllerGetUserShelfResponse, ShowsControllerDeleteEpisodeWatchHistoryEntryData, ShowsControllerDeleteEpisodeWatchHistoryEntryResponse, ShowsControllerDiscoverShowsData, ShowsControllerDiscoverShowsResponse, ShowsControllerGetEpisodeDetailsData, ShowsControllerGetEpisodeDetailsResponse, ShowsControllerGetLocalEpisodesData, ShowsControllerGetLocalEpisodesResponse, ShowsControllerGetLocalSeasonsData, ShowsControllerGetLocalSeasonsResponse, ShowsControllerGetSeasonDetailsData, ShowsControllerGetSeasonDetailsResponse, ShowsControllerGetShowData, ShowsControllerGetShowDetailsData, ShowsControllerGetShowDetailsResponse, ShowsControllerGetShowResponse, ShowsControllerGetShowWatchHistoryData, ShowsControllerGetShowWatchHistoryResponse, ShowsControllerGetUserEpisodesPaginatedData, ShowsControllerGetUserEpisodesPaginatedResponse, ShowsControllerGetUserReleaseCalendarData, ShowsControllerGetUserReleaseCalendarResponse, ShowsControllerGetUserShowsData, ShowsControllerGetUserShowsResponse, ShowsControllerGetUserUpNextData, ShowsControllerGetUserUpNextResponse, ShowsControllerMarkSeasonWatchedData, ShowsControllerMarkSeasonWatchedResponse, ShowsControllerMarkShowWatchedData, ShowsControllerMarkShowWatchedResponse, ShowsControllerMarkWatchedData, ShowsControllerMarkWatchedResponse, ShowsControllerSearchShowsData, ShowsControllerSearchShowsResponse, ShowsControllerUnmarkWatchedData, ShowsControllerUnmarkWatchedResponse, SocialControllerFollowData, SocialControllerFollowResponse, SocialControllerGetFeedData, SocialControllerGetFeedResponse, SocialControllerGetFollowersData, SocialControllerGetFollowersResponse, SocialControllerGetFollowingData, SocialControllerGetFollowingResponse, SocialControllerGetRelationshipData, SocialControllerGetRelationshipResponse, SocialControllerGetWatchersData, SocialControllerGetWatchersResponse, SocialControllerSearchPeopleData, SocialControllerSearchPeopleResponse, SocialControllerUnfollowData, SocialControllerUnfollowResponse, UsersControllerCompleteOnboardingData, UsersControllerCompleteOnboardingResponse, UsersControllerDeleteMyAccountData, UsersControllerDeleteMyAccountResponse, UsersControllerDeleteMyAvatarData, UsersControllerDeleteMyAvatarResponse, UsersControllerFetchMyTraktPublicHistoryData, UsersControllerFetchMyTraktPublicHistoryResponse, UsersControllerGetAvatarData, UsersControllerGetMyCurrentTraktImportData, UsersControllerGetMyCurrentTraktImportResponse, UsersControllerGetMySettingsData, UsersControllerGetMySettingsResponse, UsersControllerGetPublicProfileData, UsersControllerGetPublicProfileResponse, UsersControllerImportMyBlueskyFollowsData, UsersControllerImportMyBlueskyFollowsResponse, UsersControllerImportMyHistoryData, UsersControllerImportMyHistoryResponse, UsersControllerStartMyTraktImportData, UsersControllerStartMyTraktImportResponse, UsersControllerUpdateMyProfileData, UsersControllerUpdateMyProfileResponse, UsersControllerUpdateMySettingsData, UsersControllerUpdateMySettingsResponse, UsersControllerUploadMyAvatarData, UsersControllerUploadMyAvatarResponse, UsersControllerGetMyAccountDeletionData, UsersControllerGetMyAccountDeletionResponse } from '../types.gen'; 8 8 9 9 export type QueryKey<TOptions extends Options> = [ 10 10 Pick<TOptions, 'baseUrl' | 'body' | 'headers' | 'path' | 'query'> & { ··· 994 994 return data; 995 995 }, 996 996 queryKey: usersControllerGetMyCurrentTraktImportQueryKey(options) 997 + }); 998 + 999 + export const usersControllerGetMyAccountDeletionQueryKey = (options?: Options<UsersControllerGetMyAccountDeletionData>) => createQueryKey('usersControllerGetMyAccountDeletion', options); 1000 + 1001 + /** 1002 + * Get current account deletion job status 1003 + */ 1004 + export const usersControllerGetMyAccountDeletionOptions = (options?: Options<UsersControllerGetMyAccountDeletionData>) => queryOptions<UsersControllerGetMyAccountDeletionResponse, DefaultError, UsersControllerGetMyAccountDeletionResponse, ReturnType<typeof usersControllerGetMyAccountDeletionQueryKey>>({ 1005 + queryFn: async ({ queryKey, signal }) => { 1006 + const { data } = await usersControllerGetMyAccountDeletion({ 1007 + ...options, 1008 + ...queryKey[0], 1009 + signal, 1010 + throwOnError: true 1011 + }); 1012 + return data; 1013 + }, 1014 + queryKey: usersControllerGetMyAccountDeletionQueryKey(options) 997 1015 }); 998 1016 999 1017 /**
+2 -2
packages/api/src/generated/index.ts
··· 1 1 // This file is auto-generated by @hey-api/openapi-ts 2 2 3 - export { authControllerBlueskyProfileStatus, authControllerCallback, authControllerGetClientMetadata, authControllerLogin, authControllerLogout, authControllerMe, authControllerSignup, authControllerSuggestions, listsControllerAddItemToList, listsControllerCreateList, listsControllerDeleteList, listsControllerGetList, listsControllerGetListsForItem, listsControllerGetPublicUserList, listsControllerGetPublicUserLists, listsControllerGetUserLists, listsControllerRemoveItemFromList, listsControllerUpdateList, moviesControllerDeleteWatchHistoryEntry, moviesControllerDiscoverMovies, moviesControllerGetMovie, moviesControllerGetMovieDetails, moviesControllerGetMovieWatchHistory, moviesControllerGetUserMovies, moviesControllerGetUserMoviesPaginated, moviesControllerMarkWatched, moviesControllerSearchMovies, moviesControllerUnmarkWatched, type Options, searchControllerDiscoverAll, searchControllerSearchAll, shelfControllerGetUserActivitySummary, shelfControllerGetUserShelf, showsControllerDeleteEpisodeWatchHistoryEntry, showsControllerDiscoverShows, showsControllerGetEpisodeDetails, showsControllerGetLocalEpisodes, showsControllerGetLocalSeasons, showsControllerGetSeasonDetails, showsControllerGetShow, showsControllerGetShowDetails, showsControllerGetShowWatchHistory, showsControllerGetUserEpisodesPaginated, showsControllerGetUserReleaseCalendar, showsControllerGetUserShows, showsControllerGetUserUpNext, showsControllerMarkSeasonWatched, showsControllerMarkShowWatched, showsControllerMarkWatched, showsControllerSearchShows, showsControllerUnmarkWatched, socialControllerFollow, socialControllerGetFeed, socialControllerGetFollowers, socialControllerGetFollowing, socialControllerGetRelationship, socialControllerGetWatchers, socialControllerSearchPeople, socialControllerUnfollow, usersControllerCompleteOnboarding, usersControllerDeleteMyAccount, usersControllerDeleteMyAvatar, usersControllerFetchMyTraktPublicHistory, usersControllerGetAvatar, usersControllerGetMyCurrentTraktImport, usersControllerGetMySettings, usersControllerGetPublicProfile, usersControllerImportMyBlueskyFollows, usersControllerImportMyHistory, usersControllerStartMyTraktImport, usersControllerUpdateMyProfile, usersControllerUpdateMySettings, usersControllerUploadMyAvatar } from './sdk.gen'; 4 - export type { AddToListDto, AuthControllerBlueskyProfileStatusData, AuthControllerBlueskyProfileStatusErrors, AuthControllerBlueskyProfileStatusResponse, AuthControllerBlueskyProfileStatusResponses, AuthControllerCallbackData, AuthControllerGetClientMetadataData, AuthControllerGetClientMetadataResponses, AuthControllerLoginData, AuthControllerLogoutData, AuthControllerLogoutResponses, AuthControllerMeData, AuthControllerMeErrors, AuthControllerMeResponse, AuthControllerMeResponses, AuthControllerSignupData, AuthControllerSuggestionsData, AuthControllerSuggestionsResponses, BlueskyProfileStatusDto, ClientOptions, CompleteOnboardingResponseDto, CreateListDto, DeleteUserAccountDto, EpisodeContextDto, EpisodeHistoryItemDto, EpisodeReferenceDto, FetchTraktPublicHistoryDto, FetchTraktPublicHistoryResponseDto, FollowedActivityFeedDto, FollowedActivityItemDto, FollowedWatcherActorDto, FollowedWatcherDto, FollowedWatchersDto, ImportBlueskyFollowsResponseDto, ImportErrorDto, ImportHistoryDto, ImportHistoryResponseDto, ImportSkipDto, ListDto, ListsControllerAddItemToListData, ListsControllerAddItemToListErrors, ListsControllerAddItemToListResponses, ListsControllerCreateListData, ListsControllerCreateListErrors, ListsControllerCreateListResponse, ListsControllerCreateListResponses, ListsControllerDeleteListData, ListsControllerDeleteListErrors, ListsControllerDeleteListResponses, ListsControllerGetListData, ListsControllerGetListErrors, ListsControllerGetListResponse, ListsControllerGetListResponses, ListsControllerGetListsForItemData, ListsControllerGetListsForItemErrors, ListsControllerGetListsForItemResponse, ListsControllerGetListsForItemResponses, ListsControllerGetPublicUserListData, ListsControllerGetPublicUserListErrors, ListsControllerGetPublicUserListResponse, ListsControllerGetPublicUserListResponses, ListsControllerGetPublicUserListsData, ListsControllerGetPublicUserListsResponse, ListsControllerGetPublicUserListsResponses, ListsControllerGetUserListsData, ListsControllerGetUserListsErrors, ListsControllerGetUserListsResponse, ListsControllerGetUserListsResponses, ListsControllerRemoveItemFromListData, ListsControllerRemoveItemFromListErrors, ListsControllerRemoveItemFromListResponses, ListsControllerUpdateListData, ListsControllerUpdateListErrors, ListsControllerUpdateListResponse, ListsControllerUpdateListResponses, ListsForItemDto, ListSummaryDto, ListWithItemsDto, LocalEpisodeDto, LocalSeasonDto, MarkedEpisodesResponseDto, MarkEpisodeWatchedDto, MarkSeasonWatchedDto, MarkShowWatchedDto, MediaInListDto, MovieColorsDto, MovieDto, MoviesControllerDeleteWatchHistoryEntryData, MoviesControllerDeleteWatchHistoryEntryErrors, MoviesControllerDeleteWatchHistoryEntryResponse, MoviesControllerDeleteWatchHistoryEntryResponses, MoviesControllerDiscoverMoviesData, MoviesControllerDiscoverMoviesResponse, MoviesControllerDiscoverMoviesResponses, MoviesControllerGetMovieData, MoviesControllerGetMovieDetailsData, MoviesControllerGetMovieDetailsResponse, MoviesControllerGetMovieDetailsResponses, MoviesControllerGetMovieResponse, MoviesControllerGetMovieResponses, MoviesControllerGetMovieWatchHistoryData, MoviesControllerGetMovieWatchHistoryErrors, MoviesControllerGetMovieWatchHistoryResponse, MoviesControllerGetMovieWatchHistoryResponses, MoviesControllerGetUserMoviesData, MoviesControllerGetUserMoviesPaginatedData, MoviesControllerGetUserMoviesPaginatedResponse, MoviesControllerGetUserMoviesPaginatedResponses, MoviesControllerGetUserMoviesResponse, MoviesControllerGetUserMoviesResponses, MoviesControllerMarkWatchedData, MoviesControllerMarkWatchedErrors, MoviesControllerMarkWatchedResponse, MoviesControllerMarkWatchedResponses, MoviesControllerSearchMoviesData, MoviesControllerSearchMoviesResponse, MoviesControllerSearchMoviesResponses, MoviesControllerUnmarkWatchedData, MoviesControllerUnmarkWatchedErrors, MoviesControllerUnmarkWatchedResponse, MoviesControllerUnmarkWatchedResponses, NormalizedImportItemDto, PaginatedEpisodesResponseDto, PaginatedMoviesResponseDto, PaginatedSocialUsersDto, PaginatedUpNextResponseDto, PublicUserProfileDto, ReleaseCalendarItemDto, ReleaseCalendarResponseDto, SearchControllerDiscoverAllData, SearchControllerDiscoverAllResponse, SearchControllerDiscoverAllResponses, SearchControllerSearchAllData, SearchControllerSearchAllResponse, SearchControllerSearchAllResponses, SearchResultsDto, SearchShowsResultsDto, ShelfActivityBucketDto, ShelfActivitySummaryDto, ShelfControllerGetUserActivitySummaryData, ShelfControllerGetUserActivitySummaryResponse, ShelfControllerGetUserActivitySummaryResponses, ShelfControllerGetUserShelfData, ShelfControllerGetUserShelfResponse, ShelfControllerGetUserShelfResponses, ShelfResponseDto, ShowDto, ShowsControllerDeleteEpisodeWatchHistoryEntryData, ShowsControllerDeleteEpisodeWatchHistoryEntryErrors, ShowsControllerDeleteEpisodeWatchHistoryEntryResponse, ShowsControllerDeleteEpisodeWatchHistoryEntryResponses, ShowsControllerDiscoverShowsData, ShowsControllerDiscoverShowsResponse, ShowsControllerDiscoverShowsResponses, ShowsControllerGetEpisodeDetailsData, ShowsControllerGetEpisodeDetailsResponse, ShowsControllerGetEpisodeDetailsResponses, ShowsControllerGetLocalEpisodesData, ShowsControllerGetLocalEpisodesResponse, ShowsControllerGetLocalEpisodesResponses, ShowsControllerGetLocalSeasonsData, ShowsControllerGetLocalSeasonsResponse, ShowsControllerGetLocalSeasonsResponses, ShowsControllerGetSeasonDetailsData, ShowsControllerGetSeasonDetailsResponse, ShowsControllerGetSeasonDetailsResponses, ShowsControllerGetShowData, ShowsControllerGetShowDetailsData, ShowsControllerGetShowDetailsResponse, ShowsControllerGetShowDetailsResponses, ShowsControllerGetShowResponse, ShowsControllerGetShowResponses, ShowsControllerGetShowWatchHistoryData, ShowsControllerGetShowWatchHistoryErrors, ShowsControllerGetShowWatchHistoryResponse, ShowsControllerGetShowWatchHistoryResponses, ShowsControllerGetUserEpisodesPaginatedData, ShowsControllerGetUserEpisodesPaginatedResponse, ShowsControllerGetUserEpisodesPaginatedResponses, ShowsControllerGetUserReleaseCalendarData, ShowsControllerGetUserReleaseCalendarResponse, ShowsControllerGetUserReleaseCalendarResponses, ShowsControllerGetUserShowsData, ShowsControllerGetUserShowsResponse, ShowsControllerGetUserShowsResponses, ShowsControllerGetUserUpNextData, ShowsControllerGetUserUpNextResponse, ShowsControllerGetUserUpNextResponses, ShowsControllerMarkSeasonWatchedData, ShowsControllerMarkSeasonWatchedErrors, ShowsControllerMarkSeasonWatchedResponse, ShowsControllerMarkSeasonWatchedResponses, ShowsControllerMarkShowWatchedData, ShowsControllerMarkShowWatchedErrors, ShowsControllerMarkShowWatchedResponse, ShowsControllerMarkShowWatchedResponses, ShowsControllerMarkWatchedData, ShowsControllerMarkWatchedErrors, ShowsControllerMarkWatchedResponse, ShowsControllerMarkWatchedResponses, ShowsControllerSearchShowsData, ShowsControllerSearchShowsResponse, ShowsControllerSearchShowsResponses, ShowsControllerUnmarkWatchedData, ShowsControllerUnmarkWatchedResponse, ShowsControllerUnmarkWatchedResponses, SocialActorDto, SocialControllerFollowData, SocialControllerFollowResponse, SocialControllerFollowResponses, SocialControllerGetFeedData, SocialControllerGetFeedResponse, SocialControllerGetFeedResponses, SocialControllerGetFollowersData, SocialControllerGetFollowersResponse, SocialControllerGetFollowersResponses, SocialControllerGetFollowingData, SocialControllerGetFollowingResponse, SocialControllerGetFollowingResponses, SocialControllerGetRelationshipData, SocialControllerGetRelationshipResponse, SocialControllerGetRelationshipResponses, SocialControllerGetWatchersData, SocialControllerGetWatchersResponse, SocialControllerGetWatchersResponses, SocialControllerSearchPeopleData, SocialControllerSearchPeopleResponse, SocialControllerSearchPeopleResponses, SocialControllerUnfollowData, SocialControllerUnfollowResponse, SocialControllerUnfollowResponses, SocialUserCardDto, StartTraktImportDto, StartTraktImportResponseDto, TmdbCastDto, TmdbCreditsDto, TmdbCrewDto, TmdbEpisodeDto, TmdbGenreDto, TmdbMovieDetailDto, TmdbMovieResultDto, TmdbNetworkDto, TmdbSeasonDetailDto, TmdbSeasonSummaryDto, TmdbShowDetailDto, TmdbShowResultDto, TmdbTrailerDto, TrackedEpisodeDto, TrackedMovieDto, TrackedShowSummaryDto, TraktHistoryPreviewItemDto, TraktImportJobDto, TraktPublicProfileDto, UnifiedDiscoverResponseDto, UnifiedSearchResponseDto, UnifiedSearchResultDto, UpdateListDto, UpdateUserProfileDto, UpdateUserSettingsDto, UpNextEpisodeDto, UpNextShowDto, UserDto, UserProfileDto, UserRelationshipDto, UsersControllerCompleteOnboardingData, UsersControllerCompleteOnboardingErrors, UsersControllerCompleteOnboardingResponse, UsersControllerCompleteOnboardingResponses, UsersControllerDeleteMyAccountData, UsersControllerDeleteMyAccountErrors, UsersControllerDeleteMyAccountResponse, UsersControllerDeleteMyAccountResponses, UsersControllerDeleteMyAvatarData, UsersControllerDeleteMyAvatarResponse, UsersControllerDeleteMyAvatarResponses, UsersControllerFetchMyTraktPublicHistoryData, UsersControllerFetchMyTraktPublicHistoryErrors, UsersControllerFetchMyTraktPublicHistoryResponse, UsersControllerFetchMyTraktPublicHistoryResponses, UsersControllerGetAvatarData, UsersControllerGetAvatarResponses, UsersControllerGetMyCurrentTraktImportData, UsersControllerGetMyCurrentTraktImportErrors, UsersControllerGetMyCurrentTraktImportResponse, UsersControllerGetMyCurrentTraktImportResponses, UsersControllerGetMySettingsData, UsersControllerGetMySettingsErrors, UsersControllerGetMySettingsResponse, UsersControllerGetMySettingsResponses, UsersControllerGetPublicProfileData, UsersControllerGetPublicProfileErrors, UsersControllerGetPublicProfileResponse, UsersControllerGetPublicProfileResponses, UsersControllerImportMyBlueskyFollowsData, UsersControllerImportMyBlueskyFollowsErrors, UsersControllerImportMyBlueskyFollowsResponse, UsersControllerImportMyBlueskyFollowsResponses, UsersControllerImportMyHistoryData, UsersControllerImportMyHistoryErrors, UsersControllerImportMyHistoryResponse, UsersControllerImportMyHistoryResponses, UsersControllerStartMyTraktImportData, UsersControllerStartMyTraktImportErrors, UsersControllerStartMyTraktImportResponse, UsersControllerStartMyTraktImportResponses, UsersControllerUpdateMyProfileData, UsersControllerUpdateMyProfileErrors, UsersControllerUpdateMyProfileResponse, UsersControllerUpdateMyProfileResponses, UsersControllerUpdateMySettingsData, UsersControllerUpdateMySettingsErrors, UsersControllerUpdateMySettingsResponse, UsersControllerUpdateMySettingsResponses, UsersControllerUploadMyAvatarData, UsersControllerUploadMyAvatarResponse, UsersControllerUploadMyAvatarResponses, UserSettingsDto, WatchHistoryItemDto } from './types.gen'; 3 + export { authControllerBlueskyProfileStatus, authControllerCallback, authControllerGetClientMetadata, authControllerLogin, authControllerLogout, authControllerMe, authControllerSignup, authControllerSuggestions, listsControllerAddItemToList, listsControllerCreateList, listsControllerDeleteList, listsControllerGetList, listsControllerGetListsForItem, listsControllerGetPublicUserList, listsControllerGetPublicUserLists, listsControllerGetUserLists, listsControllerRemoveItemFromList, listsControllerUpdateList, moviesControllerDeleteWatchHistoryEntry, moviesControllerDiscoverMovies, moviesControllerGetMovie, moviesControllerGetMovieDetails, moviesControllerGetMovieWatchHistory, moviesControllerGetUserMovies, moviesControllerGetUserMoviesPaginated, moviesControllerMarkWatched, moviesControllerSearchMovies, moviesControllerUnmarkWatched, type Options, searchControllerDiscoverAll, searchControllerSearchAll, shelfControllerGetUserActivitySummary, shelfControllerGetUserShelf, showsControllerDeleteEpisodeWatchHistoryEntry, showsControllerDiscoverShows, showsControllerGetEpisodeDetails, showsControllerGetLocalEpisodes, showsControllerGetLocalSeasons, showsControllerGetSeasonDetails, showsControllerGetShow, showsControllerGetShowDetails, showsControllerGetShowWatchHistory, showsControllerGetUserEpisodesPaginated, showsControllerGetUserReleaseCalendar, showsControllerGetUserShows, showsControllerGetUserUpNext, showsControllerMarkSeasonWatched, showsControllerMarkShowWatched, showsControllerMarkWatched, showsControllerSearchShows, showsControllerUnmarkWatched, socialControllerFollow, socialControllerGetFeed, socialControllerGetFollowers, socialControllerGetFollowing, socialControllerGetRelationship, socialControllerGetWatchers, socialControllerSearchPeople, socialControllerUnfollow, usersControllerCompleteOnboarding, usersControllerDeleteMyAccount, usersControllerGetMyAccountDeletion, usersControllerDeleteMyAvatar, usersControllerFetchMyTraktPublicHistory, usersControllerGetAvatar, usersControllerGetMyCurrentTraktImport, usersControllerGetMySettings, usersControllerGetPublicProfile, usersControllerImportMyBlueskyFollows, usersControllerImportMyHistory, usersControllerStartMyTraktImport, usersControllerUpdateMyProfile, usersControllerUpdateMySettings, usersControllerUploadMyAvatar } from './sdk.gen'; 4 + export type { AddToListDto, AuthControllerBlueskyProfileStatusData, AuthControllerBlueskyProfileStatusErrors, AuthControllerBlueskyProfileStatusResponse, AuthControllerBlueskyProfileStatusResponses, AuthControllerCallbackData, AuthControllerGetClientMetadataData, AuthControllerGetClientMetadataResponses, AuthControllerLoginData, AuthControllerLogoutData, AuthControllerLogoutResponses, AuthControllerMeData, AuthControllerMeErrors, AuthControllerMeResponse, AuthControllerMeResponses, AuthControllerSignupData, AuthControllerSuggestionsData, AuthControllerSuggestionsResponses, BlueskyProfileStatusDto, ClientOptions, CompleteOnboardingResponseDto, CreateListDto, AccountDeletionJobDto, DeleteUserAccountDto, EpisodeContextDto, EpisodeHistoryItemDto, EpisodeReferenceDto, FetchTraktPublicHistoryDto, FetchTraktPublicHistoryResponseDto, FollowedActivityFeedDto, FollowedActivityItemDto, FollowedWatcherActorDto, FollowedWatcherDto, FollowedWatchersDto, ImportBlueskyFollowsResponseDto, ImportErrorDto, ImportHistoryDto, ImportHistoryResponseDto, ImportSkipDto, ListDto, ListsControllerAddItemToListData, ListsControllerAddItemToListErrors, ListsControllerAddItemToListResponses, ListsControllerCreateListData, ListsControllerCreateListErrors, ListsControllerCreateListResponse, ListsControllerCreateListResponses, ListsControllerDeleteListData, ListsControllerDeleteListErrors, ListsControllerDeleteListResponses, ListsControllerGetListData, ListsControllerGetListErrors, ListsControllerGetListResponse, ListsControllerGetListResponses, ListsControllerGetListsForItemData, ListsControllerGetListsForItemErrors, ListsControllerGetListsForItemResponse, ListsControllerGetListsForItemResponses, ListsControllerGetPublicUserListData, ListsControllerGetPublicUserListErrors, ListsControllerGetPublicUserListResponse, ListsControllerGetPublicUserListResponses, ListsControllerGetPublicUserListsData, ListsControllerGetPublicUserListsResponse, ListsControllerGetPublicUserListsResponses, ListsControllerGetUserListsData, ListsControllerGetUserListsErrors, ListsControllerGetUserListsResponse, ListsControllerGetUserListsResponses, ListsControllerRemoveItemFromListData, ListsControllerRemoveItemFromListErrors, ListsControllerRemoveItemFromListResponses, ListsControllerUpdateListData, ListsControllerUpdateListErrors, ListsControllerUpdateListResponse, ListsControllerUpdateListResponses, ListsForItemDto, ListSummaryDto, ListWithItemsDto, LocalEpisodeDto, LocalSeasonDto, MarkedEpisodesResponseDto, MarkEpisodeWatchedDto, MarkSeasonWatchedDto, MarkShowWatchedDto, MediaInListDto, MovieColorsDto, MovieDto, MoviesControllerDeleteWatchHistoryEntryData, MoviesControllerDeleteWatchHistoryEntryErrors, MoviesControllerDeleteWatchHistoryEntryResponse, MoviesControllerDeleteWatchHistoryEntryResponses, MoviesControllerDiscoverMoviesData, MoviesControllerDiscoverMoviesResponse, MoviesControllerDiscoverMoviesResponses, MoviesControllerGetMovieData, MoviesControllerGetMovieDetailsData, MoviesControllerGetMovieDetailsResponse, MoviesControllerGetMovieDetailsResponses, MoviesControllerGetMovieResponse, MoviesControllerGetMovieResponses, MoviesControllerGetMovieWatchHistoryData, MoviesControllerGetMovieWatchHistoryErrors, MoviesControllerGetMovieWatchHistoryResponse, MoviesControllerGetMovieWatchHistoryResponses, MoviesControllerGetUserMoviesData, MoviesControllerGetUserMoviesPaginatedData, MoviesControllerGetUserMoviesPaginatedResponse, MoviesControllerGetUserMoviesPaginatedResponses, MoviesControllerGetUserMoviesResponse, MoviesControllerGetUserMoviesResponses, MoviesControllerMarkWatchedData, MoviesControllerMarkWatchedErrors, MoviesControllerMarkWatchedResponse, MoviesControllerMarkWatchedResponses, MoviesControllerSearchMoviesData, MoviesControllerSearchMoviesResponse, MoviesControllerSearchMoviesResponses, MoviesControllerUnmarkWatchedData, MoviesControllerUnmarkWatchedErrors, MoviesControllerUnmarkWatchedResponse, MoviesControllerUnmarkWatchedResponses, NormalizedImportItemDto, PaginatedEpisodesResponseDto, PaginatedMoviesResponseDto, PaginatedSocialUsersDto, PaginatedUpNextResponseDto, PublicUserProfileDto, ReleaseCalendarItemDto, ReleaseCalendarResponseDto, SearchControllerDiscoverAllData, SearchControllerDiscoverAllResponse, SearchControllerDiscoverAllResponses, SearchControllerSearchAllData, SearchControllerSearchAllResponse, SearchControllerSearchAllResponses, SearchResultsDto, SearchShowsResultsDto, ShelfActivityBucketDto, ShelfActivitySummaryDto, ShelfControllerGetUserActivitySummaryData, ShelfControllerGetUserActivitySummaryResponse, ShelfControllerGetUserActivitySummaryResponses, ShelfControllerGetUserShelfData, ShelfControllerGetUserShelfResponse, ShelfControllerGetUserShelfResponses, ShelfResponseDto, ShowDto, ShowsControllerDeleteEpisodeWatchHistoryEntryData, ShowsControllerDeleteEpisodeWatchHistoryEntryErrors, ShowsControllerDeleteEpisodeWatchHistoryEntryResponse, ShowsControllerDeleteEpisodeWatchHistoryEntryResponses, ShowsControllerDiscoverShowsData, ShowsControllerDiscoverShowsResponse, ShowsControllerDiscoverShowsResponses, ShowsControllerGetEpisodeDetailsData, ShowsControllerGetEpisodeDetailsResponse, ShowsControllerGetEpisodeDetailsResponses, ShowsControllerGetLocalEpisodesData, ShowsControllerGetLocalEpisodesResponse, ShowsControllerGetLocalEpisodesResponses, ShowsControllerGetLocalSeasonsData, ShowsControllerGetLocalSeasonsResponse, ShowsControllerGetLocalSeasonsResponses, ShowsControllerGetSeasonDetailsData, ShowsControllerGetSeasonDetailsResponse, ShowsControllerGetSeasonDetailsResponses, ShowsControllerGetShowData, ShowsControllerGetShowDetailsData, ShowsControllerGetShowDetailsResponse, ShowsControllerGetShowDetailsResponses, ShowsControllerGetShowResponse, ShowsControllerGetShowResponses, ShowsControllerGetShowWatchHistoryData, ShowsControllerGetShowWatchHistoryErrors, ShowsControllerGetShowWatchHistoryResponse, ShowsControllerGetShowWatchHistoryResponses, ShowsControllerGetUserEpisodesPaginatedData, ShowsControllerGetUserEpisodesPaginatedResponse, ShowsControllerGetUserEpisodesPaginatedResponses, ShowsControllerGetUserReleaseCalendarData, ShowsControllerGetUserReleaseCalendarResponse, ShowsControllerGetUserReleaseCalendarResponses, ShowsControllerGetUserShowsData, ShowsControllerGetUserShowsResponse, ShowsControllerGetUserShowsResponses, ShowsControllerGetUserUpNextData, ShowsControllerGetUserUpNextResponse, ShowsControllerGetUserUpNextResponses, ShowsControllerMarkSeasonWatchedData, ShowsControllerMarkSeasonWatchedErrors, ShowsControllerMarkSeasonWatchedResponse, ShowsControllerMarkSeasonWatchedResponses, ShowsControllerMarkShowWatchedData, ShowsControllerMarkShowWatchedErrors, ShowsControllerMarkShowWatchedResponse, ShowsControllerMarkShowWatchedResponses, ShowsControllerMarkWatchedData, ShowsControllerMarkWatchedErrors, ShowsControllerMarkWatchedResponse, ShowsControllerMarkWatchedResponses, ShowsControllerSearchShowsData, ShowsControllerSearchShowsResponse, ShowsControllerSearchShowsResponses, ShowsControllerUnmarkWatchedData, ShowsControllerUnmarkWatchedResponse, ShowsControllerUnmarkWatchedResponses, SocialActorDto, SocialControllerFollowData, SocialControllerFollowResponse, SocialControllerFollowResponses, SocialControllerGetFeedData, SocialControllerGetFeedResponse, SocialControllerGetFeedResponses, SocialControllerGetFollowersData, SocialControllerGetFollowersResponse, SocialControllerGetFollowersResponses, SocialControllerGetFollowingData, SocialControllerGetFollowingResponse, SocialControllerGetFollowingResponses, SocialControllerGetRelationshipData, SocialControllerGetRelationshipResponse, SocialControllerGetRelationshipResponses, SocialControllerGetWatchersData, SocialControllerGetWatchersResponse, SocialControllerGetWatchersResponses, SocialControllerSearchPeopleData, SocialControllerSearchPeopleResponse, SocialControllerSearchPeopleResponses, SocialControllerUnfollowData, SocialControllerUnfollowResponse, SocialControllerUnfollowResponses, SocialUserCardDto, StartTraktImportDto, StartTraktImportResponseDto, TmdbCastDto, TmdbCreditsDto, TmdbCrewDto, TmdbEpisodeDto, TmdbGenreDto, TmdbMovieDetailDto, TmdbMovieResultDto, TmdbNetworkDto, TmdbSeasonDetailDto, TmdbSeasonSummaryDto, TmdbShowDetailDto, TmdbShowResultDto, TmdbTrailerDto, TrackedEpisodeDto, TrackedMovieDto, TrackedShowSummaryDto, TraktHistoryPreviewItemDto, TraktImportJobDto, TraktPublicProfileDto, UnifiedDiscoverResponseDto, UnifiedSearchResponseDto, UnifiedSearchResultDto, UpdateListDto, UpdateUserProfileDto, UpdateUserSettingsDto, UpNextEpisodeDto, UpNextShowDto, UserDto, UserProfileDto, UserRelationshipDto, UsersControllerCompleteOnboardingData, UsersControllerCompleteOnboardingErrors, UsersControllerCompleteOnboardingResponse, UsersControllerCompleteOnboardingResponses, UsersControllerDeleteMyAccountData, UsersControllerGetMyAccountDeletionData, UsersControllerGetMyAccountDeletionResponse, UsersControllerDeleteMyAccountErrors, UsersControllerDeleteMyAccountResponse, UsersControllerDeleteMyAccountResponses, UsersControllerDeleteMyAvatarData, UsersControllerDeleteMyAvatarResponse, UsersControllerDeleteMyAvatarResponses, UsersControllerFetchMyTraktPublicHistoryData, UsersControllerFetchMyTraktPublicHistoryErrors, UsersControllerFetchMyTraktPublicHistoryResponse, UsersControllerFetchMyTraktPublicHistoryResponses, UsersControllerGetAvatarData, UsersControllerGetAvatarResponses, UsersControllerGetMyCurrentTraktImportData, UsersControllerGetMyCurrentTraktImportErrors, UsersControllerGetMyCurrentTraktImportResponse, UsersControllerGetMyCurrentTraktImportResponses, UsersControllerGetMySettingsData, UsersControllerGetMySettingsErrors, UsersControllerGetMySettingsResponse, UsersControllerGetMySettingsResponses, UsersControllerGetPublicProfileData, UsersControllerGetPublicProfileErrors, UsersControllerGetPublicProfileResponse, UsersControllerGetPublicProfileResponses, UsersControllerImportMyBlueskyFollowsData, UsersControllerImportMyBlueskyFollowsErrors, UsersControllerImportMyBlueskyFollowsResponse, UsersControllerImportMyBlueskyFollowsResponses, UsersControllerImportMyHistoryData, UsersControllerImportMyHistoryErrors, UsersControllerImportMyHistoryResponse, UsersControllerImportMyHistoryResponses, UsersControllerStartMyTraktImportData, UsersControllerStartMyTraktImportErrors, UsersControllerStartMyTraktImportResponse, UsersControllerStartMyTraktImportResponses, UsersControllerUpdateMyProfileData, UsersControllerUpdateMyProfileErrors, UsersControllerUpdateMyProfileResponse, UsersControllerUpdateMyProfileResponses, UsersControllerUpdateMySettingsData, UsersControllerUpdateMySettingsErrors, UsersControllerUpdateMySettingsResponse, UsersControllerUpdateMySettingsResponses, UsersControllerUploadMyAvatarData, UsersControllerUploadMyAvatarResponse, UsersControllerUploadMyAvatarResponses, UserSettingsDto, WatchHistoryItemDto } from './types.gen';
+6 -1
packages/api/src/generated/sdk.gen.ts
··· 2 2 3 3 import { type Client, formDataBodySerializer, type Options as Options2, type TDataShape } from './client'; 4 4 import { client } from './client.gen'; 5 - import type { AuthControllerBlueskyProfileStatusData, AuthControllerBlueskyProfileStatusErrors, AuthControllerBlueskyProfileStatusResponses, AuthControllerCallbackData, AuthControllerGetClientMetadataData, AuthControllerGetClientMetadataResponses, AuthControllerLoginData, AuthControllerLogoutData, AuthControllerLogoutResponses, AuthControllerMeData, AuthControllerMeErrors, AuthControllerMeResponses, AuthControllerSignupData, AuthControllerSuggestionsData, AuthControllerSuggestionsResponses, ListsControllerAddItemToListData, ListsControllerAddItemToListErrors, ListsControllerAddItemToListResponses, ListsControllerCreateListData, ListsControllerCreateListErrors, ListsControllerCreateListResponses, ListsControllerDeleteListData, ListsControllerDeleteListErrors, ListsControllerDeleteListResponses, ListsControllerGetListData, ListsControllerGetListErrors, ListsControllerGetListResponses, ListsControllerGetListsForItemData, ListsControllerGetListsForItemErrors, ListsControllerGetListsForItemResponses, ListsControllerGetPublicUserListData, ListsControllerGetPublicUserListErrors, ListsControllerGetPublicUserListResponses, ListsControllerGetPublicUserListsData, ListsControllerGetPublicUserListsResponses, ListsControllerGetUserListsData, ListsControllerGetUserListsErrors, ListsControllerGetUserListsResponses, ListsControllerRemoveItemFromListData, ListsControllerRemoveItemFromListErrors, ListsControllerRemoveItemFromListResponses, ListsControllerUpdateListData, ListsControllerUpdateListErrors, ListsControllerUpdateListResponses, MoviesControllerDeleteWatchHistoryEntryData, MoviesControllerDeleteWatchHistoryEntryErrors, MoviesControllerDeleteWatchHistoryEntryResponses, MoviesControllerDiscoverMoviesData, MoviesControllerDiscoverMoviesResponses, MoviesControllerGetMovieData, MoviesControllerGetMovieDetailsData, MoviesControllerGetMovieDetailsResponses, MoviesControllerGetMovieResponses, MoviesControllerGetMovieWatchHistoryData, MoviesControllerGetMovieWatchHistoryErrors, MoviesControllerGetMovieWatchHistoryResponses, MoviesControllerGetUserMoviesData, MoviesControllerGetUserMoviesPaginatedData, MoviesControllerGetUserMoviesPaginatedResponses, MoviesControllerGetUserMoviesResponses, MoviesControllerMarkWatchedData, MoviesControllerMarkWatchedErrors, MoviesControllerMarkWatchedResponses, MoviesControllerSearchMoviesData, MoviesControllerSearchMoviesResponses, MoviesControllerUnmarkWatchedData, MoviesControllerUnmarkWatchedErrors, MoviesControllerUnmarkWatchedResponses, SearchControllerDiscoverAllData, SearchControllerDiscoverAllResponses, SearchControllerSearchAllData, SearchControllerSearchAllResponses, ShelfControllerGetUserActivitySummaryData, ShelfControllerGetUserActivitySummaryResponses, ShelfControllerGetUserShelfData, ShelfControllerGetUserShelfResponses, ShowsControllerDeleteEpisodeWatchHistoryEntryData, ShowsControllerDeleteEpisodeWatchHistoryEntryErrors, ShowsControllerDeleteEpisodeWatchHistoryEntryResponses, ShowsControllerDiscoverShowsData, ShowsControllerDiscoverShowsResponses, ShowsControllerGetEpisodeDetailsData, ShowsControllerGetEpisodeDetailsResponses, ShowsControllerGetLocalEpisodesData, ShowsControllerGetLocalEpisodesResponses, ShowsControllerGetLocalSeasonsData, ShowsControllerGetLocalSeasonsResponses, ShowsControllerGetSeasonDetailsData, ShowsControllerGetSeasonDetailsResponses, ShowsControllerGetShowData, ShowsControllerGetShowDetailsData, ShowsControllerGetShowDetailsResponses, ShowsControllerGetShowResponses, ShowsControllerGetShowWatchHistoryData, ShowsControllerGetShowWatchHistoryErrors, ShowsControllerGetShowWatchHistoryResponses, ShowsControllerGetUserEpisodesPaginatedData, ShowsControllerGetUserEpisodesPaginatedResponses, ShowsControllerGetUserReleaseCalendarData, ShowsControllerGetUserReleaseCalendarResponses, ShowsControllerGetUserShowsData, ShowsControllerGetUserShowsResponses, ShowsControllerGetUserUpNextData, ShowsControllerGetUserUpNextResponses, ShowsControllerMarkSeasonWatchedData, ShowsControllerMarkSeasonWatchedErrors, ShowsControllerMarkSeasonWatchedResponses, ShowsControllerMarkShowWatchedData, ShowsControllerMarkShowWatchedErrors, ShowsControllerMarkShowWatchedResponses, ShowsControllerMarkWatchedData, ShowsControllerMarkWatchedErrors, ShowsControllerMarkWatchedResponses, ShowsControllerSearchShowsData, ShowsControllerSearchShowsResponses, ShowsControllerUnmarkWatchedData, ShowsControllerUnmarkWatchedResponses, SocialControllerFollowData, SocialControllerFollowResponses, SocialControllerGetFeedData, SocialControllerGetFeedResponses, SocialControllerGetFollowersData, SocialControllerGetFollowersResponses, SocialControllerGetFollowingData, SocialControllerGetFollowingResponses, SocialControllerGetRelationshipData, SocialControllerGetRelationshipResponses, SocialControllerGetWatchersData, SocialControllerGetWatchersResponses, SocialControllerSearchPeopleData, SocialControllerSearchPeopleResponses, SocialControllerUnfollowData, SocialControllerUnfollowResponses, UsersControllerCompleteOnboardingData, UsersControllerCompleteOnboardingErrors, UsersControllerCompleteOnboardingResponses, UsersControllerDeleteMyAccountData, UsersControllerDeleteMyAccountErrors, UsersControllerDeleteMyAccountResponses, UsersControllerDeleteMyAvatarData, UsersControllerDeleteMyAvatarResponses, UsersControllerFetchMyTraktPublicHistoryData, UsersControllerFetchMyTraktPublicHistoryErrors, UsersControllerFetchMyTraktPublicHistoryResponses, UsersControllerGetAvatarData, UsersControllerGetAvatarResponses, UsersControllerGetMyCurrentTraktImportData, UsersControllerGetMyCurrentTraktImportErrors, UsersControllerGetMyCurrentTraktImportResponses, UsersControllerGetMySettingsData, UsersControllerGetMySettingsErrors, UsersControllerGetMySettingsResponses, UsersControllerGetPublicProfileData, UsersControllerGetPublicProfileErrors, UsersControllerGetPublicProfileResponses, UsersControllerImportMyBlueskyFollowsData, UsersControllerImportMyBlueskyFollowsErrors, UsersControllerImportMyBlueskyFollowsResponses, UsersControllerImportMyHistoryData, UsersControllerImportMyHistoryErrors, UsersControllerImportMyHistoryResponses, UsersControllerStartMyTraktImportData, UsersControllerStartMyTraktImportErrors, UsersControllerStartMyTraktImportResponses, UsersControllerUpdateMyProfileData, UsersControllerUpdateMyProfileErrors, UsersControllerUpdateMyProfileResponses, UsersControllerUpdateMySettingsData, UsersControllerUpdateMySettingsErrors, UsersControllerUpdateMySettingsResponses, UsersControllerUploadMyAvatarData, UsersControllerUploadMyAvatarResponses } from './types.gen'; 5 + import type { AuthControllerBlueskyProfileStatusData, AuthControllerBlueskyProfileStatusErrors, AuthControllerBlueskyProfileStatusResponses, AuthControllerCallbackData, AuthControllerGetClientMetadataData, AuthControllerGetClientMetadataResponses, AuthControllerLoginData, AuthControllerLogoutData, AuthControllerLogoutResponses, AuthControllerMeData, AuthControllerMeErrors, AuthControllerMeResponses, AuthControllerSignupData, AuthControllerSuggestionsData, AuthControllerSuggestionsResponses, ListsControllerAddItemToListData, ListsControllerAddItemToListErrors, ListsControllerAddItemToListResponses, ListsControllerCreateListData, ListsControllerCreateListErrors, ListsControllerCreateListResponses, ListsControllerDeleteListData, ListsControllerDeleteListErrors, ListsControllerDeleteListResponses, ListsControllerGetListData, ListsControllerGetListErrors, ListsControllerGetListResponses, ListsControllerGetListsForItemData, ListsControllerGetListsForItemErrors, ListsControllerGetListsForItemResponses, ListsControllerGetPublicUserListData, ListsControllerGetPublicUserListErrors, ListsControllerGetPublicUserListResponses, ListsControllerGetPublicUserListsData, ListsControllerGetPublicUserListsResponses, ListsControllerGetUserListsData, ListsControllerGetUserListsErrors, ListsControllerGetUserListsResponses, ListsControllerRemoveItemFromListData, ListsControllerRemoveItemFromListErrors, ListsControllerRemoveItemFromListResponses, ListsControllerUpdateListData, ListsControllerUpdateListErrors, ListsControllerUpdateListResponses, MoviesControllerDeleteWatchHistoryEntryData, MoviesControllerDeleteWatchHistoryEntryErrors, MoviesControllerDeleteWatchHistoryEntryResponses, MoviesControllerDiscoverMoviesData, MoviesControllerDiscoverMoviesResponses, MoviesControllerGetMovieData, MoviesControllerGetMovieDetailsData, MoviesControllerGetMovieDetailsResponses, MoviesControllerGetMovieResponses, MoviesControllerGetMovieWatchHistoryData, MoviesControllerGetMovieWatchHistoryErrors, MoviesControllerGetMovieWatchHistoryResponses, MoviesControllerGetUserMoviesData, MoviesControllerGetUserMoviesPaginatedData, MoviesControllerGetUserMoviesPaginatedResponses, MoviesControllerGetUserMoviesResponses, MoviesControllerMarkWatchedData, MoviesControllerMarkWatchedErrors, MoviesControllerMarkWatchedResponses, MoviesControllerSearchMoviesData, MoviesControllerSearchMoviesResponses, MoviesControllerUnmarkWatchedData, MoviesControllerUnmarkWatchedErrors, MoviesControllerUnmarkWatchedResponses, SearchControllerDiscoverAllData, SearchControllerDiscoverAllResponses, SearchControllerSearchAllData, SearchControllerSearchAllResponses, ShelfControllerGetUserActivitySummaryData, ShelfControllerGetUserActivitySummaryResponses, ShelfControllerGetUserShelfData, ShelfControllerGetUserShelfResponses, ShowsControllerDeleteEpisodeWatchHistoryEntryData, ShowsControllerDeleteEpisodeWatchHistoryEntryErrors, ShowsControllerDeleteEpisodeWatchHistoryEntryResponses, ShowsControllerDiscoverShowsData, ShowsControllerDiscoverShowsResponses, ShowsControllerGetEpisodeDetailsData, ShowsControllerGetEpisodeDetailsResponses, ShowsControllerGetLocalEpisodesData, ShowsControllerGetLocalEpisodesResponses, ShowsControllerGetLocalSeasonsData, ShowsControllerGetLocalSeasonsResponses, ShowsControllerGetSeasonDetailsData, ShowsControllerGetSeasonDetailsResponses, ShowsControllerGetShowData, ShowsControllerGetShowDetailsData, ShowsControllerGetShowDetailsResponses, ShowsControllerGetShowResponses, ShowsControllerGetShowWatchHistoryData, ShowsControllerGetShowWatchHistoryErrors, ShowsControllerGetShowWatchHistoryResponses, ShowsControllerGetUserEpisodesPaginatedData, ShowsControllerGetUserEpisodesPaginatedResponses, ShowsControllerGetUserReleaseCalendarData, ShowsControllerGetUserReleaseCalendarResponses, ShowsControllerGetUserShowsData, ShowsControllerGetUserShowsResponses, ShowsControllerGetUserUpNextData, ShowsControllerGetUserUpNextResponses, ShowsControllerMarkSeasonWatchedData, ShowsControllerMarkSeasonWatchedErrors, ShowsControllerMarkSeasonWatchedResponses, ShowsControllerMarkShowWatchedData, ShowsControllerMarkShowWatchedErrors, ShowsControllerMarkShowWatchedResponses, ShowsControllerMarkWatchedData, ShowsControllerMarkWatchedErrors, ShowsControllerMarkWatchedResponses, ShowsControllerSearchShowsData, ShowsControllerSearchShowsResponses, ShowsControllerUnmarkWatchedData, ShowsControllerUnmarkWatchedResponses, SocialControllerFollowData, SocialControllerFollowResponses, SocialControllerGetFeedData, SocialControllerGetFeedResponses, SocialControllerGetFollowersData, SocialControllerGetFollowersResponses, SocialControllerGetFollowingData, SocialControllerGetFollowingResponses, SocialControllerGetRelationshipData, SocialControllerGetRelationshipResponses, SocialControllerGetWatchersData, SocialControllerGetWatchersResponses, SocialControllerSearchPeopleData, SocialControllerSearchPeopleResponses, SocialControllerUnfollowData, SocialControllerUnfollowResponses, UsersControllerCompleteOnboardingData, UsersControllerCompleteOnboardingErrors, UsersControllerCompleteOnboardingResponses, UsersControllerDeleteMyAccountData, UsersControllerDeleteMyAccountErrors, UsersControllerDeleteMyAccountResponses, UsersControllerDeleteMyAvatarData, UsersControllerDeleteMyAvatarResponses, UsersControllerFetchMyTraktPublicHistoryData, UsersControllerFetchMyTraktPublicHistoryErrors, UsersControllerFetchMyTraktPublicHistoryResponses, UsersControllerGetAvatarData, UsersControllerGetAvatarResponses, UsersControllerGetMyCurrentTraktImportData, UsersControllerGetMyCurrentTraktImportErrors, UsersControllerGetMyCurrentTraktImportResponses, UsersControllerGetMySettingsData, UsersControllerGetMySettingsErrors, UsersControllerGetMySettingsResponses, UsersControllerGetPublicProfileData, UsersControllerGetPublicProfileErrors, UsersControllerGetPublicProfileResponses, UsersControllerImportMyBlueskyFollowsData, UsersControllerImportMyBlueskyFollowsErrors, UsersControllerImportMyBlueskyFollowsResponses, UsersControllerImportMyHistoryData, UsersControllerImportMyHistoryErrors, UsersControllerImportMyHistoryResponses, UsersControllerStartMyTraktImportData, UsersControllerStartMyTraktImportErrors, UsersControllerStartMyTraktImportResponses, UsersControllerUpdateMyProfileData, UsersControllerUpdateMyProfileErrors, UsersControllerUpdateMyProfileResponses, UsersControllerUpdateMySettingsData, UsersControllerUpdateMySettingsErrors, UsersControllerUpdateMySettingsResponses, UsersControllerUploadMyAvatarData, UsersControllerUploadMyAvatarResponses, UsersControllerGetMyAccountDeletionData, UsersControllerGetMyAccountDeletionErrors, UsersControllerGetMyAccountDeletionResponses } from './types.gen'; 6 6 7 7 export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = Options2<TData, ThrowOnError> & { 8 8 /** ··· 294 294 ...options.headers 295 295 } 296 296 }); 297 + 298 + /** 299 + * Get current account deletion job status 300 + */ 301 + export const usersControllerGetMyAccountDeletion = <ThrowOnError extends boolean = false>(options?: Options<UsersControllerGetMyAccountDeletionData, ThrowOnError>) => (options?.client ?? client).get<UsersControllerGetMyAccountDeletionResponses, UsersControllerGetMyAccountDeletionErrors, ThrowOnError>({ url: '/users/me/account-deletion', ...options }); 297 302 298 303 /** 299 304 * Complete onboarding for the current user
+40 -3
packages/api/src/generated/types.gen.ts
··· 544 544 deletePDSData: boolean; 545 545 }; 546 546 547 + export type AccountDeletionJobDto = { 548 + id: string; 549 + status: 'queued' | 'running' | 'completed' | 'failed'; 550 + totalRecords: number; 551 + deletedRecords: number; 552 + currentStep?: string; 553 + lastError?: string; 554 + createdAt: string; 555 + }; 556 + 547 557 export type CompleteOnboardingResponseDto = { 548 558 /** 549 559 * Timestamp when onboarding was completed ··· 1928 1938 */ 1929 1939 401: unknown; 1930 1940 /** 1931 - * Failed to delete OpnShelf data from the user's PDS, so the account was not deleted 1941 + * Account deletion already in progress 1932 1942 */ 1933 - 502: unknown; 1943 + 409: unknown; 1934 1944 }; 1935 1945 1936 1946 export type UsersControllerDeleteMyAccountResponses = { 1937 1947 /** 1938 - * Account deleted successfully 1948 + * PDS deletion requested; returns a job to poll for progress 1949 + */ 1950 + 200: AccountDeletionJobDto; 1951 + /** 1952 + * Account deleted immediately (no PDS deletion) 1939 1953 */ 1940 1954 204: void; 1941 1955 }; 1942 1956 1943 1957 export type UsersControllerDeleteMyAccountResponse = UsersControllerDeleteMyAccountResponses[keyof UsersControllerDeleteMyAccountResponses]; 1958 + 1959 + export type UsersControllerGetMyAccountDeletionData = { 1960 + body?: never; 1961 + path?: never; 1962 + query?: never; 1963 + url: '/users/me/account-deletion'; 1964 + }; 1965 + 1966 + export type UsersControllerGetMyAccountDeletionErrors = { 1967 + /** 1968 + * Not authenticated 1969 + */ 1970 + 401: unknown; 1971 + }; 1972 + 1973 + export type UsersControllerGetMyAccountDeletionResponses = { 1974 + /** 1975 + * Current or most recent account deletion job, or null when none exists 1976 + */ 1977 + 200: AccountDeletionJobDto | null; 1978 + }; 1979 + 1980 + export type UsersControllerGetMyAccountDeletionResponse = UsersControllerGetMyAccountDeletionResponses[keyof UsersControllerGetMyAccountDeletionResponses]; 1944 1981 1945 1982 export type UsersControllerCompleteOnboardingData = { 1946 1983 body?: never;
+8
packages/api/src/index.ts
··· 30 30 getYouTubeThumbnailUrl, 31 31 resolveDetailTrailer, 32 32 } from "./trailer"; 33 + export type { AccountDeletionStatusJob } from "./account-deletion-status"; 34 + export { 35 + getAccountDeletionProgress, 36 + getAccountDeletionStatusMessage, 37 + getAccountDeletionStepLabel, 38 + isActiveAccountDeletionStatus, 39 + isTerminalAccountDeletionStatus, 40 + } from "./account-deletion-status"; 33 41 export type { TraktImportStatusJob } from "./trakt-import-status"; 34 42 export { 35 43 getTraktImportStatusMessage,