feat(db): migrate from SQLite to PostgreSQL via Drizzle ORM

This commit is contained in:
Chneemann 2026-08-03 19:37:03 +02:00
parent c35379ffbe
commit c785b1bd46
No known key found for this signature in database
6 changed files with 35 additions and 56 deletions

View file

@ -8,13 +8,14 @@ A modern, high-performance Kanban & Workflow web application designed to help yo
![Tailwind CSS](https://img.shields.io/badge/Tailwind-v4-38bdf8?style=flat-square&logo=tailwind-css)
![Auth.js](https://img.shields.io/badge/Auth.js-v5-purple?style=flat-square)
![Drizzle ORM](https://img.shields.io/badge/Drizzle-ORM-C5F74F?style=flat-square&logo=drizzle)
![PostgreSQL](https://img.shields.io/badge/PostgreSQL-16-4169E1?style=flat-square&logo=postgresql)
## 🛠️ Tech Stack
- **Framework:** [Next.js 16](https://nextjs.org/) (App Router, Route Groups)
- **UI & Styling:** [React 19](https://react.dev/), [Tailwind CSS v4](https://tailwindcss.com/)
- **Authentication:** [Auth.js v5 (NextAuth)](https://authjs.dev/) with Credentials Provider & bcrypt hashing
- **Database & ORM:** [Drizzle ORM](https://orm.drizzle.team/) & Drizzle Kit
- **Database & ORM:** [PostgreSQL](https://www.postgresql.org/) managed via [Drizzle ORM](https://orm.drizzle.team/) & Drizzle Kit
## 📂 Architecture & Structure
@ -27,4 +28,4 @@ The project uses Next.js Route Groups to separate public and protected applicati
## 🎯 Current Status
_In Progress_ — Core layout structure, responsive navigation, and authentication (Auth.js v5) are implemented. Next up: Migration from SQLite to PostgreSQL via Drizzle ORM.
_In Progress_ — Core layout structure, responsive navigation, PostgreSQL database integration via Drizzle ORM, and full authentication (Auth.js v5) are implemented.

View file

@ -1,15 +1,15 @@
/**
* @file db/index.ts (oder ähnlich)
* @description Initializes the SQLite database connection using better-sqlite3 and sets up the Drizzle ORM instance with the provided schema.
* @file db/index.ts
* @description Initializes the PostgreSQL database connection using postgres-js and configures the Drizzle ORM instance.
*/
import { drizzle } from "drizzle-orm/better-sqlite3";
import Database from "better-sqlite3";
import { drizzle } from "drizzle-orm/postgres-js";
import * as schema from "./schema";
import postgres from "postgres";
const sqlite = new Database("./sqlite.db");
const client = postgres(process.env.DATABASE_URL!, { prepare: false });
/**
* The Drizzle ORM database instance configured for SQLite with type definitions from the schema.
* The Drizzle ORM database instance configured for PostgreSQL with type definitions from the schema.
*/
export const db = drizzle(sqlite, { schema });
export const db = drizzle(client, { schema });

View file

@ -1,20 +1,18 @@
/**
* @file db/schema.ts (oder ähnlich)
* @description Defines the SQLite database schema for users and exports related TypeScript types using Drizzle ORM.
* @file db/schema.ts
* @description Defines the PostgreSQL database schema for users using UUIDs, timestamps, and Drizzle ORM.
*/
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
import { pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
/**
* Database table definition for application users.
*/
export const usersTable = sqliteTable("users", {
id: integer("id").primaryKey({ autoIncrement: true }),
export const usersTable = pgTable("users", {
id: uuid("id").defaultRandom().primaryKey(),
email: text("email").notNull().unique(),
password: text("password").notNull(),
createdAt: integer("created_at", { mode: "timestamp" })
.$defaultFn(() => new Date())
.notNull(),
createdAt: timestamp("created_at").defaultNow().notNull(),
});
/**

View file

@ -1,18 +1,18 @@
/**
* @file drizzle.config.ts
* @description Drizzle Kit configuration file specifying schema locations, migration output directories, and database connection credentials for SQLite.
* @description Drizzle Kit configuration file for managing database migrations, schema paths, and database credentials.
*/
import { defineConfig } from "drizzle-kit";
/**
* Configuration object for Drizzle Kit CLI commands (migrations, introspection, studio).
* Configuration object exported for Drizzle Kit CLI commands.
*/
export default defineConfig({
schema: "./db/schema.ts",
out: "./db/migrations",
dialect: "sqlite",
dialect: "postgresql",
dbCredentials: {
url: "./sqlite.db",
url: process.env.DATABASE_URL!,
},
});

47
package-lock.json generated
View file

@ -9,17 +9,16 @@
"version": "0.1.0",
"dependencies": {
"bcryptjs": "^3.0.3",
"better-sqlite3": "^13.0.2",
"drizzle-orm": "^0.45.2",
"lucide-react": "^1.28.0",
"next": "16.2.12",
"next-auth": "^5.0.0-beta.32",
"postgres": "^3.4.9",
"react": "19.2.4",
"react-dom": "19.2.4"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/better-sqlite3": "^9.6.0",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
@ -2584,16 +2583,6 @@
"tslib": "^2.4.0"
}
},
"node_modules/@types/better-sqlite3": {
"version": "9.6.0",
"resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-9.6.0.tgz",
"integrity": "sha512-ZEEwBSgMu7GYJOynoagg5X9JbxfL6dTJDsgViJIqh67jV44kyOr9RXfmFjLK5rzC4MWssP06t9hu/JwGDnUbCg==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/estree": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
@ -3608,18 +3597,6 @@
"bcrypt": "bin/bcrypt"
}
},
"node_modules/better-sqlite3": {
"version": "13.0.2",
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-13.0.2.tgz",
"integrity": "sha512-jW6oufeDhXZaiX9Lw5A+oerVClx4iFrI6uDj1zu7SqUAjak9vbJvA0NEcKLNxHiQHb6kYCoFzzXYV0YOauhV3g==",
"license": "MIT",
"dependencies": {
"node-addon-api": "^8.0.0"
},
"engines": {
"node": ">=22"
}
},
"node_modules/brace-expansion": {
"version": "1.1.18",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
@ -6501,15 +6478,6 @@
}
}
},
"node_modules/node-addon-api": {
"version": "8.9.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.9.1.tgz",
"integrity": "sha512-4eUQWVPCUUUiBjLnHS3cXWeC6ryoPUc0U3rP7IuzapoGbzMqd/r6KKO0clr0b+snQhsrueFEhCZDdK+LK7hxKg==",
"license": "MIT",
"engines": {
"node": "^18 || ^20 || >= 21"
}
},
"node_modules/node-exports-info": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.2.tgz",
@ -6837,6 +6805,19 @@
"node": "^10 || ^12 || >=14"
}
},
"node_modules/postgres": {
"version": "3.4.9",
"resolved": "https://registry.npmjs.org/postgres/-/postgres-3.4.9.tgz",
"integrity": "sha512-GD3qdB0x1z9xgFI6cdRD6xu2Sp2WCOEoe3mtnyB5Ee0XrrL5Pe+e4CCnJrRMnL1zYtRDZmQQVbvOttLnKDLnaw==",
"license": "Unlicense",
"engines": {
"node": ">=12"
},
"funding": {
"type": "individual",
"url": "https://github.com/sponsors/porsager"
}
},
"node_modules/preact": {
"version": "10.24.3",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.24.3.tgz",

View file

@ -10,17 +10,16 @@
},
"dependencies": {
"bcryptjs": "^3.0.3",
"better-sqlite3": "^13.0.2",
"drizzle-orm": "^0.45.2",
"lucide-react": "^1.28.0",
"next": "16.2.12",
"next-auth": "^5.0.0-beta.32",
"postgres": "^3.4.9",
"react": "19.2.4",
"react-dom": "19.2.4"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/better-sqlite3": "^9.6.0",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",