feat: set up database / orm #39
11 changed files with 763 additions and 26 deletions
|
@ -1,4 +1,4 @@
|
||||||
DATABASE_URL=
|
DATABASE_URL="file:./dev.db"
|
||||||
|
|
||||||
AUTH_SECRET= # Added by `npx auth`. Read more: https://cli.authjs.dev
|
AUTH_SECRET= # Added by `npx auth`. Read more: https://cli.authjs.dev
|
||||||
|
|
||||||
|
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -40,3 +40,8 @@ yarn-error.log*
|
||||||
# typescript
|
# typescript
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
|
|
||||||
|
# database
|
||||||
|
/prisma/*.db*
|
||||||
micha.bok marked this conversation as resolved
Outdated
|
|||||||
|
src/generated/prisma
|
||||||
|
data
|
||||||
|
|
|
@ -15,6 +15,7 @@ WORKDIR /app
|
||||||
RUN corepack enable
|
RUN corepack enable
|
||||||
COPY --from=deps /app/node_modules ./node_modules
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
COPY . .
|
COPY . .
|
||||||
|
RUN yarn prisma:generate
|
||||||
RUN yarn build
|
RUN yarn build
|
||||||
|
|
||||||
# ----- Runner -----
|
# ----- Runner -----
|
||||||
|
|
|
@ -11,6 +11,9 @@ const compat = new FlatCompat({
|
||||||
|
|
||||||
const eslintConfig = [
|
const eslintConfig = [
|
||||||
...compat.extends('next/core-web-vitals', 'next/typescript', 'prettier'),
|
...compat.extends('next/core-web-vitals', 'next/typescript', 'prettier'),
|
||||||
|
{
|
||||||
|
ignores: ['src/generated/**', '.next/**', 'public/**'],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default eslintConfig;
|
export default eslintConfig;
|
||||||
|
|
14
package.json
14
package.json
|
@ -7,14 +7,21 @@
|
||||||
"build": "prettier --check . && next build",
|
"build": "prettier --check . && next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint",
|
"lint": "next lint",
|
||||||
"format": "prettier --write ."
|
"format": "prettier --write .",
|
||||||
|
"prisma:migrate": "dotenv -e .env.local -- prisma migrate dev",
|
||||||
|
"prisma:generate": "dotenv -e .env.local -- prisma generate",
|
||||||
|
"prisma:studio": "dotenv -e .env.local -- prisma studio",
|
||||||
|
"prisma:db:push": "dotenv -e .env.local -- prisma db push",
|
||||||
|
"prisma:migrate:reset": "dotenv -e .env.local -- prisma migrate reset"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@auth/prisma-adapter": "^2.9.1",
|
||||||
"@fortawesome/fontawesome-svg-core": "^6.7.2",
|
"@fortawesome/fontawesome-svg-core": "^6.7.2",
|
||||||
"@fortawesome/free-brands-svg-icons": "^6.7.2",
|
"@fortawesome/free-brands-svg-icons": "^6.7.2",
|
||||||
"@fortawesome/free-regular-svg-icons": "^6.7.2",
|
"@fortawesome/free-regular-svg-icons": "^6.7.2",
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.7.2",
|
"@fortawesome/free-solid-svg-icons": "^6.7.2",
|
||||||
"@fortawesome/react-fontawesome": "^0.2.2",
|
"@fortawesome/react-fontawesome": "^0.2.2",
|
||||||
|
"@prisma/client": "^6.8.2",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.14",
|
"@radix-ui/react-dropdown-menu": "^2.1.14",
|
||||||
"@radix-ui/react-hover-card": "^1.1.13",
|
"@radix-ui/react-hover-card": "^1.1.13",
|
||||||
"@radix-ui/react-label": "^2.1.6",
|
"@radix-ui/react-label": "^2.1.6",
|
||||||
|
@ -40,14 +47,15 @@
|
||||||
"@types/node": "22.15.19",
|
"@types/node": "22.15.19",
|
||||||
"@types/react": "19.1.4",
|
"@types/react": "19.1.4",
|
||||||
"@types/react-dom": "19.1.5",
|
"@types/react-dom": "19.1.5",
|
||||||
|
"dotenv-cli": "8.0.0",
|
||||||
"eslint": "9.27.0",
|
"eslint": "9.27.0",
|
||||||
"eslint-config-next": "15.3.2",
|
"eslint-config-next": "15.3.2",
|
||||||
"eslint-config-prettier": "10.1.5",
|
"eslint-config-prettier": "10.1.5",
|
||||||
"postcss": "8.5.3",
|
"postcss": "8.5.3",
|
||||||
"prettier": "3.5.3",
|
"prettier": "3.5.3",
|
||||||
"prisma": "6.8.2",
|
"prisma": "6.8.2",
|
||||||
"tailwindcss": "4.1.7",
|
"tailwindcss": "4.1.6",
|
||||||
"tw-animate-css": "1.3.0",
|
"tw-animate-css": "1.2.9",
|
||||||
"typescript": "5.8.3"
|
"typescript": "5.8.3"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@4.9.1"
|
"packageManager": "yarn@4.9.1"
|
||||||
|
|
298
prisma/migrations/20250519192553_init/migration.sql
Normal file
298
prisma/migrations/20250519192553_init/migration.sql
Normal file
|
@ -0,0 +1,298 @@
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "users" (
|
||||||
|
"id" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"name" TEXT NOT NULL,
|
||||||
|
"first_name" TEXT,
|
||||||
|
"last_name" TEXT,
|
||||||
|
"email" TEXT NOT NULL,
|
||||||
|
"email_verified" DATETIME,
|
||||||
|
"password_hash" TEXT,
|
||||||
|
"image" TEXT,
|
||||||
|
"timezone" TEXT NOT NULL DEFAULT 'UTC',
|
||||||
|
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updated_at" DATETIME NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "accounts" (
|
||||||
|
"id" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"user_id" TEXT NOT NULL,
|
||||||
|
"type" TEXT NOT NULL,
|
||||||
|
"provider" TEXT NOT NULL,
|
||||||
|
"provider_account_id" TEXT NOT NULL,
|
||||||
|
"refresh_token" TEXT,
|
||||||
|
"access_token" TEXT,
|
||||||
|
"expires_at" INTEGER,
|
||||||
|
"token_type" TEXT,
|
||||||
|
"scope" TEXT,
|
||||||
|
"id_token" TEXT,
|
||||||
|
"session_state" TEXT,
|
||||||
|
CONSTRAINT "accounts_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "sessions" (
|
||||||
|
"id" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"session_token" TEXT NOT NULL,
|
||||||
|
"user_id" TEXT NOT NULL,
|
||||||
|
"expires" DATETIME NOT NULL,
|
||||||
|
CONSTRAINT "sessions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "verification_tokens" (
|
||||||
|
"identifier" TEXT NOT NULL,
|
||||||
|
"token" TEXT NOT NULL,
|
||||||
|
"expires" DATETIME NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "authenticators" (
|
||||||
|
"user_id" TEXT NOT NULL,
|
||||||
|
"credential_id" TEXT NOT NULL,
|
||||||
|
"provider_account_id" TEXT NOT NULL,
|
||||||
|
"credential_public_key" TEXT NOT NULL,
|
||||||
|
"counter" INTEGER NOT NULL,
|
||||||
|
"credential_device_type" TEXT NOT NULL,
|
||||||
|
"credential_backed_up" BOOLEAN NOT NULL,
|
||||||
|
"transports" TEXT,
|
||||||
|
|
||||||
|
PRIMARY KEY ("user_id", "credential_id"),
|
||||||
|
CONSTRAINT "authenticators_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "friendships" (
|
||||||
|
"user_id_1" TEXT NOT NULL,
|
||||||
|
"user_id_2" TEXT NOT NULL,
|
||||||
|
"status" TEXT NOT NULL DEFAULT 'PENDING',
|
||||||
|
"requested_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"accepted_at" DATETIME,
|
||||||
|
|
||||||
|
PRIMARY KEY ("user_id_1", "user_id_2"),
|
||||||
|
CONSTRAINT "friendships_user_id_1_fkey" FOREIGN KEY ("user_id_1") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT "friendships_user_id_2_fkey" FOREIGN KEY ("user_id_2") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "groups" (
|
||||||
|
"id" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"name" TEXT NOT NULL,
|
||||||
|
"description" TEXT,
|
||||||
|
"creator_id" TEXT NOT NULL,
|
||||||
|
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updated_at" DATETIME NOT NULL,
|
||||||
|
CONSTRAINT "groups_creator_id_fkey" FOREIGN KEY ("creator_id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "group_members" (
|
||||||
|
"group_id" TEXT NOT NULL,
|
||||||
|
"user_id" TEXT NOT NULL,
|
||||||
|
"role" TEXT NOT NULL DEFAULT 'MEMBER',
|
||||||
|
"added_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
|
PRIMARY KEY ("group_id", "user_id"),
|
||||||
|
CONSTRAINT "group_members_group_id_fkey" FOREIGN KEY ("group_id") REFERENCES "groups" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT "group_members_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "blocked_slots" (
|
||||||
|
"id" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"user_id" TEXT NOT NULL,
|
||||||
|
"start_time" DATETIME NOT NULL,
|
||||||
|
"end_time" DATETIME NOT NULL,
|
||||||
|
"reason" TEXT,
|
||||||
|
"is_recurring" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"rrule" TEXT,
|
||||||
|
"recurrence_end_date" DATETIME,
|
||||||
|
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updated_at" DATETIME NOT NULL,
|
||||||
|
CONSTRAINT "blocked_slots_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "meetings" (
|
||||||
|
"id" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"title" TEXT NOT NULL,
|
||||||
|
"description" TEXT,
|
||||||
|
"start_time" DATETIME NOT NULL,
|
||||||
|
"end_time" DATETIME NOT NULL,
|
||||||
|
"organizer_id" TEXT NOT NULL,
|
||||||
|
"location" TEXT,
|
||||||
|
"status" TEXT NOT NULL DEFAULT 'CONFIRMED',
|
||||||
|
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updated_at" DATETIME NOT NULL,
|
||||||
|
CONSTRAINT "meetings_organizer_id_fkey" FOREIGN KEY ("organizer_id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "meeting_participants" (
|
||||||
|
"meeting_id" TEXT NOT NULL,
|
||||||
|
"user_id" TEXT NOT NULL,
|
||||||
|
"status" TEXT NOT NULL DEFAULT 'PENDING',
|
||||||
|
"added_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
|
PRIMARY KEY ("meeting_id", "user_id"),
|
||||||
|
CONSTRAINT "meeting_participants_meeting_id_fkey" FOREIGN KEY ("meeting_id") REFERENCES "meetings" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT "meeting_participants_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "notifications" (
|
||||||
|
"id" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"user_id" TEXT NOT NULL,
|
||||||
|
"type" TEXT NOT NULL,
|
||||||
|
"related_entity_type" TEXT,
|
||||||
|
"related_entity_id" TEXT,
|
||||||
|
"message" TEXT NOT NULL,
|
||||||
|
"is_read" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
CONSTRAINT "notifications_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "user_notification_preferences" (
|
||||||
|
"user_id" TEXT NOT NULL,
|
||||||
|
"notification_type" TEXT NOT NULL,
|
||||||
|
"email_enabled" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"updated_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
|
PRIMARY KEY ("user_id", "notification_type"),
|
||||||
|
CONSTRAINT "user_notification_preferences_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "email_queue" (
|
||||||
|
"id" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"user_id" TEXT NOT NULL,
|
||||||
|
"subject" TEXT NOT NULL,
|
||||||
|
"body_html" TEXT NOT NULL,
|
||||||
|
"body_text" TEXT,
|
||||||
|
"status" TEXT NOT NULL DEFAULT 'PENDING',
|
||||||
|
"scheduled_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"attempts" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"last_attempt_at" DATETIME,
|
||||||
|
"sent_at" DATETIME,
|
||||||
|
"error_message" TEXT,
|
||||||
|
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updated_at" DATETIME NOT NULL,
|
||||||
|
CONSTRAINT "email_queue_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "calendar_export_tokens" (
|
||||||
|
"id" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"user_id" TEXT NOT NULL,
|
||||||
|
"token" TEXT NOT NULL,
|
||||||
|
"scope" TEXT NOT NULL DEFAULT 'MEETINGS_ONLY',
|
||||||
|
"is_active" BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"last_accessed_at" DATETIME,
|
||||||
|
CONSTRAINT "calendar_export_tokens_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "calendar_subscriptions" (
|
||||||
|
"id" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"user_id" TEXT NOT NULL,
|
||||||
|
"feed_url" TEXT NOT NULL,
|
||||||
|
"name" TEXT,
|
||||||
|
"color" TEXT,
|
||||||
|
"is_enabled" BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
"last_synced_at" DATETIME,
|
||||||
|
"last_sync_error" TEXT,
|
||||||
|
"sync_frequency_minutes" INTEGER DEFAULT 60,
|
||||||
|
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updated_at" DATETIME NOT NULL,
|
||||||
|
CONSTRAINT "calendar_subscriptions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "external_events" (
|
||||||
|
"id" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"subscription_id" TEXT NOT NULL,
|
||||||
|
"ical_uid" TEXT NOT NULL,
|
||||||
|
"summary" TEXT,
|
||||||
|
"description" TEXT,
|
||||||
|
"start_time" DATETIME NOT NULL,
|
||||||
|
"end_time" DATETIME NOT NULL,
|
||||||
|
"is_all_day" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"location" TEXT,
|
||||||
|
"rrule" TEXT,
|
||||||
|
"dtstamp" DATETIME,
|
||||||
|
"sequence" INTEGER,
|
||||||
|
"show_as_free" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"last_fetched_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
CONSTRAINT "external_events_subscription_id_fkey" FOREIGN KEY ("subscription_id") REFERENCES "calendar_subscriptions" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "users_name_key" ON "users"("name");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "accounts_provider_provider_account_id_key" ON "accounts"("provider", "provider_account_id");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "sessions_session_token_key" ON "sessions"("session_token");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "verification_tokens_identifier_token_key" ON "verification_tokens"("identifier", "token");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "idx_friendships_user2_status" ON "friendships"("user_id_2", "status");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "groups_creator_id_idx" ON "groups"("creator_id");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "group_members_user_id_idx" ON "group_members"("user_id");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "blocked_slots_user_id_start_time_end_time_idx" ON "blocked_slots"("user_id", "start_time", "end_time");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "blocked_slots_user_id_is_recurring_idx" ON "blocked_slots"("user_id", "is_recurring");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "meetings_start_time_end_time_idx" ON "meetings"("start_time", "end_time");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "meetings_organizer_id_idx" ON "meetings"("organizer_id");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "meetings_status_idx" ON "meetings"("status");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "idx_participants_user_status" ON "meeting_participants"("user_id", "status");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "idx_notifications_user_read_time" ON "notifications"("user_id", "is_read", "created_at");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "idx_email_queue_pending_jobs" ON "email_queue"("status", "scheduled_at");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "idx_email_queue_user_history" ON "email_queue"("user_id", "created_at");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "calendar_export_tokens_token_key" ON "calendar_export_tokens"("token");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "calendar_export_tokens_user_id_idx" ON "calendar_export_tokens"("user_id");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "calendar_subscriptions_user_id_is_enabled_idx" ON "calendar_subscriptions"("user_id", "is_enabled");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "external_events_subscription_id_start_time_end_time_idx" ON "external_events"("subscription_id", "start_time", "end_time");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "external_events_subscription_id_show_as_free_idx" ON "external_events"("subscription_id", "show_as_free");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "external_events_subscription_id_ical_uid_key" ON "external_events"("subscription_id", "ical_uid");
|
3
prisma/migrations/migration_lock.toml
Normal file
3
prisma/migrations/migration_lock.toml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Please do not edit this file manually
|
||||||
|
# It should be added in your version-control system (e.g., Git)
|
||||||
|
provider = "sqlite"
|
|
@ -5,11 +5,355 @@
|
||||||
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
|
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
|
||||||
|
|
||||||
generator client {
|
generator client {
|
||||||
provider = "prisma-client-js"
|
provider = "prisma-client-js"
|
||||||
output = "../generated/prisma"
|
output = "../src/generated/prisma"
|
||||||
micha.bok marked this conversation as resolved
Outdated
dominik
commented
Am besten den output mit in den src Ordner packen, dann kann man das leichter importieren.
Am besten den output mit in den src Ordner packen, dann kann man das leichter importieren.
`../src/generated/prisma`
|
|||||||
}
|
}
|
||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
provider = "postgresql"
|
provider = "sqlite"
|
||||||
url = env("DATABASE_URL")
|
url = env("DATABASE_URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
enum participant_status {
|
||||||
|
PENDING
|
||||||
|
ACCEPTED
|
||||||
|
DECLINED
|
||||||
|
TENTATIVE
|
||||||
|
}
|
||||||
|
|
||||||
|
enum meeting_status {
|
||||||
|
TENTATIVE
|
||||||
|
CONFIRMED
|
||||||
|
CANCELLED
|
||||||
|
}
|
||||||
|
|
||||||
|
enum friendship_status {
|
||||||
|
PENDING
|
||||||
|
ACCEPTED
|
||||||
|
DECLINED
|
||||||
|
BLOCKED
|
||||||
|
}
|
||||||
|
|
||||||
|
enum notification_type {
|
||||||
|
FRIEND_REQUEST
|
||||||
|
FRIEND_ACCEPT
|
||||||
|
MEETING_INVITE
|
||||||
|
MEETING_UPDATE
|
||||||
|
MEETING_CANCEL
|
||||||
|
MEETING_REMINDER
|
||||||
|
GROUP_MEMBER_ADDED
|
||||||
|
CALENDAR_SYNC_ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
enum group_member_role {
|
||||||
|
ADMIN
|
||||||
|
MEMBER
|
||||||
|
}
|
||||||
|
|
||||||
|
enum calendar_export_scope {
|
||||||
|
MEETINGS_ONLY
|
||||||
|
MEETINGS_AND_BLOCKED
|
||||||
|
BLOCKED_ONLY
|
||||||
|
}
|
||||||
|
|
||||||
|
enum email_queue_status {
|
||||||
|
PENDING
|
||||||
|
PROCESSING
|
||||||
|
SENT
|
||||||
|
FAILED
|
||||||
|
CANCELLED
|
||||||
|
}
|
||||||
|
|
||||||
|
model User {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
name String @unique
|
||||||
lima marked this conversation as resolved
Outdated
lima
commented
"username" durch "name" ersetzen und double checken. "username" durch "name" ersetzen und double checken.
https://authjs.dev/getting-started/adapters/prisma
|
|||||||
|
first_name String?
|
||||||
|
last_name String?
|
||||||
|
email String @unique
|
||||||
|
emailVerified DateTime? @map("email_verified")
|
||||||
|
password_hash String?
|
||||||
|
image String?
|
||||||
|
timezone String @default("UTC")
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
updated_at DateTime @updatedAt
|
||||||
|
|
||||||
|
accounts Account[]
|
||||||
|
sessions Session[]
|
||||||
|
authenticators Authenticator[]
|
||||||
|
friendships1 Friendship[] @relation("FriendshipUser1")
|
||||||
|
friendships2 Friendship[] @relation("FriendshipUser2")
|
||||||
|
groupsCreated Group[] @relation("GroupCreator")
|
||||||
|
groupMembers GroupMember[]
|
||||||
|
blockedSlots BlockedSlot[]
|
||||||
|
meetingsOrg Meeting[] @relation("MeetingOrganizer")
|
||||||
|
meetingParts MeetingParticipant[]
|
||||||
|
notifications Notification[]
|
||||||
|
notifPrefs UserNotificationPreference[]
|
||||||
|
emailQueue EmailQueue[]
|
||||||
|
calendarTokens CalendarExportToken[]
|
||||||
|
subscriptions CalendarSubscription[]
|
||||||
|
|
||||||
|
@@map("users")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Account {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
userId String @map("user_id")
|
||||||
|
type String
|
||||||
|
provider String
|
||||||
|
providerAccountId String @map("provider_account_id")
|
||||||
|
refresh_token String?
|
||||||
|
access_token String?
|
||||||
|
expires_at Int?
|
||||||
|
token_type String?
|
||||||
|
scope String?
|
||||||
|
id_token String?
|
||||||
|
session_state String?
|
||||||
|
|
||||||
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
|
@@unique([provider, providerAccountId])
|
||||||
|
@@map("accounts")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Session {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
sessionToken String @unique @map("session_token")
|
||||||
|
userId String @map("user_id")
|
||||||
|
expires DateTime
|
||||||
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
|
@@map("sessions")
|
||||||
|
}
|
||||||
|
|
||||||
|
model VerificationToken {
|
||||||
|
identifier String
|
||||||
|
token String
|
||||||
|
expires DateTime
|
||||||
|
|
||||||
|
@@unique([identifier, token])
|
||||||
|
@@map("verification_tokens")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Authenticator {
|
||||||
|
user_id String
|
||||||
|
credential_id String
|
||||||
|
provider_account_id String
|
||||||
|
credential_public_key String
|
||||||
|
counter Int
|
||||||
|
credential_device_type String
|
||||||
|
credential_backed_up Boolean
|
||||||
|
transports String?
|
||||||
|
|
||||||
|
user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
|
@@id([user_id, credential_id])
|
||||||
|
@@map("authenticators")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Friendship {
|
||||||
|
user_id_1 String
|
||||||
|
user_id_2 String
|
||||||
|
status friendship_status @default(PENDING)
|
||||||
|
requested_at DateTime @default(now())
|
||||||
|
accepted_at DateTime?
|
||||||
|
|
||||||
|
user1 User @relation("FriendshipUser1", fields: [user_id_1], references: [id])
|
||||||
|
user2 User @relation("FriendshipUser2", fields: [user_id_2], references: [id])
|
||||||
|
|
||||||
|
@@id([user_id_1, user_id_2])
|
||||||
|
@@index([user_id_2, status], name: "idx_friendships_user2_status")
|
||||||
|
@@map("friendships")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Group {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
name String
|
||||||
|
description String?
|
||||||
|
creator_id String
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
updated_at DateTime @updatedAt
|
||||||
|
|
||||||
|
creator User @relation("GroupCreator", fields: [creator_id], references: [id])
|
||||||
|
members GroupMember[]
|
||||||
|
|
||||||
|
@@index([creator_id])
|
||||||
|
@@map("groups")
|
||||||
|
}
|
||||||
|
|
||||||
|
model GroupMember {
|
||||||
|
group_id String
|
||||||
|
user_id String
|
||||||
|
role group_member_role @default(MEMBER)
|
||||||
|
added_at DateTime @default(now())
|
||||||
|
|
||||||
|
group Group @relation(fields: [group_id], references: [id])
|
||||||
|
user User @relation(fields: [user_id], references: [id])
|
||||||
|
|
||||||
|
@@id([group_id, user_id])
|
||||||
|
@@index([user_id])
|
||||||
|
@@map("group_members")
|
||||||
|
}
|
||||||
|
|
||||||
|
model BlockedSlot {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
user_id String
|
||||||
|
start_time DateTime
|
||||||
|
end_time DateTime
|
||||||
|
reason String?
|
||||||
|
is_recurring Boolean @default(false)
|
||||||
|
rrule String?
|
||||||
|
recurrence_end_date DateTime?
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
updated_at DateTime @updatedAt
|
||||||
|
|
||||||
|
user User @relation(fields: [user_id], references: [id])
|
||||||
|
|
||||||
|
@@index([user_id, start_time, end_time])
|
||||||
|
@@index([user_id, is_recurring])
|
||||||
|
@@map("blocked_slots")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Meeting {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
title String
|
||||||
|
description String?
|
||||||
|
start_time DateTime
|
||||||
|
end_time DateTime
|
||||||
|
organizer_id String
|
||||||
|
location String?
|
||||||
|
status meeting_status @default(CONFIRMED)
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
updated_at DateTime @updatedAt
|
||||||
|
|
||||||
|
organizer User @relation("MeetingOrganizer", fields: [organizer_id], references: [id])
|
||||||
|
participants MeetingParticipant[]
|
||||||
|
|
||||||
|
@@index([start_time, end_time])
|
||||||
|
@@index([organizer_id])
|
||||||
|
@@index([status])
|
||||||
|
@@map("meetings")
|
||||||
|
}
|
||||||
|
|
||||||
|
model MeetingParticipant {
|
||||||
|
meeting_id String
|
||||||
|
user_id String
|
||||||
|
status participant_status @default(PENDING)
|
||||||
|
added_at DateTime @default(now())
|
||||||
|
|
||||||
|
meeting Meeting @relation(fields: [meeting_id], references: [id])
|
||||||
|
user User @relation(fields: [user_id], references: [id])
|
||||||
|
|
||||||
|
@@id([meeting_id, user_id])
|
||||||
|
@@index([user_id, status], name: "idx_participants_user_status")
|
||||||
|
@@map("meeting_participants")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Notification {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
user_id String
|
||||||
|
type notification_type
|
||||||
|
related_entity_type String?
|
||||||
|
related_entity_id String?
|
||||||
|
message String
|
||||||
|
is_read Boolean @default(false)
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
|
||||||
|
user User @relation(fields: [user_id], references: [id])
|
||||||
|
|
||||||
|
@@index([user_id, is_read, created_at], name: "idx_notifications_user_read_time")
|
||||||
|
@@map("notifications")
|
||||||
|
}
|
||||||
|
|
||||||
|
model UserNotificationPreference {
|
||||||
|
user_id String
|
||||||
|
notification_type notification_type
|
||||||
|
email_enabled Boolean @default(false)
|
||||||
|
updated_at DateTime @default(now())
|
||||||
|
|
||||||
|
user User @relation(fields: [user_id], references: [id])
|
||||||
|
|
||||||
|
@@id([user_id, notification_type])
|
||||||
|
@@map("user_notification_preferences")
|
||||||
|
}
|
||||||
|
|
||||||
|
model EmailQueue {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
user_id String
|
||||||
|
subject String
|
||||||
|
body_html String
|
||||||
|
body_text String?
|
||||||
|
status email_queue_status @default(PENDING)
|
||||||
|
scheduled_at DateTime @default(now())
|
||||||
|
attempts Int @default(0)
|
||||||
|
last_attempt_at DateTime?
|
||||||
|
sent_at DateTime?
|
||||||
|
error_message String?
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
updated_at DateTime @updatedAt
|
||||||
|
|
||||||
|
user User @relation(fields: [user_id], references: [id])
|
||||||
|
|
||||||
|
@@index([status, scheduled_at], name: "idx_email_queue_pending_jobs")
|
||||||
|
@@index([user_id, created_at], name: "idx_email_queue_user_history")
|
||||||
|
@@map("email_queue")
|
||||||
|
}
|
||||||
|
|
||||||
|
model CalendarExportToken {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
user_id String
|
||||||
|
token String @unique
|
||||||
|
scope calendar_export_scope @default(MEETINGS_ONLY)
|
||||||
|
is_active Boolean @default(true)
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
last_accessed_at DateTime?
|
||||||
|
|
||||||
|
user User @relation(fields: [user_id], references: [id])
|
||||||
|
|
||||||
|
@@index([user_id])
|
||||||
|
@@map("calendar_export_tokens")
|
||||||
|
}
|
||||||
|
|
||||||
|
model CalendarSubscription {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
user_id String
|
||||||
|
feed_url String
|
||||||
|
name String?
|
||||||
|
color String?
|
||||||
|
is_enabled Boolean @default(true)
|
||||||
|
last_synced_at DateTime?
|
||||||
|
last_sync_error String?
|
||||||
|
sync_frequency_minutes Int? @default(60)
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
updated_at DateTime @updatedAt
|
||||||
|
|
||||||
|
user User @relation(fields: [user_id], references: [id])
|
||||||
|
externalEvents ExternalEvent[]
|
||||||
|
|
||||||
|
@@index([user_id, is_enabled])
|
||||||
|
@@map("calendar_subscriptions")
|
||||||
|
}
|
||||||
|
|
||||||
|
model ExternalEvent {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
subscription_id String
|
||||||
|
ical_uid String
|
||||||
|
summary String?
|
||||||
|
description String?
|
||||||
|
start_time DateTime
|
||||||
|
end_time DateTime
|
||||||
|
is_all_day Boolean @default(false)
|
||||||
|
location String?
|
||||||
|
rrule String?
|
||||||
|
dtstamp DateTime?
|
||||||
|
sequence Int?
|
||||||
|
show_as_free Boolean @default(false)
|
||||||
|
last_fetched_at DateTime @default(now())
|
||||||
|
|
||||||
|
subscription CalendarSubscription @relation(fields: [subscription_id], references: [id])
|
||||||
|
|
||||||
|
@@unique([subscription_id, ical_uid], name: "uq_external_event_sub_uid")
|
||||||
|
@@index([subscription_id, start_time, end_time])
|
||||||
|
@@index([subscription_id, show_as_free])
|
||||||
|
@@map("external_events")
|
||||||
}
|
}
|
|
@ -5,6 +5,9 @@ import Credentials from 'next-auth/providers/credentials';
|
||||||
|
|
||||||
import Authentik from 'next-auth/providers/authentik';
|
import Authentik from 'next-auth/providers/authentik';
|
||||||
|
|
||||||
|
import { PrismaAdapter } from '@auth/prisma-adapter';
|
||||||
|
import { prisma } from '@/prisma';
|
||||||
|
|
||||||
const providers: Provider[] = [
|
const providers: Provider[] = [
|
||||||
!process.env.DISABLE_PASSWORD_LOGIN &&
|
!process.env.DISABLE_PASSWORD_LOGIN &&
|
||||||
Credentials({
|
Credentials({
|
||||||
|
@ -34,6 +37,7 @@ export const providerMap = providers
|
||||||
|
|
||||||
export const { handlers, signIn, signOut, auth } = NextAuth({
|
export const { handlers, signIn, signOut, auth } = NextAuth({
|
||||||
providers,
|
providers,
|
||||||
micha.bok marked this conversation as resolved
Outdated
dominik
commented
ist das gleiche wie
Die provider sind in der Datei weiter oben definiert. deshalb bitte nicht auf ein leeres Array setzen, sondern wieder auf ```
providers,
```
ist das gleiche wie
```
providers: providers,
```
Die provider sind in der Datei weiter oben definiert. deshalb bitte nicht auf ein leeres Array setzen, sondern wieder auf `providers`.
|
|||||||
|
adapter: PrismaAdapter(prisma),
|
||||||
session: {
|
session: {
|
||||||
strategy: 'jwt',
|
strategy: 'jwt',
|
||||||
},
|
},
|
||||||
|
|
7
src/prisma.ts
Normal file
7
src/prisma.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { PrismaClient } from '@/generated/prisma';
|
||||||
micha.bok marked this conversation as resolved
Outdated
dominik
commented
Hier muss der prisma client aus dem generated Ordner importiert werden, sonst gibt es Fehlermeldungen.
Hier muss der prisma client aus dem generated Ordner importiert werden, sonst gibt es Fehlermeldungen.
```
@/generated/prisma
```
|
|||||||
|
|
||||||
|
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
|
||||||
|
|
||||||
|
export const prisma = globalForPrisma.prisma || new PrismaClient();
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
|
100
yarn.lock
100
yarn.lock
|
@ -46,7 +46,18 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@emnapi/core@npm:^1.4.0, @emnapi/core@npm:^1.4.3":
|
"@auth/prisma-adapter@npm:^2.9.1":
|
||||||
|
version: 2.9.1
|
||||||
|
resolution: "@auth/prisma-adapter@npm:2.9.1"
|
||||||
|
dependencies:
|
||||||
|
"@auth/core": "npm:0.39.1"
|
||||||
|
peerDependencies:
|
||||||
|
"@prisma/client": ">=2.26.0 || >=3 || >=4 || >=5 || >=6"
|
||||||
|
checksum: 10c0/615ee7c02f690e35ccac8206607a4345ca6455c322a741ddd4dbd52e7a068ace9e5c46c4d8a50fe471ca2c2fb6a5b4bb9924cbd2e911613f671fe929c33278d4
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@emnapi/core@npm:^1.4.3":
|
||||||
version: 1.4.3
|
version: 1.4.3
|
||||||
resolution: "@emnapi/core@npm:1.4.3"
|
resolution: "@emnapi/core@npm:1.4.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -525,13 +536,13 @@ __metadata:
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@napi-rs/wasm-runtime@npm:^0.2.9":
|
"@napi-rs/wasm-runtime@npm:^0.2.9":
|
||||||
version: 0.2.9
|
version: 0.2.10
|
||||||
resolution: "@napi-rs/wasm-runtime@npm:0.2.9"
|
resolution: "@napi-rs/wasm-runtime@npm:0.2.10"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@emnapi/core": "npm:^1.4.0"
|
"@emnapi/core": "npm:^1.4.3"
|
||||||
"@emnapi/runtime": "npm:^1.4.0"
|
"@emnapi/runtime": "npm:^1.4.3"
|
||||||
"@tybys/wasm-util": "npm:^0.9.0"
|
"@tybys/wasm-util": "npm:^0.9.0"
|
||||||
checksum: 10c0/1cc40b854b255f84e12ade634456ba489f6bf90659ef8164a16823c515c294024c96ee2bb81ab51f35493ba9496f62842b960f915dbdcdc1791f221f989e9e59
|
checksum: 10c0/4dce9bbb94a8969805574e1b55fdbeb7623348190265d77f6507ba32e535610deeb53a33ba0bb8b05a6520f379d418b92e8a01c5cd7b9486b136d2c0c26be0bd
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -648,6 +659,21 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@prisma/client@npm:^6.8.2":
|
||||||
|
version: 6.8.2
|
||||||
|
resolution: "@prisma/client@npm:6.8.2"
|
||||||
|
peerDependencies:
|
||||||
|
prisma: "*"
|
||||||
|
typescript: ">=5.1.0"
|
||||||
|
peerDependenciesMeta:
|
||||||
|
prisma:
|
||||||
|
optional: true
|
||||||
|
typescript:
|
||||||
|
optional: true
|
||||||
|
checksum: 10c0/5ce12e4a83ece542df80195f6642e24224de8f94c2f2fd26527ca6b3a2573ea9798b5d23eac8518d8f268be19f3856516ad4e08c9bc0a4df4356a5faab879db6
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@prisma/config@npm:6.8.2":
|
"@prisma/config@npm:6.8.2":
|
||||||
version: 6.8.2
|
version: 6.8.2
|
||||||
resolution: "@prisma/config@npm:6.8.2"
|
resolution: "@prisma/config@npm:6.8.2"
|
||||||
|
@ -1915,11 +1941,11 @@ __metadata:
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"aria-hidden@npm:^1.2.4":
|
"aria-hidden@npm:^1.2.4":
|
||||||
version: 1.2.4
|
version: 1.2.6
|
||||||
resolution: "aria-hidden@npm:1.2.4"
|
resolution: "aria-hidden@npm:1.2.6"
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib: "npm:^2.0.0"
|
tslib: "npm:^2.0.0"
|
||||||
checksum: 10c0/8abcab2e1432efc4db415e97cb3959649ddf52c8fc815d7384f43f3d3abf56f1c12852575d00df9a8927f421d7e0712652dd5f8db244ea57634344e29ecfc74a
|
checksum: 10c0/7720cb539497a9f760f68f98a4b30f22c6767aa0e72fa7d58279f7c164e258fc38b2699828f8de881aab0fc8e9c56d1313a3f1a965046fc0381a554dbc72b54a
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -2376,6 +2402,34 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"dotenv-cli@npm:8.0.0":
|
||||||
|
version: 8.0.0
|
||||||
|
resolution: "dotenv-cli@npm:8.0.0"
|
||||||
|
dependencies:
|
||||||
|
cross-spawn: "npm:^7.0.6"
|
||||||
|
dotenv: "npm:^16.3.0"
|
||||||
|
dotenv-expand: "npm:^10.0.0"
|
||||||
|
minimist: "npm:^1.2.6"
|
||||||
|
bin:
|
||||||
|
dotenv: cli.js
|
||||||
|
checksum: 10c0/000469632758b7b44aaaa80cbbbd7f0c94dc170ec02e51aa8d8280341a0108fb7407954c23054257b77235b064033efdb8745836633eb6fd1586924953cf0528
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"dotenv-expand@npm:^10.0.0":
|
||||||
|
version: 10.0.0
|
||||||
|
resolution: "dotenv-expand@npm:10.0.0"
|
||||||
|
checksum: 10c0/298f5018e29cfdcb0b5f463ba8e8627749103fbcf6cf81c561119115754ed582deee37b49dfc7253028aaba875ab7aea5fa90e5dac88e511d009ab0e6677924e
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"dotenv@npm:^16.3.0":
|
||||||
|
version: 16.5.0
|
||||||
|
resolution: "dotenv@npm:16.5.0"
|
||||||
|
checksum: 10c0/5bc94c919fbd955bf0ba44d33922a1e93d1078e64a1db5c30faeded1d996e7a83c55332cb8ea4fae5a9ca4d0be44cbceb95c5811e70f9f095298df09d1997dd9
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1":
|
"dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1":
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
resolution: "dunder-proto@npm:1.0.1"
|
resolution: "dunder-proto@npm:1.0.1"
|
||||||
|
@ -3747,12 +3801,14 @@ __metadata:
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "meetup@workspace:."
|
resolution: "meetup@workspace:."
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@auth/prisma-adapter": "npm:^2.9.1"
|
||||||
"@eslint/eslintrc": "npm:3.3.1"
|
"@eslint/eslintrc": "npm:3.3.1"
|
||||||
"@fortawesome/fontawesome-svg-core": "npm:^6.7.2"
|
"@fortawesome/fontawesome-svg-core": "npm:^6.7.2"
|
||||||
"@fortawesome/free-brands-svg-icons": "npm:^6.7.2"
|
"@fortawesome/free-brands-svg-icons": "npm:^6.7.2"
|
||||||
"@fortawesome/free-regular-svg-icons": "npm:^6.7.2"
|
"@fortawesome/free-regular-svg-icons": "npm:^6.7.2"
|
||||||
"@fortawesome/free-solid-svg-icons": "npm:^6.7.2"
|
"@fortawesome/free-solid-svg-icons": "npm:^6.7.2"
|
||||||
"@fortawesome/react-fontawesome": "npm:^0.2.2"
|
"@fortawesome/react-fontawesome": "npm:^0.2.2"
|
||||||
|
"@prisma/client": "npm:^6.8.2"
|
||||||
"@radix-ui/react-dropdown-menu": "npm:^2.1.14"
|
"@radix-ui/react-dropdown-menu": "npm:^2.1.14"
|
||||||
"@radix-ui/react-hover-card": "npm:^1.1.13"
|
"@radix-ui/react-hover-card": "npm:^1.1.13"
|
||||||
"@radix-ui/react-label": "npm:^2.1.6"
|
"@radix-ui/react-label": "npm:^2.1.6"
|
||||||
|
@ -3768,6 +3824,7 @@ __metadata:
|
||||||
"@types/react-dom": "npm:19.1.5"
|
"@types/react-dom": "npm:19.1.5"
|
||||||
class-variance-authority: "npm:^0.7.1"
|
class-variance-authority: "npm:^0.7.1"
|
||||||
clsx: "npm:^2.1.1"
|
clsx: "npm:^2.1.1"
|
||||||
|
dotenv-cli: "npm:8.0.0"
|
||||||
eslint: "npm:9.27.0"
|
eslint: "npm:9.27.0"
|
||||||
eslint-config-next: "npm:15.3.2"
|
eslint-config-next: "npm:15.3.2"
|
||||||
eslint-config-prettier: "npm:10.1.5"
|
eslint-config-prettier: "npm:10.1.5"
|
||||||
|
@ -3781,8 +3838,8 @@ __metadata:
|
||||||
react: "npm:^19.0.0"
|
react: "npm:^19.0.0"
|
||||||
react-dom: "npm:^19.0.0"
|
react-dom: "npm:^19.0.0"
|
||||||
tailwind-merge: "npm:^3.2.0"
|
tailwind-merge: "npm:^3.2.0"
|
||||||
tailwindcss: "npm:4.1.7"
|
tailwindcss: "npm:4.1.6"
|
||||||
tw-animate-css: "npm:1.3.0"
|
tw-animate-css: "npm:1.2.9"
|
||||||
typescript: "npm:5.8.3"
|
typescript: "npm:5.8.3"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
@ -4300,8 +4357,8 @@ __metadata:
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"react-remove-scroll@npm:^2.6.3":
|
"react-remove-scroll@npm:^2.6.3":
|
||||||
version: 2.6.3
|
version: 2.7.0
|
||||||
resolution: "react-remove-scroll@npm:2.6.3"
|
resolution: "react-remove-scroll@npm:2.7.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
react-remove-scroll-bar: "npm:^2.3.7"
|
react-remove-scroll-bar: "npm:^2.3.7"
|
||||||
react-style-singleton: "npm:^2.2.3"
|
react-style-singleton: "npm:^2.2.3"
|
||||||
|
@ -4314,7 +4371,7 @@ __metadata:
|
||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
"@types/react":
|
"@types/react":
|
||||||
optional: true
|
optional: true
|
||||||
checksum: 10c0/068e9704ff26816fffc4c8903e2c6c8df7291ee08615d7c1ab0cf8751f7080e2c5a5d78ef5d908b11b9cfc189f176d312e44cb02ea291ca0466d8283b479b438
|
checksum: 10c0/cf8b9a1b0808cafe9f2b1fbb2ab56e3efff7f311fba847f26154b972a681c003c288af517cf48d0b68704c2be0d3d73152e7ec2cc8590fa495135b0aac07a871
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -4848,6 +4905,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"tailwindcss@npm:4.1.6":
|
||||||
|
version: 4.1.6
|
||||||
|
resolution: "tailwindcss@npm:4.1.6"
|
||||||
|
checksum: 10c0/de5a442d23d20872bfccb2b451720e8031dde27e1984a1ccb1d8c7308915213f1b3b62724ce5176d1b7031fbedc6a75fe844b73e3f13443141c11739447d8808
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"tailwindcss@npm:4.1.7":
|
"tailwindcss@npm:4.1.7":
|
||||||
version: 4.1.7
|
version: 4.1.7
|
||||||
resolution: "tailwindcss@npm:4.1.7"
|
resolution: "tailwindcss@npm:4.1.7"
|
||||||
|
@ -4923,10 +4987,10 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"tw-animate-css@npm:1.3.0":
|
"tw-animate-css@npm:1.2.9":
|
||||||
version: 1.3.0
|
version: 1.2.9
|
||||||
resolution: "tw-animate-css@npm:1.3.0"
|
resolution: "tw-animate-css@npm:1.2.9"
|
||||||
checksum: 10c0/c72a2c189d6aebd6cc31189c3ca1cf4cf2c3f37f005d0879cd40cfdd6550bfb665384e9a50b91dfc9befe9860ff09adb536a7f7431bf18132aef7e04734a02f2
|
checksum: 10c0/ffbd6dfbb34490a8752b185b40192168ce4bfa69949d153dc831d9471dec2758501f27f1784b6615de7da73a546d01d7201ed691f5220fe3e0a53694cb275a3a
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue
Bitte auch den generated ordner von prisma hier excluden