Repository: IgnisDa/ryot (language: rust)

Issue:
Allow ordering by random on collection details page
More context: https://discord.com/channels/1239445721502056459/1333001225070968884


Discussion / hints:

Fix patch:
diff --git a/Cargo.lock b/Cargo.lock
index 25ef85eb46..c37b4f4370 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1126,17 +1126,17 @@ version = "0.1.0"
 dependencies = [
  "async-graphql",
  "chrono",
- "common-models",
  "common-utils",
  "config",
  "database-models",
  "dependent-models",
- "itertools 0.14.0",
+ "either",
  "sea-orm",
  "sea-query",
  "serde",
  "serde_json",
  "tracing",
+ "uuid",
 ]
 
 [[package]]
@@ -1723,6 +1723,7 @@ dependencies = [
  "serde_json",
  "serde_with 3.12.0",
  "strum",
+ "uuid",
 ]
 
 [[package]]
@@ -1739,6 +1740,7 @@ dependencies = [
  "database-models",
  "database-utils",
  "dependent-models",
+ "either",
  "enum-models",
  "file-storage-service",
  "fitness-models",
@@ -2355,7 +2357,6 @@ name = "fitness-resolver"
 version = "0.1.0"
 dependencies = [
  "async-graphql",
- "common-models",
  "database-models",
  "dependent-models",
  "fitness-models",
@@ -2884,7 +2885,7 @@ checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba"
 dependencies = [
  "cfg-if",
  "libc",
- "windows",
+ "windows 0.52.0",
 ]
 
 [[package]]
@@ -3124,7 +3125,7 @@ dependencies = [
  "iana-time-zone-haiku",
  "js-sys",
  "wasm-bindgen",
- "windows-core",
+ "windows-core 0.52.0",
 ]
 
 [[package]]
@@ -3611,6 +3612,16 @@ version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
 
+[[package]]
+name = "localzone"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "718530aa7b3842752f82224791ea1db5e6b7260513b8ab45706937dbf54f7b4d"
+dependencies = [
+ "js-sys",
+ "windows 0.54.0",
+]
+
 [[package]]
 name = "lock_api"
 version = "0.4.12"
@@ -3810,6 +3821,7 @@ dependencies = [
  "media-models",
  "miscellaneous-service",
  "traits",
+ "uuid",
 ]
 
 [[package]]
@@ -3827,6 +3839,7 @@ dependencies = [
  "database-utils",
  "dependent-models",
  "dependent-utils",
+ "either",
  "enum-models",
  "futures",
  "itertools 0.14.0",
@@ -4010,6 +4023,15 @@ dependencies = [
  "libm",
 ]
 
+[[package]]
+name = "num_threads"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "oauth2"
 version = "4.4.2"
@@ -5214,10 +5236,11 @@ checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
 [[package]]
 name = "rustypipe"
 version = "0.9.0"
-source = "git+https://codeberg.org/ThetaDev/rustypipe.git?rev=a72029ea5428351d#a72029ea5428351d8f1ae82e255a93c1cc195a98"
+source = "git+https://codeberg.org/ThetaDev/rustypipe.git?rev=19e1428679#19e1428679ae94725cc0381350892307c04fd0d3"
 dependencies = [
  "data-encoding",
  "fancy-regex",
+ "localzone",
  "once_cell",
  "phf",
  "rand 0.8.5",
@@ -6287,7 +6310,6 @@ dependencies = [
  "common-models",
  "common-utils",
  "config",
- "database-models",
  "dependent-models",
  "enum-models",
  "env-utils",
@@ -6501,7 +6523,9 @@ checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21"
 dependencies = [
  "deranged",
  "itoa",
+ "libc",
  "num-conv",
+ "num_threads",
  "powerfmt",
  "serde",
  "time-core",
@@ -7252,7 +7276,17 @@ version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
 dependencies = [
- "windows-core",
+ "windows-core 0.52.0",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows"
+version = "0.54.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49"
+dependencies = [
+ "windows-core 0.54.0",
  "windows-targets 0.52.6",
 ]
 
@@ -7265,17 +7299,36 @@ dependencies = [
  "windows-targets 0.52.6",
 ]
 
+[[package]]
+name = "windows-core"
+version = "0.54.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65"
+dependencies = [
+ "windows-result 0.1.2",
+ "windows-targets 0.52.6",
+]
+
 [[package]]
 name = "windows-registry"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
 dependencies = [
- "windows-result",
+ "windows-result 0.2.0",
  "windows-strings",
  "windows-targets 0.52.6",
 ]
 
+[[package]]
+name = "windows-result"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
 [[package]]
 name = "windows-result"
 version = "0.2.0"
@@ -7291,7 +7344,7 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
 dependencies = [
- "windows-result",
+ "windows-result 0.2.0",
  "windows-targets 0.52.6",
 ]
 
diff --git a/Cargo.toml b/Cargo.toml
index a5c0053458..ec964fd25c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -83,6 +83,7 @@ educe = { version = "=0.6.0", features = [
     "Default",
     "full",
 ], default-features = false }
+either = "=1.13.0"
 enum_meta = "=0.7.0"
 eventsource-stream = "=0.2.3"
 flate2 = "=1.0.35"
@@ -110,7 +111,7 @@ rust_decimal = "=1.36.0"
 rust_decimal_macros = "=1.36.0"
 rust_iso3166 = "=0.1.13"
 # TODO: Update when https://codeberg.org/ThetaDev/rustypipe/issues/25 is merged
-rustypipe = { git = "https://codeberg.org/ThetaDev/rustypipe.git", rev = "a72029ea5428351d" }
+rustypipe = { git = "https://codeberg.org/ThetaDev/rustypipe.git", rev = "19e1428679" }
 schematic = { version = "=0.17.8", features = [
     "config",
     "env",
diff --git a/apps/frontend/app/components/common.tsx b/apps/frontend/app/components/common.tsx
index 1b8569dab3..761092d7d4 100644
--- a/apps/frontend/app/components/common.tsx
+++ b/apps/frontend/app/components/common.tsx
@@ -59,6 +59,7 @@ import {
 } from "@ryot/ts-utils";
 import {
 	IconArrowBigUp,
+	IconArrowsShuffle,
 	IconBarbell,
 	IconCheck,
 	IconEdit,
@@ -1319,3 +1320,41 @@ const UnstyledLink = (props: { children: ReactNode; to: string }) => {
 		</Link>
 	);
 };
+
+export const DisplayListDetailsAndRefresh = (props: {
+	total: number;
+	cacheId: string;
+	rightSection?: ReactNode;
+}) => {
+	const submit = useConfirmSubmit();
+
+	return (
+		<Group justify="space-between" wrap="nowrap">
+			<Box>
+				<Text display="inline" fw="bold">
+					{props.total}
+				</Text>{" "}
+				items found
+				{props.rightSection}
+			</Box>
+			<Form
+				replace
+				method="POST"
+				onSubmit={(e) => submit(e)}
+				action={withQuery($path("/actions"), {
+					intent: "expireCacheKey",
+				})}
+			>
+				<input type="hidden" name="cacheId" value={props.cacheId} />
+				<Button
+					size="xs"
+					type="submit"
+					variant="subtle"
+					leftSection={<IconArrowsShuffle size={20} />}
+				>
+					Refresh
+				</Button>
+			</Form>
+		</Group>
+	);
+};
diff --git a/apps/frontend/app/lib/state/collection.ts b/apps/frontend/app/lib/state/collection.ts
index 2f8baccb82..2bd1975151 100644
--- a/apps/frontend/app/lib/state/collection.ts
+++ b/apps/frontend/app/lib/state/collection.ts
@@ -4,9 +4,9 @@ import {
 	CollectionContentsDocument,
 	EntityLot,
 	MediaLot,
-	MetadataGroupsListDocument,
-	MetadataListDocument,
-	PeopleListDocument,
+	UserMetadataGroupsListDocument,
+	UserMetadataListDocument,
+	UserPeopleListDocument,
 } from "@ryot/generated/graphql/backend/graphql";
 import { isEqual } from "@ryot/ts-utils";
 import { produce } from "immer";
@@ -88,7 +88,7 @@ export const useBulkEditCollection = () => {
 											collectionId: bec.collection.id,
 										},
 									})
-									.then((r) => r.collectionContents.results.items),
+									.then((r) => r.collectionContents.response.results.items),
 							)
 							.with("add", () => {
 								const lot = Object.values(MediaLot).find((ml) =>
@@ -96,9 +96,9 @@ export const useBulkEditCollection = () => {
 								);
 								if (lot)
 									return clientGqlService
-										.request(MetadataListDocument, { input: { lot, take } })
+										.request(UserMetadataListDocument, { input: { lot, take } })
 										.then((r) =>
-											r.metadataList.items.map((m) => ({
+											r.userMetadataList.response.items.map((m) => ({
 												entityId: m,
 												entityLot: EntityLot.Metadata,
 											})),
@@ -109,11 +109,11 @@ export const useBulkEditCollection = () => {
 									)
 								)
 									return clientGqlService
-										.request(PeopleListDocument, {
+										.request(UserPeopleListDocument, {
 											input: { search: { take } },
 										})
 										.then((r) =>
-											r.peopleList.items.map((p) => ({
+											r.userPeopleList.response.items.map((p) => ({
 												entityId: p,
 												entityLot: EntityLot.Person,
 											})),
@@ -124,11 +124,11 @@ export const useBulkEditCollection = () => {
 									)
 								)
 									return clientGqlService
-										.request(MetadataGroupsListDocument, {
+										.request(UserMetadataGroupsListDocument, {
 											input: { search: { take } },
 										})
 										.then((r) =>
-											r.metadataGroupsList.items.map((p) => ({
+											r.userMetadataGroupsList.response.items.map((p) => ({
 												entityId: p,
 												entityLot: EntityLot.MetadataGroup,
 											})),
diff --git a/apps/frontend/app/lib/utilities.server.ts b/apps/frontend/app/lib/utilities.server.ts
index e59b8bb7da..516ad906eb 100644
--- a/apps/frontend/app/lib/utilities.server.ts
+++ b/apps/frontend/app/lib/utilities.server.ts
@@ -197,7 +197,7 @@ export const getUserCollectionsList = async (request: Request) => {
 		UserCollectionsListDocument,
 		{},
 	);
-	return userCollectionsList;
+	return userCollectionsList.response;
 };
 
 export const uploadFileAndGetKey = async (
@@ -383,9 +383,9 @@ export const redirectToFirstPageIfOnInvalidPage = async (
 	currentPage: number,
 ) => {
 	const coreDetails = await getCoreDetails();
-	const { searchParams } = new URL(request.url);
 	const totalPages = Math.ceil(totalResults / coreDetails.pageSize);
 	if (currentPage > totalPages && currentPage !== 1) {
+		const { searchParams } = new URL(request.url);
 		searchParams.set(pageQueryParam, "1");
 		throw redirect(`?${searchParams.toString()}`);
 	}
diff --git a/apps/frontend/app/routes/_dashboard._index.tsx b/apps/frontend/app/routes/_dashboard._index.tsx
index 0f9343f4b2..d293ae9ca2 100644
--- a/apps/frontend/app/routes/_dashboard._index.tsx
+++ b/apps/frontend/app/routes/_dashboard._index.tsx
@@ -11,7 +11,7 @@ import type {
 	LoaderFunctionArgs,
 	MetaArgs,
 } from "@remix-run/node";
-import { useLoaderData, useRevalidator } from "@remix-run/react";
+import { Form, useLoaderData } from "@remix-run/react";
 import {
 	type CalendarEventPartFragment,
 	CollectionContentsDocument,
@@ -29,12 +29,13 @@ import {
 	IconInfoCircle,
 	IconRotateClockwise,
 } from "@tabler/icons-react";
-import { useMutation } from "@tanstack/react-query";
 import CryptoJS from "crypto-js";
 import type { ReactNode } from "react";
+import { $path } from "remix-routes";
 import { ClientOnly } from "remix-utils/client-only";
 import invariant from "tiny-invariant";
 import { match } from "ts-pattern";
+import { withQuery } from "ufo";
 import { useLocalStorage } from "usehooks-ts";
 import {
 	ApplicationGrid,
@@ -43,12 +44,12 @@ import {
 } from "~/components/common";
 import { DisplayCollectionEntity } from "~/components/common";
 import { MetadataDisplayItem } from "~/components/media";
+import { dayjsLib, openConfirmationModal } from "~/lib/generals";
 import {
-	clientGqlService,
-	dayjsLib,
-	openConfirmationModal,
-} from "~/lib/generals";
-import { useCoreDetails, useUserPreferences } from "~/lib/hooks";
+	useConfirmSubmit,
+	useCoreDetails,
+	useUserPreferences,
+} from "~/lib/hooks";
 import {
 	getUserCollectionsList,
 	getUserPreferences,
@@ -66,21 +67,6 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
 	};
 	const takeUpcoming = getTake(DashboardElementLot.Upcoming);
 	const takeInProgress = getTake(DashboardElementLot.InProgress);
-	const getRecommendations = async () => {
-		if (
-			preferences.general.dashboard.find(
-				(de) => de.section === DashboardElementLot.Recommendations,
-			)?.hidden
-		)
-			return [];
-		const { userMetadataRecommendations } =
-			await serverGqlService.authenticatedRequest(
-				request,
-				UserMetadataRecommendationsDocument,
-				{},
-			);
-		return userMetadataRecommendations;
-	};
 	const userCollectionsList = await getUserCollectionsList(request);
 	const foundInProgressCollection = userCollectionsList.find(
 		(c) => c.name === "In Progress",
@@ -88,7 +74,7 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
 	invariant(foundInProgressCollection);
 	const [
 		{ collectionContents: inProgressCollectionContents },
-		userRecommendations,
+		{ userMetadataRecommendations },
 		{ userUpcomingCalendarEvents },
 		{ userAnalytics },
 	] = await Promise.all([
@@ -99,7 +85,11 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
 				collectionId: foundInProgressCollection.id,
 			},
 		}),
-		getRecommendations(),
+		serverGqlService.authenticatedRequest(
+			request,
+			UserMetadataRecommendationsDocument,
+			{},
+		),
 		serverGqlService.authenticatedRequest(
 			request,
 			UserUpcomingCalendarEventsDocument,
@@ -115,8 +105,8 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
 	return {
 		userAnalytics,
 		userUpcomingCalendarEvents,
+		userMetadataRecommendations,
 		inProgressCollectionContents,
-		userRecommendations,
 	};
 };
 
@@ -130,7 +120,6 @@ export default function Page() {
 	const loaderData = useLoaderData<typeof loader>();
 	const coreDetails = useCoreDetails();
 	const userPreferences = useUserPreferences();
-	const revalidator = useRevalidator();
 
 	const dashboardMessage = coreDetails.frontend.dashboardMessage;
 	const latestUserSummary = loaderData.userAnalytics.activities.items.at(0);
@@ -140,18 +129,10 @@ export default function Page() {
 		"false",
 	);
 
-	const refreshUserMetadataRecommendationsMutation = useMutation({
-		onSuccess: revalidator.revalidate,
-		mutationFn: async () =>
-			clientGqlService.request(UserMetadataRecommendationsDocument, {
-				shouldRefresh: true,
-			}),
-	});
-
 	const isDashboardEmpty =
 		loaderData.userUpcomingCalendarEvents.length +
-			loaderData.inProgressCollectionContents.results.items.length +
-			loaderData.userRecommendations.length +
+			loaderData.inProgressCollectionContents.response.results.items.length +
+			loaderData.userMetadataRecommendations.response.length +
 			Number(Boolean(latestUserSummary)) ===
 		0;
 
@@ -194,12 +175,16 @@ export default function Page() {
 							) : null,
 						)
 						.with([DashboardElementLot.InProgress, false], ([v, _]) =>
-							loaderData.inProgressCollectionContents.results.items.length >
-							0 ? (
+							loaderData.inProgressCollectionContents.response.results.items
+								.length > 0 ? (
 								<Section key={v} lot={v}>
-									<SectionTitle text="In Progress" />
+									<SectionTitleWithRefreshIcon
+										bypassConfirm
+										text="In Progress"
+										cacheId={loaderData.inProgressCollectionContents.cacheId}
+									/>
 									<ApplicationGrid>
-										{loaderData.inProgressCollectionContents.results.items.map(
+										{loaderData.inProgressCollectionContents.response.results.items.map(
 											(lm) => (
 												<DisplayCollectionEntity
 													key={lm.entityId}
@@ -214,33 +199,23 @@ export default function Page() {
 						)
 						.with([DashboardElementLot.Recommendations, false], ([v, _]) => (
 							<Section key={v} lot={v}>
-								<Group justify="space-between">
-									<SectionTitle text="Recommendations" />
-									<ActionIcon
-										variant="subtle"
-										loading={
-											refreshUserMetadataRecommendationsMutation.isPending
-										}
-										onClick={() => {
-											openConfirmationModal(
-												"Are you sure you want to refresh the recommendations?",
-												refreshUserMetadataRecommendationsMutation.mutate,
-											);
-										}}
-									>
-										<IconRotateClockwise />
-									</ActionIcon>
-								</Group>
+								<SectionTitleWithRefreshIcon
+									text="Recommendations"
+									cacheId={loaderData.userMetadataRecommendations.cacheId}
+								/>
 								{coreDetails.isServerKeyValidated ? (
 									<ApplicationGrid>
-										{loaderData.userRecommendations.map((lm) => (
-											<MetadataDisplayItem key={lm} metadataId={lm} />
-										))}
+										{loaderData.userMetadataRecommendations.response.map(
+											(lm) => (
+												<MetadataDisplayItem key={lm} metadataId={lm} />
+											),
+										)}
 									</ApplicationGrid>
 								) : (
 									<ProRequiredAlert tooltipLabel="Get new recommendations every hour" />
 								)}
-								{loaderData.userRecommendations.length === 0 ? (
+								{loaderData.userMetadataRecommendations.response.length ===
+								0 ? (
 									<Text c="dimmed">No recommendations available</Text>
 								) : null}
 							</Section>
@@ -262,6 +237,46 @@ export default function Page() {
 	);
 }
 
+const SectionTitleWithRefreshIcon = (props: {
+	text: string;
+	cacheId: string;
+	bypassConfirm?: true;
+}) => {
+	const submit = useConfirmSubmit();
+
+	return (
+		<Group justify="space-between">
+			<SectionTitle text={props.text} />
+			<Form
+				replace
+				method="POST"
+				action={withQuery($path("/actions"), {
+					intent: "expireCacheKey",
+				})}
+			>
+				<input type="hidden" name="cacheId" value={props.cacheId} />
+				<ActionIcon
+					type="submit"
+					variant="subtle"
+					onClick={(e) => {
+						if (props.bypassConfirm) return;
+						const form = e.currentTarget.form;
+						if (form) {
+							e.preventDefault();
+							openConfirmationModal(
+								"Are you sure you want to refresh the recommendations?",
+								() => submit(form),
+							);
+						}
+					}}
+				>
+					<IconRotateClockwise />
+				</ActionIcon>
+			</Form>
+		</Group>
+	);
+};
+
 const SectionTitle = (props: { text: string }) => (
 	<Text fz={{ base: "h2", md: "h1" }} fw="bold">
 		{props.text}
diff --git a/apps/frontend/app/routes/_dashboard.collections.$id._index.tsx b/apps/frontend/app/routes/_dashboard.collections.$id._index.tsx
index ff24402e59..b05f8e9383 100644
--- a/apps/frontend/app/routes/_dashboard.collections.$id._index.tsx
+++ b/apps/frontend/app/routes/_dashboard.collections.$id._index.tsx
@@ -46,6 +46,7 @@ import {
 	ApplicationGrid,
 	DebouncedSearchInput,
 	DisplayCollectionEntity,
+	DisplayListDetailsAndRefresh,
 	FiltersModal,
 	ReviewItemDisplay,
 } from "~/components/common";
@@ -104,14 +105,16 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
 	]);
 	const totalPages = await redirectToFirstPageIfOnInvalidPage(
 		request,
-		collectionContents.results.details.total,
+		collectionContents.response.results.details.total,
 		query[pageQueryParam] || 1,
 	);
 	return { collectionId, query, collectionContents, cookieName, totalPages };
 };
 
 export const meta = ({ data }: MetaArgs<typeof loader>) => {
-	return [{ title: `${data?.collectionContents.details.name} | Ryot` }];
+	return [
+		{ title: `${data?.collectionContents.response.details.name} | Ryot` },
+	];
 };
 
 export default function Page() {
@@ -128,10 +131,11 @@ export default function Page() {
 		filtersModalOpened,
 		{ open: openFiltersModal, close: closeFiltersModal },
 	] = useDisclosure(false);
+	const details = loaderData.collectionContents.response;
 	const colDetails = {
+		name: details.details.name,
 		id: loaderData.collectionId,
-		name: loaderData.collectionContents.details.name,
-		creatorUserId: loaderData.collectionContents.user.id,
+		creatorUserId: details.user.id,
 	};
 	const state = bulkEditingCollection.state;
 
@@ -139,16 +143,13 @@ export default function Page() {
 		<Container>
 			<Stack>
 				<Box>
-					<Title>{loaderData.collectionContents.details.name}</Title>
+					<Title>{details.details.name}</Title>
 					<Text size="sm">
-						{loaderData.collectionContents.results.details.total} items, created
-						by {loaderData.collectionContents.user.name}{" "}
-						{dayjsLib(
-							loaderData.collectionContents.details.createdOn,
-						).fromNow()}
+						{details.totalItems} items, created by {details.user.name}{" "}
+						{dayjsLib(details.details.createdOn).fromNow()}
 					</Text>
 				</Box>
-				<Text>{loaderData.collectionContents.details.description}</Text>
+				<Text>{details.details.description}</Text>
 				<Tabs value={tab} onChange={setTab}>
 					<Tabs.List mb="xs">
 						<Tabs.Tab
@@ -170,7 +171,7 @@ export default function Page() {
 						) : null}
 					</Tabs.List>
 					<Tabs.Panel value="contents">
-						<Stack>
+						<Stack gap="xs">
 							<Group wrap="nowrap">
 								<DebouncedSearchInput
 									initialValue={loaderData.query.query}
@@ -198,9 +199,13 @@ export default function Page() {
 									<FiltersModalForm />
 								</FiltersModal>
 							</Group>
-							{loaderData.collectionContents.results.items.length > 0 ? (
+							<DisplayListDetailsAndRefresh
+								total={details.results.details.total}
+								cacheId={loaderData.collectionContents.cacheId}
+							/>
+							{details.results.items.length > 0 ? (
 								<ApplicationGrid>
-									{loaderData.collectionContents.results.items.map((lm) => {
+									{details.results.items.map((lm) => {
 										const isAdded = bulkEditingCollection.isAdded(lm);
 										return (
 											<DisplayCollectionEntity
@@ -228,7 +233,7 @@ export default function Page() {
 							) : (
 								<Text>You have not added anything this collection</Text>
 							)}
-							{loaderData.collectionContents.details ? (
+							{details.details ? (
 								<Center>
 									<Pagination
 										size="sm"
@@ -247,9 +252,9 @@ export default function Page() {
 								w="100%"
 								onClick={() => {
 									setEntityToReview({
-										entityId: loaderData.collectionId,
 										entityLot: EntityLot.Collection,
-										entityTitle: loaderData.collectionContents.details.name,
+										entityId: loaderData.collectionId,
+										entityTitle: details.details.name,
 									});
 								}}
 							>
@@ -273,9 +278,7 @@ export default function Page() {
 							<Button
 								w="100%"
 								variant="outline"
-								disabled={
-									loaderData.collectionContents.results.details.total === 0
-								}
+								disabled={details.results.details.total === 0}
 								onClick={() => {
 									bulkEditingCollection.start(colDetails, "remove");
 									setTab("contents");
@@ -287,15 +290,15 @@ export default function Page() {
 					</Tabs.Panel>
 					{!userPreferences.general.disableReviews ? (
 						<Tabs.Panel value="reviews">
-							{loaderData.collectionContents.reviews.length > 0 ? (
+							{details.reviews.length > 0 ? (
 								<Stack>
-									{loaderData.collectionContents.reviews.map((r) => (
+									{details.reviews.map((r) => (
 										<ReviewItemDisplay
-											title={loaderData.collectionContents.details.name}
 											review={r}
 											key={r.id}
-											entityId={loaderData.collectionId}
 											entityLot={EntityLot.Collection}
+											entityId={loaderData.collectionId}
+											title={details.details.name}
 										/>
 									))}
 								</Stack>
diff --git a/apps/frontend/app/routes/_dashboard.collections.list.tsx b/apps/frontend/app/routes/_dashboard.collections.list.tsx
index 25a058d5bc..9289e1f79d 100644
--- a/apps/frontend/app/routes/_dashboard.collections.list.tsx
+++ b/apps/frontend/app/routes/_dashboard.collections.list.tsx
@@ -266,7 +266,8 @@ export default function Page() {
 	);
 }
 
-type Collection = UserCollectionsListQuery["userCollectionsList"][number];
+type Collection =
+	UserCollectionsListQuery["userCollectionsList"]["response"][number];
 
 const IMAGES_CONTAINER_WIDTH = 250;
 
@@ -298,7 +299,7 @@ const DisplayCollection = (props: {
 				},
 			);
 			const images = [];
-			for (const content of collectionContents.results.items) {
+			for (const content of collectionContents.response.results.items) {
 				if (images.length === 5) break;
 				if (content.entityLot !== EntityLot.Metadata) continue;
 				const { image } = await queryClient.ensureQueryData(
diff --git a/apps/frontend/app/routes/_dashboard.fitness.$entity.list.tsx b/apps/frontend/app/routes/_dashboard.fitness.$entity.list.tsx
index 5139712a8c..8c0eb310bc 100644
--- a/apps/frontend/app/routes/_dashboard.fitness.$entity.list.tsx
+++ b/apps/frontend/app/routes/_dashboard.fitness.$entity.list.tsx
@@ -10,6 +10,7 @@ import {
 	Flex,
 	Group,
 	Pagination,
+	Select,
 	Skeleton,
 	Stack,
 	Text,
@@ -20,6 +21,9 @@ import { notifications } from "@mantine/notifications";
 import type { LoaderFunctionArgs, MetaArgs } from "@remix-run/node";
 import { Link, useLoaderData } from "@remix-run/react";
 import {
+	GraphqlSortOrder,
+	type UserTemplatesOrWorkoutsListInput,
+	UserTemplatesOrWorkoutsListSortBy,
 	UserWorkoutDetailsDocument,
 	UserWorkoutTemplateDetailsDocument,
 	UserWorkoutTemplatesListDocument,
@@ -31,6 +35,7 @@ import {
 	humanizeDuration,
 	parseParameters,
 	parseSearchQuery,
+	startCase,
 	truncate,
 	zodIntAsString,
 } from "@ryot/ts-utils";
@@ -38,8 +43,11 @@ import {
 	IconChevronDown,
 	IconChevronUp,
 	IconClock,
+	IconFilter,
 	IconPlus,
 	IconRoad,
+	IconSortAscending,
+	IconSortDescending,
 	IconTrophy,
 	IconWeight,
 } from "@tabler/icons-react";
@@ -49,7 +57,11 @@ import { $path } from "remix-routes";
 import invariant from "tiny-invariant";
 import { match } from "ts-pattern";
 import { z } from "zod";
-import { DebouncedSearchInput } from "~/components/common";
+import {
+	DebouncedSearchInput,
+	DisplayListDetailsAndRefresh,
+	FiltersModal,
+} from "~/components/common";
 import {
 	displayDistanceWithUnit,
 	displayWeightWithUnit,
@@ -80,9 +92,18 @@ import {
 	serverGqlService,
 } from "~/lib/utilities.server";
 
+const defaultFilters = {
+	orderBy: GraphqlSortOrder.Desc,
+	sortBy: UserTemplatesOrWorkoutsListSortBy.Time,
+};
+
 const searchParamsSchema = z.object({
 	query: z.string().optional(),
 	[pageQueryParam]: zodIntAsString.default("1"),
+	orderBy: z.nativeEnum(GraphqlSortOrder).default(defaultFilters.orderBy),
+	sortBy: z
+		.nativeEnum(UserTemplatesOrWorkoutsListSortBy)
+		.default(defaultFilters.sortBy),
 });
 
 export type SearchParams = z.infer<typeof searchParamsSchema>;
@@ -95,16 +116,21 @@ export const loader = async ({ params, request }: LoaderFunctionArgs) => {
 	const cookieName = await getEnhancedCookieName(`${entity}.list`, request);
 	await redirectUsingEnhancedCookieSearchParams(request, cookieName);
 	const query = parseSearchQuery(request, searchParamsSchema);
-	const itemList = await match(entity)
+	const input: UserTemplatesOrWorkoutsListInput = {
+		sort: { by: query.sortBy, order: query.orderBy },
+		search: { query: query.query, page: query[pageQueryParam] },
+	};
+	const displayData = await match(entity)
 		.with(FitnessEntity.Workouts, async () => {
 			const { userWorkoutsList } = await serverGqlService.authenticatedRequest(
 				request,
 				UserWorkoutsListDocument,
-				{ input: { page: query[pageQueryParam], query: query.query } },
+				{ input },
 			);
 			return {
-				items: userWorkoutsList.items,
-				details: userWorkoutsList.details,
+				cacheId: userWorkoutsList.cacheId,
+				items: userWorkoutsList.response.items,
+				details: userWorkoutsList.response.details,
 			};
 		})
 		.with(FitnessEntity.Templates, async () => {
@@ -112,20 +138,21 @@ export const loader = async ({ params, request }: LoaderFunctionArgs) => {
 				await serverGqlService.authenticatedRequest(
 					request,
 					UserWorkoutTemplatesListDocument,
-					{ input: { page: query.page, query: query.query } },
+					{ input },
 				);
 			return {
-				items: userWorkoutTemplatesList.items,
-				details: userWorkoutTemplatesList.details,
+				cacheId: userWorkoutTemplatesList.cacheId,
+				items: userWorkoutTemplatesList.response.items,
+				details: userWorkoutTemplatesList.response.details,
 			};
 		})
 		.exhaustive();
 	const totalPages = await redirectToFirstPageIfOnInvalidPage(
 		request,
-		itemList.details.total,
+		displayData.details.total,
 		query[pageQueryParam],
 	);
-	return { query, entity, itemList, cookieName, totalPages };
+	return { query, entity, displayData, cookieName, totalPages };
 };
 
 export const meta = ({ data }: MetaArgs<typeof loader>) => {
@@ -137,6 +164,13 @@ export default function Page() {
 	const coreDetails = useCoreDetails();
 	const [_, { setP }] = useAppSearchParam(loaderData.cookieName);
 	const startWorkout = useGetWorkoutStarter();
+	const [
+		filtersModalOpened,
+		{ open: openFiltersModal, close: closeFiltersModal },
+	] = useDisclosure(false);
+	const isFilterChanged =
+		loaderData.query.sortBy !== defaultFilters.sortBy ||
+		loaderData.query.orderBy !== defaultFilters.orderBy;
 
 	return (
 		<Container size="xs">
@@ -170,14 +204,33 @@ export default function Page() {
 						<IconPlus size={16} />
 					</ActionIcon>
 				</Flex>
-				<DebouncedSearchInput
-					placeholder={`Search for ${loaderData.entity}`}
-					initialValue={loaderData.query.query}
-					enhancedQueryParams={loaderData.cookieName}
-				/>
-				{loaderData.itemList.items.length > 0 ? (
+				<Group wrap="nowrap">
+					<DebouncedSearchInput
+						initialValue={loaderData.query.query}
+						enhancedQueryParams={loaderData.cookieName}
+						placeholder={`Search for ${loaderData.entity}`}
+					/>
+					<ActionIcon
+						onClick={openFiltersModal}
+						color={isFilterChanged ? "blue" : "gray"}
+					>
+						<IconFilter size={24} />
+					</ActionIcon>
+					<FiltersModal
+						opened={filtersModalOpened}
+						cookieName={loaderData.cookieName}
+						closeFiltersModal={closeFiltersModal}
+					>
+						<FiltersModalForm />
+					</FiltersModal>
+				</Group>
+				{loaderData.displayData.items.length > 0 ? (
 					<Stack gap="xs">
-						{loaderData.itemList.items.map((entityId, index) => (
+						<DisplayListDetailsAndRefresh
+							cacheId={loaderData.displayData.cacheId}
+							total={loaderData.displayData.details.total}
+						/>
+						{loaderData.displayData.items.map((entityId, index) => (
 							<DisplayFitnessEntity
 								index={index}
 								key={entityId}
@@ -265,7 +318,7 @@ const DisplayFitnessEntity = (props: { entityId: string; index: number }) => {
 	return (
 		<>
 			{props.index !== 0 ? <Divider /> : null}
-			<Stack gap="xs" ref={parent} px={{ base: "xs", md: "md" }}>
+			<Stack gap="xs" ref={parent} px={{ base: 4 }}>
 				<Group wrap="nowrap" justify="space-between">
 					<Box>
 						<Group wrap="nowrap">
@@ -399,3 +452,37 @@ const ExerciseDisplay = (props: {
 		</Flex>
 	);
 };
+
+const FiltersModalForm = () => {
+	const loaderData = useLoaderData<typeof loader>();
+	const [_, { setP }] = useAppSearchParam(loaderData.cookieName);
+
+	return (
+		<>
+			<Flex gap="xs" align="center">
+				<Select
+					w="100%"
+					defaultValue={loaderData.query.sortBy}
+					onChange={(v) => setP("sortBy", v)}
+					data={Object.values(UserTemplatesOrWorkoutsListSortBy).map((o) => ({
+						value: o.toString(),
+						label: startCase(o.toLowerCase()),
+					}))}
+				/>
+				<ActionIcon
+					onClick={() => {
+						if (loaderData.query.orderBy === GraphqlSortOrder.Asc)
+							setP("orderBy", GraphqlSortOrder.Desc);
+						else setP("orderBy", GraphqlSortOrder.Asc);
+					}}
+				>
+					{loaderData.query.orderBy === GraphqlSortOrder.Asc ? (
+						<IconSortAscending />
+					) : (
+						<IconSortDescending />
+					)}
+				</ActionIcon>
+			</Flex>
+		</>
+	);
+};
diff --git a/apps/frontend/app/routes/_dashboard.fitness.exercises.list.tsx b/apps/frontend/app/routes/_dashboard.fitness.exercises.list.tsx
index fd96a0fff1..e5d15b1efa 100644
--- a/apps/frontend/app/routes/_dashboard.fitness.exercises.list.tsx
+++ b/apps/frontend/app/routes/_dashboard.fitness.exercises.list.tsx
@@ -2,9 +2,7 @@ import {
 	ActionIcon,
 	Affix,
 	Alert,
-	Anchor,
 	Avatar,
-	Box,
 	Center,
 	Checkbox,
 	Container,
@@ -41,8 +39,8 @@ import {
 	ExerciseMechanic,
 	ExerciseMuscle,
 	ExerciseSortBy,
-	ExercisesListDocument,
 	MergeExerciseDocument,
+	UserExercisesListDocument,
 } from "@ryot/generated/graphql/backend/graphql";
 import {
 	getActionIntent,
@@ -65,7 +63,11 @@ import { $path } from "remix-routes";
 import { match } from "ts-pattern";
 import { withQuery } from "ufo";
 import { z } from "zod";
-import { DebouncedSearchInput, FiltersModal } from "~/components/common";
+import {
+	DebouncedSearchInput,
+	DisplayListDetailsAndRefresh,
+	FiltersModal,
+} from "~/components/common";
 import {
 	dayjsLib,
 	getExerciseDetailsPath,
@@ -126,10 +128,10 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
 	const query = parseSearchQuery(request, searchParamsSchema);
 	query.sortBy = query.sortBy ?? defaultFiltersValue.sortBy;
 	query[pageQueryParam] = query[pageQueryParam] ?? 1;
-	const [{ exercisesList }] = await Promise.all([
+	const [{ userExercisesList }] = await Promise.all([
 		serverGqlService.authenticatedRequest(
 			request.clone(),
-			ExercisesListDocument,
+			UserExercisesListDocument,
 			{
 				input: {
 					search: { page: query[pageQueryParam], query: query.query },
@@ -149,10 +151,10 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
 	]);
 	const totalPages = await redirectToFirstPageIfOnInvalidPage(
 		request,
-		exercisesList.details.total,
+		userExercisesList.response.details.total,
 		query[pageQueryParam],
 	);
-	return { query, totalPages, cookieName, exercisesList };
+	return { query, totalPages, cookieName, userExercisesList };
 };
 
 export const meta = (_args: MetaArgs<typeof loader>) => {
@@ -188,7 +190,6 @@ type SelectExercise = { name: string; lot: ExerciseLot };
 export default function Page() {
 	const loaderData = useLoaderData<typeof loader>();
 	const navigate = useNavigate();
-	const coreDetails = useCoreDetails();
 	const userPreferences = useUserPreferences();
 	const [currentWorkout, setCurrentWorkout] = useCurrentWorkout();
 	const isFitnessActionActive = useIsFitnessActionActive();
@@ -215,7 +216,7 @@ export default function Page() {
 
 	return (
 		<Container size="md">
-			<Stack gap="xl">
+			<Stack>
 				<Flex align="center" gap="md">
 					<Title>Exercises</Title>
 					<ActionIcon
@@ -227,100 +228,83 @@ export default function Page() {
 						<IconPlus size={16} />
 					</ActionIcon>
 				</Flex>
-				{coreDetails.exerciseParameters.downloadRequired ? (
-					<Alert icon={<IconAlertCircle />} variant="outline" color="violet">
-						Please deploy a job to download the exercise dataset from the{" "}
-						<Anchor
-							size="sm"
-							component={Link}
-							to={$path("/settings/miscellaneous")}
-						>
-							miscellaneous settings
-						</Anchor>
-						.
+				<Group wrap="nowrap">
+					<DebouncedSearchInput
+						initialValue={loaderData.query.query}
+						enhancedQueryParams={loaderData.cookieName}
+						placeholder="Search for exercises by name or instructions"
+					/>
+					<ActionIcon
+						onClick={openFiltersModal}
+						color={isFilterChanged ? "blue" : "gray"}
+					>
+						<IconFilter size={24} />
+					</ActionIcon>
+					<FiltersModal
+						closeFiltersModal={closeFiltersModal}
+						cookieName={loaderData.cookieName}
+						opened={filtersModalOpened}
+					>
+						<FiltersModalForm />
+					</FiltersModal>
+				</Group>
+				{currentWorkout?.replacingExerciseIdx ? (
+					<Alert icon={<IconAlertCircle />}>
+						You are replacing exercise:{" "}
+						{
+							currentWorkout.exercises[currentWorkout.replacingExerciseIdx]
+								.exerciseId
+						}
 					</Alert>
-				) : (
+				) : null}
+				{mergingExercise ? (
+					<Alert icon={<IconAlertCircle />}>
+						You are merging exercise: {mergingExercise}
+					</Alert>
+				) : null}
+				{loaderData.userExercisesList.response.details.total > 0 ? (
 					<>
-						<Group wrap="nowrap">
-							<DebouncedSearchInput
-								initialValue={loaderData.query.query}
-								enhancedQueryParams={loaderData.cookieName}
-								placeholder="Search for exercises by name or instructions"
-							/>
-							<ActionIcon
-								onClick={openFiltersModal}
-								color={isFilterChanged ? "blue" : "gray"}
-							>
-								<IconFilter size={24} />
-							</ActionIcon>
-							<FiltersModal
-								closeFiltersModal={closeFiltersModal}
-								cookieName={loaderData.cookieName}
-								opened={filtersModalOpened}
-							>
-								<FiltersModalForm />
-							</FiltersModal>
-						</Group>
-						{currentWorkout?.replacingExerciseIdx ? (
-							<Alert icon={<IconAlertCircle />}>
-								You are replacing exercise:{" "}
-								{
-									currentWorkout.exercises[currentWorkout.replacingExerciseIdx]
-										.exerciseId
-								}
-							</Alert>
-						) : null}
-						{mergingExercise ? (
-							<Alert icon={<IconAlertCircle />}>
-								You are merging exercise: {mergingExercise}
-							</Alert>
-						) : null}
-						{loaderData.exercisesList.details.total > 0 ? (
-							<>
-								<Box>
-									<Text display="inline" fw="bold">
-										{loaderData.exercisesList.details.total}
-									</Text>{" "}
-									items found
-									{allowAddingExerciseToWorkout ? (
-										<>
-											{" "}
-											and{" "}
-											<Text display="inline" fw="bold">
-												{selectedExercises.length}
-											</Text>{" "}
-											selected
-										</>
-									) : null}
-								</Box>
-								<SimpleGrid cols={{ md: 2, lg: 3 }}>
-									{loaderData.exercisesList.items.map((exercise) => (
-										<ExerciseItemDisplay
-											key={exercise}
-											exerciseId={exercise}
-											mergingExercise={mergingExercise}
-											setMergingExercise={setMergingExercise}
-											setSelectedExercises={setSelectedExercises}
-											allowAddingExerciseToWorkout={
-												allowAddingExerciseToWorkout
-											}
-										/>
-									))}
-								</SimpleGrid>
-							</>
-						) : (
-							<Text>No information to display</Text>
-						)}
-						<Center>
-							<Pagination
-								size="sm"
-								value={loaderData.query[pageQueryParam]}
-								onChange={(v) => setP(pageQueryParam, v.toString())}
-								total={loaderData.totalPages}
-							/>
-						</Center>
+						<DisplayListDetailsAndRefresh
+							cacheId={loaderData.userExercisesList.cacheId}
+							total={loaderData.userExercisesList.response.details.total}
+							rightSection={
+								allowAddingExerciseToWorkout ? (
+									<>
+										{" "}
+										and{" "}
+										<Text display="inline" fw="bold">
+											{selectedExercises.length}
+										</Text>{" "}
+										selected
+									</>
+								) : null
+							}
+						/>
+						<SimpleGrid cols={{ md: 2, lg: 3 }}>
+							{loaderData.userExercisesList.response.items.map((exercise) => (
+								<ExerciseItemDisplay
+									key={exercise}
+									exerciseId={exercise}
+									mergingExercise={mergingExercise}
+									setMergingExercise={setMergingExercise}
+									setSelectedExercises={setSelectedExercises}
+									allowAddingExerciseToWorkout={allowAddingExerciseToWorkout}
+								/>
+							))}
+						</SimpleGrid>
 					</>
+				) : (
+					<Text>No information to display</Text>
 				)}
+				<Center>
+					<Pagination
+						size="sm"
+						value={loaderData.query[pageQueryParam]}
+						onChange={(v) => setP(pageQueryParam, v.toString())}
+						total={loaderData.totalPages}
+					/>
+				</Center>
+				``
 			</Stack>
 			{allowAddingExerciseToWorkout ? (
 				<Affix position={{ bottom: rem(40), right: rem(30) }}>
diff --git a/apps/frontend/app/routes/_dashboard.media.$action.$lot.tsx b/apps/frontend/app/routes/_dashboard.media.$action.$lot.tsx
index 5c47ecdb08..4fc2591105 100644
--- a/apps/frontend/app/routes/_dashboard.media.$action.$lot.tsx
+++ b/apps/frontend/app/routes/_dashboard.media.$action.$lot.tsx
@@ -32,9 +32,9 @@ import {
 	type MediaLot,
 	MediaSortBy,
 	MediaSource,
-	MetadataListDocument,
 	MetadataSearchDocument,
 	type MetadataSearchQuery,
+	UserMetadataListDocument,
 } from "@ryot/generated/graphql/backend/graphql";
 import {
 	changeCase,
@@ -66,6 +66,7 @@ import {
 	BaseMediaDisplayItem,
 	CollectionsFilter,
 	DebouncedSearchInput,
+	DisplayListDetailsAndRefresh,
 	FiltersModal,
 	ProRequiredAlert,
 } from "~/components/common";
@@ -154,9 +155,9 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
 					.default(defaultFilters.mineGeneralFilter),
 			});
 			const urlParse = parseSearchQuery(request, listSchema);
-			const { metadataList } = await serverGqlService.authenticatedRequest(
+			const { userMetadataList } = await serverGqlService.authenticatedRequest(
 				request,
-				MetadataListDocument,
+				UserMetadataListDocument,
 				{
 					input: {
 						lot,
@@ -175,8 +176,8 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
 				},
 			);
 			return [
-				metadataList.details.total,
-				{ list: metadataList, url: urlParse },
+				userMetadataList.response.details.total,
+				{ list: userMetadataList, url: urlParse },
 				undefined,
 			] as const;
 		})
@@ -340,21 +341,19 @@ export default function Page() {
 								<FiltersModalForm />
 							</FiltersModal>
 						</Group>
-						{loaderData.mediaList.list.details.total > 0 ? (
+						{loaderData.mediaList.list.response.details.total > 0 ? (
 							<>
-								<Box>
-									<Text display="inline" fw="bold">
-										{loaderData.mediaList.list.details.total}
-									</Text>{" "}
-									items found
-								</Box>
+								<DisplayListDetailsAndRefresh
+									cacheId={loaderData.mediaList.list.cacheId}
+									total={loaderData.mediaList.list.response.details.total}
+								/>
 								{(loaderData.mediaList?.url.startDateRange ||
 									loaderData.mediaList?.url.endDateRange) &&
 								!coreDetails.isServerKeyValidated ? (
 									<ProRequiredAlert alertText="Ryot Pro is required to filter by dates" />
 								) : (
 									<ApplicationGrid>
-										{loaderData.mediaList.list.items.map((item) => {
+										{loaderData.mediaList.list.response.items.map((item) => {
 											const becItem = {
 												entityId: item,
 												entityLot: EntityLot.Metadata,
diff --git a/apps/frontend/app/routes/_dashboard.media.groups.$action.tsx b/apps/frontend/app/routes/_dashboard.media.groups.$action.tsx
index 4fd43855dc..6823ba6452 100644
--- a/apps/frontend/app/routes/_dashboard.media.groups.$action.tsx
+++ b/apps/frontend/app/routes/_dashboard.media.groups.$action.tsx
@@ -23,8 +23,8 @@ import {
 	MediaSource,
 	MetadataGroupSearchDocument,
 	type MetadataGroupSearchQuery,
-	MetadataGroupsListDocument,
 	PersonAndMetadataGroupsSortBy,
+	UserMetadataGroupsListDocument,
 } from "@ryot/generated/graphql/backend/graphql";
 import {
 	changeCase,
@@ -52,6 +52,7 @@ import {
 	ApplicationGrid,
 	CollectionsFilter,
 	DebouncedSearchInput,
+	DisplayListDetailsAndRefresh,
 	FiltersModal,
 } from "~/components/common";
 import { BaseMediaDisplayItem } from "~/components/common";
@@ -102,10 +103,10 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
 					.default(defaultFilters.sortBy),
 			});
 			const urlParse = parseSearchQuery(request, listSchema);
-			const { metadataGroupsList } =
+			const { userMetadataGroupsList } =
 				await serverGqlService.authenticatedRequest(
 					request,
-					MetadataGroupsListDocument,
+					UserMetadataGroupsListDocument,
 					{
 						input: {
 							invertCollection: urlParse.invertCollection,
@@ -116,8 +117,8 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
 					},
 				);
 			return [
-				metadataGroupsList.details.total,
-				{ list: metadataGroupsList, url: urlParse },
+				userMetadataGroupsList.response.details.total,
+				{ list: userMetadataGroupsList, url: urlParse },
 				undefined,
 			] as const;
 		})
@@ -213,7 +214,6 @@ export default function Page() {
 						</Tabs.Tab>
 					</Tabs.List>
 				</Tabs>
-
 				<Group wrap="nowrap">
 					<DebouncedSearchInput
 						placeholder="Search for groups"
@@ -256,18 +256,15 @@ export default function Page() {
 						</>
 					) : null}
 				</Group>
-
 				{loaderData.list ? (
 					<>
-						<Box>
-							<Text display="inline" fw="bold">
-								{loaderData.list.list.details.total}
-							</Text>{" "}
-							items found
-						</Box>
-						{loaderData.list.list.details.total > 0 ? (
+						<DisplayListDetailsAndRefresh
+							cacheId={loaderData.list.list.cacheId}
+							total={loaderData.list.list.response.details.total}
+						/>
+						{loaderData.list.list.response.details.total > 0 ? (
 							<ApplicationGrid>
-								{loaderData.list.list.items.map((gr) => {
+								{loaderData.list.list.response.items.map((gr) => {
 									const becItem = {
 										entityId: gr,
 										entityLot: EntityLot.MetadataGroup,
diff --git a/apps/frontend/app/routes/_dashboard.media.people.$action.tsx b/apps/frontend/app/routes/_dashboard.media.people.$action.tsx
index ff41f1dd0d..6072e03d31 100644
--- a/apps/frontend/app/routes/_dashboard.media.people.$action.tsx
+++ b/apps/frontend/app/routes/_dashboard.media.people.$action.tsx
@@ -21,10 +21,10 @@ import {
 	EntityLot,
 	GraphqlSortOrder,
 	MediaSource,
-	PeopleListDocument,
 	PeopleSearchDocument,
 	type PeopleSearchQuery,
 	PersonAndMetadataGroupsSortBy,
+	UserPeopleListDocument,
 } from "@ryot/generated/graphql/backend/graphql";
 import {
 	changeCase,
@@ -50,6 +50,7 @@ import {
 	ApplicationGrid,
 	CollectionsFilter,
 	DebouncedSearchInput,
+	DisplayListDetailsAndRefresh,
 	FiltersModal,
 } from "~/components/common";
 import { BaseMediaDisplayItem } from "~/components/common";
@@ -97,7 +98,7 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
 		[pageQueryParam]: zodIntAsString.default("1"),
 	});
 	const query = parseSearchQuery(request, schema);
-	const [totalResults, peopleList, peopleSearch] = await match(action)
+	const [totalResults, list, search] = await match(action)
 		.with(Action.List, async () => {
 			const listSchema = z.object({
 				collections: zodCommaDelimitedString,
@@ -108,9 +109,9 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
 					.default(defaultFilters.sortBy),
 			});
 			const urlParse = parseSearchQuery(request, listSchema);
-			const { peopleList } = await serverGqlService.authenticatedRequest(
+			const { userPeopleList } = await serverGqlService.authenticatedRequest(
 				request,
-				PeopleListDocument,
+				UserPeopleListDocument,
 				{
 					input: {
 						invertCollection: urlParse.invertCollection,
@@ -121,8 +122,8 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
 				},
 			);
 			return [
-				peopleList.details.total,
-				{ list: peopleList, url: urlParse },
+				userPeopleList.response.details.total,
+				{ list: userPeopleList, url: urlParse },
 				undefined,
 			] as const;
 		})
@@ -156,12 +157,12 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
 		query[pageQueryParam],
 	);
 	return {
+		list,
 		query,
 		action,
-		peopleList,
+		search,
 		totalPages,
 		cookieName,
-		peopleSearch,
 		[pageQueryParam]: query[pageQueryParam],
 	};
 };
@@ -225,9 +226,8 @@ export default function Page() {
 							<ActionIcon
 								onClick={openFiltersModal}
 								color={
-									loaderData.peopleList?.url.orderBy !==
-										defaultFilters.orderBy ||
-									loaderData.peopleList?.url.sortBy !== defaultFilters.sortBy
+									loaderData.list?.url.orderBy !== defaultFilters.orderBy ||
+									loaderData.list?.url.sortBy !== defaultFilters.sortBy
 										? "blue"
 										: "gray"
 								}
@@ -247,34 +247,34 @@ export default function Page() {
 						<>
 							<Select
 								onChange={(v) => setP("source", v)}
-								defaultValue={loaderData.peopleSearch?.url.source}
+								defaultValue={loaderData.search?.url.source}
 								data={coreDetails.peopleSearchSources.map((o) => ({
 									value: o.toString(),
 									label: startCase(o.toLowerCase()),
 								}))}
 							/>
-							{loaderData.peopleSearch?.url.source === MediaSource.Tmdb ? (
+							{loaderData.search?.url.source === MediaSource.Tmdb ? (
 								<Checkbox
 									label="Company"
-									checked={loaderData.peopleSearch?.url.isTmdbCompany}
+									checked={loaderData.search?.url.isTmdbCompany}
 									onChange={(e) =>
 										setP("isTmdbCompany", String(e.target.checked))
 									}
 								/>
 							) : null}
-							{loaderData.peopleSearch?.url.source === MediaSource.Anilist ? (
+							{loaderData.search?.url.source === MediaSource.Anilist ? (
 								<Checkbox
 									label="Studio"
-									checked={loaderData.peopleSearch?.url.isAnilistStudio}
+									checked={loaderData.search?.url.isAnilistStudio}
 									onChange={(e) =>
 										setP("isAnilistStudio", String(e.target.checked))
 									}
 								/>
 							) : null}
-							{loaderData.peopleSearch?.url.source === MediaSource.Hardcover ? (
+							{loaderData.search?.url.source === MediaSource.Hardcover ? (
 								<Checkbox
 									label="Publisher"
-									checked={loaderData.peopleSearch?.url.isHardcoverPublisher}
+									checked={loaderData.search?.url.isHardcoverPublisher}
 									onChange={(e) =>
 										setP("isHardcoverPublisher", String(e.target.checked))
 									}
@@ -283,17 +283,15 @@ export default function Page() {
 						</>
 					) : null}
 				</Group>
-				{loaderData.peopleList ? (
+				{loaderData.list ? (
 					<>
-						<Box>
-							<Text display="inline" fw="bold">
-								{loaderData.peopleList.list.details.total}
-							</Text>{" "}
-							items found
-						</Box>
-						{loaderData.peopleList.list.details.total > 0 ? (
+						<DisplayListDetailsAndRefresh
+							cacheId={loaderData.list.list.cacheId}
+							total={loaderData.list.list.response.details.total}
+						/>
+						{loaderData.list.list.response.details.total > 0 ? (
 							<ApplicationGrid>
-								{loaderData.peopleList.list.items.map((person) => {
+								{loaderData.list.list.response.items.map((person) => {
 									const becItem = {
 										entityId: person,
 										entityLot: EntityLot.Person,
@@ -335,17 +333,17 @@ export default function Page() {
 						</Center>
 					</>
 				) : null}
-				{loaderData.peopleSearch ? (
+				{loaderData.search ? (
 					<>
 						<Box>
 							<Text display="inline" fw="bold">
-								{loaderData.peopleSearch.search.details.total}
+								{loaderData.search.search.details.total}
 							</Text>{" "}
 							items found
 						</Box>
-						{loaderData.peopleSearch.search.details.total > 0 ? (
+						{loaderData.search.search.details.total > 0 ? (
 							<ApplicationGrid>
-								{loaderData.peopleSearch.search.items.map((person) => (
+								{loaderData.search.search.items.map((person) => (
 									<PersonSearchItem item={person} key={person.identifier} />
 								))}
 							</ApplicationGrid>
@@ -385,12 +383,12 @@ const PersonSearchItem = (props: {
 				) : null,
 			}}
 			onImageClickBehavior={async () => {
-				if (loaderData.peopleSearch) {
+				if (loaderData.search) {
 					setIsLoading(true);
 					const id = await commitPerson(
 						props.item.name,
 						props.item.identifier,
-						loaderData.peopleSearch.url,
+						loaderData.search.url,
 					);
 					setIsLoading(false);
 					return navigate($path("/media/people/item/:id", { id }));
@@ -430,7 +428,7 @@ const FiltersModalForm = () => {
 	const loaderData = useLoaderData<typeof loader>();
 	const [_, { setP }] = useAppSearchParam(loaderData.cookieName);
 
-	if (!loaderData.peopleList) return null;
+	if (!loaderData.list) return null;
 
 	return (
 		<>
@@ -441,17 +439,17 @@ const FiltersModalForm = () => {
 						value: o.toString(),
 						label: startCase(o.toLowerCase()),
 					}))}
-					defaultValue={loaderData.peopleList.url.sortBy}
+					defaultValue={loaderData.list.url.sortBy}
 					onChange={(v) => setP("sortBy", v)}
 				/>
 				<ActionIcon
 					onClick={() => {
-						if (loaderData.peopleList?.url.orderBy === GraphqlSortOrder.Asc)
+						if (loaderData.list?.url.orderBy === GraphqlSortOrder.Asc)
 							setP("orderBy", GraphqlSortOrder.Desc);
 						else setP("orderBy", GraphqlSortOrder.Asc);
 					}}
 				>
-					{loaderData.peopleList.url.orderBy === GraphqlSortOrder.Asc ? (
+					{loaderData.list.url.orderBy === GraphqlSortOrder.Asc ? (
 						<IconSortAscending />
 					) : (
 						<IconSortDescending />
@@ -460,8 +458,8 @@ const FiltersModalForm = () => {
 			</Flex>
 			<CollectionsFilter
 				cookieName={loaderData.cookieName}
-				collections={loaderData.peopleList.url.collections}
-				invertCollection={loaderData.peopleList.url.invertCollection}
+				collections={loaderData.list.url.collections}
+				invertCollection={loaderData.list.url.invertCollection}
 			/>
 		</>
 	);
diff --git a/apps/frontend/app/routes/_dashboard.tsx b/apps/frontend/app/routes/_dashboard.tsx
index a0f6e6cf4c..e243825939 100644
--- a/apps/frontend/app/routes/_dashboard.tsx
+++ b/apps/frontend/app/routes/_dashboard.tsx
@@ -1767,7 +1767,8 @@ const ReviewEntityForm = ({
 	);
 };
 
-type Collection = UserCollectionsListQuery["userCollectionsList"][number];
+type Collection =
+	UserCollectionsListQuery["userCollectionsList"]["response"][number];
 
 const AddEntityToCollectionForm = ({
 	closeAddEntityToCollectionModal,
diff --git a/apps/frontend/app/routes/actions.tsx b/apps/frontend/app/routes/actions.tsx
index e759dd5770..465738341d 100644
--- a/apps/frontend/app/routes/actions.tsx
+++ b/apps/frontend/app/routes/actions.tsx
@@ -16,6 +16,7 @@ import {
 	DeleteS3ObjectDocument,
 	DeployBulkProgressUpdateDocument,
 	EntityLot,
+	ExpireCacheKeyDocument,
 	MarkEntityAsPartialDocument,
 	MediaLot,
 	MediaSource,
@@ -490,6 +491,12 @@ export const action = async ({ request }: ActionFunctionArgs) => {
 				}),
 			);
 		})
+		.with("expireCacheKey", async () => {
+			const submission = processSubmission(formData, expireCacheKeySchema);
+			await serverGqlService.request(ExpireCacheKeyDocument, {
+				cacheId: submission.cacheId,
+			});
+		})
 		.run();
 	if (redirectTo) {
 		headers.append("Location", redirectTo.toString());
@@ -591,3 +598,7 @@ const markEntityAsPartialSchema = z.object({
 	entityId: z.string(),
 	entityLot: z.nativeEnum(EntityLot),
 });
+
+const expireCacheKeySchema = z.object({
+	cacheId: z.string().uuid(),
+});
diff --git a/crates/models/common/src/lib.rs b/crates/models/common/src/lib.rs
index 017eeb6dae..af07b21721 100644
--- a/crates/models/common/src/lib.rs
+++ b/crates/models/common/src/lib.rs
@@ -344,24 +344,3 @@ pub struct YoutubeMusicSongListened {
     pub id: String,
     pub listened_on: NaiveDate,
 }
-
-#[skip_serializing_none]
-#[derive(
-    Clone, Hash, Debug, PartialEq, FromJsonQueryResult, Eq, Serialize, Deserialize, Display,
-)]
-pub enum ApplicationCacheKey {
-    CoreDetails,
-    IgdbSettings,
-    TmdbSettings,
-    ListennotesSettings,
-    UserCollectionsList(UserLevelCacheKey<()>),
-    UserAnalyticsParameters(UserLevelCacheKey<()>),
-    UserMetadataRecommendations(UserLevelCacheKey<()>),
-    PeopleSearch(UserLevelCacheKey<PeopleSearchInput>),
-    UserAnalytics(UserLevelCacheKey<UserAnalyticsInput>),
-    MetadataSearch(UserLevelCacheKey<MetadataSearchInput>),
-    MetadataGroupSearch(UserLevelCacheKey<MetadataGroupSearchInput>),
-    ProgressUpdateCache(UserLevelCacheKey<ProgressUpdateCacheInput>),
-    YoutubeMusicSongListened(UserLevelCacheKey<YoutubeMusicSongListened>),
-    MetadataRecentlyConsumed(UserLevelCacheKey<MetadataRecentlyConsumedCacheInput>),
-}
diff --git a/crates/models/database/src/application_cache.rs b/crates/models/database/src/application_cache.rs
index 9df657e762..22245c2357 100644
--- a/crates/models/database/src/application_cache.rs
+++ b/crates/models/database/src/application_cache.rs
@@ -1,6 +1,5 @@
 //! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.1
 
-use common_models::ApplicationCacheKey;
 use sea_orm::entity::prelude::*;
 
 #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
@@ -8,12 +7,10 @@ use sea_orm::entity::prelude::*;
 pub struct Model {
     #[sea_orm(primary_key)]
     pub id: Uuid,
+    pub key: serde_json::Value,
     pub version: Option<String>,
     pub created_at: DateTimeUtc,
     pub expires_at: DateTimeUtc,
-    #[sea_orm(column_type = "Json")]
-    pub key: ApplicationCacheKey,
-    #[sea_orm(column_type = "Json")]
     pub value: serde_json::Value,
 }
 
diff --git a/crates/models/dependent/Cargo.toml b/crates/models/dependent/Cargo.toml
index 6808eab950..77a0e77809 100644
--- a/crates/models/dependent/Cargo.toml
+++ b/crates/models/dependent/Cargo.toml
@@ -20,6 +20,7 @@ serde = { workspace = true }
 serde_json = { workspace = true }
 serde_with = { workspace = true }
 strum = { workspace = true }
+uuid = { workspace = true }
 
 [package.metadata.cargo-machete]
 ignored = ["serde_json"]
diff --git a/crates/models/dependent/src/lib.rs b/crates/models/dependent/src/lib.rs
index b095383886..3b4fc7f477 100644
--- a/crates/models/dependent/src/lib.rs
+++ b/crates/models/dependent/src/lib.rs
@@ -1,10 +1,12 @@
 use std::collections::HashMap;
 
-use async_graphql::{InputObject, OutputType, SimpleObject, Union};
+use async_graphql::{Enum, InputObject, InputType, OutputType, SimpleObject, Union};
 use chrono::NaiveDate;
 use common_models::{
     ApplicationDateRange, BackendError, DailyUserActivitiesResponseGroupedBy,
-    DailyUserActivityHourRecord, PersonSourceSpecifics, SearchDetails,
+    DailyUserActivityHourRecord, MetadataGroupSearchInput, MetadataRecentlyConsumedCacheInput,
+    MetadataSearchInput, PeopleSearchInput, PersonSourceSpecifics, ProgressUpdateCacheInput,
+    SearchDetails, SearchInput, UserAnalyticsInput, UserLevelCacheKey, YoutubeMusicSongListened,
 };
 use config::FrontendConfig;
 use database_models::{
@@ -16,13 +18,17 @@ use enum_models::{
     ExerciseEquipment, ExerciseForce, ExerciseLevel, ExerciseLot, ExerciseMechanic, ExerciseMuscle,
     MediaLot, MediaSource, UserToMediaReason, WorkoutSetPersonalBest,
 };
-use fitness_models::{UserToExerciseHistoryExtraInformation, UserWorkoutInput};
+use fitness_models::{
+    UserExercisesListInput, UserToExerciseHistoryExtraInformation, UserWorkoutInput,
+};
 use importer_models::ImportFailedItem;
 use media_models::{
-    CollectionItem, CreateOrUpdateCollectionInput, EntityWithLot, GenreListItem,
-    GraphqlMediaAssets, ImportOrExportExerciseItem, ImportOrExportMetadataGroupItem,
-    ImportOrExportMetadataItem, ImportOrExportPersonItem, MetadataCreatorGroupedByRole,
-    MetadataGroupSearchItem, MetadataSearchItem, PartialMetadataWithoutId, PeopleSearchItem,
+    CollectionContentsFilter, CollectionContentsSortBy, CollectionItem,
+    CreateOrUpdateCollectionInput, EntityWithLot, GenreListItem, GraphqlMediaAssets,
+    GraphqlSortOrder, ImportOrExportExerciseItem, ImportOrExportMetadataGroupItem,
+    ImportOrExportMetadataItem, ImportOrExportPersonItem, MediaFilter, MediaSortBy,
+    MetadataCreatorGroupedByRole, MetadataGroupSearchItem, MetadataSearchItem,
+    PartialMetadataWithoutId, PeopleSearchItem, PersonAndMetadataGroupsSortBy,
     PersonDetailsGroupedByRole, ReviewItem, UserDetailsError, UserMediaNextEntry,
     UserMetadataDetailsEpisodeProgress, UserMetadataDetailsShowSeasonProgress,
 };
@@ -32,6 +38,7 @@ use sea_orm::{FromJsonQueryResult, FromQueryResult};
 use serde::{Deserialize, Serialize};
 use serde_with::skip_serializing_none;
 use strum::Display;
+use uuid::Uuid;
 
 #[derive(PartialEq, Eq, Default, Serialize, Deserialize, Debug, SimpleObject, Clone)]
 #[graphql(concrete(
@@ -53,6 +60,40 @@ pub struct SearchResults<T: OutputType> {
     pub items: Vec<T>,
 }
 
+#[derive(Debug, PartialEq, Eq, Hash, Serialize, Deserialize, InputObject, Clone, Default)]
+#[graphql(concrete(name = "MediaSortInput", params(MediaSortBy)))]
+#[graphql(concrete(name = "PersonSortInput", params(PersonAndMetadataGroupsSortBy)))]
+#[graphql(concrete(
+    name = "UserWorkoutsListSortInput",
+    params(UserTemplatesOrWorkoutsListSortBy)
+))]
+#[graphql(concrete(name = "CollectionContentsSortInput", params(CollectionContentsSortBy)))]
+pub struct SortInput<T: InputType + Default> {
+    #[graphql(default)]
+    pub by: T,
+    #[graphql(default)]
+    pub order: GraphqlSortOrder,
+}
+
+#[derive(PartialEq, Eq, Default, Serialize, Deserialize, Debug, SimpleObject, Clone)]
+#[graphql(concrete(name = "CachedSearchIdResponse", params(UserMetadataListResponse)))]
+#[graphql(concrete(
+    name = "CachedCollectionsListResponse",
+    params(UserCollectionsListResponse)
+))]
+#[graphql(concrete(
+    name = "CachedCollectionContentsResponse",
+    params(CollectionContentsResponse)
+))]
+#[graphql(concrete(
+    name = "CachedUserMetadataRecommendationsResponse",
+    params(UserMetadataRecommendationsResponse)
+))]
+pub struct CachedResponse<T: OutputType> {
+    pub response: T,
+    pub cache_id: Uuid,
+}
+
 /// Details about a specific exercise item that needs to be exported.
 #[skip_serializing_none]
 #[derive(Debug, Serialize, Deserialize, Clone, Schematic)]
@@ -150,12 +191,13 @@ pub enum UserDetailsResult {
     Error(UserDetailsError),
 }
 
-#[derive(Debug, SimpleObject)]
+#[derive(Debug, SimpleObject, PartialEq, Eq, Serialize, Deserialize, Clone)]
 pub struct CollectionContents {
+    pub total_items: u64,
+    pub user: user::Model,
+    pub reviews: Vec<ReviewItem>,
     pub details: collection::Model,
     pub results: SearchResults<EntityWithLot>,
-    pub reviews: Vec<ReviewItem>,
-    pub user: user::Model,
 }
 
 #[derive(Debug, Serialize, Deserialize, SimpleObject, Clone)]
@@ -205,13 +247,58 @@ pub struct ExerciseFilters {
 
 #[derive(PartialEq, Eq, Debug, Serialize, Deserialize, SimpleObject, Clone)]
 pub struct ExerciseParameters {
-    pub download_required: bool,
     /// All filters applicable to an exercises query.
     pub filters: ExerciseFilters,
     /// Exercise type mapped to the personal bests possible.
     pub lot_mapping: Vec<ExerciseParametersLotMapping>,
 }
 
+#[derive(Debug, Hash, PartialEq, Eq, Clone, Serialize, Deserialize, InputObject)]
+pub struct CollectionContentsInput {
+    pub collection_id: String,
+    pub search: Option<SearchInput>,
+    pub filter: Option<CollectionContentsFilter>,
+    pub sort: Option<SortInput<CollectionContentsSortBy>>,
+}
+
+#[derive(Debug, Hash, PartialEq, Eq, Serialize, Deserialize, InputObject, Clone, Default)]
+pub struct UserMetadataListInput {
+    pub lot: Option<MediaLot>,
+    pub filter: Option<MediaFilter>,
+    pub search: Option<SearchInput>,
+    pub invert_collection: Option<bool>,
+    pub sort: Option<SortInput<MediaSortBy>>,
+}
+
+#[derive(Debug, Hash, PartialEq, Eq, Serialize, Deserialize, InputObject, Clone, Default)]
+pub struct UserPeopleListInput {
+    pub search: Option<SearchInput>,
+    pub filter: Option<MediaFilter>,
+    pub invert_collection: Option<bool>,
+    pub sort: Option<SortInput<PersonAndMetadataGroupsSortBy>>,
+}
+
+#[derive(Debug, Hash, PartialEq, Eq, Serialize, Deserialize, InputObject, Clone, Default)]
+pub struct UserMetadataGroupsListInput {
+    pub search: Option<SearchInput>,
+    pub filter: Option<MediaFilter>,
+    pub invert_collection: Option<bool>,
+    pub sort: Option<SortInput<PersonAndMetadataGroupsSortBy>>,
+}
+
+#[derive(Debug, Hash, Serialize, Deserialize, Enum, Clone, PartialEq, Eq, Copy, Default)]
+pub enum UserTemplatesOrWorkoutsListSortBy {
+    #[default]
+    Time,
+    Random,
+}
+
+#[derive(Debug, Hash, PartialEq, Eq, Serialize, Deserialize, InputObject, Clone, Default)]
+pub struct UserTemplatesOrWorkoutsListInput {
+    pub search: SearchInput,
+    pub sort: Option<SortInput<UserTemplatesOrWorkoutsListSortBy>>,
+}
+
 #[derive(PartialEq, Eq, Debug, SimpleObject, Serialize, Deserialize, Clone)]
 pub struct ProviderLanguageInformation {
     pub source: MediaSource,
@@ -445,12 +532,47 @@ pub struct EmptyCacheValue {
     pub _empty: (),
 }
 
+#[skip_serializing_none]
+#[derive(
+    Clone, Hash, Debug, PartialEq, FromJsonQueryResult, Eq, Serialize, Deserialize, Display,
+)]
+pub enum ApplicationCacheKey {
+    CoreDetails,
+    IgdbSettings,
+    TmdbSettings,
+    ListennotesSettings,
+    UserCollectionsList(UserLevelCacheKey<()>),
+    UserAnalyticsParameters(UserLevelCacheKey<()>),
+    UserMetadataRecommendations(UserLevelCacheKey<()>),
+    PeopleSearch(UserLevelCacheKey<PeopleSearchInput>),
+    UserAnalytics(UserLevelCacheKey<UserAnalyticsInput>),
+    MetadataSearch(UserLevelCacheKey<MetadataSearchInput>),
+    UserPeopleList(UserLevelCacheKey<UserPeopleListInput>),
+    UserMetadataList(UserLevelCacheKey<UserMetadataListInput>),
+    UserExercisesList(UserLevelCacheKey<UserExercisesListInput>),
+    MetadataGroupSearch(UserLevelCacheKey<MetadataGroupSearchInput>),
+    ProgressUpdateCache(UserLevelCacheKey<ProgressUpdateCacheInput>),
+    UserCollectionContents(UserLevelCacheKey<CollectionContentsInput>),
+    YoutubeMusicSongListened(UserLevelCacheKey<YoutubeMusicSongListened>),
+    UserWorkoutsList(UserLevelCacheKey<UserTemplatesOrWorkoutsListInput>),
+    UserMetadataGroupsList(UserLevelCacheKey<UserMetadataGroupsListInput>),
+    UserWorkoutTemplatesList(UserLevelCacheKey<UserTemplatesOrWorkoutsListInput>),
+    MetadataRecentlyConsumed(UserLevelCacheKey<MetadataRecentlyConsumedCacheInput>),
+}
+
 pub type IgdbSettings = String;
 pub type YoutubeMusicSongListenedResponse = bool;
 pub type ListennotesSettings = HashMap<i32, String>;
+pub type UserPeopleListResponse = SearchResults<String>;
+pub type CollectionContentsResponse = CollectionContents;
+pub type UserWorkoutsListResponse = SearchResults<String>;
+pub type UserMetadataListResponse = SearchResults<String>;
 pub type UserCollectionsListResponse = Vec<CollectionItem>;
+pub type UserExercisesListResponse = SearchResults<String>;
 pub type UserMetadataRecommendationsResponse = Vec<String>;
 pub type PeopleSearchResponse = SearchResults<PeopleSearchItem>;
+pub type UserMetadataGroupsListResponse = SearchResults<String>;
+pub type UserWorkoutsTemplatesListResponse = SearchResults<String>;
 pub type MetadataSearchResponse = SearchResults<MetadataSearchItem>;
 pub type MetadataGroupSearchResponse = SearchResults<MetadataGroupSearchItem>;
 
@@ -463,11 +585,23 @@ pub enum ApplicationCacheValue {
     PeopleSearch(PeopleSearchResponse),
     ProgressUpdateCache(EmptyCacheValue),
     MetadataSearch(MetadataSearchResponse),
+    UserPeopleList(UserPeopleListResponse),
     ListennotesSettings(ListennotesSettings),
     MetadataRecentlyConsumed(EmptyCacheValue),
+    UserWorkoutsList(UserWorkoutsListResponse),
+    UserMetadataList(UserMetadataListResponse),
+    UserExercisesList(UserExercisesListResponse),
     UserAnalyticsParameters(ApplicationDateRange),
     UserCollectionsList(UserCollectionsListResponse),
     MetadataGroupSearch(MetadataGroupSearchResponse),
+    UserMetadataGroupsList(UserMetadataGroupsListResponse),
+    UserCollectionContents(Box<CollectionContentsResponse>),
     YoutubeMusicSongListened(YoutubeMusicSongListenedResponse),
+    UserWorkoutTemplatesList(UserWorkoutsTemplatesListResponse),
     UserMetadataRecommendations(UserMetadataRecommendationsResponse),
 }
+
+pub struct GetCacheKeyResponse {
+    pub id: Uuid,
+    pub value: ApplicationCacheValue,
+}
diff --git a/crates/models/fitness/src/lib.rs b/crates/models/fitness/src/lib.rs
index 6335fff4ef..ddd1ee0748 100644
--- a/crates/models/fitness/src/lib.rs
+++ b/crates/models/fitness/src/lib.rs
@@ -652,7 +652,7 @@ pub struct UserWorkoutInput {
     pub supersets: Vec<WorkoutSupersetsInformation>,
 }
 
-#[derive(Debug, Serialize, Deserialize, InputObject, Clone)]
+#[derive(Debug, Hash, PartialEq, Eq, Serialize, Deserialize, InputObject, Clone)]
 pub struct ExerciseListFilter {
     #[graphql(name = "type")]
     pub lot: Option<ExerciseLot>,
@@ -664,16 +664,17 @@ pub struct ExerciseListFilter {
     pub collection: Option<String>,
 }
 
-#[derive(Debug, Serialize, Deserialize, Enum, Clone, PartialEq, Eq, Copy, Default)]
+#[derive(Debug, Hash, Serialize, Deserialize, Enum, Clone, PartialEq, Eq, Copy, Default)]
 pub enum ExerciseSortBy {
     Name,
+    Random,
     #[default]
     LastPerformed,
     TimesPerformed,
 }
 
-#[derive(Debug, Serialize, Deserialize, InputObject, Clone, Default)]
-pub struct ExercisesListInput {
+#[derive(Debug, Hash, PartialEq, Eq, Serialize, Deserialize, InputObject, Clone, Default)]
+pub struct UserExercisesListInput {
     pub search: SearchInput,
     pub sort_by: Option<ExerciseSortBy>,
     pub filter: Option<ExerciseListFilter>,
diff --git a/crates/models/media/src/lib.rs b/crates/models/media/src/lib.rs
index b479e4c4bd..6a4686d96c 100644
--- a/crates/models/media/src/lib.rs
+++ b/crates/models/media/src/lib.rs
@@ -1,11 +1,11 @@
 use std::collections::HashSet;
 
-use async_graphql::{Enum, InputObject, InputType, OneofObject, SimpleObject, Union};
+use async_graphql::{Enum, InputObject, OneofObject, SimpleObject, Union};
 use boilermates::boilermates;
 use chrono::{NaiveDate, NaiveDateTime};
 use common_models::{
     ApplicationDateRange, CollectionExtraInformation, IdAndNamedObject, PersonSourceSpecifics,
-    SearchInput, StoredUrl, StringIdObject,
+    StoredUrl, StringIdObject,
 };
 use common_utils::deserialize_date;
 use enum_models::{
@@ -18,7 +18,7 @@ use sea_orm::{prelude::DateTimeUtc, EnumIter, FromJsonQueryResult, FromQueryResu
 use serde::{Deserialize, Serialize};
 use serde_with::skip_serializing_none;
 
-#[derive(Debug, Default, SimpleObject, Serialize, Deserialize, Clone)]
+#[derive(Debug, PartialEq, Eq, Default, SimpleObject, Serialize, Deserialize, Clone)]
 pub struct EntityWithLot {
     pub entity_id: String,
     pub entity_lot: EntityLot,
@@ -884,7 +884,7 @@ pub struct IntegrationProviderSpecifics {
     pub youtube_music_auth_cookie: Option<String>,
 }
 
-#[derive(Debug, Clone, Serialize, Deserialize, SimpleObject)]
+#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, SimpleObject)]
 pub struct ReviewItem {
     pub id: String,
     pub is_spoiler: bool,
@@ -1134,28 +1134,21 @@ pub struct GenreDetailsInput {
     pub page: Option<u64>,
 }
 
-#[derive(Debug, Serialize, Deserialize, Enum, Clone, PartialEq, Eq, Copy, Default)]
+#[derive(Debug, Serialize, Hash, Deserialize, Enum, Clone, PartialEq, Eq, Copy, Default)]
 pub enum CollectionContentsSortBy {
+    Date,
     Title,
+    Random,
     #[default]
     LastUpdatedOn,
-    Date,
 }
 
-#[derive(Debug, Serialize, Deserialize, InputObject, Clone, Default)]
+#[derive(Debug, Hash, PartialEq, Eq, Clone, Serialize, Deserialize, InputObject, Default)]
 pub struct CollectionContentsFilter {
     pub entity_lot: Option<EntityLot>,
     pub metadata_lot: Option<MediaLot>,
 }
 
-#[derive(Debug, InputObject)]
-pub struct CollectionContentsInput {
-    pub collection_id: String,
-    pub search: Option<SearchInput>,
-    pub filter: Option<CollectionContentsFilter>,
-    pub sort: Option<SortInput<CollectionContentsSortBy>>,
-}
-
 #[derive(Debug, Clone, SimpleObject, FromQueryResult, PartialEq, Eq, Serialize, Deserialize)]
 pub struct CollectionItem {
     pub id: String,
@@ -1254,16 +1247,17 @@ pub struct GraphqlMetadataDetails {
     pub visual_novel_specifics: Option<VisualNovelSpecifics>,
 }
 
-#[derive(Debug, Serialize, Deserialize, Enum, Clone, PartialEq, Eq, Copy, Default)]
+#[derive(Debug, Serialize, Hash, Deserialize, Enum, Clone, PartialEq, Eq, Copy, Default)]
 pub enum GraphqlSortOrder {
-    Desc,
     #[default]
     Asc,
+    Desc,
 }
 
-#[derive(Debug, Serialize, Deserialize, Enum, Clone, PartialEq, Eq, Copy, Default)]
+#[derive(Debug, Hash, Serialize, Deserialize, Enum, Clone, PartialEq, Eq, Copy, Default)]
 pub enum MediaSortBy {
     Title,
+    Random,
     LastSeen,
     UserRating,
     #[default]
@@ -1273,25 +1267,15 @@ pub enum MediaSortBy {
     ProviderRating,
 }
 
-#[derive(Debug, Serialize, Deserialize, Enum, Clone, PartialEq, Eq, Copy, Default)]
+#[derive(Debug, Hash, Serialize, Deserialize, Enum, Clone, PartialEq, Eq, Copy, Default)]
 pub enum PersonAndMetadataGroupsSortBy {
     #[default]
     Name,
+    Random,
     MediaItems,
 }
 
-#[derive(Debug, Serialize, Deserialize, InputObject, Clone, Default)]
-#[graphql(concrete(name = "MediaSortInput", params(MediaSortBy)))]
-#[graphql(concrete(name = "PersonSortInput", params(PersonAndMetadataGroupsSortBy)))]
-#[graphql(concrete(name = "CollectionContentsSortInput", params(CollectionContentsSortBy)))]
-pub struct SortInput<T: InputType + Default> {
-    #[graphql(default)]
-    pub order: GraphqlSortOrder,
-    #[graphql(default)]
-    pub by: T,
-}
-
-#[derive(Debug, Serialize, Deserialize, Enum, Clone, Copy, Eq, PartialEq, Default)]
+#[derive(Debug, Hash, Serialize, Deserialize, Enum, Clone, Copy, Eq, PartialEq, Default)]
 pub enum MediaGeneralFilter {
     #[default]
     All,
@@ -1302,38 +1286,13 @@ pub enum MediaGeneralFilter {
     Unfinished,
 }
 
-#[derive(Debug, Serialize, Deserialize, InputObject, Clone, Default)]
+#[derive(Debug, Hash, PartialEq, Eq, Serialize, Deserialize, InputObject, Clone, Default)]
 pub struct MediaFilter {
     pub collections: Option<Vec<String>>,
     pub general: Option<MediaGeneralFilter>,
     pub date_range: Option<ApplicationDateRange>,
 }
 
-#[derive(Debug, Serialize, Deserialize, InputObject, Clone, Default)]
-pub struct MetadataListInput {
-    pub lot: Option<MediaLot>,
-    pub filter: Option<MediaFilter>,
-    pub search: Option<SearchInput>,
-    pub invert_collection: Option<bool>,
-    pub sort: Option<SortInput<MediaSortBy>>,
-}
-
-#[derive(Debug, Serialize, Deserialize, InputObject, Clone, Default)]
-pub struct PeopleListInput {
-    pub search: Option<SearchInput>,
-    pub filter: Option<MediaFilter>,
-    pub invert_collection: Option<bool>,
-    pub sort: Option<SortInput<PersonAndMetadataGroupsSortBy>>,
-}
-
-#[derive(Debug, Serialize, Deserialize, InputObject, Clone, Default)]
-pub struct MetadataGroupsListInput {
-    pub search: Option<SearchInput>,
-    pub filter: Option<MediaFilter>,
-    pub invert_collection: Option<bool>,
-    pub sort: Option<SortInput<PersonAndMetadataGroupsSortBy>>,
-}
-
 #[derive(Debug, Serialize, Deserialize, InputObject, Clone)]
 pub struct MediaConsumedInput {
     pub identifier: String,
diff --git a/crates/providers/src/igdb.rs b/crates/providers/src/igdb.rs
index 948ce2e897..90c2dc14d0 100644
--- a/crates/providers/src/igdb.rs
+++ b/crates/providers/src/igdb.rs
@@ -4,14 +4,12 @@ use anyhow::{anyhow, Result};
 use application_utils::get_base_http_client;
 use async_trait::async_trait;
 use chrono::Datelike;
-use common_models::{
-    ApplicationCacheKey, IdObject, NamedObject, PersonSourceSpecifics, SearchDetails, StoredUrl,
-};
+use common_models::{IdObject, NamedObject, PersonSourceSpecifics, SearchDetails, StoredUrl};
 use common_utils::{ryot_log, PAGE_SIZE};
 use database_models::metadata_group::MetadataGroupWithoutId;
 use dependent_models::{
-    ApplicationCacheValue, IgdbSettings, MetadataGroupSearchResponse, MetadataPersonRelated,
-    PeopleSearchResponse, PersonDetails, SearchResults,
+    ApplicationCacheKey, ApplicationCacheValue, IgdbSettings, MetadataGroupSearchResponse,
+    MetadataPersonRelated, PeopleSearchResponse, PersonDetails, SearchResults,
 };
 use enum_models::{MediaLot, MediaSource};
 use itertools::Itertools;
@@ -539,7 +537,7 @@ impl IgdbService {
         let maybe_settings = cc
             .get_value::<IgdbSettings>(ApplicationCacheKey::IgdbSettings)
             .await;
-        let access_token = if let Some(value) = maybe_settings {
+        let access_token = if let Some((_id, value)) = maybe_settings {
             value
         } else {
             let access_token = self.get_access_token().await;
diff --git a/crates/providers/src/listennotes.rs b/crates/providers/src/listennotes.rs
index c4101d76ca..1cd115958c 100644
--- a/crates/providers/src/listennotes.rs
+++ b/crates/providers/src/listennotes.rs
@@ -4,9 +4,11 @@ use anyhow::{anyhow, Result};
 use application_utils::get_base_http_client;
 use async_trait::async_trait;
 use chrono::Datelike;
-use common_models::{ApplicationCacheKey, SearchDetails};
+use common_models::SearchDetails;
 use common_utils::{convert_naive_to_utc, PAGE_SIZE};
-use dependent_models::{ApplicationCacheValue, ListennotesSettings, SearchResults};
+use dependent_models::{
+    ApplicationCacheKey, ApplicationCacheValue, ListennotesSettings, SearchResults,
+};
 use enum_models::{MediaLot, MediaSource};
 use itertools::Itertools;
 use media_models::{
@@ -179,7 +181,7 @@ impl ListennotesService {
         let maybe_settings = cc
             .get_value::<ListennotesSettings>(ApplicationCacheKey::ListennotesSettings)
             .await;
-        let genres = if let Some(value) = maybe_settings {
+        let genres = if let Some((_id, value)) = maybe_settings {
             value
         } else {
             #[derive(Debug, Serialize, Deserialize, Default)]
diff --git a/crates/providers/src/tmdb.rs b/crates/providers/src/tmdb.rs
index 09eeb4f4fe..0955de8a62 100644
--- a/crates/providers/src/tmdb.rs
+++ b/crates/providers/src/tmdb.rs
@@ -7,13 +7,11 @@ use anyhow::{anyhow, Result};
 use application_utils::get_base_http_client;
 use async_trait::async_trait;
 use chrono::NaiveDate;
-use common_models::{
-    ApplicationCacheKey, IdObject, NamedObject, PersonSourceSpecifics, SearchDetails, StoredUrl,
-};
+use common_models::{IdObject, NamedObject, PersonSourceSpecifics, SearchDetails, StoredUrl};
 use common_utils::{convert_date_to_year, convert_string_to_date, SHOW_SPECIAL_SEASON_NAMES};
 use database_models::metadata_group::MetadataGroupWithoutId;
 use dependent_models::{
-    ApplicationCacheValue, MetadataGroupSearchResponse, MetadataPersonRelated,
+    ApplicationCacheKey, ApplicationCacheValue, MetadataGroupSearchResponse, MetadataPersonRelated,
     PeopleSearchResponse, PersonDetails, SearchResults, TmdbLanguage, TmdbSettings,
 };
 use enum_models::{MediaLot, MediaSource};
@@ -1283,7 +1281,7 @@ async fn get_settings(
     let maybe_settings = cc
         .get_value::<TmdbSettings>(ApplicationCacheKey::TmdbSettings)
         .await;
-    let tmdb_settings = if let Some(setting) = maybe_settings {
+    let tmdb_settings = if let Some((_id, setting)) = maybe_settings {
         setting
     } else {
         #[derive(Debug, Serialize, Deserialize, Clone)]
diff --git a/crates/resolvers/collection/src/lib.rs b/crates/resolvers/collection/src/lib.rs
index eab96d4a50..94a6bd3722 100644
--- a/crates/resolvers/collection/src/lib.rs
+++ b/crates/resolvers/collection/src/lib.rs
@@ -3,8 +3,11 @@ use std::sync::Arc;
 use async_graphql::{Context, Object, Result};
 use collection_service::CollectionService;
 use common_models::{ChangeCollectionToEntityInput, StringIdObject};
-use dependent_models::{CollectionContents, UserCollectionsListResponse};
-use media_models::{CollectionContentsInput, CreateOrUpdateCollectionInput};
+use dependent_models::{
+    CachedResponse, CollectionContentsInput, CollectionContentsResponse,
+    UserCollectionsListResponse,
+};
+use media_models::CreateOrUpdateCollectionInput;
 use traits::AuthProvider;
 
 #[derive(Default)]
@@ -19,7 +22,7 @@ impl CollectionQuery {
         &self,
         gql_ctx: &Context<'_>,
         name: Option<String>,
-    ) -> Result<UserCollectionsListResponse> {
+    ) -> Result<CachedResponse<UserCollectionsListResponse>> {
         let service = gql_ctx.data_unchecked::<Arc<CollectionService>>();
         let user_id = self.user_id_from_ctx(gql_ctx).await?;
         service.user_collections_list(&user_id, name).await
@@ -30,9 +33,10 @@ impl CollectionQuery {
         &self,
         gql_ctx: &Context<'_>,
         input: CollectionContentsInput,
-    ) -> Result<CollectionContents> {
+    ) -> Result<CachedResponse<CollectionContentsResponse>> {
         let service = gql_ctx.data_unchecked::<Arc<CollectionService>>();
-        service.collection_contents(input).await
+        let user_id = self.user_id_from_ctx(gql_ctx).await?;
+        service.collection_contents(&user_id, input).await
     }
 }
 
diff --git a/crates/resolvers/fitness/Cargo.toml b/crates/resolvers/fitness/Cargo.toml
index d0942eaf5e..fee62b19bf 100644
--- a/crates/resolvers/fitness/Cargo.toml
+++ b/crates/resolvers/fitness/Cargo.toml
@@ -5,7 +5,6 @@ edition = "2021"
 
 [dependencies]
 async-graphql = { workspace = true }
-common-models = { path = "../../models/common" }
 database-models = { path = "../../models/database" }
 dependent-models = { path = "../../models/dependent" }
 fitness-service = { path = "../../services/fitness" }
diff --git a/crates/resolvers/fitness/src/lib.rs b/crates/resolvers/fitness/src/lib.rs
index 639cdee705..666744df68 100644
--- a/crates/resolvers/fitness/src/lib.rs
+++ b/crates/resolvers/fitness/src/lib.rs
@@ -1,14 +1,14 @@
 use std::sync::Arc;
 
 use async_graphql::{Context, Object, Result};
-use common_models::SearchInput;
 use database_models::{exercise, user_measurement};
 use dependent_models::{
-    SearchResults, UpdateCustomExerciseInput, UserExerciseDetails, UserWorkoutDetails,
-    UserWorkoutTemplateDetails,
+    CachedResponse, UpdateCustomExerciseInput, UserExerciseDetails, UserExercisesListResponse,
+    UserTemplatesOrWorkoutsListInput, UserWorkoutDetails, UserWorkoutTemplateDetails,
+    UserWorkoutsListResponse, UserWorkoutsTemplatesListResponse,
 };
 use fitness_models::{
-    ExercisesListInput, UpdateUserExerciseSettings, UpdateUserWorkoutAttributesInput,
+    UpdateUserExerciseSettings, UpdateUserWorkoutAttributesInput, UserExercisesListInput,
     UserMeasurementsListInput, UserWorkoutInput,
 };
 use fitness_service::FitnessService;
@@ -26,8 +26,8 @@ impl FitnessQuery {
     async fn user_workout_templates_list(
         &self,
         gql_ctx: &Context<'_>,
-        input: SearchInput,
-    ) -> Result<SearchResults<String>> {
+        input: UserTemplatesOrWorkoutsListInput,
+    ) -> Result<CachedResponse<UserWorkoutsTemplatesListResponse>> {
         let service = gql_ctx.data_unchecked::<Arc<FitnessService>>();
         let user_id = self.user_id_from_ctx(gql_ctx).await?;
         service.user_workout_templates_list(user_id, input).await
@@ -47,22 +47,22 @@ impl FitnessQuery {
     }
 
     /// Get a paginated list of exercises in the database.
-    async fn exercises_list(
+    async fn user_exercises_list(
         &self,
         gql_ctx: &Context<'_>,
-        input: ExercisesListInput,
-    ) -> Result<SearchResults<String>> {
+        input: UserExercisesListInput,
+    ) -> Result<CachedResponse<UserExercisesListResponse>> {
         let service = gql_ctx.data_unchecked::<Arc<FitnessService>>();
         let user_id = self.user_id_from_ctx(gql_ctx).await?;
-        service.exercises_list(user_id, input).await
+        service.user_exercises_list(user_id, input).await
     }
 
     /// Get a paginated list of workouts done by the user.
     async fn user_workouts_list(
         &self,
         gql_ctx: &Context<'_>,
-        input: SearchInput,
-    ) -> Result<SearchResults<String>> {
+        input: UserTemplatesOrWorkoutsListInput,
+    ) -> Result<CachedResponse<UserWorkoutsListResponse>> {
         let service = gql_ctx.data_unchecked::<Arc<FitnessService>>();
         let user_id = self.user_id_from_ctx(gql_ctx).await?;
         service.user_workouts_list(user_id, input).await
diff --git a/crates/resolvers/miscellaneous/Cargo.toml b/crates/resolvers/miscellaneous/Cargo.toml
index a7e84ef588..b5708b3e88 100644
--- a/crates/resolvers/miscellaneous/Cargo.toml
+++ b/crates/resolvers/miscellaneous/Cargo.toml
@@ -10,3 +10,4 @@ dependent-models = { path = "../../models/dependent" }
 media-models = { path = "../../models/media" }
 miscellaneous-service = { path = "../../services/miscellaneous" }
 traits = { path = "../../traits" }
+uuid = { workspace = true }
diff --git a/crates/resolvers/miscellaneous/src/lib.rs b/crates/resolvers/miscellaneous/src/lib.rs
index 4118390bbc..904d69afe3 100644
--- a/crates/resolvers/miscellaneous/src/lib.rs
+++ b/crates/resolvers/miscellaneous/src/lib.rs
@@ -6,19 +6,22 @@ use common_models::{
     StringIdObject,
 };
 use dependent_models::{
-    CoreDetails, GenreDetails, GraphqlPersonDetails, MetadataGroupDetails,
+    CachedResponse, CoreDetails, GenreDetails, GraphqlPersonDetails, MetadataGroupDetails,
     MetadataGroupSearchResponse, MetadataSearchResponse, PeopleSearchResponse, SearchResults,
-    UserMetadataDetails, UserMetadataGroupDetails, UserPersonDetails,
+    UserMetadataDetails, UserMetadataGroupDetails, UserMetadataGroupsListInput,
+    UserMetadataGroupsListResponse, UserMetadataListInput, UserMetadataListResponse,
+    UserPeopleListInput, UserPeopleListResponse, UserPersonDetails,
 };
 use media_models::{
     CommitMediaInput, CommitPersonInput, CreateCustomMetadataInput, CreateOrUpdateReviewInput,
     CreateReviewCommentInput, GenreDetailsInput, GraphqlCalendarEvent, GraphqlMetadataDetails,
-    GroupedCalendarEvent, MarkEntityAsPartialInput, MetadataGroupsListInput, MetadataListInput,
-    MetadataPartialDetails, PeopleListInput, ProgressUpdateInput, UpdateCustomMetadataInput,
-    UpdateSeenItemInput, UserCalendarEventInput, UserUpcomingCalendarEventInput,
+    GroupedCalendarEvent, MarkEntityAsPartialInput, MetadataPartialDetails, ProgressUpdateInput,
+    UpdateCustomMetadataInput, UpdateSeenItemInput, UserCalendarEventInput,
+    UserUpcomingCalendarEventInput,
 };
 use miscellaneous_service::MiscellaneousService;
 use traits::AuthProvider;
+use uuid::Uuid;
 
 #[derive(Default)]
 pub struct MiscellaneousQuery;
@@ -84,14 +87,14 @@ impl MiscellaneousQuery {
     }
 
     /// Get all the media items related to a user for a specific media type.
-    async fn metadata_list(
+    async fn user_metadata_list(
         &self,
         gql_ctx: &Context<'_>,
-        input: MetadataListInput,
-    ) -> Result<SearchResults<String>> {
+        input: UserMetadataListInput,
+    ) -> Result<CachedResponse<UserMetadataListResponse>> {
         let service = gql_ctx.data_unchecked::<Arc<MiscellaneousService>>();
         let user_id = self.user_id_from_ctx(gql_ctx).await?;
-        service.metadata_list(user_id, input).await
+        service.user_metadata_list(user_id, input).await
     }
 
     /// Search for a list of media for a given type.
@@ -116,14 +119,14 @@ impl MiscellaneousQuery {
     }
 
     /// Get paginated list of metadata groups.
-    async fn metadata_groups_list(
+    async fn user_metadata_groups_list(
         &self,
         gql_ctx: &Context<'_>,
-        input: MetadataGroupsListInput,
-    ) -> Result<SearchResults<String>> {
+        input: UserMetadataGroupsListInput,
+    ) -> Result<CachedResponse<UserMetadataGroupsListResponse>> {
         let service = gql_ctx.data_unchecked::<Arc<MiscellaneousService>>();
         let user_id = self.user_id_from_ctx(gql_ctx).await?;
-        service.metadata_groups_list(user_id, input).await
+        service.user_metadata_groups_list(user_id, input).await
     }
 
     /// Get details that can be displayed to a user for a metadata group.
@@ -184,14 +187,14 @@ impl MiscellaneousQuery {
     }
 
     /// Get paginated list of people.
-    async fn people_list(
+    async fn user_people_list(
         &self,
         gql_ctx: &Context<'_>,
-        input: PeopleListInput,
-    ) -> Result<SearchResults<String>> {
+        input: UserPeopleListInput,
+    ) -> Result<CachedResponse<UserPeopleListResponse>> {
         let service = gql_ctx.data_unchecked::<Arc<MiscellaneousService>>();
         let user_id = self.user_id_from_ctx(gql_ctx).await?;
-        service.people_list(user_id, input).await
+        service.user_people_list(user_id, input).await
     }
 
     /// Search for a list of people from a given source.
@@ -427,6 +430,12 @@ impl MiscellaneousMutation {
         service.mark_entity_as_partial(&user_id, input).await
     }
 
+    /// Expire a cache key by its ID
+    async fn expire_cache_key(&self, gql_ctx: &Context<'_>, cache_id: Uuid) -> Result<bool> {
+        let service = gql_ctx.data_unchecked::<Arc<MiscellaneousService>>();
+        service.expire_cache_key(cache_id).await
+    }
+
     /// Use this mutation to call a function that needs to be tested for implementation.
     /// It is only available in development mode.
     #[cfg(debug_assertions)]
diff --git a/crates/resolvers/user/src/lib.rs b/crates/resolvers/user/src/lib.rs
index 445d95736f..81ebb1e35b 100644
--- a/crates/resolvers/user/src/lib.rs
+++ b/crates/resolvers/user/src/lib.rs
@@ -3,7 +3,7 @@ use std::sync::Arc;
 use async_graphql::{Context, Object, Result};
 use common_models::StringIdObject;
 use database_models::{access_link, integration, notification_platform, user, user_notification};
-use dependent_models::{UserDetailsResult, UserMetadataRecommendationsResponse};
+use dependent_models::{CachedResponse, UserDetailsResult, UserMetadataRecommendationsResponse};
 use media_models::{
     AuthUserInput, CreateAccessLinkInput, CreateUserIntegrationInput,
     CreateUserNotificationPlatformInput, LoginResult, OidcTokenOutput, ProcessAccessLinkInput,
@@ -25,13 +25,10 @@ impl UserQuery {
     async fn user_metadata_recommendations(
         &self,
         gql_ctx: &Context<'_>,
-        should_refresh: Option<bool>,
-    ) -> Result<UserMetadataRecommendationsResponse> {
+    ) -> Result<CachedResponse<UserMetadataRecommendationsResponse>> {
         let service = gql_ctx.data_unchecked::<Arc<UserService>>();
         let user_id = self.user_id_from_ctx(gql_ctx).await?;
-        service
-            .user_metadata_recommendations(&user_id, should_refresh)
-            .await
+        service.user_metadata_recommendations(&user_id).await
     }
 
     /// Get all access links generated by the currently logged in user.
diff --git a/crates/services/cache/Cargo.toml b/crates/services/cache/Cargo.toml
index 29ef320797..5835ec64fc 100644
--- a/crates/services/cache/Cargo.toml
+++ b/crates/services/cache/Cargo.toml
@@ -6,17 +6,17 @@ edition = "2021"
 [dependencies]
 async-graphql = { workspace = true }
 chrono = { workspace = true }
-common-models = { path = "../../models/common" }
 common-utils = { path = "../../utils/common" }
 config = { path = "../../config" }
 database-models = { path = "../../models/database" }
 dependent-models = { path = "../../models/dependent" }
-itertools = { workspace = true }
+either = { workspace = true }
 sea-orm = { workspace = true }
 sea-query = { workspace = true }
 serde = { workspace = true }
 serde_json = { workspace = true }
 tracing = { workspace = true }
+uuid = { workspace = true }
 
 [package.metadata.cargo-machete]
 ignored = ["tracing"]
diff --git a/crates/services/cache/src/lib.rs b/crates/services/cache/src/lib.rs
index be444420ea..84d0a436c0 100644
--- a/crates/services/cache/src/lib.rs
+++ b/crates/services/cache/src/lib.rs
@@ -2,14 +2,14 @@ use std::{collections::HashMap, sync::Arc};
 
 use async_graphql::Result;
 use chrono::{Duration, Utc};
-use common_models::ApplicationCacheKey;
 use common_utils::ryot_log;
 use database_models::{application_cache, prelude::ApplicationCache};
-use dependent_models::ApplicationCacheValue;
-use itertools::Itertools;
+use dependent_models::{ApplicationCacheKey, ApplicationCacheValue, GetCacheKeyResponse};
+use either::Either;
 use sea_orm::{ActiveValue, ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter};
 use sea_query::OnConflict;
 use serde::de::DeserializeOwned;
+use uuid::Uuid;
 
 pub struct CacheService {
     version: String,
@@ -32,13 +32,19 @@ impl CacheService {
         match key {
             ApplicationCacheKey::CoreDetails
             | ApplicationCacheKey::PeopleSearch { .. }
+            | ApplicationCacheKey::UserAnalytics { .. }
+            | ApplicationCacheKey::UserPeopleList { .. }
             | ApplicationCacheKey::MetadataSearch { .. }
+            | ApplicationCacheKey::UserMetadataList { .. }
+            | ApplicationCacheKey::UserWorkoutsList { .. }
+            | ApplicationCacheKey::UserExercisesList { .. }
             | ApplicationCacheKey::MetadataGroupSearch { .. }
+            | ApplicationCacheKey::UserMetadataGroupsList { .. }
+            | ApplicationCacheKey::UserCollectionContents { .. }
+            | ApplicationCacheKey::UserWorkoutTemplatesList { .. }
             | ApplicationCacheKey::MetadataRecentlyConsumed { .. }
             | ApplicationCacheKey::UserMetadataRecommendations { .. } => 1,
 
-            ApplicationCacheKey::UserAnalytics { .. } => 2,
-
             ApplicationCacheKey::UserCollectionsList { .. }
             | ApplicationCacheKey::UserAnalyticsParameters { .. } => 8,
 
@@ -61,56 +67,55 @@ impl CacheService {
     pub async fn set_keys(
         &self,
         items: Vec<(ApplicationCacheKey, ApplicationCacheValue)>,
-    ) -> Result<()> {
+    ) -> Result<HashMap<ApplicationCacheKey, Uuid>> {
         let now = Utc::now();
-        let to_insert = items
-            .into_iter()
-            .map(|(key, value)| {
-                let version = self
-                    .should_respect_version(&key)
-                    .then(|| self.version.to_owned());
-                application_cache::ActiveModel {
-                    created_at: ActiveValue::Set(now),
-                    key: ActiveValue::Set(key.clone()),
-                    version: ActiveValue::Set(version),
-                    value: ActiveValue::Set(serde_json::to_value(value).unwrap()),
-                    expires_at: ActiveValue::Set(
-                        now + Duration::hours(self.get_expiry_for_key(&key)),
-                    ),
-                    ..Default::default()
-                }
-            })
-            .collect_vec();
-        let inserted = ApplicationCache::insert_many(to_insert)
-            .on_conflict(
-                OnConflict::column(application_cache::Column::Key)
-                    .update_columns([
-                        application_cache::Column::Value,
-                        application_cache::Column::Version,
-                        application_cache::Column::ExpiresAt,
-                        application_cache::Column::CreatedAt,
-                    ])
-                    .to_owned(),
-            )
-            .exec(&self.db)
-            .await?;
-        let insert_id = inserted.last_insert_id;
-        ryot_log!(debug, "Inserted application cache with id = {insert_id:?}");
-        Ok(())
+        let mut response = HashMap::new();
+        for (key, value) in items {
+            let version = self
+                .should_respect_version(&key)
+                .then(|| self.version.to_owned());
+            let to_insert = application_cache::ActiveModel {
+                created_at: ActiveValue::Set(now),
+                version: ActiveValue::Set(version),
+                key: ActiveValue::Set(serde_json::to_value(&key).unwrap()),
+                value: ActiveValue::Set(serde_json::to_value(value).unwrap()),
+                expires_at: ActiveValue::Set(now + Duration::hours(self.get_expiry_for_key(&key))),
+                ..Default::default()
+            };
+            let inserted = ApplicationCache::insert(to_insert)
+                .on_conflict(
+                    OnConflict::column(application_cache::Column::Key)
+                        .update_columns([
+                            application_cache::Column::Value,
+                            application_cache::Column::Version,
+                            application_cache::Column::ExpiresAt,
+                            application_cache::Column::CreatedAt,
+                        ])
+                        .to_owned(),
+                )
+                .exec(&self.db)
+                .await?;
+            let insert_id = inserted.last_insert_id;
+            response.insert(key, insert_id);
+        }
+        ryot_log!(debug, "Inserted application caches: {response:?}");
+        Ok(response)
     }
 
     pub async fn set_key(
         &self,
         key: ApplicationCacheKey,
         value: ApplicationCacheValue,
-    ) -> Result<()> {
-        self.set_keys(vec![(key, value)]).await
+    ) -> Result<Uuid> {
+        let response = self.set_keys(vec![(key.clone(), value)]).await?;
+        let uuid = response.get(&key).unwrap().to_owned();
+        Ok(uuid)
     }
 
     pub async fn get_values(
         &self,
         keys: Vec<ApplicationCacheKey>,
-    ) -> Result<HashMap<ApplicationCacheKey, ApplicationCacheValue>> {
+    ) -> Result<HashMap<ApplicationCacheKey, GetCacheKeyResponse>> {
         let caches = ApplicationCache::find()
             .filter(application_cache::Column::Key.is_in(keys))
             .all(&self.db)
@@ -126,22 +131,36 @@ impl CacheService {
                     continue;
                 }
             }
-            values.insert(cache.key, serde_json::from_value(cache.value)?);
+            values.insert(
+                serde_json::from_value(cache.key).unwrap(),
+                GetCacheKeyResponse {
+                    id: cache.id,
+                    value: serde_json::from_value(cache.value)?,
+                },
+            );
         }
         Ok(values)
     }
 
-    pub async fn get_value<T: DeserializeOwned>(&self, key: ApplicationCacheKey) -> Option<T> {
+    pub async fn get_value<T: DeserializeOwned>(
+        &self,
+        key: ApplicationCacheKey,
+    ) -> Option<(Uuid, T)> {
         let caches = self.get_values(vec![key.clone()]).await.ok()?;
-        let db_value = serde_json::to_value(caches.get(&key)?).ok()?;
-        db_value
+        let value = caches.get(&key)?;
+        let db_value = serde_json::to_value(&value.value).ok()?;
+        let db_value = db_value
             .get(key.to_string())
-            .and_then(|v| serde_json::from_value::<T>(v.to_owned()).ok())
+            .and_then(|v| serde_json::from_value::<T>(v.to_owned()).ok())?;
+        Some((value.id, db_value))
     }
 
-    pub async fn expire_key(&self, key: ApplicationCacheKey) -> Result<bool> {
+    pub async fn expire_key(&self, by: Either<ApplicationCacheKey, Uuid>) -> Result<bool> {
         let deleted = ApplicationCache::update_many()
-            .filter(application_cache::Column::Key.eq(key))
+            .filter(match by {
+                Either::Right(id) => application_cache::Column::Id.eq(id),
+                Either::Left(key) => application_cache::Column::Key.eq(key),
+            })
             .set(application_cache::ActiveModel {
                 expires_at: ActiveValue::Set(Utc::now()),
                 ..Default::default()
diff --git a/crates/services/collection/src/lib.rs b/crates/services/collection/src/lib.rs
index 828e89141e..40659d0485 100644
--- a/crates/services/collection/src/lib.rs
+++ b/crates/services/collection/src/lib.rs
@@ -3,8 +3,8 @@ use std::sync::Arc;
 use application_utils::graphql_to_db_order;
 use async_graphql::{Error, Result};
 use common_models::{
-    ApplicationCacheKey, ChangeCollectionToEntityInput, DefaultCollection, SearchDetails,
-    StringIdObject, UserLevelCacheKey,
+    ChangeCollectionToEntityInput, DefaultCollection, SearchDetails, StringIdObject,
+    UserLevelCacheKey,
 };
 use common_utils::PAGE_SIZE;
 use database_models::{
@@ -17,16 +17,16 @@ use database_models::{
 };
 use database_utils::{ilike_sql, item_reviews};
 use dependent_models::{
-    ApplicationCacheValue, CollectionContents, SearchResults, UserCollectionsListResponse,
+    ApplicationCacheKey, ApplicationCacheValue, CachedResponse, CollectionContents,
+    CollectionContentsInput, CollectionContentsResponse, SearchResults,
+    UserCollectionsListResponse,
 };
 use dependent_utils::{
-    add_entity_to_collection, create_or_update_collection, expire_user_collections_list_cache,
-    remove_entity_from_collection,
+    add_entity_to_collection, create_or_update_collection, remove_entity_from_collection,
 };
 use enum_models::EntityLot;
 use media_models::{
-    CollectionContentsInput, CollectionContentsSortBy, CollectionItem,
-    CreateOrUpdateCollectionInput, EntityWithLot,
+    CollectionContentsSortBy, CollectionItem, CreateOrUpdateCollectionInput, EntityWithLot,
 };
 use migrations::{
     AliasedCollection, AliasedCollectionToEntity, AliasedExercise, AliasedMetadata,
@@ -48,14 +48,14 @@ impl CollectionService {
         &self,
         user_id: &String,
         name: Option<String>,
-    ) -> Result<UserCollectionsListResponse> {
+    ) -> Result<CachedResponse<UserCollectionsListResponse>> {
         let cc = &self.0.cache_service;
         let cache_key = ApplicationCacheKey::UserCollectionsList(UserLevelCacheKey {
             input: (),
             user_id: user_id.to_owned(),
         });
-        if let Some(cached) = cc.get_value(cache_key.clone()).await {
-            return Ok(cached);
+        if let Some((cache_id, response)) = cc.get_value(cache_key.clone()).await {
+            return Ok(CachedResponse { cache_id, response });
         }
         let user_jsonb_build_object = PgFunc::json_build_object(vec![
             (
@@ -140,18 +140,34 @@ impl CollectionService {
             .all(&self.0.db)
             .await
             .unwrap();
-        cc.set_key(
-            cache_key,
-            ApplicationCacheValue::UserCollectionsList(response.clone()),
-        )
-        .await?;
-        Ok(response)
+        let cache_id = cc
+            .set_key(
+                cache_key,
+                ApplicationCacheValue::UserCollectionsList(response.clone()),
+            )
+            .await?;
+        Ok(CachedResponse { cache_id, response })
     }
 
     pub async fn collection_contents(
         &self,
+        user_id: &String,
         input: CollectionContentsInput,
-    ) -> Result<CollectionContents> {
+    ) -> Result<CachedResponse<CollectionContentsResponse>> {
+        let cc = &self.0.cache_service;
+        let key = ApplicationCacheKey::UserCollectionContents(UserLevelCacheKey {
+            input: input.clone(),
+            user_id: user_id.to_owned(),
+        });
+        if let Some((id, cached)) = cc
+            .get_value::<CollectionContentsResponse>(key.clone())
+            .await
+        {
+            return Ok(CachedResponse {
+                cache_id: id,
+                response: cached,
+            });
+        }
         let take = input
             .search
             .clone()
@@ -165,134 +181,131 @@ impl CollectionService {
             .one(&self.0.db)
             .await
             .unwrap();
-        let Some(collection) = maybe_collection else {
+        let Some(details) = maybe_collection else {
             return Err(Error::new("Collection not found".to_owned()));
         };
-        let results = if take != 0 {
-            let paginator = CollectionToEntity::find()
-                .left_join(Metadata)
-                .left_join(MetadataGroup)
-                .left_join(Person)
-                .left_join(Exercise)
-                .left_join(Workout)
-                .filter(collection_to_entity::Column::CollectionId.eq(collection.id.clone()))
-                .apply_if(search.query, |query, v| {
-                    query.filter(
-                        Condition::any()
-                            .add(
-                                Expr::col((AliasedMetadata::Table, AliasedMetadata::Title))
-                                    .ilike(ilike_sql(&v)),
-                            )
-                            .add(
-                                Expr::col((
-                                    AliasedMetadataGroup::Table,
-                                    AliasedMetadataGroup::Title,
-                                ))
+        let paginator = CollectionToEntity::find()
+            .left_join(Metadata)
+            .left_join(MetadataGroup)
+            .left_join(Person)
+            .left_join(Exercise)
+            .left_join(Workout)
+            .filter(collection_to_entity::Column::CollectionId.eq(details.id.clone()))
+            .apply_if(search.query, |query, v| {
+                query.filter(
+                    Condition::any()
+                        .add(
+                            Expr::col((AliasedMetadata::Table, AliasedMetadata::Title))
                                 .ilike(ilike_sql(&v)),
-                            )
-                            .add(
-                                Expr::col((AliasedPerson::Table, AliasedPerson::Name))
-                                    .ilike(ilike_sql(&v)),
-                            )
-                            .add(
-                                Expr::col((AliasedExercise::Table, AliasedExercise::Id))
-                                    .ilike(ilike_sql(&v)),
-                            ),
-                    )
-                })
-                .apply_if(filter.metadata_lot, |query, v| {
-                    query.filter(
-                        Condition::any()
-                            .add(Expr::col((AliasedMetadata::Table, AliasedMetadata::Lot)).eq(v)),
-                    )
-                })
-                .apply_if(filter.entity_lot, |query, v| {
-                    let f = match v {
-                        EntityLot::Metadata => {
-                            collection_to_entity::Column::MetadataId.is_not_null()
-                        }
-                        EntityLot::MetadataGroup => {
-                            collection_to_entity::Column::MetadataGroupId.is_not_null()
-                        }
-                        EntityLot::Person => collection_to_entity::Column::PersonId.is_not_null(),
-                        EntityLot::Exercise => {
-                            collection_to_entity::Column::ExerciseId.is_not_null()
-                        }
-                        EntityLot::Workout => collection_to_entity::Column::WorkoutId.is_not_null(),
-                        EntityLot::WorkoutTemplate => {
-                            collection_to_entity::Column::WorkoutTemplateId.is_not_null()
-                        }
-                        EntityLot::Collection | EntityLot::Review | EntityLot::UserMeasurement => {
-                            unreachable!()
-                        }
-                    };
-                    query.filter(f)
-                })
-                .order_by(
-                    match sort.by {
-                        CollectionContentsSortBy::LastUpdatedOn => {
-                            Expr::col(collection_to_entity::Column::LastUpdatedOn)
-                        }
-                        CollectionContentsSortBy::Title => Expr::expr(Func::coalesce([
-                            Expr::col((AliasedMetadata::Table, AliasedMetadata::Title)).into(),
+                        )
+                        .add(
                             Expr::col((AliasedMetadataGroup::Table, AliasedMetadataGroup::Title))
-                                .into(),
-                            Expr::col((AliasedPerson::Table, AliasedPerson::Name)).into(),
-                            Expr::col((AliasedExercise::Table, AliasedExercise::Id)).into(),
-                        ])),
-                        CollectionContentsSortBy::Date => Expr::expr(Func::coalesce([
-                            Expr::col((AliasedMetadata::Table, AliasedMetadata::PublishDate))
-                                .into(),
-                            Expr::col((AliasedPerson::Table, AliasedPerson::BirthDate)).into(),
-                        ])),
-                    },
-                    graphql_to_db_order(sort.order),
+                                .ilike(ilike_sql(&v)),
+                        )
+                        .add(
+                            Expr::col((AliasedPerson::Table, AliasedPerson::Name))
+                                .ilike(ilike_sql(&v)),
+                        )
+                        .add(
+                            Expr::col((AliasedExercise::Table, AliasedExercise::Id))
+                                .ilike(ilike_sql(&v)),
+                        ),
+                )
+            })
+            .apply_if(filter.metadata_lot, |query, v| {
+                query.filter(
+                    Condition::any()
+                        .add(Expr::col((AliasedMetadata::Table, AliasedMetadata::Lot)).eq(v)),
                 )
-                .paginate(&self.0.db, take);
-            let mut items = vec![];
-            let ItemsAndPagesNumber {
-                number_of_items,
-                number_of_pages,
-            } = paginator.num_items_and_pages().await?;
-            for cte in paginator.fetch_page(page - 1).await? {
-                items.push(EntityWithLot {
-                    entity_id: cte.entity_id,
-                    entity_lot: cte.entity_lot,
-                });
-            }
-            SearchResults {
-                details: SearchDetails {
-                    total: number_of_items.try_into().unwrap(),
-                    next_page: if page < number_of_pages {
-                        Some((page + 1).try_into().unwrap())
-                    } else {
-                        None
-                    },
+            })
+            .apply_if(filter.entity_lot, |query, v| {
+                let f = match v {
+                    EntityLot::Metadata => collection_to_entity::Column::MetadataId.is_not_null(),
+                    EntityLot::MetadataGroup => {
+                        collection_to_entity::Column::MetadataGroupId.is_not_null()
+                    }
+                    EntityLot::Person => collection_to_entity::Column::PersonId.is_not_null(),
+                    EntityLot::Exercise => collection_to_entity::Column::ExerciseId.is_not_null(),
+                    EntityLot::Workout => collection_to_entity::Column::WorkoutId.is_not_null(),
+                    EntityLot::WorkoutTemplate => {
+                        collection_to_entity::Column::WorkoutTemplateId.is_not_null()
+                    }
+                    EntityLot::Collection | EntityLot::Review | EntityLot::UserMeasurement => {
+                        unreachable!()
+                    }
+                };
+                query.filter(f)
+            })
+            .order_by(
+                match sort.by {
+                    CollectionContentsSortBy::Random => Expr::expr(Func::random()),
+                    CollectionContentsSortBy::LastUpdatedOn => {
+                        Expr::col(collection_to_entity::Column::LastUpdatedOn)
+                    }
+                    CollectionContentsSortBy::Date => Expr::expr(Func::coalesce([
+                        Expr::col((AliasedMetadata::Table, AliasedMetadata::PublishDate)).into(),
+                        Expr::col((AliasedPerson::Table, AliasedPerson::BirthDate)).into(),
+                    ])),
+                    CollectionContentsSortBy::Title => Expr::expr(Func::coalesce([
+                        Expr::col((AliasedMetadata::Table, AliasedMetadata::Title)).into(),
+                        Expr::col((AliasedMetadataGroup::Table, AliasedMetadataGroup::Title))
+                            .into(),
+                        Expr::col((AliasedPerson::Table, AliasedPerson::Name)).into(),
+                        Expr::col((AliasedExercise::Table, AliasedExercise::Id)).into(),
+                    ])),
                 },
-                items,
-            }
-        } else {
-            SearchResults::default()
+                graphql_to_db_order(sort.order),
+            )
+            .paginate(&self.0.db, take);
+        let mut items = vec![];
+        let ItemsAndPagesNumber {
+            number_of_items,
+            number_of_pages,
+        } = paginator.num_items_and_pages().await?;
+        for cte in paginator.fetch_page(page - 1).await? {
+            items.push(EntityWithLot {
+                entity_id: cte.entity_id,
+                entity_lot: cte.entity_lot,
+            });
+        }
+        let results = SearchResults {
+            details: SearchDetails {
+                total: number_of_items.try_into().unwrap(),
+                next_page: if page < number_of_pages {
+                    Some((page + 1).try_into().unwrap())
+                } else {
+                    None
+                },
+            },
+            items,
         };
-        let user = collection
-            .find_related(User)
-            .one(&self.0.db)
-            .await?
-            .unwrap();
+        let user = details.find_related(User).one(&self.0.db).await?.unwrap();
         let reviews = item_reviews(
-            &collection.user_id,
+            &details.user_id,
             &input.collection_id,
             EntityLot::Collection,
             true,
             &self.0,
         )
         .await?;
-        Ok(CollectionContents {
-            details: collection,
+        let total_items = CollectionToEntity::find()
+            .filter(collection_to_entity::Column::CollectionId.eq(input.collection_id.clone()))
+            .count(&self.0.db)
+            .await?;
+        let response = CollectionContents {
+            user,
             reviews,
             results,
-            user,
-        })
+            details,
+            total_items,
+        };
+        let cache_id = cc
+            .set_key(
+                key,
+                ApplicationCacheValue::UserCollectionContents(Box::new(response.clone())),
+            )
+            .await?;
+        Ok(CachedResponse { response, cache_id })
     }
 
     pub async fn create_or_update_collection(
@@ -316,7 +329,6 @@ impl CollectionService {
             return Ok(false);
         };
         let resp = Collection::delete_by_id(c.id).exec(&self.0.db).await;
-        expire_user_collections_list_cache(&user_id, &self.0).await?;
         Ok(resp.is_ok())
     }
 
diff --git a/crates/services/exporter/src/lib.rs b/crates/services/exporter/src/lib.rs
index 3618bf5754..e041fe18cf 100644
--- a/crates/services/exporter/src/lib.rs
+++ b/crates/services/exporter/src/lib.rs
@@ -13,19 +13,21 @@ use database_utils::{
     entity_in_collections, item_reviews, user_measurements_list, user_workout_details,
     user_workout_template_details,
 };
-use dependent_models::{ImportOrExportWorkoutItem, ImportOrExportWorkoutTemplateItem};
+use dependent_models::{
+    ImportOrExportWorkoutItem, ImportOrExportWorkoutTemplateItem, UserMetadataGroupsListInput,
+    UserMetadataListInput, UserPeopleListInput, UserTemplatesOrWorkoutsListInput,
+};
 use dependent_utils::{
-    exercises_list, metadata_groups_list, metadata_list, people_list, user_workout_templates_list,
-    user_workouts_list,
+    user_exercises_list, user_metadata_groups_list, user_metadata_list, user_people_list,
+    user_workout_templates_list, user_workouts_list,
 };
 use enum_models::EntityLot;
-use fitness_models::{ExercisesListInput, UserMeasurementsListInput};
+use fitness_models::{UserExercisesListInput, UserMeasurementsListInput};
 use itertools::Itertools;
 use media_models::{
     ImportOrExportExerciseItem, ImportOrExportItemRating, ImportOrExportItemReview,
     ImportOrExportMetadataGroupItem, ImportOrExportMetadataItem, ImportOrExportMetadataItemSeen,
-    ImportOrExportPersonItem, MetadataGroupsListInput, MetadataListInput, PeopleListInput,
-    ReviewItem,
+    ImportOrExportPersonItem, ReviewItem,
 };
 use nanoid::nanoid;
 use reqwest::{
@@ -179,9 +181,9 @@ impl ExporterService {
     ) -> Result<()> {
         let mut current_page = 1;
         loop {
-            let related_metadata = metadata_list(
+            let related_metadata = user_metadata_list(
                 user_id,
-                MetadataListInput {
+                UserMetadataListInput {
                     search: Some(SearchInput {
                         take: Some(1000),
                         page: Some(current_page),
@@ -193,7 +195,7 @@ impl ExporterService {
             )
             .await?;
             ryot_log!(debug, "Exporting metadata list page: {current_page}");
-            for rm in related_metadata.items.iter() {
+            for rm in related_metadata.response.items.iter() {
                 let m = Metadata::find_by_id(rm)
                     .one(&self.0.db)
                     .await?
@@ -254,7 +256,7 @@ impl ExporterService {
                 };
                 writer.serialize_value(&exp).unwrap();
             }
-            if let Some(next_page) = related_metadata.details.next_page {
+            if let Some(next_page) = related_metadata.response.details.next_page {
                 current_page = next_page;
             } else {
                 break;
@@ -270,10 +272,10 @@ impl ExporterService {
     ) -> Result<()> {
         let mut current_page = 1;
         loop {
-            let related_metadata = metadata_groups_list(
+            let related_metadata = user_metadata_groups_list(
                 user_id,
                 &self.0,
-                MetadataGroupsListInput {
+                UserMetadataGroupsListInput {
                     search: Some(SearchInput {
                         take: Some(1000),
                         page: Some(current_page),
@@ -284,7 +286,7 @@ impl ExporterService {
             )
             .await?;
             ryot_log!(debug, "Exporting metadata groups list page: {current_page}");
-            for rm in related_metadata.items.iter() {
+            for rm in related_metadata.response.items.iter() {
                 let m = MetadataGroup::find_by_id(rm)
                     .one(&self.0.db)
                     .await?
@@ -311,7 +313,7 @@ impl ExporterService {
                 };
                 writer.serialize_value(&exp).unwrap();
             }
-            if let Some(next_page) = related_metadata.details.next_page {
+            if let Some(next_page) = related_metadata.response.details.next_page {
                 current_page = next_page;
             } else {
                 break;
@@ -327,9 +329,9 @@ impl ExporterService {
     ) -> Result<()> {
         let mut current_page = 1;
         loop {
-            let related_people = people_list(
+            let related_people = user_people_list(
                 user_id,
-                PeopleListInput {
+                UserPeopleListInput {
                     search: Some(SearchInput {
                         take: Some(1000),
                         page: Some(current_page),
@@ -341,7 +343,7 @@ impl ExporterService {
             )
             .await?;
             ryot_log!(debug, "Exporting people list page: {current_page}");
-            for rm in related_people.items.iter() {
+            for rm in related_people.response.items.iter() {
                 let p = Person::find_by_id(rm)
                     .one(&self.0.db)
                     .await?
@@ -367,7 +369,7 @@ impl ExporterService {
                 };
                 writer.serialize_value(&exp).unwrap();
             }
-            if let Some(next_page) = related_people.details.next_page {
+            if let Some(next_page) = related_people.response.details.next_page {
                 current_page = next_page;
             } else {
                 break;
@@ -385,16 +387,19 @@ impl ExporterService {
         loop {
             let workout_ids = user_workouts_list(
                 user_id,
-                SearchInput {
-                    take: Some(1000),
-                    page: Some(current_page),
+                UserTemplatesOrWorkoutsListInput {
+                    search: SearchInput {
+                        take: Some(1000),
+                        page: Some(current_page),
+                        ..Default::default()
+                    },
                     ..Default::default()
                 },
                 &self.0,
             )
             .await?;
             ryot_log!(debug, "Exporting workouts list page: {current_page}");
-            for workout_id in workout_ids.items {
+            for workout_id in workout_ids.response.items {
                 let details = user_workout_details(user_id, workout_id, &self.0).await?;
                 let exp = ImportOrExportWorkoutItem {
                     details: details.details,
@@ -402,7 +407,7 @@ impl ExporterService {
                 };
                 writer.serialize_value(&exp).unwrap();
             }
-            if let Some(next_page) = workout_ids.details.next_page {
+            if let Some(next_page) = workout_ids.response.details.next_page {
                 current_page = next_page;
             } else {
                 break;
@@ -432,9 +437,9 @@ impl ExporterService {
     ) -> Result<()> {
         let mut current_page = 1;
         loop {
-            let exercises = exercises_list(
+            let exercises = user_exercises_list(
                 user_id,
-                ExercisesListInput {
+                UserExercisesListInput {
                     search: SearchInput {
                         take: Some(1000),
                         page: Some(current_page),
@@ -445,7 +450,7 @@ impl ExporterService {
                 &self.0,
             )
             .await?;
-            for exercise_id in exercises.items {
+            for exercise_id in exercises.response.items {
                 let reviews =
                     item_reviews(user_id, &exercise_id, EntityLot::Exercise, false, &self.0)
                         .await?
@@ -473,7 +478,7 @@ impl ExporterService {
                 };
                 writer.serialize_value(&exp).unwrap();
             }
-            if let Some(next_page) = exercises.details.next_page {
+            if let Some(next_page) = exercises.response.details.next_page {
                 current_page = next_page;
             } else {
                 break;
@@ -491,19 +496,22 @@ impl ExporterService {
         loop {
             let workout_template_ids = user_workout_templates_list(
                 user_id,
-                SearchInput {
-                    take: Some(1000),
-                    page: Some(current_page),
+                &self.0,
+                UserTemplatesOrWorkoutsListInput {
+                    search: SearchInput {
+                        take: Some(1000),
+                        page: Some(current_page),
+                        ..Default::default()
+                    },
                     ..Default::default()
                 },
-                &self.0,
             )
             .await?;
             ryot_log!(
                 debug,
                 "Exporting workout templates list page: {current_page}"
             );
-            for workout_template_id in workout_template_ids.items {
+            for workout_template_id in workout_template_ids.response.items {
                 let details =
                     user_workout_template_details(&self.0.db, user_id, workout_template_id).await?;
                 let exp = ImportOrExportWorkoutTemplateItem {
@@ -512,7 +520,7 @@ impl ExporterService {
                 };
                 writer.serialize_value(&exp).unwrap();
             }
-            if let Some(next_page) = workout_template_ids.details.next_page {
+            if let Some(next_page) = workout_template_ids.response.details.next_page {
                 current_page = next_page;
             } else {
                 break;
diff --git a/crates/services/fitness/src/lib.rs b/crates/services/fitness/src/lib.rs
index 4486ed34cc..de34f0ea1e 100644
--- a/crates/services/fitness/src/lib.rs
+++ b/crates/services/fitness/src/lib.rs
@@ -3,7 +3,7 @@ use std::sync::Arc;
 use application_utils::GraphqlRepresentation;
 use async_graphql::{Error, Result};
 use background_models::{ApplicationJob, MpApplicationJob};
-use common_models::{SearchInput, StoredUrl};
+use common_models::StoredUrl;
 use common_utils::ryot_log;
 use database_models::{
     exercise,
@@ -16,19 +16,20 @@ use database_utils::{
     user_workout_template_details,
 };
 use dependent_models::{
-    SearchResults, UpdateCustomExerciseInput, UserExerciseDetails, UserWorkoutDetails,
-    UserWorkoutTemplateDetails,
+    CachedResponse, UpdateCustomExerciseInput, UserExerciseDetails, UserExercisesListResponse,
+    UserTemplatesOrWorkoutsListInput, UserWorkoutDetails, UserWorkoutTemplateDetails,
+    UserWorkoutsListResponse, UserWorkoutsTemplatesListResponse,
 };
 use dependent_utils::{
     create_custom_exercise, create_or_update_user_workout, create_user_measurement,
-    db_workout_to_workout_input, exercises_list, get_focused_workout_summary,
+    db_workout_to_workout_input, get_focused_workout_summary, user_exercises_list,
     user_workout_templates_list, user_workouts_list,
 };
 use enum_models::{EntityLot, ExerciseLot, ExerciseSource};
 use fitness_models::{
-    ExerciseAttributes, ExerciseCategory, ExercisesListInput, GithubExercise,
-    GithubExerciseAttributes, ProcessedExercise, UpdateUserExerciseSettings,
-    UpdateUserWorkoutAttributesInput, UserMeasurementsListInput, UserToExerciseExtraInformation,
+    ExerciseAttributes, ExerciseCategory, GithubExercise, GithubExerciseAttributes,
+    ProcessedExercise, UpdateUserExerciseSettings, UpdateUserWorkoutAttributesInput,
+    UserExercisesListInput, UserMeasurementsListInput, UserToExerciseExtraInformation,
     UserWorkoutInput, WorkoutInformation, WorkoutSetRecord, WorkoutSummary, WorkoutSummaryExercise,
 };
 use futures::TryStreamExt;
@@ -50,9 +51,9 @@ impl FitnessService {
     pub async fn user_workout_templates_list(
         &self,
         user_id: String,
-        input: SearchInput,
-    ) -> Result<SearchResults<String>> {
-        user_workout_templates_list(&user_id, input, &self.0).await
+        input: UserTemplatesOrWorkoutsListInput,
+    ) -> Result<CachedResponse<UserWorkoutsTemplatesListResponse>> {
+        user_workout_templates_list(&user_id, &self.0, input).await
     }
 
     pub async fn user_workout_template_details(
@@ -222,17 +223,17 @@ impl FitnessService {
     pub async fn user_workouts_list(
         &self,
         user_id: String,
-        input: SearchInput,
-    ) -> Result<SearchResults<String>> {
+        input: UserTemplatesOrWorkoutsListInput,
+    ) -> Result<CachedResponse<UserWorkoutsListResponse>> {
         user_workouts_list(&user_id, input, &self.0).await
     }
 
-    pub async fn exercises_list(
+    pub async fn user_exercises_list(
         &self,
         user_id: String,
-        input: ExercisesListInput,
-    ) -> Result<SearchResults<String>> {
-        exercises_list(&user_id, input, &self.0).await
+        input: UserExercisesListInput,
+    ) -> Result<CachedResponse<UserExercisesListResponse>> {
+        user_exercises_list(&user_id, input, &self.0).await
     }
 
     pub async fn deploy_update_exercise_library_job(&self) -> Result<()> {
diff --git a/crates/services/integration/src/yank/youtube_music.rs b/crates/services/integration/src/yank/youtube_music.rs
index 867f794d25..c9bb118809 100644
--- a/crates/services/integration/src/yank/youtube_music.rs
+++ b/crates/services/integration/src/yank/youtube_music.rs
@@ -4,9 +4,11 @@ use anyhow::Result;
 use application_utils::{get_current_date, get_current_time};
 use chrono::{Duration, NaiveDate, NaiveDateTime, Offset, Utc};
 use chrono_tz::Tz;
-use common_models::{ApplicationCacheKey, UserLevelCacheKey, YoutubeMusicSongListened};
+use common_models::{UserLevelCacheKey, YoutubeMusicSongListened};
 use common_utils::TEMP_DIR;
-use dependent_models::{ApplicationCacheValue, ImportCompletedItem, ImportResult};
+use dependent_models::{
+    ApplicationCacheKey, ApplicationCacheValue, ImportCompletedItem, ImportResult,
+};
 use enum_models::{MediaLot, MediaSource};
 use media_models::{ImportOrExportMetadataItem, ImportOrExportMetadataItemSeen};
 use rust_decimal_macros::dec;
@@ -86,7 +88,10 @@ pub async fn yank_progress(
         .cache_service
         .get_values(cache_keys.values().cloned().collect())
         .await
-        .unwrap_or_default();
+        .unwrap_or_default()
+        .into_iter()
+        .map(|(k, v)| (k, v.value))
+        .collect::<HashMap<_, _>>();
     let mut result = ImportResult::default();
     let mut items_to_cache = vec![];
     for (song_id, name) in songs_listened_to_today {
diff --git a/crates/services/miscellaneous/Cargo.toml b/crates/services/miscellaneous/Cargo.toml
index 4cdd711807..9faad5f6e9 100644
--- a/crates/services/miscellaneous/Cargo.toml
+++ b/crates/services/miscellaneous/Cargo.toml
@@ -15,6 +15,7 @@ database-models = { path = "../../models/database" }
 database-utils = { path = "../../utils/database" }
 dependent-models = { path = "../../models/dependent" }
 dependent-utils = { path = "../../utils/dependent" }
+either = { workspace = true }
 enum-models = { path = "../../models/enum" }
 futures = { workspace = true }
 itertools = { workspace = true }
diff --git a/crates/services/miscellaneous/src/lib.rs b/crates/services/miscellaneous/src/lib.rs
index 3f7c105757..35c0e055c7 100644
--- a/crates/services/miscellaneous/src/lib.rs
+++ b/crates/services/miscellaneous/src/lib.rs
@@ -11,10 +11,10 @@ use async_graphql::{Error, Result};
 use background_models::{ApplicationJob, HpApplicationJob, MpApplicationJob};
 use chrono::{Days, Duration, NaiveDate, Utc};
 use common_models::{
-    ApplicationCacheKey, BackgroundJob, ChangeCollectionToEntityInput, DefaultCollection,
-    IdAndNamedObject, MetadataGroupSearchInput, MetadataSearchInput, PeopleSearchInput,
-    ProgressUpdateCacheInput, SearchDetails, SearchInput, StoredUrl, StringIdObject,
-    UserLevelCacheKey, UserNotificationContent,
+    BackgroundJob, ChangeCollectionToEntityInput, DefaultCollection, IdAndNamedObject,
+    MetadataGroupSearchInput, MetadataSearchInput, PeopleSearchInput, ProgressUpdateCacheInput,
+    SearchDetails, SearchInput, StoredUrl, StringIdObject, UserLevelCacheKey,
+    UserNotificationContent,
 };
 use common_utils::{
     get_first_and_last_day_of_month, ryot_log, ENTITY_BULK_DELETE_CHUNK_SIZE,
@@ -41,9 +41,11 @@ use database_utils::{
     revoke_access_link, user_by_id,
 };
 use dependent_models::{
-    ApplicationCacheValue, CoreDetails, GenreDetails, GraphqlPersonDetails, MetadataBaseData,
-    MetadataGroupDetails, MetadataGroupSearchResponse, MetadataSearchResponse,
-    PeopleSearchResponse, SearchResults, UserMetadataDetails, UserMetadataGroupDetails,
+    ApplicationCacheKey, ApplicationCacheValue, CachedResponse, CoreDetails, GenreDetails,
+    GraphqlPersonDetails, MetadataBaseData, MetadataGroupDetails, MetadataGroupSearchResponse,
+    MetadataSearchResponse, PeopleSearchResponse, SearchResults, UserMetadataDetails,
+    UserMetadataGroupDetails, UserMetadataGroupsListInput, UserMetadataGroupsListResponse,
+    UserMetadataListInput, UserMetadataListResponse, UserPeopleListInput, UserPeopleListResponse,
     UserPersonDetails,
 };
 use dependent_utils::{
@@ -54,11 +56,12 @@ use dependent_utils::{
     get_entity_recently_consumed, get_google_books_service, get_hardcover_service,
     get_metadata_provider, get_openlibrary_service, get_pending_notifications_for_user,
     get_tmdb_non_media_service, get_users_and_cte_monitoring_entity, get_users_monitoring_entity,
-    handle_after_media_seen_tasks, is_metadata_finished_by_user, metadata_groups_list,
-    metadata_images_as_urls, metadata_list, people_list, post_review, progress_update,
-    refresh_collection_to_entity_association, remove_entity_from_collection,
-    update_metadata_and_notify_users,
+    handle_after_media_seen_tasks, is_metadata_finished_by_user, metadata_images_as_urls,
+    post_review, progress_update, refresh_collection_to_entity_association,
+    remove_entity_from_collection, update_metadata_and_notify_users, user_metadata_groups_list,
+    user_metadata_list, user_people_list,
 };
+use either::Either;
 use enum_models::{
     EntityLot, MediaLot, MediaSource, MetadataToMetadataRelation, SeenState, UserNotificationLot,
     UserToMediaReason,
@@ -72,9 +75,8 @@ use media_models::{
     GraphqlMediaAssets, GraphqlMetadataDetails, GraphqlMetadataGroup, GraphqlVideoAsset,
     GroupedCalendarEvent, ImportOrExportItemReviewComment, MarkEntityAsPartialInput,
     MediaAssociatedPersonStateChanges, MetadataCreator, MetadataCreatorGroupedByRole,
-    MetadataFreeCreator, MetadataGroupsListInput, MetadataImage, MetadataListInput,
-    MetadataPartialDetails, MetadataVideo, MetadataVideoSource, PartialMetadata,
-    PartialMetadataWithoutId, PeopleListInput, PersonDetailsGroupedByRole,
+    MetadataFreeCreator, MetadataImage, MetadataPartialDetails, MetadataVideo, MetadataVideoSource,
+    PartialMetadata, PartialMetadataWithoutId, PersonDetailsGroupedByRole,
     PersonDetailsItemWithCharacter, PodcastSpecifics, ProgressUpdateInput, ReviewPostedEvent,
     SeenAnimeExtraInformation, SeenPodcastExtraInformation, SeenShowExtraInformation,
     ShowSpecifics, UniqueMediaIdentifier, UpdateCustomMetadataInput, UpdateSeenItemInput,
@@ -890,12 +892,12 @@ ORDER BY RANDOM() LIMIT 10;
         Ok(events)
     }
 
-    pub async fn metadata_list(
+    pub async fn user_metadata_list(
         &self,
         user_id: String,
-        input: MetadataListInput,
-    ) -> Result<SearchResults<String>> {
-        metadata_list(&user_id, input, &self.0).await
+        input: UserMetadataListInput,
+    ) -> Result<CachedResponse<UserMetadataListResponse>> {
+        user_metadata_list(&user_id, input, &self.0).await
     }
 
     pub async fn deploy_bulk_progress_update(
@@ -924,6 +926,13 @@ ORDER BY RANDOM() LIMIT 10;
         Ok(())
     }
 
+    pub async fn expire_cache_key(&self, cache_id: Uuid) -> Result<bool> {
+        self.0
+            .cache_service
+            .expire_key(Either::Right(cache_id))
+            .await
+    }
+
     pub async fn deploy_background_job(
         &self,
         user_id: &String,
@@ -1334,7 +1343,7 @@ ORDER BY RANDOM() LIMIT 10;
             input: input.clone(),
             user_id: user_id.to_owned(),
         });
-        if let Some(cached) = cc.get_value(cache_key.clone()).await {
+        if let Some((_id, cached)) = cc.get_value(cache_key.clone()).await {
             return Ok(cached);
         }
         let query = input.search.query.unwrap_or_default();
@@ -1364,7 +1373,7 @@ ORDER BY RANDOM() LIMIT 10;
             input: input.clone(),
             user_id: user_id.clone(),
         });
-        if let Some(results) = cc.get_value(cache_key.clone()).await {
+        if let Some((_id, results)) = cc.get_value(cache_key.clone()).await {
             return Ok(results);
         }
         let query = input.search.query.unwrap_or_default();
@@ -1399,7 +1408,7 @@ ORDER BY RANDOM() LIMIT 10;
             input: input.clone(),
             user_id: user_id.clone(),
         });
-        if let Some(results) = cc.get_value(cache_key.clone()).await {
+        if let Some((_id, results)) = cc.get_value(cache_key.clone()).await {
             return Ok(results);
         }
         let query = input.search.query.unwrap_or_default();
@@ -1516,7 +1525,7 @@ ORDER BY RANDOM() LIMIT 10;
                 provider_watched_on: si.provider_watched_on.clone(),
             },
         });
-        self.0.cache_service.expire_key(cache).await?;
+        self.0.cache_service.expire_key(Either::Left(cache)).await?;
         let seen_id = si.id.clone();
         let metadata_id = si.metadata_id.clone();
         if &si.user_id != user_id {
@@ -1816,20 +1825,20 @@ ORDER BY RANDOM() LIMIT 10;
         })
     }
 
-    pub async fn metadata_groups_list(
+    pub async fn user_metadata_groups_list(
         &self,
         user_id: String,
-        input: MetadataGroupsListInput,
-    ) -> Result<SearchResults<String>> {
-        metadata_groups_list(&user_id, &self.0, input).await
+        input: UserMetadataGroupsListInput,
+    ) -> Result<CachedResponse<UserMetadataGroupsListResponse>> {
+        user_metadata_groups_list(&user_id, &self.0, input).await
     }
 
-    pub async fn people_list(
+    pub async fn user_people_list(
         &self,
         user_id: String,
-        input: PeopleListInput,
-    ) -> Result<SearchResults<String>> {
-        people_list(&user_id, input, &self.0).await
+        input: UserPeopleListInput,
+    ) -> Result<CachedResponse<UserPeopleListResponse>> {
+        user_people_list(&user_id, input, &self.0).await
     }
 
     pub async fn person_details(&self, person_id: String) -> Result<GraphqlPersonDetails> {
diff --git a/crates/services/statistics/src/lib.rs b/crates/services/statistics/src/lib.rs
index d7fc136015..3253b5f387 100644
--- a/crates/services/statistics/src/lib.rs
+++ b/crates/services/statistics/src/lib.rs
@@ -2,13 +2,13 @@ use std::{cmp::Reverse, fmt::Write, sync::Arc};
 
 use async_graphql::Result;
 use common_models::{
-    ApplicationCacheKey, ApplicationDateRange, DailyUserActivitiesResponseGroupedBy,
-    DailyUserActivityHourRecord, UserAnalyticsInput, UserLevelCacheKey,
+    ApplicationDateRange, DailyUserActivitiesResponseGroupedBy, DailyUserActivityHourRecord,
+    UserAnalyticsInput, UserLevelCacheKey,
 };
 use database_models::{daily_user_activity, prelude::DailyUserActivity};
 use database_utils::calculate_user_activities_and_summary;
 use dependent_models::{
-    ApplicationCacheValue, DailyUserActivitiesResponse, DailyUserActivityItem,
+    ApplicationCacheKey, ApplicationCacheValue, DailyUserActivitiesResponse, DailyUserActivityItem,
     FitnessAnalyticsEquipment, FitnessAnalyticsExercise, FitnessAnalyticsMuscle, UserAnalytics,
     UserFitnessAnalytics,
 };
@@ -43,7 +43,7 @@ impl StatisticsService {
             input: (),
             user_id: user_id.to_owned(),
         });
-        if let Some(cached) = cc.get_value(cache_key.clone()).await {
+        if let Some((_id, cached)) = cc.get_value(cache_key.clone()).await {
             return Ok(cached);
         }
         let get_date = |ordering: Order| {
@@ -285,7 +285,7 @@ impl StatisticsService {
             user_id: user_id.to_owned(),
         });
         let cc = &self.0.cache_service;
-        if let Some(cached) = cc.get_value::<UserAnalytics>(cache_key.clone()).await {
+        if let Some((_id, cached)) = cc.get_value::<UserAnalytics>(cache_key.clone()).await {
             return Ok(cached);
         }
         #[derive(Debug, DerivePartialModel, FromQueryResult)]
diff --git a/crates/services/supporting/Cargo.toml b/crates/services/supporting/Cargo.toml
index e06a79522d..0d4195a2d3 100644
--- a/crates/services/supporting/Cargo.toml
+++ b/crates/services/supporting/Cargo.toml
@@ -13,7 +13,6 @@ chrono-tz = { workspace = true }
 common-models = { path = "../../models/common" }
 common-utils = { path = "../../utils/common" }
 config = { path = "../../config" }
-database-models = { path = "../../models/database" }
 dependent-models = { path = "../../models/dependent" }
 enum-models = { path = "../../models/enum" }
 env-utils = { path = "../../utils/env" }
diff --git a/crates/services/supporting/src/lib.rs b/crates/services/supporting/src/lib.rs
index 2288cb6cf8..7660ed2d90 100644
--- a/crates/services/supporting/src/lib.rs
+++ b/crates/services/supporting/src/lib.rs
@@ -5,14 +5,13 @@ use async_graphql::Result;
 use background_models::{ApplicationJob, HpApplicationJob, LpApplicationJob, MpApplicationJob};
 use cache_service::CacheService;
 use chrono::{NaiveDate, TimeZone, Utc};
-use common_models::{ApplicationCacheKey, BackendError};
+use common_models::BackendError;
 use common_utils::{
     convert_naive_to_utc, ryot_log, COMPILATION_TIMESTAMP, EXERCISE_LOT_MAPPINGS,
     METADATA_GROUP_SOURCE_LOT_MAPPINGS, METADATA_LOT_MAPPINGS, PAGE_SIZE, PEOPLE_SEARCH_SOURCES,
 };
-use database_models::prelude::Exercise;
 use dependent_models::{
-    ApplicationCacheValue, CoreDetails, ExerciseFilters, ExerciseParameters,
+    ApplicationCacheKey, ApplicationCacheValue, CoreDetails, ExerciseFilters, ExerciseParameters,
     ExerciseParametersLotMapping, MetadataGroupSourceLotMapping, MetadataLotSourceMappings,
     ProviderLanguageInformation,
 };
@@ -25,7 +24,7 @@ use file_storage_service::FileStorageService;
 use itertools::Itertools;
 use openidconnect::core::CoreClient;
 use rustypipe::param::{Language, LANGUAGES};
-use sea_orm::{DatabaseConnection, EntityTrait, Iterable, PaginatorTrait};
+use sea_orm::{DatabaseConnection, Iterable};
 use serde::{Deserialize, Serialize};
 use unkey::{models::VerifyKeyRequest, Client};
 
@@ -127,14 +126,13 @@ impl SupportingService {
 
     pub async fn core_details(&self) -> Result<CoreDetails> {
         let cc = &self.cache_service;
-        if let Some(cached) = cc.get_value(ApplicationCacheKey::CoreDetails).await {
+        if let Some((_id, cached)) = cc.get_value(ApplicationCacheKey::CoreDetails).await {
             return Ok(cached);
         }
         let mut files_enabled = self.config.file_storage.is_enabled();
         if files_enabled && !self.file_storage_service.is_enabled().await {
             files_enabled = false;
         }
-        let download_required = Exercise::find().count(&self.db).await? == 0;
         let core_details = CoreDetails {
             page_size: PAGE_SIZE,
             version: APP_VERSION.to_owned(),
@@ -167,7 +165,6 @@ impl SupportingService {
                 })
                 .collect(),
             exercise_parameters: ExerciseParameters {
-                download_required,
                 filters: ExerciseFilters {
                     lot: ExerciseLot::iter().collect_vec(),
                     level: ExerciseLevel::iter().collect_vec(),
diff --git a/crates/services/user/src/lib.rs b/crates/services/user/src/lib.rs
index ea782be581..c5ea8f6647 100644
--- a/crates/services/user/src/lib.rs
+++ b/crates/services/user/src/lib.rs
@@ -4,7 +4,7 @@ use application_utils::user_id_from_token;
 use argon2::{Argon2, PasswordHash, PasswordVerifier};
 use async_graphql::{Error, Result};
 use chrono::Utc;
-use common_models::{ApplicationCacheKey, DefaultCollection, StringIdObject, UserLevelCacheKey};
+use common_models::{DefaultCollection, StringIdObject, UserLevelCacheKey};
 use common_utils::ryot_log;
 use database_models::{
     access_link, integration, metadata, notification_platform,
@@ -16,7 +16,8 @@ use database_utils::{
     revoke_access_link, server_key_validation_guard, user_by_id,
 };
 use dependent_models::{
-    ApplicationCacheValue, UserDetailsResult, UserMetadataRecommendationsResponse,
+    ApplicationCacheKey, ApplicationCacheValue, CachedResponse, UserDetailsResult,
+    UserMetadataRecommendationsResponse,
 };
 use dependent_utils::{create_or_update_collection, get_pending_notifications_for_user};
 use enum_meta::Meta;
@@ -62,26 +63,22 @@ impl UserService {
     pub async fn user_metadata_recommendations(
         &self,
         user_id: &String,
-        should_refresh: Option<bool>,
-    ) -> Result<UserMetadataRecommendationsResponse> {
+    ) -> Result<CachedResponse<UserMetadataRecommendationsResponse>> {
         let cc = &self.0.cache_service;
         let metadata_recommendations_key =
             ApplicationCacheKey::UserMetadataRecommendations(UserLevelCacheKey {
                 input: (),
                 user_id: user_id.to_owned(),
             });
-        match should_refresh {
-            Some(true) => {}
-            _ => {
-                if let Some(recommendations) = cc
-                    .get_value::<UserMetadataRecommendationsResponse>(
-                        metadata_recommendations_key.clone(),
-                    )
-                    .await
-                {
-                    return Ok(recommendations);
-                };
-            }
+
+        if let Some((id, recommendations)) = cc
+            .get_value::<UserMetadataRecommendationsResponse>(metadata_recommendations_key.clone())
+            .await
+        {
+            return Ok(CachedResponse {
+                cache_id: id,
+                response: recommendations,
+            });
         };
         let preferences = user_by_id(user_id, &self.0).await?.preferences;
         let limit = preferences
@@ -93,9 +90,6 @@ impl UserService {
             .num_elements
             .ok_or_else(|| Error::new("Dashboard element num elements not found"))?;
         let enabled = preferences.features_enabled.media.specific;
-        if enabled.is_empty() {
-            return Ok(Vec::new());
-        }
         let started_at = Instant::now();
         let mut recommendations = HashSet::new();
         for i in 0.. {
@@ -127,12 +121,16 @@ impl UserService {
         }
         let mut recommendations = recommendations.into_iter().collect_vec();
         recommendations.shuffle(&mut rand::rng());
-        cc.set_key(
-            metadata_recommendations_key,
-            ApplicationCacheValue::UserMetadataRecommendations(recommendations.clone()),
-        )
-        .await?;
-        Ok(recommendations)
+        let id = cc
+            .set_key(
+                metadata_recommendations_key,
+                ApplicationCacheValue::UserMetadataRecommendations(recommendations.clone()),
+            )
+            .await?;
+        Ok(CachedResponse {
+            cache_id: id,
+            response: recommendations,
+        })
     }
 
     pub async fn user_access_links(&self, user_id: &String) -> Result<Vec<access_link::Model>> {
diff --git a/crates/utils/dependent/Cargo.toml b/crates/utils/dependent/Cargo.toml
index f50bc5bea9..da8ed4da50 100644
--- a/crates/utils/dependent/Cargo.toml
+++ b/crates/utils/dependent/Cargo.toml
@@ -14,6 +14,7 @@ config = { path = "../../config" }
 database-models = { path = "../../models/database" }
 database-utils = { path = "../database" }
 dependent-models = { path = "../../models/dependent" }
+either = { workspace = true }
 enum-models = { path = "../../models/enum" }
 file-storage-service = { path = "../../services/file-storage" }
 fitness-models = { path = "../../models/fitness" }
diff --git a/crates/utils/dependent/src/lib.rs b/crates/utils/dependent/src/lib.rs
index f76159dcdb..f874460689 100644
--- a/crates/utils/dependent/src/lib.rs
+++ b/crates/utils/dependent/src/lib.rs
@@ -5,9 +5,9 @@ use async_graphql::{Enum, Error, Result};
 use background_models::{ApplicationJob, HpApplicationJob, LpApplicationJob, MpApplicationJob};
 use chrono::Utc;
 use common_models::{
-    ApplicationCacheKey, BackgroundJob, ChangeCollectionToEntityInput, DefaultCollection,
-    MetadataRecentlyConsumedCacheInput, ProgressUpdateCacheInput, SearchDetails, SearchInput,
-    StoredUrl, StringIdObject, UserLevelCacheKey, UserNotificationContent,
+    BackgroundJob, ChangeCollectionToEntityInput, DefaultCollection,
+    MetadataRecentlyConsumedCacheInput, ProgressUpdateCacheInput, SearchDetails, StoredUrl,
+    StringIdObject, UserLevelCacheKey, UserNotificationContent,
 };
 use common_utils::{
     acquire_lock, ryot_log, sleep_for_n_seconds, EXERCISE_LOT_MAPPINGS,
@@ -30,16 +30,22 @@ use database_utils::{
     schedule_user_for_workout_revision, user_by_id,
 };
 use dependent_models::{
-    ApplicationCacheValue, EmptyCacheValue, ImportCompletedItem, ImportResult, SearchResults,
+    ApplicationCacheKey, ApplicationCacheValue, CachedResponse, EmptyCacheValue,
+    ImportCompletedItem, ImportResult, SearchResults, UserExercisesListResponse,
+    UserMetadataGroupsListInput, UserMetadataGroupsListResponse, UserMetadataListInput,
+    UserMetadataListResponse, UserPeopleListInput, UserPeopleListResponse,
+    UserTemplatesOrWorkoutsListInput, UserTemplatesOrWorkoutsListSortBy, UserWorkoutsListResponse,
+    UserWorkoutsTemplatesListResponse,
 };
+use either::Either;
 use enum_models::{
     EntityLot, ExerciseLot, ExerciseSource, MediaLot, MediaSource, MetadataToMetadataRelation,
     SeenState, UserNotificationLot, UserToMediaReason, Visibility, WorkoutSetPersonalBest,
 };
 use file_storage_service::FileStorageService;
 use fitness_models::{
-    ExerciseBestSetRecord, ExerciseSortBy, ExercisesListInput, ProcessedExercise,
-    UserExerciseInput, UserToExerciseBestSetExtraInformation, UserToExerciseExtraInformation,
+    ExerciseBestSetRecord, ExerciseSortBy, ProcessedExercise, UserExerciseInput,
+    UserExercisesListInput, UserToExerciseBestSetExtraInformation, UserToExerciseExtraInformation,
     UserToExerciseHistoryExtraInformation, UserWorkoutInput, UserWorkoutSetRecord, WorkoutDuration,
     WorkoutEquipmentFocusedSummary, WorkoutFocusedSummary, WorkoutForceFocusedSummary,
     WorkoutInformation, WorkoutLevelFocusedSummary, WorkoutLotFocusedSummary,
@@ -50,9 +56,8 @@ use importer_models::{ImportDetails, ImportFailStep, ImportFailedItem, ImportRes
 use itertools::Itertools;
 use media_models::{
     CommitMediaInput, CommitPersonInput, CreateOrUpdateCollectionInput, CreateOrUpdateReviewInput,
-    ImportOrExportItemRating, MediaGeneralFilter, MediaSortBy, MetadataDetails,
-    MetadataGroupsListInput, MetadataImage, MetadataListInput, PartialMetadata,
-    PartialMetadataPerson, PartialMetadataWithoutId, PeopleListInput,
+    ImportOrExportItemRating, MediaGeneralFilter, MediaSortBy, MetadataDetails, MetadataImage,
+    PartialMetadata, PartialMetadataPerson, PartialMetadataWithoutId,
     PersonAndMetadataGroupsSortBy, ProgressUpdateError, ProgressUpdateErrorVariant,
     ProgressUpdateInput, ProgressUpdateResultUnion, ReviewPostedEvent, SeenAnimeExtraInformation,
     SeenMangaExtraInformation, SeenPodcastExtraInformation, SeenPodcastExtraOptionalInformation,
@@ -2648,7 +2653,7 @@ pub async fn expire_user_collections_list_cache(
         input: (),
         user_id: user_id.to_owned(),
     });
-    ss.cache_service.expire_key(cache_key).await?;
+    ss.cache_service.expire_key(Either::Left(cache_key)).await?;
     Ok(())
 }
 
@@ -2747,11 +2752,22 @@ pub async fn remove_entity_from_collection(
     Ok(StringIdObject { id: collect.id })
 }
 
-pub async fn metadata_list(
+pub async fn user_metadata_list(
     user_id: &String,
-    input: MetadataListInput,
+    input: UserMetadataListInput,
     ss: &Arc<SupportingService>,
-) -> Result<SearchResults<String>> {
+) -> Result<CachedResponse<UserMetadataListResponse>> {
+    let cc = &ss.cache_service;
+    let key = ApplicationCacheKey::UserMetadataList(UserLevelCacheKey {
+        input: input.clone(),
+        user_id: user_id.to_owned(),
+    });
+    if let Some((id, cached)) = cc.get_value::<UserMetadataListResponse>(key.clone()).await {
+        return Ok(CachedResponse {
+            cache_id: id,
+            response: cached,
+        });
+    }
     let preferences = user_by_id(user_id, ss).await?.preferences;
 
     let avg_rating_col = "user_average_rating";
@@ -2866,6 +2882,7 @@ pub async fn metadata_list(
         })
         .apply_if(input.sort.map(|s| s.by), |query, v| match v {
             MediaSortBy::Title => query.order_by(metadata::Column::Title, order_by),
+            MediaSortBy::Random => query.order_by(Expr::expr(Func::random()), order_by),
             MediaSortBy::TimesConsumed => query.order_by(seen::Column::Id.count(), order_by),
             MediaSortBy::LastUpdated => query
                 .order_by(user_to_entity::Column::LastUpdatedOn, order_by)
@@ -2901,7 +2918,8 @@ pub async fn metadata_list(
     for c in paginator.fetch_page(page - 1).await? {
         items.push(c);
     }
-    Ok(SearchResults {
+    let response = SearchResults {
+        items,
         details: SearchDetails {
             total: number_of_items.try_into().unwrap(),
             next_page: if page < number_of_pages {
@@ -2910,15 +2928,29 @@ pub async fn metadata_list(
                 None
             },
         },
-        items,
-    })
+    };
+    let cache_id = cc
+        .set_key(
+            key,
+            ApplicationCacheValue::UserMetadataList(response.clone()),
+        )
+        .await?;
+    Ok(CachedResponse { cache_id, response })
 }
 
-pub async fn metadata_groups_list(
+pub async fn user_metadata_groups_list(
     user_id: &String,
     ss: &Arc<SupportingService>,
-    input: MetadataGroupsListInput,
-) -> Result<SearchResults<String>> {
+    input: UserMetadataGroupsListInput,
+) -> Result<CachedResponse<UserMetadataGroupsListResponse>> {
+    let cc = &ss.cache_service;
+    let key = ApplicationCacheKey::UserMetadataGroupsList(UserLevelCacheKey {
+        input: input.clone(),
+        user_id: user_id.to_owned(),
+    });
+    if let Some((cache_id, response)) = cc.get_value(key.clone()).await {
+        return Ok(CachedResponse { cache_id, response });
+    }
     let page: u64 = input
         .search
         .clone()
@@ -2927,13 +2959,14 @@ pub async fn metadata_groups_list(
         .try_into()
         .unwrap();
     let alias = "parts";
-    let media_items_col = Expr::col(Alias::new(alias));
+    let metadata_group_parts_col = Expr::col(Alias::new(alias));
     let (order_by, sort_order) = match input.sort {
-        None => (media_items_col, Order::Desc),
+        None => (metadata_group_parts_col, Order::Desc),
         Some(ord) => (
             match ord.by {
+                PersonAndMetadataGroupsSortBy::Random => Expr::expr(Func::random()),
+                PersonAndMetadataGroupsSortBy::MediaItems => metadata_group_parts_col,
                 PersonAndMetadataGroupsSortBy::Name => Expr::col(metadata_group::Column::Title),
-                PersonAndMetadataGroupsSortBy::MediaItems => media_items_col,
             },
             graphql_to_db_order(ord.order),
         ),
@@ -2978,7 +3011,8 @@ pub async fn metadata_groups_list(
     for c in paginator.fetch_page(page - 1).await? {
         items.push(c);
     }
-    Ok(SearchResults {
+    let response = SearchResults {
+        items,
         details: SearchDetails {
             total: number_of_items.try_into().unwrap(),
             next_page: if page < number_of_pages {
@@ -2987,15 +3021,29 @@ pub async fn metadata_groups_list(
                 None
             },
         },
-        items,
-    })
+    };
+    let cache_id = cc
+        .set_key(
+            key,
+            ApplicationCacheValue::UserMetadataGroupsList(response.clone()),
+        )
+        .await?;
+    Ok(CachedResponse { cache_id, response })
 }
 
-pub async fn people_list(
+pub async fn user_people_list(
     user_id: &String,
-    input: PeopleListInput,
+    input: UserPeopleListInput,
     ss: &Arc<SupportingService>,
-) -> Result<SearchResults<String>> {
+) -> Result<CachedResponse<UserPeopleListResponse>> {
+    let cc = &ss.cache_service;
+    let key = ApplicationCacheKey::UserPeopleList(UserLevelCacheKey {
+        input: input.clone(),
+        user_id: user_id.clone(),
+    });
+    if let Some((cache_id, response)) = cc.get_value::<UserPeopleListResponse>(key.clone()).await {
+        return Ok(CachedResponse { cache_id, response });
+    }
     let page: u64 = input
         .search
         .clone()
@@ -3009,8 +3057,9 @@ pub async fn people_list(
         None => (media_items_col, Order::Desc),
         Some(ord) => (
             match ord.by {
-                PersonAndMetadataGroupsSortBy::Name => Expr::col(person::Column::Name),
                 PersonAndMetadataGroupsSortBy::MediaItems => media_items_col,
+                PersonAndMetadataGroupsSortBy::Random => Expr::expr(Func::random()),
+                PersonAndMetadataGroupsSortBy::Name => Expr::col(person::Column::Name),
             },
             graphql_to_db_order(ord.order),
         ),
@@ -3055,11 +3104,12 @@ pub async fn people_list(
         number_of_items,
         number_of_pages,
     } = creators_paginator.num_items_and_pages().await?;
-    let mut creators = vec![];
+    let mut items = vec![];
     for cr in creators_paginator.fetch_page(page - 1).await? {
-        creators.push(cr);
+        items.push(cr);
     }
-    Ok(SearchResults {
+    let response = SearchResults {
+        items,
         details: SearchDetails {
             total: number_of_items.try_into().unwrap(),
             next_page: if page < number_of_pages {
@@ -3068,25 +3118,44 @@ pub async fn people_list(
                 None
             },
         },
-        items: creators,
-    })
+    };
+    let cache_id = cc
+        .set_key(key, ApplicationCacheValue::UserPeopleList(response.clone()))
+        .await?;
+    Ok(CachedResponse { cache_id, response })
 }
 
 pub async fn user_workouts_list(
     user_id: &String,
-    input: SearchInput,
+    input: UserTemplatesOrWorkoutsListInput,
     ss: &Arc<SupportingService>,
-) -> Result<SearchResults<String>> {
-    let page = input.page.unwrap_or(1);
-    let take = input.take.unwrap_or(PAGE_SIZE as u64);
+) -> Result<CachedResponse<UserWorkoutsListResponse>> {
+    let cc = &ss.cache_service;
+    let key = ApplicationCacheKey::UserWorkoutsList(UserLevelCacheKey {
+        input: input.clone(),
+        user_id: user_id.to_owned(),
+    });
+    if let Some((cache_id, response)) = cc.get_value(key.clone()).await {
+        return Ok(CachedResponse { cache_id, response });
+    }
+    let page = input.search.page.unwrap_or(1);
+    let take = input.search.take.unwrap_or(PAGE_SIZE as u64);
     let paginator = Workout::find()
         .select_only()
         .column(workout::Column::Id)
         .filter(workout::Column::UserId.eq(user_id))
-        .apply_if(input.query, |query, v| {
+        .apply_if(input.search.query, |query, v| {
             query.filter(Expr::col(workout::Column::Name).ilike(ilike_sql(&v)))
         })
-        .order_by_desc(workout::Column::EndTime)
+        .apply_if(input.sort, |query, v| {
+            query.order_by(
+                match v.by {
+                    UserTemplatesOrWorkoutsListSortBy::Random => Expr::expr(Func::random()),
+                    UserTemplatesOrWorkoutsListSortBy::Time => Expr::col(workout::Column::EndTime),
+                },
+                graphql_to_db_order(v.order),
+            )
+        })
         .into_tuple::<String>()
         .paginate(&ss.db, take);
     let ItemsAndPagesNumber {
@@ -3094,7 +3163,8 @@ pub async fn user_workouts_list(
         number_of_pages,
     } = paginator.num_items_and_pages().await?;
     let items = paginator.fetch_page((page - 1).try_into().unwrap()).await?;
-    Ok(SearchResults {
+    let response = SearchResults {
+        items,
         details: SearchDetails {
             total: number_of_items.try_into().unwrap(),
             next_page: if page < number_of_pages.try_into().unwrap() {
@@ -3103,25 +3173,49 @@ pub async fn user_workouts_list(
                 None
             },
         },
-        items,
-    })
+    };
+    let cache_id = cc
+        .set_key(
+            key,
+            ApplicationCacheValue::UserWorkoutsList(response.clone()),
+        )
+        .await?;
+    Ok(CachedResponse { cache_id, response })
 }
 
 pub async fn user_workout_templates_list(
     user_id: &String,
-    input: SearchInput,
     ss: &Arc<SupportingService>,
-) -> Result<SearchResults<String>> {
-    let page = input.page.unwrap_or(1);
-    let take = input.take.unwrap_or(PAGE_SIZE as u64);
+    input: UserTemplatesOrWorkoutsListInput,
+) -> Result<CachedResponse<UserWorkoutsTemplatesListResponse>> {
+    let cc = &ss.cache_service;
+    let key = ApplicationCacheKey::UserWorkoutTemplatesList(UserLevelCacheKey {
+        input: input.clone(),
+        user_id: user_id.to_owned(),
+    });
+    if let Some((cache_id, response)) = cc.get_value(key.clone()).await {
+        return Ok(CachedResponse { cache_id, response });
+    }
+    let page = input.search.page.unwrap_or(1);
+    let take = input.search.take.unwrap_or(PAGE_SIZE as u64);
     let paginator = WorkoutTemplate::find()
         .select_only()
         .column(workout_template::Column::Id)
         .filter(workout_template::Column::UserId.eq(user_id))
-        .apply_if(input.query, |query, v| {
+        .apply_if(input.search.query, |query, v| {
             query.filter(Expr::col(workout_template::Column::Name).ilike(ilike_sql(&v)))
         })
-        .order_by_desc(workout_template::Column::CreatedOn)
+        .apply_if(input.sort, |query, v| {
+            query.order_by(
+                match v.by {
+                    UserTemplatesOrWorkoutsListSortBy::Random => Expr::expr(Func::random()),
+                    UserTemplatesOrWorkoutsListSortBy::Time => {
+                        Expr::col(workout_template::Column::CreatedOn)
+                    }
+                },
+                graphql_to_db_order(v.order),
+            )
+        })
         .into_tuple::<String>()
         .paginate(&ss.db, take);
     let ItemsAndPagesNumber {
@@ -3129,7 +3223,8 @@ pub async fn user_workout_templates_list(
         number_of_pages,
     } = paginator.num_items_and_pages().await?;
     let items = paginator.fetch_page((page - 1).try_into().unwrap()).await?;
-    Ok(SearchResults {
+    let response = SearchResults {
+        items,
         details: SearchDetails {
             total: number_of_items.try_into().unwrap(),
             next_page: if page < number_of_pages.try_into().unwrap() {
@@ -3138,15 +3233,29 @@ pub async fn user_workout_templates_list(
                 None
             },
         },
-        items,
-    })
+    };
+    let cache_id = cc
+        .set_key(
+            key,
+            ApplicationCacheValue::UserWorkoutTemplatesList(response.clone()),
+        )
+        .await?;
+    Ok(CachedResponse { cache_id, response })
 }
 
-pub async fn exercises_list(
+pub async fn user_exercises_list(
     user_id: &String,
-    input: ExercisesListInput,
+    input: UserExercisesListInput,
     ss: &Arc<SupportingService>,
-) -> Result<SearchResults<String>> {
+) -> Result<CachedResponse<UserExercisesListResponse>> {
+    let cc = &ss.cache_service;
+    let key = ApplicationCacheKey::UserExercisesList(UserLevelCacheKey {
+        input: input.clone(),
+        user_id: user_id.to_owned(),
+    });
+    if let Some((cache_id, response)) = cc.get_value(key.clone()).await {
+        return Ok(CachedResponse { cache_id, response });
+    }
     let user_id = user_id.to_owned();
     let take = input.search.take.unwrap_or(PAGE_SIZE as u64);
     let page = input.search.page.unwrap_or(1);
@@ -3158,6 +3267,7 @@ pub async fn exercises_list(
             // DEV: This is just a small hack to reduce duplicated code. We
             // are ordering by name for the other `sort_by` anyway.
             ExerciseSortBy::Name => Expr::val("1"),
+            ExerciseSortBy::Random => Expr::expr(Func::random()),
             ExerciseSortBy::TimesPerformed => Expr::expr(Func::coalesce([
                 Expr::col((
                     etu.clone(),
@@ -3232,7 +3342,8 @@ pub async fn exercises_list(
     for ex in paginator.fetch_page((page - 1).try_into().unwrap()).await? {
         items.push(ex);
     }
-    Ok(SearchResults {
+    let response = SearchResults {
+        items,
         details: SearchDetails {
             total: number_of_items.try_into().unwrap(),
             next_page: if page < number_of_pages.try_into().unwrap() {
@@ -3241,8 +3352,14 @@ pub async fn exercises_list(
                 None
             },
         },
-        items,
-    })
+    };
+    let cache_id = cc
+        .set_key(
+            key,
+            ApplicationCacheValue::UserExercisesList(response.clone()),
+        )
+        .await?;
+    Ok(CachedResponse { cache_id, response })
 }
 
 pub async fn get_pending_notifications_for_user(
diff --git a/libs/generated/src/graphql/backend/gql.ts b/libs/generated/src/graphql/backend/gql.ts
index 8a7317c19f..71bccf0211 100644
--- a/libs/generated/src/graphql/backend/gql.ts
+++ b/libs/generated/src/graphql/backend/gql.ts
@@ -14,7 +14,7 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/
  * Learn more about it here: https://the-guild.dev/graphql/codegen/plugins/presets/preset-client#reducing-bundle-size
  */
 const documents = {
-    "mutation RegisterUser($input: RegisterUserInput!) {\n  registerUser(input: $input) {\n    __typename\n    ... on RegisterError {\n      error\n    }\n    ... on StringIdObject {\n      id\n    }\n  }\n}\n\nmutation LoginUser($input: AuthUserInput!) {\n  loginUser(input: $input) {\n    __typename\n    ... on LoginError {\n      error\n    }\n    ... on LoginResponse {\n      apiKey\n    }\n  }\n}\n\nmutation AddEntityToCollection($input: ChangeCollectionToEntityInput!) {\n  addEntityToCollection(input: $input)\n}\n\nmutation CommitMetadata($input: CommitMediaInput!) {\n  commitMetadata(input: $input) {\n    id\n  }\n}\n\nmutation CommitMetadataGroup($input: CommitMediaInput!) {\n  commitMetadataGroup(input: $input) {\n    id\n  }\n}\n\nmutation CommitPerson($input: CommitPersonInput!) {\n  commitPerson(input: $input) {\n    id\n  }\n}\n\nmutation CreateCustomExercise($input: ExerciseInput!) {\n  createCustomExercise(input: $input)\n}\n\nmutation UpdateCustomExercise($input: UpdateCustomExerciseInput!) {\n  updateCustomExercise(input: $input)\n}\n\nmutation UpdateUserIntegration($input: UpdateUserIntegrationInput!) {\n  updateUserIntegration(input: $input)\n}\n\nmutation CreateCustomMetadata($input: CreateCustomMetadataInput!) {\n  createCustomMetadata(input: $input) {\n    id\n  }\n}\n\nmutation UpdateCustomMetadata($input: UpdateCustomMetadataInput!) {\n  updateCustomMetadata(input: $input)\n}\n\nmutation CreateOrUpdateCollection($input: CreateOrUpdateCollectionInput!) {\n  createOrUpdateCollection(input: $input) {\n    id\n  }\n}\n\nmutation CreateReviewComment($input: CreateReviewCommentInput!) {\n  createReviewComment(input: $input)\n}\n\nmutation CreateUserMeasurement($input: UserMeasurementInput!) {\n  createUserMeasurement(input: $input)\n}\n\nmutation CreateUserNotificationPlatform($input: CreateUserNotificationPlatformInput!) {\n  createUserNotificationPlatform(input: $input)\n}\n\nmutation CreateUserIntegration($input: CreateUserIntegrationInput!) {\n  createUserIntegration(input: $input) {\n    id\n  }\n}\n\nmutation CreateOrUpdateUserWorkout($input: UserWorkoutInput!) {\n  createOrUpdateUserWorkout(input: $input)\n}\n\nmutation CreateOrUpdateUserWorkoutTemplate($input: UserWorkoutInput!) {\n  createOrUpdateUserWorkoutTemplate(input: $input)\n}\n\nmutation DeleteCollection($collectionName: String!) {\n  deleteCollection(collectionName: $collectionName)\n}\n\nmutation DeleteReview($reviewId: String!) {\n  deleteReview(reviewId: $reviewId)\n}\n\nmutation DeleteS3Object($key: String!) {\n  deleteS3Object(key: $key)\n}\n\nmutation DeleteSeenItem($seenId: String!) {\n  deleteSeenItem(seenId: $seenId) {\n    id\n  }\n}\n\nmutation DeleteUser($toDeleteUserId: String!) {\n  deleteUser(toDeleteUserId: $toDeleteUserId)\n}\n\nmutation DeleteUserIntegration($integrationId: String!) {\n  deleteUserIntegration(integrationId: $integrationId)\n}\n\nmutation DeleteUserMeasurement($timestamp: DateTime!) {\n  deleteUserMeasurement(timestamp: $timestamp)\n}\n\nmutation DeleteUserNotificationPlatform($notificationId: String!) {\n  deleteUserNotificationPlatform(notificationId: $notificationId)\n}\n\nmutation DeleteUserWorkout($workoutId: String!) {\n  deleteUserWorkout(workoutId: $workoutId)\n}\n\nmutation DeleteUserWorkoutTemplate($workoutTemplateId: String!) {\n  deleteUserWorkoutTemplate(workoutTemplateId: $workoutTemplateId)\n}\n\nmutation DeployBackgroundJob($jobName: BackgroundJob!) {\n  deployBackgroundJob(jobName: $jobName)\n}\n\nmutation DeployBulkProgressUpdate($input: [ProgressUpdateInput!]!) {\n  deployBulkProgressUpdate(input: $input)\n}\n\nmutation DeployExportJob {\n  deployExportJob\n}\n\nmutation DeployImportJob($input: DeployImportJobInput!) {\n  deployImportJob(input: $input)\n}\n\nmutation DeployUpdateMetadataJob($metadataId: String!) {\n  deployUpdateMetadataJob(metadataId: $metadataId)\n}\n\nmutation DeployUpdatePersonJob($personId: String!) {\n  deployUpdatePersonJob(personId: $personId)\n}\n\nmutation DeployUpdateMetadataGroupJob($metadataGroupId: String!) {\n  deployUpdateMetadataGroupJob(metadataGroupId: $metadataGroupId)\n}\n\nmutation UpdateSeenItem($input: UpdateSeenItemInput!) {\n  updateSeenItem(input: $input)\n}\n\nmutation UpdateUserNotificationPlatform($input: UpdateUserNotificationPlatformInput!) {\n  updateUserNotificationPlatform(input: $input)\n}\n\nmutation UpdateUserWorkoutAttributes($input: UpdateUserWorkoutAttributesInput!) {\n  updateUserWorkoutAttributes(input: $input)\n}\n\nmutation GenerateAuthToken {\n  generateAuthToken\n}\n\nmutation MergeMetadata($mergeFrom: String!, $mergeInto: String!) {\n  mergeMetadata(mergeFrom: $mergeFrom, mergeInto: $mergeInto)\n}\n\nmutation DisassociateMetadata($metadataId: String!) {\n  disassociateMetadata(metadataId: $metadataId)\n}\n\nmutation CreateOrUpdateReview($input: CreateOrUpdateReviewInput!) {\n  createOrUpdateReview(input: $input) {\n    id\n  }\n}\n\nmutation PresignedPutS3Url($input: PresignedPutUrlInput!) {\n  presignedPutS3Url(input: $input) {\n    key\n    uploadUrl\n  }\n}\n\nmutation RemoveEntityFromCollection($input: ChangeCollectionToEntityInput!) {\n  removeEntityFromCollection(input: $input) {\n    id\n  }\n}\n\nmutation TestUserNotificationPlatforms {\n  testUserNotificationPlatforms\n}\n\nmutation UpdateUser($input: UpdateUserInput!) {\n  updateUser(input: $input) {\n    id\n  }\n}\n\nmutation UpdateUserPreference($input: UserPreferencesInput!) {\n  updateUserPreference(input: $input)\n}\n\nmutation CreateAccessLink($input: CreateAccessLinkInput!) {\n  createAccessLink(input: $input) {\n    id\n  }\n}\n\nmutation ProcessAccessLink($input: ProcessAccessLinkInput!) {\n  processAccessLink(input: $input) {\n    __typename\n    ... on ProcessAccessLinkError {\n      error\n    }\n    ... on ProcessAccessLinkResponse {\n      apiKey\n      redirectTo\n      tokenValidForDays\n    }\n  }\n}\n\nmutation RevokeAccessLink($accessLinkId: String!) {\n  revokeAccessLink(accessLinkId: $accessLinkId)\n}\n\nmutation UpdateUserExerciseSettings($input: UpdateUserExerciseSettings!) {\n  updateUserExerciseSettings(input: $input)\n}\n\nmutation MergeExercise($mergeFrom: String!, $mergeInto: String!) {\n  mergeExercise(mergeFrom: $mergeFrom, mergeInto: $mergeInto)\n}\n\nmutation MarkEntityAsPartial($input: MarkEntityAsPartialInput!) {\n  markEntityAsPartial(input: $input)\n}\n\nmutation MarkNotificationsAsAddressed($notificationIds: [String!]!) {\n  markNotificationsAsAddressed(notificationIds: $notificationIds)\n}": types.RegisterUserDocument,
+    "mutation RegisterUser($input: RegisterUserInput!) {\n  registerUser(input: $input) {\n    __typename\n    ... on RegisterError {\n      error\n    }\n    ... on StringIdObject {\n      id\n    }\n  }\n}\n\nmutation LoginUser($input: AuthUserInput!) {\n  loginUser(input: $input) {\n    __typename\n    ... on LoginError {\n      error\n    }\n    ... on LoginResponse {\n      apiKey\n    }\n  }\n}\n\nmutation AddEntityToCollection($input: ChangeCollectionToEntityInput!) {\n  addEntityToCollection(input: $input)\n}\n\nmutation CommitMetadata($input: CommitMediaInput!) {\n  commitMetadata(input: $input) {\n    id\n  }\n}\n\nmutation CommitMetadataGroup($input: CommitMediaInput!) {\n  commitMetadataGroup(input: $input) {\n    id\n  }\n}\n\nmutation CommitPerson($input: CommitPersonInput!) {\n  commitPerson(input: $input) {\n    id\n  }\n}\n\nmutation CreateCustomExercise($input: ExerciseInput!) {\n  createCustomExercise(input: $input)\n}\n\nmutation UpdateCustomExercise($input: UpdateCustomExerciseInput!) {\n  updateCustomExercise(input: $input)\n}\n\nmutation UpdateUserIntegration($input: UpdateUserIntegrationInput!) {\n  updateUserIntegration(input: $input)\n}\n\nmutation CreateCustomMetadata($input: CreateCustomMetadataInput!) {\n  createCustomMetadata(input: $input) {\n    id\n  }\n}\n\nmutation UpdateCustomMetadata($input: UpdateCustomMetadataInput!) {\n  updateCustomMetadata(input: $input)\n}\n\nmutation CreateOrUpdateCollection($input: CreateOrUpdateCollectionInput!) {\n  createOrUpdateCollection(input: $input) {\n    id\n  }\n}\n\nmutation CreateReviewComment($input: CreateReviewCommentInput!) {\n  createReviewComment(input: $input)\n}\n\nmutation CreateUserMeasurement($input: UserMeasurementInput!) {\n  createUserMeasurement(input: $input)\n}\n\nmutation CreateUserNotificationPlatform($input: CreateUserNotificationPlatformInput!) {\n  createUserNotificationPlatform(input: $input)\n}\n\nmutation CreateUserIntegration($input: CreateUserIntegrationInput!) {\n  createUserIntegration(input: $input) {\n    id\n  }\n}\n\nmutation CreateOrUpdateUserWorkout($input: UserWorkoutInput!) {\n  createOrUpdateUserWorkout(input: $input)\n}\n\nmutation CreateOrUpdateUserWorkoutTemplate($input: UserWorkoutInput!) {\n  createOrUpdateUserWorkoutTemplate(input: $input)\n}\n\nmutation DeleteCollection($collectionName: String!) {\n  deleteCollection(collectionName: $collectionName)\n}\n\nmutation DeleteReview($reviewId: String!) {\n  deleteReview(reviewId: $reviewId)\n}\n\nmutation DeleteS3Object($key: String!) {\n  deleteS3Object(key: $key)\n}\n\nmutation DeleteSeenItem($seenId: String!) {\n  deleteSeenItem(seenId: $seenId) {\n    id\n  }\n}\n\nmutation DeleteUser($toDeleteUserId: String!) {\n  deleteUser(toDeleteUserId: $toDeleteUserId)\n}\n\nmutation DeleteUserIntegration($integrationId: String!) {\n  deleteUserIntegration(integrationId: $integrationId)\n}\n\nmutation DeleteUserMeasurement($timestamp: DateTime!) {\n  deleteUserMeasurement(timestamp: $timestamp)\n}\n\nmutation DeleteUserNotificationPlatform($notificationId: String!) {\n  deleteUserNotificationPlatform(notificationId: $notificationId)\n}\n\nmutation DeleteUserWorkout($workoutId: String!) {\n  deleteUserWorkout(workoutId: $workoutId)\n}\n\nmutation DeleteUserWorkoutTemplate($workoutTemplateId: String!) {\n  deleteUserWorkoutTemplate(workoutTemplateId: $workoutTemplateId)\n}\n\nmutation DeployBackgroundJob($jobName: BackgroundJob!) {\n  deployBackgroundJob(jobName: $jobName)\n}\n\nmutation DeployBulkProgressUpdate($input: [ProgressUpdateInput!]!) {\n  deployBulkProgressUpdate(input: $input)\n}\n\nmutation DeployExportJob {\n  deployExportJob\n}\n\nmutation DeployImportJob($input: DeployImportJobInput!) {\n  deployImportJob(input: $input)\n}\n\nmutation DeployUpdateMetadataJob($metadataId: String!) {\n  deployUpdateMetadataJob(metadataId: $metadataId)\n}\n\nmutation DeployUpdatePersonJob($personId: String!) {\n  deployUpdatePersonJob(personId: $personId)\n}\n\nmutation DeployUpdateMetadataGroupJob($metadataGroupId: String!) {\n  deployUpdateMetadataGroupJob(metadataGroupId: $metadataGroupId)\n}\n\nmutation UpdateSeenItem($input: UpdateSeenItemInput!) {\n  updateSeenItem(input: $input)\n}\n\nmutation UpdateUserNotificationPlatform($input: UpdateUserNotificationPlatformInput!) {\n  updateUserNotificationPlatform(input: $input)\n}\n\nmutation UpdateUserWorkoutAttributes($input: UpdateUserWorkoutAttributesInput!) {\n  updateUserWorkoutAttributes(input: $input)\n}\n\nmutation GenerateAuthToken {\n  generateAuthToken\n}\n\nmutation MergeMetadata($mergeFrom: String!, $mergeInto: String!) {\n  mergeMetadata(mergeFrom: $mergeFrom, mergeInto: $mergeInto)\n}\n\nmutation DisassociateMetadata($metadataId: String!) {\n  disassociateMetadata(metadataId: $metadataId)\n}\n\nmutation CreateOrUpdateReview($input: CreateOrUpdateReviewInput!) {\n  createOrUpdateReview(input: $input) {\n    id\n  }\n}\n\nmutation PresignedPutS3Url($input: PresignedPutUrlInput!) {\n  presignedPutS3Url(input: $input) {\n    key\n    uploadUrl\n  }\n}\n\nmutation RemoveEntityFromCollection($input: ChangeCollectionToEntityInput!) {\n  removeEntityFromCollection(input: $input) {\n    id\n  }\n}\n\nmutation TestUserNotificationPlatforms {\n  testUserNotificationPlatforms\n}\n\nmutation UpdateUser($input: UpdateUserInput!) {\n  updateUser(input: $input) {\n    id\n  }\n}\n\nmutation UpdateUserPreference($input: UserPreferencesInput!) {\n  updateUserPreference(input: $input)\n}\n\nmutation CreateAccessLink($input: CreateAccessLinkInput!) {\n  createAccessLink(input: $input) {\n    id\n  }\n}\n\nmutation ProcessAccessLink($input: ProcessAccessLinkInput!) {\n  processAccessLink(input: $input) {\n    __typename\n    ... on ProcessAccessLinkError {\n      error\n    }\n    ... on ProcessAccessLinkResponse {\n      apiKey\n      redirectTo\n      tokenValidForDays\n    }\n  }\n}\n\nmutation RevokeAccessLink($accessLinkId: String!) {\n  revokeAccessLink(accessLinkId: $accessLinkId)\n}\n\nmutation UpdateUserExerciseSettings($input: UpdateUserExerciseSettings!) {\n  updateUserExerciseSettings(input: $input)\n}\n\nmutation MergeExercise($mergeFrom: String!, $mergeInto: String!) {\n  mergeExercise(mergeFrom: $mergeFrom, mergeInto: $mergeInto)\n}\n\nmutation MarkEntityAsPartial($input: MarkEntityAsPartialInput!) {\n  markEntityAsPartial(input: $input)\n}\n\nmutation MarkNotificationsAsAddressed($notificationIds: [String!]!) {\n  markNotificationsAsAddressed(notificationIds: $notificationIds)\n}\n\nmutation ExpireCacheKey($cacheId: UUID!) {\n  expireCacheKey(cacheId: $cacheId)\n}": types.RegisterUserDocument,
     "query MetadataDetails($metadataId: String!) {\n  metadataDetails(metadataId: $metadataId) {\n    id\n    lot\n    title\n    source\n    isNsfw\n    isPartial\n    sourceUrl\n    identifier\n    description\n    suggestions\n    publishYear\n    publishDate\n    providerRating\n    createdByUserId\n    productionStatus\n    originalLanguage\n    animeSpecifics {\n      episodes\n    }\n    audioBookSpecifics {\n      runtime\n    }\n    movieSpecifics {\n      runtime\n    }\n    genres {\n      id\n      name\n    }\n    group {\n      id\n      name\n      part\n    }\n    watchProviders {\n      name\n      image\n      languages\n    }\n    bookSpecifics {\n      pages\n      isCompilation\n    }\n    mangaSpecifics {\n      volumes\n      chapters\n    }\n    assets {\n      images\n      videos {\n        videoId\n        source\n      }\n    }\n    creators {\n      name\n      items {\n        id\n        name\n        image\n        character\n      }\n    }\n    podcastSpecifics {\n      episodes {\n        id\n        title\n        overview\n        thumbnail\n        number\n        runtime\n        publishDate\n      }\n      totalEpisodes\n    }\n    showSpecifics {\n      totalSeasons\n      totalEpisodes\n      runtime\n      seasons {\n        id\n        seasonNumber\n        name\n        overview\n        backdropImages\n        posterImages\n        episodes {\n          id\n          name\n          posterImages\n          episodeNumber\n          publishDate\n          name\n          overview\n          runtime\n        }\n      }\n    }\n    visualNovelSpecifics {\n      length\n    }\n    videoGameSpecifics {\n      platforms\n    }\n    musicSpecifics {\n      duration\n      viewCount\n      byVariousArtists\n    }\n  }\n}": types.MetadataDetailsDocument,
     "query PersonDetails($personId: String!) {\n  personDetails(personId: $personId) {\n    associatedMetadata {\n      ...PersonDetailsGroupedByRolePart\n    }\n    associatedMetadataGroups {\n      ...PersonDetailsGroupedByRolePart\n    }\n    details {\n      id\n      name\n      place\n      source\n      gender\n      website\n      deathDate\n      birthDate\n      isPartial\n      sourceUrl\n      identifier\n      description\n      displayImages\n      alternateNames\n    }\n  }\n}": types.PersonDetailsDocument,
     "query UserAnalytics($input: UserAnalyticsInput!) {\n  userAnalytics(input: $input) {\n    hours {\n      hour\n      entities {\n        entityId\n        entityLot\n        metadataLot\n      }\n    }\n    activities {\n      groupedBy\n      totalCount\n      totalDuration\n      items {\n        day\n        bookCount\n        showCount\n        totalCount\n        movieCount\n        musicCount\n        animeCount\n        mangaCount\n        workoutCount\n        podcastCount\n        totalDuration\n        totalBookPages\n        audioBookCount\n        videoGameCount\n        totalReviewCount\n        visualNovelCount\n        totalWorkoutReps\n        totalShowDuration\n        totalMovieDuration\n        totalMusicDuration\n        totalMetadataCount\n        totalWorkoutWeight\n        totalPodcastDuration\n        totalWorkoutDistance\n        totalWorkoutRestTime\n        totalWorkoutDuration\n        userMeasurementCount\n        totalVideoGameDuration\n        totalAudioBookDuration\n        totalPersonReviewCount\n        totalVisualNovelDuration\n        totalMetadataReviewCount\n        totalWorkoutPersonalBests\n        totalCollectionReviewCount\n        totalMetadataGroupReviewCount\n      }\n    }\n    fitness {\n      workoutReps\n      workoutCount\n      workoutWeight\n      workoutDistance\n      workoutDuration\n      workoutRestTime\n      measurementCount\n      workoutPersonalBests\n      workoutCaloriesBurnt\n      workoutExercises {\n        count\n        exercise\n      }\n      workoutMuscles {\n        count\n        muscle\n      }\n      workoutEquipments {\n        count\n        equipment\n      }\n    }\n  }\n}": types.UserAnalyticsDocument,
@@ -22,7 +22,7 @@ const documents = {
     "query UserExerciseDetails($exerciseId: String!) {\n  userExerciseDetails(exerciseId: $exerciseId) {\n    collections {\n      ...CollectionPart\n    }\n    reviews {\n      ...ReviewItemPart\n    }\n    history {\n      idx\n      workoutId\n      workoutEndOn\n      bestSet {\n        ...WorkoutSetRecordPart\n      }\n    }\n    details {\n      exerciseId\n      createdOn\n      lastUpdatedOn\n      exerciseNumTimesInteracted\n      exerciseExtraInformation {\n        settings {\n          excludeFromAnalytics\n          setRestTimers {\n            ...SetRestTimersPart\n          }\n        }\n        lifetimeStats {\n          weight\n          reps\n          distance\n          duration\n          personalBestsAchieved\n        }\n        personalBests {\n          lot\n          sets {\n            setIdx\n            workoutId\n            exerciseIdx\n          }\n        }\n      }\n    }\n  }\n}": types.UserExerciseDetailsDocument,
     "query UserMeasurementsList($input: UserMeasurementsListInput!) {\n  userMeasurementsList(input: $input) {\n    timestamp\n    name\n    comment\n    stats {\n      weight\n      bodyMassIndex\n      totalBodyWater\n      muscle\n      leanBodyMass\n      bodyFat\n      boneMass\n      visceralFat\n      waistCircumference\n      waistToHeightRatio\n      hipCircumference\n      waistToHipRatio\n      chestCircumference\n      thighCircumference\n      bicepsCircumference\n      neckCircumference\n      bodyFatCaliper\n      chestSkinfold\n      abdominalSkinfold\n      thighSkinfold\n      basalMetabolicRate\n      totalDailyEnergyExpenditure\n      calories\n      custom\n    }\n  }\n}": types.UserMeasurementsListDocument,
     "query UserMetadataDetails($metadataId: String!) {\n  userMetadataDetails(metadataId: $metadataId) {\n    mediaReason\n    hasInteracted\n    averageRating\n    seenByAllCount\n    seenByUserCount\n    recentlyConsumed\n    reviews {\n      ...ReviewItemPart\n    }\n    history {\n      ...SeenPart\n    }\n    nextEntry {\n      season\n      volume\n      episode\n      chapter\n    }\n    inProgress {\n      ...SeenPart\n    }\n    collections {\n      ...CollectionPart\n    }\n    showProgress {\n      timesSeen\n      seasonNumber\n      episodes {\n        episodeNumber\n        timesSeen\n      }\n    }\n    podcastProgress {\n      episodeNumber\n      timesSeen\n    }\n  }\n}": types.UserMetadataDetailsDocument,
-    "query GetOidcRedirectUrl {\n  getOidcRedirectUrl\n}\n\nquery UserByOidcIssuerId($oidcIssuerId: String!) {\n  userByOidcIssuerId(oidcIssuerId: $oidcIssuerId)\n}\n\nquery GetOidcToken($code: String!) {\n  getOidcToken(code: $code) {\n    subject\n    email\n  }\n}\n\nquery GetPresignedS3Url($key: String!) {\n  getPresignedS3Url(key: $key)\n}\n\nquery UserExports {\n  userExports {\n    url\n    key\n    size\n    endedAt\n    startedAt\n  }\n}\n\nquery UserCollectionsList($name: String) {\n  userCollectionsList(name: $name) {\n    id\n    name\n    count\n    isDefault\n    description\n    creator {\n      id\n      name\n    }\n    collaborators {\n      id\n      name\n    }\n    informationTemplate {\n      lot\n      name\n      required\n      description\n      defaultValue\n    }\n  }\n}\n\nquery UserIntegrations {\n  userIntegrations {\n    id\n    lot\n    name\n    provider\n    createdOn\n    isDisabled\n    maximumProgress\n    minimumProgress\n    lastTriggeredOn\n    syncToOwnedCollection\n  }\n}\n\nquery UserNotificationPlatforms {\n  userNotificationPlatforms {\n    id\n    lot\n    createdOn\n    isDisabled\n    description\n  }\n}\n\nquery UsersList($query: String) {\n  usersList(query: $query) {\n    id\n    lot\n    name\n    isDisabled\n  }\n}\n\nquery UserMetadataRecommendations($shouldRefresh: Boolean) {\n  userMetadataRecommendations(shouldRefresh: $shouldRefresh)\n}\n\nquery UserUpcomingCalendarEvents($input: UserUpcomingCalendarEventInput!) {\n  userUpcomingCalendarEvents(input: $input) {\n    ...CalendarEventPart\n  }\n}\n\nquery UserCalendarEvents($input: UserCalendarEventInput!) {\n  userCalendarEvents(input: $input) {\n    date\n    events {\n      ...CalendarEventPart\n    }\n  }\n}\n\nquery MetadataPartialDetails($metadataId: String!) {\n  metadataPartialDetails(metadataId: $metadataId) {\n    id\n    lot\n    title\n    image\n    publishYear\n  }\n}\n\nquery MetadataGroupsList($input: MetadataGroupsListInput!) {\n  metadataGroupsList(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items\n  }\n}\n\nquery PeopleList($input: PeopleListInput!) {\n  peopleList(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items\n  }\n}\n\nquery UserAccessLinks {\n  userAccessLinks {\n    id\n    name\n    isDemo\n    createdOn\n    expiresOn\n    timesUsed\n    isRevoked\n    maximumUses\n    isAccountDefault\n    isMutationAllowed\n  }\n}\n\nquery ExerciseDetails($exerciseId: String!) {\n  exerciseDetails(exerciseId: $exerciseId) {\n    id\n    lot\n    name\n    level\n    force\n    source\n    muscles\n    mechanic\n    equipment\n    createdByUserId\n    attributes {\n      instructions\n      images\n    }\n  }\n}\n\nquery ExercisesList($input: ExercisesListInput!) {\n  exercisesList(input: $input) {\n    items\n    details {\n      total\n      nextPage\n    }\n  }\n}\n\nquery ImportReports {\n  importReports {\n    id\n    source\n    progress\n    startedOn\n    finishedOn\n    wasSuccess\n    estimatedFinishTime\n    details {\n      import {\n        total\n      }\n      failedItems {\n        lot\n        step\n        error\n        identifier\n      }\n    }\n  }\n}\n\nquery GenresList($input: SearchInput!) {\n  genresList(input: $input) {\n    items\n    details {\n      total\n      nextPage\n    }\n  }\n}\n\nquery GenreDetails($input: GenreDetailsInput!) {\n  genreDetails(input: $input) {\n    details {\n      id\n      name\n      numItems\n    }\n    contents {\n      details {\n        total\n        nextPage\n      }\n      items\n    }\n  }\n}\n\nquery CollectionContents($input: CollectionContentsInput!) {\n  collectionContents(input: $input) {\n    user {\n      id\n      name\n    }\n    reviews {\n      ...ReviewItemPart\n    }\n    results {\n      details {\n        total\n        nextPage\n      }\n      items {\n        entityId\n        entityLot\n      }\n    }\n    details {\n      name\n      description\n      createdOn\n    }\n  }\n}\n\nquery CoreDetails {\n  coreDetails {\n    version\n    docsLink\n    pageSize\n    websiteUrl\n    smtpEnabled\n    oidcEnabled\n    signupAllowed\n    repositoryLink\n    disableTelemetry\n    tokenValidForDays\n    localAuthDisabled\n    fileStorageEnabled\n    peopleSearchSources\n    isServerKeyValidated\n    metadataGroupSourceLotMappings {\n      lot\n      source\n    }\n    metadataLotSourceMappings {\n      lot\n      sources\n    }\n    metadataProviderLanguages {\n      source\n      default\n      supported\n    }\n    frontend {\n      url\n      oidcButtonLabel\n      dashboardMessage\n      umami {\n        domains\n        scriptUrl\n        websiteId\n      }\n    }\n    exerciseParameters {\n      downloadRequired\n      filters {\n        type\n        level\n        force\n        mechanic\n        equipment\n        muscle\n      }\n      lotMapping {\n        lot\n        bests\n      }\n    }\n  }\n}\n\nquery MetadataGroupDetails($metadataGroupId: String!) {\n  metadataGroupDetails(metadataGroupId: $metadataGroupId) {\n    contents\n    details {\n      id\n      lot\n      title\n      parts\n      source\n      isPartial\n      sourceUrl\n      identifier\n      description\n      displayImages\n    }\n  }\n}\n\nquery MetadataGroupSearch($input: MetadataGroupSearchInput!) {\n  metadataGroupSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      name\n      image\n      parts\n    }\n  }\n}\n\nquery MetadataList($input: MetadataListInput!) {\n  metadataList(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items\n  }\n}\n\nquery MetadataSearch($input: MetadataSearchInput!) {\n  metadataSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      title\n      image\n      publishYear\n    }\n  }\n}\n\nquery PeopleSearch($input: PeopleSearchInput!) {\n  peopleSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      name\n      image\n      birthYear\n    }\n  }\n}\n\nquery UserMetadataGroupDetails($metadataGroupId: String!) {\n  userMetadataGroupDetails(metadataGroupId: $metadataGroupId) {\n    recentlyConsumed\n    reviews {\n      ...ReviewItemPart\n    }\n    collections {\n      ...CollectionPart\n    }\n  }\n}\n\nquery UserPersonDetails($personId: String!) {\n  userPersonDetails(personId: $personId) {\n    recentlyConsumed\n    collections {\n      ...CollectionPart\n    }\n    reviews {\n      ...ReviewItemPart\n    }\n  }\n}\n\nquery UserWorkoutDetails($workoutId: String!) {\n  userWorkoutDetails(workoutId: $workoutId) {\n    collections {\n      ...CollectionPart\n    }\n    details {\n      id\n      name\n      endTime\n      duration\n      startTime\n      templateId\n      repeatedFrom\n      caloriesBurnt\n      summary {\n        ...WorkoutSummaryPart\n      }\n      information {\n        ...WorkoutInformationPart\n      }\n    }\n  }\n}\n\nquery UserWorkoutsList($input: SearchInput!) {\n  userWorkoutsList(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items\n  }\n}\n\nquery UserWorkoutTemplateDetails($workoutTemplateId: String!) {\n  userWorkoutTemplateDetails(workoutTemplateId: $workoutTemplateId) {\n    collections {\n      ...CollectionPart\n    }\n    details {\n      id\n      name\n      createdOn\n      summary {\n        ...WorkoutSummaryPart\n      }\n      information {\n        ...WorkoutInformationPart\n      }\n    }\n  }\n}\n\nquery UserWorkoutTemplatesList($input: SearchInput!) {\n  userWorkoutTemplatesList(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items\n  }\n}\n\nquery UserAnalyticsParameters {\n  userAnalyticsParameters {\n    endDate\n    startDate\n  }\n}\n\nquery UserPendingNotifications {\n  userPendingNotifications {\n    id\n    message\n    createdOn\n  }\n}": types.GetOidcRedirectUrlDocument,
+    "query GetOidcRedirectUrl {\n  getOidcRedirectUrl\n}\n\nquery UserByOidcIssuerId($oidcIssuerId: String!) {\n  userByOidcIssuerId(oidcIssuerId: $oidcIssuerId)\n}\n\nquery GetOidcToken($code: String!) {\n  getOidcToken(code: $code) {\n    subject\n    email\n  }\n}\n\nquery GetPresignedS3Url($key: String!) {\n  getPresignedS3Url(key: $key)\n}\n\nquery UserExports {\n  userExports {\n    url\n    key\n    size\n    endedAt\n    startedAt\n  }\n}\n\nquery UserCollectionsList($name: String) {\n  userCollectionsList(name: $name) {\n    cacheId\n    response {\n      id\n      name\n      count\n      isDefault\n      description\n      creator {\n        id\n        name\n      }\n      collaborators {\n        id\n        name\n      }\n      informationTemplate {\n        lot\n        name\n        required\n        description\n        defaultValue\n      }\n    }\n  }\n}\n\nquery UserIntegrations {\n  userIntegrations {\n    id\n    lot\n    name\n    provider\n    createdOn\n    isDisabled\n    maximumProgress\n    minimumProgress\n    lastTriggeredOn\n    syncToOwnedCollection\n  }\n}\n\nquery UserNotificationPlatforms {\n  userNotificationPlatforms {\n    id\n    lot\n    createdOn\n    isDisabled\n    description\n  }\n}\n\nquery UsersList($query: String) {\n  usersList(query: $query) {\n    id\n    lot\n    name\n    isDisabled\n  }\n}\n\nquery UserMetadataRecommendations {\n  userMetadataRecommendations {\n    cacheId\n    response\n  }\n}\n\nquery UserUpcomingCalendarEvents($input: UserUpcomingCalendarEventInput!) {\n  userUpcomingCalendarEvents(input: $input) {\n    ...CalendarEventPart\n  }\n}\n\nquery UserCalendarEvents($input: UserCalendarEventInput!) {\n  userCalendarEvents(input: $input) {\n    date\n    events {\n      ...CalendarEventPart\n    }\n  }\n}\n\nquery MetadataPartialDetails($metadataId: String!) {\n  metadataPartialDetails(metadataId: $metadataId) {\n    id\n    lot\n    title\n    image\n    publishYear\n  }\n}\n\nquery UserMetadataGroupsList($input: UserMetadataGroupsListInput!) {\n  userMetadataGroupsList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery UserPeopleList($input: UserPeopleListInput!) {\n  userPeopleList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery UserAccessLinks {\n  userAccessLinks {\n    id\n    name\n    isDemo\n    createdOn\n    expiresOn\n    timesUsed\n    isRevoked\n    maximumUses\n    isAccountDefault\n    isMutationAllowed\n  }\n}\n\nquery ExerciseDetails($exerciseId: String!) {\n  exerciseDetails(exerciseId: $exerciseId) {\n    id\n    lot\n    name\n    level\n    force\n    source\n    muscles\n    mechanic\n    equipment\n    createdByUserId\n    attributes {\n      instructions\n      images\n    }\n  }\n}\n\nquery UserExercisesList($input: UserExercisesListInput!) {\n  userExercisesList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery ImportReports {\n  importReports {\n    id\n    source\n    progress\n    startedOn\n    finishedOn\n    wasSuccess\n    estimatedFinishTime\n    details {\n      import {\n        total\n      }\n      failedItems {\n        lot\n        step\n        error\n        identifier\n      }\n    }\n  }\n}\n\nquery GenresList($input: SearchInput!) {\n  genresList(input: $input) {\n    items\n    details {\n      total\n      nextPage\n    }\n  }\n}\n\nquery GenreDetails($input: GenreDetailsInput!) {\n  genreDetails(input: $input) {\n    details {\n      id\n      name\n      numItems\n    }\n    contents {\n      details {\n        total\n        nextPage\n      }\n      items\n    }\n  }\n}\n\nquery CollectionContents($input: CollectionContentsInput!) {\n  collectionContents(input: $input) {\n    cacheId\n    response {\n      totalItems\n      user {\n        id\n        name\n      }\n      reviews {\n        ...ReviewItemPart\n      }\n      details {\n        name\n        createdOn\n        description\n      }\n      results {\n        details {\n          total\n          nextPage\n        }\n        items {\n          entityId\n          entityLot\n        }\n      }\n    }\n  }\n}\n\nquery CoreDetails {\n  coreDetails {\n    version\n    docsLink\n    pageSize\n    websiteUrl\n    smtpEnabled\n    oidcEnabled\n    signupAllowed\n    repositoryLink\n    disableTelemetry\n    tokenValidForDays\n    localAuthDisabled\n    fileStorageEnabled\n    peopleSearchSources\n    isServerKeyValidated\n    metadataGroupSourceLotMappings {\n      lot\n      source\n    }\n    metadataLotSourceMappings {\n      lot\n      sources\n    }\n    metadataProviderLanguages {\n      source\n      default\n      supported\n    }\n    frontend {\n      url\n      oidcButtonLabel\n      dashboardMessage\n      umami {\n        domains\n        scriptUrl\n        websiteId\n      }\n    }\n    exerciseParameters {\n      lotMapping {\n        lot\n        bests\n      }\n      filters {\n        type\n        level\n        force\n        muscle\n        mechanic\n        equipment\n      }\n    }\n  }\n}\n\nquery MetadataGroupDetails($metadataGroupId: String!) {\n  metadataGroupDetails(metadataGroupId: $metadataGroupId) {\n    contents\n    details {\n      id\n      lot\n      title\n      parts\n      source\n      isPartial\n      sourceUrl\n      identifier\n      description\n      displayImages\n    }\n  }\n}\n\nquery MetadataGroupSearch($input: MetadataGroupSearchInput!) {\n  metadataGroupSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      name\n      image\n      parts\n    }\n  }\n}\n\nquery UserMetadataList($input: UserMetadataListInput!) {\n  userMetadataList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery MetadataSearch($input: MetadataSearchInput!) {\n  metadataSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      title\n      image\n      publishYear\n    }\n  }\n}\n\nquery PeopleSearch($input: PeopleSearchInput!) {\n  peopleSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      name\n      image\n      birthYear\n    }\n  }\n}\n\nquery UserMetadataGroupDetails($metadataGroupId: String!) {\n  userMetadataGroupDetails(metadataGroupId: $metadataGroupId) {\n    recentlyConsumed\n    reviews {\n      ...ReviewItemPart\n    }\n    collections {\n      ...CollectionPart\n    }\n  }\n}\n\nquery UserPersonDetails($personId: String!) {\n  userPersonDetails(personId: $personId) {\n    recentlyConsumed\n    collections {\n      ...CollectionPart\n    }\n    reviews {\n      ...ReviewItemPart\n    }\n  }\n}\n\nquery UserWorkoutDetails($workoutId: String!) {\n  userWorkoutDetails(workoutId: $workoutId) {\n    collections {\n      ...CollectionPart\n    }\n    details {\n      id\n      name\n      endTime\n      duration\n      startTime\n      templateId\n      repeatedFrom\n      caloriesBurnt\n      summary {\n        ...WorkoutSummaryPart\n      }\n      information {\n        ...WorkoutInformationPart\n      }\n    }\n  }\n}\n\nquery UserWorkoutsList($input: UserTemplatesOrWorkoutsListInput!) {\n  userWorkoutsList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery UserWorkoutTemplateDetails($workoutTemplateId: String!) {\n  userWorkoutTemplateDetails(workoutTemplateId: $workoutTemplateId) {\n    collections {\n      ...CollectionPart\n    }\n    details {\n      id\n      name\n      createdOn\n      summary {\n        ...WorkoutSummaryPart\n      }\n      information {\n        ...WorkoutInformationPart\n      }\n    }\n  }\n}\n\nquery UserWorkoutTemplatesList($input: UserTemplatesOrWorkoutsListInput!) {\n  userWorkoutTemplatesList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery UserAnalyticsParameters {\n  userAnalyticsParameters {\n    endDate\n    startDate\n  }\n}\n\nquery UserPendingNotifications {\n  userPendingNotifications {\n    id\n    message\n    createdOn\n  }\n}": types.GetOidcRedirectUrlDocument,
     "fragment SeenPodcastExtraInformationPart on SeenPodcastExtraInformation {\n  episode\n}\n\nfragment SeenShowExtraInformationPart on SeenShowExtraInformation {\n  episode\n  season\n}\n\nfragment SeenAnimeExtraInformationPart on SeenAnimeExtraInformation {\n  episode\n}\n\nfragment SeenMangaExtraInformationPart on SeenMangaExtraInformation {\n  volume\n  chapter\n}\n\nfragment CalendarEventPart on GraphqlCalendarEvent {\n  date\n  metadataId\n  metadataLot\n  metadataText\n  metadataImage\n  calendarEventId\n  showExtraInformation {\n    ...SeenShowExtraInformationPart\n  }\n  podcastExtraInformation {\n    ...SeenPodcastExtraInformationPart\n  }\n  animeExtraInformation {\n    ...SeenAnimeExtraInformationPart\n  }\n}\n\nfragment SeenPart on Seen {\n  id\n  state\n  progress\n  reviewId\n  startedOn\n  finishedOn\n  lastUpdatedOn\n  manualTimeSpent\n  numTimesUpdated\n  providerWatchedOn\n  showExtraInformation {\n    ...SeenShowExtraInformationPart\n  }\n  podcastExtraInformation {\n    ...SeenPodcastExtraInformationPart\n  }\n  animeExtraInformation {\n    ...SeenAnimeExtraInformationPart\n  }\n  mangaExtraInformation {\n    ...SeenMangaExtraInformationPart\n  }\n}\n\nfragment MetadataSearchItemPart on MetadataSearchItem {\n  title\n  image\n  identifier\n  publishYear\n}\n\nfragment WorkoutOrExerciseTotalsPart on WorkoutOrExerciseTotals {\n  reps\n  weight\n  distance\n  duration\n  restTime\n  personalBestsAchieved\n}\n\nfragment EntityAssetsPart on EntityAssets {\n  images\n  videos\n}\n\nfragment WorkoutSetStatisticPart on WorkoutSetStatistic {\n  reps\n  pace\n  oneRm\n  weight\n  volume\n  duration\n  distance\n}\n\nfragment WorkoutSetRecordPart on WorkoutSetRecord {\n  lot\n  personalBests\n  statistic {\n    ...WorkoutSetStatisticPart\n  }\n}\n\nfragment WorkoutSummaryPart on WorkoutSummary {\n  total {\n    ...WorkoutOrExerciseTotalsPart\n  }\n  exercises {\n    id\n    lot\n    numSets\n    bestSet {\n      ...WorkoutSetRecordPart\n    }\n  }\n  focused {\n    lots {\n      lot\n      exercises\n    }\n    levels {\n      level\n      exercises\n    }\n    forces {\n      force\n      exercises\n    }\n    muscles {\n      muscle\n      exercises\n    }\n    equipments {\n      equipment\n      exercises\n    }\n  }\n}\n\nfragment CollectionPart on Collection {\n  id\n  name\n  userId\n}\n\nfragment ReviewItemPart on ReviewItem {\n  id\n  rating\n  postedOn\n  isSpoiler\n  visibility\n  textOriginal\n  textRendered\n  seenItemsAssociatedWith\n  postedBy {\n    id\n    name\n  }\n  comments {\n    id\n    text\n    likedBy\n    createdOn\n    user {\n      id\n      name\n    }\n  }\n  showExtraInformation {\n    season\n    episode\n  }\n  podcastExtraInformation {\n    episode\n  }\n  animeExtraInformation {\n    ...SeenAnimeExtraInformationPart\n  }\n  mangaExtraInformation {\n    ...SeenMangaExtraInformationPart\n  }\n}\n\nfragment WorkoutInformationPart on WorkoutInformation {\n  comment\n  assets {\n    ...EntityAssetsPart\n  }\n  supersets {\n    color\n    exercises\n  }\n  exercises {\n    id\n    lot\n    notes\n    total {\n      ...WorkoutOrExerciseTotalsPart\n    }\n    assets {\n      ...EntityAssetsPart\n    }\n    sets {\n      lot\n      rpe\n      note\n      restTime\n      confirmedAt\n      personalBests\n      statistic {\n        ...WorkoutSetStatisticPart\n      }\n    }\n  }\n}\n\nfragment SetRestTimersPart on SetRestTimersSettings {\n  drop\n  warmup\n  normal\n  failure\n}\n\nfragment PersonDetailsGroupedByRolePart on PersonDetailsGroupedByRole {\n  name\n  count\n  items {\n    entityId\n    character\n  }\n}": types.SeenPodcastExtraInformationPartFragmentDoc,
 };
 
@@ -43,7 +43,7 @@ export function graphql(source: string): unknown;
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
-export function graphql(source: "mutation RegisterUser($input: RegisterUserInput!) {\n  registerUser(input: $input) {\n    __typename\n    ... on RegisterError {\n      error\n    }\n    ... on StringIdObject {\n      id\n    }\n  }\n}\n\nmutation LoginUser($input: AuthUserInput!) {\n  loginUser(input: $input) {\n    __typename\n    ... on LoginError {\n      error\n    }\n    ... on LoginResponse {\n      apiKey\n    }\n  }\n}\n\nmutation AddEntityToCollection($input: ChangeCollectionToEntityInput!) {\n  addEntityToCollection(input: $input)\n}\n\nmutation CommitMetadata($input: CommitMediaInput!) {\n  commitMetadata(input: $input) {\n    id\n  }\n}\n\nmutation CommitMetadataGroup($input: CommitMediaInput!) {\n  commitMetadataGroup(input: $input) {\n    id\n  }\n}\n\nmutation CommitPerson($input: CommitPersonInput!) {\n  commitPerson(input: $input) {\n    id\n  }\n}\n\nmutation CreateCustomExercise($input: ExerciseInput!) {\n  createCustomExercise(input: $input)\n}\n\nmutation UpdateCustomExercise($input: UpdateCustomExerciseInput!) {\n  updateCustomExercise(input: $input)\n}\n\nmutation UpdateUserIntegration($input: UpdateUserIntegrationInput!) {\n  updateUserIntegration(input: $input)\n}\n\nmutation CreateCustomMetadata($input: CreateCustomMetadataInput!) {\n  createCustomMetadata(input: $input) {\n    id\n  }\n}\n\nmutation UpdateCustomMetadata($input: UpdateCustomMetadataInput!) {\n  updateCustomMetadata(input: $input)\n}\n\nmutation CreateOrUpdateCollection($input: CreateOrUpdateCollectionInput!) {\n  createOrUpdateCollection(input: $input) {\n    id\n  }\n}\n\nmutation CreateReviewComment($input: CreateReviewCommentInput!) {\n  createReviewComment(input: $input)\n}\n\nmutation CreateUserMeasurement($input: UserMeasurementInput!) {\n  createUserMeasurement(input: $input)\n}\n\nmutation CreateUserNotificationPlatform($input: CreateUserNotificationPlatformInput!) {\n  createUserNotificationPlatform(input: $input)\n}\n\nmutation CreateUserIntegration($input: CreateUserIntegrationInput!) {\n  createUserIntegration(input: $input) {\n    id\n  }\n}\n\nmutation CreateOrUpdateUserWorkout($input: UserWorkoutInput!) {\n  createOrUpdateUserWorkout(input: $input)\n}\n\nmutation CreateOrUpdateUserWorkoutTemplate($input: UserWorkoutInput!) {\n  createOrUpdateUserWorkoutTemplate(input: $input)\n}\n\nmutation DeleteCollection($collectionName: String!) {\n  deleteCollection(collectionName: $collectionName)\n}\n\nmutation DeleteReview($reviewId: String!) {\n  deleteReview(reviewId: $reviewId)\n}\n\nmutation DeleteS3Object($key: String!) {\n  deleteS3Object(key: $key)\n}\n\nmutation DeleteSeenItem($seenId: String!) {\n  deleteSeenItem(seenId: $seenId) {\n    id\n  }\n}\n\nmutation DeleteUser($toDeleteUserId: String!) {\n  deleteUser(toDeleteUserId: $toDeleteUserId)\n}\n\nmutation DeleteUserIntegration($integrationId: String!) {\n  deleteUserIntegration(integrationId: $integrationId)\n}\n\nmutation DeleteUserMeasurement($timestamp: DateTime!) {\n  deleteUserMeasurement(timestamp: $timestamp)\n}\n\nmutation DeleteUserNotificationPlatform($notificationId: String!) {\n  deleteUserNotificationPlatform(notificationId: $notificationId)\n}\n\nmutation DeleteUserWorkout($workoutId: String!) {\n  deleteUserWorkout(workoutId: $workoutId)\n}\n\nmutation DeleteUserWorkoutTemplate($workoutTemplateId: String!) {\n  deleteUserWorkoutTemplate(workoutTemplateId: $workoutTemplateId)\n}\n\nmutation DeployBackgroundJob($jobName: BackgroundJob!) {\n  deployBackgroundJob(jobName: $jobName)\n}\n\nmutation DeployBulkProgressUpdate($input: [ProgressUpdateInput!]!) {\n  deployBulkProgressUpdate(input: $input)\n}\n\nmutation DeployExportJob {\n  deployExportJob\n}\n\nmutation DeployImportJob($input: DeployImportJobInput!) {\n  deployImportJob(input: $input)\n}\n\nmutation DeployUpdateMetadataJob($metadataId: String!) {\n  deployUpdateMetadataJob(metadataId: $metadataId)\n}\n\nmutation DeployUpdatePersonJob($personId: String!) {\n  deployUpdatePersonJob(personId: $personId)\n}\n\nmutation DeployUpdateMetadataGroupJob($metadataGroupId: String!) {\n  deployUpdateMetadataGroupJob(metadataGroupId: $metadataGroupId)\n}\n\nmutation UpdateSeenItem($input: UpdateSeenItemInput!) {\n  updateSeenItem(input: $input)\n}\n\nmutation UpdateUserNotificationPlatform($input: UpdateUserNotificationPlatformInput!) {\n  updateUserNotificationPlatform(input: $input)\n}\n\nmutation UpdateUserWorkoutAttributes($input: UpdateUserWorkoutAttributesInput!) {\n  updateUserWorkoutAttributes(input: $input)\n}\n\nmutation GenerateAuthToken {\n  generateAuthToken\n}\n\nmutation MergeMetadata($mergeFrom: String!, $mergeInto: String!) {\n  mergeMetadata(mergeFrom: $mergeFrom, mergeInto: $mergeInto)\n}\n\nmutation DisassociateMetadata($metadataId: String!) {\n  disassociateMetadata(metadataId: $metadataId)\n}\n\nmutation CreateOrUpdateReview($input: CreateOrUpdateReviewInput!) {\n  createOrUpdateReview(input: $input) {\n    id\n  }\n}\n\nmutation PresignedPutS3Url($input: PresignedPutUrlInput!) {\n  presignedPutS3Url(input: $input) {\n    key\n    uploadUrl\n  }\n}\n\nmutation RemoveEntityFromCollection($input: ChangeCollectionToEntityInput!) {\n  removeEntityFromCollection(input: $input) {\n    id\n  }\n}\n\nmutation TestUserNotificationPlatforms {\n  testUserNotificationPlatforms\n}\n\nmutation UpdateUser($input: UpdateUserInput!) {\n  updateUser(input: $input) {\n    id\n  }\n}\n\nmutation UpdateUserPreference($input: UserPreferencesInput!) {\n  updateUserPreference(input: $input)\n}\n\nmutation CreateAccessLink($input: CreateAccessLinkInput!) {\n  createAccessLink(input: $input) {\n    id\n  }\n}\n\nmutation ProcessAccessLink($input: ProcessAccessLinkInput!) {\n  processAccessLink(input: $input) {\n    __typename\n    ... on ProcessAccessLinkError {\n      error\n    }\n    ... on ProcessAccessLinkResponse {\n      apiKey\n      redirectTo\n      tokenValidForDays\n    }\n  }\n}\n\nmutation RevokeAccessLink($accessLinkId: String!) {\n  revokeAccessLink(accessLinkId: $accessLinkId)\n}\n\nmutation UpdateUserExerciseSettings($input: UpdateUserExerciseSettings!) {\n  updateUserExerciseSettings(input: $input)\n}\n\nmutation MergeExercise($mergeFrom: String!, $mergeInto: String!) {\n  mergeExercise(mergeFrom: $mergeFrom, mergeInto: $mergeInto)\n}\n\nmutation MarkEntityAsPartial($input: MarkEntityAsPartialInput!) {\n  markEntityAsPartial(input: $input)\n}\n\nmutation MarkNotificationsAsAddressed($notificationIds: [String!]!) {\n  markNotificationsAsAddressed(notificationIds: $notificationIds)\n}"): (typeof documents)["mutation RegisterUser($input: RegisterUserInput!) {\n  registerUser(input: $input) {\n    __typename\n    ... on RegisterError {\n      error\n    }\n    ... on StringIdObject {\n      id\n    }\n  }\n}\n\nmutation LoginUser($input: AuthUserInput!) {\n  loginUser(input: $input) {\n    __typename\n    ... on LoginError {\n      error\n    }\n    ... on LoginResponse {\n      apiKey\n    }\n  }\n}\n\nmutation AddEntityToCollection($input: ChangeCollectionToEntityInput!) {\n  addEntityToCollection(input: $input)\n}\n\nmutation CommitMetadata($input: CommitMediaInput!) {\n  commitMetadata(input: $input) {\n    id\n  }\n}\n\nmutation CommitMetadataGroup($input: CommitMediaInput!) {\n  commitMetadataGroup(input: $input) {\n    id\n  }\n}\n\nmutation CommitPerson($input: CommitPersonInput!) {\n  commitPerson(input: $input) {\n    id\n  }\n}\n\nmutation CreateCustomExercise($input: ExerciseInput!) {\n  createCustomExercise(input: $input)\n}\n\nmutation UpdateCustomExercise($input: UpdateCustomExerciseInput!) {\n  updateCustomExercise(input: $input)\n}\n\nmutation UpdateUserIntegration($input: UpdateUserIntegrationInput!) {\n  updateUserIntegration(input: $input)\n}\n\nmutation CreateCustomMetadata($input: CreateCustomMetadataInput!) {\n  createCustomMetadata(input: $input) {\n    id\n  }\n}\n\nmutation UpdateCustomMetadata($input: UpdateCustomMetadataInput!) {\n  updateCustomMetadata(input: $input)\n}\n\nmutation CreateOrUpdateCollection($input: CreateOrUpdateCollectionInput!) {\n  createOrUpdateCollection(input: $input) {\n    id\n  }\n}\n\nmutation CreateReviewComment($input: CreateReviewCommentInput!) {\n  createReviewComment(input: $input)\n}\n\nmutation CreateUserMeasurement($input: UserMeasurementInput!) {\n  createUserMeasurement(input: $input)\n}\n\nmutation CreateUserNotificationPlatform($input: CreateUserNotificationPlatformInput!) {\n  createUserNotificationPlatform(input: $input)\n}\n\nmutation CreateUserIntegration($input: CreateUserIntegrationInput!) {\n  createUserIntegration(input: $input) {\n    id\n  }\n}\n\nmutation CreateOrUpdateUserWorkout($input: UserWorkoutInput!) {\n  createOrUpdateUserWorkout(input: $input)\n}\n\nmutation CreateOrUpdateUserWorkoutTemplate($input: UserWorkoutInput!) {\n  createOrUpdateUserWorkoutTemplate(input: $input)\n}\n\nmutation DeleteCollection($collectionName: String!) {\n  deleteCollection(collectionName: $collectionName)\n}\n\nmutation DeleteReview($reviewId: String!) {\n  deleteReview(reviewId: $reviewId)\n}\n\nmutation DeleteS3Object($key: String!) {\n  deleteS3Object(key: $key)\n}\n\nmutation DeleteSeenItem($seenId: String!) {\n  deleteSeenItem(seenId: $seenId) {\n    id\n  }\n}\n\nmutation DeleteUser($toDeleteUserId: String!) {\n  deleteUser(toDeleteUserId: $toDeleteUserId)\n}\n\nmutation DeleteUserIntegration($integrationId: String!) {\n  deleteUserIntegration(integrationId: $integrationId)\n}\n\nmutation DeleteUserMeasurement($timestamp: DateTime!) {\n  deleteUserMeasurement(timestamp: $timestamp)\n}\n\nmutation DeleteUserNotificationPlatform($notificationId: String!) {\n  deleteUserNotificationPlatform(notificationId: $notificationId)\n}\n\nmutation DeleteUserWorkout($workoutId: String!) {\n  deleteUserWorkout(workoutId: $workoutId)\n}\n\nmutation DeleteUserWorkoutTemplate($workoutTemplateId: String!) {\n  deleteUserWorkoutTemplate(workoutTemplateId: $workoutTemplateId)\n}\n\nmutation DeployBackgroundJob($jobName: BackgroundJob!) {\n  deployBackgroundJob(jobName: $jobName)\n}\n\nmutation DeployBulkProgressUpdate($input: [ProgressUpdateInput!]!) {\n  deployBulkProgressUpdate(input: $input)\n}\n\nmutation DeployExportJob {\n  deployExportJob\n}\n\nmutation DeployImportJob($input: DeployImportJobInput!) {\n  deployImportJob(input: $input)\n}\n\nmutation DeployUpdateMetadataJob($metadataId: String!) {\n  deployUpdateMetadataJob(metadataId: $metadataId)\n}\n\nmutation DeployUpdatePersonJob($personId: String!) {\n  deployUpdatePersonJob(personId: $personId)\n}\n\nmutation DeployUpdateMetadataGroupJob($metadataGroupId: String!) {\n  deployUpdateMetadataGroupJob(metadataGroupId: $metadataGroupId)\n}\n\nmutation UpdateSeenItem($input: UpdateSeenItemInput!) {\n  updateSeenItem(input: $input)\n}\n\nmutation UpdateUserNotificationPlatform($input: UpdateUserNotificationPlatformInput!) {\n  updateUserNotificationPlatform(input: $input)\n}\n\nmutation UpdateUserWorkoutAttributes($input: UpdateUserWorkoutAttributesInput!) {\n  updateUserWorkoutAttributes(input: $input)\n}\n\nmutation GenerateAuthToken {\n  generateAuthToken\n}\n\nmutation MergeMetadata($mergeFrom: String!, $mergeInto: String!) {\n  mergeMetadata(mergeFrom: $mergeFrom, mergeInto: $mergeInto)\n}\n\nmutation DisassociateMetadata($metadataId: String!) {\n  disassociateMetadata(metadataId: $metadataId)\n}\n\nmutation CreateOrUpdateReview($input: CreateOrUpdateReviewInput!) {\n  createOrUpdateReview(input: $input) {\n    id\n  }\n}\n\nmutation PresignedPutS3Url($input: PresignedPutUrlInput!) {\n  presignedPutS3Url(input: $input) {\n    key\n    uploadUrl\n  }\n}\n\nmutation RemoveEntityFromCollection($input: ChangeCollectionToEntityInput!) {\n  removeEntityFromCollection(input: $input) {\n    id\n  }\n}\n\nmutation TestUserNotificationPlatforms {\n  testUserNotificationPlatforms\n}\n\nmutation UpdateUser($input: UpdateUserInput!) {\n  updateUser(input: $input) {\n    id\n  }\n}\n\nmutation UpdateUserPreference($input: UserPreferencesInput!) {\n  updateUserPreference(input: $input)\n}\n\nmutation CreateAccessLink($input: CreateAccessLinkInput!) {\n  createAccessLink(input: $input) {\n    id\n  }\n}\n\nmutation ProcessAccessLink($input: ProcessAccessLinkInput!) {\n  processAccessLink(input: $input) {\n    __typename\n    ... on ProcessAccessLinkError {\n      error\n    }\n    ... on ProcessAccessLinkResponse {\n      apiKey\n      redirectTo\n      tokenValidForDays\n    }\n  }\n}\n\nmutation RevokeAccessLink($accessLinkId: String!) {\n  revokeAccessLink(accessLinkId: $accessLinkId)\n}\n\nmutation UpdateUserExerciseSettings($input: UpdateUserExerciseSettings!) {\n  updateUserExerciseSettings(input: $input)\n}\n\nmutation MergeExercise($mergeFrom: String!, $mergeInto: String!) {\n  mergeExercise(mergeFrom: $mergeFrom, mergeInto: $mergeInto)\n}\n\nmutation MarkEntityAsPartial($input: MarkEntityAsPartialInput!) {\n  markEntityAsPartial(input: $input)\n}\n\nmutation MarkNotificationsAsAddressed($notificationIds: [String!]!) {\n  markNotificationsAsAddressed(notificationIds: $notificationIds)\n}"];
+export function graphql(source: "mutation RegisterUser($input: RegisterUserInput!) {\n  registerUser(input: $input) {\n    __typename\n    ... on RegisterError {\n      error\n    }\n    ... on StringIdObject {\n      id\n    }\n  }\n}\n\nmutation LoginUser($input: AuthUserInput!) {\n  loginUser(input: $input) {\n    __typename\n    ... on LoginError {\n      error\n    }\n    ... on LoginResponse {\n      apiKey\n    }\n  }\n}\n\nmutation AddEntityToCollection($input: ChangeCollectionToEntityInput!) {\n  addEntityToCollection(input: $input)\n}\n\nmutation CommitMetadata($input: CommitMediaInput!) {\n  commitMetadata(input: $input) {\n    id\n  }\n}\n\nmutation CommitMetadataGroup($input: CommitMediaInput!) {\n  commitMetadataGroup(input: $input) {\n    id\n  }\n}\n\nmutation CommitPerson($input: CommitPersonInput!) {\n  commitPerson(input: $input) {\n    id\n  }\n}\n\nmutation CreateCustomExercise($input: ExerciseInput!) {\n  createCustomExercise(input: $input)\n}\n\nmutation UpdateCustomExercise($input: UpdateCustomExerciseInput!) {\n  updateCustomExercise(input: $input)\n}\n\nmutation UpdateUserIntegration($input: UpdateUserIntegrationInput!) {\n  updateUserIntegration(input: $input)\n}\n\nmutation CreateCustomMetadata($input: CreateCustomMetadataInput!) {\n  createCustomMetadata(input: $input) {\n    id\n  }\n}\n\nmutation UpdateCustomMetadata($input: UpdateCustomMetadataInput!) {\n  updateCustomMetadata(input: $input)\n}\n\nmutation CreateOrUpdateCollection($input: CreateOrUpdateCollectionInput!) {\n  createOrUpdateCollection(input: $input) {\n    id\n  }\n}\n\nmutation CreateReviewComment($input: CreateReviewCommentInput!) {\n  createReviewComment(input: $input)\n}\n\nmutation CreateUserMeasurement($input: UserMeasurementInput!) {\n  createUserMeasurement(input: $input)\n}\n\nmutation CreateUserNotificationPlatform($input: CreateUserNotificationPlatformInput!) {\n  createUserNotificationPlatform(input: $input)\n}\n\nmutation CreateUserIntegration($input: CreateUserIntegrationInput!) {\n  createUserIntegration(input: $input) {\n    id\n  }\n}\n\nmutation CreateOrUpdateUserWorkout($input: UserWorkoutInput!) {\n  createOrUpdateUserWorkout(input: $input)\n}\n\nmutation CreateOrUpdateUserWorkoutTemplate($input: UserWorkoutInput!) {\n  createOrUpdateUserWorkoutTemplate(input: $input)\n}\n\nmutation DeleteCollection($collectionName: String!) {\n  deleteCollection(collectionName: $collectionName)\n}\n\nmutation DeleteReview($reviewId: String!) {\n  deleteReview(reviewId: $reviewId)\n}\n\nmutation DeleteS3Object($key: String!) {\n  deleteS3Object(key: $key)\n}\n\nmutation DeleteSeenItem($seenId: String!) {\n  deleteSeenItem(seenId: $seenId) {\n    id\n  }\n}\n\nmutation DeleteUser($toDeleteUserId: String!) {\n  deleteUser(toDeleteUserId: $toDeleteUserId)\n}\n\nmutation DeleteUserIntegration($integrationId: String!) {\n  deleteUserIntegration(integrationId: $integrationId)\n}\n\nmutation DeleteUserMeasurement($timestamp: DateTime!) {\n  deleteUserMeasurement(timestamp: $timestamp)\n}\n\nmutation DeleteUserNotificationPlatform($notificationId: String!) {\n  deleteUserNotificationPlatform(notificationId: $notificationId)\n}\n\nmutation DeleteUserWorkout($workoutId: String!) {\n  deleteUserWorkout(workoutId: $workoutId)\n}\n\nmutation DeleteUserWorkoutTemplate($workoutTemplateId: String!) {\n  deleteUserWorkoutTemplate(workoutTemplateId: $workoutTemplateId)\n}\n\nmutation DeployBackgroundJob($jobName: BackgroundJob!) {\n  deployBackgroundJob(jobName: $jobName)\n}\n\nmutation DeployBulkProgressUpdate($input: [ProgressUpdateInput!]!) {\n  deployBulkProgressUpdate(input: $input)\n}\n\nmutation DeployExportJob {\n  deployExportJob\n}\n\nmutation DeployImportJob($input: DeployImportJobInput!) {\n  deployImportJob(input: $input)\n}\n\nmutation DeployUpdateMetadataJob($metadataId: String!) {\n  deployUpdateMetadataJob(metadataId: $metadataId)\n}\n\nmutation DeployUpdatePersonJob($personId: String!) {\n  deployUpdatePersonJob(personId: $personId)\n}\n\nmutation DeployUpdateMetadataGroupJob($metadataGroupId: String!) {\n  deployUpdateMetadataGroupJob(metadataGroupId: $metadataGroupId)\n}\n\nmutation UpdateSeenItem($input: UpdateSeenItemInput!) {\n  updateSeenItem(input: $input)\n}\n\nmutation UpdateUserNotificationPlatform($input: UpdateUserNotificationPlatformInput!) {\n  updateUserNotificationPlatform(input: $input)\n}\n\nmutation UpdateUserWorkoutAttributes($input: UpdateUserWorkoutAttributesInput!) {\n  updateUserWorkoutAttributes(input: $input)\n}\n\nmutation GenerateAuthToken {\n  generateAuthToken\n}\n\nmutation MergeMetadata($mergeFrom: String!, $mergeInto: String!) {\n  mergeMetadata(mergeFrom: $mergeFrom, mergeInto: $mergeInto)\n}\n\nmutation DisassociateMetadata($metadataId: String!) {\n  disassociateMetadata(metadataId: $metadataId)\n}\n\nmutation CreateOrUpdateReview($input: CreateOrUpdateReviewInput!) {\n  createOrUpdateReview(input: $input) {\n    id\n  }\n}\n\nmutation PresignedPutS3Url($input: PresignedPutUrlInput!) {\n  presignedPutS3Url(input: $input) {\n    key\n    uploadUrl\n  }\n}\n\nmutation RemoveEntityFromCollection($input: ChangeCollectionToEntityInput!) {\n  removeEntityFromCollection(input: $input) {\n    id\n  }\n}\n\nmutation TestUserNotificationPlatforms {\n  testUserNotificationPlatforms\n}\n\nmutation UpdateUser($input: UpdateUserInput!) {\n  updateUser(input: $input) {\n    id\n  }\n}\n\nmutation UpdateUserPreference($input: UserPreferencesInput!) {\n  updateUserPreference(input: $input)\n}\n\nmutation CreateAccessLink($input: CreateAccessLinkInput!) {\n  createAccessLink(input: $input) {\n    id\n  }\n}\n\nmutation ProcessAccessLink($input: ProcessAccessLinkInput!) {\n  processAccessLink(input: $input) {\n    __typename\n    ... on ProcessAccessLinkError {\n      error\n    }\n    ... on ProcessAccessLinkResponse {\n      apiKey\n      redirectTo\n      tokenValidForDays\n    }\n  }\n}\n\nmutation RevokeAccessLink($accessLinkId: String!) {\n  revokeAccessLink(accessLinkId: $accessLinkId)\n}\n\nmutation UpdateUserExerciseSettings($input: UpdateUserExerciseSettings!) {\n  updateUserExerciseSettings(input: $input)\n}\n\nmutation MergeExercise($mergeFrom: String!, $mergeInto: String!) {\n  mergeExercise(mergeFrom: $mergeFrom, mergeInto: $mergeInto)\n}\n\nmutation MarkEntityAsPartial($input: MarkEntityAsPartialInput!) {\n  markEntityAsPartial(input: $input)\n}\n\nmutation MarkNotificationsAsAddressed($notificationIds: [String!]!) {\n  markNotificationsAsAddressed(notificationIds: $notificationIds)\n}\n\nmutation ExpireCacheKey($cacheId: UUID!) {\n  expireCacheKey(cacheId: $cacheId)\n}"): (typeof documents)["mutation RegisterUser($input: RegisterUserInput!) {\n  registerUser(input: $input) {\n    __typename\n    ... on RegisterError {\n      error\n    }\n    ... on StringIdObject {\n      id\n    }\n  }\n}\n\nmutation LoginUser($input: AuthUserInput!) {\n  loginUser(input: $input) {\n    __typename\n    ... on LoginError {\n      error\n    }\n    ... on LoginResponse {\n      apiKey\n    }\n  }\n}\n\nmutation AddEntityToCollection($input: ChangeCollectionToEntityInput!) {\n  addEntityToCollection(input: $input)\n}\n\nmutation CommitMetadata($input: CommitMediaInput!) {\n  commitMetadata(input: $input) {\n    id\n  }\n}\n\nmutation CommitMetadataGroup($input: CommitMediaInput!) {\n  commitMetadataGroup(input: $input) {\n    id\n  }\n}\n\nmutation CommitPerson($input: CommitPersonInput!) {\n  commitPerson(input: $input) {\n    id\n  }\n}\n\nmutation CreateCustomExercise($input: ExerciseInput!) {\n  createCustomExercise(input: $input)\n}\n\nmutation UpdateCustomExercise($input: UpdateCustomExerciseInput!) {\n  updateCustomExercise(input: $input)\n}\n\nmutation UpdateUserIntegration($input: UpdateUserIntegrationInput!) {\n  updateUserIntegration(input: $input)\n}\n\nmutation CreateCustomMetadata($input: CreateCustomMetadataInput!) {\n  createCustomMetadata(input: $input) {\n    id\n  }\n}\n\nmutation UpdateCustomMetadata($input: UpdateCustomMetadataInput!) {\n  updateCustomMetadata(input: $input)\n}\n\nmutation CreateOrUpdateCollection($input: CreateOrUpdateCollectionInput!) {\n  createOrUpdateCollection(input: $input) {\n    id\n  }\n}\n\nmutation CreateReviewComment($input: CreateReviewCommentInput!) {\n  createReviewComment(input: $input)\n}\n\nmutation CreateUserMeasurement($input: UserMeasurementInput!) {\n  createUserMeasurement(input: $input)\n}\n\nmutation CreateUserNotificationPlatform($input: CreateUserNotificationPlatformInput!) {\n  createUserNotificationPlatform(input: $input)\n}\n\nmutation CreateUserIntegration($input: CreateUserIntegrationInput!) {\n  createUserIntegration(input: $input) {\n    id\n  }\n}\n\nmutation CreateOrUpdateUserWorkout($input: UserWorkoutInput!) {\n  createOrUpdateUserWorkout(input: $input)\n}\n\nmutation CreateOrUpdateUserWorkoutTemplate($input: UserWorkoutInput!) {\n  createOrUpdateUserWorkoutTemplate(input: $input)\n}\n\nmutation DeleteCollection($collectionName: String!) {\n  deleteCollection(collectionName: $collectionName)\n}\n\nmutation DeleteReview($reviewId: String!) {\n  deleteReview(reviewId: $reviewId)\n}\n\nmutation DeleteS3Object($key: String!) {\n  deleteS3Object(key: $key)\n}\n\nmutation DeleteSeenItem($seenId: String!) {\n  deleteSeenItem(seenId: $seenId) {\n    id\n  }\n}\n\nmutation DeleteUser($toDeleteUserId: String!) {\n  deleteUser(toDeleteUserId: $toDeleteUserId)\n}\n\nmutation DeleteUserIntegration($integrationId: String!) {\n  deleteUserIntegration(integrationId: $integrationId)\n}\n\nmutation DeleteUserMeasurement($timestamp: DateTime!) {\n  deleteUserMeasurement(timestamp: $timestamp)\n}\n\nmutation DeleteUserNotificationPlatform($notificationId: String!) {\n  deleteUserNotificationPlatform(notificationId: $notificationId)\n}\n\nmutation DeleteUserWorkout($workoutId: String!) {\n  deleteUserWorkout(workoutId: $workoutId)\n}\n\nmutation DeleteUserWorkoutTemplate($workoutTemplateId: String!) {\n  deleteUserWorkoutTemplate(workoutTemplateId: $workoutTemplateId)\n}\n\nmutation DeployBackgroundJob($jobName: BackgroundJob!) {\n  deployBackgroundJob(jobName: $jobName)\n}\n\nmutation DeployBulkProgressUpdate($input: [ProgressUpdateInput!]!) {\n  deployBulkProgressUpdate(input: $input)\n}\n\nmutation DeployExportJob {\n  deployExportJob\n}\n\nmutation DeployImportJob($input: DeployImportJobInput!) {\n  deployImportJob(input: $input)\n}\n\nmutation DeployUpdateMetadataJob($metadataId: String!) {\n  deployUpdateMetadataJob(metadataId: $metadataId)\n}\n\nmutation DeployUpdatePersonJob($personId: String!) {\n  deployUpdatePersonJob(personId: $personId)\n}\n\nmutation DeployUpdateMetadataGroupJob($metadataGroupId: String!) {\n  deployUpdateMetadataGroupJob(metadataGroupId: $metadataGroupId)\n}\n\nmutation UpdateSeenItem($input: UpdateSeenItemInput!) {\n  updateSeenItem(input: $input)\n}\n\nmutation UpdateUserNotificationPlatform($input: UpdateUserNotificationPlatformInput!) {\n  updateUserNotificationPlatform(input: $input)\n}\n\nmutation UpdateUserWorkoutAttributes($input: UpdateUserWorkoutAttributesInput!) {\n  updateUserWorkoutAttributes(input: $input)\n}\n\nmutation GenerateAuthToken {\n  generateAuthToken\n}\n\nmutation MergeMetadata($mergeFrom: String!, $mergeInto: String!) {\n  mergeMetadata(mergeFrom: $mergeFrom, mergeInto: $mergeInto)\n}\n\nmutation DisassociateMetadata($metadataId: String!) {\n  disassociateMetadata(metadataId: $metadataId)\n}\n\nmutation CreateOrUpdateReview($input: CreateOrUpdateReviewInput!) {\n  createOrUpdateReview(input: $input) {\n    id\n  }\n}\n\nmutation PresignedPutS3Url($input: PresignedPutUrlInput!) {\n  presignedPutS3Url(input: $input) {\n    key\n    uploadUrl\n  }\n}\n\nmutation RemoveEntityFromCollection($input: ChangeCollectionToEntityInput!) {\n  removeEntityFromCollection(input: $input) {\n    id\n  }\n}\n\nmutation TestUserNotificationPlatforms {\n  testUserNotificationPlatforms\n}\n\nmutation UpdateUser($input: UpdateUserInput!) {\n  updateUser(input: $input) {\n    id\n  }\n}\n\nmutation UpdateUserPreference($input: UserPreferencesInput!) {\n  updateUserPreference(input: $input)\n}\n\nmutation CreateAccessLink($input: CreateAccessLinkInput!) {\n  createAccessLink(input: $input) {\n    id\n  }\n}\n\nmutation ProcessAccessLink($input: ProcessAccessLinkInput!) {\n  processAccessLink(input: $input) {\n    __typename\n    ... on ProcessAccessLinkError {\n      error\n    }\n    ... on ProcessAccessLinkResponse {\n      apiKey\n      redirectTo\n      tokenValidForDays\n    }\n  }\n}\n\nmutation RevokeAccessLink($accessLinkId: String!) {\n  revokeAccessLink(accessLinkId: $accessLinkId)\n}\n\nmutation UpdateUserExerciseSettings($input: UpdateUserExerciseSettings!) {\n  updateUserExerciseSettings(input: $input)\n}\n\nmutation MergeExercise($mergeFrom: String!, $mergeInto: String!) {\n  mergeExercise(mergeFrom: $mergeFrom, mergeInto: $mergeInto)\n}\n\nmutation MarkEntityAsPartial($input: MarkEntityAsPartialInput!) {\n  markEntityAsPartial(input: $input)\n}\n\nmutation MarkNotificationsAsAddressed($notificationIds: [String!]!) {\n  markNotificationsAsAddressed(notificationIds: $notificationIds)\n}\n\nmutation ExpireCacheKey($cacheId: UUID!) {\n  expireCacheKey(cacheId: $cacheId)\n}"];
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
@@ -75,7 +75,7 @@ export function graphql(source: "query UserMetadataDetails($metadataId: String!)
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
-export function graphql(source: "query GetOidcRedirectUrl {\n  getOidcRedirectUrl\n}\n\nquery UserByOidcIssuerId($oidcIssuerId: String!) {\n  userByOidcIssuerId(oidcIssuerId: $oidcIssuerId)\n}\n\nquery GetOidcToken($code: String!) {\n  getOidcToken(code: $code) {\n    subject\n    email\n  }\n}\n\nquery GetPresignedS3Url($key: String!) {\n  getPresignedS3Url(key: $key)\n}\n\nquery UserExports {\n  userExports {\n    url\n    key\n    size\n    endedAt\n    startedAt\n  }\n}\n\nquery UserCollectionsList($name: String) {\n  userCollectionsList(name: $name) {\n    id\n    name\n    count\n    isDefault\n    description\n    creator {\n      id\n      name\n    }\n    collaborators {\n      id\n      name\n    }\n    informationTemplate {\n      lot\n      name\n      required\n      description\n      defaultValue\n    }\n  }\n}\n\nquery UserIntegrations {\n  userIntegrations {\n    id\n    lot\n    name\n    provider\n    createdOn\n    isDisabled\n    maximumProgress\n    minimumProgress\n    lastTriggeredOn\n    syncToOwnedCollection\n  }\n}\n\nquery UserNotificationPlatforms {\n  userNotificationPlatforms {\n    id\n    lot\n    createdOn\n    isDisabled\n    description\n  }\n}\n\nquery UsersList($query: String) {\n  usersList(query: $query) {\n    id\n    lot\n    name\n    isDisabled\n  }\n}\n\nquery UserMetadataRecommendations($shouldRefresh: Boolean) {\n  userMetadataRecommendations(shouldRefresh: $shouldRefresh)\n}\n\nquery UserUpcomingCalendarEvents($input: UserUpcomingCalendarEventInput!) {\n  userUpcomingCalendarEvents(input: $input) {\n    ...CalendarEventPart\n  }\n}\n\nquery UserCalendarEvents($input: UserCalendarEventInput!) {\n  userCalendarEvents(input: $input) {\n    date\n    events {\n      ...CalendarEventPart\n    }\n  }\n}\n\nquery MetadataPartialDetails($metadataId: String!) {\n  metadataPartialDetails(metadataId: $metadataId) {\n    id\n    lot\n    title\n    image\n    publishYear\n  }\n}\n\nquery MetadataGroupsList($input: MetadataGroupsListInput!) {\n  metadataGroupsList(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items\n  }\n}\n\nquery PeopleList($input: PeopleListInput!) {\n  peopleList(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items\n  }\n}\n\nquery UserAccessLinks {\n  userAccessLinks {\n    id\n    name\n    isDemo\n    createdOn\n    expiresOn\n    timesUsed\n    isRevoked\n    maximumUses\n    isAccountDefault\n    isMutationAllowed\n  }\n}\n\nquery ExerciseDetails($exerciseId: String!) {\n  exerciseDetails(exerciseId: $exerciseId) {\n    id\n    lot\n    name\n    level\n    force\n    source\n    muscles\n    mechanic\n    equipment\n    createdByUserId\n    attributes {\n      instructions\n      images\n    }\n  }\n}\n\nquery ExercisesList($input: ExercisesListInput!) {\n  exercisesList(input: $input) {\n    items\n    details {\n      total\n      nextPage\n    }\n  }\n}\n\nquery ImportReports {\n  importReports {\n    id\n    source\n    progress\n    startedOn\n    finishedOn\n    wasSuccess\n    estimatedFinishTime\n    details {\n      import {\n        total\n      }\n      failedItems {\n        lot\n        step\n        error\n        identifier\n      }\n    }\n  }\n}\n\nquery GenresList($input: SearchInput!) {\n  genresList(input: $input) {\n    items\n    details {\n      total\n      nextPage\n    }\n  }\n}\n\nquery GenreDetails($input: GenreDetailsInput!) {\n  genreDetails(input: $input) {\n    details {\n      id\n      name\n      numItems\n    }\n    contents {\n      details {\n        total\n        nextPage\n      }\n      items\n    }\n  }\n}\n\nquery CollectionContents($input: CollectionContentsInput!) {\n  collectionContents(input: $input) {\n    user {\n      id\n      name\n    }\n    reviews {\n      ...ReviewItemPart\n    }\n    results {\n      details {\n        total\n        nextPage\n      }\n      items {\n        entityId\n        entityLot\n      }\n    }\n    details {\n      name\n      description\n      createdOn\n    }\n  }\n}\n\nquery CoreDetails {\n  coreDetails {\n    version\n    docsLink\n    pageSize\n    websiteUrl\n    smtpEnabled\n    oidcEnabled\n    signupAllowed\n    repositoryLink\n    disableTelemetry\n    tokenValidForDays\n    localAuthDisabled\n    fileStorageEnabled\n    peopleSearchSources\n    isServerKeyValidated\n    metadataGroupSourceLotMappings {\n      lot\n      source\n    }\n    metadataLotSourceMappings {\n      lot\n      sources\n    }\n    metadataProviderLanguages {\n      source\n      default\n      supported\n    }\n    frontend {\n      url\n      oidcButtonLabel\n      dashboardMessage\n      umami {\n        domains\n        scriptUrl\n        websiteId\n      }\n    }\n    exerciseParameters {\n      downloadRequired\n      filters {\n        type\n        level\n        force\n        mechanic\n        equipment\n        muscle\n      }\n      lotMapping {\n        lot\n        bests\n      }\n    }\n  }\n}\n\nquery MetadataGroupDetails($metadataGroupId: String!) {\n  metadataGroupDetails(metadataGroupId: $metadataGroupId) {\n    contents\n    details {\n      id\n      lot\n      title\n      parts\n      source\n      isPartial\n      sourceUrl\n      identifier\n      description\n      displayImages\n    }\n  }\n}\n\nquery MetadataGroupSearch($input: MetadataGroupSearchInput!) {\n  metadataGroupSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      name\n      image\n      parts\n    }\n  }\n}\n\nquery MetadataList($input: MetadataListInput!) {\n  metadataList(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items\n  }\n}\n\nquery MetadataSearch($input: MetadataSearchInput!) {\n  metadataSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      title\n      image\n      publishYear\n    }\n  }\n}\n\nquery PeopleSearch($input: PeopleSearchInput!) {\n  peopleSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      name\n      image\n      birthYear\n    }\n  }\n}\n\nquery UserMetadataGroupDetails($metadataGroupId: String!) {\n  userMetadataGroupDetails(metadataGroupId: $metadataGroupId) {\n    recentlyConsumed\n    reviews {\n      ...ReviewItemPart\n    }\n    collections {\n      ...CollectionPart\n    }\n  }\n}\n\nquery UserPersonDetails($personId: String!) {\n  userPersonDetails(personId: $personId) {\n    recentlyConsumed\n    collections {\n      ...CollectionPart\n    }\n    reviews {\n      ...ReviewItemPart\n    }\n  }\n}\n\nquery UserWorkoutDetails($workoutId: String!) {\n  userWorkoutDetails(workoutId: $workoutId) {\n    collections {\n      ...CollectionPart\n    }\n    details {\n      id\n      name\n      endTime\n      duration\n      startTime\n      templateId\n      repeatedFrom\n      caloriesBurnt\n      summary {\n        ...WorkoutSummaryPart\n      }\n      information {\n        ...WorkoutInformationPart\n      }\n    }\n  }\n}\n\nquery UserWorkoutsList($input: SearchInput!) {\n  userWorkoutsList(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items\n  }\n}\n\nquery UserWorkoutTemplateDetails($workoutTemplateId: String!) {\n  userWorkoutTemplateDetails(workoutTemplateId: $workoutTemplateId) {\n    collections {\n      ...CollectionPart\n    }\n    details {\n      id\n      name\n      createdOn\n      summary {\n        ...WorkoutSummaryPart\n      }\n      information {\n        ...WorkoutInformationPart\n      }\n    }\n  }\n}\n\nquery UserWorkoutTemplatesList($input: SearchInput!) {\n  userWorkoutTemplatesList(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items\n  }\n}\n\nquery UserAnalyticsParameters {\n  userAnalyticsParameters {\n    endDate\n    startDate\n  }\n}\n\nquery UserPendingNotifications {\n  userPendingNotifications {\n    id\n    message\n    createdOn\n  }\n}"): (typeof documents)["query GetOidcRedirectUrl {\n  getOidcRedirectUrl\n}\n\nquery UserByOidcIssuerId($oidcIssuerId: String!) {\n  userByOidcIssuerId(oidcIssuerId: $oidcIssuerId)\n}\n\nquery GetOidcToken($code: String!) {\n  getOidcToken(code: $code) {\n    subject\n    email\n  }\n}\n\nquery GetPresignedS3Url($key: String!) {\n  getPresignedS3Url(key: $key)\n}\n\nquery UserExports {\n  userExports {\n    url\n    key\n    size\n    endedAt\n    startedAt\n  }\n}\n\nquery UserCollectionsList($name: String) {\n  userCollectionsList(name: $name) {\n    id\n    name\n    count\n    isDefault\n    description\n    creator {\n      id\n      name\n    }\n    collaborators {\n      id\n      name\n    }\n    informationTemplate {\n      lot\n      name\n      required\n      description\n      defaultValue\n    }\n  }\n}\n\nquery UserIntegrations {\n  userIntegrations {\n    id\n    lot\n    name\n    provider\n    createdOn\n    isDisabled\n    maximumProgress\n    minimumProgress\n    lastTriggeredOn\n    syncToOwnedCollection\n  }\n}\n\nquery UserNotificationPlatforms {\n  userNotificationPlatforms {\n    id\n    lot\n    createdOn\n    isDisabled\n    description\n  }\n}\n\nquery UsersList($query: String) {\n  usersList(query: $query) {\n    id\n    lot\n    name\n    isDisabled\n  }\n}\n\nquery UserMetadataRecommendations($shouldRefresh: Boolean) {\n  userMetadataRecommendations(shouldRefresh: $shouldRefresh)\n}\n\nquery UserUpcomingCalendarEvents($input: UserUpcomingCalendarEventInput!) {\n  userUpcomingCalendarEvents(input: $input) {\n    ...CalendarEventPart\n  }\n}\n\nquery UserCalendarEvents($input: UserCalendarEventInput!) {\n  userCalendarEvents(input: $input) {\n    date\n    events {\n      ...CalendarEventPart\n    }\n  }\n}\n\nquery MetadataPartialDetails($metadataId: String!) {\n  metadataPartialDetails(metadataId: $metadataId) {\n    id\n    lot\n    title\n    image\n    publishYear\n  }\n}\n\nquery MetadataGroupsList($input: MetadataGroupsListInput!) {\n  metadataGroupsList(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items\n  }\n}\n\nquery PeopleList($input: PeopleListInput!) {\n  peopleList(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items\n  }\n}\n\nquery UserAccessLinks {\n  userAccessLinks {\n    id\n    name\n    isDemo\n    createdOn\n    expiresOn\n    timesUsed\n    isRevoked\n    maximumUses\n    isAccountDefault\n    isMutationAllowed\n  }\n}\n\nquery ExerciseDetails($exerciseId: String!) {\n  exerciseDetails(exerciseId: $exerciseId) {\n    id\n    lot\n    name\n    level\n    force\n    source\n    muscles\n    mechanic\n    equipment\n    createdByUserId\n    attributes {\n      instructions\n      images\n    }\n  }\n}\n\nquery ExercisesList($input: ExercisesListInput!) {\n  exercisesList(input: $input) {\n    items\n    details {\n      total\n      nextPage\n    }\n  }\n}\n\nquery ImportReports {\n  importReports {\n    id\n    source\n    progress\n    startedOn\n    finishedOn\n    wasSuccess\n    estimatedFinishTime\n    details {\n      import {\n        total\n      }\n      failedItems {\n        lot\n        step\n        error\n        identifier\n      }\n    }\n  }\n}\n\nquery GenresList($input: SearchInput!) {\n  genresList(input: $input) {\n    items\n    details {\n      total\n      nextPage\n    }\n  }\n}\n\nquery GenreDetails($input: GenreDetailsInput!) {\n  genreDetails(input: $input) {\n    details {\n      id\n      name\n      numItems\n    }\n    contents {\n      details {\n        total\n        nextPage\n      }\n      items\n    }\n  }\n}\n\nquery CollectionContents($input: CollectionContentsInput!) {\n  collectionContents(input: $input) {\n    user {\n      id\n      name\n    }\n    reviews {\n      ...ReviewItemPart\n    }\n    results {\n      details {\n        total\n        nextPage\n      }\n      items {\n        entityId\n        entityLot\n      }\n    }\n    details {\n      name\n      description\n      createdOn\n    }\n  }\n}\n\nquery CoreDetails {\n  coreDetails {\n    version\n    docsLink\n    pageSize\n    websiteUrl\n    smtpEnabled\n    oidcEnabled\n    signupAllowed\n    repositoryLink\n    disableTelemetry\n    tokenValidForDays\n    localAuthDisabled\n    fileStorageEnabled\n    peopleSearchSources\n    isServerKeyValidated\n    metadataGroupSourceLotMappings {\n      lot\n      source\n    }\n    metadataLotSourceMappings {\n      lot\n      sources\n    }\n    metadataProviderLanguages {\n      source\n      default\n      supported\n    }\n    frontend {\n      url\n      oidcButtonLabel\n      dashboardMessage\n      umami {\n        domains\n        scriptUrl\n        websiteId\n      }\n    }\n    exerciseParameters {\n      downloadRequired\n      filters {\n        type\n        level\n        force\n        mechanic\n        equipment\n        muscle\n      }\n      lotMapping {\n        lot\n        bests\n      }\n    }\n  }\n}\n\nquery MetadataGroupDetails($metadataGroupId: String!) {\n  metadataGroupDetails(metadataGroupId: $metadataGroupId) {\n    contents\n    details {\n      id\n      lot\n      title\n      parts\n      source\n      isPartial\n      sourceUrl\n      identifier\n      description\n      displayImages\n    }\n  }\n}\n\nquery MetadataGroupSearch($input: MetadataGroupSearchInput!) {\n  metadataGroupSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      name\n      image\n      parts\n    }\n  }\n}\n\nquery MetadataList($input: MetadataListInput!) {\n  metadataList(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items\n  }\n}\n\nquery MetadataSearch($input: MetadataSearchInput!) {\n  metadataSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      title\n      image\n      publishYear\n    }\n  }\n}\n\nquery PeopleSearch($input: PeopleSearchInput!) {\n  peopleSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      name\n      image\n      birthYear\n    }\n  }\n}\n\nquery UserMetadataGroupDetails($metadataGroupId: String!) {\n  userMetadataGroupDetails(metadataGroupId: $metadataGroupId) {\n    recentlyConsumed\n    reviews {\n      ...ReviewItemPart\n    }\n    collections {\n      ...CollectionPart\n    }\n  }\n}\n\nquery UserPersonDetails($personId: String!) {\n  userPersonDetails(personId: $personId) {\n    recentlyConsumed\n    collections {\n      ...CollectionPart\n    }\n    reviews {\n      ...ReviewItemPart\n    }\n  }\n}\n\nquery UserWorkoutDetails($workoutId: String!) {\n  userWorkoutDetails(workoutId: $workoutId) {\n    collections {\n      ...CollectionPart\n    }\n    details {\n      id\n      name\n      endTime\n      duration\n      startTime\n      templateId\n      repeatedFrom\n      caloriesBurnt\n      summary {\n        ...WorkoutSummaryPart\n      }\n      information {\n        ...WorkoutInformationPart\n      }\n    }\n  }\n}\n\nquery UserWorkoutsList($input: SearchInput!) {\n  userWorkoutsList(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items\n  }\n}\n\nquery UserWorkoutTemplateDetails($workoutTemplateId: String!) {\n  userWorkoutTemplateDetails(workoutTemplateId: $workoutTemplateId) {\n    collections {\n      ...CollectionPart\n    }\n    details {\n      id\n      name\n      createdOn\n      summary {\n        ...WorkoutSummaryPart\n      }\n      information {\n        ...WorkoutInformationPart\n      }\n    }\n  }\n}\n\nquery UserWorkoutTemplatesList($input: SearchInput!) {\n  userWorkoutTemplatesList(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items\n  }\n}\n\nquery UserAnalyticsParameters {\n  userAnalyticsParameters {\n    endDate\n    startDate\n  }\n}\n\nquery UserPendingNotifications {\n  userPendingNotifications {\n    id\n    message\n    createdOn\n  }\n}"];
+export function graphql(source: "query GetOidcRedirectUrl {\n  getOidcRedirectUrl\n}\n\nquery UserByOidcIssuerId($oidcIssuerId: String!) {\n  userByOidcIssuerId(oidcIssuerId: $oidcIssuerId)\n}\n\nquery GetOidcToken($code: String!) {\n  getOidcToken(code: $code) {\n    subject\n    email\n  }\n}\n\nquery GetPresignedS3Url($key: String!) {\n  getPresignedS3Url(key: $key)\n}\n\nquery UserExports {\n  userExports {\n    url\n    key\n    size\n    endedAt\n    startedAt\n  }\n}\n\nquery UserCollectionsList($name: String) {\n  userCollectionsList(name: $name) {\n    cacheId\n    response {\n      id\n      name\n      count\n      isDefault\n      description\n      creator {\n        id\n        name\n      }\n      collaborators {\n        id\n        name\n      }\n      informationTemplate {\n        lot\n        name\n        required\n        description\n        defaultValue\n      }\n    }\n  }\n}\n\nquery UserIntegrations {\n  userIntegrations {\n    id\n    lot\n    name\n    provider\n    createdOn\n    isDisabled\n    maximumProgress\n    minimumProgress\n    lastTriggeredOn\n    syncToOwnedCollection\n  }\n}\n\nquery UserNotificationPlatforms {\n  userNotificationPlatforms {\n    id\n    lot\n    createdOn\n    isDisabled\n    description\n  }\n}\n\nquery UsersList($query: String) {\n  usersList(query: $query) {\n    id\n    lot\n    name\n    isDisabled\n  }\n}\n\nquery UserMetadataRecommendations {\n  userMetadataRecommendations {\n    cacheId\n    response\n  }\n}\n\nquery UserUpcomingCalendarEvents($input: UserUpcomingCalendarEventInput!) {\n  userUpcomingCalendarEvents(input: $input) {\n    ...CalendarEventPart\n  }\n}\n\nquery UserCalendarEvents($input: UserCalendarEventInput!) {\n  userCalendarEvents(input: $input) {\n    date\n    events {\n      ...CalendarEventPart\n    }\n  }\n}\n\nquery MetadataPartialDetails($metadataId: String!) {\n  metadataPartialDetails(metadataId: $metadataId) {\n    id\n    lot\n    title\n    image\n    publishYear\n  }\n}\n\nquery UserMetadataGroupsList($input: UserMetadataGroupsListInput!) {\n  userMetadataGroupsList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery UserPeopleList($input: UserPeopleListInput!) {\n  userPeopleList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery UserAccessLinks {\n  userAccessLinks {\n    id\n    name\n    isDemo\n    createdOn\n    expiresOn\n    timesUsed\n    isRevoked\n    maximumUses\n    isAccountDefault\n    isMutationAllowed\n  }\n}\n\nquery ExerciseDetails($exerciseId: String!) {\n  exerciseDetails(exerciseId: $exerciseId) {\n    id\n    lot\n    name\n    level\n    force\n    source\n    muscles\n    mechanic\n    equipment\n    createdByUserId\n    attributes {\n      instructions\n      images\n    }\n  }\n}\n\nquery UserExercisesList($input: UserExercisesListInput!) {\n  userExercisesList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery ImportReports {\n  importReports {\n    id\n    source\n    progress\n    startedOn\n    finishedOn\n    wasSuccess\n    estimatedFinishTime\n    details {\n      import {\n        total\n      }\n      failedItems {\n        lot\n        step\n        error\n        identifier\n      }\n    }\n  }\n}\n\nquery GenresList($input: SearchInput!) {\n  genresList(input: $input) {\n    items\n    details {\n      total\n      nextPage\n    }\n  }\n}\n\nquery GenreDetails($input: GenreDetailsInput!) {\n  genreDetails(input: $input) {\n    details {\n      id\n      name\n      numItems\n    }\n    contents {\n      details {\n        total\n        nextPage\n      }\n      items\n    }\n  }\n}\n\nquery CollectionContents($input: CollectionContentsInput!) {\n  collectionContents(input: $input) {\n    cacheId\n    response {\n      totalItems\n      user {\n        id\n        name\n      }\n      reviews {\n        ...ReviewItemPart\n      }\n      details {\n        name\n        createdOn\n        description\n      }\n      results {\n        details {\n          total\n          nextPage\n        }\n        items {\n          entityId\n          entityLot\n        }\n      }\n    }\n  }\n}\n\nquery CoreDetails {\n  coreDetails {\n    version\n    docsLink\n    pageSize\n    websiteUrl\n    smtpEnabled\n    oidcEnabled\n    signupAllowed\n    repositoryLink\n    disableTelemetry\n    tokenValidForDays\n    localAuthDisabled\n    fileStorageEnabled\n    peopleSearchSources\n    isServerKeyValidated\n    metadataGroupSourceLotMappings {\n      lot\n      source\n    }\n    metadataLotSourceMappings {\n      lot\n      sources\n    }\n    metadataProviderLanguages {\n      source\n      default\n      supported\n    }\n    frontend {\n      url\n      oidcButtonLabel\n      dashboardMessage\n      umami {\n        domains\n        scriptUrl\n        websiteId\n      }\n    }\n    exerciseParameters {\n      lotMapping {\n        lot\n        bests\n      }\n      filters {\n        type\n        level\n        force\n        muscle\n        mechanic\n        equipment\n      }\n    }\n  }\n}\n\nquery MetadataGroupDetails($metadataGroupId: String!) {\n  metadataGroupDetails(metadataGroupId: $metadataGroupId) {\n    contents\n    details {\n      id\n      lot\n      title\n      parts\n      source\n      isPartial\n      sourceUrl\n      identifier\n      description\n      displayImages\n    }\n  }\n}\n\nquery MetadataGroupSearch($input: MetadataGroupSearchInput!) {\n  metadataGroupSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      name\n      image\n      parts\n    }\n  }\n}\n\nquery UserMetadataList($input: UserMetadataListInput!) {\n  userMetadataList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery MetadataSearch($input: MetadataSearchInput!) {\n  metadataSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      title\n      image\n      publishYear\n    }\n  }\n}\n\nquery PeopleSearch($input: PeopleSearchInput!) {\n  peopleSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      name\n      image\n      birthYear\n    }\n  }\n}\n\nquery UserMetadataGroupDetails($metadataGroupId: String!) {\n  userMetadataGroupDetails(metadataGroupId: $metadataGroupId) {\n    recentlyConsumed\n    reviews {\n      ...ReviewItemPart\n    }\n    collections {\n      ...CollectionPart\n    }\n  }\n}\n\nquery UserPersonDetails($personId: String!) {\n  userPersonDetails(personId: $personId) {\n    recentlyConsumed\n    collections {\n      ...CollectionPart\n    }\n    reviews {\n      ...ReviewItemPart\n    }\n  }\n}\n\nquery UserWorkoutDetails($workoutId: String!) {\n  userWorkoutDetails(workoutId: $workoutId) {\n    collections {\n      ...CollectionPart\n    }\n    details {\n      id\n      name\n      endTime\n      duration\n      startTime\n      templateId\n      repeatedFrom\n      caloriesBurnt\n      summary {\n        ...WorkoutSummaryPart\n      }\n      information {\n        ...WorkoutInformationPart\n      }\n    }\n  }\n}\n\nquery UserWorkoutsList($input: UserTemplatesOrWorkoutsListInput!) {\n  userWorkoutsList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery UserWorkoutTemplateDetails($workoutTemplateId: String!) {\n  userWorkoutTemplateDetails(workoutTemplateId: $workoutTemplateId) {\n    collections {\n      ...CollectionPart\n    }\n    details {\n      id\n      name\n      createdOn\n      summary {\n        ...WorkoutSummaryPart\n      }\n      information {\n        ...WorkoutInformationPart\n      }\n    }\n  }\n}\n\nquery UserWorkoutTemplatesList($input: UserTemplatesOrWorkoutsListInput!) {\n  userWorkoutTemplatesList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery UserAnalyticsParameters {\n  userAnalyticsParameters {\n    endDate\n    startDate\n  }\n}\n\nquery UserPendingNotifications {\n  userPendingNotifications {\n    id\n    message\n    createdOn\n  }\n}"): (typeof documents)["query GetOidcRedirectUrl {\n  getOidcRedirectUrl\n}\n\nquery UserByOidcIssuerId($oidcIssuerId: String!) {\n  userByOidcIssuerId(oidcIssuerId: $oidcIssuerId)\n}\n\nquery GetOidcToken($code: String!) {\n  getOidcToken(code: $code) {\n    subject\n    email\n  }\n}\n\nquery GetPresignedS3Url($key: String!) {\n  getPresignedS3Url(key: $key)\n}\n\nquery UserExports {\n  userExports {\n    url\n    key\n    size\n    endedAt\n    startedAt\n  }\n}\n\nquery UserCollectionsList($name: String) {\n  userCollectionsList(name: $name) {\n    cacheId\n    response {\n      id\n      name\n      count\n      isDefault\n      description\n      creator {\n        id\n        name\n      }\n      collaborators {\n        id\n        name\n      }\n      informationTemplate {\n        lot\n        name\n        required\n        description\n        defaultValue\n      }\n    }\n  }\n}\n\nquery UserIntegrations {\n  userIntegrations {\n    id\n    lot\n    name\n    provider\n    createdOn\n    isDisabled\n    maximumProgress\n    minimumProgress\n    lastTriggeredOn\n    syncToOwnedCollection\n  }\n}\n\nquery UserNotificationPlatforms {\n  userNotificationPlatforms {\n    id\n    lot\n    createdOn\n    isDisabled\n    description\n  }\n}\n\nquery UsersList($query: String) {\n  usersList(query: $query) {\n    id\n    lot\n    name\n    isDisabled\n  }\n}\n\nquery UserMetadataRecommendations {\n  userMetadataRecommendations {\n    cacheId\n    response\n  }\n}\n\nquery UserUpcomingCalendarEvents($input: UserUpcomingCalendarEventInput!) {\n  userUpcomingCalendarEvents(input: $input) {\n    ...CalendarEventPart\n  }\n}\n\nquery UserCalendarEvents($input: UserCalendarEventInput!) {\n  userCalendarEvents(input: $input) {\n    date\n    events {\n      ...CalendarEventPart\n    }\n  }\n}\n\nquery MetadataPartialDetails($metadataId: String!) {\n  metadataPartialDetails(metadataId: $metadataId) {\n    id\n    lot\n    title\n    image\n    publishYear\n  }\n}\n\nquery UserMetadataGroupsList($input: UserMetadataGroupsListInput!) {\n  userMetadataGroupsList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery UserPeopleList($input: UserPeopleListInput!) {\n  userPeopleList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery UserAccessLinks {\n  userAccessLinks {\n    id\n    name\n    isDemo\n    createdOn\n    expiresOn\n    timesUsed\n    isRevoked\n    maximumUses\n    isAccountDefault\n    isMutationAllowed\n  }\n}\n\nquery ExerciseDetails($exerciseId: String!) {\n  exerciseDetails(exerciseId: $exerciseId) {\n    id\n    lot\n    name\n    level\n    force\n    source\n    muscles\n    mechanic\n    equipment\n    createdByUserId\n    attributes {\n      instructions\n      images\n    }\n  }\n}\n\nquery UserExercisesList($input: UserExercisesListInput!) {\n  userExercisesList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery ImportReports {\n  importReports {\n    id\n    source\n    progress\n    startedOn\n    finishedOn\n    wasSuccess\n    estimatedFinishTime\n    details {\n      import {\n        total\n      }\n      failedItems {\n        lot\n        step\n        error\n        identifier\n      }\n    }\n  }\n}\n\nquery GenresList($input: SearchInput!) {\n  genresList(input: $input) {\n    items\n    details {\n      total\n      nextPage\n    }\n  }\n}\n\nquery GenreDetails($input: GenreDetailsInput!) {\n  genreDetails(input: $input) {\n    details {\n      id\n      name\n      numItems\n    }\n    contents {\n      details {\n        total\n        nextPage\n      }\n      items\n    }\n  }\n}\n\nquery CollectionContents($input: CollectionContentsInput!) {\n  collectionContents(input: $input) {\n    cacheId\n    response {\n      totalItems\n      user {\n        id\n        name\n      }\n      reviews {\n        ...ReviewItemPart\n      }\n      details {\n        name\n        createdOn\n        description\n      }\n      results {\n        details {\n          total\n          nextPage\n        }\n        items {\n          entityId\n          entityLot\n        }\n      }\n    }\n  }\n}\n\nquery CoreDetails {\n  coreDetails {\n    version\n    docsLink\n    pageSize\n    websiteUrl\n    smtpEnabled\n    oidcEnabled\n    signupAllowed\n    repositoryLink\n    disableTelemetry\n    tokenValidForDays\n    localAuthDisabled\n    fileStorageEnabled\n    peopleSearchSources\n    isServerKeyValidated\n    metadataGroupSourceLotMappings {\n      lot\n      source\n    }\n    metadataLotSourceMappings {\n      lot\n      sources\n    }\n    metadataProviderLanguages {\n      source\n      default\n      supported\n    }\n    frontend {\n      url\n      oidcButtonLabel\n      dashboardMessage\n      umami {\n        domains\n        scriptUrl\n        websiteId\n      }\n    }\n    exerciseParameters {\n      lotMapping {\n        lot\n        bests\n      }\n      filters {\n        type\n        level\n        force\n        muscle\n        mechanic\n        equipment\n      }\n    }\n  }\n}\n\nquery MetadataGroupDetails($metadataGroupId: String!) {\n  metadataGroupDetails(metadataGroupId: $metadataGroupId) {\n    contents\n    details {\n      id\n      lot\n      title\n      parts\n      source\n      isPartial\n      sourceUrl\n      identifier\n      description\n      displayImages\n    }\n  }\n}\n\nquery MetadataGroupSearch($input: MetadataGroupSearchInput!) {\n  metadataGroupSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      name\n      image\n      parts\n    }\n  }\n}\n\nquery UserMetadataList($input: UserMetadataListInput!) {\n  userMetadataList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery MetadataSearch($input: MetadataSearchInput!) {\n  metadataSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      title\n      image\n      publishYear\n    }\n  }\n}\n\nquery PeopleSearch($input: PeopleSearchInput!) {\n  peopleSearch(input: $input) {\n    details {\n      total\n      nextPage\n    }\n    items {\n      identifier\n      name\n      image\n      birthYear\n    }\n  }\n}\n\nquery UserMetadataGroupDetails($metadataGroupId: String!) {\n  userMetadataGroupDetails(metadataGroupId: $metadataGroupId) {\n    recentlyConsumed\n    reviews {\n      ...ReviewItemPart\n    }\n    collections {\n      ...CollectionPart\n    }\n  }\n}\n\nquery UserPersonDetails($personId: String!) {\n  userPersonDetails(personId: $personId) {\n    recentlyConsumed\n    collections {\n      ...CollectionPart\n    }\n    reviews {\n      ...ReviewItemPart\n    }\n  }\n}\n\nquery UserWorkoutDetails($workoutId: String!) {\n  userWorkoutDetails(workoutId: $workoutId) {\n    collections {\n      ...CollectionPart\n    }\n    details {\n      id\n      name\n      endTime\n      duration\n      startTime\n      templateId\n      repeatedFrom\n      caloriesBurnt\n      summary {\n        ...WorkoutSummaryPart\n      }\n      information {\n        ...WorkoutInformationPart\n      }\n    }\n  }\n}\n\nquery UserWorkoutsList($input: UserTemplatesOrWorkoutsListInput!) {\n  userWorkoutsList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery UserWorkoutTemplateDetails($workoutTemplateId: String!) {\n  userWorkoutTemplateDetails(workoutTemplateId: $workoutTemplateId) {\n    collections {\n      ...CollectionPart\n    }\n    details {\n      id\n      name\n      createdOn\n      summary {\n        ...WorkoutSummaryPart\n      }\n      information {\n        ...WorkoutInformationPart\n      }\n    }\n  }\n}\n\nquery UserWorkoutTemplatesList($input: UserTemplatesOrWorkoutsListInput!) {\n  userWorkoutTemplatesList(input: $input) {\n    cacheId\n    response {\n      items\n      details {\n        total\n        nextPage\n      }\n    }\n  }\n}\n\nquery UserAnalyticsParameters {\n  userAnalyticsParameters {\n    endDate\n    startDate\n  }\n}\n\nquery UserPendingNotifications {\n  userPendingNotifications {\n    id\n    message\n    createdOn\n  }\n}"];
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
diff --git a/libs/generated/src/graphql/backend/graphql.ts b/libs/generated/src/graphql/backend/graphql.ts
index 53e2938ea3..041aa0b7df 100644
--- a/libs/generated/src/graphql/backend/graphql.ts
+++ b/libs/generated/src/graphql/backend/graphql.ts
@@ -43,6 +43,17 @@ export type Scalars = {
    * * `2015-07-01T08:59:60.123`,
    */
   NaiveDateTime: { input: any; output: any; }
+  /**
+   * A UUID is a unique 128-bit number, stored as 16 octets. UUIDs are parsed as
+   * Strings within GraphQL. UUIDs are used to assign unique identifiers to
+   * entities without requiring a central allocating authority.
+   *
+   * # References
+   *
+   * * [Wikipedia: Universally Unique Identifier](http://en.wikipedia.org/wiki/Universally_unique_identifier)
+   * * [RFC4122: A Universally Unique IDentifier (UUID) URN Namespace](http://tools.ietf.org/html/rfc4122)
+   */
+  UUID: { input: string; output: string; }
 };
 
 export type AccessLink = {
@@ -131,6 +142,26 @@ export type BookSpecificsInput = {
   pages?: InputMaybe<Scalars['Int']['input']>;
 };
 
+export type CachedCollectionContentsResponse = {
+  cacheId: Scalars['UUID']['output'];
+  response: CollectionContents;
+};
+
+export type CachedCollectionsListResponse = {
+  cacheId: Scalars['UUID']['output'];
+  response: Array<CollectionItem>;
+};
+
+export type CachedSearchIdResponse = {
+  cacheId: Scalars['UUID']['output'];
+  response: IdResults;
+};
+
+export type CachedUserMetadataRecommendationsResponse = {
+  cacheId: Scalars['UUID']['output'];
+  response: Array<Scalars['String']['output']>;
+};
+
 export type ChangeCollectionToEntityInput = {
   collectionName: Scalars['String']['input'];
   creatorUserId: Scalars['String']['input'];
@@ -153,6 +184,7 @@ export type CollectionContents = {
   details: Collection;
   results: MediaCollectionContentsResults;
   reviews: Array<ReviewItem>;
+  totalItems: Scalars['Int']['output'];
   user: User;
 };
 
@@ -171,6 +203,7 @@ export type CollectionContentsInput = {
 export enum CollectionContentsSortBy {
   Date = 'DATE',
   LastUpdatedOn = 'LAST_UPDATED_ON',
+  Random = 'RANDOM',
   Title = 'TITLE'
 }
 
@@ -619,7 +652,6 @@ export enum ExerciseMuscle {
 }
 
 export type ExerciseParameters = {
-  downloadRequired: Scalars['Boolean']['output'];
   /** All filters applicable to an exercises query. */
   filters: ExerciseFilters;
   /** Exercise type mapped to the personal bests possible. */
@@ -634,6 +666,7 @@ export type ExerciseParametersLotMapping = {
 export enum ExerciseSortBy {
   LastPerformed = 'LAST_PERFORMED',
   Name = 'NAME',
+  Random = 'RANDOM',
   TimesPerformed = 'TIMES_PERFORMED'
 }
 
@@ -642,12 +675,6 @@ export enum ExerciseSource {
   Github = 'GITHUB'
 }
 
-export type ExercisesListInput = {
-  filter?: InputMaybe<ExerciseListFilter>;
-  search: SearchInput;
-  sortBy?: InputMaybe<ExerciseSortBy>;
-};
-
 export type ExportJob = {
   endedAt: Scalars['DateTime']['output'];
   key: Scalars['String']['output'];
@@ -1004,6 +1031,7 @@ export enum MediaSortBy {
   LastSeen = 'LAST_SEEN',
   LastUpdated = 'LAST_UPDATED',
   ProviderRating = 'PROVIDER_RATING',
+  Random = 'RANDOM',
   ReleaseDate = 'RELEASE_DATE',
   TimesConsumed = 'TIMES_CONSUMED',
   Title = 'TITLE',
@@ -1086,21 +1114,6 @@ export type MetadataGroupSourceLotMapping = {
   source: MediaSource;
 };
 
-export type MetadataGroupsListInput = {
-  filter?: InputMaybe<MediaFilter>;
-  invertCollection?: InputMaybe<Scalars['Boolean']['input']>;
-  search?: InputMaybe<SearchInput>;
-  sort?: InputMaybe<PersonSortInput>;
-};
-
-export type MetadataListInput = {
-  filter?: InputMaybe<MediaFilter>;
-  invertCollection?: InputMaybe<Scalars['Boolean']['input']>;
-  lot?: InputMaybe<MediaLot>;
-  search?: InputMaybe<SearchInput>;
-  sort?: InputMaybe<MediaSortInput>;
-};
-
 export type MetadataLotSourceMappings = {
   lot: MediaLot;
   sources: Array<MediaSource>;
@@ -1236,6 +1249,8 @@ export type MutationRoot = {
    * collections for the user.
    */
   disassociateMetadata: Scalars['Boolean']['output'];
+  /** Expire a cache key by its ID */
+  expireCacheKey: Scalars['Boolean']['output'];
   /** Generate an auth token without any expiry. */
   generateAuthToken: Scalars['String']['output'];
   /** Login a user using their username and password and return an auth token. */
@@ -1447,6 +1462,11 @@ export type MutationRootDisassociateMetadataArgs = {
 };
 
 
+export type MutationRootExpireCacheKeyArgs = {
+  cacheId: Scalars['UUID']['input'];
+};
+
+
 export type MutationRootLoginUserArgs = {
   input: AuthUserInput;
 };
@@ -1578,13 +1598,6 @@ export type PasswordUserInput = {
   username: Scalars['String']['input'];
 };
 
-export type PeopleListInput = {
-  filter?: InputMaybe<MediaFilter>;
-  invertCollection?: InputMaybe<Scalars['Boolean']['input']>;
-  search?: InputMaybe<SearchInput>;
-  sort?: InputMaybe<PersonSortInput>;
-};
-
 export type PeopleSearchInput = {
   search: SearchInput;
   source: MediaSource;
@@ -1624,7 +1637,8 @@ export type Person = {
 
 export enum PersonAndMetadataGroupsSortBy {
   MediaItems = 'MEDIA_ITEMS',
-  Name = 'NAME'
+  Name = 'NAME',
+  Random = 'RANDOM'
 }
 
 export type PersonDetailsGroupedByRole = {
@@ -1748,13 +1762,11 @@ export type ProviderLanguageInformation = {
 
 export type QueryRoot = {
   /** Get the contents of a collection and respect visibility. */
-  collectionContents: CollectionContents;
+  collectionContents: CachedCollectionContentsResponse;
   /** Get some primary information about the service. */
   coreDetails: CoreDetails;
   /** Get details about an exercise. */
   exerciseDetails: Exercise;
-  /** Get a paginated list of exercises in the database. */
-  exercisesList: IdResults;
   /** Get details about a genre present in the database. */
   genreDetails: GenreDetails;
   /** Get paginated list of genres. */
@@ -1773,16 +1785,10 @@ export type QueryRoot = {
   metadataGroupDetails: MetadataGroupDetails;
   /** Search for a list of groups from a given source. */
   metadataGroupSearch: MetadataGroupSearchResults;
-  /** Get paginated list of metadata groups. */
-  metadataGroupsList: IdResults;
-  /** Get all the media items related to a user for a specific media type. */
-  metadataList: IdResults;
   /** Get partial details about a media present in the database. */
   metadataPartialDetails: MetadataPartialDetails;
   /** Search for a list of media for a given type. */
   metadataSearch: MetadataSearchResults;
-  /** Get paginated list of people. */
-  peopleList: IdResults;
   /** Search for a list of people from a given source. */
   peopleSearch: PeopleSearchResults;
   /** Get details about a creator present in the database. */
@@ -1798,11 +1804,13 @@ export type QueryRoot = {
   /** Get calendar events for a user between a given date range. */
   userCalendarEvents: Array<GroupedCalendarEvent>;
   /** Get all collections for the currently logged in user. */
-  userCollectionsList: Array<CollectionItem>;
+  userCollectionsList: CachedCollectionsListResponse;
   /** Get details about the currently logged in user. */
   userDetails: UserDetailsResult;
   /** Get information about an exercise for a user. */
   userExerciseDetails: UserExerciseDetails;
+  /** Get a paginated list of exercises in the database. */
+  userExercisesList: CachedSearchIdResponse;
   /** Get all the export jobs for the current user. */
   userExports: Array<ExportJob>;
   /** Get all the integrations for the currently logged in user. */
@@ -1813,12 +1821,18 @@ export type QueryRoot = {
   userMetadataDetails: UserMetadataDetails;
   /** Get details that can be displayed to a user for a metadata group. */
   userMetadataGroupDetails: UserMetadataGroupDetails;
+  /** Get paginated list of metadata groups. */
+  userMetadataGroupsList: CachedSearchIdResponse;
+  /** Get all the media items related to a user for a specific media type. */
+  userMetadataList: CachedSearchIdResponse;
   /** Get metadata recommendations for the currently logged in user. */
-  userMetadataRecommendations: Array<Scalars['String']['output']>;
+  userMetadataRecommendations: CachedUserMetadataRecommendationsResponse;
   /** Get all the notification platforms for the currently logged in user. */
   userNotificationPlatforms: Array<NotificationPlatform>;
   /** Get all pending display notifications for the currently logged in user. */
   userPendingNotifications: Array<UserNotification>;
+  /** Get paginated list of people. */
+  userPeopleList: CachedSearchIdResponse;
   /** Get details that can be displayed to a user for a creator. */
   userPersonDetails: UserPersonDetails;
   /** Get upcoming calendar events for the given filter. */
@@ -1828,9 +1842,9 @@ export type QueryRoot = {
   /** Get information about a workout template. */
   userWorkoutTemplateDetails: UserWorkoutTemplateDetails;
   /** Get a paginated list of templates created by the user. */
-  userWorkoutTemplatesList: IdResults;
+  userWorkoutTemplatesList: CachedSearchIdResponse;
   /** Get a paginated list of workouts done by the user. */
-  userWorkoutsList: IdResults;
+  userWorkoutsList: CachedSearchIdResponse;
   /** Get details about all the users in the service. */
   usersList: Array<User>;
 };
@@ -1846,11 +1860,6 @@ export type QueryRootExerciseDetailsArgs = {
 };
 
 
-export type QueryRootExercisesListArgs = {
-  input: ExercisesListInput;
-};
-
-
 export type QueryRootGenreDetailsArgs = {
   input: GenreDetailsInput;
 };
@@ -1886,16 +1895,6 @@ export type QueryRootMetadataGroupSearchArgs = {
 };
 
 
-export type QueryRootMetadataGroupsListArgs = {
-  input: MetadataGroupsListInput;
-};
-
-
-export type QueryRootMetadataListArgs = {
-  input: MetadataListInput;
-};
-
-
 export type QueryRootMetadataPartialDetailsArgs = {
   metadataId: Scalars['String']['input'];
 };
@@ -1906,11 +1905,6 @@ export type QueryRootMetadataSearchArgs = {
 };
 
 
-export type QueryRootPeopleListArgs = {
-  input: PeopleListInput;
-};
-
-
 export type QueryRootPeopleSearchArgs = {
   input: PeopleSearchInput;
 };
@@ -1946,6 +1940,11 @@ export type QueryRootUserExerciseDetailsArgs = {
 };
 
 
+export type QueryRootUserExercisesListArgs = {
+  input: UserExercisesListInput;
+};
+
+
 export type QueryRootUserMeasurementsListArgs = {
   input: UserMeasurementsListInput;
 };
@@ -1961,8 +1960,18 @@ export type QueryRootUserMetadataGroupDetailsArgs = {
 };
 
 
-export type QueryRootUserMetadataRecommendationsArgs = {
-  shouldRefresh?: InputMaybe<Scalars['Boolean']['input']>;
+export type QueryRootUserMetadataGroupsListArgs = {
+  input: UserMetadataGroupsListInput;
+};
+
+
+export type QueryRootUserMetadataListArgs = {
+  input: UserMetadataListInput;
+};
+
+
+export type QueryRootUserPeopleListArgs = {
+  input: UserPeopleListInput;
 };
 
 
@@ -1987,12 +1996,12 @@ export type QueryRootUserWorkoutTemplateDetailsArgs = {
 
 
 export type QueryRootUserWorkoutTemplatesListArgs = {
-  input: SearchInput;
+  input: UserTemplatesOrWorkoutsListInput;
 };
 
 
 export type QueryRootUserWorkoutsListArgs = {
-  input: SearchInput;
+  input: UserTemplatesOrWorkoutsListInput;
 };
 
 
@@ -2330,6 +2339,12 @@ export type UserExerciseInput = {
   sets: Array<UserWorkoutSetRecord>;
 };
 
+export type UserExercisesListInput = {
+  filter?: InputMaybe<ExerciseListFilter>;
+  search: SearchInput;
+  sortBy?: InputMaybe<ExerciseSortBy>;
+};
+
 export type UserFeaturesEnabledPreferences = {
   analytics: UserAnalyticsFeaturesEnabledPreferences;
   fitness: UserFitnessFeaturesEnabledPreferences;
@@ -2682,6 +2697,21 @@ export type UserMetadataGroupDetails = {
   reviews: Array<ReviewItem>;
 };
 
+export type UserMetadataGroupsListInput = {
+  filter?: InputMaybe<MediaFilter>;
+  invertCollection?: InputMaybe<Scalars['Boolean']['input']>;
+  search?: InputMaybe<SearchInput>;
+  sort?: InputMaybe<PersonSortInput>;
+};
+
+export type UserMetadataListInput = {
+  filter?: InputMaybe<MediaFilter>;
+  invertCollection?: InputMaybe<Scalars['Boolean']['input']>;
+  lot?: InputMaybe<MediaLot>;
+  search?: InputMaybe<SearchInput>;
+  sort?: InputMaybe<MediaSortInput>;
+};
+
 export type UserNotification = {
   createdOn: Scalars['DateTime']['output'];
   id: Scalars['String']['output'];
@@ -2724,6 +2754,13 @@ export type UserOthersFeaturesEnabledPreferencesInput = {
   collections: Scalars['Boolean']['input'];
 };
 
+export type UserPeopleListInput = {
+  filter?: InputMaybe<MediaFilter>;
+  invertCollection?: InputMaybe<Scalars['Boolean']['input']>;
+  search?: InputMaybe<SearchInput>;
+  sort?: InputMaybe<PersonSortInput>;
+};
+
 export type UserPersonDetails = {
   collections: Array<Collection>;
   recentlyConsumed: Scalars['Boolean']['output'];
@@ -2750,6 +2787,16 @@ export enum UserReviewScale {
   ThreePointSmiley = 'THREE_POINT_SMILEY'
 }
 
+export type UserTemplatesOrWorkoutsListInput = {
+  search: SearchInput;
+  sort?: InputMaybe<UserWorkoutsListSortInput>;
+};
+
+export enum UserTemplatesOrWorkoutsListSortBy {
+  Random = 'RANDOM',
+  Time = 'TIME'
+}
+
 export type UserToEntity = {
   collectionId?: Maybe<Scalars['String']['output']>;
   createdOn: Scalars['DateTime']['output'];
@@ -2851,6 +2898,11 @@ export type UserWorkoutTemplateDetails = {
   details: WorkoutTemplate;
 };
 
+export type UserWorkoutsListSortInput = {
+  by?: UserTemplatesOrWorkoutsListSortBy;
+  order?: GraphqlSortOrder;
+};
+
 export type VideoGameSpecifics = {
   platforms: Array<Scalars['String']['output']>;
 };
@@ -3406,6 +3458,13 @@ export type MarkNotificationsAsAddressedMutationVariables = Exact<{
 
 export type MarkNotificationsAsAddressedMutation = { markNotificationsAsAddressed: boolean };
 
+export type ExpireCacheKeyMutationVariables = Exact<{
+  cacheId: Scalars['UUID']['input'];
+}>;
+
+
+export type ExpireCacheKeyMutation = { expireCacheKey: boolean };
+
 export type MetadataDetailsQueryVariables = Exact<{
   metadataId: Scalars['String']['input'];
 }>;
@@ -3489,7 +3548,7 @@ export type UserCollectionsListQueryVariables = Exact<{
 }>;
 
 
-export type UserCollectionsListQuery = { userCollectionsList: Array<{ id: string, name: string, count: number, isDefault: boolean, description?: string | null, creator: { id: string, name: string }, collaborators: Array<{ id: string, name: string }>, informationTemplate?: Array<{ lot: CollectionExtraInformationLot, name: string, required?: boolean | null, description: string, defaultValue?: string | null }> | null }> };
+export type UserCollectionsListQuery = { userCollectionsList: { cacheId: string, response: Array<{ id: string, name: string, count: number, isDefault: boolean, description?: string | null, creator: { id: string, name: string }, collaborators: Array<{ id: string, name: string }>, informationTemplate?: Array<{ lot: CollectionExtraInformationLot, name: string, required?: boolean | null, description: string, defaultValue?: string | null }> | null }> } };
 
 export type UserIntegrationsQueryVariables = Exact<{ [key: string]: never; }>;
 
@@ -3508,12 +3567,10 @@ export type UsersListQueryVariables = Exact<{
 
 export type UsersListQuery = { usersList: Array<{ id: string, lot: UserLot, name: string, isDisabled?: boolean | null }> };
 
-export type UserMetadataRecommendationsQueryVariables = Exact<{
-  shouldRefresh?: InputMaybe<Scalars['Boolean']['input']>;
-}>;
+export type UserMetadataRecommendationsQueryVariables = Exact<{ [key: string]: never; }>;
 
 
-export type UserMetadataRecommendationsQuery = { userMetadataRecommendations: Array<string> };
+export type UserMetadataRecommendationsQuery = { userMetadataRecommendations: { cacheId: string, response: Array<string> } };
 
 export type UserUpcomingCalendarEventsQueryVariables = Exact<{
   input: UserUpcomingCalendarEventInput;
@@ -3536,19 +3593,19 @@ export type MetadataPartialDetailsQueryVariables = Exact<{
 
 export type MetadataPartialDetailsQuery = { metadataPartialDetails: { id: string, lot: MediaLot, title: string, image?: string | null, publishYear?: number | null } };
 
-export type MetadataGroupsListQueryVariables = Exact<{
-  input: MetadataGroupsListInput;
+export type UserMetadataGroupsListQueryVariables = Exact<{
+  input: UserMetadataGroupsListInput;
 }>;
 
 
-export type MetadataGroupsListQuery = { metadataGroupsList: { items: Array<string>, details: { total: number, nextPage?: number | null } } };
+export type UserMetadataGroupsListQuery = { userMetadataGroupsList: { cacheId: string, response: { items: Array<string>, details: { total: number, nextPage?: number | null } } } };
 
-export type PeopleListQueryVariables = Exact<{
-  input: PeopleListInput;
+export type UserPeopleListQueryVariables = Exact<{
+  input: UserPeopleListInput;
 }>;
 
 
-export type PeopleListQuery = { peopleList: { items: Array<string>, details: { total: number, nextPage?: number | null } } };
+export type UserPeopleListQuery = { userPeopleList: { cacheId: string, response: { items: Array<string>, details: { total: number, nextPage?: number | null } } } };
 
 export type UserAccessLinksQueryVariables = Exact<{ [key: string]: never; }>;
 
@@ -3562,12 +3619,12 @@ export type ExerciseDetailsQueryVariables = Exact<{
 
 export type ExerciseDetailsQuery = { exerciseDetails: { id: string, lot: ExerciseLot, name: string, level: ExerciseLevel, force?: ExerciseForce | null, source: ExerciseSource, muscles: Array<ExerciseMuscle>, mechanic?: ExerciseMechanic | null, equipment?: ExerciseEquipment | null, createdByUserId?: string | null, attributes: { instructions: Array<string>, images: Array<string> } } };
 
-export type ExercisesListQueryVariables = Exact<{
-  input: ExercisesListInput;
+export type UserExercisesListQueryVariables = Exact<{
+  input: UserExercisesListInput;
 }>;
 
 
-export type ExercisesListQuery = { exercisesList: { items: Array<string>, details: { total: number, nextPage?: number | null } } };
+export type UserExercisesListQuery = { userExercisesList: { cacheId: string, response: { items: Array<string>, details: { total: number, nextPage?: number | null } } } };
 
 export type ImportReportsQueryVariables = Exact<{ [key: string]: never; }>;
 
@@ -3593,12 +3650,12 @@ export type CollectionContentsQueryVariables = Exact<{
 }>;
 
 
-export type CollectionContentsQuery = { collectionContents: { user: { id: string, name: string }, reviews: Array<{ id: string, rating?: string | null, postedOn: string, isSpoiler: boolean, visibility: Visibility, textOriginal?: string | null, textRendered?: string | null, seenItemsAssociatedWith: Array<string>, postedBy: { id: string, name: string }, comments: Array<{ id: string, text: string, likedBy: Array<string>, createdOn: string, user: { id: string, name: string } }>, showExtraInformation?: { season?: number | null, episode?: number | null } | null, podcastExtraInformation?: { episode?: number | null } | null, animeExtraInformation?: { episode?: number | null } | null, mangaExtraInformation?: { volume?: number | null, chapter?: string | null } | null }>, results: { details: { total: number, nextPage?: number | null }, items: Array<{ entityId: string, entityLot: EntityLot }> }, details: { name: string, description?: string | null, createdOn: string } } };
+export type CollectionContentsQuery = { collectionContents: { cacheId: string, response: { totalItems: number, user: { id: string, name: string }, reviews: Array<{ id: string, rating?: string | null, postedOn: string, isSpoiler: boolean, visibility: Visibility, textOriginal?: string | null, textRendered?: string | null, seenItemsAssociatedWith: Array<string>, postedBy: { id: string, name: string }, comments: Array<{ id: string, text: string, likedBy: Array<string>, createdOn: string, user: { id: string, name: string } }>, showExtraInformation?: { season?: number | null, episode?: number | null } | null, podcastExtraInformation?: { episode?: number | null } | null, animeExtraInformation?: { episode?: number | null } | null, mangaExtraInformation?: { volume?: number | null, chapter?: string | null } | null }>, details: { name: string, createdOn: string, description?: string | null }, results: { details: { total: number, nextPage?: number | null }, items: Array<{ entityId: string, entityLot: EntityLot }> } } } };
 
 export type CoreDetailsQueryVariables = Exact<{ [key: string]: never; }>;
 
 
-export type CoreDetailsQuery = { coreDetails: { version: string, docsLink: string, pageSize: number, websiteUrl: string, smtpEnabled: boolean, oidcEnabled: boolean, signupAllowed: boolean, repositoryLink: string, disableTelemetry: boolean, tokenValidForDays: number, localAuthDisabled: boolean, fileStorageEnabled: boolean, peopleSearchSources: Array<MediaSource>, isServerKeyValidated: boolean, metadataGroupSourceLotMappings: Array<{ lot: MediaLot, source: MediaSource }>, metadataLotSourceMappings: Array<{ lot: MediaLot, sources: Array<MediaSource> }>, metadataProviderLanguages: Array<{ source: MediaSource, default: string, supported: Array<string> }>, frontend: { url: string, oidcButtonLabel: string, dashboardMessage: string, umami: { domains: string, scriptUrl: string, websiteId: string } }, exerciseParameters: { downloadRequired: boolean, filters: { type: Array<ExerciseLot>, level: Array<ExerciseLevel>, force: Array<ExerciseForce>, mechanic: Array<ExerciseMechanic>, equipment: Array<ExerciseEquipment>, muscle: Array<ExerciseMuscle> }, lotMapping: Array<{ lot: ExerciseLot, bests: Array<WorkoutSetPersonalBest> }> } } };
+export type CoreDetailsQuery = { coreDetails: { version: string, docsLink: string, pageSize: number, websiteUrl: string, smtpEnabled: boolean, oidcEnabled: boolean, signupAllowed: boolean, repositoryLink: string, disableTelemetry: boolean, tokenValidForDays: number, localAuthDisabled: boolean, fileStorageEnabled: boolean, peopleSearchSources: Array<MediaSource>, isServerKeyValidated: boolean, metadataGroupSourceLotMappings: Array<{ lot: MediaLot, source: MediaSource }>, metadataLotSourceMappings: Array<{ lot: MediaLot, sources: Array<MediaSource> }>, metadataProviderLanguages: Array<{ source: MediaSource, default: string, supported: Array<string> }>, frontend: { url: string, oidcButtonLabel: string, dashboardMessage: string, umami: { domains: string, scriptUrl: string, websiteId: string } }, exerciseParameters: { lotMapping: Array<{ lot: ExerciseLot, bests: Array<WorkoutSetPersonalBest> }>, filters: { type: Array<ExerciseLot>, level: Array<ExerciseLevel>, force: Array<ExerciseForce>, muscle: Array<ExerciseMuscle>, mechanic: Array<ExerciseMechanic>, equipment: Array<ExerciseEquipment> } } } };
 
 export type MetadataGroupDetailsQueryVariables = Exact<{
   metadataGroupId: Scalars['String']['input'];
@@ -3614,12 +3671,12 @@ export type MetadataGroupSearchQueryVariables = Exact<{
 
 export type MetadataGroupSearchQuery = { metadataGroupSearch: { details: { total: number, nextPage?: number | null }, items: Array<{ identifier: string, name: string, image?: string | null, parts?: number | null }> } };
 
-export type MetadataListQueryVariables = Exact<{
-  input: MetadataListInput;
+export type UserMetadataListQueryVariables = Exact<{
+  input: UserMetadataListInput;
 }>;
 
 
-export type MetadataListQuery = { metadataList: { items: Array<string>, details: { total: number, nextPage?: number | null } } };
+export type UserMetadataListQuery = { userMetadataList: { cacheId: string, response: { items: Array<string>, details: { total: number, nextPage?: number | null } } } };
 
 export type MetadataSearchQueryVariables = Exact<{
   input: MetadataSearchInput;
@@ -3657,11 +3714,11 @@ export type UserWorkoutDetailsQueryVariables = Exact<{
 export type UserWorkoutDetailsQuery = { userWorkoutDetails: { collections: Array<{ id: string, name: string, userId: string }>, details: { id: string, name: string, endTime: string, duration: number, startTime: string, templateId?: string | null, repeatedFrom?: string | null, caloriesBurnt?: string | null, summary: { total?: { reps: string, weight: string, distance: string, duration: string, restTime: number, personalBestsAchieved: number } | null, exercises: Array<{ id: string, lot?: ExerciseLot | null, numSets: number, bestSet?: { lot: SetLot, personalBests?: Array<WorkoutSetPersonalBest> | null, statistic: { reps?: string | null, pace?: string | null, oneRm?: string | null, weight?: string | null, volume?: string | null, duration?: string | null, distance?: string | null } } | null }>, focused: { lots: Array<{ lot: ExerciseLot, exercises: Array<number> }>, levels: Array<{ level: ExerciseLevel, exercises: Array<number> }>, forces: Array<{ force: ExerciseForce, exercises: Array<number> }>, muscles: Array<{ muscle: ExerciseMuscle, exercises: Array<number> }>, equipments: Array<{ equipment: ExerciseEquipment, exercises: Array<number> }> } }, information: { comment?: string | null, assets?: { images: Array<string>, videos: Array<string> } | null, supersets: Array<{ color: string, exercises: Array<number> }>, exercises: Array<{ id: string, lot: ExerciseLot, notes: Array<string>, total?: { reps: string, weight: string, distance: string, duration: string, restTime: number, personalBestsAchieved: number } | null, assets?: { images: Array<string>, videos: Array<string> } | null, sets: Array<{ lot: SetLot, rpe?: number | null, note?: string | null, restTime?: number | null, confirmedAt?: string | null, personalBests?: Array<WorkoutSetPersonalBest> | null, statistic: { reps?: string | null, pace?: string | null, oneRm?: string | null, weight?: string | null, volume?: string | null, duration?: string | null, distance?: string | null } }> }> } } } };
 
 export type UserWorkoutsListQueryVariables = Exact<{
-  input: SearchInput;
+  input: UserTemplatesOrWorkoutsListInput;
 }>;
 
 
-export type UserWorkoutsListQuery = { userWorkoutsList: { items: Array<string>, details: { total: number, nextPage?: number | null } } };
+export type UserWorkoutsListQuery = { userWorkoutsList: { cacheId: string, response: { items: Array<string>, details: { total: number, nextPage?: number | null } } } };
 
 export type UserWorkoutTemplateDetailsQueryVariables = Exact<{
   workoutTemplateId: Scalars['String']['input'];
@@ -3671,11 +3728,11 @@ export type UserWorkoutTemplateDetailsQueryVariables = Exact<{
 export type UserWorkoutTemplateDetailsQuery = { userWorkoutTemplateDetails: { collections: Array<{ id: string, name: string, userId: string }>, details: { id: string, name: string, createdOn: string, summary: { total?: { reps: string, weight: string, distance: string, duration: string, restTime: number, personalBestsAchieved: number } | null, exercises: Array<{ id: string, lot?: ExerciseLot | null, numSets: number, bestSet?: { lot: SetLot, personalBests?: Array<WorkoutSetPersonalBest> | null, statistic: { reps?: string | null, pace?: string | null, oneRm?: string | null, weight?: string | null, volume?: string | null, duration?: string | null, distance?: string | null } } | null }>, focused: { lots: Array<{ lot: ExerciseLot, exercises: Array<number> }>, levels: Array<{ level: ExerciseLevel, exercises: Array<number> }>, forces: Array<{ force: ExerciseForce, exercises: Array<number> }>, muscles: Array<{ muscle: ExerciseMuscle, exercises: Array<number> }>, equipments: Array<{ equipment: ExerciseEquipment, exercises: Array<number> }> } }, information: { comment?: string | null, assets?: { images: Array<string>, videos: Array<string> } | null, supersets: Array<{ color: string, exercises: Array<number> }>, exercises: Array<{ id: string, lot: ExerciseLot, notes: Array<string>, total?: { reps: string, weight: string, distance: string, duration: string, restTime: number, personalBestsAchieved: number } | null, assets?: { images: Array<string>, videos: Array<string> } | null, sets: Array<{ lot: SetLot, rpe?: number | null, note?: string | null, restTime?: number | null, confirmedAt?: string | null, personalBests?: Array<WorkoutSetPersonalBest> | null, statistic: { reps?: string | null, pace?: string | null, oneRm?: string | null, weight?: string | null, volume?: string | null, duration?: string | null, distance?: string | null } }> }> } } } };
 
 export type UserWorkoutTemplatesListQueryVariables = Exact<{
-  input: SearchInput;
+  input: UserTemplatesOrWorkoutsListInput;
 }>;
 
 
-export type UserWorkoutTemplatesListQuery = { userWorkoutTemplatesList: { items: Array<string>, details: { total: number, nextPage?: number | null } } };
+export type UserWorkoutTemplatesListQuery = { userWorkoutTemplatesList: { cacheId: string, response: { items: Array<string>, details: { total: number, nextPage?: number | null } } } };
 
 export type UserAnalyticsParametersQueryVariables = Exact<{ [key: string]: never; }>;
 
@@ -3792,6 +3849,7 @@ export const UpdateUserExerciseSettingsDocument = {"kind":"Document","definition
 export const MergeExerciseDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"MergeExercise"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"mergeFrom"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"mergeInto"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"mergeExercise"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"mergeFrom"},"value":{"kind":"Variable","name":{"kind":"Name","value":"mergeFrom"}}},{"kind":"Argument","name":{"kind":"Name","value":"mergeInto"},"value":{"kind":"Variable","name":{"kind":"Name","value":"mergeInto"}}}]}]}}]} as unknown as DocumentNode<MergeExerciseMutation, MergeExerciseMutationVariables>;
 export const MarkEntityAsPartialDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"MarkEntityAsPartial"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"MarkEntityAsPartialInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"markEntityAsPartial"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode<MarkEntityAsPartialMutation, MarkEntityAsPartialMutationVariables>;
 export const MarkNotificationsAsAddressedDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"MarkNotificationsAsAddressed"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"notificationIds"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"markNotificationsAsAddressed"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"notificationIds"},"value":{"kind":"Variable","name":{"kind":"Name","value":"notificationIds"}}}]}]}}]} as unknown as DocumentNode<MarkNotificationsAsAddressedMutation, MarkNotificationsAsAddressedMutationVariables>;
+export const ExpireCacheKeyDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ExpireCacheKey"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cacheId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"expireCacheKey"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"cacheId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cacheId"}}}]}]}}]} as unknown as DocumentNode<ExpireCacheKeyMutation, ExpireCacheKeyMutationVariables>;
 export const MetadataDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MetadataDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"metadataId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"metadataDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"metadataId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"metadataId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"isNsfw"}},{"kind":"Field","name":{"kind":"Name","value":"isPartial"}},{"kind":"Field","name":{"kind":"Name","value":"sourceUrl"}},{"kind":"Field","name":{"kind":"Name","value":"identifier"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"suggestions"}},{"kind":"Field","name":{"kind":"Name","value":"publishYear"}},{"kind":"Field","name":{"kind":"Name","value":"publishDate"}},{"kind":"Field","name":{"kind":"Name","value":"providerRating"}},{"kind":"Field","name":{"kind":"Name","value":"createdByUserId"}},{"kind":"Field","name":{"kind":"Name","value":"productionStatus"}},{"kind":"Field","name":{"kind":"Name","value":"originalLanguage"}},{"kind":"Field","name":{"kind":"Name","value":"animeSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episodes"}}]}},{"kind":"Field","name":{"kind":"Name","value":"audioBookSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"runtime"}}]}},{"kind":"Field","name":{"kind":"Name","value":"movieSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"runtime"}}]}},{"kind":"Field","name":{"kind":"Name","value":"genres"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"group"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"part"}}]}},{"kind":"Field","name":{"kind":"Name","value":"watchProviders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"languages"}}]}},{"kind":"Field","name":{"kind":"Name","value":"bookSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"pages"}},{"kind":"Field","name":{"kind":"Name","value":"isCompilation"}}]}},{"kind":"Field","name":{"kind":"Name","value":"mangaSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"volumes"}},{"kind":"Field","name":{"kind":"Name","value":"chapters"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"images"}},{"kind":"Field","name":{"kind":"Name","value":"videos"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"videoId"}},{"kind":"Field","name":{"kind":"Name","value":"source"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"creators"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"character"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"podcastSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episodes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"overview"}},{"kind":"Field","name":{"kind":"Name","value":"thumbnail"}},{"kind":"Field","name":{"kind":"Name","value":"number"}},{"kind":"Field","name":{"kind":"Name","value":"runtime"}},{"kind":"Field","name":{"kind":"Name","value":"publishDate"}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalEpisodes"}}]}},{"kind":"Field","name":{"kind":"Name","value":"showSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalSeasons"}},{"kind":"Field","name":{"kind":"Name","value":"totalEpisodes"}},{"kind":"Field","name":{"kind":"Name","value":"runtime"}},{"kind":"Field","name":{"kind":"Name","value":"seasons"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"seasonNumber"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"overview"}},{"kind":"Field","name":{"kind":"Name","value":"backdropImages"}},{"kind":"Field","name":{"kind":"Name","value":"posterImages"}},{"kind":"Field","name":{"kind":"Name","value":"episodes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"posterImages"}},{"kind":"Field","name":{"kind":"Name","value":"episodeNumber"}},{"kind":"Field","name":{"kind":"Name","value":"publishDate"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"overview"}},{"kind":"Field","name":{"kind":"Name","value":"runtime"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"visualNovelSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"length"}}]}},{"kind":"Field","name":{"kind":"Name","value":"videoGameSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"platforms"}}]}},{"kind":"Field","name":{"kind":"Name","value":"musicSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"viewCount"}},{"kind":"Field","name":{"kind":"Name","value":"byVariousArtists"}}]}}]}}]}}]} as unknown as DocumentNode<MetadataDetailsQuery, MetadataDetailsQueryVariables>;
 export const PersonDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"PersonDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"personId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"personDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"personId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"personId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"associatedMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"PersonDetailsGroupedByRolePart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"associatedMetadataGroups"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"PersonDetailsGroupedByRolePart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"place"}},{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"gender"}},{"kind":"Field","name":{"kind":"Name","value":"website"}},{"kind":"Field","name":{"kind":"Name","value":"deathDate"}},{"kind":"Field","name":{"kind":"Name","value":"birthDate"}},{"kind":"Field","name":{"kind":"Name","value":"isPartial"}},{"kind":"Field","name":{"kind":"Name","value":"sourceUrl"}},{"kind":"Field","name":{"kind":"Name","value":"identifier"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"displayImages"}},{"kind":"Field","name":{"kind":"Name","value":"alternateNames"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PersonDetailsGroupedByRolePart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PersonDetailsGroupedByRole"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"entityId"}},{"kind":"Field","name":{"kind":"Name","value":"character"}}]}}]}}]} as unknown as DocumentNode<PersonDetailsQuery, PersonDetailsQueryVariables>;
 export const UserAnalyticsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserAnalytics"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserAnalyticsInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userAnalytics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hours"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hour"}},{"kind":"Field","name":{"kind":"Name","value":"entities"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"entityId"}},{"kind":"Field","name":{"kind":"Name","value":"entityLot"}},{"kind":"Field","name":{"kind":"Name","value":"metadataLot"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"activities"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"groupedBy"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalDuration"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"day"}},{"kind":"Field","name":{"kind":"Name","value":"bookCount"}},{"kind":"Field","name":{"kind":"Name","value":"showCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}},{"kind":"Field","name":{"kind":"Name","value":"movieCount"}},{"kind":"Field","name":{"kind":"Name","value":"musicCount"}},{"kind":"Field","name":{"kind":"Name","value":"animeCount"}},{"kind":"Field","name":{"kind":"Name","value":"mangaCount"}},{"kind":"Field","name":{"kind":"Name","value":"workoutCount"}},{"kind":"Field","name":{"kind":"Name","value":"podcastCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalDuration"}},{"kind":"Field","name":{"kind":"Name","value":"totalBookPages"}},{"kind":"Field","name":{"kind":"Name","value":"audioBookCount"}},{"kind":"Field","name":{"kind":"Name","value":"videoGameCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalReviewCount"}},{"kind":"Field","name":{"kind":"Name","value":"visualNovelCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutReps"}},{"kind":"Field","name":{"kind":"Name","value":"totalShowDuration"}},{"kind":"Field","name":{"kind":"Name","value":"totalMovieDuration"}},{"kind":"Field","name":{"kind":"Name","value":"totalMusicDuration"}},{"kind":"Field","name":{"kind":"Name","value":"totalMetadataCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutWeight"}},{"kind":"Field","name":{"kind":"Name","value":"totalPodcastDuration"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutDistance"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutRestTime"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutDuration"}},{"kind":"Field","name":{"kind":"Name","value":"userMeasurementCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalVideoGameDuration"}},{"kind":"Field","name":{"kind":"Name","value":"totalAudioBookDuration"}},{"kind":"Field","name":{"kind":"Name","value":"totalPersonReviewCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalVisualNovelDuration"}},{"kind":"Field","name":{"kind":"Name","value":"totalMetadataReviewCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutPersonalBests"}},{"kind":"Field","name":{"kind":"Name","value":"totalCollectionReviewCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalMetadataGroupReviewCount"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"fitness"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workoutReps"}},{"kind":"Field","name":{"kind":"Name","value":"workoutCount"}},{"kind":"Field","name":{"kind":"Name","value":"workoutWeight"}},{"kind":"Field","name":{"kind":"Name","value":"workoutDistance"}},{"kind":"Field","name":{"kind":"Name","value":"workoutDuration"}},{"kind":"Field","name":{"kind":"Name","value":"workoutRestTime"}},{"kind":"Field","name":{"kind":"Name","value":"measurementCount"}},{"kind":"Field","name":{"kind":"Name","value":"workoutPersonalBests"}},{"kind":"Field","name":{"kind":"Name","value":"workoutCaloriesBurnt"}},{"kind":"Field","name":{"kind":"Name","value":"workoutExercises"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"exercise"}}]}},{"kind":"Field","name":{"kind":"Name","value":"workoutMuscles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"muscle"}}]}},{"kind":"Field","name":{"kind":"Name","value":"workoutEquipments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"equipment"}}]}}]}}]}}]}}]} as unknown as DocumentNode<UserAnalyticsQuery, UserAnalyticsQueryVariables>;
@@ -3804,34 +3862,34 @@ export const UserByOidcIssuerIdDocument = {"kind":"Document","definitions":[{"ki
 export const GetOidcTokenDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOidcToken"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"code"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getOidcToken"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"code"},"value":{"kind":"Variable","name":{"kind":"Name","value":"code"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"subject"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}}]}}]} as unknown as DocumentNode<GetOidcTokenQuery, GetOidcTokenQueryVariables>;
 export const GetPresignedS3UrlDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetPresignedS3Url"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"key"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getPresignedS3Url"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"key"},"value":{"kind":"Variable","name":{"kind":"Name","value":"key"}}}]}]}}]} as unknown as DocumentNode<GetPresignedS3UrlQuery, GetPresignedS3UrlQueryVariables>;
 export const UserExportsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserExports"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userExports"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"size"}},{"kind":"Field","name":{"kind":"Name","value":"endedAt"}},{"kind":"Field","name":{"kind":"Name","value":"startedAt"}}]}}]}}]} as unknown as DocumentNode<UserExportsQuery, UserExportsQueryVariables>;
-export const UserCollectionsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserCollectionsList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userCollectionsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"isDefault"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"creator"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"collaborators"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"informationTemplate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"required"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"defaultValue"}}]}}]}}]}}]} as unknown as DocumentNode<UserCollectionsListQuery, UserCollectionsListQueryVariables>;
+export const UserCollectionsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserCollectionsList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userCollectionsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cacheId"}},{"kind":"Field","name":{"kind":"Name","value":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"isDefault"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"creator"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"collaborators"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"informationTemplate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"required"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"defaultValue"}}]}}]}}]}}]}}]} as unknown as DocumentNode<UserCollectionsListQuery, UserCollectionsListQueryVariables>;
 export const UserIntegrationsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserIntegrations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userIntegrations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"provider"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}},{"kind":"Field","name":{"kind":"Name","value":"isDisabled"}},{"kind":"Field","name":{"kind":"Name","value":"maximumProgress"}},{"kind":"Field","name":{"kind":"Name","value":"minimumProgress"}},{"kind":"Field","name":{"kind":"Name","value":"lastTriggeredOn"}},{"kind":"Field","name":{"kind":"Name","value":"syncToOwnedCollection"}}]}}]}}]} as unknown as DocumentNode<UserIntegrationsQuery, UserIntegrationsQueryVariables>;
 export const UserNotificationPlatformsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserNotificationPlatforms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userNotificationPlatforms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}},{"kind":"Field","name":{"kind":"Name","value":"isDisabled"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}}]}}]} as unknown as DocumentNode<UserNotificationPlatformsQuery, UserNotificationPlatformsQueryVariables>;
 export const UsersListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UsersList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"query"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"usersList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"query"},"value":{"kind":"Variable","name":{"kind":"Name","value":"query"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"isDisabled"}}]}}]}}]} as unknown as DocumentNode<UsersListQuery, UsersListQueryVariables>;
-export const UserMetadataRecommendationsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserMetadataRecommendations"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"shouldRefresh"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userMetadataRecommendations"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"shouldRefresh"},"value":{"kind":"Variable","name":{"kind":"Name","value":"shouldRefresh"}}}]}]}}]} as unknown as DocumentNode<UserMetadataRecommendationsQuery, UserMetadataRecommendationsQueryVariables>;
+export const UserMetadataRecommendationsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserMetadataRecommendations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userMetadataRecommendations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cacheId"}},{"kind":"Field","name":{"kind":"Name","value":"response"}}]}}]}}]} as unknown as DocumentNode<UserMetadataRecommendationsQuery, UserMetadataRecommendationsQueryVariables>;
 export const UserUpcomingCalendarEventsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserUpcomingCalendarEvents"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserUpcomingCalendarEventInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userUpcomingCalendarEvents"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CalendarEventPart"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenShowExtraInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SeenShowExtraInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}},{"kind":"Field","name":{"kind":"Name","value":"season"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenPodcastExtraInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SeenPodcastExtraInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenAnimeExtraInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SeenAnimeExtraInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CalendarEventPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"GraphqlCalendarEvent"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"metadataId"}},{"kind":"Field","name":{"kind":"Name","value":"metadataLot"}},{"kind":"Field","name":{"kind":"Name","value":"metadataText"}},{"kind":"Field","name":{"kind":"Name","value":"metadataImage"}},{"kind":"Field","name":{"kind":"Name","value":"calendarEventId"}},{"kind":"Field","name":{"kind":"Name","value":"showExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenShowExtraInformationPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"podcastExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenPodcastExtraInformationPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"animeExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenAnimeExtraInformationPart"}}]}}]}}]} as unknown as DocumentNode<UserUpcomingCalendarEventsQuery, UserUpcomingCalendarEventsQueryVariables>;
 export const UserCalendarEventsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserCalendarEvents"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserCalendarEventInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userCalendarEvents"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"events"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CalendarEventPart"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenShowExtraInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SeenShowExtraInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}},{"kind":"Field","name":{"kind":"Name","value":"season"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenPodcastExtraInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SeenPodcastExtraInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenAnimeExtraInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SeenAnimeExtraInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CalendarEventPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"GraphqlCalendarEvent"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"metadataId"}},{"kind":"Field","name":{"kind":"Name","value":"metadataLot"}},{"kind":"Field","name":{"kind":"Name","value":"metadataText"}},{"kind":"Field","name":{"kind":"Name","value":"metadataImage"}},{"kind":"Field","name":{"kind":"Name","value":"calendarEventId"}},{"kind":"Field","name":{"kind":"Name","value":"showExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenShowExtraInformationPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"podcastExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenPodcastExtraInformationPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"animeExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenAnimeExtraInformationPart"}}]}}]}}]} as unknown as DocumentNode<UserCalendarEventsQuery, UserCalendarEventsQueryVariables>;
 export const MetadataPartialDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MetadataPartialDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"metadataId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"metadataPartialDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"metadataId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"metadataId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"publishYear"}}]}}]}}]} as unknown as DocumentNode<MetadataPartialDetailsQuery, MetadataPartialDetailsQueryVariables>;
-export const MetadataGroupsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MetadataGroupsList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"MetadataGroupsListInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"metadataGroupsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"}}]}}]}}]} as unknown as DocumentNode<MetadataGroupsListQuery, MetadataGroupsListQueryVariables>;
-export const PeopleListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"PeopleList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"PeopleListInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"peopleList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"}}]}}]}}]} as unknown as DocumentNode<PeopleListQuery, PeopleListQueryVariables>;
+export const UserMetadataGroupsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserMetadataGroupsList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserMetadataGroupsListInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userMetadataGroupsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cacheId"}},{"kind":"Field","name":{"kind":"Name","value":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}}]}}]}}]}}]} as unknown as DocumentNode<UserMetadataGroupsListQuery, UserMetadataGroupsListQueryVariables>;
+export const UserPeopleListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserPeopleList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserPeopleListInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userPeopleList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cacheId"}},{"kind":"Field","name":{"kind":"Name","value":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}}]}}]}}]}}]} as unknown as DocumentNode<UserPeopleListQuery, UserPeopleListQueryVariables>;
 export const UserAccessLinksDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserAccessLinks"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userAccessLinks"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"isDemo"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}},{"kind":"Field","name":{"kind":"Name","value":"expiresOn"}},{"kind":"Field","name":{"kind":"Name","value":"timesUsed"}},{"kind":"Field","name":{"kind":"Name","value":"isRevoked"}},{"kind":"Field","name":{"kind":"Name","value":"maximumUses"}},{"kind":"Field","name":{"kind":"Name","value":"isAccountDefault"}},{"kind":"Field","name":{"kind":"Name","value":"isMutationAllowed"}}]}}]}}]} as unknown as DocumentNode<UserAccessLinksQuery, UserAccessLinksQueryVariables>;
 export const ExerciseDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ExerciseDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"exerciseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"exerciseDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"exerciseId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"exerciseId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"level"}},{"kind":"Field","name":{"kind":"Name","value":"force"}},{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"muscles"}},{"kind":"Field","name":{"kind":"Name","value":"mechanic"}},{"kind":"Field","name":{"kind":"Name","value":"equipment"}},{"kind":"Field","name":{"kind":"Name","value":"createdByUserId"}},{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"instructions"}},{"kind":"Field","name":{"kind":"Name","value":"images"}}]}}]}}]}}]} as unknown as DocumentNode<ExerciseDetailsQuery, ExerciseDetailsQueryVariables>;
-export const ExercisesListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ExercisesList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ExercisesListInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"exercisesList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}}]}}]}}]} as unknown as DocumentNode<ExercisesListQuery, ExercisesListQueryVariables>;
+export const UserExercisesListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserExercisesList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserExercisesListInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userExercisesList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cacheId"}},{"kind":"Field","name":{"kind":"Name","value":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}}]}}]}}]}}]} as unknown as DocumentNode<UserExercisesListQuery, UserExercisesListQueryVariables>;
 export const ImportReportsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ImportReports"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"importReports"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"progress"}},{"kind":"Field","name":{"kind":"Name","value":"startedOn"}},{"kind":"Field","name":{"kind":"Name","value":"finishedOn"}},{"kind":"Field","name":{"kind":"Name","value":"wasSuccess"}},{"kind":"Field","name":{"kind":"Name","value":"estimatedFinishTime"}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"import"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}}]}},{"kind":"Field","name":{"kind":"Name","value":"failedItems"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"step"}},{"kind":"Field","name":{"kind":"Name","value":"error"}},{"kind":"Field","name":{"kind":"Name","value":"identifier"}}]}}]}}]}}]}}]} as unknown as DocumentNode<ImportReportsQuery, ImportReportsQueryVariables>;
 export const GenresListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GenresList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"SearchInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"genresList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}}]}}]}}]} as unknown as DocumentNode<GenresListQuery, GenresListQueryVariables>;
 export const GenreDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GenreDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GenreDetailsInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"genreDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"numItems"}}]}},{"kind":"Field","name":{"kind":"Name","value":"contents"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"}}]}}]}}]}}]} as unknown as DocumentNode<GenreDetailsQuery, GenreDetailsQueryVariables>;
-export const CollectionContentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CollectionContents"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CollectionContentsInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"collectionContents"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"reviews"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ReviewItemPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"results"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"entityId"}},{"kind":"Field","name":{"kind":"Name","value":"entityLot"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenAnimeExtraInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SeenAnimeExtraInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenMangaExtraInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SeenMangaExtraInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"volume"}},{"kind":"Field","name":{"kind":"Name","value":"chapter"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ReviewItemPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ReviewItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"postedOn"}},{"kind":"Field","name":{"kind":"Name","value":"isSpoiler"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"textOriginal"}},{"kind":"Field","name":{"kind":"Name","value":"textRendered"}},{"kind":"Field","name":{"kind":"Name","value":"seenItemsAssociatedWith"}},{"kind":"Field","name":{"kind":"Name","value":"postedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"likedBy"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"showExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"season"}},{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"Field","name":{"kind":"Name","value":"podcastExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"Field","name":{"kind":"Name","value":"animeExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenAnimeExtraInformationPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"mangaExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenMangaExtraInformationPart"}}]}}]}}]} as unknown as DocumentNode<CollectionContentsQuery, CollectionContentsQueryVariables>;
-export const CoreDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CoreDetails"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"coreDetails"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"docsLink"}},{"kind":"Field","name":{"kind":"Name","value":"pageSize"}},{"kind":"Field","name":{"kind":"Name","value":"websiteUrl"}},{"kind":"Field","name":{"kind":"Name","value":"smtpEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"oidcEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"signupAllowed"}},{"kind":"Field","name":{"kind":"Name","value":"repositoryLink"}},{"kind":"Field","name":{"kind":"Name","value":"disableTelemetry"}},{"kind":"Field","name":{"kind":"Name","value":"tokenValidForDays"}},{"kind":"Field","name":{"kind":"Name","value":"localAuthDisabled"}},{"kind":"Field","name":{"kind":"Name","value":"fileStorageEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"peopleSearchSources"}},{"kind":"Field","name":{"kind":"Name","value":"isServerKeyValidated"}},{"kind":"Field","name":{"kind":"Name","value":"metadataGroupSourceLotMappings"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"source"}}]}},{"kind":"Field","name":{"kind":"Name","value":"metadataLotSourceMappings"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"sources"}}]}},{"kind":"Field","name":{"kind":"Name","value":"metadataProviderLanguages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"default"}},{"kind":"Field","name":{"kind":"Name","value":"supported"}}]}},{"kind":"Field","name":{"kind":"Name","value":"frontend"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"oidcButtonLabel"}},{"kind":"Field","name":{"kind":"Name","value":"dashboardMessage"}},{"kind":"Field","name":{"kind":"Name","value":"umami"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"domains"}},{"kind":"Field","name":{"kind":"Name","value":"scriptUrl"}},{"kind":"Field","name":{"kind":"Name","value":"websiteId"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"exerciseParameters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"downloadRequired"}},{"kind":"Field","name":{"kind":"Name","value":"filters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"level"}},{"kind":"Field","name":{"kind":"Name","value":"force"}},{"kind":"Field","name":{"kind":"Name","value":"mechanic"}},{"kind":"Field","name":{"kind":"Name","value":"equipment"}},{"kind":"Field","name":{"kind":"Name","value":"muscle"}}]}},{"kind":"Field","name":{"kind":"Name","value":"lotMapping"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"bests"}}]}}]}}]}}]}}]} as unknown as DocumentNode<CoreDetailsQuery, CoreDetailsQueryVariables>;
+export const CollectionContentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CollectionContents"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CollectionContentsInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"collectionContents"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cacheId"}},{"kind":"Field","name":{"kind":"Name","value":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalItems"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"reviews"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ReviewItemPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"results"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"entityId"}},{"kind":"Field","name":{"kind":"Name","value":"entityLot"}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenAnimeExtraInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SeenAnimeExtraInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenMangaExtraInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SeenMangaExtraInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"volume"}},{"kind":"Field","name":{"kind":"Name","value":"chapter"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ReviewItemPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ReviewItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"postedOn"}},{"kind":"Field","name":{"kind":"Name","value":"isSpoiler"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"textOriginal"}},{"kind":"Field","name":{"kind":"Name","value":"textRendered"}},{"kind":"Field","name":{"kind":"Name","value":"seenItemsAssociatedWith"}},{"kind":"Field","name":{"kind":"Name","value":"postedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"likedBy"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"showExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"season"}},{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"Field","name":{"kind":"Name","value":"podcastExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"Field","name":{"kind":"Name","value":"animeExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenAnimeExtraInformationPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"mangaExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenMangaExtraInformationPart"}}]}}]}}]} as unknown as DocumentNode<CollectionContentsQuery, CollectionContentsQueryVariables>;
+export const CoreDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CoreDetails"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"coreDetails"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"docsLink"}},{"kind":"Field","name":{"kind":"Name","value":"pageSize"}},{"kind":"Field","name":{"kind":"Name","value":"websiteUrl"}},{"kind":"Field","name":{"kind":"Name","value":"smtpEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"oidcEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"signupAllowed"}},{"kind":"Field","name":{"kind":"Name","value":"repositoryLink"}},{"kind":"Field","name":{"kind":"Name","value":"disableTelemetry"}},{"kind":"Field","name":{"kind":"Name","value":"tokenValidForDays"}},{"kind":"Field","name":{"kind":"Name","value":"localAuthDisabled"}},{"kind":"Field","name":{"kind":"Name","value":"fileStorageEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"peopleSearchSources"}},{"kind":"Field","name":{"kind":"Name","value":"isServerKeyValidated"}},{"kind":"Field","name":{"kind":"Name","value":"metadataGroupSourceLotMappings"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"source"}}]}},{"kind":"Field","name":{"kind":"Name","value":"metadataLotSourceMappings"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"sources"}}]}},{"kind":"Field","name":{"kind":"Name","value":"metadataProviderLanguages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"default"}},{"kind":"Field","name":{"kind":"Name","value":"supported"}}]}},{"kind":"Field","name":{"kind":"Name","value":"frontend"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"oidcButtonLabel"}},{"kind":"Field","name":{"kind":"Name","value":"dashboardMessage"}},{"kind":"Field","name":{"kind":"Name","value":"umami"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"domains"}},{"kind":"Field","name":{"kind":"Name","value":"scriptUrl"}},{"kind":"Field","name":{"kind":"Name","value":"websiteId"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"exerciseParameters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lotMapping"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"bests"}}]}},{"kind":"Field","name":{"kind":"Name","value":"filters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"level"}},{"kind":"Field","name":{"kind":"Name","value":"force"}},{"kind":"Field","name":{"kind":"Name","value":"muscle"}},{"kind":"Field","name":{"kind":"Name","value":"mechanic"}},{"kind":"Field","name":{"kind":"Name","value":"equipment"}}]}}]}}]}}]}}]} as unknown as DocumentNode<CoreDetailsQuery, CoreDetailsQueryVariables>;
 export const MetadataGroupDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MetadataGroupDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"metadataGroupId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"metadataGroupDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"metadataGroupId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"metadataGroupId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"contents"}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"parts"}},{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"isPartial"}},{"kind":"Field","name":{"kind":"Name","value":"sourceUrl"}},{"kind":"Field","name":{"kind":"Name","value":"identifier"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"displayImages"}}]}}]}}]}}]} as unknown as DocumentNode<MetadataGroupDetailsQuery, MetadataGroupDetailsQueryVariables>;
 export const MetadataGroupSearchDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MetadataGroupSearch"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"MetadataGroupSearchInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"metadataGroupSearch"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"identifier"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"parts"}}]}}]}}]}}]} as unknown as DocumentNode<MetadataGroupSearchQuery, MetadataGroupSearchQueryVariables>;
-export const MetadataListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MetadataList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"MetadataListInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"metadataList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"}}]}}]}}]} as unknown as DocumentNode<MetadataListQuery, MetadataListQueryVariables>;
+export const UserMetadataListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserMetadataList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserMetadataListInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userMetadataList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cacheId"}},{"kind":"Field","name":{"kind":"Name","value":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}}]}}]}}]}}]} as unknown as DocumentNode<UserMetadataListQuery, UserMetadataListQueryVariables>;
 export const MetadataSearchDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MetadataSearch"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"MetadataSearchInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"metadataSearch"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"identifier"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"publishYear"}}]}}]}}]}}]} as unknown as DocumentNode<MetadataSearchQuery, MetadataSearchQueryVariables>;
 export const PeopleSearchDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"PeopleSearch"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"PeopleSearchInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"peopleSearch"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"identifier"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"birthYear"}}]}}]}}]}}]} as unknown as DocumentNode<PeopleSearchQuery, PeopleSearchQueryVariables>;
 export const UserMetadataGroupDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserMetadataGroupDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"metadataGroupId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userMetadataGroupDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"metadataGroupId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"metadataGroupId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"recentlyConsumed"}},{"kind":"Field","name":{"kind":"Name","value":"reviews"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ReviewItemPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"collections"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CollectionPart"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenAnimeExtraInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SeenAnimeExtraInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenMangaExtraInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SeenMangaExtraInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"volume"}},{"kind":"Field","name":{"kind":"Name","value":"chapter"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ReviewItemPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ReviewItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"postedOn"}},{"kind":"Field","name":{"kind":"Name","value":"isSpoiler"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"textOriginal"}},{"kind":"Field","name":{"kind":"Name","value":"textRendered"}},{"kind":"Field","name":{"kind":"Name","value":"seenItemsAssociatedWith"}},{"kind":"Field","name":{"kind":"Name","value":"postedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"likedBy"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"showExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"season"}},{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"Field","name":{"kind":"Name","value":"podcastExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"Field","name":{"kind":"Name","value":"animeExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenAnimeExtraInformationPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"mangaExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenMangaExtraInformationPart"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CollectionPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Collection"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}}]}}]} as unknown as DocumentNode<UserMetadataGroupDetailsQuery, UserMetadataGroupDetailsQueryVariables>;
 export const UserPersonDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserPersonDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"personId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userPersonDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"personId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"personId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"recentlyConsumed"}},{"kind":"Field","name":{"kind":"Name","value":"collections"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CollectionPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"reviews"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ReviewItemPart"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenAnimeExtraInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SeenAnimeExtraInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenMangaExtraInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SeenMangaExtraInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"volume"}},{"kind":"Field","name":{"kind":"Name","value":"chapter"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CollectionPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Collection"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ReviewItemPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ReviewItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"postedOn"}},{"kind":"Field","name":{"kind":"Name","value":"isSpoiler"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"textOriginal"}},{"kind":"Field","name":{"kind":"Name","value":"textRendered"}},{"kind":"Field","name":{"kind":"Name","value":"seenItemsAssociatedWith"}},{"kind":"Field","name":{"kind":"Name","value":"postedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"likedBy"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"showExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"season"}},{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"Field","name":{"kind":"Name","value":"podcastExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}},{"kind":"Field","name":{"kind":"Name","value":"animeExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenAnimeExtraInformationPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"mangaExtraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenMangaExtraInformationPart"}}]}}]}}]} as unknown as DocumentNode<UserPersonDetailsQuery, UserPersonDetailsQueryVariables>;
 export const UserWorkoutDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserWorkoutDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"workoutId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userWorkoutDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"workoutId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"workoutId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"collections"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CollectionPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"endTime"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"startTime"}},{"kind":"Field","name":{"kind":"Name","value":"templateId"}},{"kind":"Field","name":{"kind":"Name","value":"repeatedFrom"}},{"kind":"Field","name":{"kind":"Name","value":"caloriesBurnt"}},{"kind":"Field","name":{"kind":"Name","value":"summary"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutSummaryPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"information"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutInformationPart"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutOrExerciseTotalsPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutOrExerciseTotals"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"reps"}},{"kind":"Field","name":{"kind":"Name","value":"weight"}},{"kind":"Field","name":{"kind":"Name","value":"distance"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"restTime"}},{"kind":"Field","name":{"kind":"Name","value":"personalBestsAchieved"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutSetStatisticPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutSetStatistic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"reps"}},{"kind":"Field","name":{"kind":"Name","value":"pace"}},{"kind":"Field","name":{"kind":"Name","value":"oneRm"}},{"kind":"Field","name":{"kind":"Name","value":"weight"}},{"kind":"Field","name":{"kind":"Name","value":"volume"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"distance"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutSetRecordPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutSetRecord"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"personalBests"}},{"kind":"Field","name":{"kind":"Name","value":"statistic"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutSetStatisticPart"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"EntityAssetsPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"EntityAssets"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"images"}},{"kind":"Field","name":{"kind":"Name","value":"videos"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CollectionPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Collection"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutSummaryPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutSummary"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutOrExerciseTotalsPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"exercises"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"numSets"}},{"kind":"Field","name":{"kind":"Name","value":"bestSet"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutSetRecordPart"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"focused"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lots"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"exercises"}}]}},{"kind":"Field","name":{"kind":"Name","value":"levels"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"level"}},{"kind":"Field","name":{"kind":"Name","value":"exercises"}}]}},{"kind":"Field","name":{"kind":"Name","value":"forces"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"force"}},{"kind":"Field","name":{"kind":"Name","value":"exercises"}}]}},{"kind":"Field","name":{"kind":"Name","value":"muscles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"muscle"}},{"kind":"Field","name":{"kind":"Name","value":"exercises"}}]}},{"kind":"Field","name":{"kind":"Name","value":"equipments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"equipment"}},{"kind":"Field","name":{"kind":"Name","value":"exercises"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"comment"}},{"kind":"Field","name":{"kind":"Name","value":"assets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"EntityAssetsPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"supersets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"exercises"}}]}},{"kind":"Field","name":{"kind":"Name","value":"exercises"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"notes"}},{"kind":"Field","name":{"kind":"Name","value":"total"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutOrExerciseTotalsPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"EntityAssetsPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"sets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"rpe"}},{"kind":"Field","name":{"kind":"Name","value":"note"}},{"kind":"Field","name":{"kind":"Name","value":"restTime"}},{"kind":"Field","name":{"kind":"Name","value":"confirmedAt"}},{"kind":"Field","name":{"kind":"Name","value":"personalBests"}},{"kind":"Field","name":{"kind":"Name","value":"statistic"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutSetStatisticPart"}}]}}]}}]}}]}}]} as unknown as DocumentNode<UserWorkoutDetailsQuery, UserWorkoutDetailsQueryVariables>;
-export const UserWorkoutsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserWorkoutsList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"SearchInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userWorkoutsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"}}]}}]}}]} as unknown as DocumentNode<UserWorkoutsListQuery, UserWorkoutsListQueryVariables>;
+export const UserWorkoutsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserWorkoutsList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserTemplatesOrWorkoutsListInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userWorkoutsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cacheId"}},{"kind":"Field","name":{"kind":"Name","value":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}}]}}]}}]}}]} as unknown as DocumentNode<UserWorkoutsListQuery, UserWorkoutsListQueryVariables>;
 export const UserWorkoutTemplateDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserWorkoutTemplateDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"workoutTemplateId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userWorkoutTemplateDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"workoutTemplateId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"workoutTemplateId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"collections"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CollectionPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}},{"kind":"Field","name":{"kind":"Name","value":"summary"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutSummaryPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"information"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutInformationPart"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutOrExerciseTotalsPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutOrExerciseTotals"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"reps"}},{"kind":"Field","name":{"kind":"Name","value":"weight"}},{"kind":"Field","name":{"kind":"Name","value":"distance"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"restTime"}},{"kind":"Field","name":{"kind":"Name","value":"personalBestsAchieved"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutSetStatisticPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutSetStatistic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"reps"}},{"kind":"Field","name":{"kind":"Name","value":"pace"}},{"kind":"Field","name":{"kind":"Name","value":"oneRm"}},{"kind":"Field","name":{"kind":"Name","value":"weight"}},{"kind":"Field","name":{"kind":"Name","value":"volume"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"distance"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutSetRecordPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutSetRecord"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"personalBests"}},{"kind":"Field","name":{"kind":"Name","value":"statistic"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutSetStatisticPart"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"EntityAssetsPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"EntityAssets"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"images"}},{"kind":"Field","name":{"kind":"Name","value":"videos"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CollectionPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Collection"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutSummaryPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutSummary"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutOrExerciseTotalsPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"exercises"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"numSets"}},{"kind":"Field","name":{"kind":"Name","value":"bestSet"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutSetRecordPart"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"focused"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lots"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"exercises"}}]}},{"kind":"Field","name":{"kind":"Name","value":"levels"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"level"}},{"kind":"Field","name":{"kind":"Name","value":"exercises"}}]}},{"kind":"Field","name":{"kind":"Name","value":"forces"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"force"}},{"kind":"Field","name":{"kind":"Name","value":"exercises"}}]}},{"kind":"Field","name":{"kind":"Name","value":"muscles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"muscle"}},{"kind":"Field","name":{"kind":"Name","value":"exercises"}}]}},{"kind":"Field","name":{"kind":"Name","value":"equipments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"equipment"}},{"kind":"Field","name":{"kind":"Name","value":"exercises"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutInformationPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutInformation"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"comment"}},{"kind":"Field","name":{"kind":"Name","value":"assets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"EntityAssetsPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"supersets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"exercises"}}]}},{"kind":"Field","name":{"kind":"Name","value":"exercises"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"notes"}},{"kind":"Field","name":{"kind":"Name","value":"total"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutOrExerciseTotalsPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"EntityAssetsPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"sets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"rpe"}},{"kind":"Field","name":{"kind":"Name","value":"note"}},{"kind":"Field","name":{"kind":"Name","value":"restTime"}},{"kind":"Field","name":{"kind":"Name","value":"confirmedAt"}},{"kind":"Field","name":{"kind":"Name","value":"personalBests"}},{"kind":"Field","name":{"kind":"Name","value":"statistic"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutSetStatisticPart"}}]}}]}}]}}]}}]} as unknown as DocumentNode<UserWorkoutTemplateDetailsQuery, UserWorkoutTemplateDetailsQueryVariables>;
-export const UserWorkoutTemplatesListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserWorkoutTemplatesList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"SearchInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userWorkoutTemplatesList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"}}]}}]}}]} as unknown as DocumentNode<UserWorkoutTemplatesListQuery, UserWorkoutTemplatesListQueryVariables>;
+export const UserWorkoutTemplatesListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserWorkoutTemplatesList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserTemplatesOrWorkoutsListInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userWorkoutTemplatesList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cacheId"}},{"kind":"Field","name":{"kind":"Name","value":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}}]}}]}}]}}]} as unknown as DocumentNode<UserWorkoutTemplatesListQuery, UserWorkoutTemplatesListQueryVariables>;
 export const UserAnalyticsParametersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserAnalyticsParameters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userAnalyticsParameters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"endDate"}},{"kind":"Field","name":{"kind":"Name","value":"startDate"}}]}}]}}]} as unknown as DocumentNode<UserAnalyticsParametersQuery, UserAnalyticsParametersQueryVariables>;
 export const UserPendingNotificationsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserPendingNotifications"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userPendingNotifications"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}}]}}]}}]} as unknown as DocumentNode<UserPendingNotificationsQuery, UserPendingNotificationsQueryVariables>;
\ No newline at end of file
diff --git a/libs/generated/src/graphql/backend/types.generated.ts b/libs/generated/src/graphql/backend/types.generated.ts
index 0a0a121aac..b767645c08 100644
--- a/libs/generated/src/graphql/backend/types.generated.ts
+++ b/libs/generated/src/graphql/backend/types.generated.ts
@@ -18,6 +18,7 @@ export type Scalars = {
   JSONObject: { input: any; output: any; }
   NaiveDate: { input: string; output: string; }
   NaiveDateTime: { input: any; output: any; }
+  UUID: { input: string; output: string; }
 };
 
 export type AccessLink = {
@@ -112,6 +113,30 @@ export type BookSpecificsInput = {
   pages?: InputMaybe<Scalars['Int']['input']>;
 };
 
+export type CachedCollectionContentsResponse = {
+  __typename?: 'CachedCollectionContentsResponse';
+  cacheId: Scalars['UUID']['output'];
+  response: CollectionContents;
+};
+
+export type CachedCollectionsListResponse = {
+  __typename?: 'CachedCollectionsListResponse';
+  cacheId: Scalars['UUID']['output'];
+  response: Array<CollectionItem>;
+};
+
+export type CachedSearchIdResponse = {
+  __typename?: 'CachedSearchIdResponse';
+  cacheId: Scalars['UUID']['output'];
+  response: IdResults;
+};
+
+export type CachedUserMetadataRecommendationsResponse = {
+  __typename?: 'CachedUserMetadataRecommendationsResponse';
+  cacheId: Scalars['UUID']['output'];
+  response: Array<Scalars['String']['output']>;
+};
+
 export type ChangeCollectionToEntityInput = {
   collectionName: Scalars['String']['input'];
   creatorUserId: Scalars['String']['input'];
@@ -136,6 +161,7 @@ export type CollectionContents = {
   details: Collection;
   results: MediaCollectionContentsResults;
   reviews: Array<ReviewItem>;
+  totalItems: Scalars['Int']['output'];
   user: User;
 };
 
@@ -154,6 +180,7 @@ export type CollectionContentsInput = {
 export enum CollectionContentsSortBy {
   Date = 'DATE',
   LastUpdatedOn = 'LAST_UPDATED_ON',
+  Random = 'RANDOM',
   Title = 'TITLE'
 }
 
@@ -616,7 +643,6 @@ export enum ExerciseMuscle {
 
 export type ExerciseParameters = {
   __typename?: 'ExerciseParameters';
-  downloadRequired: Scalars['Boolean']['output'];
   /** All filters applicable to an exercises query. */
   filters: ExerciseFilters;
   /** Exercise type mapped to the personal bests possible. */
@@ -632,6 +658,7 @@ export type ExerciseParametersLotMapping = {
 export enum ExerciseSortBy {
   LastPerformed = 'LAST_PERFORMED',
   Name = 'NAME',
+  Random = 'RANDOM',
   TimesPerformed = 'TIMES_PERFORMED'
 }
 
@@ -640,12 +667,6 @@ export enum ExerciseSource {
   Github = 'GITHUB'
 }
 
-export type ExercisesListInput = {
-  filter?: InputMaybe<ExerciseListFilter>;
-  search: SearchInput;
-  sortBy?: InputMaybe<ExerciseSortBy>;
-};
-
 export type ExportJob = {
   __typename?: 'ExportJob';
   endedAt: Scalars['DateTime']['output'];
@@ -1029,6 +1050,7 @@ export enum MediaSortBy {
   LastSeen = 'LAST_SEEN',
   LastUpdated = 'LAST_UPDATED',
   ProviderRating = 'PROVIDER_RATING',
+  Random = 'RANDOM',
   ReleaseDate = 'RELEASE_DATE',
   TimesConsumed = 'TIMES_CONSUMED',
   Title = 'TITLE',
@@ -1118,21 +1140,6 @@ export type MetadataGroupSourceLotMapping = {
   source: MediaSource;
 };
 
-export type MetadataGroupsListInput = {
-  filter?: InputMaybe<MediaFilter>;
-  invertCollection?: InputMaybe<Scalars['Boolean']['input']>;
-  search?: InputMaybe<SearchInput>;
-  sort?: InputMaybe<PersonSortInput>;
-};
-
-export type MetadataListInput = {
-  filter?: InputMaybe<MediaFilter>;
-  invertCollection?: InputMaybe<Scalars['Boolean']['input']>;
-  lot?: InputMaybe<MediaLot>;
-  search?: InputMaybe<SearchInput>;
-  sort?: InputMaybe<MediaSortInput>;
-};
-
 export type MetadataLotSourceMappings = {
   __typename?: 'MetadataLotSourceMappings';
   lot: MediaLot;
@@ -1275,6 +1282,8 @@ export type MutationRoot = {
    * collections for the user.
    */
   disassociateMetadata: Scalars['Boolean']['output'];
+  /** Expire a cache key by its ID */
+  expireCacheKey: Scalars['Boolean']['output'];
   /** Generate an auth token without any expiry. */
   generateAuthToken: Scalars['String']['output'];
   /** Login a user using their username and password and return an auth token. */
@@ -1486,6 +1495,11 @@ export type MutationRootDisassociateMetadataArgs = {
 };
 
 
+export type MutationRootExpireCacheKeyArgs = {
+  cacheId: Scalars['UUID']['input'];
+};
+
+
 export type MutationRootLoginUserArgs = {
   input: AuthUserInput;
 };
@@ -1619,13 +1633,6 @@ export type PasswordUserInput = {
   username: Scalars['String']['input'];
 };
 
-export type PeopleListInput = {
-  filter?: InputMaybe<MediaFilter>;
-  invertCollection?: InputMaybe<Scalars['Boolean']['input']>;
-  search?: InputMaybe<SearchInput>;
-  sort?: InputMaybe<PersonSortInput>;
-};
-
 export type PeopleSearchInput = {
   search: SearchInput;
   source: MediaSource;
@@ -1668,7 +1675,8 @@ export type Person = {
 
 export enum PersonAndMetadataGroupsSortBy {
   MediaItems = 'MEDIA_ITEMS',
-  Name = 'NAME'
+  Name = 'NAME',
+  Random = 'RANDOM'
 }
 
 export type PersonDetailsGroupedByRole = {
@@ -1802,13 +1810,11 @@ export type ProviderLanguageInformation = {
 export type QueryRoot = {
   __typename?: 'QueryRoot';
   /** Get the contents of a collection and respect visibility. */
-  collectionContents: CollectionContents;
+  collectionContents: CachedCollectionContentsResponse;
   /** Get some primary information about the service. */
   coreDetails: CoreDetails;
   /** Get details about an exercise. */
   exerciseDetails: Exercise;
-  /** Get a paginated list of exercises in the database. */
-  exercisesList: IdResults;
   /** Get details about a genre present in the database. */
   genreDetails: GenreDetails;
   /** Get paginated list of genres. */
@@ -1827,16 +1833,10 @@ export type QueryRoot = {
   metadataGroupDetails: MetadataGroupDetails;
   /** Search for a list of groups from a given source. */
   metadataGroupSearch: MetadataGroupSearchResults;
-  /** Get paginated list of metadata groups. */
-  metadataGroupsList: IdResults;
-  /** Get all the media items related to a user for a specific media type. */
-  metadataList: IdResults;
   /** Get partial details about a media present in the database. */
   metadataPartialDetails: MetadataPartialDetails;
   /** Search for a list of media for a given type. */
   metadataSearch: MetadataSearchResults;
-  /** Get paginated list of people. */
-  peopleList: IdResults;
   /** Search for a list of people from a given source. */
   peopleSearch: PeopleSearchResults;
   /** Get details about a creator present in the database. */
@@ -1852,11 +1852,13 @@ export type QueryRoot = {
   /** Get calendar events for a user between a given date range. */
   userCalendarEvents: Array<GroupedCalendarEvent>;
   /** Get all collections for the currently logged in user. */
-  userCollectionsList: Array<CollectionItem>;
+  userCollectionsList: CachedCollectionsListResponse;
   /** Get details about the currently logged in user. */
   userDetails: UserDetailsResult;
   /** Get information about an exercise for a user. */
   userExerciseDetails: UserExerciseDetails;
+  /** Get a paginated list of exercises in the database. */
+  userExercisesList: CachedSearchIdResponse;
   /** Get all the export jobs for the current user. */
   userExports: Array<ExportJob>;
   /** Get all the integrations for the currently logged in user. */
@@ -1867,12 +1869,18 @@ export type QueryRoot = {
   userMetadataDetails: UserMetadataDetails;
   /** Get details that can be displayed to a user for a metadata group. */
   userMetadataGroupDetails: UserMetadataGroupDetails;
+  /** Get paginated list of metadata groups. */
+  userMetadataGroupsList: CachedSearchIdResponse;
+  /** Get all the media items related to a user for a specific media type. */
+  userMetadataList: CachedSearchIdResponse;
   /** Get metadata recommendations for the currently logged in user. */
-  userMetadataRecommendations: Array<Scalars['String']['output']>;
+  userMetadataRecommendations: CachedUserMetadataRecommendationsResponse;
   /** Get all the notification platforms for the currently logged in user. */
   userNotificationPlatforms: Array<NotificationPlatform>;
   /** Get all pending display notifications for the currently logged in user. */
   userPendingNotifications: Array<UserNotification>;
+  /** Get paginated list of people. */
+  userPeopleList: CachedSearchIdResponse;
   /** Get details that can be displayed to a user for a creator. */
   userPersonDetails: UserPersonDetails;
   /** Get upcoming calendar events for the given filter. */
@@ -1882,9 +1890,9 @@ export type QueryRoot = {
   /** Get information about a workout template. */
   userWorkoutTemplateDetails: UserWorkoutTemplateDetails;
   /** Get a paginated list of templates created by the user. */
-  userWorkoutTemplatesList: IdResults;
+  userWorkoutTemplatesList: CachedSearchIdResponse;
   /** Get a paginated list of workouts done by the user. */
-  userWorkoutsList: IdResults;
+  userWorkoutsList: CachedSearchIdResponse;
   /** Get details about all the users in the service. */
   usersList: Array<User>;
 };
@@ -1900,11 +1908,6 @@ export type QueryRootExerciseDetailsArgs = {
 };
 
 
-export type QueryRootExercisesListArgs = {
-  input: ExercisesListInput;
-};
-
-
 export type QueryRootGenreDetailsArgs = {
   input: GenreDetailsInput;
 };
@@ -1940,16 +1943,6 @@ export type QueryRootMetadataGroupSearchArgs = {
 };
 
 
-export type QueryRootMetadataGroupsListArgs = {
-  input: MetadataGroupsListInput;
-};
-
-
-export type QueryRootMetadataListArgs = {
-  input: MetadataListInput;
-};
-
-
 export type QueryRootMetadataPartialDetailsArgs = {
   metadataId: Scalars['String']['input'];
 };
@@ -1960,11 +1953,6 @@ export type QueryRootMetadataSearchArgs = {
 };
 
 
-export type QueryRootPeopleListArgs = {
-  input: PeopleListInput;
-};
-
-
 export type QueryRootPeopleSearchArgs = {
   input: PeopleSearchInput;
 };
@@ -2000,6 +1988,11 @@ export type QueryRootUserExerciseDetailsArgs = {
 };
 
 
+export type QueryRootUserExercisesListArgs = {
+  input: UserExercisesListInput;
+};
+
+
 export type QueryRootUserMeasurementsListArgs = {
   input: UserMeasurementsListInput;
 };
@@ -2015,8 +2008,18 @@ export type QueryRootUserMetadataGroupDetailsArgs = {
 };
 
 
-export type QueryRootUserMetadataRecommendationsArgs = {
-  shouldRefresh?: InputMaybe<Scalars['Boolean']['input']>;
+export type QueryRootUserMetadataGroupsListArgs = {
+  input: UserMetadataGroupsListInput;
+};
+
+
+export type QueryRootUserMetadataListArgs = {
+  input: UserMetadataListInput;
+};
+
+
+export type QueryRootUserPeopleListArgs = {
+  input: UserPeopleListInput;
 };
 
 
@@ -2041,12 +2044,12 @@ export type QueryRootUserWorkoutTemplateDetailsArgs = {
 
 
 export type QueryRootUserWorkoutTemplatesListArgs = {
-  input: SearchInput;
+  input: UserTemplatesOrWorkoutsListInput;
 };
 
 
 export type QueryRootUserWorkoutsListArgs = {
-  input: SearchInput;
+  input: UserTemplatesOrWorkoutsListInput;
 };
 
 
@@ -2405,6 +2408,12 @@ export type UserExerciseInput = {
   sets: Array<UserWorkoutSetRecord>;
 };
 
+export type UserExercisesListInput = {
+  filter?: InputMaybe<ExerciseListFilter>;
+  search: SearchInput;
+  sortBy?: InputMaybe<ExerciseSortBy>;
+};
+
 export type UserFeaturesEnabledPreferences = {
   __typename?: 'UserFeaturesEnabledPreferences';
   analytics: UserAnalyticsFeaturesEnabledPreferences;
@@ -2776,6 +2785,21 @@ export type UserMetadataGroupDetails = {
   reviews: Array<ReviewItem>;
 };
 
+export type UserMetadataGroupsListInput = {
+  filter?: InputMaybe<MediaFilter>;
+  invertCollection?: InputMaybe<Scalars['Boolean']['input']>;
+  search?: InputMaybe<SearchInput>;
+  sort?: InputMaybe<PersonSortInput>;
+};
+
+export type UserMetadataListInput = {
+  filter?: InputMaybe<MediaFilter>;
+  invertCollection?: InputMaybe<Scalars['Boolean']['input']>;
+  lot?: InputMaybe<MediaLot>;
+  search?: InputMaybe<SearchInput>;
+  sort?: InputMaybe<MediaSortInput>;
+};
+
 export type UserNotification = {
   __typename?: 'UserNotification';
   createdOn: Scalars['DateTime']['output'];
@@ -2821,6 +2845,13 @@ export type UserOthersFeaturesEnabledPreferencesInput = {
   collections: Scalars['Boolean']['input'];
 };
 
+export type UserPeopleListInput = {
+  filter?: InputMaybe<MediaFilter>;
+  invertCollection?: InputMaybe<Scalars['Boolean']['input']>;
+  search?: InputMaybe<SearchInput>;
+  sort?: InputMaybe<PersonSortInput>;
+};
+
 export type UserPersonDetails = {
   __typename?: 'UserPersonDetails';
   collections: Array<Collection>;
@@ -2849,6 +2880,16 @@ export enum UserReviewScale {
   ThreePointSmiley = 'THREE_POINT_SMILEY'
 }
 
+export type UserTemplatesOrWorkoutsListInput = {
+  search: SearchInput;
+  sort?: InputMaybe<UserWorkoutsListSortInput>;
+};
+
+export enum UserTemplatesOrWorkoutsListSortBy {
+  Random = 'RANDOM',
+  Time = 'TIME'
+}
+
 export type UserToEntity = {
   __typename?: 'UserToEntity';
   collectionId?: Maybe<Scalars['String']['output']>;
@@ -2957,6 +2998,11 @@ export type UserWorkoutTemplateDetails = {
   details: WorkoutTemplate;
 };
 
+export type UserWorkoutsListSortInput = {
+  by?: UserTemplatesOrWorkoutsListSortBy;
+  order?: GraphqlSortOrder;
+};
+
 export type VideoGameSpecifics = {
   __typename?: 'VideoGameSpecifics';
   platforms: Array<Scalars['String']['output']>;
diff --git a/libs/graphql/src/backend/mutations/combined.gql b/libs/graphql/src/backend/mutations/combined.gql
index 34364c700d..89381bb625 100644
--- a/libs/graphql/src/backend/mutations/combined.gql
+++ b/libs/graphql/src/backend/mutations/combined.gql
@@ -270,3 +270,7 @@ mutation MarkEntityAsPartial($input: MarkEntityAsPartialInput!) {
 mutation MarkNotificationsAsAddressed($notificationIds: [String!]!) {
   markNotificationsAsAddressed(notificationIds: $notificationIds)
 }
+
+mutation ExpireCacheKey($cacheId: UUID!) {
+  expireCacheKey(cacheId: $cacheId)
+}
diff --git a/libs/graphql/src/backend/queries/combined.gql b/libs/graphql/src/backend/queries/combined.gql
index a9105b78eb..16ed54b826 100644
--- a/libs/graphql/src/backend/queries/combined.gql
+++ b/libs/graphql/src/backend/queries/combined.gql
@@ -29,25 +29,28 @@ query UserExports {
 
 query UserCollectionsList($name: String) {
   userCollectionsList(name: $name) {
-    id
-    name
-    count
-    isDefault
-    description
-    creator {
-      id
-      name
-    }
-    collaborators {
+    cacheId
+    response {
       id
       name
-    }
-    informationTemplate {
-      lot
-      name
-      required
+      count
+      isDefault
       description
-      defaultValue
+      creator {
+        id
+        name
+      }
+      collaborators {
+        id
+        name
+      }
+      informationTemplate {
+        lot
+        name
+        required
+        description
+        defaultValue
+      }
     }
   }
 }
@@ -86,8 +89,11 @@ query UsersList($query: String) {
   }
 }
 
-query UserMetadataRecommendations($shouldRefresh: Boolean) {
-  userMetadataRecommendations(shouldRefresh: $shouldRefresh)
+query UserMetadataRecommendations {
+  userMetadataRecommendations {
+    cacheId
+    response
+  }
 }
 
 query UserUpcomingCalendarEvents($input: UserUpcomingCalendarEventInput!) {
@@ -115,23 +121,29 @@ query MetadataPartialDetails($metadataId: String!) {
   }
 }
 
-query MetadataGroupsList($input: MetadataGroupsListInput!) {
-  metadataGroupsList(input: $input) {
-    details {
-      total
-      nextPage
+query UserMetadataGroupsList($input: UserMetadataGroupsListInput!) {
+  userMetadataGroupsList(input: $input) {
+    cacheId
+    response {
+      items
+      details {
+        total
+        nextPage
+      }
     }
-    items
   }
 }
 
-query PeopleList($input: PeopleListInput!) {
-  peopleList(input: $input) {
-    details {
-      total
-      nextPage
+query UserPeopleList($input: UserPeopleListInput!) {
+  userPeopleList(input: $input) {
+    cacheId
+    response {
+      items
+      details {
+        total
+        nextPage
+      }
     }
-    items
   }
 }
 
@@ -169,12 +181,15 @@ query ExerciseDetails($exerciseId: String!) {
   }
 }
 
-query ExercisesList($input: ExercisesListInput!) {
-  exercisesList(input: $input) {
-    items
-    details {
-      total
-      nextPage
+query UserExercisesList($input: UserExercisesListInput!) {
+  userExercisesList(input: $input) {
+    cacheId
+    response {
+      items
+      details {
+        total
+        nextPage
+      }
     }
   }
 }
@@ -231,28 +246,32 @@ query GenreDetails($input: GenreDetailsInput!) {
 
 query CollectionContents($input: CollectionContentsInput!) {
   collectionContents(input: $input) {
-    user {
-      id
-      name
-    }
-    reviews {
-      ...ReviewItemPart
-    }
-    results {
+    cacheId
+    response {
+      totalItems
+      user {
+        id
+        name
+      }
+      reviews {
+        ...ReviewItemPart
+      }
       details {
-        total
-        nextPage
+        name
+        createdOn
+        description
       }
-      items {
-        entityId
-        entityLot
+      results {
+        details {
+          total
+          nextPage
+        }
+        items {
+          entityId
+          entityLot
+        }
       }
     }
-    details {
-      name
-      description
-      createdOn
-    }
   }
 }
 
@@ -296,18 +315,17 @@ query CoreDetails {
       }
     }
     exerciseParameters {
-      downloadRequired
+      lotMapping {
+        lot
+        bests
+      }
       filters {
         type
         level
         force
+        muscle
         mechanic
         equipment
-        muscle
-      }
-      lotMapping {
-        lot
-        bests
       }
     }
   }
@@ -346,13 +364,16 @@ query MetadataGroupSearch($input: MetadataGroupSearchInput!) {
   }
 }
 
-query MetadataList($input: MetadataListInput!) {
-  metadataList(input: $input) {
-    details {
-      total
-      nextPage
+query UserMetadataList($input: UserMetadataListInput!) {
+  userMetadataList(input: $input) {
+    cacheId
+    response {
+      items
+      details {
+        total
+        nextPage
+      }
     }
-    items
   }
 }
 
@@ -434,13 +455,16 @@ query UserWorkoutDetails($workoutId: String!) {
   }
 }
 
-query UserWorkoutsList($input: SearchInput!) {
+query UserWorkoutsList($input: UserTemplatesOrWorkoutsListInput!) {
   userWorkoutsList(input: $input) {
-    details {
-      total
-      nextPage
+    cacheId
+    response {
+      items
+      details {
+        total
+        nextPage
+      }
     }
-    items
   }
 }
 
@@ -463,13 +487,16 @@ query UserWorkoutTemplateDetails($workoutTemplateId: String!) {
   }
 }
 
-query UserWorkoutTemplatesList($input: SearchInput!) {
+query UserWorkoutTemplatesList($input: UserTemplatesOrWorkoutsListInput!) {
   userWorkoutTemplatesList(input: $input) {
-    details {
-      total
-      nextPage
+    cacheId
+    response {
+      items
+      details {
+        total
+        nextPage
+      }
     }
-    items
   }
 }
 


Test patch: