Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .cursor/rules/docs-embeddings-generation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Documentation Embeddings Generation System

## Overview

The documentation embeddings generation system processes various documentation sources and uploads their metadata to a database for semantic search functionality. The system is located in `apps/docs/scripts/search/` and works by:

1. **Discovering content sources** from multiple types of documentation
2. **Processing content** into structured sections with checksums
3. **Generating embeddings** using OpenAI's text-embedding-ada-002 model
4. **Storing in database** with vector embeddings for semantic search

## Architecture

### Main Entry Point
- `generate-embeddings.ts` - Main script that orchestrates the entire process
- Supports `--refresh` flag to force regeneration of all content

### Content Sources (`sources/` directory)

#### Base Classes
- `BaseLoader` - Abstract class for loading content from different sources
- `BaseSource` - Abstract class for processing and formatting content

#### Source Types
1. **Markdown Sources** (`markdown.ts`)
- Processes `.mdx` files from guides and documentation
- Extracts frontmatter metadata and content sections

2. **Reference Documentation** (`reference-doc.ts`)
- **OpenAPI References** - Management API documentation from OpenAPI specs
- **Client Library References** - JavaScript, Dart, Python, C#, Swift, Kotlin SDKs
- **CLI References** - Command-line interface documentation
- Processes YAML/JSON specs and matches with common sections

3. **GitHub Discussions** (`github-discussion.ts`)
- Fetches troubleshooting discussions from GitHub using GraphQL API
- Uses GitHub App authentication for access

4. **Partner Integrations** (`partner-integrations.ts`)
- Fetches approved partner integration documentation from Supabase database
- Technology integrations only (excludes agencies)

### Processing Flow

1. **Content Discovery**: Each source loader discovers and loads content files/data
2. **Content Processing**: Each source processes content into:
- Checksum for change detection
- Metadata (title, subtitle, etc.)
- Sections with headings and content
3. **Change Detection**: Compares checksums against existing database records
4. **Embedding Generation**: Uses OpenAI to generate embeddings for new/changed content
5. **Database Storage**: Stores in `page` and `page_section` tables with embeddings
6. **Cleanup**: Removes outdated pages using version tracking

### Database Schema

- **`page`** table: Stores page metadata, content, checksum, version
- **`page_section`** table: Stores individual sections with embeddings, token counts

14 changes: 14 additions & 0 deletions apps/docs/app/api/graphql/__snapshots__/route.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,20 @@ type CLICommandReference implements SearchResult {
content: String
}

"""
A reference document containing a description of a Supabase Management API endpoint
"""
type ManagementApiReference implements SearchResult {
"""The title of the document"""
title: String

"""The URL of the document"""
href: String

"""The content of the reference document, as text"""
content: String
}

"""
A reference document containing a description of a function from a Supabase client library
"""
Expand Down
36 changes: 36 additions & 0 deletions apps/docs/app/api/graphql/tests/searchDocs.smoke.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,40 @@ describe('prod smoke test: graphql: searchDocs', () => {
expect(guideNode).toHaveProperty('href')
expect(guideNode).toHaveProperty('content')
})

it('searchDocs query includes Management API references', async () => {
const query = `
query SearchDocsQuery($query: String!) {
searchDocs(query: $query) {
nodes {
...on ManagementApiReference {
title
href
content
}
}
}
}
`
const result = await fetch(GRAPHQL_URL, {
method: 'POST',
body: JSON.stringify({ query, variables: { query: 'create SSO provider' } }),
})

expect(result.status).toBe(200)
const { data, errors } = await result.json()
expect(errors).toBeUndefined()

const {
searchDocs: { nodes },
} = data
expect(Array.isArray(nodes)).toBe(true)
expect(nodes.length).toBeGreaterThan(0)

const managementApiNode = nodes.find((node: any) => !!node.title)
expect(managementApiNode).toBeDefined()
expect(managementApiNode).toHaveProperty('title')
expect(managementApiNode).toHaveProperty('href')
expect(managementApiNode).toHaveProperty('content')
})
})
46 changes: 46 additions & 0 deletions apps/docs/app/api/graphql/tests/searchDocs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ const rpcSpy = vi.fn().mockImplementation((funcName, params) => {
content: params?.include_full_content ? 'Another content' : null,
subsections: [{ title: 'Getting Started', content: 'Getting Started content' }],
},
{
type: 'reference',
page_title: 'Create a SSO provider',
href: 'https://supabase.com/docs/reference/api/v1-create-a-sso-provider',
content: params?.include_full_content ? 'Creates a new SSO provider for a project' : null,
metadata: {
title: 'Create a SSO provider',
subtitle: 'Management API Reference: Create a SSO provider',
},
},
]
return Promise.resolve({ data: mockResults.slice(0, limit), error: null })
}
Expand Down Expand Up @@ -190,4 +200,40 @@ describe('/api/graphql searchDocs', () => {
expect(json.errors).toBeDefined()
expect(json.errors[0].message).toContain('required')
})

