Migrate architecture to PostgreSQL for Swarm HA

This commit is contained in:
ypratama committed 2026-08-12 14:32:00 +07:00
1 parent ee28968a70
commit 2317f9f133
39 files changed
+3849 -10

No files matched your search

+112
View File
@@ -0,0 +1,112 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
username String? @unique
email String @unique
password String
name String
role String @default("user") // "user", "approver", "super_admin"
failedLoginAttempts Int @default(0)
lockoutUntil DateTime?
requests Request[]
approvals ApprovalLog[]
activityLogs ActivityLog[]
categories Category[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model SystemSettings {
id Int @id @default(1)
telegramBotToken String?
telegramChatId String?
isTelegramEnabled Boolean @default(false)
// Email Config
isEmailEnabled Boolean @default(false)
smtpHost String?
smtpPort Int?
smtpUser String?
smtpPass String?
targetEmail String? // Comma separated for multiple
updatedAt DateTime @updatedAt
}
model Category {
id Int @id @default(autoincrement())
name String @unique
users User[]
items Item[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Item {
id Int @id @default(autoincrement())
name String @unique
totalQuantity Int @default(0)
borrowedQty Int @default(0)
trialQty Int @default(0)
billedQty Int @default(0)
availableQty Int @default(0)
damagedQty Int @default(0)
soldQty Int @default(0)
categoryId Int?
category Category? @relation(fields: [categoryId], references: [id])
requests Request[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Request {
id Int @id @default(autoincrement())
userId Int
itemId Int
quantity Int @default(1)
purpose String
company String
address String
requestDate DateTime @default(now())
status String @default("pending") // "pending", "approved_1", "approved_2", "rejected"
type String @default("borrow") // "borrow", "trial", "billed", "purchase", "return_borrow", "return_trial", "return_billed"
notes String?
serialNumber String?
user User @relation(fields: [userId], references: [id])
item Item @relation(fields: [itemId], references: [id])
approvalLogs ApprovalLog[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model ApprovalLog {
id Int @id @default(autoincrement())
requestId Int
approverId Int
approvalStep Int // 1 or 2
status String // "approved", "rejected"
request Request @relation(fields: [requestId], references: [id])
approver User @relation(fields: [approverId], references: [id])
createdAt DateTime @default(now())
}
model ActivityLog {
id Int @id @default(autoincrement())
userId Int
user User @relation(fields: [userId], references: [id])
action String
details String
type String // "request", "approval", "admin_item", "admin_user"
createdAt DateTime @default(now())
}
+60
View File
@@ -0,0 +1,60 @@
import { PrismaClient } from '@prisma/client'
import { PrismaLibSql } from '@prisma/adapter-libsql'
import 'dotenv/config'
const adapter = new PrismaLibSql({
url: process.env.DATABASE_URL || 'file:./dev.db',
})
const prisma = new PrismaClient({ adapter })
async function main() {
const items = [
'BackOne Lite',
'BackOne Pro',
'BackOne Gateway',
'BackOne Enterprise',
'BackOne Ultimate'
]
console.log('Seeding initial items...')
for (const itemName of items) {
const existing = await prisma.item.findUnique({ where: { name: itemName } })
if (!existing) {
await prisma.item.create({
data: {
name: itemName,
totalQuantity: 0,
},
})
console.log(`Created item: ${itemName}`)
} else {
console.log(`Item ${itemName} already exists.`)
}
}
// Create an initial super admin
const existingAdmin = await prisma.user.findUnique({ where: { email: 'admin@backone.id' } })
if (!existingAdmin) {
await prisma.user.create({
data: {
name: 'Super Admin',
email: 'admin@backone.id',
password: 'password', // TODO: In production this should be hashed
role: 'super_admin'
}
})
console.log('Created Super Admin (admin@backone.id / password)')
}
console.log('Seeding finished.')
}
main()
.catch((e) => {
console.error(e)
process.exit(1)
})
.finally(async () => {
await prisma.$disconnect()
})