From 450b5f67ecc89e71a7f0cf9c71ea3edccb500e53 Mon Sep 17 00:00:00 2001 From: marselkhisamov Date: Mon, 3 Jun 2024 17:42:11 +0400 Subject: [PATCH 1/2] feat(verity): db schema and public api enpoind for versions --- .gitignore | 2 + apps/web/app/api/deps/route.ts | 5 ++ apps/web/app/api/hello/route.ts | 3 -- libs/deps-api/.eslintrc.json | 18 +++++++ libs/deps-api/README.md | 7 +++ libs/deps-api/project.json | 9 ++++ libs/deps-api/src/lib/deps-api.ts | 51 +++++++++++++++++++ libs/deps-api/src/server.ts | 1 + libs/deps-api/tsconfig.json | 17 +++++++ libs/deps-api/tsconfig.lib.json | 25 +++++++++ libs/utils/src/lib/utils.ts | 5 ++ .../20240603122534_deps_tables/migration.sql | 46 +++++++++++++++++ prisma/schema.prisma | 30 +++++++++++ tsconfig.base.json | 1 + 14 files changed, 217 insertions(+), 3 deletions(-) create mode 100644 apps/web/app/api/deps/route.ts delete mode 100644 apps/web/app/api/hello/route.ts create mode 100644 libs/deps-api/.eslintrc.json create mode 100644 libs/deps-api/README.md create mode 100644 libs/deps-api/project.json create mode 100644 libs/deps-api/src/lib/deps-api.ts create mode 100644 libs/deps-api/src/server.ts create mode 100644 libs/deps-api/tsconfig.json create mode 100644 libs/deps-api/tsconfig.lib.json create mode 100644 prisma/migrations/20240603122534_deps_tables/migration.sql diff --git a/.gitignore b/.gitignore index 89d58ef..d5ff783 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,8 @@ Thumbs.db .nx/cache +.env + # Next.js .next out \ No newline at end of file diff --git a/apps/web/app/api/deps/route.ts b/apps/web/app/api/deps/route.ts new file mode 100644 index 0000000..4c80dc0 --- /dev/null +++ b/apps/web/app/api/deps/route.ts @@ -0,0 +1,5 @@ +import { getAppDepsHandler } from '@verity/deps-api'; + +export async function GET(request: Request) { + return getAppDepsHandler(request); +} diff --git a/apps/web/app/api/hello/route.ts b/apps/web/app/api/hello/route.ts deleted file mode 100644 index de70bac..0000000 --- a/apps/web/app/api/hello/route.ts +++ /dev/null @@ -1,3 +0,0 @@ -export async function GET(request: Request) { - return new Response('Hello, from API!'); -} diff --git a/libs/deps-api/.eslintrc.json b/libs/deps-api/.eslintrc.json new file mode 100644 index 0000000..a39ac5d --- /dev/null +++ b/libs/deps-api/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["plugin:@nx/react", "../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/deps-api/README.md b/libs/deps-api/README.md new file mode 100644 index 0000000..5c30a0d --- /dev/null +++ b/libs/deps-api/README.md @@ -0,0 +1,7 @@ +# deps-api + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test api` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/deps-api/project.json b/libs/deps-api/project.json new file mode 100644 index 0000000..7b34083 --- /dev/null +++ b/libs/deps-api/project.json @@ -0,0 +1,9 @@ +{ + "name": "deps-api", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/api/src", + "projectType": "library", + "tags": [], + "// targets": "to see all targets run: nx show project api --web", + "targets": {} +} diff --git a/libs/deps-api/src/lib/deps-api.ts b/libs/deps-api/src/lib/deps-api.ts new file mode 100644 index 0000000..9022f44 --- /dev/null +++ b/libs/deps-api/src/lib/deps-api.ts @@ -0,0 +1,51 @@ +import { PrismaClient } from '@prisma/client'; + +import { getQueryParams } from '@verity/utils'; + +const prisma = new PrismaClient(); + +export const getAppDepsHandler = async (request: Request) => { + const { app, version } = getQueryParams(request); + + if (!app || !version) { + return new Response('app and version params are required', { status: 400 }); + } + + const rawAppVersion = await prisma.appVersion.findFirst({ + where: { + appId: app, + value: version, + }, + select: { + dependencies: { + select: { + dependencyAppVersion: { + select: { + value: true, + appId: true, + }, + }, + }, + }, + }, + }); + + if (!rawAppVersion) { + return new Response('app version not found', { status: 404 }); + } + + const dependencies = rawAppVersion.dependencies.reduce((acc, dep) => { + const appId = dep.dependencyAppVersion?.appId; + + if (!appId) { + return acc; + } else { + return { + ...acc, + [appId]: dep.dependencyAppVersion?.value, + }; + } + }, {}); + + return new Response(JSON.stringify(dependencies), { status: 200 }); +}; diff --git a/libs/deps-api/src/server.ts b/libs/deps-api/src/server.ts new file mode 100644 index 0000000..e9aeb2a --- /dev/null +++ b/libs/deps-api/src/server.ts @@ -0,0 +1 @@ +export * from './lib/deps-api'; diff --git a/libs/deps-api/tsconfig.json b/libs/deps-api/tsconfig.json new file mode 100644 index 0000000..95cfeb2 --- /dev/null +++ b/libs/deps-api/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ], + "extends": "../../tsconfig.base.json" +} diff --git a/libs/deps-api/tsconfig.lib.json b/libs/deps-api/tsconfig.lib.json new file mode 100644 index 0000000..08e579b --- /dev/null +++ b/libs/deps-api/tsconfig.lib.json @@ -0,0 +1,25 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": [ + "node", + "@nx/react/typings/cssmodule.d.ts", + "@nx/react/typings/image.d.ts", + "next", + "@nx/next/typings/image.d.ts" + ] + }, + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.jsx", + "src/**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/libs/utils/src/lib/utils.ts b/libs/utils/src/lib/utils.ts index 2819a83..adf113c 100644 --- a/libs/utils/src/lib/utils.ts +++ b/libs/utils/src/lib/utils.ts @@ -4,3 +4,8 @@ import { twMerge } from 'tailwind-merge'; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } + +export function getQueryParams(request: Request): Record { + const url = new URL(request.url); + return Object.fromEntries(url.searchParams.entries()); +} diff --git a/prisma/migrations/20240603122534_deps_tables/migration.sql b/prisma/migrations/20240603122534_deps_tables/migration.sql new file mode 100644 index 0000000..d9f6505 --- /dev/null +++ b/prisma/migrations/20240603122534_deps_tables/migration.sql @@ -0,0 +1,46 @@ +-- CreateTable +CREATE TABLE "App" ( + "id" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "App_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "AppVersion" ( + "id" SERIAL NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "value" TEXT NOT NULL, + "builtAt" TIMESTAMP(3), + "appId" TEXT NOT NULL, + + CONSTRAINT "AppVersion_pkey" PRIMARY KEY ("appId","value") +); + +-- CreateTable +CREATE TABLE "AppVersionDependency" ( + "id" SERIAL NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dependantAppVersionId" INTEGER NOT NULL, + "dependencyAppVersionId" INTEGER NOT NULL, + + CONSTRAINT "AppVersionDependency_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "App_id_key" ON "App"("id"); + +-- CreateIndex +CREATE UNIQUE INDEX "AppVersion_id_key" ON "AppVersion"("id"); + +-- CreateIndex +CREATE UNIQUE INDEX "AppVersionDependency_id_key" ON "AppVersionDependency"("id"); + +-- AddForeignKey +ALTER TABLE "AppVersion" ADD CONSTRAINT "AppVersion_appId_fkey" FOREIGN KEY ("appId") REFERENCES "App"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "AppVersionDependency" ADD CONSTRAINT "AppVersionDependency_dependantAppVersionId_fkey" FOREIGN KEY ("dependantAppVersionId") REFERENCES "AppVersion"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "AppVersionDependency" ADD CONSTRAINT "AppVersionDependency_dependencyAppVersionId_fkey" FOREIGN KEY ("dependencyAppVersionId") REFERENCES "AppVersion"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 6debc4c..8ebefab 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -76,3 +76,33 @@ model Authenticator { @@id([userId, credentialID]) } + +model App { + id String @id @unique + createdAt DateTime @default(now()) + versions AppVersion[] +} + +model AppVersion { + id Int @unique @default(autoincrement()) + createdAt DateTime @default(now()) + value String + builtAt DateTime? + appId String + dependencies AppVersionDependency[] @relation("AppVersionDependency") + dependsOn AppVersionDependency[] @relation("AppVersionDependsOn") + + app App @relation(fields: [appId], references: [id]) + + @@id([appId, value]) +} + +model AppVersionDependency { + id Int @id @unique @default(autoincrement()) + createdAt DateTime @default(now()) + dependantAppVersionId Int + dependencyAppVersionId Int + + dependantAppVersion AppVersion? @relation("AppVersionDependency", fields: [dependantAppVersionId], references: [id]) + dependencyAppVersion AppVersion? @relation("AppVersionDependsOn", fields: [dependencyAppVersionId], references: [id]) +} diff --git a/tsconfig.base.json b/tsconfig.base.json index 669fee5..d604da3 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -17,6 +17,7 @@ "paths": { "@verity/auth": ["libs/auth/src/index.ts"], "@verity/auth/server": ["libs/auth/src/server.ts"], + "@verity/deps-api": ["libs/deps-api/src/server.ts"], "@verity/ui": ["libs/ui/src/index.ts"], "@verity/ui/*": ["libs/ui/src/lib/*"], "@verity/ui/server": ["libs/ui/src/server.ts"], From 2ebc52207df37bef98be74da74034dde0f7f4c52 Mon Sep 17 00:00:00 2001 From: marselkhisamov Date: Mon, 3 Jun 2024 19:10:12 +0400 Subject: [PATCH 2/2] feat(verity): singleton prisma client, review issues --- apps/web/app/api/deps/route.ts | 8 ++-- libs/auth/src/lib/auth.ts | 3 +- libs/deps-api/src/lib/deps-api.ts | 34 ++++++-------- libs/prisma/.eslintrc.json | 18 ++++++++ libs/prisma/README.md | 7 +++ libs/prisma/project.json | 9 ++++ libs/prisma/src/index.ts | 1 + libs/prisma/src/lib/prisma-client.ts | 15 ++++++ libs/prisma/tsconfig.json | 17 +++++++ libs/prisma/tsconfig.lib.json | 25 ++++++++++ libs/utils/src/lib/utils.ts | 5 -- .../20240603122534_deps_tables/migration.sql | 46 ------------------- .../20240603152308_deps_tables/migration.sql | 46 +++++++++++++++++++ prisma/schema.prisma | 14 +++--- tsconfig.base.json | 1 + 15 files changed, 166 insertions(+), 83 deletions(-) create mode 100644 libs/prisma/.eslintrc.json create mode 100644 libs/prisma/README.md create mode 100644 libs/prisma/project.json create mode 100644 libs/prisma/src/index.ts create mode 100644 libs/prisma/src/lib/prisma-client.ts create mode 100644 libs/prisma/tsconfig.json create mode 100644 libs/prisma/tsconfig.lib.json delete mode 100644 prisma/migrations/20240603122534_deps_tables/migration.sql create mode 100644 prisma/migrations/20240603152308_deps_tables/migration.sql diff --git a/apps/web/app/api/deps/route.ts b/apps/web/app/api/deps/route.ts index 4c80dc0..afa5310 100644 --- a/apps/web/app/api/deps/route.ts +++ b/apps/web/app/api/deps/route.ts @@ -1,5 +1,7 @@ -import { getAppDepsHandler } from '@verity/deps-api'; +import { NextRequest } from 'next/server'; -export async function GET(request: Request) { - return getAppDepsHandler(request); +import { getApplicationDependencies } from '@verity/deps-api'; + +export async function GET(request: NextRequest) { + return getApplicationDependencies(request); } diff --git a/libs/auth/src/lib/auth.ts b/libs/auth/src/lib/auth.ts index fd8ab72..923291c 100644 --- a/libs/auth/src/lib/auth.ts +++ b/libs/auth/src/lib/auth.ts @@ -2,9 +2,8 @@ import NextAuth from 'next-auth'; import Keycloak from 'next-auth/providers/keycloak'; import { PrismaAdapter } from '@auth/prisma-adapter'; -import { PrismaClient } from '@prisma/client'; -const prisma = new PrismaClient(); +import { prisma } from '@verity/prisma'; export const { handlers, signIn, signOut, auth } = NextAuth({ adapter: PrismaAdapter(prisma), diff --git a/libs/deps-api/src/lib/deps-api.ts b/libs/deps-api/src/lib/deps-api.ts index 9022f44..19e653e 100644 --- a/libs/deps-api/src/lib/deps-api.ts +++ b/libs/deps-api/src/lib/deps-api.ts @@ -1,17 +1,16 @@ -import { PrismaClient } from '@prisma/client'; +import { NextRequest, NextResponse } from 'next/server'; -import { getQueryParams } from '@verity/utils'; +import { prisma } from '@verity/prisma'; -const prisma = new PrismaClient(); - -export const getAppDepsHandler = async (request: Request) => { - const { app, version } = getQueryParams(request); +export const getApplicationDependencies = async (request: NextRequest) => { + const app = request.nextUrl.searchParams.get('app'); + const version = request.nextUrl.searchParams.get('version'); if (!app || !version) { return new Response('app and version params are required', { status: 400 }); } - const rawAppVersion = await prisma.appVersion.findFirst({ + const rawAppVersion = await prisma.version.findFirst({ where: { appId: app, value: version, @@ -34,18 +33,13 @@ export const getAppDepsHandler = async (request: Request) => { return new Response('app version not found', { status: 404 }); } - const dependencies = rawAppVersion.dependencies.reduce((acc, dep) => { - const appId = dep.dependencyAppVersion?.appId; - - if (!appId) { - return acc; - } else { - return { - ...acc, - [appId]: dep.dependencyAppVersion?.value, - }; - } - }, {}); + const dependencies = rawAppVersion.dependencies.reduce( + (acc, dep) => ({ + ...acc, + [dep.dependencyAppVersion.appId]: dep.dependencyAppVersion.value, + }), + {}, + ); - return new Response(JSON.stringify(dependencies), { status: 200 }); + return NextResponse.json(dependencies); }; diff --git a/libs/prisma/.eslintrc.json b/libs/prisma/.eslintrc.json new file mode 100644 index 0000000..a39ac5d --- /dev/null +++ b/libs/prisma/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["plugin:@nx/react", "../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/prisma/README.md b/libs/prisma/README.md new file mode 100644 index 0000000..60954c4 --- /dev/null +++ b/libs/prisma/README.md @@ -0,0 +1,7 @@ +# prisma + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test prisma` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/prisma/project.json b/libs/prisma/project.json new file mode 100644 index 0000000..c4fd47d --- /dev/null +++ b/libs/prisma/project.json @@ -0,0 +1,9 @@ +{ + "name": "prisma", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/prisma/src", + "projectType": "library", + "tags": [], + "// targets": "to see all targets run: nx show project prisma --web", + "targets": {} +} diff --git a/libs/prisma/src/index.ts b/libs/prisma/src/index.ts new file mode 100644 index 0000000..7c095d7 --- /dev/null +++ b/libs/prisma/src/index.ts @@ -0,0 +1 @@ +export { default as prisma } from './lib/prisma-client'; diff --git a/libs/prisma/src/lib/prisma-client.ts b/libs/prisma/src/lib/prisma-client.ts new file mode 100644 index 0000000..6d1f46c --- /dev/null +++ b/libs/prisma/src/lib/prisma-client.ts @@ -0,0 +1,15 @@ +import { PrismaClient } from '@prisma/client'; + +const prismaClientSingleton = () => { + return new PrismaClient(); +}; + +declare const globalThis: { + prismaGlobal: ReturnType; +} & typeof global; + +const prisma = globalThis.prismaGlobal ?? prismaClientSingleton(); + +export default prisma; + +if (process.env.NODE_ENV !== 'production') globalThis.prismaGlobal = prisma; diff --git a/libs/prisma/tsconfig.json b/libs/prisma/tsconfig.json new file mode 100644 index 0000000..95cfeb2 --- /dev/null +++ b/libs/prisma/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ], + "extends": "../../tsconfig.base.json" +} diff --git a/libs/prisma/tsconfig.lib.json b/libs/prisma/tsconfig.lib.json new file mode 100644 index 0000000..08e579b --- /dev/null +++ b/libs/prisma/tsconfig.lib.json @@ -0,0 +1,25 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": [ + "node", + "@nx/react/typings/cssmodule.d.ts", + "@nx/react/typings/image.d.ts", + "next", + "@nx/next/typings/image.d.ts" + ] + }, + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.jsx", + "src/**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/libs/utils/src/lib/utils.ts b/libs/utils/src/lib/utils.ts index adf113c..2819a83 100644 --- a/libs/utils/src/lib/utils.ts +++ b/libs/utils/src/lib/utils.ts @@ -4,8 +4,3 @@ import { twMerge } from 'tailwind-merge'; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } - -export function getQueryParams(request: Request): Record { - const url = new URL(request.url); - return Object.fromEntries(url.searchParams.entries()); -} diff --git a/prisma/migrations/20240603122534_deps_tables/migration.sql b/prisma/migrations/20240603122534_deps_tables/migration.sql deleted file mode 100644 index d9f6505..0000000 --- a/prisma/migrations/20240603122534_deps_tables/migration.sql +++ /dev/null @@ -1,46 +0,0 @@ --- CreateTable -CREATE TABLE "App" ( - "id" TEXT NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - - CONSTRAINT "App_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "AppVersion" ( - "id" SERIAL NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "value" TEXT NOT NULL, - "builtAt" TIMESTAMP(3), - "appId" TEXT NOT NULL, - - CONSTRAINT "AppVersion_pkey" PRIMARY KEY ("appId","value") -); - --- CreateTable -CREATE TABLE "AppVersionDependency" ( - "id" SERIAL NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dependantAppVersionId" INTEGER NOT NULL, - "dependencyAppVersionId" INTEGER NOT NULL, - - CONSTRAINT "AppVersionDependency_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "App_id_key" ON "App"("id"); - --- CreateIndex -CREATE UNIQUE INDEX "AppVersion_id_key" ON "AppVersion"("id"); - --- CreateIndex -CREATE UNIQUE INDEX "AppVersionDependency_id_key" ON "AppVersionDependency"("id"); - --- AddForeignKey -ALTER TABLE "AppVersion" ADD CONSTRAINT "AppVersion_appId_fkey" FOREIGN KEY ("appId") REFERENCES "App"("id") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "AppVersionDependency" ADD CONSTRAINT "AppVersionDependency_dependantAppVersionId_fkey" FOREIGN KEY ("dependantAppVersionId") REFERENCES "AppVersion"("id") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "AppVersionDependency" ADD CONSTRAINT "AppVersionDependency_dependencyAppVersionId_fkey" FOREIGN KEY ("dependencyAppVersionId") REFERENCES "AppVersion"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20240603152308_deps_tables/migration.sql b/prisma/migrations/20240603152308_deps_tables/migration.sql new file mode 100644 index 0000000..1431301 --- /dev/null +++ b/prisma/migrations/20240603152308_deps_tables/migration.sql @@ -0,0 +1,46 @@ +-- CreateTable +CREATE TABLE "App" ( + "id" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "App_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Version" ( + "id" SERIAL NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "value" TEXT NOT NULL, + "builtAt" TIMESTAMP(3), + "appId" TEXT NOT NULL, + + CONSTRAINT "Version_pkey" PRIMARY KEY ("appId","value") +); + +-- CreateTable +CREATE TABLE "Dependency" ( + "id" SERIAL NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dependantAppVersionId" INTEGER NOT NULL, + "dependencyAppVersionId" INTEGER NOT NULL, + + CONSTRAINT "Dependency_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "App_id_key" ON "App"("id"); + +-- CreateIndex +CREATE UNIQUE INDEX "Version_id_key" ON "Version"("id"); + +-- CreateIndex +CREATE UNIQUE INDEX "Dependency_id_key" ON "Dependency"("id"); + +-- AddForeignKey +ALTER TABLE "Version" ADD CONSTRAINT "Version_appId_fkey" FOREIGN KEY ("appId") REFERENCES "App"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Dependency" ADD CONSTRAINT "Dependency_dependantAppVersionId_fkey" FOREIGN KEY ("dependantAppVersionId") REFERENCES "Version"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Dependency" ADD CONSTRAINT "Dependency_dependencyAppVersionId_fkey" FOREIGN KEY ("dependencyAppVersionId") REFERENCES "Version"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 8ebefab..37f6198 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -80,29 +80,29 @@ model Authenticator { model App { id String @id @unique createdAt DateTime @default(now()) - versions AppVersion[] + versions Version[] } -model AppVersion { +model Version { id Int @unique @default(autoincrement()) createdAt DateTime @default(now()) value String builtAt DateTime? appId String - dependencies AppVersionDependency[] @relation("AppVersionDependency") - dependsOn AppVersionDependency[] @relation("AppVersionDependsOn") + dependencies Dependency[] @relation("AppVersionDependency") + dependsOn Dependency[] @relation("AppVersionDependsOn") app App @relation(fields: [appId], references: [id]) @@id([appId, value]) } -model AppVersionDependency { +model Dependency { id Int @id @unique @default(autoincrement()) createdAt DateTime @default(now()) dependantAppVersionId Int dependencyAppVersionId Int - dependantAppVersion AppVersion? @relation("AppVersionDependency", fields: [dependantAppVersionId], references: [id]) - dependencyAppVersion AppVersion? @relation("AppVersionDependsOn", fields: [dependencyAppVersionId], references: [id]) + dependantAppVersion Version @relation("AppVersionDependency", fields: [dependantAppVersionId], references: [id], onDelete: Cascade) + dependencyAppVersion Version @relation("AppVersionDependsOn", fields: [dependencyAppVersionId], references: [id], onDelete: Cascade) } diff --git a/tsconfig.base.json b/tsconfig.base.json index d604da3..7a5b0ea 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -18,6 +18,7 @@ "@verity/auth": ["libs/auth/src/index.ts"], "@verity/auth/server": ["libs/auth/src/server.ts"], "@verity/deps-api": ["libs/deps-api/src/server.ts"], + "@verity/prisma": ["libs/prisma/src/index.ts"], "@verity/ui": ["libs/ui/src/index.ts"], "@verity/ui/*": ["libs/ui/src/lib/*"], "@verity/ui/server": ["libs/ui/src/server.ts"],