Skip to content

Commit

Permalink
feat: add project module
Browse files Browse the repository at this point in the history
  • Loading branch information
rajdip-b committed Dec 27, 2023
1 parent b89cc2f commit c96df17
Show file tree
Hide file tree
Showing 13 changed files with 291 additions and 111 deletions.
76 changes: 0 additions & 76 deletions apps/api/src/prisma/migrations/20231225074847_init/migration.sql

This file was deleted.

134 changes: 134 additions & 0 deletions apps/api/src/prisma/migrations/20231226184616_init/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
-- CreateEnum
CREATE TYPE "ProjectRole" AS ENUM ('OWNER', 'MAINTAINER', 'VIEWER');

-- CreateEnum
CREATE TYPE "ApiKeyRole" AS ENUM ('CREATE_PROJECT', 'READ_PROJECT', 'UPDATE_PROJECT', 'DELETE_PROJECT', 'CREATE_SECRET', 'READ_SECRET', 'UPDATE_SECRET', 'DELETE_SECRET', 'ADD_USER', 'REMOVE_USER', 'UPDATE_USER_ROLE', 'CREATE_API_KEY', 'READ_API_KEY', 'UPDATE_API_KEY', 'DELETE_API_KEY');

-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
"email" TEXT NOT NULL,
"name" TEXT,
"profilePictureUrl" TEXT,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"isOnboardingFinished" BOOLEAN NOT NULL DEFAULT false,
"isAdmin" BOOLEAN NOT NULL DEFAULT false,

CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Subscription" (
"id" TEXT NOT NULL,
"plan" TEXT NOT NULL,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"userId" TEXT NOT NULL,

CONSTRAINT "Subscription_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Project" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"publicKey" TEXT NOT NULL,
"privateKey" TEXT,
"lastUpdatedById" TEXT NOT NULL,

CONSTRAINT "Project_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "ProjectMember" (
"id" TEXT NOT NULL,
"role" "ProjectRole" NOT NULL,
"userId" TEXT NOT NULL,
"projectId" TEXT NOT NULL,

CONSTRAINT "ProjectMember_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "ApiKeyScope" (
"id" TEXT NOT NULL,
"role" "ApiKeyRole" NOT NULL,
"apiKeyId" TEXT NOT NULL,
"projectId" TEXT NOT NULL,

CONSTRAINT "ApiKeyScope_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Secret" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"value" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"rotateAt" TIMESTAMP(3),
"lastUpdatedById" TEXT NOT NULL,
"projectId" TEXT NOT NULL,

CONSTRAINT "Secret_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "ApiKey" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"value" TEXT NOT NULL,
"expiresAt" TIMESTAMP(3),
"userId" TEXT NOT NULL,

CONSTRAINT "ApiKey_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Otp" (
"code" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"expiresAt" TIMESTAMP(3) NOT NULL
);

-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");

-- CreateIndex
CREATE UNIQUE INDEX "Subscription_userId_key" ON "Subscription"("userId");

-- CreateIndex
CREATE UNIQUE INDEX "Otp_code_key" ON "Otp"("code");

-- AddForeignKey
ALTER TABLE "Subscription" ADD CONSTRAINT "Subscription_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Project" ADD CONSTRAINT "Project_lastUpdatedById_fkey" FOREIGN KEY ("lastUpdatedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "ProjectMember" ADD CONSTRAINT "ProjectMember_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "ProjectMember" ADD CONSTRAINT "ProjectMember_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "ApiKeyScope" ADD CONSTRAINT "ApiKeyScope_apiKeyId_fkey" FOREIGN KEY ("apiKeyId") REFERENCES "ApiKey"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "ApiKeyScope" ADD CONSTRAINT "ApiKeyScope_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Secret" ADD CONSTRAINT "Secret_lastUpdatedById_fkey" FOREIGN KEY ("lastUpdatedById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Secret" ADD CONSTRAINT "Secret_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "ApiKey" ADD CONSTRAINT "ApiKey_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Otp" ADD CONSTRAINT "Otp_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
117 changes: 88 additions & 29 deletions apps/api/src/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -7,64 +7,123 @@ datasource db {
url = env("DATABASE_URL")
}

enum Scope {
CREATE
READ
UPDATE
DELETE
enum ProjectRole {
OWNER // Can do everything
MAINTAINER // Can do everything except deleting the project
VIEWER // Can only view the project and its secrets
}

enum ApiKeyRole {
CREATE_PROJECT
READ_PROJECT
UPDATE_PROJECT
DELETE_PROJECT
CREATE_SECRET
READ_SECRET
UPDATE_SECRET
DELETE_SECRET
ADD_USER
REMOVE_USER
UPDATE_USER_ROLE
CREATE_API_KEY
READ_API_KEY
UPDATE_API_KEY
DELETE_API_KEY
}

model User {
id String @id @default(cuid())
email String @unique
id String @id @default(cuid())
email String @unique
name String?
profilePictureUrl String?
isActive Boolean @default(true)
isOnboardingFinished Boolean @default(false)
isAdmin Boolean @default(false)
isActive Boolean @default(true)
isOnboardingFinished Boolean @default(false)
isAdmin Boolean @default(false)
subscription Subscription?
projects Project[]
projects ProjectMember[]
apiKeys ApiKey[]
otps Otp[]
Secret Secret[] // Stores the secrets the user updated
Project Project[] // Stores the projects the user updated
}

model Subscription {
id String @id @default(cuid())
plan String
isActive Boolean @default(true)
user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade)
userId String @unique
}

model Project {
id String @id @default(cuid())
id String @id @default(cuid())
name String
description String?
owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade)
ownerId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
publicKey String
privateKey String? // We store this only if the user wants us to do so!
secrets Secret[]
ApiKey ApiKey[]
lastUpdatedBy User @relation(fields: [lastUpdatedById], references: [id], onDelete: Cascade, onUpdate: Cascade)
lastUpdatedById String
members ProjectMember[]
secrets Secret[]
apiKeyScopes ApiKeyScope[]
}

model Secret {
id String @id @default(cuid())
name String
value String
model ProjectMember {
id String @id @default(cuid())
role ProjectRole
user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade)
userId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
}

model ApiKeyScope {
id String @id @default(cuid())
role ApiKeyRole
apiKey ApiKey @relation(fields: [apiKeyId], references: [id], onDelete: Cascade, onUpdate: Cascade)
apiKeyId String
projectId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
}

model ApiKey {
id String @id @default(cuid())
name String
value String
model Secret {
id String @id @default(cuid())
name String
value String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
rotateAt DateTime?
lastUpdatedBy User @relation(fields: [lastUpdatedById], references: [id])
lastUpdatedById String
projectId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
}

model ApiKey {
id String @id @default(cuid())
name String
value String
expiresAt DateTime?
scopes Scope[]
apiKeyScopes ApiKeyScope[]
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade)
userId String
}

model Otp {
code String @unique
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade)
userId String
createdAt DateTime @default(now())
expiresAt DateTime
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { CreateProject } from './create.project';

describe('CreateProject', () => {
it('should be defined', () => {
expect(new CreateProject()).toBeDefined();
});
});
1 change: 1 addition & 0 deletions apps/api/src/project/dto/create.project/create.project.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export class CreateProject {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { UpdateProject } from './update.project';

describe('UpdateProject', () => {
it('should be defined', () => {
expect(new UpdateProject()).toBeDefined();
});
});
1 change: 1 addition & 0 deletions apps/api/src/project/dto/update.project/update.project.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export class UpdateProject {}
Loading

0 comments on commit c96df17

Please sign in to comment.