Relations working (I think???

This commit is contained in:
Fergal Moran
2023-12-20 11:17:34 +00:00
parent 0ad598f6f0
commit 3f9ca9f73a
12 changed files with 82 additions and 125 deletions

1
.gitignore vendored
View File

@@ -33,3 +33,4 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
.krud/

BIN
bun.lockb

Binary file not shown.

View File

@@ -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

View File

@@ -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
},

View File

@@ -5,8 +5,8 @@
{
"idx": 0,
"version": "5",
"when": 1702675078550,
"tag": "0000_brainy_marvel_apes",
"when": 1703070994335,
"tag": "0000_thankful_sasquatch",
"breakpoints": true
}
]

View File

@@ -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"
}

View File

@@ -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

View File

@@ -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)

View File

@@ -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;

8
src/db/migrate.ts Normal file
View File

@@ -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')
// );

View File

@@ -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

5
src/db/seed.ts Normal file
View File

@@ -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');