From 96fc6a1b1609293f43b61689bc3dac087d323a4e Mon Sep 17 00:00:00 2001 From: Don Strawsburg Date: Mon, 16 Dec 2024 17:28:57 -0500 Subject: [PATCH 1/2] pushing it broke --- package-lock.json | 250 +++++++++++++++++++++++++--- package.json | 4 +- src/app/auth.ts | 18 ++ src/app/signin/page.tsx | 2 +- src/db/schema/Accounts.ts | 26 +++ src/db/schema/AeroPrecision.ts | 29 ++++ src/db/schema/Authenticators.ts | 22 +++ src/db/schema/Sessions.ts | 10 ++ src/db/schema/User.ts | 12 +- src/db/schema/UserActivity.ts | 3 +- src/db/schema/VerificationTokens.ts | 16 ++ src/drizzle/relations.ts | 16 +- src/drizzle/schema.ts | 8 +- 13 files changed, 380 insertions(+), 36 deletions(-) create mode 100644 src/app/auth.ts create mode 100644 src/db/schema/Accounts.ts create mode 100644 src/db/schema/AeroPrecision.ts create mode 100644 src/db/schema/Authenticators.ts create mode 100644 src/db/schema/Sessions.ts create mode 100644 src/db/schema/VerificationTokens.ts diff --git a/package-lock.json b/package-lock.json index 79a0de7..62146c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,6 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "dotenv": "^16.4.7", - "drizzle-orm": "^0.36.4", "fontsource-roboto": "^4.0.0", "framer-motion": "^11.11.17", "lucide-react": "^0.460.0", @@ -38,6 +37,7 @@ "tailwindcss-animate": "^1.0.7" }, "devDependencies": { + "@auth/drizzle-adapter": "^1.7.4", "@types/bun": "^1.1.13", "@types/node": "^20.17.6", "@types/pg": "^8.11.10", @@ -45,8 +45,10 @@ "@types/react-dom": "^18", "autoprefixer": "^10.4.20", "drizzle-kit": "^0.28.1", + "drizzle-orm": "^0.38.2", "eslint": "^8", "eslint-config-next": "15.0.3", + "next-auth": "^5.0.0-beta.25", "postcss": "^8", "tailwindcss": "^3.4.15", "tsx": "^4.19.2", @@ -64,6 +66,99 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@auth/core": { + "version": "0.37.2", + "resolved": "https://registry.npmjs.org/@auth/core/-/core-0.37.2.tgz", + "integrity": "sha512-kUvzyvkcd6h1vpeMAojK2y7+PAV5H+0Cc9+ZlKYDFhDY31AlvsB+GW5vNO4qE3Y07KeQgvNO9U0QUx/fN62kBw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@panva/hkdf": "^1.2.1", + "@types/cookie": "0.6.0", + "cookie": "0.7.1", + "jose": "^5.9.3", + "oauth4webapi": "^3.0.0", + "preact": "10.11.3", + "preact-render-to-string": "5.2.3" + }, + "peerDependencies": { + "@simplewebauthn/browser": "^9.0.1", + "@simplewebauthn/server": "^9.0.2", + "nodemailer": "^6.8.0" + }, + "peerDependenciesMeta": { + "@simplewebauthn/browser": { + "optional": true + }, + "@simplewebauthn/server": { + "optional": true + }, + "nodemailer": { + "optional": true + } + } + }, + "node_modules/@auth/core/node_modules/preact": { + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz", + "integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/@auth/drizzle-adapter": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@auth/drizzle-adapter/-/drizzle-adapter-1.7.4.tgz", + "integrity": "sha512-OPZQakWWm5Hbx6okVMbtgI08WBliz/dCbFUXiPg9TThpp3Wh7MME/ubg4fW1oOp8P0gul6MkFvMVO733sVtd2w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@auth/core": "0.37.4" + } + }, + "node_modules/@auth/drizzle-adapter/node_modules/@auth/core": { + "version": "0.37.4", + "resolved": "https://registry.npmjs.org/@auth/core/-/core-0.37.4.tgz", + "integrity": "sha512-HOXJwXWXQRhbBDHlMU0K/6FT1v+wjtzdKhsNg0ZN7/gne6XPsIrjZ4daMcFnbq0Z/vsAbYBinQhhua0d77v7qw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@panva/hkdf": "^1.2.1", + "jose": "^5.9.6", + "oauth4webapi": "^3.1.1", + "preact": "10.24.3", + "preact-render-to-string": "6.5.11" + }, + "peerDependencies": { + "@simplewebauthn/browser": "^9.0.1", + "@simplewebauthn/server": "^9.0.2", + "nodemailer": "^6.8.0" + }, + "peerDependenciesMeta": { + "@simplewebauthn/browser": { + "optional": true + }, + "@simplewebauthn/server": { + "optional": true + }, + "nodemailer": { + "optional": true + } + } + }, + "node_modules/@auth/drizzle-adapter/node_modules/preact-render-to-string": { + "version": "6.5.11", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.5.11.tgz", + "integrity": "sha512-ubnauqoGczeGISiOh6RjX0/cdaF8v/oDXIjO85XALCQjwQP+SB4RDXXtvZ6yTYSjG+PC1QRP2AhPgCEsM2EvUw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "preact": ">=10" + } + }, "node_modules/@babel/code-frame": { "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", @@ -2544,6 +2639,16 @@ "node": ">=12.4.0" } }, + "node_modules/@panva/hkdf": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.2.1.tgz", + "integrity": "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -2566,6 +2671,7 @@ "version": "5.22.0", "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.22.0.tgz", "integrity": "sha512-M0SVXfyHnQREBKxCgyo7sffrKttwE6R8PMq330MIUF0pTwjUhLbW84pFDlf06B27XyCR++VtjugEnIHdr07SVA==", + "dev": true, "hasInstallScript": true, "optional": true, "peer": true, @@ -2585,6 +2691,7 @@ "version": "5.22.0", "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.22.0.tgz", "integrity": "sha512-AUt44v3YJeggO2ZU5BkXI7M4hu9BF2zzH2iF2V5pyXT/lRTyWiElZ7It+bRH1EshoMRxHgpYg4VB6rCM+mG5jQ==", + "dev": true, "optional": true, "peer": true }, @@ -2592,6 +2699,7 @@ "version": "5.22.0", "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.22.0.tgz", "integrity": "sha512-UNjfslWhAt06kVL3CjkuYpHAWSO6L4kDCVPegV6itt7nD1kSJavd3vhgAEhjglLJJKEdJ7oIqDJ+yHk6qO8gPA==", + "dev": true, "hasInstallScript": true, "optional": true, "peer": true, @@ -2606,6 +2714,7 @@ "version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2.tgz", "integrity": "sha512-2PTmxFR2yHW/eB3uqWtcgRcgAbG1rwG9ZriSvQw+nnb7c4uCr3RAcGMb6/zfE88SKlC1Nj2ziUvc96Z379mHgQ==", + "dev": true, "optional": true, "peer": true }, @@ -2613,6 +2722,7 @@ "version": "5.22.0", "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.22.0.tgz", "integrity": "sha512-bkrD/Mc2fSvkQBV5EpoFcZ87AvOgDxbG99488a5cexp5Ccny+UM6MAe/UFkUC0wLYD9+9befNOqGiIJhhq+HbA==", + "dev": true, "optional": true, "peer": true, "dependencies": { @@ -2625,6 +2735,7 @@ "version": "5.22.0", "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.22.0.tgz", "integrity": "sha512-pHhpQdr1UPFpt+zFfnPazhulaZYCUqeIcPpJViYoq9R+D/yw4fjE+CtnsnKzPYm0ddUbeXUzjGVGIRVgPDCk4Q==", + "dev": true, "optional": true, "peer": true, "dependencies": { @@ -2814,6 +2925,13 @@ "bun-types": "1.1.34" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -2824,7 +2942,7 @@ "version": "20.17.6", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.6.tgz", "integrity": "sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==", - "devOptional": true, + "dev": true, "dependencies": { "undici-types": "~6.19.2" } @@ -2838,7 +2956,7 @@ "version": "8.11.10", "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.10.tgz", "integrity": "sha512-LczQUW4dbOQzsH2RQ5qoeJ6qJPdrcM/DcMLoqWQkMLMsq83J5lAX3LXjdkWdpscFy67JSOWDnh7Ny/sPFykmkg==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -2850,7 +2968,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.2.tgz", "integrity": "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==", - "devOptional": true, + "dev": true, "dependencies": { "pg-int8": "1.0.1", "pg-numeric": "1.0.2", @@ -2868,7 +2986,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", - "devOptional": true, + "dev": true, "engines": { "node": ">=12" } @@ -2877,7 +2995,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", - "devOptional": true, + "dev": true, "dependencies": { "obuf": "~1.1.2" }, @@ -2889,7 +3007,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.1.0.tgz", "integrity": "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=12" } @@ -2898,7 +3016,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", - "devOptional": true, + "dev": true, "engines": { "node": ">=12" } @@ -2938,7 +3056,7 @@ "version": "8.5.13", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", - "devOptional": true, + "dev": true, "dependencies": { "@types/node": "*" } @@ -3604,7 +3722,7 @@ "version": "1.1.34", "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.1.34.tgz", "integrity": "sha512-br5QygTEL/TwB4uQOb96Ky22j4Gq2WxWH/8Oqv20fk5HagwKXo/akB+LiYgSfzexCt6kkcUaVm+bKiPl71xPvw==", - "devOptional": true, + "dev": true, "dependencies": { "@types/node": "~20.12.8", "@types/ws": "~8.5.10" @@ -3614,7 +3732,7 @@ "version": "20.12.14", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.14.tgz", "integrity": "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==", - "devOptional": true, + "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -3623,7 +3741,7 @@ "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "devOptional": true + "dev": true }, "node_modules/busboy": { "version": "1.6.0", @@ -3833,6 +3951,16 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", @@ -4481,12 +4609,14 @@ } }, "node_modules/drizzle-orm": { - "version": "0.36.4", - "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.36.4.tgz", - "integrity": "sha512-1OZY3PXD7BR00Gl61UUOFihslDldfH4NFRH2MbP54Yxi0G/PKn4HfO65JYZ7c16DeP3SpM3Aw+VXVG9j6CRSXA==", + "version": "0.38.2", + "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.38.2.tgz", + "integrity": "sha512-eCE3yPRAskLo1WpM9OHpFaM70tBEDsWhwR/0M3CKyztAXKR9Qs3asZlcJOEliIcUSg8GuwrlY0dmYDgmm6y5GQ==", + "dev": true, + "license": "Apache-2.0", "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", - "@cloudflare/workers-types": ">=3", + "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", @@ -6293,6 +6423,16 @@ "jiti": "bin/jiti.js" } }, + "node_modules/jose": { + "version": "5.9.6", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.9.6.tgz", + "integrity": "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -6692,6 +6832,34 @@ } } }, + "node_modules/next-auth": { + "version": "5.0.0-beta.25", + "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-5.0.0-beta.25.tgz", + "integrity": "sha512-2dJJw1sHQl2qxCrRk+KTQbeH+izFbGFPuJj5eGgBZFYyiYYtvlrBeUw1E/OJJxTRjuxbSYGnCTkUIRsIIW0bog==", + "dev": true, + "license": "ISC", + "dependencies": { + "@auth/core": "0.37.2" + }, + "peerDependencies": { + "@simplewebauthn/browser": "^9.0.1", + "@simplewebauthn/server": "^9.0.2", + "next": "^14.0.0-0 || ^15.0.0-0", + "nodemailer": "^6.6.5", + "react": "^18.2.0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@simplewebauthn/browser": { + "optional": true + }, + "@simplewebauthn/server": { + "optional": true + }, + "nodemailer": { + "optional": true + } + } + }, "node_modules/next-themes": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.3.tgz", @@ -6752,6 +6920,16 @@ "node": ">=0.10.0" } }, + "node_modules/oauth4webapi": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.1.4.tgz", + "integrity": "sha512-eVfN3nZNbok2s/ROifO0UAc5G8nRoLSbrcKJ09OqmucgnhXEfdIQOR4gq1eJH1rN3gV7rNw62bDEgftsgFtBEg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -6874,7 +7052,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "devOptional": true + "dev": true }, "node_modules/once": { "version": "1.4.0", @@ -7068,7 +7246,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", - "devOptional": true, + "dev": true, "engines": { "node": ">=4" } @@ -7336,7 +7514,31 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.4.tgz", "integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==", - "devOptional": true + "dev": true + }, + "node_modules/preact": { + "version": "10.24.3", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.3.tgz", + "integrity": "sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/preact-render-to-string": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz", + "integrity": "sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pretty-format": "^3.8.0" + }, + "peerDependencies": { + "preact": ">=10" + } }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -7347,10 +7549,18 @@ "node": ">= 0.8.0" } }, + "node_modules/pretty-format": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", + "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==", + "dev": true, + "license": "MIT" + }, "node_modules/prisma": { "version": "5.22.0", "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.22.0.tgz", "integrity": "sha512-vtpjW3XuYCSnMsNVBjLMNkTj6OZbudcPPTPYHqX0CJfpcdWciI1dM8uHETwmDxxiqEwCIE6WvXucWUetJgfu/A==", + "dev": true, "hasInstallScript": true, "optional": true, "peer": true, @@ -8473,7 +8683,7 @@ "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "devOptional": true + "dev": true }, "node_modules/update-browserslist-db": { "version": "1.1.1", diff --git a/package.json b/package.json index 6de5330..03a9656 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "dotenv": "^16.4.7", - "drizzle-orm": "^0.36.4", "fontsource-roboto": "^4.0.0", "framer-motion": "^11.11.17", "lucide-react": "^0.460.0", @@ -39,6 +38,7 @@ "tailwindcss-animate": "^1.0.7" }, "devDependencies": { + "@auth/drizzle-adapter": "^1.7.4", "@types/bun": "^1.1.13", "@types/node": "^20.17.6", "@types/pg": "^8.11.10", @@ -46,8 +46,10 @@ "@types/react-dom": "^18", "autoprefixer": "^10.4.20", "drizzle-kit": "^0.28.1", + "drizzle-orm": "^0.38.2", "eslint": "^8", "eslint-config-next": "15.0.3", + "next-auth": "^5.0.0-beta.25", "postcss": "^8", "tailwindcss": "^3.4.15", "tsx": "^4.19.2", diff --git a/src/app/auth.ts b/src/app/auth.ts new file mode 100644 index 0000000..65b84df --- /dev/null +++ b/src/app/auth.ts @@ -0,0 +1,18 @@ +import NextAuth from "next-auth" +import Google from "next-auth/providers/google" +import { DrizzleAdapter } from "@auth/drizzle-adapter" +import { db } from "../db"; +import { users } from "@schemas/User" +import { accounts } from "@schemas/Accounts"; +import { sessions } from "@schemas/Sessions"; +import { verificationTokens } from "@schemas/VerificationTokens"; + +export const { handlers, auth } = NextAuth({ + adapter: DrizzleAdapter(db, { + usersTable: users, + accountsTable: accounts, + sessionsTable: sessions, + verificationTokensTable: verificationTokens, + }), + providers: [] +}) \ No newline at end of file diff --git a/src/app/signin/page.tsx b/src/app/signin/page.tsx index 39af355..824332f 100644 --- a/src/app/signin/page.tsx +++ b/src/app/signin/page.tsx @@ -1,7 +1,7 @@ 'use client'; import React, { useState } from 'react'; import { useRouter } from 'next/navigation'; -import constants from '@src/lib/constants'; +import constants from '@lib/constants'; import Link from 'next/link'; export default function SignInPage() { diff --git a/src/db/schema/Accounts.ts b/src/db/schema/Accounts.ts new file mode 100644 index 0000000..183412b --- /dev/null +++ b/src/db/schema/Accounts.ts @@ -0,0 +1,26 @@ +import { users } from "@schemas/User"; +import { integer, pgTable, primaryKey, text } from "drizzle-orm/pg-core"; +import type { AdapterAccountType } from "next-auth/adapters" +export const accounts = pgTable( + "account", + { + userId: text("userId") + .notNull() + .references(() => users.id, { onDelete: "cascade" }), + type: text("type").$type().notNull(), + provider: text("provider").notNull(), + providerAccountId: text("providerAccountId").notNull(), + refresh_token: text("refresh_token"), + access_token: text("access_token"), + expires_at: integer("expires_at"), + token_type: text("token_type"), + scope: text("scope"), + id_token: text("id_token"), + session_state: text("session_state"), + }, + (account) => ({ + compoundKey: primaryKey({ + columns: [account.provider, account.providerAccountId], + }), + }) + ) \ No newline at end of file diff --git a/src/db/schema/AeroPrecision.ts b/src/db/schema/AeroPrecision.ts new file mode 100644 index 0000000..f216491 --- /dev/null +++ b/src/db/schema/AeroPrecision.ts @@ -0,0 +1,29 @@ +import { numeric, pgTable, text, uuid } from "drizzle-orm/pg-core"; + +export const aeroPrecision = pgTable("aero_precision", { + sku: text().primaryKey().notNull(), + manufacturerId: text("manufacturer_id"), + brandName: text("brand_name"), + productName: text("product_name"), + longDescription: text("long_description"), + shortDescription: text("short_description"), + department: text(), + category: text(), + subcategory: text(), + thumbUrl: text("thumb_url"), + imageUrl: text("image_url"), + buyLink: text("buy_link"), + keywords: text(), + reviews: text(), + retailPrice: numeric("retail_price"), + salePrice: numeric("sale_price"), + brandPageLink: text("brand_page_link"), + brandLogoImage: text("brand_logo_image"), + productPageViewTracking: text("product_page_view_tracking"), + variantsXml: text("variants_xml"), + mediumImageUrl: text("medium_image_url"), + productContentWidget: text("product_content_widget"), + googleCategorization: text("google_categorization"), + itemBasedCommission: text("item_based_commission"), + uuid: uuid().defaultRandom(), +}); diff --git a/src/db/schema/Authenticators.ts b/src/db/schema/Authenticators.ts new file mode 100644 index 0000000..03b4cce --- /dev/null +++ b/src/db/schema/Authenticators.ts @@ -0,0 +1,22 @@ +import { boolean, integer, pgTable, primaryKey, text } from "drizzle-orm/pg-core"; +import { users } from '@schemas/User' +export const authenticators = pgTable( + "authenticator", + { + credentialID: text("credentialID").notNull().unique(), + userId: text("userId") + .notNull() + .references(() => users.id, { onDelete: "cascade" }), + providerAccountId: text("providerAccountId").notNull(), + credentialPublicKey: text("credentialPublicKey").notNull(), + counter: integer("counter").notNull(), + credentialDeviceType: text("credentialDeviceType").notNull(), + credentialBackedUp: boolean("credentialBackedUp").notNull(), + transports: text("transports"), + }, + (authenticator) => ({ + compositePK: primaryKey({ + columns: [authenticator.userId, authenticator.credentialID], + }), + }) + ) \ No newline at end of file diff --git a/src/db/schema/Sessions.ts b/src/db/schema/Sessions.ts new file mode 100644 index 0000000..2cd04e2 --- /dev/null +++ b/src/db/schema/Sessions.ts @@ -0,0 +1,10 @@ +import { pgTable, text, timestamp } from "drizzle-orm/pg-core"; +import {User} from '@schemas/User'; +export const sessions = pgTable("session", { + sessionToken: text("sessionToken").primaryKey(), + userId: text("userId") + .notNull() + .references(() => User.id, { onDelete: "cascade" }), + expires: timestamp("expires", { mode: "date" }).notNull(), + }) + \ No newline at end of file diff --git a/src/db/schema/User.ts b/src/db/schema/User.ts index 825eafb..4bbee53 100644 --- a/src/db/schema/User.ts +++ b/src/db/schema/User.ts @@ -24,4 +24,14 @@ export const User = pgTable("users", { usersEmailKey: unique("users_email_key").on(table.email), usersBuildPrivacySettingCheck: check("users_build_privacy_setting_check", sql`build_privacy_setting = ANY (ARRAY['private'::text, 'public'::text])`), } -}); \ No newline at end of file +}); + +export const users = pgTable("user", { + id: text("id") + .primaryKey() + .$defaultFn(() => crypto.randomUUID()), + name: text("name"), + email: text("email").unique(), + emailVerified: timestamp("emailVerified", { mode: "date" }), + image: text("image"), + }) \ No newline at end of file diff --git a/src/db/schema/UserActivity.ts b/src/db/schema/UserActivity.ts index 41bf2e6..4e9347b 100644 --- a/src/db/schema/UserActivity.ts +++ b/src/db/schema/UserActivity.ts @@ -1,8 +1,9 @@ import { bigint, bigserial, foreignKey, pgTable, text, timestamp } from "drizzle-orm/pg-core"; +import { sql } from "drizzle-orm"; import { users } from "./User"; export const userActivityLog = pgTable("user_activity_log", { - id: bigserial({ mode: "bigint" }).primaryKey().notNull(), + id: bigint({ mode: "bigint" }).primaryKey().generatedAlwaysAsIdentity({ name: "user_activity_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }).notNull(), // You can use { mode: "bigint" } if numbers are exceeding js number limitations userId: bigint("user_id", { mode: "number" }).notNull(), activity: text().notNull(), diff --git a/src/db/schema/VerificationTokens.ts b/src/db/schema/VerificationTokens.ts new file mode 100644 index 0000000..36217ad --- /dev/null +++ b/src/db/schema/VerificationTokens.ts @@ -0,0 +1,16 @@ +import { pgTable, primaryKey, text, timestamp } from "drizzle-orm/pg-core"; + +export const verificationTokens = pgTable( + "verificationToken", + { + identifier: text("identifier").notNull(), + token: text("token").notNull(), + expires: timestamp("expires", { mode: "date" }).notNull(), + }, + (verificationToken) => ({ + compositePk: primaryKey({ + columns: [verificationToken.identifier, verificationToken.token], + }), + }) + ) + \ No newline at end of file diff --git a/src/drizzle/relations.ts b/src/drizzle/relations.ts index fffbdec..5b87bf1 100644 --- a/src/drizzle/relations.ts +++ b/src/drizzle/relations.ts @@ -1,29 +1,29 @@ import { relations } from "drizzle-orm/relations"; -import { users, userBuilds, userFavorites, userActivityLog } from "./schema"; +import { usersKeep, userBuilds, userFavorites, userActivityLog } from "./schema"; export const userBuildsRelations = relations(userBuilds, ({one}) => ({ - user: one(users, { + usersKeep: one(usersKeep, { fields: [userBuilds.userId], - references: [users.id] + references: [usersKeep.id] }), })); -export const usersRelations = relations(users, ({many}) => ({ +export const usersKeepRelations = relations(usersKeep, ({many}) => ({ userBuilds: many(userBuilds), userFavorites: many(userFavorites), userActivityLogs: many(userActivityLog), })); export const userFavoritesRelations = relations(userFavorites, ({one}) => ({ - user: one(users, { + usersKeep: one(usersKeep, { fields: [userFavorites.userId], - references: [users.id] + references: [usersKeep.id] }), })); export const userActivityLogRelations = relations(userActivityLog, ({one}) => ({ - user: one(users, { + usersKeep: one(usersKeep, { fields: [userActivityLog.userId], - references: [users.id] + references: [usersKeep.id] }), })); \ No newline at end of file diff --git a/src/drizzle/schema.ts b/src/drizzle/schema.ts index 70a39e9..dc56401 100644 --- a/src/drizzle/schema.ts +++ b/src/drizzle/schema.ts @@ -54,7 +54,7 @@ export const userBuilds = pgTable("user_builds", { return { userBuildsUserIdFkey: foreignKey({ columns: [table.userId], - foreignColumns: [users.id], + foreignColumns: [usersKeep.id], name: "user_builds_user_id_fkey" }).onDelete("cascade"), } @@ -71,7 +71,7 @@ export const userFavorites = pgTable("user_favorites", { return { userFavoritesUserIdFkey: foreignKey({ columns: [table.userId], - foreignColumns: [users.id], + foreignColumns: [usersKeep.id], name: "user_favorites_user_id_fkey" }).onDelete("cascade"), } @@ -113,7 +113,7 @@ export const userActivityLog = pgTable("user_activity_log", { return { userActivityLogUserIdFkey: foreignKey({ columns: [table.userId], - foreignColumns: [users.id], + foreignColumns: [usersKeep.id], name: "user_activity_log_user_id_fkey" }).onDelete("cascade"), } @@ -285,7 +285,7 @@ export const psa = pgTable("psa", { uuid: uuid().defaultRandom(), }); -export const users = pgTable("users", { +export const usersKeep = pgTable("users_keep", { id: bigserial({ mode: "bigint" }).primaryKey().notNull(), username: varchar({ length: 50 }).notNull(), email: varchar({ length: 255 }).notNull(), From 0bf9011cc6eb84460853d1e56c6f9593103b4628 Mon Sep 17 00:00:00 2001 From: Don Strawsburg Date: Mon, 16 Dec 2024 17:54:50 -0500 Subject: [PATCH 2/2] moved schema to a single file --- drizzle.config.ts | 4 +- .../BaseDBTableForDrizzle/baseTable.ts | 2 +- src/app/auth.ts | 12 +- src/db/queries/PSA/index.ts | 2 +- src/db/schema/Accounts.ts | 2 +- src/db/schema/Authenticators.ts | 2 +- src/db/schema/Brand.ts | 2 +- src/db/schema/Build.ts | 2 +- src/db/schema/BuildComponent.ts | 2 +- src/db/schema/Category.ts | 2 +- src/db/schema/Compartment.ts | 2 +- src/db/schema/ComponentTypes.ts | 2 +- src/db/schema/LipseyCatalog.ts | 2 +- src/db/schema/Manufacturer.ts | 2 +- src/db/schema/Product.ts | 2 +- src/db/schema/Product_feed.ts | 2 +- src/db/schema/Psa.ts | 2 +- src/db/schema/Reseller.ts | 2 +- src/db/schema/Sessions.ts | 4 +- src/drizzle/relations.ts | 30 +- src/drizzle/schema.ts | 224 +- src/drizzle/schema/0000_stiff_odin.sql | 349 +++ .../schema/helpers/columns.helpers.ts | 0 src/drizzle/schema/meta/0000_snapshot.json | 2174 +++++++++++++++++ src/drizzle/schema/meta/_journal.json | 13 + src/drizzle/schema/relations.ts | 13 + src/drizzle/schema/schema.ts | 386 +++ tsconfig.json | 2 +- 28 files changed, 3059 insertions(+), 184 deletions(-) create mode 100644 src/drizzle/schema/0000_stiff_odin.sql rename src/{db => drizzle}/schema/helpers/columns.helpers.ts (100%) create mode 100644 src/drizzle/schema/meta/0000_snapshot.json create mode 100644 src/drizzle/schema/meta/_journal.json create mode 100644 src/drizzle/schema/relations.ts create mode 100644 src/drizzle/schema/schema.ts diff --git a/drizzle.config.ts b/drizzle.config.ts index fb87a06..b51c989 100644 --- a/drizzle.config.ts +++ b/drizzle.config.ts @@ -1,8 +1,8 @@ import 'dotenv/config'; import { defineConfig } from 'drizzle-kit'; export default defineConfig({ - out: './src/drizzle', - schema: './src/db/schema/', + out: './src/drizzle/schema/', + schema: './src/drizzle/schema/', dialect: 'postgresql', dbCredentials: { url: process.env.DATABASE_URL!, diff --git a/src/Example Code/BaseDBTableForDrizzle/baseTable.ts b/src/Example Code/BaseDBTableForDrizzle/baseTable.ts index ab4a613..82bf9ca 100644 --- a/src/Example Code/BaseDBTableForDrizzle/baseTable.ts +++ b/src/Example Code/BaseDBTableForDrizzle/baseTable.ts @@ -1,6 +1,6 @@ import { pgTable, integer, varchar } from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm"; -import { timestamps } from "../../db/schema/helpers/columns.helpers"; +import { timestamps } from "../../drizzle/schema/helpers/columns.helpers"; export const accounts = pgTable("base_table", { id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "base_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), diff --git a/src/app/auth.ts b/src/app/auth.ts index 65b84df..7b82186 100644 --- a/src/app/auth.ts +++ b/src/app/auth.ts @@ -2,17 +2,15 @@ import NextAuth from "next-auth" import Google from "next-auth/providers/google" import { DrizzleAdapter } from "@auth/drizzle-adapter" import { db } from "../db"; -import { users } from "@schemas/User" -import { accounts } from "@schemas/Accounts"; -import { sessions } from "@schemas/Sessions"; -import { verificationTokens } from "@schemas/VerificationTokens"; +import { users, account, session, verificationToken } from "@schemas/schema"; + export const { handlers, auth } = NextAuth({ adapter: DrizzleAdapter(db, { usersTable: users, - accountsTable: accounts, - sessionsTable: sessions, - verificationTokensTable: verificationTokens, + accountsTable: account, + sessionsTable: session, + verificationTokensTable: verificationToken, }), providers: [] }) \ No newline at end of file diff --git a/src/db/queries/PSA/index.ts b/src/db/queries/PSA/index.ts index 9cb7d32..3d8d7b8 100644 --- a/src/db/queries/PSA/index.ts +++ b/src/db/queries/PSA/index.ts @@ -1,5 +1,5 @@ import { db } from '../../index'; -import { psa } from '@schemas/Psa'; +import { psa } from '@schemas/schema'; import { eq, lt, gte, ne, and, like } from 'drizzle-orm'; import CATEGORY from '@src/data/parts_cats.json'; diff --git a/src/db/schema/Accounts.ts b/src/db/schema/Accounts.ts index 183412b..580a598 100644 --- a/src/db/schema/Accounts.ts +++ b/src/db/schema/Accounts.ts @@ -1,4 +1,4 @@ -import { users } from "@schemas/User"; +import { users } from "@schemas/schema"; import { integer, pgTable, primaryKey, text } from "drizzle-orm/pg-core"; import type { AdapterAccountType } from "next-auth/adapters" export const accounts = pgTable( diff --git a/src/db/schema/Authenticators.ts b/src/db/schema/Authenticators.ts index 03b4cce..de46e09 100644 --- a/src/db/schema/Authenticators.ts +++ b/src/db/schema/Authenticators.ts @@ -1,5 +1,5 @@ import { boolean, integer, pgTable, primaryKey, text } from "drizzle-orm/pg-core"; -import { users } from '@schemas/User' +import { users } from '@schemas/schema' export const authenticators = pgTable( "authenticator", { diff --git a/src/db/schema/Brand.ts b/src/db/schema/Brand.ts index b18bcee..b8ea7ce 100644 --- a/src/db/schema/Brand.ts +++ b/src/db/schema/Brand.ts @@ -1,6 +1,6 @@ import { pgTable, integer, varchar, uuid } from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm"; -import { timestamps } from "./helpers/columns.helpers"; +import { timestamps } from "../../drizzle/schema/helpers/columns.helpers"; export const brand = pgTable("brands", { id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "brands_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), diff --git a/src/db/schema/Build.ts b/src/db/schema/Build.ts index e6e2a6e..e683b6b 100644 --- a/src/db/schema/Build.ts +++ b/src/db/schema/Build.ts @@ -1,6 +1,6 @@ import { pgTable, integer, varchar, text, uuid } from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm"; -import { timestamps } from "./helpers/columns.helpers"; +import { timestamps } from "../../drizzle/schema/helpers/columns.helpers"; export const Build = pgTable("builds", { id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "build_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), diff --git a/src/db/schema/BuildComponent.ts b/src/db/schema/BuildComponent.ts index 8fbdbf3..361e7a6 100644 --- a/src/db/schema/BuildComponent.ts +++ b/src/db/schema/BuildComponent.ts @@ -1,6 +1,6 @@ import { pgTable, integer, varchar, text, uuid } from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm"; -import { timestamps } from "./helpers/columns.helpers"; +import { timestamps } from "../../drizzle/schema/helpers/columns.helpers"; export const BuildComponent = pgTable("builds_components", { id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "build_components_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), diff --git a/src/db/schema/Category.ts b/src/db/schema/Category.ts index 3f17fd5..1e7196d 100644 --- a/src/db/schema/Category.ts +++ b/src/db/schema/Category.ts @@ -1,6 +1,6 @@ import { pgTable, integer, varchar, uuid } from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm"; -import { timestamps } from "./helpers/columns.helpers"; +import { timestamps } from "../../drizzle/schema/helpers/columns.helpers"; export const Category = pgTable("categories", { id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "categories_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), diff --git a/src/db/schema/Compartment.ts b/src/db/schema/Compartment.ts index ede7cfa..f2af28f 100644 --- a/src/db/schema/Compartment.ts +++ b/src/db/schema/Compartment.ts @@ -1,6 +1,6 @@ import { pgTable, integer, varchar, text,uuid} from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm"; -import { timestamps } from "./helpers/columns.helpers"; +import { timestamps } from "../../drizzle/schema/helpers/columns.helpers"; export const compartment = pgTable("compartment", { id: uuid().defaultRandom().primaryKey().notNull(), diff --git a/src/db/schema/ComponentTypes.ts b/src/db/schema/ComponentTypes.ts index 95467db..8043d36 100644 --- a/src/db/schema/ComponentTypes.ts +++ b/src/db/schema/ComponentTypes.ts @@ -1,6 +1,6 @@ import { pgTable, integer, varchar, uuid} from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm"; -import { timestamps } from "./helpers/columns.helpers"; +import { timestamps } from "../../drizzle/schema/helpers/columns.helpers"; export const ComponentType = pgTable("component_type", { id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "component_type_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), diff --git a/src/db/schema/LipseyCatalog.ts b/src/db/schema/LipseyCatalog.ts index 05ab6eb..87d92da 100644 --- a/src/db/schema/LipseyCatalog.ts +++ b/src/db/schema/LipseyCatalog.ts @@ -1,6 +1,6 @@ import { pgTable, integer, varchar, text, doublePrecision, timestamp } from "drizzle-orm/pg-core" import { sql } from "drizzle-orm" -import { timestamps } from "./helpers/columns.helpers"; +import { timestamps } from "../../drizzle/schema/helpers/columns.helpers"; export const LipseyCatalog = pgTable("lipseycatalog", { diff --git a/src/db/schema/Manufacturer.ts b/src/db/schema/Manufacturer.ts index 22cece9..5d3092c 100644 --- a/src/db/schema/Manufacturer.ts +++ b/src/db/schema/Manufacturer.ts @@ -1,6 +1,6 @@ import { pgTable, integer, varchar, uuid} from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm"; -import { timestamps } from "./helpers/columns.helpers"; +import { timestamps } from "../../drizzle/schema/helpers/columns.helpers"; export const manufacturer = pgTable("manufacturer", { id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "manufacturer_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), diff --git a/src/db/schema/Product.ts b/src/db/schema/Product.ts index 85bb63b..f419369 100644 --- a/src/db/schema/Product.ts +++ b/src/db/schema/Product.ts @@ -1,6 +1,6 @@ import { pgTable, integer, varchar, text, decimal } from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm"; -import { timestamps } from "./helpers/columns.helpers"; +import { timestamps } from "../../drizzle/schema/helpers/columns.helpers"; export const Product = pgTable("products", { id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "products_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), diff --git a/src/db/schema/Product_feed.ts b/src/db/schema/Product_feed.ts index b5d155c..1468e19 100644 --- a/src/db/schema/Product_feed.ts +++ b/src/db/schema/Product_feed.ts @@ -1,6 +1,6 @@ import { pgTable, integer, varchar, timestamp, uuid } from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm"; -import { timestamps } from "./helpers/columns.helpers"; +import { timestamps } from "../../drizzle/schema/helpers/columns.helpers"; export const Product_feed = pgTable("product_feeds", { id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "productfeeds_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), diff --git a/src/db/schema/Psa.ts b/src/db/schema/Psa.ts index 6a4303e..fc846c0 100644 --- a/src/db/schema/Psa.ts +++ b/src/db/schema/Psa.ts @@ -1,7 +1,7 @@ import { pgTable, integer, varchar, text, decimal, uuid, real } from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm"; -import { timestamps } from "./helpers/columns.helpers"; +import { timestamps } from "../../drizzle/schema/helpers/columns.helpers"; export const psa = pgTable("psa", { sku: varchar("SKU", { length: 50 }), diff --git a/src/db/schema/Reseller.ts b/src/db/schema/Reseller.ts index e138b5e..d03afdf 100644 --- a/src/db/schema/Reseller.ts +++ b/src/db/schema/Reseller.ts @@ -1,6 +1,6 @@ import { pgTable, integer, varchar, uuid } from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm"; -import { timestamps } from "./helpers/columns.helpers"; +import { timestamps } from "../../drizzle/schema/helpers/columns.helpers"; export const Reseller = pgTable("bal_resellers", { id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "resellers_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), diff --git a/src/db/schema/Sessions.ts b/src/db/schema/Sessions.ts index 2cd04e2..ec0ea85 100644 --- a/src/db/schema/Sessions.ts +++ b/src/db/schema/Sessions.ts @@ -1,10 +1,10 @@ import { pgTable, text, timestamp } from "drizzle-orm/pg-core"; -import {User} from '@schemas/User'; +import {user} from '@schemas/schema'; export const sessions = pgTable("session", { sessionToken: text("sessionToken").primaryKey(), userId: text("userId") .notNull() - .references(() => User.id, { onDelete: "cascade" }), + .references(() => user.id, { onDelete: "cascade" }), expires: timestamp("expires", { mode: "date" }).notNull(), }) \ No newline at end of file diff --git a/src/drizzle/relations.ts b/src/drizzle/relations.ts index 5b87bf1..678475a 100644 --- a/src/drizzle/relations.ts +++ b/src/drizzle/relations.ts @@ -1,29 +1,13 @@ import { relations } from "drizzle-orm/relations"; -import { usersKeep, userBuilds, userFavorites, userActivityLog } from "./schema"; +import { user, authenticator } from "./schema"; -export const userBuildsRelations = relations(userBuilds, ({one}) => ({ - usersKeep: one(usersKeep, { - fields: [userBuilds.userId], - references: [usersKeep.id] +export const authenticatorRelations = relations(authenticator, ({one}) => ({ + user: one(user, { + fields: [authenticator.userId], + references: [user.id] }), })); -export const usersKeepRelations = relations(usersKeep, ({many}) => ({ - userBuilds: many(userBuilds), - userFavorites: many(userFavorites), - userActivityLogs: many(userActivityLog), -})); - -export const userFavoritesRelations = relations(userFavorites, ({one}) => ({ - usersKeep: one(usersKeep, { - fields: [userFavorites.userId], - references: [usersKeep.id] - }), -})); - -export const userActivityLogRelations = relations(userActivityLog, ({one}) => ({ - usersKeep: one(usersKeep, { - fields: [userActivityLog.userId], - references: [usersKeep.id] - }), +export const userRelations = relations(user, ({many}) => ({ + authenticators: many(authenticator), })); \ No newline at end of file diff --git a/src/drizzle/schema.ts b/src/drizzle/schema.ts index dc56401..8d5e1a8 100644 --- a/src/drizzle/schema.ts +++ b/src/drizzle/schema.ts @@ -1,4 +1,4 @@ -import { pgTable, integer, varchar, text, numeric, timestamp, uuid, unique, foreignKey, bigserial, bigint, boolean, index, real, check, date, doublePrecision, pgView } from "drizzle-orm/pg-core" +import { pgTable, integer, varchar, text, numeric, timestamp, unique, check, bigserial, date, boolean, uuid, bigint, real, doublePrecision, primaryKey, foreignKey } from "drizzle-orm/pg-core" import { sql } from "drizzle-orm" @@ -16,6 +16,31 @@ export const products = pgTable("products", { deletedAt: timestamp("deleted_at", { mode: 'string' }), }); +export const users = pgTable("users", { + id: bigserial({ mode: "bigint" }).primaryKey().notNull(), + username: varchar({ length: 50 }).notNull(), + email: varchar({ length: 255 }).notNull(), + passwordHash: varchar("password_hash", { length: 255 }).notNull(), + firstName: varchar("first_name", { length: 50 }), + lastName: varchar("last_name", { length: 50 }), + profilePicture: varchar("profile_picture", { length: 255 }), + dateOfBirth: date("date_of_birth"), + phoneNumber: varchar("phone_number", { length: 20 }), + createdAt: timestamp("created_at", { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`), + updatedAt: timestamp("updated_at", { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`), + isAdmin: boolean("is_admin").default(false), + lastLogin: timestamp("last_login", { mode: 'string' }), + emailVerified: boolean("email_verified").default(false), + buildPrivacySetting: text("build_privacy_setting").default('public'), + uuid: uuid().defaultRandom(), +}, (table) => { + return { + usersUsernameKey: unique("users_username_key").on(table.username), + usersEmailKey: unique("users_email_key").on(table.email), + usersBuildPrivacySettingCheck: check("users_build_privacy_setting_check", sql`build_privacy_setting = ANY (ARRAY['private'::text, 'public'::text])`), + } +}); + export const categories = pgTable("categories", { id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "categories_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), name: varchar({ length: 100 }).notNull(), @@ -41,40 +66,25 @@ export const productFeeds = pgTable("product_feeds", { } }); -export const userBuilds = pgTable("user_builds", { - id: bigserial({ mode: "bigint" }).primaryKey().notNull(), - // You can use { mode: "bigint" } if numbers are exceeding js number limitations - userId: bigint("user_id", { mode: "number" }).notNull(), - buildName: varchar("build_name", { length: 255 }).notNull(), - buildDescription: text("build_description"), - createdAt: timestamp("created_at", { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`), - updatedAt: timestamp("updated_at", { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`), - isShared: boolean("is_shared").default(false), +export const user = pgTable("user", { + id: text().primaryKey().notNull(), + name: text(), + email: text(), + emailVerified: timestamp({ mode: 'string' }), + image: text(), }, (table) => { return { - userBuildsUserIdFkey: foreignKey({ - columns: [table.userId], - foreignColumns: [usersKeep.id], - name: "user_builds_user_id_fkey" - }).onDelete("cascade"), + userEmailUnique: unique("user_email_unique").on(table.email), } }); -export const userFavorites = pgTable("user_favorites", { - id: bigserial({ mode: "bigint" }).primaryKey().notNull(), +export const userActivityLog = pgTable("user_activity_log", { + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + id: bigint({ mode: "number" }).primaryKey().generatedAlwaysAsIdentity({ name: "user_activity_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), // You can use { mode: "bigint" } if numbers are exceeding js number limitations userId: bigint("user_id", { mode: "number" }).notNull(), - // You can use { mode: "bigint" } if numbers are exceeding js number limitations - itemId: bigint("item_id", { mode: "number" }).notNull(), - addedAt: timestamp("added_at", { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`), -}, (table) => { - return { - userFavoritesUserIdFkey: foreignKey({ - columns: [table.userId], - foreignColumns: [usersKeep.id], - name: "user_favorites_user_id_fkey" - }).onDelete("cascade"), - } + activity: text().notNull(), + timestamp: timestamp({ mode: 'string' }).default(sql`CURRENT_TIMESTAMP`), }); export const brands = pgTable("brands", { @@ -103,20 +113,10 @@ export const manufacturer = pgTable("manufacturer", { } }); -export const userActivityLog = pgTable("user_activity_log", { - id: bigserial({ mode: "bigint" }).primaryKey().notNull(), - // You can use { mode: "bigint" } if numbers are exceeding js number limitations - userId: bigint("user_id", { mode: "number" }).notNull(), - activity: text().notNull(), - timestamp: timestamp({ mode: 'string' }).default(sql`CURRENT_TIMESTAMP`), -}, (table) => { - return { - userActivityLogUserIdFkey: foreignKey({ - columns: [table.userId], - foreignColumns: [usersKeep.id], - name: "user_activity_log_user_id_fkey" - }).onDelete("cascade"), - } +export const session = pgTable("session", { + sessionToken: text().primaryKey().notNull(), + userId: text().notNull(), + expires: timestamp({ mode: 'string' }).notNull(), }); export const states = pgTable("states", { @@ -186,72 +186,10 @@ export const builds = pgTable("builds", { uuid: uuid().defaultRandom(), }, (table) => { return { - idIdx: index("builds_id_idx").using("btree", table.id.asc().nullsLast().op("int4_ops")), - uuidIdx: index("builds_uuid_idx").using("btree", table.uuid.asc().nullsLast().op("uuid_ops")), buildsUuidUnique: unique("builds_uuid_unique").on(table.uuid), } }); -export const balAccounts = pgTable("bal_accounts", { - id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "accountsid_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), - firstName: varchar("first_name", { length: 40 }), - lastName: varchar("last_name", { length: 40 }), - updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(), - createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(), - deletedAt: timestamp("deleted_at", { mode: 'string' }), - email: varchar({ length: 100 }), - username: varchar({ length: 50 }).notNull(), - passwordHash: varchar("password_hash", { length: 255 }).notNull(), - uuid: uuid().defaultRandom(), -}, (table) => { - return { - balAccountsUsernameUnique: unique("bal_accounts_username_unique").on(table.username), - balAccountsPasswordHashUnique: unique("bal_accounts_password_hash_unique").on(table.passwordHash), - balAccountsUuidUnique: unique("bal_accounts_uuid_unique").on(table.uuid), - } -}); - -export const brownells = pgTable("brownells", { - sku: text(), - manufacturerId: text("manufacturer_id"), - brandName: text("brand_name"), - productName: text("product_name"), - longDescription: text("long_description"), - shortDescription: text("short_description"), - department: text(), - category: text(), - subcategory: text(), - thumbUrl: text("thumb_url"), - imageUrl: text("image_url"), - buyLink: text("buy_link"), - keywords: text(), - reviews: text(), - retailPrice: numeric("retail_price"), - salePrice: numeric("sale_price"), - brandPageLink: text("brand_page_link"), - brandLogoImage: text("brand_logo_image"), - productPageViewTracking: text("product_page_view_tracking"), - parentGroupId: text("parent_group_id"), - color: text(), - size: text(), - pattern: text(), - material: text(), - ageGroup: text("age_group"), - gender: text(), - upc: text(), - availability: text(), - googleProductCategory: text("google_product_category"), - mediumImageUrl: text("medium_image_url"), - variantsXml: text("variants_xml"), - gtin: text(), - keyWords: text("key_words"), - productContentWidget: text("product_content_widget"), - googleCategorization: text("google_categorization"), - itemBasedCommission: text("item_based_commission"), - itemBasedCommissionRate: text("item_based_commission_rate"), - itemBasedCommissionRule: text("item_based_commission_rule"), -}); - export const psa = pgTable("psa", { sku: varchar("SKU", { length: 50 }), manufacturerId: varchar("MANUFACTURER_ID", { length: 50 }), @@ -285,31 +223,6 @@ export const psa = pgTable("psa", { uuid: uuid().defaultRandom(), }); -export const usersKeep = pgTable("users_keep", { - id: bigserial({ mode: "bigint" }).primaryKey().notNull(), - username: varchar({ length: 50 }).notNull(), - email: varchar({ length: 255 }).notNull(), - passwordHash: varchar("password_hash", { length: 255 }).notNull(), - firstName: varchar("first_name", { length: 50 }), - lastName: varchar("last_name", { length: 50 }), - profilePicture: varchar("profile_picture", { length: 255 }), - dateOfBirth: date("date_of_birth"), - phoneNumber: varchar("phone_number", { length: 20 }), - createdAt: timestamp("created_at", { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`), - updatedAt: timestamp("updated_at", { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`), - isAdmin: boolean("is_admin").default(false), - lastLogin: timestamp("last_login", { mode: 'string' }), - emailVerified: boolean("email_verified").default(false), - buildPrivacySetting: text("build_privacy_setting").default('public'), - uuid: uuid().defaultRandom(), -}, (table) => { - return { - usersUsernameKey: unique("users_username_key").on(table.username), - usersEmailKey: unique("users_email_key").on(table.email), - usersBuildPrivacySettingCheck: check("users_build_privacy_setting_check", sql`build_privacy_setting = ANY (ARRAY['private'::text, 'public'::text])`), - } -}); - export const lipseycatalog = pgTable("lipseycatalog", { id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "lipseycatalog_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), itemno: varchar({ length: 20 }).notNull(), @@ -422,7 +335,52 @@ export const balResellers = pgTable("bal_resellers", { balResellersUuidUnique: unique("bal_resellers_uuid_unique").on(table.uuid), } }); -export const vwProducts = pgView("vw_products", { aeroSku: text("aero_sku"), - aeroCategory: text("aero_category"), - aeroProductName: text("aero_product_name"), -}).as(sql`SELECT aero.sku AS aero_sku, aero.category AS aero_category, aero.product_name AS aero_product_name FROM aero_precision aero WHERE aero.department = 'Stripped Lowers'::text UNION ALL SELECT psa."SKU" AS aero_sku, psa."CATEGORY" AS aero_category, psa."PRODUCT_NAME" AS aero_product_name FROM psa psa WHERE psa."FINELINE"::text = 'AR Complete Lowers'::text`); \ No newline at end of file + +export const verificationToken = pgTable("verificationToken", { + identifier: text().notNull(), + token: text().notNull(), + expires: timestamp({ mode: 'string' }).notNull(), +}, (table) => { + return { + verificationTokenIdentifierTokenPk: primaryKey({ columns: [table.identifier, table.token], name: "verificationToken_identifier_token_pk"}), + } +}); + +export const authenticator = pgTable("authenticator", { + credentialId: text().notNull(), + userId: text().notNull(), + providerAccountId: text().notNull(), + credentialPublicKey: text().notNull(), + counter: integer().notNull(), + credentialDeviceType: text().notNull(), + credentialBackedUp: boolean().notNull(), + transports: text(), +}, (table) => { + return { + authenticatorUserIdUserIdFk: foreignKey({ + columns: [table.userId], + foreignColumns: [user.id], + name: "authenticator_userId_user_id_fk" + }).onDelete("cascade"), + authenticatorUserIdCredentialIdPk: primaryKey({ columns: [table.credentialId, table.userId], name: "authenticator_userId_credentialID_pk"}), + authenticatorCredentialIdUnique: unique("authenticator_credentialID_unique").on(table.credentialId), + } +}); + +export const account = pgTable("account", { + userId: text().notNull(), + type: text().notNull(), + provider: text().notNull(), + providerAccountId: text().notNull(), + refreshToken: text("refresh_token"), + accessToken: text("access_token"), + expiresAt: integer("expires_at"), + tokenType: text("token_type"), + scope: text(), + idToken: text("id_token"), + sessionState: text("session_state"), +}, (table) => { + return { + accountProviderProviderAccountIdPk: primaryKey({ columns: [table.provider, table.providerAccountId], name: "account_provider_providerAccountId_pk"}), + } +}); diff --git a/src/drizzle/schema/0000_stiff_odin.sql b/src/drizzle/schema/0000_stiff_odin.sql new file mode 100644 index 0000000..cb6d1e5 --- /dev/null +++ b/src/drizzle/schema/0000_stiff_odin.sql @@ -0,0 +1,349 @@ +-- Current sql file was generated after introspecting the database +-- If you want to run this migration please uncomment this code before executing migrations +/* +CREATE TABLE IF NOT EXISTS "products" ( + "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "products_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), + "name" varchar(255) NOT NULL, + "description" text NOT NULL, + "price" numeric NOT NULL, + "reseller_id" integer NOT NULL, + "category_id" integer NOT NULL, + "stock_qty" integer DEFAULT 0, + "updated_at" timestamp DEFAULT now() NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "deleted_at" timestamp +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "users" ( + "id" bigserial PRIMARY KEY NOT NULL, + "username" varchar(50) NOT NULL, + "email" varchar(255) NOT NULL, + "password_hash" varchar(255) NOT NULL, + "first_name" varchar(50), + "last_name" varchar(50), + "profile_picture" varchar(255), + "date_of_birth" date, + "phone_number" varchar(20), + "created_at" timestamp DEFAULT CURRENT_TIMESTAMP, + "updated_at" timestamp DEFAULT CURRENT_TIMESTAMP, + "is_admin" boolean DEFAULT false, + "last_login" timestamp, + "email_verified" boolean DEFAULT false, + "build_privacy_setting" text DEFAULT 'public', + "uuid" uuid DEFAULT gen_random_uuid(), + CONSTRAINT "users_username_key" UNIQUE("username"), + CONSTRAINT "users_email_key" UNIQUE("email"), + CONSTRAINT "users_build_privacy_setting_check" CHECK (build_privacy_setting = ANY (ARRAY['private'::text, 'public'::text])) +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "categories" ( + "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "categories_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), + "name" varchar(100) NOT NULL, + "parent_category_id" integer, + "updated_at" timestamp DEFAULT now() NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "deleted_at" timestamp, + "uuid" uuid DEFAULT gen_random_uuid() +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "product_feeds" ( + "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "productfeeds_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), + "reseller_id" integer NOT NULL, + "feed_url" varchar(255) NOT NULL, + "last_update" timestamp, + "updated_at" timestamp DEFAULT now() NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "deleted_at" timestamp, + "uuid" uuid DEFAULT gen_random_uuid(), + CONSTRAINT "product_feeds_uuid_unique" UNIQUE("uuid") +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "user" ( + "id" text PRIMARY KEY NOT NULL, + "name" text, + "email" text, + "emailVerified" timestamp, + "image" text, + CONSTRAINT "user_email_unique" UNIQUE("email") +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "user_activity_log" ( + "id" bigint PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "user_activity_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), + "user_id" bigint NOT NULL, + "activity" text NOT NULL, + "timestamp" timestamp DEFAULT CURRENT_TIMESTAMP +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "brands" ( + "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "brands_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), + "name" varchar(100) NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "deleted_at" timestamp, + "uuid" uuid DEFAULT gen_random_uuid(), + CONSTRAINT "brands_uuid_unique" UNIQUE("uuid") +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "manufacturer" ( + "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "manufacturer_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), + "name" varchar(100) NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "deleted_at" timestamp, + "uuid" uuid DEFAULT gen_random_uuid(), + CONSTRAINT "manufacturer_uuid_unique" UNIQUE("uuid") +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "session" ( + "sessionToken" text PRIMARY KEY NOT NULL, + "userId" text NOT NULL, + "expires" timestamp NOT NULL +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "states" ( + "id" integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (sequence name "states_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), + "state" varchar(50), + "abbreviation" varchar(50) +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "component_type" ( + "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "component_type_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), + "name" varchar(100) NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "deleted_at" timestamp, + "uuid" uuid DEFAULT gen_random_uuid(), + CONSTRAINT "component_type_uuid_unique" UNIQUE("uuid") +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "aero_precision" ( + "sku" text PRIMARY KEY NOT NULL, + "manufacturer_id" text, + "brand_name" text, + "product_name" text, + "long_description" text, + "short_description" text, + "department" text, + "category" text, + "subcategory" text, + "thumb_url" text, + "image_url" text, + "buy_link" text, + "keywords" text, + "reviews" text, + "retail_price" numeric, + "sale_price" numeric, + "brand_page_link" text, + "brand_logo_image" text, + "product_page_view_tracking" text, + "variants_xml" text, + "medium_image_url" text, + "product_content_widget" text, + "google_categorization" text, + "item_based_commission" text, + "uuid" uuid DEFAULT gen_random_uuid() +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "compartment" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "name" varchar(100) NOT NULL, + "description" varchar(300), + "updated_at" timestamp DEFAULT now() NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "deleted_at" timestamp +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "builds" ( + "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "build_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), + "account_id" integer NOT NULL, + "name" varchar(255) NOT NULL, + "description" text, + "updated_at" timestamp DEFAULT now() NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "deleted_at" timestamp, + "uuid" uuid DEFAULT gen_random_uuid(), + CONSTRAINT "builds_uuid_unique" UNIQUE("uuid") +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "psa" ( + "SKU" varchar(50), + "MANUFACTURER_ID" varchar(50), + "BRAND_NAME" varchar(50), + "PRODUCT_NAME" varchar(255), + "LONG_DESCRIPTION" text, + "SHORT_DESCRIPTION" varchar(50), + "DEPARTMENT" varchar(50), + "CATEGORY" varchar(50), + "SUBCATEGORY" varchar(50), + "THUMB_URL" varchar(50), + "IMAGE_URL" varchar(50), + "BUY_LINK" varchar(128), + "KEYWORDS" varchar(50), + "REVIEWS" varchar(50), + "RETAIL_PRICE" real, + "SALE_PRICE" real, + "BRAND_PAGE_LINK" varchar(50), + "BRAND_LOGO_IMAGE" varchar(50), + "PRODUCT_PAGE_VIEW_TRACKING" varchar(256), + "PARENT_GROUP_ID" varchar(50), + "FINELINE" varchar(50), + "SUPERFINELINE" varchar(200), + "MODELNUMBER" varchar(50), + "CALIBER" varchar(200), + "UPC" varchar(100), + "MEDIUM_IMAGE_URL" varchar(50), + "PRODUCT_CONTENT_WIDGET" varchar(256), + "GOOGLE_CATEGORIZATION" varchar(50), + "ITEM_BASED_COMMISSION" varchar(50), + "uuid" uuid DEFAULT gen_random_uuid() +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "lipseycatalog" ( + "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "lipseycatalog_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), + "itemno" varchar(20) NOT NULL, + "description1" text, + "description2" text, + "upc" varchar(20), + "manufacturermodelno" varchar(30), + "msrp" double precision, + "model" text, + "calibergauge" text, + "manufacturer" text, + "type" text, + "action" text, + "barrellength" text, + "capacity" text, + "finish" text, + "overalllength" text, + "receiver" text, + "safety" text, + "sights" text, + "stockframegrips" text, + "magazine" text, + "weight" text, + "imagename" text, + "chamber" text, + "drilledandtapped" text, + "rateoftwist" text, + "itemtype" text, + "additionalfeature1" text, + "additionalfeature2" text, + "additionalfeature3" text, + "shippingweight" text, + "boundbookmanufacturer" text, + "boundbookmodel" text, + "boundbooktype" text, + "nfathreadpattern" text, + "nfaattachmentmethod" text, + "nfabaffletype" text, + "silencercanbedisassembled" text, + "silencerconstructionmaterial" text, + "nfadbreduction" text, + "silenceroutsidediameter" text, + "nfaform3Caliber" text, + "opticmagnification" text, + "maintubesize" text, + "adjustableobjective" text, + "objectivesize" text, + "opticadjustments" text, + "illuminatedreticle" text, + "reticle" text, + "exclusive" text, + "quantity" varchar(10) DEFAULT NULL, + "allocated" text, + "onsale" text, + "price" double precision, + "currentprice" double precision, + "retailmap" double precision, + "fflrequired" text, + "sotrequired" text, + "exclusivetype" text, + "scopecoverincluded" text, + "special" text, + "sightstype" text, + "case" text, + "choke" text, + "dbreduction" text, + "family" text, + "finishtype" text, + "frame" text, + "griptype" varchar(30), + "handgunslidematerial" text, + "countryoforigin" varchar(4), + "itemlength" text, + "itemwidth" text, + "itemheight" text, + "packagelength" double precision, + "packagewidth" double precision, + "packageheight" double precision, + "itemgroup" varchar(40), + "updated_at" timestamp DEFAULT now() NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "deleted_at" timestamp +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "builds_components" ( + "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "build_components_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), + "build_id" integer NOT NULL, + "product_id" integer NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "deleted_at" timestamp, + "uuid" uuid DEFAULT gen_random_uuid(), + CONSTRAINT "builds_components_uuid_unique" UNIQUE("uuid") +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "bal_resellers" ( + "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "resellers_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), + "name" varchar(100) NOT NULL, + "website_url" varchar(255), + "contact_email" varchar(100), + "updated_at" timestamp DEFAULT now() NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "deleted_at" timestamp, + "uuid" uuid DEFAULT gen_random_uuid(), + CONSTRAINT "bal_resellers_uuid_unique" UNIQUE("uuid") +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "verificationToken" ( + "identifier" text NOT NULL, + "token" text NOT NULL, + "expires" timestamp NOT NULL, + CONSTRAINT "verificationToken_identifier_token_pk" PRIMARY KEY("identifier","token") +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "authenticator" ( + "credentialID" text NOT NULL, + "userId" text NOT NULL, + "providerAccountId" text NOT NULL, + "credentialPublicKey" text NOT NULL, + "counter" integer NOT NULL, + "credentialDeviceType" text NOT NULL, + "credentialBackedUp" boolean NOT NULL, + "transports" text, + CONSTRAINT "authenticator_userId_credentialID_pk" PRIMARY KEY("credentialID","userId"), + CONSTRAINT "authenticator_credentialID_unique" UNIQUE("credentialID") +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "account" ( + "userId" text NOT NULL, + "type" text NOT NULL, + "provider" text NOT NULL, + "providerAccountId" text NOT NULL, + "refresh_token" text, + "access_token" text, + "expires_at" integer, + "token_type" text, + "scope" text, + "id_token" text, + "session_state" text, + CONSTRAINT "account_provider_providerAccountId_pk" PRIMARY KEY("provider","providerAccountId") +); +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "authenticator" ADD CONSTRAINT "authenticator_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; + +*/ \ No newline at end of file diff --git a/src/db/schema/helpers/columns.helpers.ts b/src/drizzle/schema/helpers/columns.helpers.ts similarity index 100% rename from src/db/schema/helpers/columns.helpers.ts rename to src/drizzle/schema/helpers/columns.helpers.ts diff --git a/src/drizzle/schema/meta/0000_snapshot.json b/src/drizzle/schema/meta/0000_snapshot.json new file mode 100644 index 0000000..4a39f92 --- /dev/null +++ b/src/drizzle/schema/meta/0000_snapshot.json @@ -0,0 +1,2174 @@ +{ + "id": "00000000-0000-0000-0000-000000000000", + "prevId": "", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.products": { + "name": "products", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "products_id_seq", + "increment": "1", + "minValue": "1", + "maxValue": "2147483647", + "startWith": "1", + "cache": "1", + "cycle": false, + "schema": "public" + } + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "price": { + "name": "price", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "reseller_id": { + "name": "reseller_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "category_id": { + "name": "category_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "stock_qty": { + "name": "stock_qty", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "username": { + "name": "username", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "first_name": { + "name": "first_name", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "last_name": { + "name": "last_name", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "profile_picture": { + "name": "profile_picture", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "date_of_birth": { + "name": "date_of_birth", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "phone_number": { + "name": "phone_number", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "is_admin": { + "name": "is_admin", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "last_login": { + "name": "last_login", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "build_privacy_setting": { + "name": "build_privacy_setting", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'public'" + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": false, + "default": "gen_random_uuid()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_username_key": { + "columns": [ + "username" + ], + "nullsNotDistinct": false, + "name": "users_username_key" + }, + "users_email_key": { + "columns": [ + "email" + ], + "nullsNotDistinct": false, + "name": "users_email_key" + } + }, + "checkConstraints": { + "users_build_privacy_setting_check": { + "name": "users_build_privacy_setting_check", + "value": "build_privacy_setting = ANY (ARRAY['private'::text, 'public'::text])" + } + }, + "policies": {}, + "isRLSEnabled": false + }, + "public.categories": { + "name": "categories", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "categories_id_seq", + "increment": "1", + "minValue": "1", + "maxValue": "2147483647", + "startWith": "1", + "cache": "1", + "cycle": false, + "schema": "public" + } + }, + "name": { + "name": "name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "parent_category_id": { + "name": "parent_category_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": false, + "default": "gen_random_uuid()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.product_feeds": { + "name": "product_feeds", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "productfeeds_id_seq", + "increment": "1", + "minValue": "1", + "maxValue": "2147483647", + "startWith": "1", + "cache": "1", + "cycle": false, + "schema": "public" + } + }, + "reseller_id": { + "name": "reseller_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "feed_url": { + "name": "feed_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "last_update": { + "name": "last_update", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": false, + "default": "gen_random_uuid()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "product_feeds_uuid_unique": { + "columns": [ + "uuid" + ], + "nullsNotDistinct": false, + "name": "product_feeds_uuid_unique" + } + }, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "emailVerified": { + "name": "emailVerified", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "columns": [ + "email" + ], + "nullsNotDistinct": false, + "name": "user_email_unique" + } + }, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.user_activity_log": { + "name": "user_activity_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigint", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "user_activity_id_seq", + "increment": "1", + "minValue": "1", + "maxValue": "2147483647", + "startWith": "1", + "cache": "1", + "cycle": false, + "schema": "public" + } + }, + "user_id": { + "name": "user_id", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "activity": { + "name": "activity", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.brands": { + "name": "brands", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "brands_id_seq", + "increment": "1", + "minValue": "1", + "maxValue": "2147483647", + "startWith": "1", + "cache": "1", + "cycle": false, + "schema": "public" + } + }, + "name": { + "name": "name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": false, + "default": "gen_random_uuid()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "brands_uuid_unique": { + "columns": [ + "uuid" + ], + "nullsNotDistinct": false, + "name": "brands_uuid_unique" + } + }, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.manufacturer": { + "name": "manufacturer", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "manufacturer_id_seq", + "increment": "1", + "minValue": "1", + "maxValue": "2147483647", + "startWith": "1", + "cache": "1", + "cycle": false, + "schema": "public" + } + }, + "name": { + "name": "name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": false, + "default": "gen_random_uuid()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "manufacturer_uuid_unique": { + "columns": [ + "uuid" + ], + "nullsNotDistinct": false, + "name": "manufacturer_uuid_unique" + } + }, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "sessionToken": { + "name": "sessionToken", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.states": { + "name": "states", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "states_id_seq", + "increment": "1", + "minValue": "1", + "maxValue": "2147483647", + "startWith": "1", + "cache": "1", + "cycle": false, + "schema": "public" + } + }, + "state": { + "name": "state", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "abbreviation": { + "name": "abbreviation", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.component_type": { + "name": "component_type", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "component_type_id_seq", + "increment": "1", + "minValue": "1", + "maxValue": "2147483647", + "startWith": "1", + "cache": "1", + "cycle": false, + "schema": "public" + } + }, + "name": { + "name": "name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": false, + "default": "gen_random_uuid()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "component_type_uuid_unique": { + "columns": [ + "uuid" + ], + "nullsNotDistinct": false, + "name": "component_type_uuid_unique" + } + }, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.aero_precision": { + "name": "aero_precision", + "schema": "", + "columns": { + "sku": { + "name": "sku", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "manufacturer_id": { + "name": "manufacturer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "brand_name": { + "name": "brand_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "product_name": { + "name": "product_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "long_description": { + "name": "long_description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "short_description": { + "name": "short_description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "department": { + "name": "department", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subcategory": { + "name": "subcategory", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumb_url": { + "name": "thumb_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "image_url": { + "name": "image_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "buy_link": { + "name": "buy_link", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "keywords": { + "name": "keywords", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reviews": { + "name": "reviews", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "retail_price": { + "name": "retail_price", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "sale_price": { + "name": "sale_price", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "brand_page_link": { + "name": "brand_page_link", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "brand_logo_image": { + "name": "brand_logo_image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "product_page_view_tracking": { + "name": "product_page_view_tracking", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "variants_xml": { + "name": "variants_xml", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "medium_image_url": { + "name": "medium_image_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "product_content_widget": { + "name": "product_content_widget", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "google_categorization": { + "name": "google_categorization", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "item_based_commission": { + "name": "item_based_commission", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": false, + "default": "gen_random_uuid()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.compartment": { + "name": "compartment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "varchar(300)", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.builds": { + "name": "builds", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "build_id_seq", + "increment": "1", + "minValue": "1", + "maxValue": "2147483647", + "startWith": "1", + "cache": "1", + "cycle": false, + "schema": "public" + } + }, + "account_id": { + "name": "account_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": false, + "default": "gen_random_uuid()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "builds_uuid_unique": { + "columns": [ + "uuid" + ], + "nullsNotDistinct": false, + "name": "builds_uuid_unique" + } + }, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.psa": { + "name": "psa", + "schema": "", + "columns": { + "SKU": { + "name": "SKU", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "MANUFACTURER_ID": { + "name": "MANUFACTURER_ID", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "BRAND_NAME": { + "name": "BRAND_NAME", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "PRODUCT_NAME": { + "name": "PRODUCT_NAME", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "LONG_DESCRIPTION": { + "name": "LONG_DESCRIPTION", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "SHORT_DESCRIPTION": { + "name": "SHORT_DESCRIPTION", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "DEPARTMENT": { + "name": "DEPARTMENT", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "CATEGORY": { + "name": "CATEGORY", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "SUBCATEGORY": { + "name": "SUBCATEGORY", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "THUMB_URL": { + "name": "THUMB_URL", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "IMAGE_URL": { + "name": "IMAGE_URL", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "BUY_LINK": { + "name": "BUY_LINK", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "KEYWORDS": { + "name": "KEYWORDS", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "REVIEWS": { + "name": "REVIEWS", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "RETAIL_PRICE": { + "name": "RETAIL_PRICE", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "SALE_PRICE": { + "name": "SALE_PRICE", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "BRAND_PAGE_LINK": { + "name": "BRAND_PAGE_LINK", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "BRAND_LOGO_IMAGE": { + "name": "BRAND_LOGO_IMAGE", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "PRODUCT_PAGE_VIEW_TRACKING": { + "name": "PRODUCT_PAGE_VIEW_TRACKING", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "PARENT_GROUP_ID": { + "name": "PARENT_GROUP_ID", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "FINELINE": { + "name": "FINELINE", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "SUPERFINELINE": { + "name": "SUPERFINELINE", + "type": "varchar(200)", + "primaryKey": false, + "notNull": false + }, + "MODELNUMBER": { + "name": "MODELNUMBER", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "CALIBER": { + "name": "CALIBER", + "type": "varchar(200)", + "primaryKey": false, + "notNull": false + }, + "UPC": { + "name": "UPC", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "MEDIUM_IMAGE_URL": { + "name": "MEDIUM_IMAGE_URL", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "PRODUCT_CONTENT_WIDGET": { + "name": "PRODUCT_CONTENT_WIDGET", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "GOOGLE_CATEGORIZATION": { + "name": "GOOGLE_CATEGORIZATION", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "ITEM_BASED_COMMISSION": { + "name": "ITEM_BASED_COMMISSION", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": false, + "default": "gen_random_uuid()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.lipseycatalog": { + "name": "lipseycatalog", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "lipseycatalog_id_seq", + "increment": "1", + "minValue": "1", + "maxValue": "2147483647", + "startWith": "1", + "cache": "1", + "cycle": false, + "schema": "public" + } + }, + "itemno": { + "name": "itemno", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "description1": { + "name": "description1", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description2": { + "name": "description2", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "upc": { + "name": "upc", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false + }, + "manufacturermodelno": { + "name": "manufacturermodelno", + "type": "varchar(30)", + "primaryKey": false, + "notNull": false + }, + "msrp": { + "name": "msrp", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "calibergauge": { + "name": "calibergauge", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "manufacturer": { + "name": "manufacturer", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "barrellength": { + "name": "barrellength", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "capacity": { + "name": "capacity", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "finish": { + "name": "finish", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "overalllength": { + "name": "overalllength", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "receiver": { + "name": "receiver", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "safety": { + "name": "safety", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sights": { + "name": "sights", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stockframegrips": { + "name": "stockframegrips", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "magazine": { + "name": "magazine", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "weight": { + "name": "weight", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "imagename": { + "name": "imagename", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "chamber": { + "name": "chamber", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "drilledandtapped": { + "name": "drilledandtapped", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rateoftwist": { + "name": "rateoftwist", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "itemtype": { + "name": "itemtype", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "additionalfeature1": { + "name": "additionalfeature1", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "additionalfeature2": { + "name": "additionalfeature2", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "additionalfeature3": { + "name": "additionalfeature3", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "shippingweight": { + "name": "shippingweight", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "boundbookmanufacturer": { + "name": "boundbookmanufacturer", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "boundbookmodel": { + "name": "boundbookmodel", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "boundbooktype": { + "name": "boundbooktype", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "nfathreadpattern": { + "name": "nfathreadpattern", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "nfaattachmentmethod": { + "name": "nfaattachmentmethod", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "nfabaffletype": { + "name": "nfabaffletype", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "silencercanbedisassembled": { + "name": "silencercanbedisassembled", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "silencerconstructionmaterial": { + "name": "silencerconstructionmaterial", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "nfadbreduction": { + "name": "nfadbreduction", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "silenceroutsidediameter": { + "name": "silenceroutsidediameter", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "nfaform3Caliber": { + "name": "nfaform3Caliber", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "opticmagnification": { + "name": "opticmagnification", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "maintubesize": { + "name": "maintubesize", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "adjustableobjective": { + "name": "adjustableobjective", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "objectivesize": { + "name": "objectivesize", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "opticadjustments": { + "name": "opticadjustments", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "illuminatedreticle": { + "name": "illuminatedreticle", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reticle": { + "name": "reticle", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "exclusive": { + "name": "exclusive", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "quantity": { + "name": "quantity", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false, + "default": "NULL" + }, + "allocated": { + "name": "allocated", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "onsale": { + "name": "onsale", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "price": { + "name": "price", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "currentprice": { + "name": "currentprice", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "retailmap": { + "name": "retailmap", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "fflrequired": { + "name": "fflrequired", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sotrequired": { + "name": "sotrequired", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "exclusivetype": { + "name": "exclusivetype", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scopecoverincluded": { + "name": "scopecoverincluded", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "special": { + "name": "special", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sightstype": { + "name": "sightstype", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "case": { + "name": "case", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "choke": { + "name": "choke", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dbreduction": { + "name": "dbreduction", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "family": { + "name": "family", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "finishtype": { + "name": "finishtype", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "frame": { + "name": "frame", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "griptype": { + "name": "griptype", + "type": "varchar(30)", + "primaryKey": false, + "notNull": false + }, + "handgunslidematerial": { + "name": "handgunslidematerial", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "countryoforigin": { + "name": "countryoforigin", + "type": "varchar(4)", + "primaryKey": false, + "notNull": false + }, + "itemlength": { + "name": "itemlength", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "itemwidth": { + "name": "itemwidth", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "itemheight": { + "name": "itemheight", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "packagelength": { + "name": "packagelength", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "packagewidth": { + "name": "packagewidth", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "packageheight": { + "name": "packageheight", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "itemgroup": { + "name": "itemgroup", + "type": "varchar(40)", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.builds_components": { + "name": "builds_components", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "build_components_id_seq", + "increment": "1", + "minValue": "1", + "maxValue": "2147483647", + "startWith": "1", + "cache": "1", + "cycle": false, + "schema": "public" + } + }, + "build_id": { + "name": "build_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "product_id": { + "name": "product_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": false, + "default": "gen_random_uuid()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "builds_components_uuid_unique": { + "columns": [ + "uuid" + ], + "nullsNotDistinct": false, + "name": "builds_components_uuid_unique" + } + }, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.bal_resellers": { + "name": "bal_resellers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "resellers_id_seq", + "increment": "1", + "minValue": "1", + "maxValue": "2147483647", + "startWith": "1", + "cache": "1", + "cycle": false, + "schema": "public" + } + }, + "name": { + "name": "name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "website_url": { + "name": "website_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "contact_email": { + "name": "contact_email", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "uuid": { + "name": "uuid", + "type": "uuid", + "primaryKey": false, + "notNull": false, + "default": "gen_random_uuid()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "bal_resellers_uuid_unique": { + "columns": [ + "uuid" + ], + "nullsNotDistinct": false, + "name": "bal_resellers_uuid_unique" + } + }, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.verificationToken": { + "name": "verificationToken", + "schema": "", + "columns": { + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "verificationToken_identifier_token_pk": { + "name": "verificationToken_identifier_token_pk", + "columns": [ + "identifier", + "token" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.authenticator": { + "name": "authenticator", + "schema": "", + "columns": { + "credentialID": { + "name": "credentialID", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "providerAccountId": { + "name": "providerAccountId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "credentialPublicKey": { + "name": "credentialPublicKey", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "counter": { + "name": "counter", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "credentialDeviceType": { + "name": "credentialDeviceType", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "credentialBackedUp": { + "name": "credentialBackedUp", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "transports": { + "name": "transports", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "authenticator_userId_user_id_fk": { + "name": "authenticator_userId_user_id_fk", + "tableFrom": "authenticator", + "tableTo": "user", + "schemaTo": "public", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "authenticator_userId_credentialID_pk": { + "name": "authenticator_userId_credentialID_pk", + "columns": [ + "credentialID", + "userId" + ] + } + }, + "uniqueConstraints": { + "authenticator_credentialID_unique": { + "columns": [ + "credentialID" + ], + "nullsNotDistinct": false, + "name": "authenticator_credentialID_unique" + } + }, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.account": { + "name": "account", + "schema": "", + "columns": { + "userId": { + "name": "userId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "providerAccountId": { + "name": "providerAccountId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "token_type": { + "name": "token_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "session_state": { + "name": "session_state", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "account_provider_providerAccountId_pk": { + "name": "account_provider_providerAccountId_pk", + "columns": [ + "provider", + "providerAccountId" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "tables": { + "lipseycatalog": { + "columns": { + "quantity": { + "isDefaultAnExpression": true + } + } + } + } + } +} \ No newline at end of file diff --git a/src/drizzle/schema/meta/_journal.json b/src/drizzle/schema/meta/_journal.json new file mode 100644 index 0000000..15c8e32 --- /dev/null +++ b/src/drizzle/schema/meta/_journal.json @@ -0,0 +1,13 @@ +{ + "version": "7", + "dialect": "postgresql", + "entries": [ + { + "idx": 0, + "version": "7", + "when": 1734388473133, + "tag": "0000_stiff_odin", + "breakpoints": true + } + ] +} \ No newline at end of file diff --git a/src/drizzle/schema/relations.ts b/src/drizzle/schema/relations.ts new file mode 100644 index 0000000..678475a --- /dev/null +++ b/src/drizzle/schema/relations.ts @@ -0,0 +1,13 @@ +import { relations } from "drizzle-orm/relations"; +import { user, authenticator } from "./schema"; + +export const authenticatorRelations = relations(authenticator, ({one}) => ({ + user: one(user, { + fields: [authenticator.userId], + references: [user.id] + }), +})); + +export const userRelations = relations(user, ({many}) => ({ + authenticators: many(authenticator), +})); \ No newline at end of file diff --git a/src/drizzle/schema/schema.ts b/src/drizzle/schema/schema.ts new file mode 100644 index 0000000..8d5e1a8 --- /dev/null +++ b/src/drizzle/schema/schema.ts @@ -0,0 +1,386 @@ +import { pgTable, integer, varchar, text, numeric, timestamp, unique, check, bigserial, date, boolean, uuid, bigint, real, doublePrecision, primaryKey, foreignKey } from "drizzle-orm/pg-core" +import { sql } from "drizzle-orm" + + + +export const products = pgTable("products", { + id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "products_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), + name: varchar({ length: 255 }).notNull(), + description: text().notNull(), + price: numeric().notNull(), + resellerId: integer("reseller_id").notNull(), + categoryId: integer("category_id").notNull(), + stockQty: integer("stock_qty").default(0), + updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(), + createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(), + deletedAt: timestamp("deleted_at", { mode: 'string' }), +}); + +export const users = pgTable("users", { + id: bigserial({ mode: "bigint" }).primaryKey().notNull(), + username: varchar({ length: 50 }).notNull(), + email: varchar({ length: 255 }).notNull(), + passwordHash: varchar("password_hash", { length: 255 }).notNull(), + firstName: varchar("first_name", { length: 50 }), + lastName: varchar("last_name", { length: 50 }), + profilePicture: varchar("profile_picture", { length: 255 }), + dateOfBirth: date("date_of_birth"), + phoneNumber: varchar("phone_number", { length: 20 }), + createdAt: timestamp("created_at", { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`), + updatedAt: timestamp("updated_at", { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`), + isAdmin: boolean("is_admin").default(false), + lastLogin: timestamp("last_login", { mode: 'string' }), + emailVerified: boolean("email_verified").default(false), + buildPrivacySetting: text("build_privacy_setting").default('public'), + uuid: uuid().defaultRandom(), +}, (table) => { + return { + usersUsernameKey: unique("users_username_key").on(table.username), + usersEmailKey: unique("users_email_key").on(table.email), + usersBuildPrivacySettingCheck: check("users_build_privacy_setting_check", sql`build_privacy_setting = ANY (ARRAY['private'::text, 'public'::text])`), + } +}); + +export const categories = pgTable("categories", { + id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "categories_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), + name: varchar({ length: 100 }).notNull(), + parentCategoryId: integer("parent_category_id"), + updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(), + createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(), + deletedAt: timestamp("deleted_at", { mode: 'string' }), + uuid: uuid().defaultRandom(), +}); + +export const productFeeds = pgTable("product_feeds", { + id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "productfeeds_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), + resellerId: integer("reseller_id").notNull(), + feedUrl: varchar("feed_url", { length: 255 }).notNull(), + lastUpdate: timestamp("last_update", { mode: 'string' }), + updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(), + createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(), + deletedAt: timestamp("deleted_at", { mode: 'string' }), + uuid: uuid().defaultRandom(), +}, (table) => { + return { + productFeedsUuidUnique: unique("product_feeds_uuid_unique").on(table.uuid), + } +}); + +export const user = pgTable("user", { + id: text().primaryKey().notNull(), + name: text(), + email: text(), + emailVerified: timestamp({ mode: 'string' }), + image: text(), +}, (table) => { + return { + userEmailUnique: unique("user_email_unique").on(table.email), + } +}); + +export const userActivityLog = pgTable("user_activity_log", { + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + id: bigint({ mode: "number" }).primaryKey().generatedAlwaysAsIdentity({ name: "user_activity_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + userId: bigint("user_id", { mode: "number" }).notNull(), + activity: text().notNull(), + timestamp: timestamp({ mode: 'string' }).default(sql`CURRENT_TIMESTAMP`), +}); + +export const brands = pgTable("brands", { + id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "brands_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), + name: varchar({ length: 100 }).notNull(), + updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(), + createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(), + deletedAt: timestamp("deleted_at", { mode: 'string' }), + uuid: uuid().defaultRandom(), +}, (table) => { + return { + brandsUuidUnique: unique("brands_uuid_unique").on(table.uuid), + } +}); + +export const manufacturer = pgTable("manufacturer", { + id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "manufacturer_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), + name: varchar({ length: 100 }).notNull(), + updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(), + createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(), + deletedAt: timestamp("deleted_at", { mode: 'string' }), + uuid: uuid().defaultRandom(), +}, (table) => { + return { + manufacturerUuidUnique: unique("manufacturer_uuid_unique").on(table.uuid), + } +}); + +export const session = pgTable("session", { + sessionToken: text().primaryKey().notNull(), + userId: text().notNull(), + expires: timestamp({ mode: 'string' }).notNull(), +}); + +export const states = pgTable("states", { + id: integer().primaryKey().generatedByDefaultAsIdentity({ name: "states_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), + state: varchar({ length: 50 }), + abbreviation: varchar({ length: 50 }), +}); + +export const componentType = pgTable("component_type", { + id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "component_type_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), + name: varchar({ length: 100 }).notNull(), + updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(), + createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(), + deletedAt: timestamp("deleted_at", { mode: 'string' }), + uuid: uuid().defaultRandom(), +}, (table) => { + return { + componentTypeUuidUnique: unique("component_type_uuid_unique").on(table.uuid), + } +}); + +export const aeroPrecision = pgTable("aero_precision", { + sku: text().primaryKey().notNull(), + manufacturerId: text("manufacturer_id"), + brandName: text("brand_name"), + productName: text("product_name"), + longDescription: text("long_description"), + shortDescription: text("short_description"), + department: text(), + category: text(), + subcategory: text(), + thumbUrl: text("thumb_url"), + imageUrl: text("image_url"), + buyLink: text("buy_link"), + keywords: text(), + reviews: text(), + retailPrice: numeric("retail_price"), + salePrice: numeric("sale_price"), + brandPageLink: text("brand_page_link"), + brandLogoImage: text("brand_logo_image"), + productPageViewTracking: text("product_page_view_tracking"), + variantsXml: text("variants_xml"), + mediumImageUrl: text("medium_image_url"), + productContentWidget: text("product_content_widget"), + googleCategorization: text("google_categorization"), + itemBasedCommission: text("item_based_commission"), + uuid: uuid().defaultRandom(), +}); + +export const compartment = pgTable("compartment", { + id: uuid().defaultRandom().primaryKey().notNull(), + name: varchar({ length: 100 }).notNull(), + description: varchar({ length: 300 }), + updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(), + createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(), + deletedAt: timestamp("deleted_at", { mode: 'string' }), +}); + +export const builds = pgTable("builds", { + id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "build_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), + accountId: integer("account_id").notNull(), + name: varchar({ length: 255 }).notNull(), + description: text(), + updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(), + createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(), + deletedAt: timestamp("deleted_at", { mode: 'string' }), + uuid: uuid().defaultRandom(), +}, (table) => { + return { + buildsUuidUnique: unique("builds_uuid_unique").on(table.uuid), + } +}); + +export const psa = pgTable("psa", { + sku: varchar("SKU", { length: 50 }), + manufacturerId: varchar("MANUFACTURER_ID", { length: 50 }), + brandName: varchar("BRAND_NAME", { length: 50 }), + productName: varchar("PRODUCT_NAME", { length: 255 }), + longDescription: text("LONG_DESCRIPTION"), + shortDescription: varchar("SHORT_DESCRIPTION", { length: 50 }), + department: varchar("DEPARTMENT", { length: 50 }), + category: varchar("CATEGORY", { length: 50 }), + subcategory: varchar("SUBCATEGORY", { length: 50 }), + thumbUrl: varchar("THUMB_URL", { length: 50 }), + imageUrl: varchar("IMAGE_URL", { length: 50 }), + buyLink: varchar("BUY_LINK", { length: 128 }), + keywords: varchar("KEYWORDS", { length: 50 }), + reviews: varchar("REVIEWS", { length: 50 }), + retailPrice: real("RETAIL_PRICE"), + salePrice: real("SALE_PRICE"), + brandPageLink: varchar("BRAND_PAGE_LINK", { length: 50 }), + brandLogoImage: varchar("BRAND_LOGO_IMAGE", { length: 50 }), + productPageViewTracking: varchar("PRODUCT_PAGE_VIEW_TRACKING", { length: 256 }), + parentGroupId: varchar("PARENT_GROUP_ID", { length: 50 }), + fineline: varchar("FINELINE", { length: 50 }), + superfineline: varchar("SUPERFINELINE", { length: 200 }), + modelnumber: varchar("MODELNUMBER", { length: 50 }), + caliber: varchar("CALIBER", { length: 200 }), + upc: varchar("UPC", { length: 100 }), + mediumImageUrl: varchar("MEDIUM_IMAGE_URL", { length: 50 }), + productContentWidget: varchar("PRODUCT_CONTENT_WIDGET", { length: 256 }), + googleCategorization: varchar("GOOGLE_CATEGORIZATION", { length: 50 }), + itemBasedCommission: varchar("ITEM_BASED_COMMISSION", { length: 50 }), + uuid: uuid().defaultRandom(), +}); + +export const lipseycatalog = pgTable("lipseycatalog", { + id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "lipseycatalog_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), + itemno: varchar({ length: 20 }).notNull(), + description1: text(), + description2: text(), + upc: varchar({ length: 20 }), + manufacturermodelno: varchar({ length: 30 }), + msrp: doublePrecision(), + model: text(), + calibergauge: text(), + manufacturer: text(), + type: text(), + action: text(), + barrellength: text(), + capacity: text(), + finish: text(), + overalllength: text(), + receiver: text(), + safety: text(), + sights: text(), + stockframegrips: text(), + magazine: text(), + weight: text(), + imagename: text(), + chamber: text(), + drilledandtapped: text(), + rateoftwist: text(), + itemtype: text(), + additionalfeature1: text(), + additionalfeature2: text(), + additionalfeature3: text(), + shippingweight: text(), + boundbookmanufacturer: text(), + boundbookmodel: text(), + boundbooktype: text(), + nfathreadpattern: text(), + nfaattachmentmethod: text(), + nfabaffletype: text(), + silencercanbedisassembled: text(), + silencerconstructionmaterial: text(), + nfadbreduction: text(), + silenceroutsidediameter: text(), + nfaform3Caliber: text(), + opticmagnification: text(), + maintubesize: text(), + adjustableobjective: text(), + objectivesize: text(), + opticadjustments: text(), + illuminatedreticle: text(), + reticle: text(), + exclusive: text(), + quantity: varchar({ length: 10 }).default(sql`NULL`), + allocated: text(), + onsale: text(), + price: doublePrecision(), + currentprice: doublePrecision(), + retailmap: doublePrecision(), + fflrequired: text(), + sotrequired: text(), + exclusivetype: text(), + scopecoverincluded: text(), + special: text(), + sightstype: text(), + case: text(), + choke: text(), + dbreduction: text(), + family: text(), + finishtype: text(), + frame: text(), + griptype: varchar({ length: 30 }), + handgunslidematerial: text(), + countryoforigin: varchar({ length: 4 }), + itemlength: text(), + itemwidth: text(), + itemheight: text(), + packagelength: doublePrecision(), + packagewidth: doublePrecision(), + packageheight: doublePrecision(), + itemgroup: varchar({ length: 40 }), + updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(), + createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(), + deletedAt: timestamp("deleted_at", { mode: 'string' }), +}); + +export const buildsComponents = pgTable("builds_components", { + id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "build_components_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), + buildId: integer("build_id").notNull(), + productId: integer("product_id").notNull(), + updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(), + createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(), + deletedAt: timestamp("deleted_at", { mode: 'string' }), + uuid: uuid().defaultRandom(), +}, (table) => { + return { + buildsComponentsUuidUnique: unique("builds_components_uuid_unique").on(table.uuid), + } +}); + +export const balResellers = pgTable("bal_resellers", { + id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "resellers_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }), + name: varchar({ length: 100 }).notNull(), + websiteUrl: varchar("website_url", { length: 255 }), + contactEmail: varchar("contact_email", { length: 100 }), + updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(), + createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(), + deletedAt: timestamp("deleted_at", { mode: 'string' }), + uuid: uuid().defaultRandom(), +}, (table) => { + return { + balResellersUuidUnique: unique("bal_resellers_uuid_unique").on(table.uuid), + } +}); + +export const verificationToken = pgTable("verificationToken", { + identifier: text().notNull(), + token: text().notNull(), + expires: timestamp({ mode: 'string' }).notNull(), +}, (table) => { + return { + verificationTokenIdentifierTokenPk: primaryKey({ columns: [table.identifier, table.token], name: "verificationToken_identifier_token_pk"}), + } +}); + +export const authenticator = pgTable("authenticator", { + credentialId: text().notNull(), + userId: text().notNull(), + providerAccountId: text().notNull(), + credentialPublicKey: text().notNull(), + counter: integer().notNull(), + credentialDeviceType: text().notNull(), + credentialBackedUp: boolean().notNull(), + transports: text(), +}, (table) => { + return { + authenticatorUserIdUserIdFk: foreignKey({ + columns: [table.userId], + foreignColumns: [user.id], + name: "authenticator_userId_user_id_fk" + }).onDelete("cascade"), + authenticatorUserIdCredentialIdPk: primaryKey({ columns: [table.credentialId, table.userId], name: "authenticator_userId_credentialID_pk"}), + authenticatorCredentialIdUnique: unique("authenticator_credentialID_unique").on(table.credentialId), + } +}); + +export const account = pgTable("account", { + userId: text().notNull(), + type: text().notNull(), + provider: text().notNull(), + providerAccountId: text().notNull(), + refreshToken: text("refresh_token"), + accessToken: text("access_token"), + expiresAt: integer("expires_at"), + tokenType: text("token_type"), + scope: text(), + idToken: text("id_token"), + sessionState: text("session_state"), +}, (table) => { + return { + accountProviderProviderAccountIdPk: primaryKey({ columns: [table.provider, table.providerAccountId], name: "account_provider_providerAccountId_pk"}), + } +}); diff --git a/tsconfig.json b/tsconfig.json index dc2f3e9..0b7ce07 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,7 +27,7 @@ "@queries/*": [ "./src/db/queries/*"], "@schemas/*": [ - "./src/db/schema/*"], + "./src/drizzle/schema/*"], "@db/*": [ "./src/db/*"], "@types/*": [