feat(db): add AdminUser and Code models with migration

- Add AdminUser model (username, passwordHash, role enum)
- Add Code model (code, createdBy, usedByUserId, timestamps)
- Install bcryptjs for password hashing
- Run migration add_admin_and_code
This commit is contained in:
dimitar 2026-07-29 18:54:40 +02:00
parent 6bb72dc97f
commit 8569b506d2
4 changed files with 87 additions and 0 deletions

18
package-lock.json generated
View File

@ -12,6 +12,7 @@
"@aws-sdk/s3-request-presigner": "^3.1073.0", "@aws-sdk/s3-request-presigner": "^3.1073.0",
"@clerk/nextjs": "^7.5.7", "@clerk/nextjs": "^7.5.7",
"@prisma/client": "^5.22.0", "@prisma/client": "^5.22.0",
"bcryptjs": "^3.0.3",
"next": "^15.5.19", "next": "^15.5.19",
"qrcode": "^1.5.4", "qrcode": "^1.5.4",
"react": "19.2.4", "react": "19.2.4",
@ -20,6 +21,7 @@
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/postcss": "^4", "@tailwindcss/postcss": "^4",
"@types/bcryptjs": "^2.4.6",
"@types/node": "^20", "@types/node": "^20",
"@types/qrcode": "^1.5.6", "@types/qrcode": "^1.5.6",
"@types/react": "^19", "@types/react": "^19",
@ -2062,6 +2064,13 @@
"tslib": "^2.4.0" "tslib": "^2.4.0"
} }
}, },
"node_modules/@types/bcryptjs": {
"version": "2.4.6",
"resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.6.tgz",
"integrity": "sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/estree": { "node_modules/@types/estree": {
"version": "1.0.9", "version": "1.0.9",
"dev": true, "dev": true,
@ -3038,6 +3047,15 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/bcryptjs": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.3.tgz",
"integrity": "sha512-GlF5wPWnSa/X5LKM1o0wz0suXIINz1iHRLvTS+sLyi7XPbe5ycmYI3DlZqVGZZtDgl4DmasFg7gOB3JYbphV5g==",
"license": "BSD-3-Clause",
"bin": {
"bcrypt": "bin/bcrypt"
}
},
"node_modules/bowser": { "node_modules/bowser": {
"version": "2.14.1", "version": "2.14.1",
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz",

View File

@ -17,6 +17,7 @@
"@aws-sdk/s3-request-presigner": "^3.1073.0", "@aws-sdk/s3-request-presigner": "^3.1073.0",
"@clerk/nextjs": "^7.5.7", "@clerk/nextjs": "^7.5.7",
"@prisma/client": "^5.22.0", "@prisma/client": "^5.22.0",
"bcryptjs": "^3.0.3",
"next": "^15.5.19", "next": "^15.5.19",
"qrcode": "^1.5.4", "qrcode": "^1.5.4",
"react": "19.2.4", "react": "19.2.4",
@ -25,6 +26,7 @@
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/postcss": "^4", "@tailwindcss/postcss": "^4",
"@types/bcryptjs": "^2.4.6",
"@types/node": "^20", "@types/node": "^20",
"@types/qrcode": "^1.5.6", "@types/qrcode": "^1.5.6",
"@types/react": "^19", "@types/react": "^19",

View File

@ -0,0 +1,40 @@
-- CreateEnum
CREATE TYPE "Role" AS ENUM ('SUPER_ADMIN', 'ADMIN');
-- CreateTable
CREATE TABLE "AdminUser" (
"id" TEXT NOT NULL,
"username" TEXT NOT NULL,
"passwordHash" TEXT NOT NULL,
"role" "Role" NOT NULL DEFAULT 'ADMIN',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "AdminUser_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Code" (
"id" TEXT NOT NULL,
"code" TEXT NOT NULL,
"createdById" TEXT NOT NULL,
"usedByUserId" TEXT,
"usedAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Code_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "AdminUser_username_key" ON "AdminUser"("username");
-- CreateIndex
CREATE UNIQUE INDEX "Code_code_key" ON "Code"("code");
-- CreateIndex
CREATE INDEX "Code_code_idx" ON "Code"("code");
-- CreateIndex
CREATE INDEX "Code_usedByUserId_idx" ON "Code"("usedByUserId");
-- AddForeignKey
ALTER TABLE "Code" ADD CONSTRAINT "Code_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "AdminUser"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@ -36,3 +36,30 @@ model Image {
@@index([userId]) @@index([userId])
} }
enum Role {
SUPER_ADMIN
ADMIN
}
model AdminUser {
id String @id @default(cuid())
username String @unique
passwordHash String
role Role @default(ADMIN)
createdAt DateTime @default(now())
createdCodes Code[]
}
model Code {
id String @id @default(cuid())
code String @unique
createdById String
createdBy AdminUser @relation(fields: [createdById], references: [id])
usedByUserId String?
usedAt DateTime?
createdAt DateTime @default(now())
@@index([code])
@@index([usedByUserId])
}