* feat(graphql): add paginated errors collection query - Add new GraphQL query field 'errors' with cursor-based pagination - Add UUID id column to content.error table for cursor pagination - Implement error collection resolver with forward/backward pagination - Add comprehensive test suite for pagination functionality - Update database types and schema to support new error collection - Add utility functions for handling collection queries and errors - Add seed data for testing pagination scenarios This change allows clients to efficiently paginate through error codes using cursor-based pagination, supporting both forward and backward traversal. The implementation follows the Relay connection specification and includes proper error handling and type safety. * docs(graphql): add comprehensive GraphQL architecture documentation Add detailed documentation for the docs GraphQL endpoint architecture, including: - Modular query pattern and folder structure - Step-by-step guide for creating new top-level queries - Best practices for error handling, field optimization, and testing - Code examples for schemas, models, resolvers, and tests * feat(graphql): add service filtering to errors collection query Enable filtering error codes by Supabase service in the GraphQL errors collection: - Add optional service argument to errors query resolver - Update error model to support service-based filtering in database queries - Maintain pagination compatibility with service filtering - Add comprehensive tests for service filtering with and without pagination * feat(graphql): add service filtering and fix cursor encoding for errors collection - Add service parameter to errors GraphQL query for filtering by Supabase service - Implement base64 encoding/decoding for pagination cursors in error resolver - Fix test cursor encoding to match resolver implementation - Update GraphQL schema snapshot to reflect new service filter field * docs(graphql): fix codegen instruction
58 lines
2.2 KiB
TypeScript
58 lines
2.2 KiB
TypeScript
import { GraphQLObjectType, GraphQLString } from 'graphql'
|
|
import { GraphQLInterfaceTypeSearchResult } from '../globalSearch/globalSearchSchema'
|
|
import { createCollectionType, GraphQLCollectionBuilder } from '../utils/connections'
|
|
import { GuideModel, SubsectionModel } from './guideModel'
|
|
|
|
export const GraphQLObjectTypeSubsection = new GraphQLObjectType({
|
|
name: 'Subsection',
|
|
isTypeOf: (value: unknown) => value instanceof SubsectionModel,
|
|
description: 'A content chunk taken from a larger document in the Supabase docs',
|
|
fields: {
|
|
title: {
|
|
type: GraphQLString,
|
|
description: 'The title of the subsection',
|
|
},
|
|
href: {
|
|
type: GraphQLString,
|
|
description: 'The URL of the subsection',
|
|
},
|
|
content: {
|
|
type: GraphQLString,
|
|
description: 'The content of the subsection',
|
|
},
|
|
},
|
|
})
|
|
|
|
export const GraphQLObjectTypeGuide = new GraphQLObjectType({
|
|
name: 'Guide',
|
|
interfaces: [GraphQLInterfaceTypeSearchResult],
|
|
isTypeOf: (value: unknown) => value instanceof GuideModel,
|
|
description:
|
|
'A document containing content from the Supabase docs. This is a guide, which might describe a concept, or explain the steps for using or implementing a feature.',
|
|
fields: {
|
|
title: {
|
|
type: GraphQLString,
|
|
description: 'The title of the document',
|
|
},
|
|
href: {
|
|
type: GraphQLString,
|
|
description: 'The URL of the document',
|
|
},
|
|
content: {
|
|
type: GraphQLString,
|
|
description:
|
|
'The full content of the document, including all subsections (both those matching and not matching any query string) and possibly more content',
|
|
},
|
|
subsections: {
|
|
type: createCollectionType(GraphQLObjectTypeSubsection, {
|
|
skipPageInfo: true,
|
|
description: 'A collection of content chunks from a larger document in the Supabase docs.',
|
|
}),
|
|
description:
|
|
'The subsections of the document. If the document is returned from a search match, only matching content chunks are returned. For the full content of the original document, use the content field in the parent Guide.',
|
|
resolve: async (node: GuideModel) =>
|
|
(await GraphQLCollectionBuilder.create({ items: node.subsections })).unwrap(),
|
|
},
|
|
},
|
|
})
|