From 3f9ca9f73aa932289bf6f00fce944a119a6615a7 Mon Sep 17 00:00:00 2001 From: Fergal Moran Date: Wed, 20 Dec 2023 11:17:34 +0000 Subject: [PATCH] Relations working (I think??? --- .gitignore | 1 + bun.lockb | Bin 286373 -> 285566 bytes ...l_apes.sql => 0000_thankful_sasquatch.sql} | 31 ++----- drizzle/meta/0000_snapshot.json | 76 ++++-------------- drizzle/meta/_journal.json | 4 +- package.json | 21 ++--- scripts/reset.sh | 7 +- src/app/api/child/route.ts | 1 - src/db/index.ts | 6 +- src/db/migrate.ts | 8 ++ src/db/schema.ts | 47 ++++++----- src/db/seed.ts | 5 ++ 12 files changed, 82 insertions(+), 125 deletions(-) rename drizzle/{0000_brainy_marvel_apes.sql => 0000_thankful_sasquatch.sql} (64%) create mode 100644 src/db/migrate.ts create mode 100644 src/db/seed.ts diff --git a/.gitignore b/.gitignore index 0f264b2..bd707d9 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts +.krud/ diff --git a/bun.lockb b/bun.lockb index f180b5a592ad5c941bfbd0b5240ca6c40c725eee..367c336679c53b73a0994811ce4743db01aed5ce 100755 GIT binary patch delta 40168 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 delta 39747 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 diff --git a/drizzle/0000_brainy_marvel_apes.sql b/drizzle/0000_thankful_sasquatch.sql similarity index 64% rename from drizzle/0000_brainy_marvel_apes.sql rename to drizzle/0000_thankful_sasquatch.sql index 95eba0f..04b27b7 100644 --- a/drizzle/0000_brainy_marvel_apes.sql +++ b/drizzle/0000_thankful_sasquatch.sql @@ -10,33 +10,30 @@ CREATE TABLE IF NOT EXISTS "account" ( "scope" text, "id_token" text, "session_state" text, - CONSTRAINT account_provider_providerAccountId_pk PRIMARY KEY("provider","providerAccountId") + CONSTRAINT "account_provider_providerAccountId_pk" PRIMARY KEY("provider","providerAccountId") ); --> statement-breakpoint CREATE TABLE IF NOT EXISTS "child" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid - () NOT NULL, - "parent_id" uuid NOT NULL, + "id" uuid PRIMARY KEY NOT NULL, "name" varchar(256), "phone" varchar(256), - "key" varchar(256) + "key" varchar(256), + "parent_id" uuid ); --> statement-breakpoint CREATE TABLE IF NOT EXISTS "device" ( - "device_id" varchar NOT NULL, - "child_id" uuid NOT NULL, + "id" uuid PRIMARY KEY NOT NULL, + "child_id" uuid, "api_key" varchar NOT NULL, "pin" integer NOT NULL, "expires" timestamp DEFAULT now () + interval '1 hour', - CONSTRAINT device_device_id_child_id_pk PRIMARY KEY("device_id","child_id"), - CONSTRAINT "device_device_id_unique" UNIQUE("device_id"), CONSTRAINT "device_api_key_unique" UNIQUE("api_key") ); --> statement-breakpoint CREATE TABLE IF NOT EXISTS "ping" ( - "device_id" varchar NOT NULL, + "device_id" uuid NOT NULL, "latitude" double precision NOT NULL, "longitude" double precision NOT NULL, "timestamp" timestamp NOT NULL @@ -60,7 +57,7 @@ CREATE TABLE IF NOT EXISTS "verification_token" ( "identifier" text NOT NULL, "token" text NOT NULL, "expires" timestamp NOT NULL, - CONSTRAINT verification_token_identifier_token_pk PRIMARY KEY("identifier","token") + CONSTRAINT "verification_token_identifier_token_pk" PRIMARY KEY("identifier","token") ); --> statement-breakpoint DO $$ BEGIN @@ -69,18 +66,6 @@ EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "child" ADD CONSTRAINT "child_parent_id_user_id_fk" FOREIGN KEY ("parent_id") REFERENCES "user"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "device" ADD CONSTRAINT "device_child_id_child_id_fk" FOREIGN KEY ("child_id") REFERENCES "child"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint DO $$ BEGIN ALTER TABLE "session" ADD CONSTRAINT "session_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION diff --git a/drizzle/meta/0000_snapshot.json b/drizzle/meta/0000_snapshot.json index 5caf859..9dfc748 100644 --- a/drizzle/meta/0000_snapshot.json +++ b/drizzle/meta/0000_snapshot.json @@ -1,5 +1,5 @@ { - "id": "cbc2e341-c3c0-4b72-b8ee-bcb6e11b7b34", + "id": "876770f8-cae4-4913-b299-855783c0b37c", "prevId": "00000000-0000-0000-0000-000000000000", "version": "5", "dialect": "pg", @@ -110,13 +110,6 @@ "name": "id", "type": "uuid", "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid\n ()" - }, - "parent_id": { - "name": "parent_id", - "type": "uuid", - "primaryKey": false, "notNull": true }, "name": { @@ -136,24 +129,16 @@ "type": "varchar(256)", "primaryKey": false, "notNull": false + }, + "parent_id": { + "name": "parent_id", + "type": "uuid", + "primaryKey": false, + "notNull": false } }, "indexes": {}, - "foreignKeys": { - "child_parent_id_user_id_fk": { - "name": "child_parent_id_user_id_fk", - "tableFrom": "child", - "tableTo": "user", - "columnsFrom": [ - "parent_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, + "foreignKeys": {}, "compositePrimaryKeys": {}, "uniqueConstraints": {} }, @@ -161,17 +146,17 @@ "name": "device", "schema": "", "columns": { - "device_id": { - "name": "device_id", - "type": "varchar", - "primaryKey": false, + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, "notNull": true }, "child_id": { "name": "child_id", "type": "uuid", "primaryKey": false, - "notNull": true + "notNull": false }, "api_key": { "name": "api_key", @@ -194,38 +179,9 @@ } }, "indexes": {}, - "foreignKeys": { - "device_child_id_child_id_fk": { - "name": "device_child_id_child_id_fk", - "tableFrom": "device", - "tableTo": "child", - "columnsFrom": [ - "child_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "device_device_id_child_id_pk": { - "name": "device_device_id_child_id_pk", - "columns": [ - "device_id", - "child_id" - ] - } - }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, "uniqueConstraints": { - "device_device_id_unique": { - "name": "device_device_id_unique", - "nullsNotDistinct": false, - "columns": [ - "device_id" - ] - }, "device_api_key_unique": { "name": "device_api_key_unique", "nullsNotDistinct": false, @@ -241,7 +197,7 @@ "columns": { "device_id": { "name": "device_id", - "type": "varchar", + "type": "uuid", "primaryKey": false, "notNull": true }, diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index 65c5f56..195b37c 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -5,8 +5,8 @@ { "idx": 0, "version": "5", - "when": 1702675078550, - "tag": "0000_brainy_marvel_apes", + "when": 1703070994335, + "tag": "0000_thankful_sasquatch", "breakpoints": true } ] diff --git a/package.json b/package.json index f602c26..30f28d5 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,13 @@ "scripts": { "dev2": "next dev", "dev": "NODE_ENV=development next dev -p 3002 & local-ssl-proxy --key /etc/letsencrypt/live/dev.fergl.ie/privkey.pem --cert /etc/letsencrypt/live/dev.fergl.ie/fullchain.pem --source 3000 --target 3002", + "drizzle:seed": "node --loader esbuild-register/loader -r esbuild-register ./src/db/seed.ts", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { - "@auth/drizzle-adapter": "^0.3.9", + "@auth/drizzle-adapter": "^0.3.11", "@hookform/resolvers": "^3.3.2", "@microsoft/signalr": "^8.0.0", "@radix-ui/react-accordion": "^1.1.2", @@ -41,21 +42,21 @@ "@radix-ui/react-tooltip": "^1.0.7", "@t3-oss/env-core": "^0.7.1", "@t3-oss/env-nextjs": "^0.7.1", - "@tanstack/react-query": "^5.12.2", - "@tanstack/react-query-devtools": "^5.13.3", + "@tanstack/react-query": "^5.14.1", + "@tanstack/react-query-devtools": "^5.14.1", "axios": "^1.6.2", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", "cmdk": "^0.2.0", - "date-fns": "^2.30.0", + "date-fns": "^3.0.0", "dotenv": "^16.3.1", "drizzle-orm": "^0.29.1", "generate-api-key": "^1.0.2", "http-status-codes": "^2.3.0", "leaflet": "^1.9.4", "local-ssl-proxy": "^2.0.5", - "lucide-react": "^0.294.0", - "next": "14.0.3", + "lucide-react": "^0.298.0", + "next": "14.0.4", "next-auth": "^4.24.5", "next-themes": "^0.2.1", "pg": "^8.11.3", @@ -63,7 +64,7 @@ "react": "^18", "react-day-picker": "^8.9.1", "react-dom": "^18", - "react-hook-form": "^7.48.2", + "react-hook-form": "^7.49.2", "react-leaflet": "^4.2.1", "react-qr-code": "^2.0.12", "socket.io": "^4.7.2", @@ -79,11 +80,11 @@ "@types/react": "^18", "@types/react-dom": "^18", "autoprefixer": "^10", - "drizzle-kit": "^0.20.6", + "drizzle-kit": "^0.20.7", "eslint": "^8", - "eslint-config-next": "14.0.3", + "eslint-config-next": "14.0.4", "postcss": "^8", - "prettier": "3.1.0", + "prettier": "3.1.1", "tailwindcss": "^3", "typescript": "^5" } diff --git a/scripts/reset.sh b/scripts/reset.sh index 8b6f28c..c07a717 100755 --- a/scripts/reset.sh +++ b/scripts/reset.sh @@ -11,6 +11,9 @@ echo "Dropping db" dropdb -f --if-exists parentgrine echo "Creating db" createdb parentgrine +echo "Exiting" +exit -npx drizzle-kit generate:pg --config=./drizzle.config.ts -npx drizzle-kit push:pg --config=./drizzle.config.ts +bunx drizzle-kit generate:pg --config=./drizzle.config.ts +bunx drizzle-kit push:pg --config=./drizzle.config.ts +bunx tsx src/db/migrate.ts diff --git a/src/app/api/child/route.ts b/src/app/api/child/route.ts index 13e8304..cb0f4c8 100644 --- a/src/app/api/child/route.ts +++ b/src/app/api/child/route.ts @@ -5,7 +5,6 @@ import { NextResponse } from 'next/server'; import { getServerAuthSession } from '@/lib/services/auth/config'; import { eq } from 'drizzle-orm'; -//TODO: create-t3-app supports app router now export async function GET(request: Request) { const session = await getServerAuthSession(); if (!session || !session.user) diff --git a/src/db/index.ts b/src/db/index.ts index 9395f0b..4ecbf71 100644 --- a/src/db/index.ts +++ b/src/db/index.ts @@ -7,7 +7,7 @@ import { migrate } from 'drizzle-orm/postgres-js/migrator'; const client = postgres(env.DATABASE_URL as string); const db = drizzle(client, { schema }); -console.log('DRIZZLE', 'migrating'); -migrate(db, { migrationsFolder: 'drizzle' }) - .then(() => console.log('DRIZZLE', 'migrated')); +// console.log('DRIZZLE', 'migrating'); +// migrate(db, { migrationsFolder: 'drizzle' }) +// .then(() => console.log('DRIZZLE', 'migrated')); export default db; diff --git a/src/db/migrate.ts b/src/db/migrate.ts new file mode 100644 index 0000000..19a901d --- /dev/null +++ b/src/db/migrate.ts @@ -0,0 +1,8 @@ +import 'dotenv/config'; +import db from '.'; +import { migrate } from 'drizzle-orm/postgres-js/migrator'; + +// This will run migrations on the database, skipping the ones already applied +// migrate(db, { migrationsFolder: './drizzle' }).then(() => +// console.log('DRIZZLE', 'migrated') +// ); diff --git a/src/db/schema.ts b/src/db/schema.ts index 4f5286c..fdd38fd 100644 --- a/src/db/schema.ts +++ b/src/db/schema.ts @@ -68,57 +68,56 @@ export const verificationTokens = pgTable( ); //#endregion auth +export const userRelations = relations(users, ({ many }) => ({ + children: many(child), +})); + //#region child export const child = pgTable('child', { - id: uuid('id') - .default(sql`gen_random_uuid()`) - .primaryKey(), - parentId: uuid('parent_id') - .notNull() - .references(() => users.id, { onDelete: 'cascade' }), + id: uuid('id').primaryKey(), name: varchar('name', { length: 256 }), phone: varchar('phone', { length: 256 }), apiKey: varchar('key', { length: 256 }), + parentId: uuid('parent_id'), }); - -export const childDevices = relations(child, ({ many }) => ({ +export const childRelations = relations(child, ({ one, many }) => ({ + parent: one(users, { + fields: [child.parentId], + references: [users.id], + }), devices: many(device), })); -//#endregion child -//#region device + export const device = pgTable( 'device', { - deviceId: varchar('device_id').notNull().unique(), - childId: uuid('child_id') - .notNull() - .references(() => child.id, { onDelete: 'cascade' }), + id: uuid('id').primaryKey(), + childId: uuid('child_id'), apiKey: varchar('api_key').notNull().unique(), //TODO: make the device request/pin a separate table and enforce the expiry pin: integer('pin').notNull(), expires: timestamp('expires').default(sql`now () + interval '1 hour'`), - }, - (device) => ({ - composePk: primaryKey({ columns: [device.deviceId, device.childId] }), - }) + } ); -const deviceRelations = relations(device, ({ one }) => ({ +export const deviceRelations = relations(device, ({ one, many }) => ({ child: one(child, { fields: [device.childId], references: [child.id], }), + pings: many(ping), })); export const ping = pgTable('ping', { - deviceId: varchar('device_id').notNull(), + deviceId: uuid('device_id').notNull(), latitude: doublePrecision('latitude').notNull(), longitude: doublePrecision('longitude').notNull(), timestamp: timestamp('timestamp').notNull(), }); -export const devicePings = relations(device, ({ many }) => ({ - pings: many(ping), +export const pingRelations = relations(ping, ({ one, many }) => ({ + child: one(device, { + fields: [ping.deviceId], + references: [device.id], + }), })); - -//#endregion device diff --git a/src/db/seed.ts b/src/db/seed.ts new file mode 100644 index 0000000..b672832 --- /dev/null +++ b/src/db/seed.ts @@ -0,0 +1,5 @@ +import * as dotenv from 'dotenv'; +dotenv.config({ path: './.env' }); + +if (!('DATABASE_URL' in process.env)) + throw new Error('DATABASE_URL not found on .env.development');