plugin postgre database with prisma

This commit is contained in:
2026-03-27 18:34:13 +01:00
parent d79ba35e1d
commit 70ca3fc5de
11 changed files with 869 additions and 194 deletions

4
.gitignore vendored
View File

@@ -53,3 +53,7 @@ coverage/
.cache/
/src/generated/prisma
/src/generated/prisma
/src/generated/prisma

907
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "ts-node src/server.ts",
"dev": "tsx src/server.ts",
"build": "tsc",
"start": "node dist/server.js"
},
@@ -16,13 +16,16 @@
"author": "Raffi",
"license": "ISC",
"dependencies": {
"@prisma/adapter-pg": "^7.6.0",
"@prisma/client": "^7.6.0",
"fastify": "^5.8.4"
"fastify": "^5.8.4",
"fastify-plugin": "^5.1.0",
"pg": "^8.20.0"
},
"devDependencies": {
"@types/node": "^25.5.0",
"prisma": "^7.6.0",
"ts-node": "^10.9.2",
"tsx": "^4.21.0",
"typescript": "^6.0.2"
}
}

14
prisma.config.ts Normal file
View File

@@ -0,0 +1,14 @@
// This file was generated by Prisma, and assumes you have installed the following:
// npm install --save-dev prisma dotenv
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});

44
prisma/schema.prisma Normal file
View File

@@ -0,0 +1,44 @@
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model ActionToken {
id String @id
userId String
token String @unique
type String
expiresAt DateTime
used Boolean @default(false)
createdAt DateTime @default(now())
User User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model AuthToken {
id String @id
userId String
token String @unique
expiresAt DateTime
createdAt DateTime @default(now())
revoked Boolean @default(false)
User User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model User {
id String @id
email String @unique
passwordHash String
displayName String
isConfirmed Boolean @default(false)
isGoogleUser Boolean @default(false)
avatar String
createdAt DateTime @default(now())
publicKey String?
encryptedPrivateKey String?
ActionToken ActionToken[]
AuthToken AuthToken[]
}

View File

@@ -1,9 +1,14 @@
import Fastify from 'fastify'
import prismaPlugin from './plugins/prisma'
import userRoutes from './routes/users.js'
const app = Fastify({ logger: true })
export default function buildApp() {
const app = Fastify({ logger: true })
app.get('/health', async () => {
return { status: 'ok' }
})
app.register(prismaPlugin)
app.register(userRoutes, { prefix: '/api' })
export default app
app.get('/health', async () => ({ status: 'ok' }))
return app
}

24
src/plugins/prisma.ts Normal file
View File

@@ -0,0 +1,24 @@
import fp from 'fastify-plugin'
import { FastifyInstance } from 'fastify'
import { PrismaClient } from '../generated/prisma/client.js'
import { PrismaPg } from '@prisma/adapter-pg'
declare module 'fastify' {
interface FastifyInstance {
prisma: PrismaClient
}
}
export default fp(async (fastify: FastifyInstance) => {
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
})
const prisma = new PrismaClient({ adapter })
fastify.decorate('prisma', prisma)
fastify.addHook('onClose', async () => {
await prisma.$disconnect()
})
})

19
src/routes/users.ts Normal file
View File

@@ -0,0 +1,19 @@
import { FastifyInstance } from 'fastify'
export default async function userRoutes(fastify: FastifyInstance) {
fastify.get('/users', async (request, reply) => {
const users = await fastify.prisma.user.findMany({
select: {
id: true,
email: true,
displayName: true,
isConfirmed: true,
isGoogleUser: true,
avatar: true,
createdAt: true,
},
})
return users
})
}

View File

@@ -1,5 +1,7 @@
import app from './app'
import 'dotenv/config'
import buildApp from './app.js'
const app = buildApp()
const start = async () => {
try {

7
src/types/fastify.d.ts vendored Normal file
View File

@@ -0,0 +1,7 @@
import { PrismaClient } from '../generated/prisma/client.js'
declare module 'fastify' {
interface FastifyInstance {
prisma: PrismaClient
}
}

View File

@@ -1,11 +1,15 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"rootDir": "./src",
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
}
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}