diff --git a/nuxt.config.ts b/nuxt.config.ts index ceef7f6..69d7fdd 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -17,6 +17,46 @@ export default defineNuxtConfig({ nitro: { modules: ['nitro-graphql'], + hooks: { + compiled: async () => { + // Migration dosyalarını build output'a kopyala + const { copyFileSync, existsSync, mkdirSync, readdirSync, statSync } = await import('node:fs') + const { join } = await import('node:path') + + const copyDirectory = (source: string, target: string) => { + if (!existsSync(source)) + return + + const files = readdirSync(source) + + for (const file of files) { + const sourcePath = join(source, file) + const targetPath = join(target, file) + + if (statSync(sourcePath).isDirectory()) { + if (!existsSync(targetPath)) { + mkdirSync(targetPath, { recursive: true }) + } + copyDirectory(sourcePath, targetPath) + } + else { + copyFileSync(sourcePath, targetPath) + } + } + } + + const migrationsSource = './server/database/migrations' + const migrationsTarget = './.output/server/migrations' + + if (existsSync(migrationsSource)) { + console.log('[build] Copying migration files to build directory...') + // Hedef klasörü oluştur + mkdirSync(migrationsTarget, { recursive: true }) + copyDirectory(migrationsSource, migrationsTarget) + console.log('[build] ✅ Migration files copied successfully') + } + }, + }, graphql: { framework: 'graphql-yoga', codegen: { diff --git a/package.json b/package.json index e286f56..e53c2c6 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "db:push": "drizzle-kit push --config ./server/drizzle.config.ts", "db:drop": "drizzle-kit drop --config ./server/drizzle.config.ts", "db:up": "drizzle-kit up --config ./server/drizzle.config.ts", + "db:pull": "drizzle-kit pull --config ./server/drizzle.config.ts", "db:check": "drizzle-kit check --config ./server/drizzle.config.ts", "db:studio": "drizzle-kit studio", "test": "vitest", diff --git a/server/database/migrations/0000_jazzy_jackpot.sql b/server/database/migrations/0000_jazzy_jackpot.sql new file mode 100644 index 0000000..36b42fb --- /dev/null +++ b/server/database/migrations/0000_jazzy_jackpot.sql @@ -0,0 +1,152 @@ +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'delivery_status') THEN + CREATE TYPE "public"."delivery_status" AS ENUM('PENDING', 'SENT', 'DELIVERED', 'FAILED', 'CLICKED'); + END IF; +END $$;--> statement-breakpoint +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'device_status') THEN + CREATE TYPE "public"."device_status" AS ENUM('ACTIVE', 'INACTIVE', 'EXPIRED'); + END IF; +END $$;--> statement-breakpoint +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'notification_status') THEN + CREATE TYPE "public"."notification_status" AS ENUM('PENDING', 'SENT', 'DELIVERED', 'FAILED', 'SCHEDULED'); + END IF; +END $$;--> statement-breakpoint +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'platform') THEN + CREATE TYPE "public"."platform" AS ENUM('IOS', 'ANDROID', 'WEB'); + END IF; +END $$;--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "apiKey" ( + "id" uuid PRIMARY KEY NOT NULL, + "appId" uuid NOT NULL, + "name" text NOT NULL, + "key" text NOT NULL, + "permissions" jsonb, + "isActive" boolean DEFAULT true, + "lastUsedAt" timestamp(3) with time zone, + "expiresAt" timestamp(3) with time zone, + "createdAt" timestamp(3) with time zone DEFAULT now() NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT now() NOT NULL, + CONSTRAINT "apiKey_key_unique" UNIQUE("key") +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "app" ( + "id" uuid PRIMARY KEY NOT NULL, + "name" text NOT NULL, + "slug" text NOT NULL, + "description" text, + "apiKey" text NOT NULL, + "fcmServerKey" text, + "fcmProjectId" text, + "apnsCertificate" text, + "apnsKeyId" text, + "apnsTeamId" text, + "bundleId" text, + "vapidPublicKey" text, + "vapidPrivateKey" text, + "vapidSubject" text, + "isActive" boolean DEFAULT true NOT NULL, + "createdAt" timestamp(3) with time zone DEFAULT now() NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT now() NOT NULL, + CONSTRAINT "app_slug_unique" UNIQUE("slug"), + CONSTRAINT "app_apiKey_unique" UNIQUE("apiKey") +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "deliveryLog" ( + "id" uuid PRIMARY KEY NOT NULL, + "notificationId" uuid NOT NULL, + "deviceId" uuid NOT NULL, + "status" "delivery_status" NOT NULL, + "providerResponse" jsonb, + "errorMessage" text, + "attemptCount" integer DEFAULT 1, + "sentAt" timestamp(3) with time zone, + "deliveredAt" timestamp(3) with time zone, + "openedAt" timestamp(3) with time zone, + "clickedAt" timestamp(3) with time zone, + "platform" text, + "userAgent" text, + "appVersion" text, + "osVersion" text, + "createdAt" timestamp(3) with time zone DEFAULT now() NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT now() NOT NULL, + CONSTRAINT "deliveryLog_notificationId_deviceId_unique" UNIQUE("notificationId","deviceId") +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "device" ( + "id" uuid PRIMARY KEY NOT NULL, + "appId" uuid NOT NULL, + "token" text NOT NULL, + "platform" "platform" NOT NULL, + "userId" text, + "status" "device_status" DEFAULT 'ACTIVE' NOT NULL, + "metadata" jsonb, + "lastSeenAt" timestamp(3) with time zone, + "createdAt" timestamp(3) with time zone DEFAULT now() NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT now() NOT NULL, + CONSTRAINT "device_appId_token_userId_unique" UNIQUE("appId","token","userId") +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "notification" ( + "id" uuid PRIMARY KEY NOT NULL, + "appId" uuid NOT NULL, + "title" text NOT NULL, + "body" text NOT NULL, + "data" jsonb, + "badge" integer, + "sound" text, + "clickAction" text, + "icon" text, + "image" text, + "imageUrl" text, + "targetDevices" jsonb, + "platforms" jsonb, + "scheduledAt" timestamp(3) with time zone, + "expiresAt" timestamp(3) with time zone, + "status" "notification_status" DEFAULT 'PENDING' NOT NULL, + "totalTargets" integer DEFAULT 0 NOT NULL, + "totalSent" integer DEFAULT 0 NOT NULL, + "totalDelivered" integer DEFAULT 0 NOT NULL, + "totalFailed" integer DEFAULT 0 NOT NULL, + "totalClicked" integer DEFAULT 0 NOT NULL, + "sentAt" timestamp(3) with time zone, + "createdAt" timestamp(3) with time zone DEFAULT now() NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'apiKey_appId_app_id_fk') THEN + ALTER TABLE "apiKey" ADD CONSTRAINT "apiKey_appId_app_id_fk" FOREIGN KEY ("appId") REFERENCES "public"."app"("id") ON DELETE cascade ON UPDATE no action; + END IF; +END $$;--> statement-breakpoint +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'deliveryLog_notificationId_notification_id_fk') THEN + ALTER TABLE "deliveryLog" ADD CONSTRAINT "deliveryLog_notificationId_notification_id_fk" FOREIGN KEY ("notificationId") REFERENCES "public"."notification"("id") ON DELETE cascade ON UPDATE no action; + END IF; +END $$;--> statement-breakpoint +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'deliveryLog_deviceId_device_id_fk') THEN + ALTER TABLE "deliveryLog" ADD CONSTRAINT "deliveryLog_deviceId_device_id_fk" FOREIGN KEY ("deviceId") REFERENCES "public"."device"("id") ON DELETE cascade ON UPDATE no action; + END IF; +END $$;--> statement-breakpoint +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'device_appId_app_id_fk') THEN + ALTER TABLE "device" ADD CONSTRAINT "device_appId_app_id_fk" FOREIGN KEY ("appId") REFERENCES "public"."app"("id") ON DELETE cascade ON UPDATE no action; + END IF; +END $$;--> statement-breakpoint +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'notification_appId_app_id_fk') THEN + ALTER TABLE "notification" ADD CONSTRAINT "notification_appId_app_id_fk" FOREIGN KEY ("appId") REFERENCES "public"."app"("id") ON DELETE cascade ON UPDATE no action; + END IF; +END $$; \ No newline at end of file diff --git a/server/database/migrations/0000_open_master_mold.sql b/server/database/migrations/0000_open_master_mold.sql deleted file mode 100644 index ef099d5..0000000 --- a/server/database/migrations/0000_open_master_mold.sql +++ /dev/null @@ -1,95 +0,0 @@ -CREATE TYPE "public"."device_status" AS ENUM('ACTIVE', 'INACTIVE', 'EXPIRED');--> statement-breakpoint -CREATE TYPE "public"."notification_status" AS ENUM('PENDING', 'SENT', 'DELIVERED', 'FAILED', 'SCHEDULED');--> statement-breakpoint -CREATE TYPE "public"."platform" AS ENUM('IOS', 'ANDROID', 'WEB');--> statement-breakpoint -CREATE TABLE "apiKey" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "appId" uuid NOT NULL, - "name" text NOT NULL, - "key" text NOT NULL, - "permissions" jsonb, - "isActive" boolean DEFAULT true, - "lastUsedAt" timestamp, - "expiresAt" timestamp, - "createdAt" timestamp DEFAULT now(), - "updatedAt" timestamp DEFAULT now(), - CONSTRAINT "apiKey_key_unique" UNIQUE("key") -); ---> statement-breakpoint -CREATE TABLE "app" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "name" text NOT NULL, - "slug" text NOT NULL, - "description" text, - "apiKey" text NOT NULL, - "fcmServerKey" text, - "fcmProjectId" text, - "apnsCertificate" text, - "apnsKeyId" text, - "apnsTeamId" text, - "bundleId" text, - "vapidPublicKey" text, - "vapidPrivateKey" text, - "vapidSubject" text, - "isActive" boolean DEFAULT true, - "createdAt" timestamp DEFAULT now(), - "updatedAt" timestamp DEFAULT now(), - CONSTRAINT "app_slug_unique" UNIQUE("slug"), - CONSTRAINT "app_apiKey_unique" UNIQUE("apiKey") -); ---> statement-breakpoint -CREATE TABLE "deliveryLog" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "notificationId" uuid NOT NULL, - "deviceId" uuid NOT NULL, - "status" "notification_status" NOT NULL, - "providerResponse" jsonb, - "errorMessage" text, - "attemptCount" integer DEFAULT 1, - "sentAt" timestamp, - "deliveredAt" timestamp, - "createdAt" timestamp DEFAULT now() -); ---> statement-breakpoint -CREATE TABLE "device" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "appId" uuid NOT NULL, - "token" text NOT NULL, - "platform" "platform" NOT NULL, - "userId" text, - "status" "device_status" DEFAULT 'ACTIVE', - "metadata" jsonb, - "lastSeenAt" timestamp, - "createdAt" timestamp DEFAULT now(), - "updatedAt" timestamp DEFAULT now() -); ---> statement-breakpoint -CREATE TABLE "notification" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "appId" uuid NOT NULL, - "title" text NOT NULL, - "body" text NOT NULL, - "data" jsonb, - "badge" integer, - "sound" text, - "clickAction" text, - "icon" text, - "image" text, - "targetDevices" jsonb, - "platforms" jsonb, - "scheduledAt" timestamp, - "expiresAt" timestamp, - "status" "notification_status" DEFAULT 'PENDING', - "totalTargets" integer DEFAULT 0, - "totalSent" integer DEFAULT 0, - "totalDelivered" integer DEFAULT 0, - "totalFailed" integer DEFAULT 0, - "totalClicked" integer DEFAULT 0, - "createdAt" timestamp DEFAULT now(), - "updatedAt" timestamp DEFAULT now() -); ---> statement-breakpoint -ALTER TABLE "apiKey" ADD CONSTRAINT "apiKey_appId_app_id_fk" FOREIGN KEY ("appId") REFERENCES "public"."app"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint -ALTER TABLE "deliveryLog" ADD CONSTRAINT "deliveryLog_notificationId_notification_id_fk" FOREIGN KEY ("notificationId") REFERENCES "public"."notification"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint -ALTER TABLE "deliveryLog" ADD CONSTRAINT "deliveryLog_deviceId_device_id_fk" FOREIGN KEY ("deviceId") REFERENCES "public"."device"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint -ALTER TABLE "device" ADD CONSTRAINT "device_appId_app_id_fk" FOREIGN KEY ("appId") REFERENCES "public"."app"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint -ALTER TABLE "notification" ADD CONSTRAINT "notification_appId_app_id_fk" FOREIGN KEY ("appId") REFERENCES "public"."app"("id") ON DELETE cascade ON UPDATE no action; \ No newline at end of file diff --git a/server/database/migrations/0001_flowery_dexter_bennett.sql b/server/database/migrations/0001_flowery_dexter_bennett.sql deleted file mode 100644 index cfc31b8..0000000 --- a/server/database/migrations/0001_flowery_dexter_bennett.sql +++ /dev/null @@ -1,6 +0,0 @@ -ALTER TABLE "deliveryLog" ADD COLUMN "openedAt" timestamp;--> statement-breakpoint -ALTER TABLE "deliveryLog" ADD COLUMN "clickedAt" timestamp;--> statement-breakpoint -ALTER TABLE "deliveryLog" ADD COLUMN "platform" text;--> statement-breakpoint -ALTER TABLE "deliveryLog" ADD COLUMN "userAgent" text;--> statement-breakpoint -ALTER TABLE "deliveryLog" ADD COLUMN "appVersion" text;--> statement-breakpoint -ALTER TABLE "deliveryLog" ADD COLUMN "osVersion" text; \ No newline at end of file diff --git a/server/database/migrations/0002_dapper_moon_knight.sql b/server/database/migrations/0002_dapper_moon_knight.sql deleted file mode 100644 index ab37524..0000000 --- a/server/database/migrations/0002_dapper_moon_knight.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "deliveryLog" ADD CONSTRAINT "deliveryLog_notificationId_deviceId_unique" UNIQUE("notificationId","deviceId"); \ No newline at end of file diff --git a/server/database/migrations/0003_warm_legion.sql b/server/database/migrations/0003_warm_legion.sql deleted file mode 100644 index 8e61417..0000000 --- a/server/database/migrations/0003_warm_legion.sql +++ /dev/null @@ -1,54 +0,0 @@ -CREATE TYPE "public"."delivery_status" AS ENUM('PENDING', 'SENT', 'DELIVERED', 'FAILED', 'CLICKED');--> statement-breakpoint -ALTER TABLE "apiKey" ALTER COLUMN "id" DROP DEFAULT;--> statement-breakpoint -ALTER TABLE "apiKey" ALTER COLUMN "lastUsedAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "apiKey" ALTER COLUMN "expiresAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "apiKey" ALTER COLUMN "createdAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "apiKey" ALTER COLUMN "createdAt" SET DEFAULT now();--> statement-breakpoint -ALTER TABLE "apiKey" ALTER COLUMN "createdAt" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "apiKey" ALTER COLUMN "updatedAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "apiKey" ALTER COLUMN "updatedAt" SET DEFAULT now();--> statement-breakpoint -ALTER TABLE "apiKey" ALTER COLUMN "updatedAt" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "app" ALTER COLUMN "id" DROP DEFAULT;--> statement-breakpoint -ALTER TABLE "app" ALTER COLUMN "isActive" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "app" ALTER COLUMN "createdAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "app" ALTER COLUMN "createdAt" SET DEFAULT now();--> statement-breakpoint -ALTER TABLE "app" ALTER COLUMN "createdAt" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "app" ALTER COLUMN "updatedAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "app" ALTER COLUMN "updatedAt" SET DEFAULT now();--> statement-breakpoint -ALTER TABLE "app" ALTER COLUMN "updatedAt" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "deliveryLog" ALTER COLUMN "id" DROP DEFAULT;--> statement-breakpoint -ALTER TABLE "deliveryLog" ALTER COLUMN "status" SET DATA TYPE "public"."delivery_status" USING "status"::text::"public"."delivery_status";--> statement-breakpoint -ALTER TABLE "deliveryLog" ALTER COLUMN "sentAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "deliveryLog" ALTER COLUMN "deliveredAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "deliveryLog" ALTER COLUMN "openedAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "deliveryLog" ALTER COLUMN "clickedAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "deliveryLog" ALTER COLUMN "createdAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "deliveryLog" ALTER COLUMN "createdAt" SET DEFAULT now();--> statement-breakpoint -ALTER TABLE "deliveryLog" ALTER COLUMN "createdAt" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "device" ALTER COLUMN "id" DROP DEFAULT;--> statement-breakpoint -ALTER TABLE "device" ALTER COLUMN "status" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "device" ALTER COLUMN "lastSeenAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "device" ALTER COLUMN "createdAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "device" ALTER COLUMN "createdAt" SET DEFAULT now();--> statement-breakpoint -ALTER TABLE "device" ALTER COLUMN "createdAt" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "device" ALTER COLUMN "updatedAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "device" ALTER COLUMN "updatedAt" SET DEFAULT now();--> statement-breakpoint -ALTER TABLE "device" ALTER COLUMN "updatedAt" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "notification" ALTER COLUMN "id" DROP DEFAULT;--> statement-breakpoint -ALTER TABLE "notification" ALTER COLUMN "scheduledAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "notification" ALTER COLUMN "expiresAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "notification" ALTER COLUMN "status" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "notification" ALTER COLUMN "totalTargets" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "notification" ALTER COLUMN "totalSent" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "notification" ALTER COLUMN "totalDelivered" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "notification" ALTER COLUMN "totalFailed" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "notification" ALTER COLUMN "totalClicked" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "notification" ALTER COLUMN "createdAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "notification" ALTER COLUMN "createdAt" SET DEFAULT now();--> statement-breakpoint -ALTER TABLE "notification" ALTER COLUMN "createdAt" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "notification" ALTER COLUMN "updatedAt" SET DATA TYPE timestamp(3) with time zone;--> statement-breakpoint -ALTER TABLE "notification" ALTER COLUMN "updatedAt" SET DEFAULT now();--> statement-breakpoint -ALTER TABLE "notification" ALTER COLUMN "updatedAt" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "deliveryLog" ADD COLUMN "updatedAt" timestamp(3) with time zone DEFAULT now() NOT NULL;--> statement-breakpoint -ALTER TABLE "notification" ADD COLUMN "imageUrl" text;--> statement-breakpoint -ALTER TABLE "notification" ADD COLUMN "sentAt" timestamp(3) with time zone; \ No newline at end of file diff --git a/server/database/migrations/0004_dry_switch.sql b/server/database/migrations/0004_dry_switch.sql deleted file mode 100644 index 5162d0c..0000000 --- a/server/database/migrations/0004_dry_switch.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "device" ADD CONSTRAINT "device_appId_token_userId_unique" UNIQUE("appId","token","userId"); \ No newline at end of file diff --git a/server/database/migrations/meta/0000_snapshot.json b/server/database/migrations/meta/0000_snapshot.json index da5d8b9..cdac154 100644 --- a/server/database/migrations/meta/0000_snapshot.json +++ b/server/database/migrations/meta/0000_snapshot.json @@ -1,5 +1,5 @@ { - "id": "31cf4594-9d2a-48fa-8cc7-444c78699d1f", + "id": "ee2d8092-bf88-4efd-b823-bd6b709305df", "prevId": "00000000-0000-0000-0000-000000000000", "version": "7", "dialect": "postgresql", @@ -12,8 +12,7 @@ "name": "id", "type": "uuid", "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" + "notNull": true }, "appId": { "name": "appId", @@ -48,28 +47,28 @@ }, "lastUsedAt": { "name": "lastUsedAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", "primaryKey": false, "notNull": false }, "expiresAt": { "name": "expiresAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", "primaryKey": false, "notNull": false }, "createdAt": { "name": "createdAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", "primaryKey": false, - "notNull": false, + "notNull": true, "default": "now()" }, "updatedAt": { "name": "updatedAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", "primaryKey": false, - "notNull": false, + "notNull": true, "default": "now()" } }, @@ -111,8 +110,7 @@ "name": "id", "type": "uuid", "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" + "notNull": true }, "name": { "name": "name", @@ -196,21 +194,21 @@ "name": "isActive", "type": "boolean", "primaryKey": false, - "notNull": false, + "notNull": true, "default": true }, "createdAt": { "name": "createdAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", "primaryKey": false, - "notNull": false, + "notNull": true, "default": "now()" }, "updatedAt": { "name": "updatedAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", "primaryKey": false, - "notNull": false, + "notNull": true, "default": "now()" } }, @@ -245,8 +243,7 @@ "name": "id", "type": "uuid", "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" + "notNull": true }, "notificationId": { "name": "notificationId", @@ -262,7 +259,7 @@ }, "status": { "name": "status", - "type": "notification_status", + "type": "delivery_status", "typeSchema": "public", "primaryKey": false, "notNull": true @@ -288,21 +285,64 @@ }, "sentAt": { "name": "sentAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", "primaryKey": false, "notNull": false }, "deliveredAt": { "name": "deliveredAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "openedAt": { + "name": "openedAt", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "clickedAt": { + "name": "clickedAt", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "userAgent": { + "name": "userAgent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "appVersion": { + "name": "appVersion", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "osVersion": { + "name": "osVersion", + "type": "text", "primaryKey": false, "notNull": false }, "createdAt": { "name": "createdAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", "primaryKey": false, - "notNull": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, "default": "now()" } }, @@ -336,7 +376,16 @@ } }, "compositePrimaryKeys": {}, - "uniqueConstraints": {}, + "uniqueConstraints": { + "deliveryLog_notificationId_deviceId_unique": { + "name": "deliveryLog_notificationId_deviceId_unique", + "nullsNotDistinct": false, + "columns": [ + "notificationId", + "deviceId" + ] + } + }, "policies": {}, "checkConstraints": {}, "isRLSEnabled": false @@ -349,8 +398,7 @@ "name": "id", "type": "uuid", "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" + "notNull": true }, "appId": { "name": "appId", @@ -382,7 +430,7 @@ "type": "device_status", "typeSchema": "public", "primaryKey": false, - "notNull": false, + "notNull": true, "default": "'ACTIVE'" }, "metadata": { @@ -393,22 +441,22 @@ }, "lastSeenAt": { "name": "lastSeenAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", "primaryKey": false, "notNull": false }, "createdAt": { "name": "createdAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", "primaryKey": false, - "notNull": false, + "notNull": true, "default": "now()" }, "updatedAt": { "name": "updatedAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", "primaryKey": false, - "notNull": false, + "notNull": true, "default": "now()" } }, @@ -429,7 +477,17 @@ } }, "compositePrimaryKeys": {}, - "uniqueConstraints": {}, + "uniqueConstraints": { + "device_appId_token_userId_unique": { + "name": "device_appId_token_userId_unique", + "nullsNotDistinct": false, + "columns": [ + "appId", + "token", + "userId" + ] + } + }, "policies": {}, "checkConstraints": {}, "isRLSEnabled": false @@ -442,8 +500,7 @@ "name": "id", "type": "uuid", "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" + "notNull": true }, "appId": { "name": "appId", @@ -499,6 +556,12 @@ "primaryKey": false, "notNull": false }, + "imageUrl": { + "name": "imageUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, "targetDevices": { "name": "targetDevices", "type": "jsonb", @@ -513,13 +576,13 @@ }, "scheduledAt": { "name": "scheduledAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", "primaryKey": false, "notNull": false }, "expiresAt": { "name": "expiresAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", "primaryKey": false, "notNull": false }, @@ -528,56 +591,62 @@ "type": "notification_status", "typeSchema": "public", "primaryKey": false, - "notNull": false, + "notNull": true, "default": "'PENDING'" }, "totalTargets": { "name": "totalTargets", "type": "integer", "primaryKey": false, - "notNull": false, + "notNull": true, "default": 0 }, "totalSent": { "name": "totalSent", "type": "integer", "primaryKey": false, - "notNull": false, + "notNull": true, "default": 0 }, "totalDelivered": { "name": "totalDelivered", "type": "integer", "primaryKey": false, - "notNull": false, + "notNull": true, "default": 0 }, "totalFailed": { "name": "totalFailed", "type": "integer", "primaryKey": false, - "notNull": false, + "notNull": true, "default": 0 }, "totalClicked": { "name": "totalClicked", "type": "integer", "primaryKey": false, - "notNull": false, + "notNull": true, "default": 0 }, + "sentAt": { + "name": "sentAt", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, "createdAt": { "name": "createdAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", "primaryKey": false, - "notNull": false, + "notNull": true, "default": "now()" }, "updatedAt": { "name": "updatedAt", - "type": "timestamp", + "type": "timestamp(3) with time zone", "primaryKey": false, - "notNull": false, + "notNull": true, "default": "now()" } }, @@ -605,6 +674,17 @@ } }, "enums": { + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "PENDING", + "SENT", + "DELIVERED", + "FAILED", + "CLICKED" + ] + }, "public.device_status": { "name": "device_status", "schema": "public", diff --git a/server/database/migrations/meta/0001_snapshot.json b/server/database/migrations/meta/0001_snapshot.json deleted file mode 100644 index 939e788..0000000 --- a/server/database/migrations/meta/0001_snapshot.json +++ /dev/null @@ -1,684 +0,0 @@ -{ - "id": "cc245e4e-f792-4a92-a5a7-911ccc7480d7", - "prevId": "31cf4594-9d2a-48fa-8cc7-444c78699d1f", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.apiKey": { - "name": "apiKey", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "appId": { - "name": "appId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "key": { - "name": "key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "permissions": { - "name": "permissions", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "isActive": { - "name": "isActive", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": true - }, - "lastUsedAt": { - "name": "lastUsedAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "expiresAt": { - "name": "expiresAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "apiKey_appId_app_id_fk": { - "name": "apiKey_appId_app_id_fk", - "tableFrom": "apiKey", - "tableTo": "app", - "columnsFrom": [ - "appId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "apiKey_key_unique": { - "name": "apiKey_key_unique", - "nullsNotDistinct": false, - "columns": [ - "key" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.app": { - "name": "app", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "slug": { - "name": "slug", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apiKey": { - "name": "apiKey", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "fcmServerKey": { - "name": "fcmServerKey", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "fcmProjectId": { - "name": "fcmProjectId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apnsCertificate": { - "name": "apnsCertificate", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apnsKeyId": { - "name": "apnsKeyId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apnsTeamId": { - "name": "apnsTeamId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "bundleId": { - "name": "bundleId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "vapidPublicKey": { - "name": "vapidPublicKey", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "vapidPrivateKey": { - "name": "vapidPrivateKey", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "vapidSubject": { - "name": "vapidSubject", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "isActive": { - "name": "isActive", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": true - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "app_slug_unique": { - "name": "app_slug_unique", - "nullsNotDistinct": false, - "columns": [ - "slug" - ] - }, - "app_apiKey_unique": { - "name": "app_apiKey_unique", - "nullsNotDistinct": false, - "columns": [ - "apiKey" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.deliveryLog": { - "name": "deliveryLog", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "notificationId": { - "name": "notificationId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "deviceId": { - "name": "deviceId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "notification_status", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "providerResponse": { - "name": "providerResponse", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "errorMessage": { - "name": "errorMessage", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "attemptCount": { - "name": "attemptCount", - "type": "integer", - "primaryKey": false, - "notNull": false, - "default": 1 - }, - "sentAt": { - "name": "sentAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "deliveredAt": { - "name": "deliveredAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "openedAt": { - "name": "openedAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "clickedAt": { - "name": "clickedAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "platform": { - "name": "platform", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "userAgent": { - "name": "userAgent", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "appVersion": { - "name": "appVersion", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "osVersion": { - "name": "osVersion", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "deliveryLog_notificationId_notification_id_fk": { - "name": "deliveryLog_notificationId_notification_id_fk", - "tableFrom": "deliveryLog", - "tableTo": "notification", - "columnsFrom": [ - "notificationId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "deliveryLog_deviceId_device_id_fk": { - "name": "deliveryLog_deviceId_device_id_fk", - "tableFrom": "deliveryLog", - "tableTo": "device", - "columnsFrom": [ - "deviceId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.device": { - "name": "device", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "appId": { - "name": "appId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "platform": { - "name": "platform", - "type": "platform", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "device_status", - "typeSchema": "public", - "primaryKey": false, - "notNull": false, - "default": "'ACTIVE'" - }, - "metadata": { - "name": "metadata", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "lastSeenAt": { - "name": "lastSeenAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "device_appId_app_id_fk": { - "name": "device_appId_app_id_fk", - "tableFrom": "device", - "tableTo": "app", - "columnsFrom": [ - "appId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.notification": { - "name": "notification", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "appId": { - "name": "appId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "title": { - "name": "title", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "body": { - "name": "body", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "data": { - "name": "data", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "badge": { - "name": "badge", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "sound": { - "name": "sound", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "clickAction": { - "name": "clickAction", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "icon": { - "name": "icon", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "image": { - "name": "image", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "targetDevices": { - "name": "targetDevices", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "platforms": { - "name": "platforms", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "scheduledAt": { - "name": "scheduledAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "expiresAt": { - "name": "expiresAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "notification_status", - "typeSchema": "public", - "primaryKey": false, - "notNull": false, - "default": "'PENDING'" - }, - "totalTargets": { - "name": "totalTargets", - "type": "integer", - "primaryKey": false, - "notNull": false, - "default": 0 - }, - "totalSent": { - "name": "totalSent", - "type": "integer", - "primaryKey": false, - "notNull": false, - "default": 0 - }, - "totalDelivered": { - "name": "totalDelivered", - "type": "integer", - "primaryKey": false, - "notNull": false, - "default": 0 - }, - "totalFailed": { - "name": "totalFailed", - "type": "integer", - "primaryKey": false, - "notNull": false, - "default": 0 - }, - "totalClicked": { - "name": "totalClicked", - "type": "integer", - "primaryKey": false, - "notNull": false, - "default": 0 - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "notification_appId_app_id_fk": { - "name": "notification_appId_app_id_fk", - "tableFrom": "notification", - "tableTo": "app", - "columnsFrom": [ - "appId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": { - "public.device_status": { - "name": "device_status", - "schema": "public", - "values": [ - "ACTIVE", - "INACTIVE", - "EXPIRED" - ] - }, - "public.notification_status": { - "name": "notification_status", - "schema": "public", - "values": [ - "PENDING", - "SENT", - "DELIVERED", - "FAILED", - "SCHEDULED" - ] - }, - "public.platform": { - "name": "platform", - "schema": "public", - "values": [ - "IOS", - "ANDROID", - "WEB" - ] - } - }, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/server/database/migrations/meta/0002_snapshot.json b/server/database/migrations/meta/0002_snapshot.json deleted file mode 100644 index b6bbd51..0000000 --- a/server/database/migrations/meta/0002_snapshot.json +++ /dev/null @@ -1,693 +0,0 @@ -{ - "id": "e46f0a6b-28e7-412c-8455-c44dd6dab042", - "prevId": "cc245e4e-f792-4a92-a5a7-911ccc7480d7", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.apiKey": { - "name": "apiKey", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "appId": { - "name": "appId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "key": { - "name": "key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "permissions": { - "name": "permissions", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "isActive": { - "name": "isActive", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": true - }, - "lastUsedAt": { - "name": "lastUsedAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "expiresAt": { - "name": "expiresAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "apiKey_appId_app_id_fk": { - "name": "apiKey_appId_app_id_fk", - "tableFrom": "apiKey", - "tableTo": "app", - "columnsFrom": [ - "appId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "apiKey_key_unique": { - "name": "apiKey_key_unique", - "nullsNotDistinct": false, - "columns": [ - "key" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.app": { - "name": "app", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "slug": { - "name": "slug", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apiKey": { - "name": "apiKey", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "fcmServerKey": { - "name": "fcmServerKey", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "fcmProjectId": { - "name": "fcmProjectId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apnsCertificate": { - "name": "apnsCertificate", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apnsKeyId": { - "name": "apnsKeyId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apnsTeamId": { - "name": "apnsTeamId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "bundleId": { - "name": "bundleId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "vapidPublicKey": { - "name": "vapidPublicKey", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "vapidPrivateKey": { - "name": "vapidPrivateKey", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "vapidSubject": { - "name": "vapidSubject", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "isActive": { - "name": "isActive", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": true - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "app_slug_unique": { - "name": "app_slug_unique", - "nullsNotDistinct": false, - "columns": [ - "slug" - ] - }, - "app_apiKey_unique": { - "name": "app_apiKey_unique", - "nullsNotDistinct": false, - "columns": [ - "apiKey" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.deliveryLog": { - "name": "deliveryLog", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "notificationId": { - "name": "notificationId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "deviceId": { - "name": "deviceId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "notification_status", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "providerResponse": { - "name": "providerResponse", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "errorMessage": { - "name": "errorMessage", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "attemptCount": { - "name": "attemptCount", - "type": "integer", - "primaryKey": false, - "notNull": false, - "default": 1 - }, - "sentAt": { - "name": "sentAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "deliveredAt": { - "name": "deliveredAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "openedAt": { - "name": "openedAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "clickedAt": { - "name": "clickedAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "platform": { - "name": "platform", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "userAgent": { - "name": "userAgent", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "appVersion": { - "name": "appVersion", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "osVersion": { - "name": "osVersion", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "deliveryLog_notificationId_notification_id_fk": { - "name": "deliveryLog_notificationId_notification_id_fk", - "tableFrom": "deliveryLog", - "tableTo": "notification", - "columnsFrom": [ - "notificationId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "deliveryLog_deviceId_device_id_fk": { - "name": "deliveryLog_deviceId_device_id_fk", - "tableFrom": "deliveryLog", - "tableTo": "device", - "columnsFrom": [ - "deviceId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "deliveryLog_notificationId_deviceId_unique": { - "name": "deliveryLog_notificationId_deviceId_unique", - "nullsNotDistinct": false, - "columns": [ - "notificationId", - "deviceId" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.device": { - "name": "device", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "appId": { - "name": "appId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "platform": { - "name": "platform", - "type": "platform", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "device_status", - "typeSchema": "public", - "primaryKey": false, - "notNull": false, - "default": "'ACTIVE'" - }, - "metadata": { - "name": "metadata", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "lastSeenAt": { - "name": "lastSeenAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "device_appId_app_id_fk": { - "name": "device_appId_app_id_fk", - "tableFrom": "device", - "tableTo": "app", - "columnsFrom": [ - "appId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.notification": { - "name": "notification", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "appId": { - "name": "appId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "title": { - "name": "title", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "body": { - "name": "body", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "data": { - "name": "data", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "badge": { - "name": "badge", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "sound": { - "name": "sound", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "clickAction": { - "name": "clickAction", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "icon": { - "name": "icon", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "image": { - "name": "image", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "targetDevices": { - "name": "targetDevices", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "platforms": { - "name": "platforms", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "scheduledAt": { - "name": "scheduledAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "expiresAt": { - "name": "expiresAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "notification_status", - "typeSchema": "public", - "primaryKey": false, - "notNull": false, - "default": "'PENDING'" - }, - "totalTargets": { - "name": "totalTargets", - "type": "integer", - "primaryKey": false, - "notNull": false, - "default": 0 - }, - "totalSent": { - "name": "totalSent", - "type": "integer", - "primaryKey": false, - "notNull": false, - "default": 0 - }, - "totalDelivered": { - "name": "totalDelivered", - "type": "integer", - "primaryKey": false, - "notNull": false, - "default": 0 - }, - "totalFailed": { - "name": "totalFailed", - "type": "integer", - "primaryKey": false, - "notNull": false, - "default": 0 - }, - "totalClicked": { - "name": "totalClicked", - "type": "integer", - "primaryKey": false, - "notNull": false, - "default": 0 - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "notification_appId_app_id_fk": { - "name": "notification_appId_app_id_fk", - "tableFrom": "notification", - "tableTo": "app", - "columnsFrom": [ - "appId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": { - "public.device_status": { - "name": "device_status", - "schema": "public", - "values": [ - "ACTIVE", - "INACTIVE", - "EXPIRED" - ] - }, - "public.notification_status": { - "name": "notification_status", - "schema": "public", - "values": [ - "PENDING", - "SENT", - "DELIVERED", - "FAILED", - "SCHEDULED" - ] - }, - "public.platform": { - "name": "platform", - "schema": "public", - "values": [ - "IOS", - "ANDROID", - "WEB" - ] - } - }, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/server/database/migrations/meta/0003_snapshot.json b/server/database/migrations/meta/0003_snapshot.json deleted file mode 100644 index 519aebb..0000000 --- a/server/database/migrations/meta/0003_snapshot.json +++ /dev/null @@ -1,718 +0,0 @@ -{ - "id": "d85d102f-b6dd-420d-b2c7-17e7bcda8be0", - "prevId": "e46f0a6b-28e7-412c-8455-c44dd6dab042", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.apiKey": { - "name": "apiKey", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true - }, - "appId": { - "name": "appId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "key": { - "name": "key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "permissions": { - "name": "permissions", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "isActive": { - "name": "isActive", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": true - }, - "lastUsedAt": { - "name": "lastUsedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "expiresAt": { - "name": "expiresAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "apiKey_appId_app_id_fk": { - "name": "apiKey_appId_app_id_fk", - "tableFrom": "apiKey", - "tableTo": "app", - "columnsFrom": [ - "appId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "apiKey_key_unique": { - "name": "apiKey_key_unique", - "nullsNotDistinct": false, - "columns": [ - "key" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.app": { - "name": "app", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "slug": { - "name": "slug", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apiKey": { - "name": "apiKey", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "fcmServerKey": { - "name": "fcmServerKey", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "fcmProjectId": { - "name": "fcmProjectId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apnsCertificate": { - "name": "apnsCertificate", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apnsKeyId": { - "name": "apnsKeyId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apnsTeamId": { - "name": "apnsTeamId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "bundleId": { - "name": "bundleId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "vapidPublicKey": { - "name": "vapidPublicKey", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "vapidPrivateKey": { - "name": "vapidPrivateKey", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "vapidSubject": { - "name": "vapidSubject", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "isActive": { - "name": "isActive", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "app_slug_unique": { - "name": "app_slug_unique", - "nullsNotDistinct": false, - "columns": [ - "slug" - ] - }, - "app_apiKey_unique": { - "name": "app_apiKey_unique", - "nullsNotDistinct": false, - "columns": [ - "apiKey" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.deliveryLog": { - "name": "deliveryLog", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true - }, - "notificationId": { - "name": "notificationId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "deviceId": { - "name": "deviceId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "delivery_status", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "providerResponse": { - "name": "providerResponse", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "errorMessage": { - "name": "errorMessage", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "attemptCount": { - "name": "attemptCount", - "type": "integer", - "primaryKey": false, - "notNull": false, - "default": 1 - }, - "sentAt": { - "name": "sentAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "deliveredAt": { - "name": "deliveredAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "openedAt": { - "name": "openedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "clickedAt": { - "name": "clickedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "platform": { - "name": "platform", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "userAgent": { - "name": "userAgent", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "appVersion": { - "name": "appVersion", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "osVersion": { - "name": "osVersion", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "deliveryLog_notificationId_notification_id_fk": { - "name": "deliveryLog_notificationId_notification_id_fk", - "tableFrom": "deliveryLog", - "tableTo": "notification", - "columnsFrom": [ - "notificationId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "deliveryLog_deviceId_device_id_fk": { - "name": "deliveryLog_deviceId_device_id_fk", - "tableFrom": "deliveryLog", - "tableTo": "device", - "columnsFrom": [ - "deviceId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "deliveryLog_notificationId_deviceId_unique": { - "name": "deliveryLog_notificationId_deviceId_unique", - "nullsNotDistinct": false, - "columns": [ - "notificationId", - "deviceId" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.device": { - "name": "device", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true - }, - "appId": { - "name": "appId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "platform": { - "name": "platform", - "type": "platform", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "device_status", - "typeSchema": "public", - "primaryKey": false, - "notNull": true, - "default": "'ACTIVE'" - }, - "metadata": { - "name": "metadata", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "lastSeenAt": { - "name": "lastSeenAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "device_appId_app_id_fk": { - "name": "device_appId_app_id_fk", - "tableFrom": "device", - "tableTo": "app", - "columnsFrom": [ - "appId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.notification": { - "name": "notification", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true - }, - "appId": { - "name": "appId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "title": { - "name": "title", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "body": { - "name": "body", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "data": { - "name": "data", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "badge": { - "name": "badge", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "sound": { - "name": "sound", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "clickAction": { - "name": "clickAction", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "icon": { - "name": "icon", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "image": { - "name": "image", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "imageUrl": { - "name": "imageUrl", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "targetDevices": { - "name": "targetDevices", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "platforms": { - "name": "platforms", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "scheduledAt": { - "name": "scheduledAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "expiresAt": { - "name": "expiresAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "notification_status", - "typeSchema": "public", - "primaryKey": false, - "notNull": true, - "default": "'PENDING'" - }, - "totalTargets": { - "name": "totalTargets", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "totalSent": { - "name": "totalSent", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "totalDelivered": { - "name": "totalDelivered", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "totalFailed": { - "name": "totalFailed", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "totalClicked": { - "name": "totalClicked", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "sentAt": { - "name": "sentAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "notification_appId_app_id_fk": { - "name": "notification_appId_app_id_fk", - "tableFrom": "notification", - "tableTo": "app", - "columnsFrom": [ - "appId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": { - "public.delivery_status": { - "name": "delivery_status", - "schema": "public", - "values": [ - "PENDING", - "SENT", - "DELIVERED", - "FAILED", - "CLICKED" - ] - }, - "public.device_status": { - "name": "device_status", - "schema": "public", - "values": [ - "ACTIVE", - "INACTIVE", - "EXPIRED" - ] - }, - "public.notification_status": { - "name": "notification_status", - "schema": "public", - "values": [ - "PENDING", - "SENT", - "DELIVERED", - "FAILED", - "SCHEDULED" - ] - }, - "public.platform": { - "name": "platform", - "schema": "public", - "values": [ - "IOS", - "ANDROID", - "WEB" - ] - } - }, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/server/database/migrations/meta/0004_snapshot.json b/server/database/migrations/meta/0004_snapshot.json deleted file mode 100644 index 2a482dc..0000000 --- a/server/database/migrations/meta/0004_snapshot.json +++ /dev/null @@ -1,728 +0,0 @@ -{ - "id": "8718cd87-184e-4736-8189-85d46170d7c5", - "prevId": "d85d102f-b6dd-420d-b2c7-17e7bcda8be0", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.apiKey": { - "name": "apiKey", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true - }, - "appId": { - "name": "appId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "key": { - "name": "key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "permissions": { - "name": "permissions", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "isActive": { - "name": "isActive", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": true - }, - "lastUsedAt": { - "name": "lastUsedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "expiresAt": { - "name": "expiresAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "apiKey_appId_app_id_fk": { - "name": "apiKey_appId_app_id_fk", - "tableFrom": "apiKey", - "tableTo": "app", - "columnsFrom": [ - "appId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "apiKey_key_unique": { - "name": "apiKey_key_unique", - "nullsNotDistinct": false, - "columns": [ - "key" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.app": { - "name": "app", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "slug": { - "name": "slug", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apiKey": { - "name": "apiKey", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "fcmServerKey": { - "name": "fcmServerKey", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "fcmProjectId": { - "name": "fcmProjectId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apnsCertificate": { - "name": "apnsCertificate", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apnsKeyId": { - "name": "apnsKeyId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apnsTeamId": { - "name": "apnsTeamId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "bundleId": { - "name": "bundleId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "vapidPublicKey": { - "name": "vapidPublicKey", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "vapidPrivateKey": { - "name": "vapidPrivateKey", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "vapidSubject": { - "name": "vapidSubject", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "isActive": { - "name": "isActive", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "app_slug_unique": { - "name": "app_slug_unique", - "nullsNotDistinct": false, - "columns": [ - "slug" - ] - }, - "app_apiKey_unique": { - "name": "app_apiKey_unique", - "nullsNotDistinct": false, - "columns": [ - "apiKey" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.deliveryLog": { - "name": "deliveryLog", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true - }, - "notificationId": { - "name": "notificationId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "deviceId": { - "name": "deviceId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "delivery_status", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "providerResponse": { - "name": "providerResponse", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "errorMessage": { - "name": "errorMessage", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "attemptCount": { - "name": "attemptCount", - "type": "integer", - "primaryKey": false, - "notNull": false, - "default": 1 - }, - "sentAt": { - "name": "sentAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "deliveredAt": { - "name": "deliveredAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "openedAt": { - "name": "openedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "clickedAt": { - "name": "clickedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "platform": { - "name": "platform", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "userAgent": { - "name": "userAgent", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "appVersion": { - "name": "appVersion", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "osVersion": { - "name": "osVersion", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "deliveryLog_notificationId_notification_id_fk": { - "name": "deliveryLog_notificationId_notification_id_fk", - "tableFrom": "deliveryLog", - "tableTo": "notification", - "columnsFrom": [ - "notificationId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "deliveryLog_deviceId_device_id_fk": { - "name": "deliveryLog_deviceId_device_id_fk", - "tableFrom": "deliveryLog", - "tableTo": "device", - "columnsFrom": [ - "deviceId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "deliveryLog_notificationId_deviceId_unique": { - "name": "deliveryLog_notificationId_deviceId_unique", - "nullsNotDistinct": false, - "columns": [ - "notificationId", - "deviceId" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.device": { - "name": "device", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true - }, - "appId": { - "name": "appId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "platform": { - "name": "platform", - "type": "platform", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "device_status", - "typeSchema": "public", - "primaryKey": false, - "notNull": true, - "default": "'ACTIVE'" - }, - "metadata": { - "name": "metadata", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "lastSeenAt": { - "name": "lastSeenAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "device_appId_app_id_fk": { - "name": "device_appId_app_id_fk", - "tableFrom": "device", - "tableTo": "app", - "columnsFrom": [ - "appId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "device_appId_token_userId_unique": { - "name": "device_appId_token_userId_unique", - "nullsNotDistinct": false, - "columns": [ - "appId", - "token", - "userId" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.notification": { - "name": "notification", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true - }, - "appId": { - "name": "appId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "title": { - "name": "title", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "body": { - "name": "body", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "data": { - "name": "data", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "badge": { - "name": "badge", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "sound": { - "name": "sound", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "clickAction": { - "name": "clickAction", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "icon": { - "name": "icon", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "image": { - "name": "image", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "imageUrl": { - "name": "imageUrl", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "targetDevices": { - "name": "targetDevices", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "platforms": { - "name": "platforms", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "scheduledAt": { - "name": "scheduledAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "expiresAt": { - "name": "expiresAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "notification_status", - "typeSchema": "public", - "primaryKey": false, - "notNull": true, - "default": "'PENDING'" - }, - "totalTargets": { - "name": "totalTargets", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "totalSent": { - "name": "totalSent", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "totalDelivered": { - "name": "totalDelivered", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "totalFailed": { - "name": "totalFailed", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "totalClicked": { - "name": "totalClicked", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "sentAt": { - "name": "sentAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp(3) with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "notification_appId_app_id_fk": { - "name": "notification_appId_app_id_fk", - "tableFrom": "notification", - "tableTo": "app", - "columnsFrom": [ - "appId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": { - "public.delivery_status": { - "name": "delivery_status", - "schema": "public", - "values": [ - "PENDING", - "SENT", - "DELIVERED", - "FAILED", - "CLICKED" - ] - }, - "public.device_status": { - "name": "device_status", - "schema": "public", - "values": [ - "ACTIVE", - "INACTIVE", - "EXPIRED" - ] - }, - "public.notification_status": { - "name": "notification_status", - "schema": "public", - "values": [ - "PENDING", - "SENT", - "DELIVERED", - "FAILED", - "SCHEDULED" - ] - }, - "public.platform": { - "name": "platform", - "schema": "public", - "values": [ - "IOS", - "ANDROID", - "WEB" - ] - } - }, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/server/database/migrations/meta/_journal.json b/server/database/migrations/meta/_journal.json index 855e981..a9d3bbd 100644 --- a/server/database/migrations/meta/_journal.json +++ b/server/database/migrations/meta/_journal.json @@ -5,36 +5,8 @@ { "idx": 0, "version": "7", - "when": 1755351121608, - "tag": "0000_open_master_mold", - "breakpoints": true - }, - { - "idx": 1, - "version": "7", - "when": 1755360568009, - "tag": "0001_flowery_dexter_bennett", - "breakpoints": true - }, - { - "idx": 2, - "version": "7", - "when": 1755368468884, - "tag": "0002_dapper_moon_knight", - "breakpoints": true - }, - { - "idx": 3, - "version": "7", - "when": 1755469936657, - "tag": "0003_warm_legion", - "breakpoints": true - }, - { - "idx": 4, - "version": "7", - "when": 1755497847178, - "tag": "0004_dry_switch", + "when": 1755509589512, + "tag": "0000_jazzy_jackpot", "breakpoints": true } ] diff --git a/server/plugins/01.database-migrate.ts b/server/plugins/01.database-migrate.ts new file mode 100644 index 0000000..f393f38 --- /dev/null +++ b/server/plugins/01.database-migrate.ts @@ -0,0 +1,75 @@ +import { dirname, join } from 'node:path' +import { fileURLToPath } from 'node:url' +import { drizzle } from 'drizzle-orm/postgres-js' +import { migrate } from 'drizzle-orm/postgres-js/migrator' +import postgres from 'postgres' +import * as schema from '../database/schema' + +export default defineNitroPlugin(async () => { + const shouldMigrate = process.env.AUTO_MIGRATE !== 'false' + const isDev = process.env.NODE_ENV === 'development' + + if (!shouldMigrate) { + console.log('[database-migrate] Auto migration disabled') + return + } + + // Development'ta silent mode + const silentMode = isDev + + const connectionString = process.env.DATABASE_URL + if (!connectionString) { + console.error('[database-migrate] DATABASE_URL not found, skipping migration') + return + } + + let migrationClient: ReturnType | null = null + + try { + if (!silentMode) { + console.log('[database-migrate] Starting database migration...') + } + + // PostgreSQL NOTICE mesajlarını bastır (silent mode için) + migrationClient = postgres(connectionString, { + max: 1, + onnotice: silentMode ? () => {} : undefined, // Silent mode'da NOTICE'ları gizle + }) + const migrationDb = drizzle(migrationClient, { schema }) + + // Plugin dosyasının konumundan relative path ile migration klasörünü bul + const currentFileUrl = import.meta.url + const currentDir = dirname(fileURLToPath(currentFileUrl)) + + const migrationsPath = isDev + ? './server/database/migrations' // development: root'tan absolute + : join(currentDir, '../migrations') // production: plugin konumundan relative + + if (!silentMode) { + console.log('[database-migrate] Using migrations path:', migrationsPath) + } + + await migrate(migrationDb, { + migrationsFolder: migrationsPath, + }) + + if (!silentMode) { + console.log('[database-migrate] ✅ Database migration completed successfully') + } + } + catch (error: any) { + console.error('[database-migrate] Error details:', { + message: error?.message, + cause: error?.cause, + code: error?.cause?.code, + }) + } + finally { + if (migrationClient) { + await migrationClient.end() + if (!silentMode) { + console.log('[database-migrate] Migration client connection closed') + } + } + } +})