feat(db): migrate from SQLite to PostgreSQL via Drizzle ORM
This commit is contained in:
parent
c35379ffbe
commit
c785b1bd46
6 changed files with 35 additions and 56 deletions
|
|
@ -8,13 +8,14 @@ A modern, high-performance Kanban & Workflow web application designed to help yo
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|

|
||||||
|
|
||||||
## 🛠️ Tech Stack
|
## 🛠️ Tech Stack
|
||||||
|
|
||||||
- **Framework:** [Next.js 16](https://nextjs.org/) (App Router, Route Groups)
|
- **Framework:** [Next.js 16](https://nextjs.org/) (App Router, Route Groups)
|
||||||
- **UI & Styling:** [React 19](https://react.dev/), [Tailwind CSS v4](https://tailwindcss.com/)
|
- **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
|
- **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
|
## 📂 Architecture & Structure
|
||||||
|
|
||||||
|
|
@ -27,4 +28,4 @@ The project uses Next.js Route Groups to separate public and protected applicati
|
||||||
|
|
||||||
## 🎯 Current Status
|
## 🎯 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.
|
||||||
|
|
|
||||||
14
db/index.ts
14
db/index.ts
|
|
@ -1,15 +1,15 @@
|
||||||
/**
|
/**
|
||||||
* @file db/index.ts (oder ähnlich)
|
* @file db/index.ts
|
||||||
* @description Initializes the SQLite database connection using better-sqlite3 and sets up the Drizzle ORM instance with the provided schema.
|
* @description Initializes the PostgreSQL database connection using postgres-js and configures the Drizzle ORM instance.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
import { drizzle } from "drizzle-orm/postgres-js";
|
||||||
import Database from "better-sqlite3";
|
|
||||||
import * as schema from "./schema";
|
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 });
|
||||||
|
|
|
||||||
14
db/schema.ts
14
db/schema.ts
|
|
@ -1,20 +1,18 @@
|
||||||
/**
|
/**
|
||||||
* @file db/schema.ts (oder ähnlich)
|
* @file db/schema.ts
|
||||||
* @description Defines the SQLite database schema for users and exports related TypeScript types using Drizzle ORM.
|
* @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.
|
* Database table definition for application users.
|
||||||
*/
|
*/
|
||||||
export const usersTable = sqliteTable("users", {
|
export const usersTable = pgTable("users", {
|
||||||
id: integer("id").primaryKey({ autoIncrement: true }),
|
id: uuid("id").defaultRandom().primaryKey(),
|
||||||
email: text("email").notNull().unique(),
|
email: text("email").notNull().unique(),
|
||||||
password: text("password").notNull(),
|
password: text("password").notNull(),
|
||||||
createdAt: integer("created_at", { mode: "timestamp" })
|
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||||
.$defaultFn(() => new Date())
|
|
||||||
.notNull(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
/**
|
/**
|
||||||
* @file drizzle.config.ts
|
* @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";
|
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({
|
export default defineConfig({
|
||||||
schema: "./db/schema.ts",
|
schema: "./db/schema.ts",
|
||||||
out: "./db/migrations",
|
out: "./db/migrations",
|
||||||
dialect: "sqlite",
|
dialect: "postgresql",
|
||||||
dbCredentials: {
|
dbCredentials: {
|
||||||
url: "./sqlite.db",
|
url: process.env.DATABASE_URL!,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
47
package-lock.json
generated
47
package-lock.json
generated
|
|
@ -9,17 +9,16 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcryptjs": "^3.0.3",
|
"bcryptjs": "^3.0.3",
|
||||||
"better-sqlite3": "^13.0.2",
|
|
||||||
"drizzle-orm": "^0.45.2",
|
"drizzle-orm": "^0.45.2",
|
||||||
"lucide-react": "^1.28.0",
|
"lucide-react": "^1.28.0",
|
||||||
"next": "16.2.12",
|
"next": "16.2.12",
|
||||||
"next-auth": "^5.0.0-beta.32",
|
"next-auth": "^5.0.0-beta.32",
|
||||||
|
"postgres": "^3.4.9",
|
||||||
"react": "19.2.4",
|
"react": "19.2.4",
|
||||||
"react-dom": "19.2.4"
|
"react-dom": "19.2.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/postcss": "^4",
|
"@tailwindcss/postcss": "^4",
|
||||||
"@types/better-sqlite3": "^9.6.0",
|
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
|
|
@ -2584,16 +2583,6 @@
|
||||||
"tslib": "^2.4.0"
|
"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": {
|
"node_modules/@types/estree": {
|
||||||
"version": "1.0.9",
|
"version": "1.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
|
||||||
|
|
@ -3608,18 +3597,6 @@
|
||||||
"bcrypt": "bin/bcrypt"
|
"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": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.18",
|
"version": "1.1.18",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
|
"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": {
|
"node_modules/node-exports-info": {
|
||||||
"version": "1.6.2",
|
"version": "1.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.2.tgz",
|
||||||
|
|
@ -6837,6 +6805,19 @@
|
||||||
"node": "^10 || ^12 || >=14"
|
"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": {
|
"node_modules/preact": {
|
||||||
"version": "10.24.3",
|
"version": "10.24.3",
|
||||||
"resolved": "https://registry.npmjs.org/preact/-/preact-10.24.3.tgz",
|
"resolved": "https://registry.npmjs.org/preact/-/preact-10.24.3.tgz",
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,16 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcryptjs": "^3.0.3",
|
"bcryptjs": "^3.0.3",
|
||||||
"better-sqlite3": "^13.0.2",
|
|
||||||
"drizzle-orm": "^0.45.2",
|
"drizzle-orm": "^0.45.2",
|
||||||
"lucide-react": "^1.28.0",
|
"lucide-react": "^1.28.0",
|
||||||
"next": "16.2.12",
|
"next": "16.2.12",
|
||||||
"next-auth": "^5.0.0-beta.32",
|
"next-auth": "^5.0.0-beta.32",
|
||||||
|
"postgres": "^3.4.9",
|
||||||
"react": "19.2.4",
|
"react": "19.2.4",
|
||||||
"react-dom": "19.2.4"
|
"react-dom": "19.2.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/postcss": "^4",
|
"@tailwindcss/postcss": "^4",
|
||||||
"@types/better-sqlite3": "^9.6.0",
|
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue