From 31794231ff67448848bf35a192a5be6e0227830e Mon Sep 17 00:00:00 2001 From: Gerard Clos Date: Fri, 26 Jul 2024 17:56:48 +0200 Subject: [PATCH] feature: crud provider apikeys Implements basic crud for apikeys --- .../src/actions/providerApiKeuys/create.ts | 26 + .../src/actions/providerApiKeuys/destroy.ts | 27 + .../web/src/actions/providerApiKeuys/fetch.ts | 13 + apps/web/src/actions/users/fetch.ts | 13 + apps/web/src/actions/workspaces/update.ts | 2 +- apps/web/src/app/(private)/settings/page.tsx | 15 +- apps/web/src/middleware.ts | 2 +- apps/web/src/stores/currentWorkspace.ts | 10 +- apps/web/src/stores/providerApiKeys.ts | 97 +++ apps/web/src/stores/users.ts | 27 + packages/core/drizzle/0008_mean_wallop.sql | 25 + .../core/drizzle/0009_cheerful_sir_ram.sql | 2 + .../core/drizzle/0010_flippant_ma_gnuci.sql | 1 + packages/core/drizzle/0011_nosy_mystique.sql | 8 + .../core/drizzle/0012_common_fat_cobra.sql | 9 + packages/core/drizzle/meta/0008_snapshot.json | 743 ++++++++++++++++ packages/core/drizzle/meta/0009_snapshot.json | 743 ++++++++++++++++ packages/core/drizzle/meta/0010_snapshot.json | 749 +++++++++++++++++ packages/core/drizzle/meta/0011_snapshot.json | 749 +++++++++++++++++ packages/core/drizzle/meta/0012_snapshot.json | 790 ++++++++++++++++++ packages/core/drizzle/meta/_journal.json | 35 + packages/core/src/browser.ts | 5 + packages/core/src/data-access/apiKeys.ts | 4 +- packages/core/src/repositories/index.ts | 2 + .../repositories/providerApiKeysRepository.ts | 32 + .../core/src/repositories/usersRepository.ts | 26 + .../src/repositories/workspacesRepository.ts | 2 +- packages/core/src/schema/index.ts | 2 + packages/core/src/schema/models/apiKeys.ts | 4 +- .../core/src/schema/models/providerApiKeys.ts | 61 ++ packages/core/src/services/index.ts | 1 + .../src/services/providerApiKeys/create.ts | 36 + .../src/services/providerApiKeys/destroy.ts | 19 + .../src/services/providerApiKeys/index.ts | 2 + packages/web-ui/src/ds/atoms/Icons/index.tsx | 2 + .../Settings/ProviderApiKeys/index.tsx | 80 ++ .../sections/Settings/WorkspaceName/index.tsx | 2 +- .../web-ui/src/sections/Settings/index.tsx | 34 +- 38 files changed, 4381 insertions(+), 19 deletions(-) create mode 100644 apps/web/src/actions/providerApiKeuys/create.ts create mode 100644 apps/web/src/actions/providerApiKeuys/destroy.ts create mode 100644 apps/web/src/actions/providerApiKeuys/fetch.ts create mode 100644 apps/web/src/actions/users/fetch.ts create mode 100644 apps/web/src/stores/providerApiKeys.ts create mode 100644 apps/web/src/stores/users.ts create mode 100644 packages/core/drizzle/0008_mean_wallop.sql create mode 100644 packages/core/drizzle/0009_cheerful_sir_ram.sql create mode 100644 packages/core/drizzle/0010_flippant_ma_gnuci.sql create mode 100644 packages/core/drizzle/0011_nosy_mystique.sql create mode 100644 packages/core/drizzle/0012_common_fat_cobra.sql create mode 100644 packages/core/drizzle/meta/0008_snapshot.json create mode 100644 packages/core/drizzle/meta/0009_snapshot.json create mode 100644 packages/core/drizzle/meta/0010_snapshot.json create mode 100644 packages/core/drizzle/meta/0011_snapshot.json create mode 100644 packages/core/drizzle/meta/0012_snapshot.json create mode 100644 packages/core/src/repositories/providerApiKeysRepository.ts create mode 100644 packages/core/src/repositories/usersRepository.ts create mode 100644 packages/core/src/schema/models/providerApiKeys.ts create mode 100644 packages/core/src/services/providerApiKeys/create.ts create mode 100644 packages/core/src/services/providerApiKeys/destroy.ts create mode 100644 packages/core/src/services/providerApiKeys/index.ts create mode 100644 packages/web-ui/src/sections/Settings/ProviderApiKeys/index.tsx diff --git a/apps/web/src/actions/providerApiKeuys/create.ts b/apps/web/src/actions/providerApiKeuys/create.ts new file mode 100644 index 000000000..36ccc58ce --- /dev/null +++ b/apps/web/src/actions/providerApiKeuys/create.ts @@ -0,0 +1,26 @@ +'use server' + +import { createProviderApiKey } from '@latitude-data/core' +import { Providers } from '@latitude-data/core/browser' +import { z } from 'zod' + +import { authProcedure } from '../procedures' + +export const createProviderApiKeyAction = authProcedure + .createServerAction() + .input( + z.object({ + provider: z.string(), + token: z.string(), + name: z.string(), + }), + ) + .handler(async ({ input, ctx }) => { + return await createProviderApiKey({ + workspace: ctx.workspace, + provider: input.provider as Providers, + token: input.token, + name: input.name, + authorId: ctx.user.id, + }).then((r) => r.unwrap()) + }) diff --git a/apps/web/src/actions/providerApiKeuys/destroy.ts b/apps/web/src/actions/providerApiKeuys/destroy.ts new file mode 100644 index 000000000..b8e0f2365 --- /dev/null +++ b/apps/web/src/actions/providerApiKeuys/destroy.ts @@ -0,0 +1,27 @@ +'use server' + +import { + destroyProviderApiKey, + ProviderApiKeysRepository, +} from '@latitude-data/core' +import { z } from 'zod' + +import { authProcedure } from '../procedures' + +export const destroyProviderApiKeyAction = authProcedure + .createServerAction() + .input( + z.object({ + id: z.number(), + }), + ) + .handler(async ({ input, ctx }) => { + const providerApiKeysRepository = new ProviderApiKeysRepository( + ctx.workspace.id, + ) + const apiKeyProvider = await providerApiKeysRepository + .find(input.id) + .then((r) => r.unwrap()) + + return await destroyProviderApiKey(apiKeyProvider).then((r) => r.unwrap()) + }) diff --git a/apps/web/src/actions/providerApiKeuys/fetch.ts b/apps/web/src/actions/providerApiKeuys/fetch.ts new file mode 100644 index 000000000..1e97c8e65 --- /dev/null +++ b/apps/web/src/actions/providerApiKeuys/fetch.ts @@ -0,0 +1,13 @@ +'use server' + +import { ProviderApiKeysRepository } from '@latitude-data/core' + +import { authProcedure } from '../procedures' + +export const getProviderApiKeyAction = authProcedure + .createServerAction() + .handler(async ({ ctx }) => { + const providerApiKeysScope = new ProviderApiKeysRepository(ctx.workspace.id) + + return await providerApiKeysScope.findAll().then((r) => r.unwrap()) + }) diff --git a/apps/web/src/actions/users/fetch.ts b/apps/web/src/actions/users/fetch.ts new file mode 100644 index 000000000..498ba9d71 --- /dev/null +++ b/apps/web/src/actions/users/fetch.ts @@ -0,0 +1,13 @@ +'use server' + +import { UsersRepository } from '@latitude-data/core' + +import { authProcedure } from '../procedures' + +export const getUsersActions = authProcedure + .createServerAction() + .handler(async ({ ctx }) => { + const usersScope = new UsersRepository(ctx.workspace.id) + + return await usersScope.findAll().then((r) => r.unwrap()) + }) diff --git a/apps/web/src/actions/workspaces/update.ts b/apps/web/src/actions/workspaces/update.ts index 5d187085b..9f992394a 100644 --- a/apps/web/src/actions/workspaces/update.ts +++ b/apps/web/src/actions/workspaces/update.ts @@ -17,7 +17,7 @@ export const updateWorkspaceAction = authProcedure const userId = ctx.session.userId const workspacesScope = new WorkspacesRepository(userId) const workspace = await workspacesScope - .getWorkspaceById(input.workspaceId) + .find(input.workspaceId) .then((r) => r.unwrap()) const updatedWorkspace = await updateWorkspace({ diff --git a/apps/web/src/app/(private)/settings/page.tsx b/apps/web/src/app/(private)/settings/page.tsx index 9caf65731..236ed376c 100644 --- a/apps/web/src/app/(private)/settings/page.tsx +++ b/apps/web/src/app/(private)/settings/page.tsx @@ -2,9 +2,22 @@ import { Settings } from '@latitude-data/web-ui' import useCurrentWorkspace from '$/stores/currentWorkspace' +import useProviderApiKeys from '$/stores/providerApiKeys' +import useUsers from '$/stores/users' export default function SettingsPage() { const { data, update } = useCurrentWorkspace() + const { data: apiKeys, create, destroy } = useProviderApiKeys() + const { data: users } = useUsers() - return + return ( + + ) } diff --git a/apps/web/src/middleware.ts b/apps/web/src/middleware.ts index 8bf0ca80f..237e5c5d3 100644 --- a/apps/web/src/middleware.ts +++ b/apps/web/src/middleware.ts @@ -15,7 +15,7 @@ export async function middleware(request: LatitudeRequest) { return apiUnauthorized() } - const result = await unsafelyGetApiKey({ uuid: token }) + const result = await unsafelyGetApiKey({ token }) if (result.error) return apiUnauthorized() request.workspaceId = result.value.workspaceId diff --git a/apps/web/src/stores/currentWorkspace.ts b/apps/web/src/stores/currentWorkspace.ts index 9c73279fb..21650cad1 100644 --- a/apps/web/src/stores/currentWorkspace.ts +++ b/apps/web/src/stores/currentWorkspace.ts @@ -25,7 +25,15 @@ export default function useCurrentWorkspace(opts?: SWRConfiguration) { workspaceId: data!.id, name: payload.name, }) - if (error) throw error + if (error) { + toast({ + title: 'Failed to update workspace name', + description: error.message, + variant: 'destructive', + }) + + return + } toast({ title: 'Name updated to ' + payload.name, diff --git a/apps/web/src/stores/providerApiKeys.ts b/apps/web/src/stores/providerApiKeys.ts new file mode 100644 index 000000000..fc8bb65b7 --- /dev/null +++ b/apps/web/src/stores/providerApiKeys.ts @@ -0,0 +1,97 @@ +import { useCallback } from 'react' + +import { ProviderApiKey } from '@latitude-data/core' +import { Providers } from '@latitude-data/core/browser' +import { useToast } from '@latitude-data/web-ui' +import { createProviderApiKeyAction } from '$/actions/providerApiKeuys/create' +import { destroyProviderApiKeyAction } from '$/actions/providerApiKeuys/destroy' +import { getProviderApiKeyAction } from '$/actions/providerApiKeuys/fetch' +import useSWR, { SWRConfiguration } from 'swr' + +export default function useProviderApiKeys(opts?: SWRConfiguration) { + const { toast } = useToast() + const key = 'api/providerApiKeys' + const fetcher = async () => { + const [data, error] = await getProviderApiKeyAction() + if (error) { + toast({ + title: 'Error', + description: error.message, + variant: 'destructive', + }) + + return [] + } + + return data + } + const { + data = [], + mutate, + ...rest + } = useSWR(key, fetcher, opts) + const create = useCallback( + async ({ + name, + provider, + token, + }: { + name: string + provider: Providers + token: string + }) => { + const [apikey, error] = await createProviderApiKeyAction({ + provider, + token, + name, + }) + + if (error) { + toast({ + title: 'Error', + description: error.message, + variant: 'destructive', + }) + + return + } + + mutate([...data, apikey]) + + toast({ + title: 'Success', + description: 'API Key ' + apikey.name + ' created', + }) + + return apikey + }, + [data, mutate], + ) + + const destroy = useCallback( + async (id: number) => { + const [apikey, error] = await destroyProviderApiKeyAction({ id }) + if (error) { + toast({ + title: 'Error', + description: error.message, + variant: 'destructive', + }) + + return + } + + mutate(data.filter((apikey) => apikey.id !== id)) + + toast({ + title: 'Success', + description: 'API Key ' + apikey!.name + ' deleted', + }) + + return apikey! + }, + [data, mutate], + ) + + return { data, create, destroy, mutate, ...rest } +} diff --git a/apps/web/src/stores/users.ts b/apps/web/src/stores/users.ts new file mode 100644 index 000000000..ee641c2c4 --- /dev/null +++ b/apps/web/src/stores/users.ts @@ -0,0 +1,27 @@ +import { User } from '@latitude-data/core' +import { useToast } from '@latitude-data/web-ui' +import { getUsersActions } from '$/actions/users/fetch' +import useSWR, { SWRConfiguration } from 'swr' + +export default function useUsers(opts?: SWRConfiguration) { + const { toast } = useToast() + + const fetcher = async () => { + const [data, error] = await getUsersActions() + if (error) { + toast({ + title: 'Error', + description: error.message, + variant: 'destructive', + }) + + return [] + } + + return data + } + + const { data = [], ...rest } = useSWR('api/users', fetcher, opts) + + return { data, ...rest } +} diff --git a/packages/core/drizzle/0008_mean_wallop.sql b/packages/core/drizzle/0008_mean_wallop.sql new file mode 100644 index 000000000..985ac3178 --- /dev/null +++ b/packages/core/drizzle/0008_mean_wallop.sql @@ -0,0 +1,25 @@ +DO $$ BEGIN + CREATE TYPE "public"."provider" AS ENUM('openai', 'anthropic'); +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "latitude"."providerApiKeys" ( + "id" bigserial PRIMARY KEY NOT NULL, + "uuid" uuid NOT NULL, + "provider" "provider" NOT NULL, + "workspace_id" bigint NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +ALTER TABLE "latitude"."api_keys" RENAME COLUMN "uuid" TO "token";--> statement-breakpoint +ALTER TABLE "latitude"."api_keys" DROP CONSTRAINT "api_keys_uuid_unique";--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "latitude"."providerApiKeys" ADD CONSTRAINT "providerApiKeys_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "latitude"."workspaces"("id") ON DELETE no action ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +CREATE INDEX IF NOT EXISTS "provider_apikeys_workspace_id_idx" ON "latitude"."providerApiKeys" USING btree ("workspace_id");--> statement-breakpoint +ALTER TABLE "latitude"."api_keys" ADD CONSTRAINT "api_keys_token_unique" UNIQUE("token"); \ No newline at end of file diff --git a/packages/core/drizzle/0009_cheerful_sir_ram.sql b/packages/core/drizzle/0009_cheerful_sir_ram.sql new file mode 100644 index 000000000..3efc04476 --- /dev/null +++ b/packages/core/drizzle/0009_cheerful_sir_ram.sql @@ -0,0 +1,2 @@ +ALTER TABLE "latitude"."providerApiKeys" RENAME COLUMN "uuid" TO "token";--> statement-breakpoint +ALTER TABLE "latitude"."providerApiKeys" ALTER COLUMN "token" SET DATA TYPE varchar; \ No newline at end of file diff --git a/packages/core/drizzle/0010_flippant_ma_gnuci.sql b/packages/core/drizzle/0010_flippant_ma_gnuci.sql new file mode 100644 index 000000000..32e9086ef --- /dev/null +++ b/packages/core/drizzle/0010_flippant_ma_gnuci.sql @@ -0,0 +1 @@ +ALTER TABLE "latitude"."providerApiKeys" ADD COLUMN "name" varchar NOT NULL; \ No newline at end of file diff --git a/packages/core/drizzle/0011_nosy_mystique.sql b/packages/core/drizzle/0011_nosy_mystique.sql new file mode 100644 index 000000000..d2bf1e5db --- /dev/null +++ b/packages/core/drizzle/0011_nosy_mystique.sql @@ -0,0 +1,8 @@ +ALTER TABLE "latitude"."providerApiKeys" RENAME TO "provider_api_keys";--> statement-breakpoint +ALTER TABLE "latitude"."provider_api_keys" DROP CONSTRAINT "providerApiKeys_workspace_id_workspaces_id_fk"; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "latitude"."provider_api_keys" ADD CONSTRAINT "provider_api_keys_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "latitude"."workspaces"("id") ON DELETE no action ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; diff --git a/packages/core/drizzle/0012_common_fat_cobra.sql b/packages/core/drizzle/0012_common_fat_cobra.sql new file mode 100644 index 000000000..05f7a3830 --- /dev/null +++ b/packages/core/drizzle/0012_common_fat_cobra.sql @@ -0,0 +1,9 @@ +ALTER TABLE "latitude"."provider_api_keys" ADD COLUMN "author_id" text NOT NULL;--> statement-breakpoint +ALTER TABLE "latitude"."provider_api_keys" ADD COLUMN "last_used_at" timestamp;--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "latitude"."provider_api_keys" ADD CONSTRAINT "provider_api_keys_author_id_users_id_fk" FOREIGN KEY ("author_id") REFERENCES "latitude"."users"("id") ON DELETE no action ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +CREATE INDEX IF NOT EXISTS "provider_apikeys_user_id_idx" ON "latitude"."provider_api_keys" USING btree ("author_id"); \ No newline at end of file diff --git a/packages/core/drizzle/meta/0008_snapshot.json b/packages/core/drizzle/meta/0008_snapshot.json new file mode 100644 index 000000000..6dee54ced --- /dev/null +++ b/packages/core/drizzle/meta/0008_snapshot.json @@ -0,0 +1,743 @@ +{ + "id": "cdbacb2f-e215-4533-ab77-0620cd5e1d3d", + "prevId": "4a4bcd53-4c0d-4f9e-9e42-b968270f5ba8", + "version": "7", + "dialect": "postgresql", + "tables": { + "latitude.users": { + "name": "users", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "encrypted_password": { + "name": "encrypted_password", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_unique": { + "name": "users_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + } + }, + "latitude.sessions": { + "name": "sessions", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "latitude.workspaces": { + "name": "workspaces", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "creator_id": { + "name": "creator_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "workspaces_creator_id_users_id_fk": { + "name": "workspaces_creator_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "latitude.memberships": { + "name": "memberships", + "schema": "latitude", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {} + }, + "latitude.api_keys": { + "name": "api_keys", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_id_idx": { + "name": "workspace_id_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "api_keys_workspace_id_workspaces_id_fk": { + "name": "api_keys_workspace_id_workspaces_id_fk", + "tableFrom": "api_keys", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "api_keys_token_unique": { + "name": "api_keys_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + } + }, + "latitude.projects": { + "name": "projects", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_idx": { + "name": "workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "latitude.commits": { + "name": "commits", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "title": { + "name": "title", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "merged_at": { + "name": "merged_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "project_commit_order_idx": { + "name": "project_commit_order_idx", + "columns": [ + { + "expression": "merged_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "commits_project_id_projects_id_fk": { + "name": "commits_project_id_projects_id_fk", + "tableFrom": "commits", + "tableTo": "projects", + "schemaTo": "latitude", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "commits_uuid_unique": { + "name": "commits_uuid_unique", + "nullsNotDistinct": false, + "columns": [ + "uuid" + ] + } + } + }, + "latitude.document_versions": { + "name": "document_versions", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "document_uuid": { + "name": "document_uuid", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_content": { + "name": "resolved_content", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "commit_id": { + "name": "commit_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "document_uuid_commit_id_idx": { + "name": "document_uuid_commit_id_idx", + "columns": [ + { + "expression": "document_uuid", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "commit_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "document_versions_commit_id_commits_id_fk": { + "name": "document_versions_commit_id_commits_id_fk", + "tableFrom": "document_versions", + "tableTo": "commits", + "schemaTo": "latitude", + "columnsFrom": [ + "commit_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_document_uuid_commit_id": { + "name": "unique_document_uuid_commit_id", + "nullsNotDistinct": false, + "columns": [ + "document_uuid", + "commit_id" + ] + }, + "unique_path_commit_id": { + "name": "unique_path_commit_id", + "nullsNotDistinct": false, + "columns": [ + "path", + "commit_id" + ] + } + } + }, + "latitude.providerApiKeys": { + "name": "providerApiKeys", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "provider_apikeys_workspace_id_idx": { + "name": "provider_apikeys_workspace_id_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "providerApiKeys_workspace_id_workspaces_id_fk": { + "name": "providerApiKeys_workspace_id_workspaces_id_fk", + "tableFrom": "providerApiKeys", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": { + "public.provider": { + "name": "provider", + "schema": "public", + "values": [ + "openai", + "anthropic" + ] + } + }, + "schemas": { + "latitude": "latitude" + }, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/core/drizzle/meta/0009_snapshot.json b/packages/core/drizzle/meta/0009_snapshot.json new file mode 100644 index 000000000..96f20b38f --- /dev/null +++ b/packages/core/drizzle/meta/0009_snapshot.json @@ -0,0 +1,743 @@ +{ + "id": "13c98507-1f30-4774-9c89-b0ca67d08c30", + "prevId": "cdbacb2f-e215-4533-ab77-0620cd5e1d3d", + "version": "7", + "dialect": "postgresql", + "tables": { + "latitude.users": { + "name": "users", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "encrypted_password": { + "name": "encrypted_password", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_unique": { + "name": "users_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + } + }, + "latitude.sessions": { + "name": "sessions", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "latitude.workspaces": { + "name": "workspaces", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "creator_id": { + "name": "creator_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "workspaces_creator_id_users_id_fk": { + "name": "workspaces_creator_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "latitude.memberships": { + "name": "memberships", + "schema": "latitude", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {} + }, + "latitude.api_keys": { + "name": "api_keys", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_id_idx": { + "name": "workspace_id_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "api_keys_workspace_id_workspaces_id_fk": { + "name": "api_keys_workspace_id_workspaces_id_fk", + "tableFrom": "api_keys", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "api_keys_token_unique": { + "name": "api_keys_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + } + }, + "latitude.projects": { + "name": "projects", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_idx": { + "name": "workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "latitude.commits": { + "name": "commits", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "title": { + "name": "title", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "merged_at": { + "name": "merged_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "project_commit_order_idx": { + "name": "project_commit_order_idx", + "columns": [ + { + "expression": "merged_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "commits_project_id_projects_id_fk": { + "name": "commits_project_id_projects_id_fk", + "tableFrom": "commits", + "tableTo": "projects", + "schemaTo": "latitude", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "commits_uuid_unique": { + "name": "commits_uuid_unique", + "nullsNotDistinct": false, + "columns": [ + "uuid" + ] + } + } + }, + "latitude.document_versions": { + "name": "document_versions", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "document_uuid": { + "name": "document_uuid", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_content": { + "name": "resolved_content", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "commit_id": { + "name": "commit_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "document_uuid_commit_id_idx": { + "name": "document_uuid_commit_id_idx", + "columns": [ + { + "expression": "document_uuid", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "commit_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "document_versions_commit_id_commits_id_fk": { + "name": "document_versions_commit_id_commits_id_fk", + "tableFrom": "document_versions", + "tableTo": "commits", + "schemaTo": "latitude", + "columnsFrom": [ + "commit_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_document_uuid_commit_id": { + "name": "unique_document_uuid_commit_id", + "nullsNotDistinct": false, + "columns": [ + "document_uuid", + "commit_id" + ] + }, + "unique_path_commit_id": { + "name": "unique_path_commit_id", + "nullsNotDistinct": false, + "columns": [ + "path", + "commit_id" + ] + } + } + }, + "latitude.providerApiKeys": { + "name": "providerApiKeys", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "provider_apikeys_workspace_id_idx": { + "name": "provider_apikeys_workspace_id_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "providerApiKeys_workspace_id_workspaces_id_fk": { + "name": "providerApiKeys_workspace_id_workspaces_id_fk", + "tableFrom": "providerApiKeys", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": { + "public.provider": { + "name": "provider", + "schema": "public", + "values": [ + "openai", + "anthropic" + ] + } + }, + "schemas": { + "latitude": "latitude" + }, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/core/drizzle/meta/0010_snapshot.json b/packages/core/drizzle/meta/0010_snapshot.json new file mode 100644 index 000000000..dac024fc6 --- /dev/null +++ b/packages/core/drizzle/meta/0010_snapshot.json @@ -0,0 +1,749 @@ +{ + "id": "0818c405-22f1-4c44-a93c-565399ee82f8", + "prevId": "13c98507-1f30-4774-9c89-b0ca67d08c30", + "version": "7", + "dialect": "postgresql", + "tables": { + "latitude.users": { + "name": "users", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "encrypted_password": { + "name": "encrypted_password", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_unique": { + "name": "users_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + } + }, + "latitude.sessions": { + "name": "sessions", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "latitude.workspaces": { + "name": "workspaces", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "creator_id": { + "name": "creator_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "workspaces_creator_id_users_id_fk": { + "name": "workspaces_creator_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "latitude.memberships": { + "name": "memberships", + "schema": "latitude", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {} + }, + "latitude.api_keys": { + "name": "api_keys", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_id_idx": { + "name": "workspace_id_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "api_keys_workspace_id_workspaces_id_fk": { + "name": "api_keys_workspace_id_workspaces_id_fk", + "tableFrom": "api_keys", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "api_keys_token_unique": { + "name": "api_keys_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + } + }, + "latitude.projects": { + "name": "projects", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_idx": { + "name": "workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "latitude.commits": { + "name": "commits", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "title": { + "name": "title", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "merged_at": { + "name": "merged_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "project_commit_order_idx": { + "name": "project_commit_order_idx", + "columns": [ + { + "expression": "merged_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "commits_project_id_projects_id_fk": { + "name": "commits_project_id_projects_id_fk", + "tableFrom": "commits", + "tableTo": "projects", + "schemaTo": "latitude", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "commits_uuid_unique": { + "name": "commits_uuid_unique", + "nullsNotDistinct": false, + "columns": [ + "uuid" + ] + } + } + }, + "latitude.document_versions": { + "name": "document_versions", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "document_uuid": { + "name": "document_uuid", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_content": { + "name": "resolved_content", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "commit_id": { + "name": "commit_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "document_uuid_commit_id_idx": { + "name": "document_uuid_commit_id_idx", + "columns": [ + { + "expression": "document_uuid", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "commit_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "document_versions_commit_id_commits_id_fk": { + "name": "document_versions_commit_id_commits_id_fk", + "tableFrom": "document_versions", + "tableTo": "commits", + "schemaTo": "latitude", + "columnsFrom": [ + "commit_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_document_uuid_commit_id": { + "name": "unique_document_uuid_commit_id", + "nullsNotDistinct": false, + "columns": [ + "document_uuid", + "commit_id" + ] + }, + "unique_path_commit_id": { + "name": "unique_path_commit_id", + "nullsNotDistinct": false, + "columns": [ + "path", + "commit_id" + ] + } + } + }, + "latitude.providerApiKeys": { + "name": "providerApiKeys", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "provider_apikeys_workspace_id_idx": { + "name": "provider_apikeys_workspace_id_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "providerApiKeys_workspace_id_workspaces_id_fk": { + "name": "providerApiKeys_workspace_id_workspaces_id_fk", + "tableFrom": "providerApiKeys", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": { + "public.provider": { + "name": "provider", + "schema": "public", + "values": [ + "openai", + "anthropic" + ] + } + }, + "schemas": { + "latitude": "latitude" + }, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/core/drizzle/meta/0011_snapshot.json b/packages/core/drizzle/meta/0011_snapshot.json new file mode 100644 index 000000000..f219bc03a --- /dev/null +++ b/packages/core/drizzle/meta/0011_snapshot.json @@ -0,0 +1,749 @@ +{ + "id": "4c18f752-c3fb-411c-8310-2cde1410da67", + "prevId": "0818c405-22f1-4c44-a93c-565399ee82f8", + "version": "7", + "dialect": "postgresql", + "tables": { + "latitude.users": { + "name": "users", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "encrypted_password": { + "name": "encrypted_password", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_unique": { + "name": "users_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + } + }, + "latitude.sessions": { + "name": "sessions", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "latitude.workspaces": { + "name": "workspaces", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "creator_id": { + "name": "creator_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "workspaces_creator_id_users_id_fk": { + "name": "workspaces_creator_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "latitude.memberships": { + "name": "memberships", + "schema": "latitude", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {} + }, + "latitude.api_keys": { + "name": "api_keys", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_id_idx": { + "name": "workspace_id_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "api_keys_workspace_id_workspaces_id_fk": { + "name": "api_keys_workspace_id_workspaces_id_fk", + "tableFrom": "api_keys", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "api_keys_token_unique": { + "name": "api_keys_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + } + }, + "latitude.projects": { + "name": "projects", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_idx": { + "name": "workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "latitude.commits": { + "name": "commits", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "title": { + "name": "title", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "merged_at": { + "name": "merged_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "project_commit_order_idx": { + "name": "project_commit_order_idx", + "columns": [ + { + "expression": "merged_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "commits_project_id_projects_id_fk": { + "name": "commits_project_id_projects_id_fk", + "tableFrom": "commits", + "tableTo": "projects", + "schemaTo": "latitude", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "commits_uuid_unique": { + "name": "commits_uuid_unique", + "nullsNotDistinct": false, + "columns": [ + "uuid" + ] + } + } + }, + "latitude.document_versions": { + "name": "document_versions", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "document_uuid": { + "name": "document_uuid", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_content": { + "name": "resolved_content", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "commit_id": { + "name": "commit_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "document_uuid_commit_id_idx": { + "name": "document_uuid_commit_id_idx", + "columns": [ + { + "expression": "document_uuid", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "commit_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "document_versions_commit_id_commits_id_fk": { + "name": "document_versions_commit_id_commits_id_fk", + "tableFrom": "document_versions", + "tableTo": "commits", + "schemaTo": "latitude", + "columnsFrom": [ + "commit_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_document_uuid_commit_id": { + "name": "unique_document_uuid_commit_id", + "nullsNotDistinct": false, + "columns": [ + "document_uuid", + "commit_id" + ] + }, + "unique_path_commit_id": { + "name": "unique_path_commit_id", + "nullsNotDistinct": false, + "columns": [ + "path", + "commit_id" + ] + } + } + }, + "latitude.provider_api_keys": { + "name": "provider_api_keys", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "provider_apikeys_workspace_id_idx": { + "name": "provider_apikeys_workspace_id_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "provider_api_keys_workspace_id_workspaces_id_fk": { + "name": "provider_api_keys_workspace_id_workspaces_id_fk", + "tableFrom": "provider_api_keys", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": { + "public.provider": { + "name": "provider", + "schema": "public", + "values": [ + "openai", + "anthropic" + ] + } + }, + "schemas": { + "latitude": "latitude" + }, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/core/drizzle/meta/0012_snapshot.json b/packages/core/drizzle/meta/0012_snapshot.json new file mode 100644 index 000000000..53ad96e46 --- /dev/null +++ b/packages/core/drizzle/meta/0012_snapshot.json @@ -0,0 +1,790 @@ +{ + "id": "c3ab8fd4-5d3d-4712-b67d-8d2c696033c8", + "prevId": "4c18f752-c3fb-411c-8310-2cde1410da67", + "version": "7", + "dialect": "postgresql", + "tables": { + "latitude.users": { + "name": "users", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "encrypted_password": { + "name": "encrypted_password", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_unique": { + "name": "users_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + } + }, + "latitude.sessions": { + "name": "sessions", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "latitude.workspaces": { + "name": "workspaces", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "creator_id": { + "name": "creator_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "workspaces_creator_id_users_id_fk": { + "name": "workspaces_creator_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "latitude.memberships": { + "name": "memberships", + "schema": "latitude", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {} + }, + "latitude.api_keys": { + "name": "api_keys", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_id_idx": { + "name": "workspace_id_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "api_keys_workspace_id_workspaces_id_fk": { + "name": "api_keys_workspace_id_workspaces_id_fk", + "tableFrom": "api_keys", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "api_keys_token_unique": { + "name": "api_keys_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + } + }, + "latitude.projects": { + "name": "projects", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_idx": { + "name": "workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "latitude.commits": { + "name": "commits", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "title": { + "name": "title", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "merged_at": { + "name": "merged_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "project_commit_order_idx": { + "name": "project_commit_order_idx", + "columns": [ + { + "expression": "merged_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "commits_project_id_projects_id_fk": { + "name": "commits_project_id_projects_id_fk", + "tableFrom": "commits", + "tableTo": "projects", + "schemaTo": "latitude", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "commits_uuid_unique": { + "name": "commits_uuid_unique", + "nullsNotDistinct": false, + "columns": [ + "uuid" + ] + } + } + }, + "latitude.document_versions": { + "name": "document_versions", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "document_uuid": { + "name": "document_uuid", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_content": { + "name": "resolved_content", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "commit_id": { + "name": "commit_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "document_uuid_commit_id_idx": { + "name": "document_uuid_commit_id_idx", + "columns": [ + { + "expression": "document_uuid", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "commit_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "document_versions_commit_id_commits_id_fk": { + "name": "document_versions_commit_id_commits_id_fk", + "tableFrom": "document_versions", + "tableTo": "commits", + "schemaTo": "latitude", + "columnsFrom": [ + "commit_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_document_uuid_commit_id": { + "name": "unique_document_uuid_commit_id", + "nullsNotDistinct": false, + "columns": [ + "document_uuid", + "commit_id" + ] + }, + "unique_path_commit_id": { + "name": "unique_path_commit_id", + "nullsNotDistinct": false, + "columns": [ + "path", + "commit_id" + ] + } + } + }, + "latitude.provider_api_keys": { + "name": "provider_api_keys", + "schema": "latitude", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "provider_apikeys_workspace_id_idx": { + "name": "provider_apikeys_workspace_id_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "provider_apikeys_user_id_idx": { + "name": "provider_apikeys_user_id_idx", + "columns": [ + { + "expression": "author_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "provider_api_keys_author_id_users_id_fk": { + "name": "provider_api_keys_author_id_users_id_fk", + "tableFrom": "provider_api_keys", + "tableTo": "users", + "schemaTo": "latitude", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "provider_api_keys_workspace_id_workspaces_id_fk": { + "name": "provider_api_keys_workspace_id_workspaces_id_fk", + "tableFrom": "provider_api_keys", + "tableTo": "workspaces", + "schemaTo": "latitude", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": { + "public.provider": { + "name": "provider", + "schema": "public", + "values": [ + "openai", + "anthropic" + ] + } + }, + "schemas": { + "latitude": "latitude" + }, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/core/drizzle/meta/_journal.json b/packages/core/drizzle/meta/_journal.json index 4d991f326..0cfc0a5b3 100644 --- a/packages/core/drizzle/meta/_journal.json +++ b/packages/core/drizzle/meta/_journal.json @@ -57,6 +57,41 @@ "when": 1721831263108, "tag": "0007_secret_may_parker", "breakpoints": true + }, + { + "idx": 8, + "version": "7", + "when": 1722009396473, + "tag": "0008_mean_wallop", + "breakpoints": true + }, + { + "idx": 9, + "version": "7", + "when": 1722012262737, + "tag": "0009_cheerful_sir_ram", + "breakpoints": true + }, + { + "idx": 10, + "version": "7", + "when": 1722012528513, + "tag": "0010_flippant_ma_gnuci", + "breakpoints": true + }, + { + "idx": 11, + "version": "7", + "when": 1722012608957, + "tag": "0011_nosy_mystique", + "breakpoints": true + }, + { + "idx": 12, + "version": "7", + "when": 1722013988045, + "tag": "0012_common_fat_cobra", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/core/src/browser.ts b/packages/core/src/browser.ts index f87cf0102..b1ac99f30 100644 --- a/packages/core/src/browser.ts +++ b/packages/core/src/browser.ts @@ -1 +1,6 @@ export * from './constants' + +export enum Providers { + OpenAI = 'openai', + Anthropic = 'anthropic', +} diff --git a/packages/core/src/data-access/apiKeys.ts b/packages/core/src/data-access/apiKeys.ts index 1c4984123..71b6045c7 100644 --- a/packages/core/src/data-access/apiKeys.ts +++ b/packages/core/src/data-access/apiKeys.ts @@ -4,11 +4,11 @@ import { apiKeys } from '$core/schema' import { eq } from 'drizzle-orm' export async function unsafelyGetApiKey( - { uuid }: { uuid: string }, + { token }: { token: string }, db = database, ) { const apiKey = await db.query.apiKeys.findFirst({ - where: eq(apiKeys.uuid, uuid), + where: eq(apiKeys.token, token), }) if (!apiKey) return Result.error(new NotFoundError('API key not found')) diff --git a/packages/core/src/repositories/index.ts b/packages/core/src/repositories/index.ts index b31484364..1621031b2 100644 --- a/packages/core/src/repositories/index.ts +++ b/packages/core/src/repositories/index.ts @@ -2,3 +2,5 @@ export * from './commitsRepository' export * from './projectsRepository' export * from './documentVersionsRepository' export * from './workspacesRepository' +export * from './providerApiKeysRepository' +export * from './usersRepository' diff --git a/packages/core/src/repositories/providerApiKeysRepository.ts b/packages/core/src/repositories/providerApiKeysRepository.ts new file mode 100644 index 000000000..0a1b9e5a3 --- /dev/null +++ b/packages/core/src/repositories/providerApiKeysRepository.ts @@ -0,0 +1,32 @@ +import { NotFoundError, Result } from '$core/lib' +import { providerApiKeys, workspaces } from '$core/schema' +import { eq, getTableColumns } from 'drizzle-orm' + +import Repository from './repository' + +export class ProviderApiKeysRepository extends Repository { + get scope() { + return this.db + .select(getTableColumns(providerApiKeys)) + .from(providerApiKeys) + .innerJoin(workspaces, eq(workspaces.id, providerApiKeys.workspaceId)) + .as('providerApiKeysScope') + } + + async find(id: number) { + const result = await this.db + .select() + .from(this.scope) + .where(eq(this.scope.id, id)) + if (!result.length) { + return Result.error(new NotFoundError('ProviderApiKey not found')) + } + + return Result.ok(result[0]!) + } + + async findAll() { + const result = await this.db.select().from(this.scope) + return Result.ok(result) + } +} diff --git a/packages/core/src/repositories/usersRepository.ts b/packages/core/src/repositories/usersRepository.ts new file mode 100644 index 000000000..919f8fc03 --- /dev/null +++ b/packages/core/src/repositories/usersRepository.ts @@ -0,0 +1,26 @@ +import { Result } from '$core/lib' +import { memberships, users } from '$core/schema' +import { and, eq, getTableColumns } from 'drizzle-orm' + +import Repository from './repository' + +export class UsersRepository extends Repository { + get scope() { + return this.db + .select(getTableColumns(users)) + .from(users) + .innerJoin( + memberships, + and( + eq(memberships.userId, users.id), + eq(memberships.workspaceId, this.workspaceId), + ), + ) + .as('usersScope') + } + + async findAll() { + const result = await this.db.select().from(this.scope) + return Result.ok(result) + } +} diff --git a/packages/core/src/repositories/workspacesRepository.ts b/packages/core/src/repositories/workspacesRepository.ts index 954207b91..850d1f5af 100644 --- a/packages/core/src/repositories/workspacesRepository.ts +++ b/packages/core/src/repositories/workspacesRepository.ts @@ -21,7 +21,7 @@ export class WorkspacesRepository { .as('workspacesScope') } - async getWorkspaceById(workspaceId: number) { + async find(workspaceId: number) { const result = await this.db .select() .from(this.scope) diff --git a/packages/core/src/schema/index.ts b/packages/core/src/schema/index.ts index 84189c8aa..d94aa4550 100644 --- a/packages/core/src/schema/index.ts +++ b/packages/core/src/schema/index.ts @@ -11,3 +11,5 @@ export * from './models/apiKeys' export * from './models/projects' export * from './models/commits' export * from './models/documentVersions' + +export * from './models/providerApiKeys' diff --git a/packages/core/src/schema/models/apiKeys.ts b/packages/core/src/schema/models/apiKeys.ts index e08a91e53..b364c5f43 100644 --- a/packages/core/src/schema/models/apiKeys.ts +++ b/packages/core/src/schema/models/apiKeys.ts @@ -16,7 +16,7 @@ export const apiKeys = latitudeSchema.table( 'api_keys', { id: bigserial('id', { mode: 'number' }).notNull().primaryKey(), - uuid: uuid('uuid') + token: uuid('token') .notNull() .unique() .$defaultFn(() => crypto.randomUUID()), @@ -24,8 +24,8 @@ export const apiKeys = latitudeSchema.table( .notNull() .references(() => workspaces.id), name: varchar('name', { length: 256 }), - ...timestamps(), deletedAt: timestamp('deleted_at'), + ...timestamps(), }, (table) => ({ workspaceIdIdx: index('workspace_id_idx').on(table.workspaceId), diff --git a/packages/core/src/schema/models/providerApiKeys.ts b/packages/core/src/schema/models/providerApiKeys.ts new file mode 100644 index 000000000..61f2f4bd6 --- /dev/null +++ b/packages/core/src/schema/models/providerApiKeys.ts @@ -0,0 +1,61 @@ +import { Providers } from '$core/browser' +import { InferSelectModel, relations } from 'drizzle-orm' +import { + bigint, + bigserial, + index, + pgEnum, + text, + timestamp, + varchar, +} from 'drizzle-orm/pg-core' + +import { latitudeSchema } from '../db-schema' +import { timestamps } from '../schemaHelpers' +import { users } from './users' +import { workspaces } from './workspaces' + +export const providersEnum = pgEnum('provider', [ + Providers.OpenAI, + Providers.Anthropic, +]) + +export const providerApiKeys = latitudeSchema.table( + 'provider_api_keys', + { + id: bigserial('id', { mode: 'number' }).notNull().primaryKey(), + name: varchar('name').notNull(), + token: varchar('token').notNull(), + provider: providersEnum('provider').notNull(), + authorId: text('author_id') + .notNull() + .references(() => users.id), + workspaceId: bigint('workspace_id', { mode: 'number' }) + .notNull() + .references(() => workspaces.id), + lastUsedAt: timestamp('last_used_at'), + ...timestamps(), + }, + (table) => ({ + workspaceIdIdx: index('provider_apikeys_workspace_id_idx').on( + table.workspaceId, + ), + userIdIdx: index('provider_apikeys_user_id_idx').on(table.authorId), + }), +) + +export const providerApiKeysRelations = relations( + providerApiKeys, + ({ one }) => ({ + author: one(users, { + fields: [providerApiKeys.authorId], + references: [users.id], + }), + workspace: one(workspaces, { + fields: [providerApiKeys.workspaceId], + references: [workspaces.id], + }), + }), +) + +export type ProviderApiKey = InferSelectModel diff --git a/packages/core/src/services/index.ts b/packages/core/src/services/index.ts index 75272032f..13ef50b78 100644 --- a/packages/core/src/services/index.ts +++ b/packages/core/src/services/index.ts @@ -4,3 +4,4 @@ export * from './documents' export * from './commits' export * from './projects' export * from './workspaces' +export * from './providerApiKeys' diff --git a/packages/core/src/services/providerApiKeys/create.ts b/packages/core/src/services/providerApiKeys/create.ts new file mode 100644 index 000000000..a5e3670a3 --- /dev/null +++ b/packages/core/src/services/providerApiKeys/create.ts @@ -0,0 +1,36 @@ +import { Providers } from '$core/browser' +import { database } from '$core/client' +import { Result, Transaction } from '$core/lib' +import { providerApiKeys, Workspace } from '$core/schema' + +export function createProviderApiKey( + { + workspace, + provider, + token, + name, + authorId, + }: { + workspace: Partial + provider: Providers + token: string + name: string + authorId: string + }, + db = database, +) { + return Transaction.call(async (tx) => { + const result = await tx + .insert(providerApiKeys) + .values({ + workspaceId: workspace.id!, + provider, + token, + name, + authorId, + }) + .returning() + + return Result.ok(result[0]!) + }, db) +} diff --git a/packages/core/src/services/providerApiKeys/destroy.ts b/packages/core/src/services/providerApiKeys/destroy.ts new file mode 100644 index 000000000..d753fd9ec --- /dev/null +++ b/packages/core/src/services/providerApiKeys/destroy.ts @@ -0,0 +1,19 @@ +import { database } from '$core/client' +import { Result, Transaction } from '$core/lib' +import { ProviderApiKey, providerApiKeys } from '$core/schema' +import { eq } from 'drizzle-orm' + +export function destroyProviderApiKey( + providerApiKey: ProviderApiKey, + db = database, +) { + return Transaction.call(async (tx) => { + const result = await tx + .delete(providerApiKeys) + .where(eq(providerApiKeys.id, providerApiKey.id)) + .returning() + const deleted = result[0] + + return Result.ok(deleted) + }, db) +} diff --git a/packages/core/src/services/providerApiKeys/index.ts b/packages/core/src/services/providerApiKeys/index.ts new file mode 100644 index 000000000..42f1ddcbf --- /dev/null +++ b/packages/core/src/services/providerApiKeys/index.ts @@ -0,0 +1,2 @@ +export * from './create' +export * from './destroy' diff --git a/packages/web-ui/src/ds/atoms/Icons/index.tsx b/packages/web-ui/src/ds/atoms/Icons/index.tsx index 9a69b33b3..22c619d9f 100644 --- a/packages/web-ui/src/ds/atoms/Icons/index.tsx +++ b/packages/web-ui/src/ds/atoms/Icons/index.tsx @@ -6,6 +6,7 @@ import { File, FolderClosed, FolderOpen, + Trash, type LucideIcon, } from 'lucide-react' @@ -30,4 +31,5 @@ export const Icons = { folderOpen: FolderOpen, clipboard: Copy, ellipsisVertical: EllipsisVertical, + trash: Trash, } diff --git a/packages/web-ui/src/sections/Settings/ProviderApiKeys/index.tsx b/packages/web-ui/src/sections/Settings/ProviderApiKeys/index.tsx new file mode 100644 index 000000000..9f9a3a290 --- /dev/null +++ b/packages/web-ui/src/sections/Settings/ProviderApiKeys/index.tsx @@ -0,0 +1,80 @@ +import { ProviderApiKey, User } from '@latitude-data/core' +import { Providers } from '@latitude-data/core/browser' +import { Button, Icons, Text } from '$ui/ds/atoms' +import { defaultGenerateNodeUuid } from '$ui/sections/Document/Sidebar/Files/useTree' + +export default function ProviderApiKeys({ + apiKeys, + users, + createApiKey, + destroyApiKey, +}: { + apiKeys: ProviderApiKey[] + users: User[] + createApiKey: (payload: { + provider: Providers + token: string + name: string + }) => Promise + destroyApiKey: (id: number) => Promise +}) { + const findUser = (id: string) => users.find((u) => u.id === id) + return ( +
+
+ LLM API Keys + +
+
+ + + {apiKeys.map((apiKey) => ( + + + + + + + + + + ))} + +
+ {apiKey.name} + + {apiKey.provider} + + {apiKey.token} + + {apiKey.createdAt.toDateString()} + + + {apiKey.lastUsedAt?.toISOString() || 'never'} + + + {findUser(apiKey.authorId)?.name} + + +
+
+
+ ) +} diff --git a/packages/web-ui/src/sections/Settings/WorkspaceName/index.tsx b/packages/web-ui/src/sections/Settings/WorkspaceName/index.tsx index ce69a3bf5..1ad407efe 100644 --- a/packages/web-ui/src/sections/Settings/WorkspaceName/index.tsx +++ b/packages/web-ui/src/sections/Settings/WorkspaceName/index.tsx @@ -10,7 +10,7 @@ export default function WorkspaceName({ update, }: { workspace: SessionWorkspace - update: (payload: { name: string }) => Promise + update: (payload: { name: string }) => Promise }) { const onChange = async (ev: React.ChangeEvent) => { const name = ev.target.value diff --git a/packages/web-ui/src/sections/Settings/index.tsx b/packages/web-ui/src/sections/Settings/index.tsx index 1f18b72c7..104e9e634 100644 --- a/packages/web-ui/src/sections/Settings/index.tsx +++ b/packages/web-ui/src/sections/Settings/index.tsx @@ -1,25 +1,41 @@ -import { Workspace } from '@latitude-data/core' +import { ProviderApiKey, User, Workspace } from '@latitude-data/core' +import { Providers } from '@latitude-data/core/browser' import { SessionWorkspace } from '$ui/providers' +import ProviderApiKeys from './ProviderApiKeys' import WorkspaceName from './WorkspaceName' -function ProviderApiKeys() { - return null -} - -// TODO: Prop drilling of actions can become unwieldy. Can be avoided with context or zustand stores. +// TODO: Prop drilling of actions can become unwieldy. Can be avoided with +// context or zustand stores. export default function Settings({ workspace, updateWorkspace, + users, + apiKeys, + createApiKey, + destroyApiKey, }: { workspace: SessionWorkspace - updateWorkspace: (payload: { name: string }) => Promise + updateWorkspace: (payload: { name: string }) => Promise + users: User[] + apiKeys: ProviderApiKey[] + createApiKey: (payload: { + name: string + provider: Providers + token: string + }) => Promise + destroyApiKey: (id: number) => Promise }) { return (
-
+
- +
)