it('should return Management API references with proper fields', async () => {
const searchQuery = `
query {
searchDocs(query: "SSO provider", limit: 3) {
nodes {
... on ManagementApiReference {
title
href
content
}
}
}
}
`
const request = new Request('http://localhost/api/graphql', {
method: 'POST',
body: JSON.stringify({ query: searchQuery }),
})

const response = await POST(request)
const json = await response.json()

expect(json.errors).toBeUndefined()
expect(json.data).toBeDefined()
expect(json.data.searchDocs).toBeDefined()
expect(json.data.searchDocs.nodes).toBeInstanceOf(Array)
expect(json.data.searchDocs.nodes).toHaveLength(3)

const managementApiNode = json.data.searchDocs.nodes[2]
expect(managementApiNode).toMatchObject({
title: 'Create a SSO provider',
href: 'https://supabase.com/docs/reference/api/v1-create-a-sso-provider',
content: 'Creates a new SSO provider for a project',
})
})
})
2 changes: 1 addition & 1 deletion apps/docs/content/guides/getting-started/features.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ In addition to the Beta requirements, features in GA are covered by the [uptime
| Platform | Custom Domains | `GA` | N/A |
| Platform | Network Restrictions | `beta` | N/A |
| Platform | SSL enforcement | `GA` | N/A |
| Platform | Branching | `public alpha` | N/A |
| Platform | Branching | `beta` | N/A |
| Platform | Terraform Provider | `public alpha` | N/A |
| Platform | Read Replicas | `private alpha` | N/A |
| Platform | Log Drains | `public alpha` | ✅ |
Expand Down
13 changes: 12 additions & 1 deletion apps/docs/content/guides/local-development.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Develop locally while running the Supabase stack on your machine.
</TabPanel><TabPanel id="yarn" label="yarn">

```sh
yarn add supabase --dev
NODE_OPTIONS=--no-experimental-fetch yarn add supabase --dev
```

</TabPanel><TabPanel id="pnpm" label="pnpm">
Expand Down Expand Up @@ -95,6 +95,17 @@ Develop locally while running the Supabase stack on your machine.

</Tabs>

<Admonition type="note">

As a prerequisite, you must install a container runtime compatible with Docker APIs.

- [Docker Desktop](https://docs.docker.com/desktop/) (macOS, Windows, Linux)
- [Rancher Desktop](https://rancherdesktop.io/) (macOS, Windows, Linux)
- [Podman](https://podman.io/) (macOS, Windows, Linux)
- [OrbStack](https://orbstack.dev/) (macOS)

</Admonition>

4. View your local Supabase instance at [http://localhost:54323](http://localhost:54323).

## Local development
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Restoring a downloaded backup locally
subtitle: Restore a backup of a remote database on a local instance to inspect and extract data
---

You can restore a downloaded backup to a local Supabase instance. This might be useful if your paused project has exceeded its [restoring time limit](/docs/guides/platform/upgrading#time-limits). You can download the latest backup, then load it locally to inspect and extract your data.
If your paused project has exceeded its [restoring time limit](/docs/guides/platform/upgrading#time-limits), you can download a backup from the dashboard and restore it to your local development environment. This might be useful for inspecting and extracting data from your paused project.

<Admonition type="caution">

Expand Down
7 changes: 6 additions & 1 deletion apps/docs/lib/supabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ type Database = {
DatabaseGenerated['public']['Functions']['search_content']['Returns'][number],
'subsections' | 'metadata'
> & {
metadata: { language?: string; methodName?: string; platform?: string }
metadata: {
subtitle?: string
language?: string
methodName?: string
platform?: string
}
subsections: Array<{ title?: string; href?: string; content?: string }>
}
>
Expand Down
1 change: 1 addition & 0 deletions apps/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"postbuild": "pnpm run build:sitemap && pnpm run build:llms && ./../../scripts/upload-static-assets.sh",
"prebuild": "pnpm run codegen:graphql && pnpm run codegen:references && pnpm run codegen:examples",
"predev": "pnpm run codegen:graphql && pnpm run codegen:references && pnpm run codegen:examples",
"preembeddings": "pnpm run codegen:references",
"preinstall": "npx only-allow pnpm",
"presync": "pnpm run codegen:graphql",
"pretest": "pnpm run codegen:examples",
Expand Down
8 changes: 8 additions & 0 deletions apps/docs/resources/globalSearch/globalSearchModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
DB_METADATA_TAG_PLATFORM_CLI,
ReferenceCLICommandModel,
} from '../reference/referenceCLIModel'
import { ReferenceManagementApiModel } from '../reference/referenceManagementApiModel'
import { ReferenceSDKFunctionModel, SDKLanguageValues } from '../reference/referenceSDKModel'
import { TroubleshootingModel } from '../troubleshooting/troubleshootingModel'
import { SearchResultInterface } from './globalSearchInterface'
Expand Down Expand Up @@ -74,6 +75,13 @@ function createModelFromMatch({
content,
subsections,
})
// TODO [Charis 2025-06-09] replace with less hacky check
} else if (metadata.subtitle?.startsWith('Management API Reference')) {
return new ReferenceManagementApiModel({
title: page_title,
href,
content,
})
} else {
return null
}
Expand Down
13 changes: 13 additions & 0 deletions apps/docs/resources/reference/referenceManagementApiModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { type SearchResultInterface } from '../globalSearch/globalSearchInterface'

export class ReferenceManagementApiModel implements SearchResultInterface {
public title?: string
public href?: string
public content?: string

constructor({ title, href, content }: { title?: string; href?: string; content?: string }) {
this.title = title
this.href = href
this.content = content
}
}
25 changes: 25 additions & 0 deletions apps/docs/resources/reference/referenceManagementApiSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { GraphQLObjectType, GraphQLString } from 'graphql'
import { GraphQLInterfaceTypeSearchResult } from '../globalSearch/globalSearchSchema'
import { ReferenceManagementApiModel } from './referenceManagementApiModel'

export const GraphQLObjectTypeReferenceManagementApi = new GraphQLObjectType({
name: 'ManagementApiReference',
interfaces: [GraphQLInterfaceTypeSearchResult],
isTypeOf: (value: unknown) => value instanceof ReferenceManagementApiModel,
description:
'A reference document containing a description of a Supabase Management API endpoint',
fields: {
title: {
type: GraphQLString,
description: 'The title of the document',
},
href: {
type: GraphQLString,
description: 'The URL of the document',
},
content: {
type: GraphQLString,
description: 'The content of the reference document, as text',
},
},
})
2 changes: 2 additions & 0 deletions apps/docs/resources/rootSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { errorRoot, errorsRoot } from './error/errorResolver'
import { searchRoot } from './globalSearch/globalSearchResolver'
import { GraphQLObjectTypeGuide } from './guide/guideSchema'
import { GraphQLObjectTypeReferenceCLICommand } from './reference/referenceCLISchema'
import { GraphQLObjectTypeReferenceManagementApi } from './reference/referenceManagementApiSchema'
import { GraphQLObjectTypeReferenceSDKFunction } from './reference/referenceSDKSchema'
import { GraphQLObjectTypeTroubleshooting } from './troubleshooting/troubleshootingSchema'

Expand Down Expand Up @@ -43,6 +44,7 @@ export const rootGraphQLSchema = new GraphQLSchema({
types: [
GraphQLObjectTypeGuide,
GraphQLObjectTypeReferenceCLICommand,
GraphQLObjectTypeReferenceManagementApi,
GraphQLObjectTypeReferenceSDKFunction,
GraphQLObjectTypeTroubleshooting,
],
Expand Down
Loading
Loading