Repository: datacite/akita
Pull request #470: Migrate repository query to rest api
Author: login: bklaing2
Created: 2025-03-05T20:34:16Z | Merged: 2025-03-05T22:14:50Z

## Purpose
Migrate the repository and search repository queries from graphQL to the REST API

closes: https://github.com/datacite/product-backlog/issues/180, https://github.com/datacite/product-backlog/issues/223

## Approach
<!--- _How does this change address the problem?_ -->

#### Open Questions and Pre-Merge TODOs
<!--- - [ ] Use github checklists. When solved, check the box and explain the answer. -->

## Learning
<!--- _Describe the research stage_ -->

<!--- _Links to blog posts, patterns, libraries or addons used to solve this problem_ -->


## Types of changes

- [ ] Bug fix (non-breaking change which fixes an issue)

- [ ] New feature (non-breaking change which adds functionality)

- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Reviewer, please remember our [guidelines](https://datacite.atlassian.net/wiki/spaces/TEC/pages/1168375809/Pull+Request+Guidelines):

- Be humble in the language and feedback you give, ask don't tell.
- Consider using positive language as opposed to neutral when offering feedback. This is to avoid the negative bias that can occur with neutral language appearing negative.
- Offer suggestions on how to improve code e.g. simplification or expanding clarity.
- Ensure you give reasons for the changes you are proposing.


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
	- Dynamic display of repository-related content and works metrics.
	- Enhanced search functionality using a dual REST and GraphQL approach.
	- Introduction of a new function for mapping JSON data to a repository format.
	- Added conditional checks for improved handling of repository-related content.

- **Bug Fixes**
	- Improved error handling during data fetching operations.

- **Refactor**
	- Optimized data fetching to use specific repository identifiers for improved performance.
	- Standardized metadata presentation for DOIs and subject tags to ensure consistency.

- **Style**
	- Applied minor formatting updates for cleaner, more consistent presentation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/src/app/repositories/[...repoid]/Content.tsx b/src/app/repositories/[...repoid]/Content.tsx
index 0147fc94..438c5cde 100644
--- a/src/app/repositories/[...repoid]/Content.tsx
+++ b/src/app/repositories/[...repoid]/Content.tsx
@@ -17,7 +17,7 @@ interface Props {
 export default async function Content(props: Props) {
   const { variables } = props
 
-  const { data, error } = await fetchRepository(variables)
+  const { data, error } = await fetchRepository(variables.id)
 
   if (error) return (
     <Col md={{ span: 9, offset: 3 }}>
diff --git a/src/app/repositories/[...repoid]/page.tsx b/src/app/repositories/[...repoid]/page.tsx
index 07ed24a7..367699e6 100644
--- a/src/app/repositories/[...repoid]/page.tsx
+++ b/src/app/repositories/[...repoid]/page.tsx
@@ -3,7 +3,7 @@ import { Metadata } from 'next'
 import { notFound } from 'next/navigation'
 import Content from './Content'
 import Loading from 'src/components/Loading/Loading'
-import { fetchRepositoryMetadata } from 'src/data/queries/repositoryQuery'
+import { fetchRepository } from 'src/data/queries/repositoryQuery'
 import { COMMONS_URL, LOGO_URL } from 'src/data/constants'
 
 
@@ -16,9 +16,9 @@ interface Props {
 
 
 export async function generateMetadata({ params }: Props): Promise<Metadata> {
-  const repoid = params.repoid.join('/')
+  const repoid = decodeURIComponent(params.repoid.join('/'))
 
-  const { data } = await fetchRepositoryMetadata(repoid)
+  const { data } = await fetchRepository(repoid)
 
   if (!data) return {
     title: '',
@@ -40,7 +40,7 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
     openGraph: {
       title,
       // type: 'repository',
-      url: `${COMMONS_URL}/repositories/${repo.re3dataDoi || repo.id}`,
+      url: `${COMMONS_URL}/repositories/${repo.re3doi || repo.id}`,
       images: [{ url: LOGO_URL }]
     }
   }
@@ -52,7 +52,7 @@ export default async function Page({ params }: Props) {
   const repoid = decodeURIComponent(params.repoid.join('/'))
 
   // Fetch Repository metadata
-  const { data } = await fetchRepositoryMetadata(repoid)
+  const { data } = await fetchRepository(repoid)
 
   if (!data) notFound()
 
diff --git a/src/components/RepositoryDetail/RepositoryDetail.tsx b/src/components/RepositoryDetail/RepositoryDetail.tsx
index d99a061e..cffe5fac 100644
--- a/src/components/RepositoryDetail/RepositoryDetail.tsx
+++ b/src/components/RepositoryDetail/RepositoryDetail.tsx
@@ -1,3 +1,5 @@
+'use client'
+
 import React from 'react'
 import Button from 'react-bootstrap/Button'
 import Badge from 'react-bootstrap/Badge'
@@ -9,12 +11,15 @@ import styles from './RepositoryDetail.module.scss'
 import { MetricsDisplay } from 'src/components/MetricsDisplay/MetricsDisplay';
 import { Repository } from 'src/data/types';
 import { RepositoryDashboard } from 'src/components/RepositoryDetail/RepositoryDashboard'
+import { useRepositoryRelatedContent } from 'src/data/queries/repositoryRelatedContentQuery'
 
 type Props = {
   repo: Repository
 }
 
 export function RepositorySidebar({ repo }: Props) {
+  const { data } = useRepositoryRelatedContent(repo.clientId)
+
   const gotoButtons = () => {
     return (
       <>
@@ -25,7 +30,7 @@ export function RepositorySidebar({ repo }: Props) {
             Go to Repository
           </Button>
         )}
-        {repo.works && (repo.works.totalCount > 0) && (
+        {data && (data.works.totalCount > 0) && (
           <Button variant="primary" href={"/doi.org?query=client.uid:" + repo.clientId} id="find-related">
             <FontAwesomeIcon icon={faNewspaper} />
             &nbsp;
@@ -77,15 +82,16 @@ export function RepositorySidebar({ repo }: Props) {
 
 export function RepositoryDetail({ repo }: Props) {
 
-
+  const { data } = useRepositoryRelatedContent(repo.clientId)
+  const works = data?.works
 
   const tags = () => {
-    if (repo.re3dataDoi == null) return "";
+    if (repo.re3doi == null) return "";
     const keywordList = repo.keyword.map((kw) => (
       kw.toLowerCase()
     ))
     const subjectList = repo.subject.map((subject) => (
-      subject.name.toLowerCase()
+      subject.text.toLowerCase()
     ))
     return (
       <>
@@ -114,7 +120,7 @@ export function RepositoryDetail({ repo }: Props) {
   }
 
   const extended_metadata = () => {
-    if (repo.re3dataDoi == null) return "";
+    if (repo.re3doi == null) return "";
     const metadata = [
       {
         label: "Data Access",
@@ -161,7 +167,7 @@ export function RepositoryDetail({ repo }: Props) {
     <>
       <div className={styles.header}>
         <h3>{repo.name}</h3>
-        <MetricsDisplay counts={{ works: repo.works.totalCount, citations: repo.citationCount, views: repo.viewCount, downloads: repo.downloadCount }} />
+        <MetricsDisplay counts={{ works: works?.totalCount, citations: works?.citationCount, views: works?.viewCount, downloads: works?.downloadCount }} />
       </div>
       <div className={styles.metadata}>
         <div className={styles.mdmain}>{repo.description}</div>
diff --git a/src/components/RepositoryMetadata/RepositoryMetadata.tsx b/src/components/RepositoryMetadata/RepositoryMetadata.tsx
index c163a8f9..025be3fc 100644
--- a/src/components/RepositoryMetadata/RepositoryMetadata.tsx
+++ b/src/components/RepositoryMetadata/RepositoryMetadata.tsx
@@ -18,7 +18,7 @@ function RepositoryMetadata({ repo }: Props) {
   }
 
   const re3DataURL = () => {
-    return `https://doi.org/${repo.re3dataDoi}`
+    return `https://doi.org/${repo.re3doi}`
   }
 
   const description = () => {
@@ -37,7 +37,7 @@ function RepositoryMetadata({ repo }: Props) {
       kw.toLowerCase()
     ))
     const subjectList = repo.subject.map((subject) => (
-      subject.name.toLowerCase()
+      subject.text.toLowerCase()
     ))
     return (
       <div className="tags">
@@ -53,9 +53,9 @@ function RepositoryMetadata({ repo }: Props) {
   const links = () => {
     return (
       <>
-        {(repo.url || repo.re3dataDoi) && (
+        {(repo.url || repo.re3doi) && (
           <>
-            {repo.re3dataDoi && (
+            {repo.re3doi && (
               <div>
                 <a className="re3data-link" href={re3DataURL()}>
                   More info about {repo.name} Repository</a>
diff --git a/src/data/queries/repositoryQuery.ts b/src/data/queries/repositoryQuery.ts
index 38d77669..89d48ea5 100644
--- a/src/data/queries/repositoryQuery.ts
+++ b/src/data/queries/repositoryQuery.ts
@@ -1,9 +1,37 @@
 import { gql } from '@apollo/client'
 import { Repository, RepositoryMetadata } from 'src/data/types'
 import apolloClient from 'src/utils/apolloClient/apolloClient'
+import { DATACITE_API_URL } from 'src/data/constants'
+import { mapJsonToRepository } from 'src/utils/helpers'
 
+function convertToQueryData(repository: any): QueryData {
+  return {
+    repository: mapJsonToRepository(repository)
+  }
+}
+
+export async function fetchRepository(id: string) {
+  try {
+    const options = {
+      method: 'GET',
+      headers: { accept: 'application/vnd.api+json' }
+    }
+
+    const res = await fetch(`${DATACITE_API_URL}/reference-repositories/${id}`, options)
+
+    if (!res.ok)
+      throw new Error(`API returned ${res.status}`)
+
+    const json = await res.json()
+
+    const data = convertToQueryData(json.data)
+    return { data }
+  } catch (error) {
+    return { error }
+  }
+}
 
-export async function fetchRepositoryMetadata(id: string) {
+export async function fetchRepositoryMetadataGQL(id: string) {
   const { data, error } = await apolloClient.query<MetadataQueryData, QueryVar>({
     query: REPOSITORY_METADATA_QUERY,
     variables: { id },
@@ -13,7 +41,7 @@ export async function fetchRepositoryMetadata(id: string) {
   return { data, error }
 }
 
-export async function fetchRepository(variables: QueryVar) {
+export async function fetchRepositoryGQL(variables: QueryVar) {
   const { data, error } = await apolloClient.query<QueryData, QueryVar>({
     query: REPOSITORY_QUERY,
     variables,
diff --git a/src/data/queries/repositoryRelatedContentQuery.ts b/src/data/queries/repositoryRelatedContentQuery.ts
index 123a4f96..4edcaf05 100644
--- a/src/data/queries/repositoryRelatedContentQuery.ts
+++ b/src/data/queries/repositoryRelatedContentQuery.ts
@@ -1,6 +1,7 @@
 import { useSearchDoiFacetsQuery } from './searchDoiFacetsQuery'
 
 export function useRepositoryRelatedContent(id: string) {
+  if (!id) return { data: undefined, loading: false, error: null }
   const vars = { clientId: id }
   return useSearchDoiFacetsQuery(vars)
 }
diff --git a/src/data/queries/searchDoiQuery.ts b/src/data/queries/searchDoiQuery.ts
index d1dfb2bc..bc2ac1c2 100644
--- a/src/data/queries/searchDoiQuery.ts
+++ b/src/data/queries/searchDoiQuery.ts
@@ -2,7 +2,7 @@ import { gql, useQuery as useGQLQuery } from '@apollo/client'
 import { useQuery } from '@tanstack/react-query'
 import { PageInfo, Works } from 'src/data/types'
 import { workFragment, workConnection } from 'src/data/queries/queryFragments'
-import { mapJsonToWork, cursorToPage} from 'src/utils/helpers'
+import { mapJsonToWork, cursorToPage } from 'src/utils/helpers'
 import { DATACITE_API_URL } from 'src/data/constants'
 
 
@@ -193,11 +193,11 @@ export interface QueryVar {
 }
 
 
-function getPageInfo(links: { self: string, next?: string }): PageInfo {
+export function getPageInfo(links: { self: string, next?: string }): PageInfo {
   if (!links.next) return { endCursor: '', hasNextPage: false };
 
   const url = new URL(links.next);
-  const pageString  = url.searchParams.get("page[number]")
+  const pageString = url.searchParams.get("page[number]")
   if (!pageString) return { endCursor: '', hasNextPage: false };
   const page = cursorToPage(pageString)
 
diff --git a/src/data/queries/searchRepositoryQuery.ts b/src/data/queries/searchRepositoryQuery.ts
index 16bd98a8..08ac6310 100644
--- a/src/data/queries/searchRepositoryQuery.ts
+++ b/src/data/queries/searchRepositoryQuery.ts
@@ -1,8 +1,77 @@
-import { gql, useQuery } from '@apollo/client'
+import { gql, useQuery as useQueryGQL } from '@apollo/client'
+import { useQuery } from '@tanstack/react-query'
 import { Repositories } from 'src/data/types'
+import { DATACITE_API_URL } from 'src/data/constants'
+import { getPageInfo } from './searchDoiQuery'
+import { mapJsonToRepository } from 'src/utils/helpers'
 
+function buildRepositorySearchParams(variables: QueryVar): URLSearchParams {
+  const searchParams = new URLSearchParams({
+    query: variables.query,
+  })
+
+  function optionalAppend(param: string, value: string | undefined) {
+    if (!value) return
+    searchParams.append(param, value)
+  }
+
+  // optionalAppend('year', variables.year)
+  optionalAppend('certificate', variables.certificate)
+  optionalAppend('software', variables.software)
+  optionalAppend('has_pid', variables.hasPid)
+  optionalAppend('is_open', variables.isOpen)
+  optionalAppend('is_certified', variables.isCertified)
+  optionalAppend('subject_id', variables.subjectId)
+
+  searchParams.append('page[number]', variables.cursor || '1')
+  return searchParams
+}
+
+function convertToQueryData(json: any): QueryData {
+  const nodes = json.data as any[]
+  const { meta, links } = json
+
+  return {
+    repositories: {
+      totalCount: meta.total,
+      pageInfo: getPageInfo(links),
+      nodes: nodes.map(r => mapJsonToRepository(r)),
+      certificates: meta.certificates,
+      software: meta.software
+    }
+  }
+}
+
+
+export async function fetchRepositories(variables: QueryVar) {
+  const options = {
+    method: 'GET',
+    headers: { accept: 'application/vnd.api+json' }
+  }
+  const searchParams = buildRepositorySearchParams(variables)
+
+  const res = await fetch(
+    `${DATACITE_API_URL}/reference-repositories?${searchParams.toString()}`,
+    options
+  )
+  const json = await res.json()
+
+  if (!res.ok) {
+    const errorMessage = json?.errors?.title || `Request for repositories failed with status: ${res.status}`;
+    throw new Error(errorMessage);
+  }
+
+  const data = convertToQueryData(json)
+  return { data }
+}
 export function useSearchRepositoryQuery(variables: QueryVar) {
-  const { loading, data, error } = useQuery<QueryData, QueryVar>(
+  const { isPending, data, error } = useQuery({ queryKey: ['repositorySearch', variables], queryFn: async () => fetchRepositories(variables) })
+
+  return { loading: isPending, data: data?.data, error }
+}
+
+export function useSearchRepositoryQueryGQL(variables: QueryVar) {
+  const { loading, data, error } = useQueryGQL<QueryData, QueryVar>(
     SEARCH_REPOSITORIES_GQL,
     {
       variables,
@@ -84,5 +153,4 @@ export interface QueryVar {
   isOpen?: string
   isCertified?: string
   subjectId?: string
-
 }
diff --git a/src/data/types.ts b/src/data/types.ts
index 172614a4..c1a9e2c7 100644
--- a/src/data/types.ts
+++ b/src/data/types.ts
@@ -261,7 +261,7 @@ interface PersonWorks extends Works {
 export type RepositoryMetadata = {
   id: string
   name: string
-  re3dataDoi: string
+  re3doi: string
 }
 
 export type Repository = RepositoryMetadata & {
@@ -273,7 +273,7 @@ export type Repository = RepositoryMetadata & {
   repositoryType: string[]
   url: string
   keyword: string[]
-  subject: DefinedTerm[]
+  subject: { text: string }[]
 
   citationCount: number
   downloadCount: number
@@ -313,10 +313,6 @@ interface TextRestriction {
   type: string
 }
 
-type DefinedTerm = {
-  name: string
-}
-
 // Shared types
 type Identifier = {
   identifier: string
diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts
index c4c804cd..a4a20b82 100644
--- a/src/utils/helpers.ts
+++ b/src/utils/helpers.ts
@@ -180,6 +180,15 @@ export function mapJsonToWork(json: any, included: any[]) {
   }
 }
 
+export function mapJsonToRepository(json: any) {
+  const attrs = json.attributes
+
+  return {
+    id: json.id,
+    ...attrs,
+  }
+}
+
 export function getDateFromParts(year?: number, month = 1, day = 1): string | null {
   if (!year) return null;
   return new Date(year, month - 1, day).toISOString();
@@ -221,7 +230,7 @@ const REGISTRATION_AGENCIES = {
   op: 'OP'
 }
 
-export function cursorToPage(cursor :string) {
+export function cursorToPage(cursor: string) {
   if (!cursor) return 1
   const potentialPage = cursor ? parseInt(cursor, 10) : 1
   return potentialPage <= 1 ? 1 : potentialPage


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 5**

<details>
<summary>🔭 Outside diff range comments (2)</summary><blockquote>

<details>
<summary>src/data/queries/repositoryQuery.ts (2)</summary><blockquote>

`55-65`: _⚠️ Potential issue_

**Update GraphQL query to match type changes.**

The GraphQL query still uses `re3dataDoi` but the type in `src/data/types.ts` has been updated to `re3doi`. This inconsistency could cause issues.

```diff
 export const REPOSITORY_METADATA_QUERY = gql`
   query repositoryDetailQuery(
     $id: ID!
   ) {
     repository(id: $id){
       id:uid
       name
-      re3dataDoi
+      re3doi
     }
   }
 `
```

---

`108-108`: _⚠️ Potential issue_

**Update GraphQL query to match type changes.**

The GraphQL query still uses `re3dataDoi` but the type in `src/data/types.ts` has been updated to `re3doi`. This inconsistency could cause issues.

```diff
   fragment repoFields on Repository{
     id:uid
-    re3dataDoi
+    re3doi
     clientId
     name
     language
```

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (9)</summary><blockquote>

<details>
<summary>src/utils/helpers.ts (1)</summary><blockquote>

`183-190`: **Well-implemented repository JSON mapping function.**

The new `mapJsonToRepository` function extracts the repository ID and attributes from the JSON response, following the same pattern as the existing `mapJsonToWork` function.


This function is a crucial part of the migration from GraphQL to REST API, enabling the application to process the repository data returned by the REST endpoint. It keeps the implementation clean and focused.

I'd recommend adding a JSDoc comment to describe the function's purpose and parameters, similar to other mapping functions in this file:

```typescript
/**
 * Maps a JSON response from the repository API to a Repository object.
 * @param json The JSON data returned from the API
 * @returns A repository object with ID and attributes
 */
export function mapJsonToRepository(json: any) {
  // existing implementation
}
```

</blockquote></details>
<details>
<summary>src/components/RepositoryDetail/RepositoryDetail.tsx (1)</summary><blockquote>

`21-22`: **Add error handling for the hook data.**

While the hook implementation is good, there's no error handling if the hook fails to fetch data. Consider adding error state handling.

```diff
-  const { data } = useRepositoryRelatedContent(repo.clientId)
+  const { data, error } = useRepositoryRelatedContent(repo.clientId)
+  
+  // Handle error state if needed
+  if (error) {
+    console.error('Failed to fetch repository related content:', error)
+  }
```

</blockquote></details>
<details>
<summary>src/data/queries/repositoryQuery.ts (2)</summary><blockquote>

`8-12`: **Add error handling for malformed repository data.**

The `convertToQueryData` function doesn't handle potential issues with malformed repository data, which could lead to runtime errors.

```diff
 function convertToQueryData(repository: any): QueryData {
+  if (!repository || typeof repository !== 'object') {
+    throw new Error('Invalid repository data format')
+  }
   return {
     repository: mapJsonToRepository(repository)
   }
 }
```

---

`14-33`: **Add timeout handling to fetch request.**

The fetch request doesn't have a timeout set, which could lead to hanging requests if the API is slow to respond.

```diff
 export async function fetchRepository(id: string) {
   try {
     const options = {
       method: 'GET',
       headers: { accept: 'application/vnd.api+json' }
-    }
+    },
+    controller = new AbortController(),
+    timeoutId = setTimeout(() => controller.abort(), 10000);  // 10 second timeout
+    
+    options.signal = controller.signal;

     const res = await fetch(`${DATACITE_API_URL}/reference-repositories/${id}`, options)
+    clearTimeout(timeoutId);

     if (!res.ok)
       throw new Error(`API returned ${res.status}`)

     const json = await res.json()

     const data = convertToQueryData(json.data)
     return { data }
   } catch (error) {
+    if (error.name === 'AbortError') {
+      return { error: new Error('Request timeout') }
+    }
     return { error }
   }
 }
```

</blockquote></details>
<details>
<summary>src/data/queries/searchRepositoryQuery.ts (5)</summary><blockquote>

`8-28`: **Review the commented out year parameter.**

The parameter building function is well-structured with the optional parameter handling, but there's a commented-out line for the 'year' parameter. Either implement this parameter if needed or remove the commented code for cleanliness.


```diff
- // optionalAppend('year', variables.year)
```

---

`46-66`: **Enhance error handling with more robust approach.**

The error handling in `fetchRepositories` only checks for `json?.errors?.title`, which may not handle all error formats from the API. Some REST APIs return an array of errors or use different error structures.


```diff
- const errorMessage = json?.errors?.title || `Request for repositories failed with status: ${res.status}`;
+ const errorMessage = 
+   json?.errors?.title || 
+   (Array.isArray(json?.errors) && json.errors.length > 0 ? json.errors[0].title || json.errors[0].message : null) ||
+   `Request for repositories failed with status: ${res.status}`;
```

---

`67-71`: **Consider simplifying data access pattern in the return value.**

The function returns `data?.data` which introduces an additional nesting level compared to the GraphQL version. This could cause confusion for consuming components that expect the original structure.


```diff
- return { loading: isPending, data: data?.data, error }
+ // Extract data once in the fetch function to maintain consistent API
+ return { loading: isPending, data: data, error }
```

Then update line 65 in fetchRepositories:

```diff
- return { data }
+ return data
```

---

`73-83`: **Add documentation about the dual implementation.**

The presence of both REST and GraphQL implementations suggests this is part of a migration strategy. Consider adding a comment to explain the purpose of maintaining both implementations and if there's a plan to remove the GraphQL version in the future.


```diff
+// This GraphQL implementation is maintained for backward compatibility during migration
+// to REST API. It will be removed once all components have been updated to use the REST version.
export function useSearchRepositoryQueryGQL(variables: QueryVar) {
```

---

`68-68`: **Consider adding caching configuration for React Query.**

The React Query implementation doesn't specify any caching strategy. Consider adding appropriate cacheTime and staleTime settings based on how frequently the repository data changes.


```diff
- const { isPending, data, error } = useQuery({ queryKey: ['repositorySearch', variables], queryFn: async () => fetchRepositories(variables) })
+ const { isPending, data, error } = useQuery({ 
+   queryKey: ['repositorySearch', variables], 
+   queryFn: async () => fetchRepositories(variables),
+   staleTime: 5 * 60 * 1000, // Consider how fresh the data needs to be (e.g., 5 minutes)
+   cacheTime: 30 * 60 * 1000 // How long to keep unused data in cache (e.g., 30 minutes)
+ })
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 47c6a5ee0680b74627b4dcd8ab9c5c13eee15541 and 16d7d663d9aa6425417a13bd9443e54797880abb.

</details>

<details>
<summary>📒 Files selected for processing (9)</summary>

* `src/app/repositories/[...repoid]/Content.tsx` (1 hunks)
* `src/app/repositories/[...repoid]/page.tsx` (4 hunks)
* `src/components/RepositoryDetail/RepositoryDetail.tsx` (6 hunks)
* `src/components/RepositoryMetadata/RepositoryMetadata.tsx` (3 hunks)
* `src/data/queries/repositoryQuery.ts` (2 hunks)
* `src/data/queries/searchDoiQuery.ts` (2 hunks)
* `src/data/queries/searchRepositoryQuery.ts` (1 hunks)
* `src/data/types.ts` (2 hunks)
* `src/utils/helpers.ts` (2 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🪛 ESLint</summary>

<details>
<summary>src/app/repositories/[...repoid]/page.tsx</summary>

[error] 6-6: 'fetchRepositoryMetadataGQL' is defined but never used.

(no-unused-vars)

</details>
<details>
<summary>src/data/queries/repositoryQuery.ts</summary>

[error] 4-4: 'fetchConditionalCache' is defined but never used.

(no-unused-vars)

</details>

</details>
<details>
<summary>🪛 GitHub Actions: Test Pull Request</summary>

<details>
<summary>src/app/repositories/[...repoid]/page.tsx</summary>

[error] 6-6: 'fetchRepositoryMetadataGQL' is defined but never used.  no-unused-vars

</details>
<details>
<summary>src/data/queries/repositoryQuery.ts</summary>

[error] 4-4: 'fetchConditionalCache' is defined but never used.  no-unused-vars

</details>

</details>

</details>

<details>
<summary>🔇 Additional comments (22)</summary><blockquote>

<details>
<summary>src/data/queries/searchDoiQuery.ts (3)</summary>

`5-5`: **Well-structured import organization.**

The import statement is now properly aligned with the rest of the import statements, making the code more consistent.

---

`196-205`: **Good decision to make the `getPageInfo` function exportable.**

Making this utility function exportable allows for reuse across different query implementations, which aligns with the PR's goal of migrating repository queries to the REST API. This function is now likely being used in the new REST-based repository query implementation.


The implementation is solid:
1. It handles cases where there's no next page
2. It extracts pagination parameters properly from the URL
3. It returns a properly structured `PageInfo` object

---

`200-200`: **Minor spacing improvement.**

The spacing around the assignment of the `pageString` variable has been standardized, improving readability.

</details>
<details>
<summary>src/components/RepositoryMetadata/RepositoryMetadata.tsx (3)</summary>

`21-21`: **Property name update from `re3dataDoi` to `re3doi`.**

The property name has been changed from `re3dataDoi` to `re3doi`. This is consistent with the overall migration mentioned in the PR objectives.


Make sure this change is reflected in your data type definitions and that all other code accessing this property has been updated accordingly.

---

`40-40`: **Property name update from `subject.name` to `subject.text`.**

The change from accessing `subject.name` to `subject.text` reflects an update in the data structure returned by the new REST API.


This change correctly aligns with the data structure of the subjects array as retrieved from the REST API.

---

`56-59`: **Consistent property naming in conditional checks.**

The conditional checks have been updated to use `repo.re3doi` instead of `repo.re3dataDoi`, maintaining consistency with the property name change.


This ensures that the links section renders correctly when repository data is available from the REST API.

</details>
<details>
<summary>src/app/repositories/[...repoid]/Content.tsx (1)</summary>

`20-20`: **Updated function call to match new API.**

The call to `fetchRepository` has been updated to pass only the `id` property instead of the entire `variables` object, which aligns with the new REST API implementation.


This change simplifies the function signature of `fetchRepository` and makes it more focused on its specific responsibility - fetching a repository by its ID. This is a good practice that follows the Single Responsibility Principle.

</details>
<details>
<summary>src/utils/helpers.ts (1)</summary>

`233-233`: **Fixed type annotation formatting.**

The spacing in the type annotation of the `cursorToPage` function has been standardized, improving code consistency.

</details>
<details>
<summary>src/app/repositories/[...repoid]/page.tsx (3)</summary>

`19-21`: **Good use of URL decoding.**

The implementation correctly decodes the repository ID using `decodeURIComponent` before using it to fetch data. This is important for handling special characters in repository IDs.

---

`43-43`: <details>
<summary>❓ Verification inconclusive</summary>

**Ensure property name change is consistent across codebase.**

The property name change from `repo.re3dataDoi` to `repo.re3doi` reflects the type changes in `src/data/types.ts`. This is good for maintaining consistency.


---

🏁 Script executed:

```shell
#!/bin/bash
# Check for any instances of re3dataDoi that might have been missed during the migration
echo "Checking for remaining instances of re3dataDoi in the codebase:"
rg "re3dataDoi" --type ts --type tsx

echo "Checking for instances of new re3doi property:"
rg "re3doi" --type ts --type tsx
```

Length of output: 365

---



</details>

**Verify Consistency of Property Name Update**

The change from `repo.re3dataDoi` to `repo.re3doi` in `src/app/repositories/[...repoid]/page.tsx` appears to match the updates in `src/data/types.ts`. However, the initial regex search using `--type tsx` encountered an error. To ensure no lingering instances of `re3dataDoi` remain and that `re3doi` is used consistently across both TypeScript and TSX files, please re-run the search with updated file filters:

```shell
#!/bin/bash
echo "Checking for remaining instances of 're3dataDoi' in .ts and .tsx files:"
rg "re3dataDoi" -g "*.ts" -g "*.tsx"

echo "Checking for occurrences of the updated 're3doi' property in .ts and .tsx files:"
rg "re3doi" -g "*.ts" -g "*.tsx"
```

Once you confirm that no instances of `re3dataDoi` exist and that `re3doi` is consistently applied, this change can be approved.

---

`54-55`: <details>
<summary>❓ Verification inconclusive</summary>

**Verify impact of API migration.**

The switch from GraphQL to REST API looks good. Make sure all necessary data is returned by the new endpoint to maintain feature parity.


---

🏁 Script executed:

```shell
#!/bin/bash
# Compare the data structure returned by the new fetchRepository function
# with what was previously returned by the GraphQL query

echo "Looking at repository data structure usage patterns:"
rg "repo\.(re3doi|id|name|works|clientId)" --type tsx -A 1 -B 1 src/components/
```

Length of output: 224

---

**API Migration – Manual Verification Required**

The REST API migration appears solid, but we need to ensure that the new endpoint returns all the metadata expected by the client components. The previous verification command failed due to the unrecognized file type "tsx". Please re-run the above script (or verify manually) to confirm that all necessary repository fields (such as `re3doi`, `id`, `name`, `works`, `clientId`) are being used consistently across TSX files.



---

🏁 Script executed:

```shell

#!/bin/bash
# Re-run search to inspect repository data structure usage in TSX files using globbing
echo "Searching for repository usage in TSX files:"
rg "repo\.(re3doi|id|name|works|clientId)" -g "*.tsx" -A 1 -B 1 src/components/
```

Length of output: 6919

---



</details>

**API Migration Verification: Manual Check Required**

The REST API migration appears to integrate well with our components. Our inspection of TSX files (e.g., in `RepositoryMetadata.tsx`, `RepositoryDetail.tsx`, and `SearchRepository.tsx`) confirms that key repository properties such as `id`, `re3doi`, `name`, `url`, `clientId`, and `works` are actively used. However, please ensure that the new `fetchRepository` endpoint indeed returns all these fields (and any additional ones relied upon) to maintain full feature parity with the previous GraphQL endpoint. A manual re-check of the API response is recommended to confirm the complete data structure match.

</details>
<details>
<summary>src/components/RepositoryDetail/RepositoryDetail.tsx (5)</summary>

`1-2`: **Good addition of 'use client' directive.**

Adding the 'use client' directive at the top of the file is necessary for components that need client-side interactivity, especially when using React hooks.

---

`14-14`: **Clean import of new hook.**

The import of the `useRepositoryRelatedContent` hook is well organized and follows the project's import pattern.

---

`33-33`: **Good conditional rendering update.**

The condition for rendering the "Find Related Works" button has been updated to check the data from the hook instead of directly accessing `repo.works`. This is a good approach since it reflects the new data flow.

---

`89-89`: **Property name change is consistent.**

The change from `repo.re3dataDoi` to `repo.re3doi` matches the type changes in `src/data/types.ts`. This consistency is good.

---

`123-123`: **Property name change is consistent.**

The change from `repo.re3dataDoi` to `repo.re3doi` matches the type changes in `src/data/types.ts`. This consistency is good.

</details>
<details>
<summary>src/data/types.ts (1)</summary>

`264-264`: **Good property name update.**

Renaming `re3dataDoi` to `re3doi` is a good naming improvement that's been consistently applied across files.

</details>
<details>
<summary>src/data/queries/repositoryQuery.ts (2)</summary>

`45-53`: <details>
<summary>❓ Verification inconclusive</summary>

**Good function renaming.**

Renaming the function to `fetchRepositoryGQL` clearly indicates that it uses GraphQL, which is helpful to distinguish it from the new REST-based function.


---

🏁 Script executed:

```shell
#!/bin/bash
# Verify that all calls to the old function name have been updated
echo "Checking for any remaining calls to old fetchRepository function:"
rg "fetchRepositoryGQL\(" --type ts --type tsx

echo "Checking for calls to the new function name:"
rg "fetchRepository\(" --type ts --type tsx
```

Length of output: 390

---



</details>

**Action Required: Verify Function Renaming**

The renaming to `fetchRepositoryGQL` clearly distinguishes its GraphQL usage, which is excellent. However, our initial verification encountered an error with ripgrep's file type recognition for `tsx` files. Please re-run the verification using the revised shell script below to ensure that all references have been updated correctly:

```shell
#!/bin/bash
echo "Checking for any remaining calls to old fetchRepositoryGQL function:"
rg "fetchRepositoryGQL(" -g "*.ts" -g "*.tsx"

echo "Checking for calls to the new function name:"
rg "fetchRepository(" -g "*.ts" -g "*.tsx"
```

After manually verifying that the output is as expected (i.e., there are no unintended references), we can finalize our review.

---

`35-43`: <details>
<summary>❓ Verification inconclusive</summary>

**Good function renaming.**

Renaming the function to `fetchRepositoryMetadataGQL` clearly indicates that it uses GraphQL, which is helpful to distinguish it from the new REST-based function.


---

🏁 Script executed:

```shell
#!/bin/bash
# Verify that all calls to the old function name have been updated
echo "Checking for any remaining calls to fetchRepositoryMetadata:"
rg "fetchRepositoryMetadata\(" --type ts --type tsx

echo "Checking for calls to the new function name:"
rg "fetchRepositoryMetadataGQL\(" --type ts --type tsx
```

Length of output: 396

---



</details>

**Renaming Verified – Please Manually Confirm Function Calls**

The update renaming the function to `fetchRepositoryMetadataGQL` clearly indicates its use of GraphQL, which improves clarity compared to the prior REST-based naming. However, the previous verification script returned an error when filtering for TSX files. Please run the updated verification script below to ensure that no calls to the old function name remain and that only the new name is in use:

```shell
#!/bin/bash
echo "Checking for any remaining calls to fetchRepositoryMetadata:"
rg "fetchRepositoryMetadata\(" -g "*.ts" -g "*.tsx"
echo "Checking for calls to the new function name:"
rg "fetchRepositoryMetadataGQL\(" -g "*.ts" -g "*.tsx"
```

Once you manually verify that the old function name no longer appears anywhere and that all invocations use `fetchRepositoryMetadataGQL`, this change can be fully approved.

</details>
<details>
<summary>src/data/queries/searchRepositoryQuery.ts (3)</summary>

`1-6`: **Import changes look good.**

Good approach using named imports to differentiate Apollo's useQuery from tanstack's useQuery. The additional imports for API URL and helper functions are appropriate for the REST implementation.

---

`30-43`: **Conversion function looks good.**

The `convertToQueryData` function properly transforms the REST API response to match the expected format. Using helper functions like `getPageInfo` and `mapJsonToRepository` maintains consistency in data structure.

---

`52-56`: <details>
<summary>✅ Verification successful</summary>

**Verify API endpoint and parameters format.**

Confirm that the reference-repositories endpoint and the query parameter format (`page[number]`) match the REST API specification. This pagination approach differs from the cursor-based pagination used in GraphQL.

---

🌐 Web query:

```web
What is the pagination format for DataCite REST API?
```

💡 Result:

The DataCite REST API supports **cursor-based pagination** alongside traditional **page-based pagination**, offering flexibility for different use cases. Here's a breakdown of the pagination formats:

### Cursor-Based Pagination
- **Usage**: Designed for large datasets or real-time updates to avoid duplicates/skips.  
- **Parameters**:
  - `cursor`: Start with `cursor=1`, then use the `next` link in the response for subsequent pages[1][4].
  - `limit`: Controls the number of results per page (default: 25, max: 1,000)[1][4].
- **Response Metadata**: Includes `links.next` containing the cursor for the next page[1][4].  
- **Example**:  
  ```bash
  GET /dois?cursor=1&limit=50
  ```

### Page-Based Pagination
- **Usage**: Simpler for static datasets, using page numbers.  
- **Parameters**:
  - `page`: Page number (default: 1)[4].
  - `page[size]`: Results per page (default: 25, max: 1,000)[4].
- **Example**:  
  ```bash
  GET /dois?page[number]=2&page[size]=100
  ```

### Key Features
1. **Hybrid Support**: Some endpoints allow combining parameters like `page[size]` with `cursor`[4].  
2. **Sorting**: Results can be ordered by fields like `created`, `updated`, or `relevance`[4].  
3. **Metadata**: Responses include totals (e.g., `total-pages`, `total-results`) for page-based requests[4][9].  

### Recommendations
- Use **cursor-based** for dynamic datasets (e.g., frequently updated DOIs)[1][6].  
- Use **page-based** for predictable navigation (e.g., filtered queries)[4][6].  

For implementation details, refer to DataCite’s [API documentation](https://support.datacite.org/docs/api-queries#pagination)[4][9].

Citations:

- 1: https://cran.r-project.org/web/packages/rdatacite/rdatacite.pdf
- 2: https://pidforum.org/t/pagination-with-cursor-in-graphql-api/1572
- 3: https://docs.rivery.io/docs/pagination-options-in-rest-api
- 4: https://github.com/datacite/lupo/blob/master/openapi.yaml
- 5: https://support.datacite.org/docs/datacite-graphql-api-guide
- 6: https://www.merge.dev/blog/rest-api-pagination
- 7: https://pidforum.org/t/datacite-rest-api-python-client-library/1707/3
- 8: https://nordicapis.com/4-examples-of-restful-api-pagination-in-production/
- 9: https://www.youtube.com/watch?v=mh_r6ohJOac
- 10: https://cran.r-project.org/web/packages/rcrossref/rcrossref.pdf

---



</details>

**Action Required: Confirm Correct Page-Based Pagination Setup for DataCite API**

The DataCite REST API supports both cursor- and page-based pagination. For endpoints using page-based pagination (e.g., `/dois` and similar), the documentation specifies parameters such as `page[number]` and `page[size]` (see [API documentation](https://support.datacite.org/docs/api-queries#pagination)). In this case, please verify that:

- The `/reference-repositories` endpoint is intended to use page-based pagination.
- The `searchParams` variable correctly includes the required page-based parameters (e.g., `page[number]` and, if applicable, `page[size]`).

No changes are needed if the implementation is meant to follow page-based pagination. If a cursor-based approach is desired instead, the parameters will need to be adjusted accordingly.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T20:46:12Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 2**

<details>
<summary>🧹 Nitpick comments (2)</summary><blockquote>

<details>
<summary>src/data/queries/repositoryQuery.ts (2)</summary><blockquote>

`7-11`: **Specify a more precise type for `repository` parameter.**

The `convertToQueryData` function currently uses `any` type which loses type safety. Consider defining an interface for the REST API response structure.

```diff
-function convertToQueryData(repository: any): QueryData {
+interface RepositoryApiResponse {
+  id: string;
+  type: string;
+  attributes: Record<string, any>;
+  // Add other expected fields from the API response
+}
+
+function convertToQueryData(repository: RepositoryApiResponse): QueryData {
```

---

`20-20`: **Enhance error handling with URL in error message.**

Include the URL in the error message to make debugging easier when API calls fail.

```diff
-    const res = await fetch(`${DATACITE_API_URL}/reference-repositories/${id}`, options)
+    const url = `${DATACITE_API_URL}/reference-repositories/${id}`
+    const res = await fetch(url, options)
+
+    if (!res.ok)
+      throw new Error(`API returned ${res.status} for ${url}`)
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 16d7d663d9aa6425417a13bd9443e54797880abb and 902b5aebd8115f386381ba6e3f3eee732b2c5576.

</details>

<details>
<summary>📒 Files selected for processing (2)</summary>

* `src/app/repositories/[...repoid]/page.tsx` (4 hunks)
* `src/data/queries/repositoryQuery.ts` (2 hunks)

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (1)</summary>

* src/app/repositories/[...repoid]/page.tsx

</details>

<details>
<summary>🔇 Additional comments (3)</summary><blockquote>

<details>
<summary>src/data/queries/repositoryQuery.ts (3)</summary>

`4-5`: **LGTM: New imports added correctly.**

The imports for `DATACITE_API_URL` and `mapJsonToRepository` align with the PR objective of migrating repository queries to REST API.

---

`27-28`: <details>
<summary>❓ Verification inconclusive</summary>

**Verify response structure handling.**

The REST API response is expected to have a `data` property that contains the repository information. Verify this structure is consistent across all API endpoints.

---

🏁 Script executed:

```shell
#!/bin/bash
# Look for similar API response handling patterns
echo "Checking for similar API response handling patterns..."
rg "const json = await res\.json\(\)" -A 2 --type ts

# Check for other usages of DATACITE_API_URL to understand API structure
echo "Checking other usages of DATACITE_API_URL..."
rg "DATACITE_API_URL.*reference-repositories" --type ts
```

Length of output: 1955

---



</details>

**API Response Structure Verification Needed**

The repository query currently extracts the repository information via `json.data` before conversion. However, note that similar API calls (e.g., in `searchPersonQuery.ts`) pass the whole JSON to the conversion function. Please verify that the API contract is consistent—that is, the repository endpoint actually returns a JSON object with a `data` property, and other endpoints either follow a similar pattern or are explicitly designed to handle their differing structures.

- Confirm that the API response for `/reference-repositories/{id}` always includes a `data` property.
- If inconsistencies are intentional, ensure this is clearly documented in both the API contract and the conversion logic at `convertToQueryData`.
- Reconcile any differences among endpoints (e.g., between the repository and person queries) to avoid unexpected behavior.

---

`54-126`: <details>
<summary>❓ Verification inconclusive</summary>

**Verify GraphQL schema consistency with REST API.**

The GraphQL queries remain unchanged, but the migration to REST API might introduce field inconsistencies. Ensure the REST API returns data that can be properly mapped to match the GraphQL schema, particularly fields like `re3dataDoi`.

---

🏁 Script executed:

```shell
#!/bin/bash
# Check where mapJsonToRepository is defined to understand the mapping
echo "Looking for mapJsonToRepository definition..."
rg "export.*mapJsonToRepository" --type ts

# Check if there's any reference to re3dataDoi vs re3doi in the codebase
echo "Checking for re3dataDoi vs re3doi usage..."
rg "re3dataDoi|re3doi" --type ts --type tsx
```

Length of output: 384

---

Below is a new shell script to re-run the search for both TS and TSX files. It uses glob patterns instead of file-type filters to avoid the previous error:



Once this script is executed, please review the output to ensure that the field name used in the REST API response is consistently mapped (via the `mapJsonToRepository` function defined in `src/utils/helpers.ts`) to the GraphQL schema—especially for the `re3dataDoi` field. If discrepancies such as an alternative field name (`re3doi`) are found, adjust either the mapping function or the GraphQL fragment accordingly.

---

**Action: Verify consistent mapping of REST API fields to GraphQL schema**

- Confirm that `mapJsonToRepository` (defined in `src/utils/helpers.ts`) properly translates the REST API response to include the `re3dataDoi` field.
- Re-run the above script to check for any inconsistent usage of `re3dataDoi` versus `re3doi` in both TypeScript and TSX files.
- Based on the findings, ensure the REST API returns data that conforms to the GraphQL schema expectations.



---

🏁 Script executed:

```shell

#!/bin/bash
echo "Re-verifying usage of re3dataDoi and re3doi across TS and TSX files..."
rg -i "re3dataDoi|re3doi" -g "*.ts" -g "*.tsx"
```

Length of output: 1098

---



</details>

**Action: Verify DOI Field Mapping Consistency**

The GraphQL queries are still returning the field `re3dataDoi`, yet several client files (e.g., in RepositoryMetadata.tsx, RepositoryDetail.tsx, and TypeScript types in `src/data/types.ts`) expect the property `re3doi`. Please verify that the mapping function (`mapJsonToRepository` in `src/utils/helpers.ts`) correctly translates the REST API response so that the GraphQL field (`re3dataDoi`) is mapped to the application’s `re3doi`. If discrepancies are found, adjust the mapping or update the query to align field names consistently across the codebase.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T20:50:07Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 0**

<details>
<summary>🧹 Nitpick comments (1)</summary><blockquote>

<details>
<summary>src/data/queries/repositoryRelatedContentQuery.ts (1)</summary><blockquote>

`3-3`: **Consider updating the TypeScript parameter type to match implementation.**

The function now handles cases where `id` might be falsy, but the type declaration specifies it as `string` without indicating it could be nullable/undefined.


```diff
-export function useRepositoryRelatedContent(id: string) {
+export function useRepositoryRelatedContent(id: string | undefined | null) {
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 902b5aebd8115f386381ba6e3f3eee732b2c5576 and c46988adc291d794b299c89201ee16740531ca85.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `src/data/queries/repositoryRelatedContentQuery.ts` (1 hunks)

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (2)</summary>

* GitHub Check: CodeQL-Build
* GitHub Check: CodeQL-Build

</details>

<details>
<summary>🔇 Additional comments (2)</summary><blockquote>

<details>
<summary>src/data/queries/repositoryRelatedContentQuery.ts (2)</summary>

`4-4`: **Good defensive programming practice added.**

Adding this null check prevents potential errors when the hook is used in components where the repository ID might not be immediately available (like during loading states).

---

`3-7`: <details>
<summary>❓ Verification inconclusive</summary>

**Verify this relates to the GraphQL to REST API migration.**

This change adds a defensive check but doesn't appear to directly modify the API access mechanism. Is the actual migration from GraphQL to REST happening in the `useSearchDoiFacetsQuery` function that this hook calls?

---

🏁 Script executed:

```shell
#!/bin/bash
# Check if searchDoiFacetsQuery has been modified as part of this PR
git diff --name-only origin/main -- src/data/queries/searchDoiFacetsQuery.ts

# Look at what changed in that file if it exists
if git diff --name-only origin/main -- src/data/queries/searchDoiFacetsQuery.ts | grep -q .; then
  echo "Found changes in searchDoiFacetsQuery.ts:"
  git diff origin/main -- src/data/queries/searchDoiFacetsQuery.ts
fi

# Check for other repository-related query functions 
echo "Other repository-related query files changed in this PR:"
git diff --name-only origin/main | grep -i "repository.*query"
```

Length of output: 617

---



</details>

**Action Required: Verify API Migration in useSearchDoiFacetsQuery**

The update in `repositoryRelatedContentQuery.ts` adds a necessary defensive check for an empty `id`. However, it's still unclear whether the migration from GraphQL to REST is implemented in the `useSearchDoiFacetsQuery` function. The diff command for `searchDoiFacetsQuery.ts` failed due to an invalid base revision reference (`origin/main`), so please manually verify whether `useSearchDoiFacetsQuery` now utilizes REST endpoints as intended. Additionally, if you meant to compare against a different branch or commit, adjust the diff reference accordingly.

- Verify that `useSearchDoiFacetsQuery` has been refactored to perform REST calls.
- Confirm that the migration from GraphQL to REST is reflected in its implementation.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T21:27:42Z
user: login: jrhoads
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T21:50:33Z

Review comments:
diff_hunk: @@ -3,7 +3,7 @@ import { Metadata } from 'next'
 import { notFound } from 'next/navigation'
 import Content from './Content'
 import Loading from 'src/components/Loading/Loading'
-import { fetchRepositoryMetadata } from 'src/data/queries/repositoryQuery'
+import { fetchRepository, fetchRepositoryMetadataGQL } from 'src/data/queries/repositoryQuery'
path: src/app/repositories/[...repoid]/page.tsx
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Remove unused import.**

The `fetchRepositoryMetadataGQL` function is imported but never used in this file, causing lint errors in the pipeline.

```diff
-import { fetchRepository, fetchRepositoryMetadataGQL } from 'src/data/queries/repositoryQuery'
+import { fetchRepository } from 'src/data/queries/repositoryQuery'
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
import { fetchRepository } from 'src/data/queries/repositoryQuery'
`````

</details>

<!-- suggestion_end -->

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 ESLint</summary>

[error] 6-6: 'fetchRepositoryMetadataGQL' is defined but never used.

(no-unused-vars)

</details>
<details>
<summary>🪛 GitHub Actions: Test Pull Request</summary>

[error] 6-6: 'fetchRepositoryMetadataGQL' is defined but never used.  no-unused-vars

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-05T20:46:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -77,15 +82,16 @@ export function RepositorySidebar({ repo }: Props) {
 
 export function RepositoryDetail({ repo }: Props) {
 
-
+  const { data } = useRepositoryRelatedContent(repo.clientId)
+  const works = data?.works
path: src/components/RepositoryDetail/RepositoryDetail.tsx
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Add null checks for works variable.**

The works data is extracted from the hook result without null checks. This could lead to runtime errors if the data is not available.

```diff
-  const { data } = useRepositoryRelatedContent(repo.clientId)
-  const works = data?.works
+  const { data } = useRepositoryRelatedContent(repo.clientId)
+  const works = data?.works || { totalCount: 0, citationCount: 0, viewCount: 0, downloadCount: 0 }
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
  const { data } = useRepositoryRelatedContent(repo.clientId)
  const works = data?.works || { totalCount: 0, citationCount: 0, viewCount: 0, downloadCount: 0 }
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-05T20:46:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -161,7 +167,7 @@
     <>
       <div className={styles.header}>
         <h3>{repo.name}</h3>
-        <MetricsDisplay counts={{ works: repo.works.totalCount, citations: repo.citationCount, views: repo.viewCount, downloads: repo.downloadCount }} />
+        <MetricsDisplay counts={{ works: works?.totalCount, citations: works?.citationCount, views: works?.viewCount, downloads: works?.downloadCount }} />
path: src/components/RepositoryDetail/RepositoryDetail.tsx
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Add null/undefined checks for metrics display.**

The MetricsDisplay component receives counts directly from the works variable without adequate null checks. This could cause issues when data is not available.

```diff
-        <MetricsDisplay counts={{ works: works?.totalCount, citations: works?.citationCount, views: works?.viewCount, downloads: works?.downloadCount }} />
+        <MetricsDisplay counts={{ 
+          works: works?.totalCount || 0, 
+          citations: works?.citationCount || 0, 
+          views: works?.viewCount || 0, 
+          downloads: works?.downloadCount || 0 
+        }} />
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
        <MetricsDisplay counts={{ 
          works: works?.totalCount || 0, 
          citations: works?.citationCount || 0, 
          views: works?.viewCount || 0, 
          downloads: works?.downloadCount || 0 
        }} />
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-05T20:46:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -273,7 +273,7 @@ export type Repository = RepositoryMetadata & {
   repositoryType: string[]
   url: string
   keyword: string[]
-  subject: DefinedTerm[]
+  subject: { text: string }[]
path: src/data/types.ts
user: login: coderabbitai[bot]
body: _💡 Verification agent_

<details>
<summary>🧩 Analysis chain</summary>

**Verify all usages of the updated subject property type.**

The change from `subject: DefinedTerm[]` to `subject: { text: string }[]` is significant. Ensure all components that use this property have been updated to access `text` instead of any previous property like `name`.

---

🏁 Script executed:

```shell
#!/bin/bash
# Check how the subject property was previously accessed
echo "Checking for previous usages of subject property:"
rg "subject\." --type ts --type tsx -A 2 -B 2

# Check for current usages after the change
echo "Checking for current usages of subject text property:"
rg "subject.*text" --type ts --type tsx -A 2 -B 2
```

Length of output: 381

---

Below is a new verification shell script that uses explicit glob patterns for TS and TSX files. This should bypass the file type error and allow you to see if any old (e.g. `subject.name`) or updated (`subject.text`) usages remain:



---

**Action Required: Verify Updated Access to the `subject` Property**

The type change from `subject: DefinedTerm[]` to `subject: { text: string }[]` is significant. Please ensure that:
- All components accessing the `subject` property now use the updated `text` field.
- There are no remaining usages expecting a field like `name`.
- Both `.ts` and `.tsx` files have been updated accordingly (re-run the above script to double-check).



---

🏁 Script executed:

```shell

#!/bin/bash
echo "Searching for all subject property usages in TypeScript files:"
rg "subject\." -g "*.ts" -g "*.tsx" -A 2 -B 2

echo "Searching specifically for usages of subject.text in TypeScript files:"
rg "subject.*text" -g "*.ts" -g "*.tsx" -A 2 -B 2
```

Length of output: 2720

---



</details>

**Action Required: Update Subject Access in Utility Functions**

We've confirmed that the components in `RepositoryDetail.tsx` and `RepositoryMetadata.tsx` correctly use the updated `subject.text` access. However, the helper function in `src/utils/helpers.ts` still uses the old property access (e.g., `s.subject.startsWith('FOS: ')` and `s.slice(5)`). This is incompatible with the new type and needs updating.

- **File to Update:** `src/utils/helpers.ts`
  - **Change Needed:**  
    Replace:
    ```ts
    .filter((s) => s.subject.startsWith('FOS: '))
    .map(({ subject: s }) => ({ id: kebabify(s.slice(5)), name: s.slice(5) }))
    ```
    With:
    ```ts
    .filter((s) => s.subject.text.startsWith('FOS: '))
    .map(({ subject: s }) => ({ id: kebabify(s.text.slice(5)), name: s.text.slice(5) }))
    ```

Please verify that all uses of the `subject` property align with the updated type across the codebase.

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-05T20:46:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,9 +1,38 @@
 import { gql } from '@apollo/client'
 import { Repository, RepositoryMetadata } from 'src/data/types'
 import apolloClient from 'src/utils/apolloClient/apolloClient'
+import fetchConditionalCache from 'src/utils/fetchConditionalCache'
path: src/data/queries/repositoryQuery.ts
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Remove unused import.**

The `fetchConditionalCache` function is imported but never used in this file, causing lint errors in the pipeline.

```diff
-import fetchConditionalCache from 'src/utils/fetchConditionalCache'
```

Alternatively, implement caching for the new fetch function if that was the original intention:

```diff
 export async function fetchRepository(id: string) {
   try {
     const options = {
       method: 'GET',
       headers: { accept: 'application/vnd.api+json' }
     }
 
-    const res = await fetch(`${DATACITE_API_URL}/reference-repositories/${id}`, options)
+    const res = await fetchConditionalCache(`${DATACITE_API_URL}/reference-repositories/${id}`, options)
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
// (Other existing imports remain unchanged)
// Removed: import fetchConditionalCache from 'src/utils/fetchConditionalCache'

// ... rest of the code

export async function fetchRepository(id: string) {
  try {
    const options = {
      method: 'GET',
      headers: { accept: 'application/vnd.api+json' }
    }
    const res = await fetch(`${DATACITE_API_URL}/reference-repositories/${id}`, options)
    // ... further processing
  } catch (error) {
    // error handling
  }
}
`````

`````suggestion
import fetchConditionalCache from 'src/utils/fetchConditionalCache'
// (Other existing imports remain unchanged)

// ... rest of the code

export async function fetchRepository(id: string) {
  try {
    const options = {
      method: 'GET',
      headers: { accept: 'application/vnd.api+json' }
    }
    const res = await fetchConditionalCache(`${DATACITE_API_URL}/reference-repositories/${id}`, options)
    // ... further processing
  } catch (error) {
    // error handling
  }
}
`````

</details>

<!-- suggestion_end -->

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 ESLint</summary>

[error] 4-4: 'fetchConditionalCache' is defined but never used.

(no-unused-vars)

</details>
<details>
<summary>🪛 GitHub Actions: Test Pull Request</summary>

[error] 4-4: 'fetchConditionalCache' is defined but never used.  no-unused-vars

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-05T20:46:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,9 +1,37 @@
 import { gql } from '@apollo/client'
 import { Repository, RepositoryMetadata } from 'src/data/types'
 import apolloClient from 'src/utils/apolloClient/apolloClient'
+import { DATACITE_API_URL } from 'src/data/constants'
+import { mapJsonToRepository } from 'src/utils/helpers'
 
+function convertToQueryData(repository: any): QueryData {
+  return {
+    repository: mapJsonToRepository(repository)
+  }
+}
+
+export async function fetchRepository(id: string) {
+  try {
+    const options = {
+      method: 'GET',
+      headers: { accept: 'application/vnd.api+json' }
+    }
+
+    const res = await fetch(`${DATACITE_API_URL}/reference-repositories/${id}`, options)
+
+    if (!res.ok)
+      throw new Error(`API returned ${res.status}`)
+
+    const json = await res.json()
+
+    const data = convertToQueryData(json.data)
+    return { data }
+  } catch (error) {
+    return { error }
+  }
+}
path: src/data/queries/repositoryQuery.ts
user: login: coderabbitai[bot]
body: _💡 Verification agent_

<details>
<summary>🧩 Analysis chain</summary>

**Consider implementing caching for the new fetch function.**

The new REST API implementation doesn't utilize caching. Consider using `fetchConditionalCache` to maintain consistent caching behavior across the application.


---

🏁 Script executed:

```shell
#!/bin/bash
# Check if fetchConditionalCache is used elsewhere in the codebase
echo "Searching for fetchConditionalCache usage in the codebase..."
rg "fetchConditionalCache" --type ts
```

Length of output: 483

---



</details>

**Implement caching in fetchRepository for consistency**

The current implementation of `fetchRepository` (lines 13-32 in `src/data/queries/repositoryQuery.ts`) directly uses `fetch` without any caching, which is inconsistent with the application's other query functions (e.g. `doiQuery.ts` uses caching via `fetchConditionalCache` from `src/utils/fetchConditionalCache.ts`). Please consider refactoring `fetchRepository` to use `fetchConditionalCache` to ensure consistent caching behavior across the codebase.

- Import `fetchConditionalCache` from `src/utils/fetchConditionalCache.ts`.
- Replace the direct `fetch` call with `fetchConditionalCache`, following the usage pattern seen in `src/data/queries/doiQuery.ts`.

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-05T20:50:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,9 +1,37 @@
 import { gql } from '@apollo/client'
 import { Repository, RepositoryMetadata } from 'src/data/types'
 import apolloClient from 'src/utils/apolloClient/apolloClient'
+import { DATACITE_API_URL } from 'src/data/constants'
+import { mapJsonToRepository } from 'src/utils/helpers'
 
+function convertToQueryData(repository: any): QueryData {
+  return {
+    repository: mapJsonToRepository(repository)
+  }
+}
+
+export async function fetchRepository(id: string) {
+  try {
+    const options = {
+      method: 'GET',
+      headers: { accept: 'application/vnd.api+json' }
+    }
+
+    const res = await fetch(`${DATACITE_API_URL}/reference-repositories/${id}`, options)
+
+    if (!res.ok)
+      throw new Error(`API returned ${res.status}`)
+
+    const json = await res.json()
+
+    const data = convertToQueryData(json.data)
+    return { data }
+  } catch (error) {
+    return { error }
+  }
+}
 
-export async function fetchRepositoryMetadata(id: string) {
+export async function fetchRepositoryMetadataGQL(id: string) {
path: src/data/queries/repositoryQuery.ts
user: login: coderabbitai[bot]
body: _💡 Verification agent_

<details>
<summary>🧩 Analysis chain</summary>

**Verify all usages of renamed functions are updated.**

The GraphQL functions have been renamed to include 'GQL' suffix. Ensure all usages throughout the codebase are updated accordingly.




Also applies to: 44-44

---

🏁 Script executed:

```shell
#!/bin/bash
# Search for usages of the old function names
echo "Searching for usages of old function names..."
rg "\bfetchRepositoryMetadata\b|\bfetchRepository\([^G]" --type ts --type tsx

echo "Checking newly renamed functions usages..."
rg "\bfetchRepositoryMetadataGQL\b|\bfetchRepositoryGQL\b" --type ts --type tsx
```

Length of output: 413

---

**Action Required: Verify All References to Renamed GraphQL Functions**

- The previous search command failed due to an unrecognized file type error for `.tsx` files.
- The script above leverages `find` and `grep` to scan both `.ts` and `.tsx` files for any legacy references (e.g., `fetchRepositoryMetadata`, `fetchRepository`) and for the new names (`fetchRepositoryMetadataGQL`, `fetchRepositoryGQL`).
- Please execute this script to manually verify that there are no lingering usages of the old function names.



---

🏁 Script executed:

```shell

#!/bin/bash
# Search for usages of old function names in .ts and .tsx files using find and grep
echo "Searching for usages of old function names in .ts and .tsx files..."
find . -type f \( -iname "*.ts" -o -iname "*.tsx" \) -print0 | xargs -0 grep -E "\bfetchRepositoryMetadata\b|\bfetchRepository\([^G]"

echo "Searching for usages of the updated renamed functions in .ts and .tsx files..."
find . -type f \( -iname "*.ts" -o -iname "*.tsx" \) -print0 | xargs -0 grep -E "\bfetchRepositoryMetadataGQL\b|\bfetchRepositoryGQL\b"
```

Length of output: 1299

---



</details>

**Action Required: Update remaining legacy function references**

The codebase still contains references to the old function name (`fetchRepository`) that have not been updated to the new GraphQL naming convention. Specifically, please address the following:

- **File:** `src/data/queries/repositoryQuery.ts`  
  - The old function `fetchRepository` is still defined and used. This should be refactored to include the 'GQL' suffix (e.g., to `fetchRepositoryGQL`) if appropriate.

- **File:** `src/app/repositories/[...repoid]/page.tsx`  
  - Call(s) to `fetchRepository` need to be updated to use the corresponding GQL function.

- **File:** `src/app/repositories/[...repoid]/Content.tsx`  
  - Likewise, update the call to `fetchRepository` to the new GQL version.

Please verify that these changes align with your intended GraphQL API refactoring, and update all occurrences to maintain consistency across the codebase.

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-05T20:50:06Z
author_association: CONTRIBUTOR

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-03-05T20:34:26Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough
The pull request updates several components and modules to change the way repository data is fetched and processed. In the UI components, the fetch function argument is refined to only include the repository `id`, and properties have been renamed from `re3dataDoi` to `re3doi`. Additionally, repository IDs are now decoded before use, and a new hook retrieves related repository content. On the data layer, new REST-based functions are introduced while existing GraphQL-based functions are renamed, and type definitions are updated accordingly.

## Changes

| File(s) | Change Summary |
| --- | --- |
| `src/app/repositories/[...repoid]/Content.tsx`<br>`src/app/repositories/[...repoid]/page.tsx` | In the Page components, the argument passed to `fetchRepository` is changed to only the repository `id`, with the repository ID being decoded. Open Graph metadata now uses `repo.re3doi` instead of `repo.re3dataDoi`. |
| `src/components/RepositoryDetail/RepositoryDetail.tsx`<br>`src/components/RepositoryMetadata/RepositoryMetadata.tsx` | Added a new hook `useRepositoryRelatedContent` for fetching related repository content. Updated property access from `repo.re3dataDoi` to `repo.re3doi` and modified mapping in subjects (using `subject.text`). |
| `src/data/queries/repositoryQuery.ts`<br>`src/data/queries/searchRepositoryQuery.ts`<br>`src/data/queries/searchDoiQuery.ts` | Introduced a new REST API-based `fetchRepository` function and new methods (`fetchRepositories`, `buildRepositorySearchParams`, `convertToQueryData`). Renamed existing GraphQL-based functions to include a `GQL` suffix and exported `getPageInfo` from search DOI query. |
| `src/data/types.ts`<br>`src/utils/helpers.ts` | Updated type definitions by renaming `re3dataDoi` to `re3doi` and changing the structure of `subject` (removing `DefinedTerm`). Added a new helper function `mapJsonToRepository` and made minor formatting adjustments. |

## Sequence Diagram(s)
```mermaid
sequenceDiagram
  participant User
  participant PageComponent
  participant API
  participant Renderer

  User->>PageComponent: Request repository page
  PageComponent->>PageComponent: Decode repository ID
  PageComponent->>API: Call fetchRepository(id)
  API-->>PageComponent: Return repository data (using REST API)
  PageComponent->>Renderer: Render repository details & Open Graph metadata using `repo.re3doi`
```

```mermaid
sequenceDiagram
  participant SearchUI
  participant SearchHook
  participant REST_API
  participant GraphQL_API
  participant DataMapper

  SearchUI->>SearchHook: Trigger repository search
  alt Use REST approach
    SearchHook->>REST_API: Call fetchRepositories(variables)
    REST_API-->>SearchHook: JSON response
    SearchHook->>DataMapper: Call convertToQueryData(json)
    DataMapper-->>SearchHook: Structured query data
  else Use GraphQL approach
    SearchHook->>GraphQL_API: Call useSearchRepositoryQueryGQL(variables)
    GraphQL_API-->>SearchHook: Data response
  end
  SearchHook-->>SearchUI: Return search results
```

## Suggested reviewers
- codycooperross
- jrhoads

## Poem
> Oh hi, I’m a hopping code rabbit,  
> New REST and GraphQL now in our habit.  
> IDs decoded, data refined with care,  
> Re3doi shines in the fresh code air.  
> With hooks and helpers, our work’s complete,  
> A joyful sprint, light on our feet!  
> 🐰✨

<!-- walkthrough_end -->


---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between c46988adc291d794b299c89201ee16740531ca85 and ab8f84b60f3d88dafc152a3362136be5e300dc75.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `src/data/queries/repositoryRelatedContentQuery.ts` (1 hunks)

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (1)</summary>

* src/data/queries/repositoryRelatedContentQuery.ts

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (7)</summary>

* GitHub Check: test / cypress (5)
* GitHub Check: test / cypress (4)
* GitHub Check: test / cypress (3)
* GitHub Check: test / cypress (2)
* GitHub Check: test / cypress (1)
* GitHub Check: CodeQL-Build
* GitHub Check: CodeQL-Build

</details>

</details>
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- tips_start -->

---



<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=datacite/akita&utm_content=470):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: CONTRIBUTOR
user: login: cypress[bot]
created_at: 2025-03-05T20:46:17Z
body: 
<h3>
  <a href="https://cloud.cypress.io/projects/yur1cf?utm_source=github&utm_medium=PASSED&utm_campaign=project">akita</a>&nbsp;
  <img src="https://assets.cypress.io/github-pr-comment-icons/chevron.svg" alt="" height="14" width="14" />&nbsp;
  <a href="https://cloud.cypress.io/projects/yur1cf/runs/1605/overview?utm_source=github&utm_medium=PASSED&utm_campaign=run%20number">Run #1605</a>
</h3>

<details>
  <summary>
    <strong>Run Properties:</strong>&nbsp;
    <code><img src="https://assets.cypress.io/github-pr-comment-icons/passed.svg" alt="status check passed" height="10" width="10" />&nbsp;Passed&nbsp;<a href="https://cloud.cypress.io/projects/yur1cf/runs/1605/overview?utm_source=github&utm_medium=PASSED&utm_campaign=run%20number">#1605</a></code> &nbsp;&bull;&nbsp;
    <code><img src="https://assets.cypress.io/github-pr-comment-icons/git-commit.svg" alt="git commit" width="10" height="10" /> <a href="https://github.com/datacite/akita/commit/4878a2ab35b14cc05b4663ed4a71c4f503cbff8b">4878a2ab35 <span style="cursor:help;" title="Your CI provider generated this commit by merging this branch into the target branch.">ℹ️</span></a>: Merge ab8f84b60f3d88dafc152a3362136be5e300dc75 into 47c6a5ee0680b74627b4dcd8ab9c...</code>
  </summary><br />

  <table width="744">
    <tbody>
      <tr />
      <tr height="48">
        <td width="224">
          <strong>Project</strong>
        </td>
        <td width="520">
          <code><a href="https://cloud.cypress.io/projects/yur1cf?utm_source=github&utm_medium=PASSED&utm_campaign=project">akita</a></code>
        </td>
      </tr>
      <tr />
      <tr height="48">
        <td width="224">
          <strong>Branch Review</strong>
        </th>
        <td>
          <code><a href="https://cloud.cypress.io/projects/yur1cf/branches/migrate-repository-query-to-rest-api/review?utm_source=github&utm_medium=PASSED&utm_campaign=review%20changes&changeRequest=470">migrate-repository-query-to-rest-api</a></code>
        </td>
      </tr>
      <tr />
      <tr height="48">
        <td><strong>Run status</strong></td>
        <td>
          <code><img src="https://assets.cypress.io/github-pr-comment-icons/passed.svg" alt="status check passed" height="10" width="10" />&nbsp;Passed&nbsp;<a href="https://cloud.cypress.io/projects/yur1cf/runs/1605/overview?utm_source=github&utm_medium=PASSED&utm_campaign=run%20number">#1605</a></code>
        </td>
      </tr>
      <tr />
      <tr height="48">
        <td><strong>Run duration</strong></td>
        <td><code>01m 37s</code></td>
      </tr>
      <tr />
      <tr height="48">
        <td><strong>Commit</strong></td>
        <td>
          <code><img src="https://assets.cypress.io/github-pr-comment-icons/git-commit.svg" alt="git commit" width="10" height="10" /> <a href="https://github.com/datacite/akita/commit/4878a2ab35b14cc05b4663ed4a71c4f503cbff8b">4878a2ab35 <span style="cursor:help;" title="Your CI provider generated this commit by merging this branch into the target branch.">ℹ️</span></a>: Merge ab8f84b60f3d88dafc152a3362136be5e300dc75 into 47c6a5ee0680b74627b4dcd8ab9c...</code>
        </td>
      </tr>
      <tr />
      <tr height="48">
        <td><strong>Committer</strong></td>
        <td><code>Bryceson Laing</code></td>
      </tr>
    </tbody>
    <tfoot>
      <tr />
      <tr height="48">
        <td colspan="2">
          <a href="https://cloud.cypress.io/projects/yur1cf/runs/1605/properties?utm_source=github&utm_medium=PASSED&utm_campaign=properties">View all properties for this run ↗︎</a>
        </td>
      </tr>
    </tfoot>
  </table>
  <hr />
</details>

<table width="744">
  <thead>
    <tr />
    <tr height="48">
      <th colspan="2" align="left" width="744">Test results</th>
    </tr>
  </thead>
  <tbody>
    <tr height="48">
      <td width="224">
        <img src="https://assets.cypress.io/github-pr-comment-icons/failed.svg" alt="Tests that failed" width="10" height="10" />&nbsp;
        <a href="https://cloud.cypress.io/projects/yur1cf/runs/1605/overview?reviewViewBy=FAILED&utm_source=github&utm_medium=PASSED&utm_campaign=failed%20tests">
          <strong>Failures</strong>
        </a>
      </td>
      <td>
        <code><strong>0</strong></code>
      </td>
    </tr>
    <tr />
    <tr height="48">
      <td width="224">
        <img src="https://assets.cypress.io/github-pr-comment-icons/flaky-v3.svg" alt="Tests that were flaky" width="10" height="10" />&nbsp;
        <a href="https://cloud.cypress.io/projects/yur1cf/runs/1605/overview?reviewViewBy=FLAKY&utm_source=github&utm_medium=PASSED&utm_campaign=flaky%20tests">
          <strong>Flaky</strong>
        </a>
      </td>
      <td>
        <code><strong>0</strong></code>
      </td>
    </tr>
    <tr />
    <tr height="48">
      <td width="224">
        <img src="https://assets.cypress.io/github-pr-comment-icons/pending.svg" alt="Tests that did not run due to a developer annotating a test with .skip" width="10" height="10" />&nbsp;
        <a href="https://cloud.cypress.io/projects/yur1cf/runs/1605/test-results?utm_source=github&utm_medium=PASSED&utm_campaign=pending%20tests&statuses=%5B%7B%22value%22%3A%22PENDING%22%2C%22label%22%3A%22PENDING%22%7D%5D">
          <strong>Pending</strong>
        </a>
      </td>
      <td>
        <code><strong>3</strong></code>
      </td>
    </tr>
    <tr />
    <tr height="48">
      <td width="224">
        <img src="https://assets.cypress.io/github-pr-comment-icons/skipped-v3.svg" alt="Tests that did not run due to a failure in a mocha hook" width="10" height="10" />&nbsp;
        <a href="https://cloud.cypress.io/projects/yur1cf/runs/1605/test-results?utm_source=github&utm_medium=PASSED&utm_campaign=skipped%20tests&statuses=%5B%7B%22value%22%3A%22SKIPPED%22%2C%22label%22%3A%22SKIPPED%22%7D%5D">
          <strong>Skipped</strong>
        </a>
      </td>
      <td>
        <code><strong>0</strong></code>
      </td>
    </tr>
    <tr />
    <tr height="48">
      <td width="224">
        <img src="https://assets.cypress.io/github-pr-comment-icons/passed.svg" alt="Tests that passed" width="10" height="10" />&nbsp;
        <a href="https://cloud.cypress.io/projects/yur1cf/runs/1605/overview?utm_source=github&utm_medium=PASSED&utm_campaign=passed%20tests">
          <strong>Passing</strong>
        </a>
      </td>
      <td>
        <code><strong>49</strong></code>
      </td>
    </tr><tfoot>
    <tr height="48"><td colspan="2"><a href="https://cloud.cypress.io/projects/yur1cf/branches/migrate-repository-query-to-rest-api/review?utm_source=github&utm_medium=PASSED&utm_campaign=review%20changes&changeRequest=470">View all changes introduced in this branch ↗︎</a></td></tr></tfoot>
  </tbody>
</table>






author_association: NONE
user: login: cypress[bot]
created_at: 2025-03-05T22:19:55Z
body: 
<h3>
  <a href="https://cloud.cypress.io/projects/yur1cf?utm_source=github&utm_medium=flaky&utm_campaign=project">akita</a>&nbsp;
  <img src="https://assets.cypress.io/github-pr-comment-icons/chevron.svg" alt="" height="14" width="14" />&nbsp;
  <a href="https://cloud.cypress.io/projects/yur1cf/runs/1606/overview?utm_source=github&utm_medium=flaky&utm_campaign=run%20number">Run #1606</a>
</h3>

<details>
  <summary>
    <strong>Run Properties:</strong>&nbsp;
    <code><img src="https://assets.cypress.io/github-pr-comment-icons/passed.svg" alt="status check passed" height="10" width="10" />&nbsp;Passed&nbsp;<a href="https://cloud.cypress.io/projects/yur1cf/runs/1606/overview?utm_source=github&utm_medium=flaky&utm_campaign=run%20number">#1606</a></code> &nbsp;&bull;&nbsp;
    <code><img src="https://assets.cypress.io/github-pr-comment-icons/git-commit.svg" alt="git commit" width="10" height="10" /> <a href="https://github.com/datacite/akita/commit/442db7787729b452efa5cdde69913b2e0d767408">442db77877</a>: Migrate repository query to rest api (#470)</code>
  </summary><br />

  <table width="744">
    <tbody>
      <tr />
      <tr height="48">
        <td width="224">
          <strong>Project</strong>
        </td>
        <td width="520">
          <code><a href="https://cloud.cypress.io/projects/yur1cf?utm_source=github&utm_medium=flaky&utm_campaign=project">akita</a></code>
        </td>
      </tr>
      <tr />
      <tr height="48">
        <td width="224">
          <strong>Branch Review</strong>
        </th>
        <td>
          <code><a href="https://cloud.cypress.io/projects/yur1cf/branches/master/review?utm_source=github&utm_medium=flaky&utm_campaign=review%20changes&changeRequest=470">master</a></code>
        </td>
      </tr>
      <tr />
      <tr height="48">
        <td><strong>Run status</strong></td>
        <td>
          <code><img src="https://assets.cypress.io/github-pr-comment-icons/passed.svg" alt="status check passed" height="10" width="10" />&nbsp;Passed&nbsp;<a href="https://cloud.cypress.io/projects/yur1cf/runs/1606/overview?utm_source=github&utm_medium=flaky&utm_campaign=run%20number">#1606</a></code>
        </td>
      </tr>
      <tr />
      <tr height="48">
        <td><strong>Run duration</strong></td>
        <td><code>03m 04s</code></td>
      </tr>
      <tr />
      <tr height="48">
        <td><strong>Commit</strong></td>
        <td>
          <code><img src="https://assets.cypress.io/github-pr-comment-icons/git-commit.svg" alt="git commit" width="10" height="10" /> <a href="https://github.com/datacite/akita/commit/442db7787729b452efa5cdde69913b2e0d767408">442db77877</a>: Migrate repository query to rest api (#470)</code>
        </td>
      </tr>
      <tr />
      <tr height="48">
        <td><strong>Committer</strong></td>
        <td><code>Bryceson Laing</code></td>
      </tr>
    </tbody>
    <tfoot>
      <tr />
      <tr height="48">
        <td colspan="2">
          <a href="https://cloud.cypress.io/projects/yur1cf/runs/1606/properties?utm_source=github&utm_medium=flaky&utm_campaign=properties">View all properties for this run ↗︎</a>
        </td>
      </tr>
    </tfoot>
  </table>
  <hr />
</details>

<table width="744">
  <thead>
    <tr />
    <tr height="48">
      <th colspan="2" align="left" width="744">Test results</th>
    </tr>
  </thead>
  <tbody>
    <tr height="48">
      <td width="224">
        <img src="https://assets.cypress.io/github-pr-comment-icons/failed.svg" alt="Tests that failed" width="10" height="10" />&nbsp;
        <a href="https://cloud.cypress.io/projects/yur1cf/runs/1606/overview?reviewViewBy=FAILED&utm_source=github&utm_medium=flaky&utm_campaign=failed%20tests">
          <strong>Failures</strong>
        </a>
      </td>
      <td>
        <code><strong>0</strong></code>
      </td>
    </tr>
    <tr />
    <tr height="48">
      <td width="224">
        <img src="https://assets.cypress.io/github-pr-comment-icons/flaky-v3.svg" alt="Tests that were flaky" width="10" height="10" />&nbsp;
        <a href="https://cloud.cypress.io/projects/yur1cf/runs/1606/overview?reviewViewBy=FLAKY&utm_source=github&utm_medium=flaky&utm_campaign=flaky%20tests">
          <strong>Flaky</strong>
        </a>
      </td>
      <td>
        <code><strong>7</strong></code>
      </td>
    </tr>
    <tr />
    <tr height="48">
      <td width="224">
        <img src="https://assets.cypress.io/github-pr-comment-icons/pending.svg" alt="Tests that did not run due to a developer annotating a test with .skip" width="10" height="10" />&nbsp;
        <a href="https://cloud.cypress.io/projects/yur1cf/runs/1606/test-results?utm_source=github&utm_medium=flaky&utm_campaign=pending%20tests&statuses=%5B%7B%22value%22%3A%22PENDING%22%2C%22label%22%3A%22PENDING%22%7D%5D">
          <strong>Pending</strong>
        </a>
      </td>
      <td>
        <code><strong>3</strong></code>
      </td>
    </tr>
    <tr />
    <tr height="48">
      <td width="224">
        <img src="https://assets.cypress.io/github-pr-comment-icons/skipped-v3.svg" alt="Tests that did not run due to a failure in a mocha hook" width="10" height="10" />&nbsp;
        <a href="https://cloud.cypress.io/projects/yur1cf/runs/1606/test-results?utm_source=github&utm_medium=flaky&utm_campaign=skipped%20tests&statuses=%5B%7B%22value%22%3A%22SKIPPED%22%2C%22label%22%3A%22SKIPPED%22%7D%5D">
          <strong>Skipped</strong>
        </a>
      </td>
      <td>
        <code><strong>0</strong></code>
      </td>
    </tr>
    <tr />
    <tr height="48">
      <td width="224">
        <img src="https://assets.cypress.io/github-pr-comment-icons/passed.svg" alt="Tests that passed" width="10" height="10" />&nbsp;
        <a href="https://cloud.cypress.io/projects/yur1cf/runs/1606/overview?utm_source=github&utm_medium=flaky&utm_campaign=passed%20tests">
          <strong>Passing</strong>
        </a>
      </td>
      <td>
        <code><strong>49</strong></code>
      </td>
    </tr><tfoot>
    <tr height="48"><td colspan="2"><a href="https://cloud.cypress.io/projects/yur1cf/branches/master/review?utm_source=github&utm_medium=flaky&utm_campaign=review%20changes&changeRequest=470">View all changes introduced in this branch ↗︎</a></td></tr></tfoot>
  </tbody>
</table>






author_association: NONE