mirror of
https://gitea.gofwd.group/sean/gunbuilder-next-tailwind.git
synced 2025-12-06 02:56:45 -05:00
shit show but data works
This commit is contained in:
1
.frontmatter/database/taxonomyDb.json
Normal file
1
.frontmatter/database/taxonomyDb.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@@ -3,8 +3,13 @@ import type { Config } from "drizzle-kit";
|
|||||||
export default {
|
export default {
|
||||||
schema: "./src/db/schema.ts",
|
schema: "./src/db/schema.ts",
|
||||||
out: "./drizzle/migrations",
|
out: "./drizzle/migrations",
|
||||||
driver: "pg",
|
dialect: "postgresql",
|
||||||
dbCredentials: {
|
dbCredentials: {
|
||||||
connectionString: process.env.DATABASE_URL!,
|
host: process.env.DB_HOST!,
|
||||||
|
port: Number(process.env.DB_PORT!),
|
||||||
|
user: process.env.DB_USER!,
|
||||||
|
password: process.env.DB_PASSWORD!,
|
||||||
|
database: process.env.DB_NAME!,
|
||||||
|
ssl: false,
|
||||||
},
|
},
|
||||||
} satisfies Config;
|
} satisfies Config;
|
||||||
77
drizzle/migrations/0000_luxuriant_albert_cleary.sql
Normal file
77
drizzle/migrations/0000_luxuriant_albert_cleary.sql
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
-- 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 "product_category_mappings" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"feed_name" varchar(255),
|
||||||
|
"feed_category_value" varchar(255),
|
||||||
|
"canonical_category_id" integer,
|
||||||
|
"confidence_score" double precision,
|
||||||
|
"last_reviewed_by" varchar(255),
|
||||||
|
"last_reviewed_at" timestamp
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE "categories" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"name" varchar(255) NOT NULL,
|
||||||
|
"parent_id" integer,
|
||||||
|
"slug" varchar(255) NOT NULL,
|
||||||
|
CONSTRAINT "categories_slug_key" UNIQUE("slug")
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE "products" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"name" varchar(255) NOT NULL,
|
||||||
|
"brand" varchar(255),
|
||||||
|
"description" text,
|
||||||
|
"upc" varchar(32),
|
||||||
|
"mpn" varchar(64),
|
||||||
|
"canonical_category_id" integer,
|
||||||
|
"created_at" timestamp DEFAULT now(),
|
||||||
|
"updated_at" timestamp DEFAULT now()
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE "offers" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"product_id" integer,
|
||||||
|
"feed_name" varchar(255) NOT NULL,
|
||||||
|
"feed_sku" varchar(255),
|
||||||
|
"price" numeric(10, 2),
|
||||||
|
"url" text,
|
||||||
|
"in_stock" boolean,
|
||||||
|
"vendor" varchar(255),
|
||||||
|
"last_seen_at" timestamp DEFAULT now(),
|
||||||
|
"raw_data" jsonb,
|
||||||
|
CONSTRAINT "offers_product_id_feed_name_feed_sku_key" UNIQUE("product_id","feed_name","feed_sku"),
|
||||||
|
CONSTRAINT "offers_feed_unique" UNIQUE("feed_name","feed_sku")
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE "offer_price_history" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"offer_id" integer,
|
||||||
|
"price" numeric(10, 2) NOT NULL,
|
||||||
|
"seen_at" timestamp DEFAULT now()
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE "feeds" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"name" varchar(255) NOT NULL,
|
||||||
|
"url" text,
|
||||||
|
"last_imported_at" timestamp,
|
||||||
|
CONSTRAINT "feeds_name_key" UNIQUE("name")
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE "product_attributes" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"product_id" integer,
|
||||||
|
"name" varchar(255) NOT NULL,
|
||||||
|
"value" varchar(255) NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "product_category_mappings" ADD CONSTRAINT "product_category_mappings_canonical_category_id_fkey" FOREIGN KEY ("canonical_category_id") REFERENCES "public"."categories"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "categories" ADD CONSTRAINT "categories_parent_id_fkey" FOREIGN KEY ("parent_id") REFERENCES "public"."categories"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "products" ADD CONSTRAINT "products_canonical_category_id_fkey" FOREIGN KEY ("canonical_category_id") REFERENCES "public"."categories"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "offers" ADD CONSTRAINT "offers_product_id_fkey" FOREIGN KEY ("product_id") REFERENCES "public"."products"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "offer_price_history" ADD CONSTRAINT "offer_price_history_offer_id_fkey" FOREIGN KEY ("offer_id") REFERENCES "public"."offers"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "product_attributes" ADD CONSTRAINT "product_attributes_product_id_fkey" FOREIGN KEY ("product_id") REFERENCES "public"."products"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
*/
|
||||||
7
drizzle/migrations/0001_superb_umar.sql
Normal file
7
drizzle/migrations/0001_superb_umar.sql
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
DROP TABLE "product_category_mappings" CASCADE;--> statement-breakpoint
|
||||||
|
DROP TABLE "categories" CASCADE;--> statement-breakpoint
|
||||||
|
DROP TABLE "products" CASCADE;--> statement-breakpoint
|
||||||
|
DROP TABLE "offers" CASCADE;--> statement-breakpoint
|
||||||
|
DROP TABLE "offer_price_history" CASCADE;--> statement-breakpoint
|
||||||
|
DROP TABLE "feeds" CASCADE;--> statement-breakpoint
|
||||||
|
DROP TABLE "product_attributes" CASCADE;
|
||||||
493
drizzle/migrations/meta/0000_snapshot.json
Normal file
493
drizzle/migrations/meta/0000_snapshot.json
Normal file
@@ -0,0 +1,493 @@
|
|||||||
|
{
|
||||||
|
"id": "00000000-0000-0000-0000-000000000000",
|
||||||
|
"prevId": "",
|
||||||
|
"version": "7",
|
||||||
|
"dialect": "postgresql",
|
||||||
|
"tables": {
|
||||||
|
"public.product_category_mappings": {
|
||||||
|
"name": "product_category_mappings",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "serial",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"feed_name": {
|
||||||
|
"name": "feed_name",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"feed_category_value": {
|
||||||
|
"name": "feed_category_value",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"canonical_category_id": {
|
||||||
|
"name": "canonical_category_id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"confidence_score": {
|
||||||
|
"name": "confidence_score",
|
||||||
|
"type": "double precision",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"last_reviewed_by": {
|
||||||
|
"name": "last_reviewed_by",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"last_reviewed_at": {
|
||||||
|
"name": "last_reviewed_at",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"product_category_mappings_canonical_category_id_fkey": {
|
||||||
|
"name": "product_category_mappings_canonical_category_id_fkey",
|
||||||
|
"tableFrom": "product_category_mappings",
|
||||||
|
"tableTo": "categories",
|
||||||
|
"schemaTo": "public",
|
||||||
|
"columnsFrom": [
|
||||||
|
"canonical_category_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.categories": {
|
||||||
|
"name": "categories",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "serial",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"parent_id": {
|
||||||
|
"name": "parent_id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"slug": {
|
||||||
|
"name": "slug",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"categories_parent_id_fkey": {
|
||||||
|
"name": "categories_parent_id_fkey",
|
||||||
|
"tableFrom": "categories",
|
||||||
|
"tableTo": "categories",
|
||||||
|
"schemaTo": "public",
|
||||||
|
"columnsFrom": [
|
||||||
|
"parent_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"categories_slug_key": {
|
||||||
|
"columns": [
|
||||||
|
"slug"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"name": "categories_slug_key"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.products": {
|
||||||
|
"name": "products",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "serial",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"brand": {
|
||||||
|
"name": "brand",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"upc": {
|
||||||
|
"name": "upc",
|
||||||
|
"type": "varchar(32)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"mpn": {
|
||||||
|
"name": "mpn",
|
||||||
|
"type": "varchar(64)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"canonical_category_id": {
|
||||||
|
"name": "canonical_category_id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"name": "created_at",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"name": "updated_at",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"products_canonical_category_id_fkey": {
|
||||||
|
"name": "products_canonical_category_id_fkey",
|
||||||
|
"tableFrom": "products",
|
||||||
|
"tableTo": "categories",
|
||||||
|
"schemaTo": "public",
|
||||||
|
"columnsFrom": [
|
||||||
|
"canonical_category_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.offers": {
|
||||||
|
"name": "offers",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "serial",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"product_id": {
|
||||||
|
"name": "product_id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"feed_name": {
|
||||||
|
"name": "feed_name",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"feed_sku": {
|
||||||
|
"name": "feed_sku",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"price": {
|
||||||
|
"name": "price",
|
||||||
|
"type": "numeric(10, 2)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"name": "url",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"in_stock": {
|
||||||
|
"name": "in_stock",
|
||||||
|
"type": "boolean",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"vendor": {
|
||||||
|
"name": "vendor",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"last_seen_at": {
|
||||||
|
"name": "last_seen_at",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"raw_data": {
|
||||||
|
"name": "raw_data",
|
||||||
|
"type": "jsonb",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"offers_product_id_fkey": {
|
||||||
|
"name": "offers_product_id_fkey",
|
||||||
|
"tableFrom": "offers",
|
||||||
|
"tableTo": "products",
|
||||||
|
"schemaTo": "public",
|
||||||
|
"columnsFrom": [
|
||||||
|
"product_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"offers_product_id_feed_name_feed_sku_key": {
|
||||||
|
"columns": [
|
||||||
|
"product_id",
|
||||||
|
"feed_name",
|
||||||
|
"feed_sku"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"name": "offers_product_id_feed_name_feed_sku_key"
|
||||||
|
},
|
||||||
|
"offers_feed_unique": {
|
||||||
|
"columns": [
|
||||||
|
"feed_name",
|
||||||
|
"feed_sku"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"name": "offers_feed_unique"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.offer_price_history": {
|
||||||
|
"name": "offer_price_history",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "serial",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"offer_id": {
|
||||||
|
"name": "offer_id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"price": {
|
||||||
|
"name": "price",
|
||||||
|
"type": "numeric(10, 2)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"seen_at": {
|
||||||
|
"name": "seen_at",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"offer_price_history_offer_id_fkey": {
|
||||||
|
"name": "offer_price_history_offer_id_fkey",
|
||||||
|
"tableFrom": "offer_price_history",
|
||||||
|
"tableTo": "offers",
|
||||||
|
"schemaTo": "public",
|
||||||
|
"columnsFrom": [
|
||||||
|
"offer_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.feeds": {
|
||||||
|
"name": "feeds",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "serial",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"name": "url",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"last_imported_at": {
|
||||||
|
"name": "last_imported_at",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"feeds_name_key": {
|
||||||
|
"columns": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"name": "feeds_name_key"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
},
|
||||||
|
"public.product_attributes": {
|
||||||
|
"name": "product_attributes",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "serial",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"product_id": {
|
||||||
|
"name": "product_id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "value",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"product_attributes_product_id_fkey": {
|
||||||
|
"name": "product_attributes_product_id_fkey",
|
||||||
|
"tableFrom": "product_attributes",
|
||||||
|
"tableTo": "products",
|
||||||
|
"schemaTo": "public",
|
||||||
|
"columnsFrom": [
|
||||||
|
"product_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {},
|
||||||
|
"policies": {},
|
||||||
|
"isRLSEnabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enums": {},
|
||||||
|
"schemas": {},
|
||||||
|
"sequences": {},
|
||||||
|
"roles": {},
|
||||||
|
"policies": {},
|
||||||
|
"views": {},
|
||||||
|
"_meta": {
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {},
|
||||||
|
"columns": {}
|
||||||
|
},
|
||||||
|
"internal": {
|
||||||
|
"tables": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
drizzle/migrations/meta/0001_snapshot.json
Normal file
18
drizzle/migrations/meta/0001_snapshot.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"id": "919e511e-3cff-4bd0-b4ec-20865db2d1d3",
|
||||||
|
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||||
|
"version": "7",
|
||||||
|
"dialect": "postgresql",
|
||||||
|
"tables": {},
|
||||||
|
"enums": {},
|
||||||
|
"schemas": {},
|
||||||
|
"sequences": {},
|
||||||
|
"roles": {},
|
||||||
|
"policies": {},
|
||||||
|
"views": {},
|
||||||
|
"_meta": {
|
||||||
|
"columns": {},
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
drizzle/migrations/meta/_journal.json
Normal file
20
drizzle/migrations/meta/_journal.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"version": "7",
|
||||||
|
"dialect": "postgresql",
|
||||||
|
"entries": [
|
||||||
|
{
|
||||||
|
"idx": 0,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1751488452074,
|
||||||
|
"tag": "0000_luxuriant_albert_cleary",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 1,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1751488491929,
|
||||||
|
"tag": "0001_superb_umar",
|
||||||
|
"breakpoints": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
53
drizzle/migrations/relations.ts
Normal file
53
drizzle/migrations/relations.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import { relations } from "drizzle-orm/relations";
|
||||||
|
import { categories, productCategoryMappings, products, offers, offerPriceHistory, productAttributes } from "./schema";
|
||||||
|
|
||||||
|
export const productCategoryMappingsRelations = relations(productCategoryMappings, ({one}) => ({
|
||||||
|
category: one(categories, {
|
||||||
|
fields: [productCategoryMappings.canonicalCategoryId],
|
||||||
|
references: [categories.id]
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const categoriesRelations = relations(categories, ({one, many}) => ({
|
||||||
|
productCategoryMappings: many(productCategoryMappings),
|
||||||
|
category: one(categories, {
|
||||||
|
fields: [categories.parentId],
|
||||||
|
references: [categories.id],
|
||||||
|
relationName: "categories_parentId_categories_id"
|
||||||
|
}),
|
||||||
|
categories: many(categories, {
|
||||||
|
relationName: "categories_parentId_categories_id"
|
||||||
|
}),
|
||||||
|
products: many(products),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const productsRelations = relations(products, ({one, many}) => ({
|
||||||
|
category: one(categories, {
|
||||||
|
fields: [products.canonicalCategoryId],
|
||||||
|
references: [categories.id]
|
||||||
|
}),
|
||||||
|
offers: many(offers),
|
||||||
|
productAttributes: many(productAttributes),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const offersRelations = relations(offers, ({one, many}) => ({
|
||||||
|
product: one(products, {
|
||||||
|
fields: [offers.productId],
|
||||||
|
references: [products.id]
|
||||||
|
}),
|
||||||
|
offerPriceHistories: many(offerPriceHistory),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const offerPriceHistoryRelations = relations(offerPriceHistory, ({one}) => ({
|
||||||
|
offer: one(offers, {
|
||||||
|
fields: [offerPriceHistory.offerId],
|
||||||
|
references: [offers.id]
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const productAttributesRelations = relations(productAttributes, ({one}) => ({
|
||||||
|
product: one(products, {
|
||||||
|
fields: [productAttributes.productId],
|
||||||
|
references: [products.id]
|
||||||
|
}),
|
||||||
|
}));
|
||||||
108
drizzle/migrations/schema.ts
Normal file
108
drizzle/migrations/schema.ts
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
import { pgTable, foreignKey, serial, varchar, integer, doublePrecision, timestamp, unique, text, numeric, boolean, jsonb } from "drizzle-orm/pg-core"
|
||||||
|
import { sql } from "drizzle-orm"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const productCategoryMappings = pgTable("product_category_mappings", {
|
||||||
|
id: serial().primaryKey().notNull(),
|
||||||
|
feedName: varchar("feed_name", { length: 255 }),
|
||||||
|
feedCategoryValue: varchar("feed_category_value", { length: 255 }),
|
||||||
|
canonicalCategoryId: integer("canonical_category_id"),
|
||||||
|
confidenceScore: doublePrecision("confidence_score"),
|
||||||
|
lastReviewedBy: varchar("last_reviewed_by", { length: 255 }),
|
||||||
|
lastReviewedAt: timestamp("last_reviewed_at", { mode: 'string' }),
|
||||||
|
}, (table) => [
|
||||||
|
foreignKey({
|
||||||
|
columns: [table.canonicalCategoryId],
|
||||||
|
foreignColumns: [categories.id],
|
||||||
|
name: "product_category_mappings_canonical_category_id_fkey"
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const categories = pgTable("categories", {
|
||||||
|
id: serial().primaryKey().notNull(),
|
||||||
|
name: varchar({ length: 255 }).notNull(),
|
||||||
|
parentId: integer("parent_id"),
|
||||||
|
slug: varchar({ length: 255 }).notNull(),
|
||||||
|
}, (table) => [
|
||||||
|
foreignKey({
|
||||||
|
columns: [table.parentId],
|
||||||
|
foreignColumns: [table.id],
|
||||||
|
name: "categories_parent_id_fkey"
|
||||||
|
}),
|
||||||
|
unique("categories_slug_key").on(table.slug),
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const products = pgTable("products", {
|
||||||
|
id: serial().primaryKey().notNull(),
|
||||||
|
name: varchar({ length: 255 }).notNull(),
|
||||||
|
brand: varchar({ length: 255 }),
|
||||||
|
description: text(),
|
||||||
|
upc: varchar({ length: 32 }),
|
||||||
|
mpn: varchar({ length: 64 }),
|
||||||
|
canonicalCategoryId: integer("canonical_category_id"),
|
||||||
|
createdAt: timestamp("created_at", { mode: 'string' }).defaultNow(),
|
||||||
|
updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow(),
|
||||||
|
}, (table) => [
|
||||||
|
foreignKey({
|
||||||
|
columns: [table.canonicalCategoryId],
|
||||||
|
foreignColumns: [categories.id],
|
||||||
|
name: "products_canonical_category_id_fkey"
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const offers = pgTable("offers", {
|
||||||
|
id: serial().primaryKey().notNull(),
|
||||||
|
productId: integer("product_id"),
|
||||||
|
feedName: varchar("feed_name", { length: 255 }).notNull(),
|
||||||
|
feedSku: varchar("feed_sku", { length: 255 }),
|
||||||
|
price: numeric({ precision: 10, scale: 2 }),
|
||||||
|
url: text(),
|
||||||
|
inStock: boolean("in_stock"),
|
||||||
|
vendor: varchar({ length: 255 }),
|
||||||
|
lastSeenAt: timestamp("last_seen_at", { mode: 'string' }).defaultNow(),
|
||||||
|
rawData: jsonb("raw_data"),
|
||||||
|
}, (table) => [
|
||||||
|
foreignKey({
|
||||||
|
columns: [table.productId],
|
||||||
|
foreignColumns: [products.id],
|
||||||
|
name: "offers_product_id_fkey"
|
||||||
|
}).onDelete("cascade"),
|
||||||
|
unique("offers_product_id_feed_name_feed_sku_key").on(table.productId, table.feedName, table.feedSku),
|
||||||
|
unique("offers_feed_unique").on(table.feedName, table.feedSku),
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const offerPriceHistory = pgTable("offer_price_history", {
|
||||||
|
id: serial().primaryKey().notNull(),
|
||||||
|
offerId: integer("offer_id"),
|
||||||
|
price: numeric({ precision: 10, scale: 2 }).notNull(),
|
||||||
|
seenAt: timestamp("seen_at", { mode: 'string' }).defaultNow(),
|
||||||
|
}, (table) => [
|
||||||
|
foreignKey({
|
||||||
|
columns: [table.offerId],
|
||||||
|
foreignColumns: [offers.id],
|
||||||
|
name: "offer_price_history_offer_id_fkey"
|
||||||
|
}).onDelete("cascade"),
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const feeds = pgTable("feeds", {
|
||||||
|
id: serial().primaryKey().notNull(),
|
||||||
|
name: varchar({ length: 255 }).notNull(),
|
||||||
|
url: text(),
|
||||||
|
lastImportedAt: timestamp("last_imported_at", { mode: 'string' }),
|
||||||
|
}, (table) => [
|
||||||
|
unique("feeds_name_key").on(table.name),
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const productAttributes = pgTable("product_attributes", {
|
||||||
|
id: serial().primaryKey().notNull(),
|
||||||
|
productId: integer("product_id"),
|
||||||
|
name: varchar({ length: 255 }).notNull(),
|
||||||
|
value: varchar({ length: 255 }).notNull(),
|
||||||
|
}, (table) => [
|
||||||
|
foreignKey({
|
||||||
|
columns: [table.productId],
|
||||||
|
foreignColumns: [products.id],
|
||||||
|
name: "product_attributes_product_id_fkey"
|
||||||
|
}).onDelete("cascade"),
|
||||||
|
]);
|
||||||
52
frontmatter.json
Normal file
52
frontmatter.json
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://frontmatter.codes/frontmatter.schema.json",
|
||||||
|
"frontMatter.taxonomy.contentTypes": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"pageBundle": false,
|
||||||
|
"previewPath": null,
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"title": "Title",
|
||||||
|
"name": "title",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Description",
|
||||||
|
"name": "description",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Publishing date",
|
||||||
|
"name": "date",
|
||||||
|
"type": "datetime",
|
||||||
|
"default": "{{now}}",
|
||||||
|
"isPublishDate": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Content preview",
|
||||||
|
"name": "preview",
|
||||||
|
"type": "image"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Is in draft",
|
||||||
|
"name": "draft",
|
||||||
|
"type": "draft"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Tags",
|
||||||
|
"name": "tags",
|
||||||
|
"type": "tags"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Categories",
|
||||||
|
"name": "categories",
|
||||||
|
"type": "categories"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"frontMatter.framework.id": "next",
|
||||||
|
"frontMatter.content.publicFolder": "public",
|
||||||
|
"frontMatter.preview.host": "http://localhost:3000"
|
||||||
|
}
|
||||||
70
package-lock.json
generated
70
package-lock.json
generated
@@ -16,7 +16,6 @@
|
|||||||
"bcryptjs": "^3.0.2",
|
"bcryptjs": "^3.0.2",
|
||||||
"daisyui": "^4.7.3",
|
"daisyui": "^4.7.3",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"drizzle-kit": "^0.31.4",
|
|
||||||
"drizzle-orm": "^0.44.2",
|
"drizzle-orm": "^0.44.2",
|
||||||
"lucide-react": "^0.525.0",
|
"lucide-react": "^0.525.0",
|
||||||
"next": "^14.2.30",
|
"next": "^14.2.30",
|
||||||
@@ -33,6 +32,7 @@
|
|||||||
"@types/pg": "^8.15.4",
|
"@types/pg": "^8.15.4",
|
||||||
"@types/react": "^18.2.0",
|
"@types/react": "^18.2.0",
|
||||||
"@types/react-dom": "^18.2.0",
|
"@types/react-dom": "^18.2.0",
|
||||||
|
"drizzle-kit": "^0.31.4",
|
||||||
"eslint": "^9",
|
"eslint": "^9",
|
||||||
"eslint-config-next": "15.3.4",
|
"eslint-config-next": "15.3.4",
|
||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
@@ -159,7 +159,8 @@
|
|||||||
"node_modules/@drizzle-team/brocli": {
|
"node_modules/@drizzle-team/brocli": {
|
||||||
"version": "0.10.2",
|
"version": "0.10.2",
|
||||||
"resolved": "https://registry.npmjs.org/@drizzle-team/brocli/-/brocli-0.10.2.tgz",
|
"resolved": "https://registry.npmjs.org/@drizzle-team/brocli/-/brocli-0.10.2.tgz",
|
||||||
"integrity": "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="
|
"integrity": "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@emnapi/core": {
|
"node_modules/@emnapi/core": {
|
||||||
"version": "1.4.3",
|
"version": "1.4.3",
|
||||||
@@ -197,6 +198,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz",
|
||||||
"integrity": "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==",
|
"integrity": "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==",
|
||||||
"deprecated": "Merged into tsx: https://tsx.is",
|
"deprecated": "Merged into tsx: https://tsx.is",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "~0.18.20",
|
"esbuild": "~0.18.20",
|
||||||
"source-map-support": "^0.5.21"
|
"source-map-support": "^0.5.21"
|
||||||
@@ -209,6 +211,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
@@ -224,6 +227,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
@@ -239,6 +243,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
@@ -254,6 +259,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
@@ -269,6 +275,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
@@ -284,6 +291,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"freebsd"
|
"freebsd"
|
||||||
@@ -299,6 +307,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"freebsd"
|
"freebsd"
|
||||||
@@ -314,6 +323,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -329,6 +339,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -344,6 +355,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -359,6 +371,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"loong64"
|
"loong64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -374,6 +387,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"mips64el"
|
"mips64el"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -389,6 +403,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -404,6 +419,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -419,6 +435,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -434,6 +451,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -449,6 +467,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"netbsd"
|
"netbsd"
|
||||||
@@ -464,6 +483,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"openbsd"
|
"openbsd"
|
||||||
@@ -479,6 +499,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"sunos"
|
"sunos"
|
||||||
@@ -494,6 +515,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
@@ -509,6 +531,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
@@ -524,6 +547,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
@@ -536,6 +560,7 @@
|
|||||||
"version": "0.18.20",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
|
||||||
"integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
|
"integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
|
||||||
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"esbuild": "bin/esbuild"
|
"esbuild": "bin/esbuild"
|
||||||
@@ -573,6 +598,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz",
|
||||||
"integrity": "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==",
|
"integrity": "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==",
|
||||||
"deprecated": "Merged into tsx: https://tsx.is",
|
"deprecated": "Merged into tsx: https://tsx.is",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@esbuild-kit/core-utils": "^3.3.2",
|
"@esbuild-kit/core-utils": "^3.3.2",
|
||||||
"get-tsconfig": "^4.7.0"
|
"get-tsconfig": "^4.7.0"
|
||||||
@@ -585,6 +611,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"aix"
|
"aix"
|
||||||
@@ -600,6 +627,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
@@ -615,6 +643,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
@@ -630,6 +659,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
@@ -645,6 +675,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
@@ -660,6 +691,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
@@ -675,6 +707,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"freebsd"
|
"freebsd"
|
||||||
@@ -690,6 +723,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"freebsd"
|
"freebsd"
|
||||||
@@ -705,6 +739,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -720,6 +755,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -735,6 +771,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -750,6 +787,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"loong64"
|
"loong64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -765,6 +803,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"mips64el"
|
"mips64el"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -780,6 +819,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -795,6 +835,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -810,6 +851,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -825,6 +867,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@@ -840,6 +883,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"netbsd"
|
"netbsd"
|
||||||
@@ -855,6 +899,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"netbsd"
|
"netbsd"
|
||||||
@@ -870,6 +915,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"openbsd"
|
"openbsd"
|
||||||
@@ -885,6 +931,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"openbsd"
|
"openbsd"
|
||||||
@@ -900,6 +947,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"sunos"
|
"sunos"
|
||||||
@@ -915,6 +963,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
@@ -930,6 +979,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
@@ -945,6 +995,7 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
@@ -2652,7 +2703,8 @@
|
|||||||
"node_modules/buffer-from": {
|
"node_modules/buffer-from": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/busboy": {
|
"node_modules/busboy": {
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
@@ -2985,6 +3037,7 @@
|
|||||||
"version": "4.4.1",
|
"version": "4.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
|
||||||
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
|
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "^2.1.3"
|
"ms": "^2.1.3"
|
||||||
},
|
},
|
||||||
@@ -3063,6 +3116,8 @@
|
|||||||
"version": "0.31.4",
|
"version": "0.31.4",
|
||||||
"resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.31.4.tgz",
|
"resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.31.4.tgz",
|
||||||
"integrity": "sha512-tCPWVZWZqWVx2XUsVpJRnH9Mx0ClVOf5YUHerZ5so1OKSlqww4zy1R5ksEdGRcO3tM3zj0PYN6V48TbQCL1RfA==",
|
"integrity": "sha512-tCPWVZWZqWVx2XUsVpJRnH9Mx0ClVOf5YUHerZ5so1OKSlqww4zy1R5ksEdGRcO3tM3zj0PYN6V48TbQCL1RfA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@drizzle-team/brocli": "^0.10.2",
|
"@drizzle-team/brocli": "^0.10.2",
|
||||||
"@esbuild-kit/esm-loader": "^2.5.5",
|
"@esbuild-kit/esm-loader": "^2.5.5",
|
||||||
@@ -3399,6 +3454,7 @@
|
|||||||
"version": "0.25.5",
|
"version": "0.25.5",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz",
|
||||||
"integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==",
|
"integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==",
|
||||||
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"esbuild": "bin/esbuild"
|
"esbuild": "bin/esbuild"
|
||||||
@@ -3438,6 +3494,7 @@
|
|||||||
"version": "3.6.0",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz",
|
||||||
"integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==",
|
"integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.3.4"
|
||||||
},
|
},
|
||||||
@@ -4136,6 +4193,7 @@
|
|||||||
"version": "4.10.1",
|
"version": "4.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz",
|
||||||
"integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==",
|
"integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"resolve-pkg-maps": "^1.0.0"
|
"resolve-pkg-maps": "^1.0.0"
|
||||||
},
|
},
|
||||||
@@ -5059,7 +5117,8 @@
|
|||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/mz": {
|
"node_modules/mz": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
@@ -6038,6 +6097,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
||||||
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
|
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
|
||||||
|
"dev": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
||||||
}
|
}
|
||||||
@@ -6297,6 +6357,7 @@
|
|||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||||
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@@ -6313,6 +6374,7 @@
|
|||||||
"version": "0.5.21",
|
"version": "0.5.21",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
|
||||||
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"buffer-from": "^1.0.0",
|
"buffer-from": "^1.0.0",
|
||||||
"source-map": "^0.6.0"
|
"source-map": "^0.6.0"
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
"bcryptjs": "^3.0.2",
|
"bcryptjs": "^3.0.2",
|
||||||
"daisyui": "^4.7.3",
|
"daisyui": "^4.7.3",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"drizzle-kit": "^0.31.4",
|
|
||||||
"drizzle-orm": "^0.44.2",
|
"drizzle-orm": "^0.44.2",
|
||||||
"lucide-react": "^0.525.0",
|
"lucide-react": "^0.525.0",
|
||||||
"next": "^14.2.30",
|
"next": "^14.2.30",
|
||||||
@@ -34,6 +33,7 @@
|
|||||||
"@types/pg": "^8.15.4",
|
"@types/pg": "^8.15.4",
|
||||||
"@types/react": "^18.2.0",
|
"@types/react": "^18.2.0",
|
||||||
"@types/react-dom": "^18.2.0",
|
"@types/react-dom": "^18.2.0",
|
||||||
|
"drizzle-kit": "^0.31.4",
|
||||||
"eslint": "^9",
|
"eslint": "^9",
|
||||||
"eslint-config-next": "15.3.4",
|
"eslint-config-next": "15.3.4",
|
||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
|
|||||||
@@ -3,14 +3,12 @@ import { useEffect, useState, useMemo } from 'react';
|
|||||||
import { useParams } from 'next/navigation';
|
import { useParams } from 'next/navigation';
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
'brandName',
|
'name',
|
||||||
'productName',
|
'brand',
|
||||||
'department',
|
'description',
|
||||||
'category',
|
'slug',
|
||||||
'subcategory',
|
'createdAt',
|
||||||
'retailPrice',
|
'updatedAt',
|
||||||
'salePrice',
|
|
||||||
'imageUrl',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function PartsCategoryPage() {
|
export default function PartsCategoryPage() {
|
||||||
@@ -61,14 +59,14 @@ export default function PartsCategoryPage() {
|
|||||||
});
|
});
|
||||||
}, [products, categoryParam]);
|
}, [products, categoryParam]);
|
||||||
|
|
||||||
const brandOptions = useMemo(() => Array.from(new Set(filteredByCategory.map(p => p.brandName).filter(Boolean))).sort(), [filteredByCategory]);
|
const brandOptions = useMemo(() => Array.from(new Set(filteredByCategory.map(p => p.brand).filter(Boolean))).sort(), [filteredByCategory]);
|
||||||
const departmentOptions = useMemo(() => Array.from(new Set(filteredByCategory.map(p => p.department).filter(Boolean))).sort(), [filteredByCategory]);
|
const departmentOptions = useMemo(() => Array.from(new Set(filteredByCategory.map(p => p.department).filter(Boolean))).sort(), [filteredByCategory]);
|
||||||
const subcategoryOptions = useMemo(() => Array.from(new Set(filteredByCategory.map(p => p.subcategory).filter(Boolean))).sort(), [filteredByCategory]);
|
const subcategoryOptions = useMemo(() => Array.from(new Set(filteredByCategory.map(p => p.subcategory).filter(Boolean))).sort(), [filteredByCategory]);
|
||||||
|
|
||||||
// Further filter by sidebar filters
|
// Further filter by sidebar filters
|
||||||
const filteredProducts = useMemo(() => {
|
const filteredProducts = useMemo(() => {
|
||||||
return filteredByCategory.filter(p =>
|
return filteredByCategory.filter(p =>
|
||||||
(!brand || p.brandName === brand) &&
|
(!brand || p.brand === brand) &&
|
||||||
(!department || p.department === department) &&
|
(!department || p.department === department) &&
|
||||||
(!subcategory || p.subcategory === subcategory)
|
(!subcategory || p.subcategory === subcategory)
|
||||||
);
|
);
|
||||||
@@ -138,15 +136,15 @@ export default function PartsCategoryPage() {
|
|||||||
) : paginatedProducts.length === 0 ? (
|
) : paginatedProducts.length === 0 ? (
|
||||||
<tr><td colSpan={columns.length} className="text-center py-8">No products found.</td></tr>
|
<tr><td colSpan={columns.length} className="text-center py-8">No products found.</td></tr>
|
||||||
) : (
|
) : (
|
||||||
paginatedProducts.map((product, i) => (
|
paginatedProducts
|
||||||
<tr key={product.uuid || i} className="border-b hover:bg-zinc-50">
|
.filter(product => columns.some(col => product[col] && String(product[col]).trim() !== ''))
|
||||||
|
.map((product, i) => (
|
||||||
|
<tr key={product.id || i} className="border-b hover:bg-zinc-50">
|
||||||
{columns.map(col => (
|
{columns.map(col => (
|
||||||
<td key={col} className="px-2 py-1 max-w-xs truncate">
|
<td key={col} className="px-2 py-1 max-w-xs truncate">
|
||||||
{col === 'imageUrl' && product[col] ? (
|
{typeof product[col] === 'object' && product[col] !== null
|
||||||
<img src={product[col]} alt="thumb" className="h-10 w-10 object-contain border rounded" />
|
? JSON.stringify(product[col])
|
||||||
) : (
|
: product[col] ?? ''}
|
||||||
product[col] ?? ''
|
|
||||||
)}
|
|
||||||
</td>
|
</td>
|
||||||
))}
|
))}
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ const useCanonicalCategories = () => {
|
|||||||
const [categories, setCategories] = useState<any[]>([]);
|
const [categories, setCategories] = useState<any[]>([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch('/api/product-categories')
|
fetch('/api/categories')
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
setCategories(data.data);
|
setCategories(data.data);
|
||||||
@@ -390,14 +390,12 @@ function getDescendantCategoryIds(categories: any[], selectedId: string): string
|
|||||||
}
|
}
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
'brandName',
|
'name',
|
||||||
'productName',
|
'brand',
|
||||||
'department',
|
'description',
|
||||||
'category',
|
'slug',
|
||||||
'subcategory',
|
'createdAt',
|
||||||
'retailPrice',
|
'updatedAt',
|
||||||
'salePrice',
|
|
||||||
'imageUrl',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function PartsPage() {
|
export default function PartsPage() {
|
||||||
@@ -413,6 +411,20 @@ export default function PartsPage() {
|
|||||||
const [category, setCategory] = useState('');
|
const [category, setCategory] = useState('');
|
||||||
const [subcategory, setSubcategory] = useState('');
|
const [subcategory, setSubcategory] = useState('');
|
||||||
|
|
||||||
|
// Category data from canonical API
|
||||||
|
const { categories, loading: categoriesLoading } = useCanonicalCategories();
|
||||||
|
const flatCategories = useMemo(() => flattenCategories(categories), [categories]);
|
||||||
|
|
||||||
|
// Updated filter options
|
||||||
|
const categoryOptions = useMemo(
|
||||||
|
() => flatCategories.filter(cat => cat.parentId === null).map(cat => ({ value: String(cat.id), label: cat.name })),
|
||||||
|
[flatCategories]
|
||||||
|
);
|
||||||
|
const subcategoryOptions = useMemo(
|
||||||
|
() => flatCategories.filter(cat => cat.parentId === parseInt(category)).map(cat => ({ value: String(cat.id), label: cat.name })),
|
||||||
|
[flatCategories, category]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
@@ -431,16 +443,14 @@ export default function PartsPage() {
|
|||||||
// Get unique filter options from all products
|
// Get unique filter options from all products
|
||||||
const brandOptions = useMemo(() => Array.from(new Set(products.map(p => p.brandName).filter(Boolean))).sort(), [products]);
|
const brandOptions = useMemo(() => Array.from(new Set(products.map(p => p.brandName).filter(Boolean))).sort(), [products]);
|
||||||
const departmentOptions = useMemo(() => Array.from(new Set(products.map(p => p.department).filter(Boolean))).sort(), [products]);
|
const departmentOptions = useMemo(() => Array.from(new Set(products.map(p => p.department).filter(Boolean))).sort(), [products]);
|
||||||
const categoryOptions = useMemo(() => Array.from(new Set(products.map(p => p.category).filter(Boolean))).sort(), [products]);
|
|
||||||
const subcategoryOptions = useMemo(() => Array.from(new Set(products.map(p => p.subcategory).filter(Boolean))).sort(), [products]);
|
|
||||||
|
|
||||||
// Filter products before rendering
|
// Filter products before rendering (match by category/subcategory ID if available)
|
||||||
const filteredProducts = useMemo(() => {
|
const filteredProducts = useMemo(() => {
|
||||||
return products.filter(p =>
|
return products.filter(p =>
|
||||||
(!brand || p.brandName === brand) &&
|
(!brand || p.brandName === brand) &&
|
||||||
(!department || p.department === department) &&
|
(!department || p.department === department) &&
|
||||||
(!category || p.category === category) &&
|
(!category || String(p.categoryId) === category) &&
|
||||||
(!subcategory || p.subcategory === subcategory)
|
(!subcategory || String(p.subcategoryId) === subcategory)
|
||||||
);
|
);
|
||||||
}, [products, brand, department, category, subcategory]);
|
}, [products, brand, department, category, subcategory]);
|
||||||
|
|
||||||
@@ -465,25 +475,18 @@ export default function PartsPage() {
|
|||||||
{brandOptions.map(opt => <option key={opt} value={opt}>{opt}</option>)}
|
{brandOptions.map(opt => <option key={opt} value={opt}>{opt}</option>)}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<label className="block text-xs font-semibold mb-1">Department</label>
|
|
||||||
<select className="border rounded px-2 py-1 min-w-[120px] w-full" value={department} onChange={e => setDepartment(e.target.value)}>
|
|
||||||
<option value="">All</option>
|
|
||||||
{departmentOptions.map(opt => <option key={opt} value={opt}>{opt}</option>)}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-semibold mb-1">Category</label>
|
<label className="block text-xs font-semibold mb-1">Category</label>
|
||||||
<select className="border rounded px-2 py-1 min-w-[120px] w-full" value={category} onChange={e => setCategory(e.target.value)}>
|
<select className="border rounded px-2 py-1 min-w-[120px] w-full" value={category} onChange={e => { setCategory(e.target.value); setSubcategory(''); }}>
|
||||||
<option value="">All</option>
|
<option value="">All</option>
|
||||||
{categoryOptions.map(opt => <option key={opt} value={opt}>{opt}</option>)}
|
{categoryOptions.map(opt => <option key={opt.value} value={opt.value}>{opt.label}</option>)}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-semibold mb-1">Subcategory</label>
|
<label className="block text-xs font-semibold mb-1">Subcategory</label>
|
||||||
<select className="border rounded px-2 py-1 min-w-[120px] w-full" value={subcategory} onChange={e => setSubcategory(e.target.value)}>
|
<select className="border rounded px-2 py-1 min-w-[120px] w-full" value={subcategory} onChange={e => setSubcategory(e.target.value)}>
|
||||||
<option value="">All</option>
|
<option value="">All</option>
|
||||||
{subcategoryOptions.map(opt => <option key={opt} value={opt}>{opt}</option>)}
|
{subcategoryOptions.map(opt => <option key={opt.value} value={opt.value}>{opt.label}</option>)}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -505,15 +508,15 @@ export default function PartsPage() {
|
|||||||
) : paginatedProducts.length === 0 ? (
|
) : paginatedProducts.length === 0 ? (
|
||||||
<tr><td colSpan={columns.length} className="text-center py-8">No products found.</td></tr>
|
<tr><td colSpan={columns.length} className="text-center py-8">No products found.</td></tr>
|
||||||
) : (
|
) : (
|
||||||
paginatedProducts.map((product, i) => (
|
paginatedProducts
|
||||||
<tr key={product.uuid || i} className="border-b hover:bg-zinc-50">
|
.filter(product => columns.some(col => product[col] && String(product[col]).trim() !== ''))
|
||||||
|
.map((product, i) => (
|
||||||
|
<tr key={product.id || i} className="border-b hover:bg-zinc-50">
|
||||||
{columns.map(col => (
|
{columns.map(col => (
|
||||||
<td key={col} className="px-2 py-1 max-w-xs truncate">
|
<td key={col} className="px-2 py-1 max-w-xs truncate">
|
||||||
{col === 'imageUrl' && product[col] ? (
|
{typeof product[col] === 'object' && product[col] !== null
|
||||||
<img src={product[col]} alt="thumb" className="h-10 w-10 object-contain border rounded" />
|
? JSON.stringify(product[col])
|
||||||
) : (
|
: product[col] ?? ''}
|
||||||
product[col] ?? ''
|
|
||||||
)}
|
|
||||||
</td>
|
</td>
|
||||||
))}
|
))}
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { db } from '@/db';
|
import { db } from '@/db';
|
||||||
import { bb_products } from '@/db/schema';
|
import { products } from '@/db/schema';
|
||||||
|
|
||||||
function slugify(name: string): string {
|
function slugify(name: string): string {
|
||||||
return name
|
return name
|
||||||
@@ -13,7 +13,7 @@ export async function GET(
|
|||||||
{ params }: { params: { slug: string } }
|
{ params }: { params: { slug: string } }
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const allProducts = await db.select().from(bb_products);
|
const allProducts = await db.select().from(products);
|
||||||
const mapped = allProducts.map((item: any) => ({
|
const mapped = allProducts.map((item: any) => ({
|
||||||
id: item.uuid,
|
id: item.uuid,
|
||||||
name: item.productName,
|
name: item.productName,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { db } from '@/db';
|
import { db } from '@/db';
|
||||||
import { bb_products } from '@/db/schema';
|
import { products } from '@/db/schema';
|
||||||
import { NextResponse } from 'next/server';
|
import { NextResponse } from 'next/server';
|
||||||
import { sql } from 'drizzle-orm';
|
import { sql } from 'drizzle-orm';
|
||||||
|
|
||||||
@@ -18,11 +18,11 @@ export async function GET(req: Request) {
|
|||||||
const offset = (page - 1) * limit;
|
const offset = (page - 1) * limit;
|
||||||
|
|
||||||
// Get total count using raw SQL
|
// Get total count using raw SQL
|
||||||
const totalResult = await db.execute(sql`SELECT COUNT(*)::int AS count FROM bb_products`);
|
const totalResult = await db.execute(sql`SELECT COUNT(*)::int AS count FROM products`);
|
||||||
const total = Number(totalResult.rows?.[0]?.count || 0);
|
const total = Number(totalResult.rows?.[0]?.count || 0);
|
||||||
|
|
||||||
// Get paginated products
|
// Get paginated products
|
||||||
const allProducts = await db.select().from(bb_products).limit(limit).offset(offset);
|
const allProducts = await db.select().from(products).limit(limit).offset(offset);
|
||||||
const mapped = allProducts.map((item: any) => ({
|
const mapped = allProducts.map((item: any) => ({
|
||||||
...item,
|
...item,
|
||||||
slug: slugify(item.productName || item.product_name || item.name || ''),
|
slug: slugify(item.productName || item.product_name || item.name || ''),
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { db } from "@/db";
|
import { db } from "@/db";
|
||||||
import { bb_products } from "@/db/schema";
|
import { products } from "@/db/schema";
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
try {
|
try {
|
||||||
const allProducts = await db.select().from(bb_products).limit(50);
|
const allProducts = await db.select().from(products).limit(50);
|
||||||
const mapped = allProducts.map((item: any) => ({
|
const mapped = allProducts.map((item: any) => ({
|
||||||
id: item.uuid,
|
id: item.uuid,
|
||||||
name: item.productName,
|
name: item.productName,
|
||||||
|
|||||||
571
src/db/schema-org.ts
Normal file
571
src/db/schema-org.ts
Normal file
@@ -0,0 +1,571 @@
|
|||||||
|
import { pgTableCreator, integer, varchar, text, numeric, timestamp, unique, check, date, boolean, uuid, bigint, real, doublePrecision, primaryKey, pgView, index, serial } from "drizzle-orm/pg-core";
|
||||||
|
import { relations, sql } from "drizzle-orm";
|
||||||
|
import { DATABASE_PREFIX as prefix } from "@/lib/constants";
|
||||||
|
|
||||||
|
export const pgTable = pgTableCreator((name) => (prefix == "" || prefix == null) ? name: `${prefix}_${name}`);
|
||||||
|
///
|
||||||
|
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 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 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 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 bb_products = pgTable("bb_products", {
|
||||||
|
uuid: uuid().defaultRandom().primaryKey().notNull(),
|
||||||
|
upc: varchar("UPC", { length: 100 }),
|
||||||
|
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: 500 }),
|
||||||
|
department: varchar("DEPARTMENT", { length: 100 }),
|
||||||
|
category: varchar("CATEGORY", { length: 100 }),
|
||||||
|
subcategory: varchar("SUBCATEGORY", { length: 100 }),
|
||||||
|
thumbUrl: varchar("THUMB_URL", { length: 500 }),
|
||||||
|
imageUrl: varchar("IMAGE_URL", { length: 500 }),
|
||||||
|
buyLink: varchar("BUY_LINK", { length: 500 }),
|
||||||
|
keywords: varchar("KEYWORDS", { length: 500 }),
|
||||||
|
reviews: varchar("REVIEWS", { length: 500 }),
|
||||||
|
retailPrice: varchar("RETAIL_PRICE", { length: 50 }),
|
||||||
|
salePrice: varchar("SALE_PRICE", { length: 50 }),
|
||||||
|
brandPageLink: varchar("BRAND_PAGE_LINK", { length: 500 }),
|
||||||
|
brandLogoImage: varchar("BRAND_LOGO_IMAGE", { length: 500 }),
|
||||||
|
productPageViewTracking: varchar("PRODUCT_PAGE_VIEW_TRACKING", { length: 500 }),
|
||||||
|
parentGroupId: varchar("PARENT_GROUP_ID", { length: 200 }),
|
||||||
|
fineline: varchar("FINELINE", { length: 200 }),
|
||||||
|
superfineline: varchar("SUPERFINELINE", { length: 200 }),
|
||||||
|
modelnumber: varchar("MODELNUMBER", { length: 100 }),
|
||||||
|
caliber: varchar("CALIBER", { length: 200 }),
|
||||||
|
mediumImageUrl: varchar("MEDIUM_IMAGE_URL", { length: 500 }),
|
||||||
|
productContentWidget: varchar("PRODUCT_CONTENT_WIDGET", { length: 500 }),
|
||||||
|
googleCategorization: varchar("GOOGLE_CATEGORIZATION", { length: 500 }),
|
||||||
|
itemBasedCommission: varchar("ITEM_BASED_COMMISSION", { length: 500 }),
|
||||||
|
itemBasedCommissionRate: varchar("ITEM_BASED_COMMISSION RATE", { length: 50 }),
|
||||||
|
updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(),
|
||||||
|
createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(),
|
||||||
|
deletedAt: timestamp("deleted_at", { mode: 'string' }),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const psa_old = pgTable("psa_old", {
|
||||||
|
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 psa = pgTable("psa", {
|
||||||
|
id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "psa_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }),
|
||||||
|
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 verificationTokens = pgTable("verificationTokens", {
|
||||||
|
identifier: varchar("identifier").notNull(),
|
||||||
|
token: varchar("token").notNull(),
|
||||||
|
expires: timestamp("expires").notNull(),
|
||||||
|
});
|
||||||
|
|
||||||
|
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 {
|
||||||
|
authenticatorUserIdCredentialIdPk: primaryKey({ columns: [table.credentialId, table.userId], name: "authenticator_userId_credentialID_pk"}),
|
||||||
|
authenticatorCredentialIdUnique: unique("authenticator_credentialID_unique").on(table.credentialId),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const accounts = pgTable("accounts", {
|
||||||
|
id: uuid("id").primaryKey().defaultRandom(),
|
||||||
|
uuid: uuid("uuid").defaultRandom(),
|
||||||
|
userId: uuid("user_id").notNull(),
|
||||||
|
type: varchar("type").notNull(),
|
||||||
|
provider: text().notNull(),
|
||||||
|
providerAccountId: varchar("provider_account_id").notNull(),
|
||||||
|
refreshToken: text("refresh_token"),
|
||||||
|
accessToken: text("access_token"),
|
||||||
|
expiresAt: integer("expires_at"),
|
||||||
|
tokenType: varchar("token_type"),
|
||||||
|
idToken: text("id_token"),
|
||||||
|
sessionState: varchar("session_state"),
|
||||||
|
scope: text(),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/* export const vw_accounts = pgView("vw_accounts", {
|
||||||
|
uuid: uuid().defaultRandom(),
|
||||||
|
userId: text("user_id").notNull(),
|
||||||
|
type: text().notNull(),
|
||||||
|
provider: text().notNull(),
|
||||||
|
providerAccountId: text("provider_account_id").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"),
|
||||||
|
first_name: text("first_name"),
|
||||||
|
last_name: text("last_name"),
|
||||||
|
|
||||||
|
},) */
|
||||||
|
|
||||||
|
/* From here down is the authentication library Lusia tables */
|
||||||
|
|
||||||
|
export const users = pgTable("user",
|
||||||
|
{
|
||||||
|
id: varchar("id", { length: 21 }).primaryKey(),
|
||||||
|
name: varchar("name"),
|
||||||
|
username: varchar({ length: 50 }),
|
||||||
|
discordId: varchar("discord_id", { length: 255 }).unique(),
|
||||||
|
email: varchar("email", { length: 255 }).unique().notNull(),
|
||||||
|
emailVerified: boolean("email_verified").default(false).notNull(),
|
||||||
|
hashedPassword: varchar("hashed_password", { length: 255 }),
|
||||||
|
first_name: varchar("first_name", { length: 50 }),
|
||||||
|
last_name: varchar("last_name", { length: 50 }),
|
||||||
|
full_name: varchar("full_name", { length: 50 }),
|
||||||
|
profilePicture: varchar("profile_picture", { length: 255 }),
|
||||||
|
image: text("image"),
|
||||||
|
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' }),
|
||||||
|
buildPrivacySetting: text("build_privacy_setting").default('public'),
|
||||||
|
uuid: uuid().defaultRandom(),
|
||||||
|
avatar: varchar("avatar", { length: 255 }),
|
||||||
|
stripeSubscriptionId: varchar("stripe_subscription_id", { length: 191 }),
|
||||||
|
stripePriceId: varchar("stripe_price_id", { length: 191 }),
|
||||||
|
stripeCustomerId: varchar("stripe_customer_id", { length: 191 }),
|
||||||
|
stripeCurrentPeriodEnd: timestamp("stripe_current_period_end"),
|
||||||
|
}, (table) => ({
|
||||||
|
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])`),
|
||||||
|
emailIdx: index("user_email_idx").on(table.email),
|
||||||
|
discordIdx: index("user_discord_idx").on(table.discordId),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
export type User = typeof users.$inferSelect;
|
||||||
|
export type NewUser = typeof users.$inferInsert;
|
||||||
|
|
||||||
|
export const session = pgTable(
|
||||||
|
"session",
|
||||||
|
{
|
||||||
|
sessionToken: varchar("sessionToken", { length: 255 }).primaryKey(),
|
||||||
|
userId: varchar("userId", { length: 21 }).notNull(),
|
||||||
|
expires: timestamp("expires", { withTimezone: true, mode: "date" }).notNull(),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const emailVerificationCodes = pgTable(
|
||||||
|
"email_verification_codes",
|
||||||
|
{
|
||||||
|
id: serial("id").primaryKey(),
|
||||||
|
userId: varchar("user_id", { length: 21 }).unique().notNull(),
|
||||||
|
email: varchar("email", { length: 255 }).notNull(),
|
||||||
|
code: varchar("code", { length: 8 }).notNull(),
|
||||||
|
expiresAt: timestamp("expires_at", { withTimezone: true, mode: "date" }).notNull(),
|
||||||
|
},
|
||||||
|
(t) => ({
|
||||||
|
userIdx: index("verification_code_user_idx").on(t.userId),
|
||||||
|
emailIdx: index("verification_code_email_idx").on(t.email),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
export const passwordResetTokens = pgTable(
|
||||||
|
"password_reset_tokens",
|
||||||
|
{
|
||||||
|
id: varchar("id", { length: 40 }).primaryKey(),
|
||||||
|
userId: varchar("user_id", { length: 21 }).notNull(),
|
||||||
|
expiresAt: timestamp("expires_at", { withTimezone: true, mode: "date" }).notNull(),
|
||||||
|
},
|
||||||
|
(t) => ({
|
||||||
|
userIdx: index("password_token_user_idx").on(t.userId),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
export const posts = pgTable(
|
||||||
|
"posts",
|
||||||
|
{
|
||||||
|
id: varchar("id", { length: 15 }).primaryKey(),
|
||||||
|
userId: varchar("user_id", { length: 255 }).notNull(),
|
||||||
|
title: varchar("title", { length: 255 }).notNull(),
|
||||||
|
excerpt: varchar("excerpt", { length: 255 }).notNull(),
|
||||||
|
content: text("content").notNull(),
|
||||||
|
status: varchar("status", { length: 10, enum: ["draft", "published"] })
|
||||||
|
.default("draft")
|
||||||
|
.notNull(),
|
||||||
|
tags: varchar("tags", { length: 255 }),
|
||||||
|
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||||
|
updatedAt: timestamp("updated_at", { mode: "date" }).$onUpdate(() => new Date()),
|
||||||
|
},
|
||||||
|
(t) => ({
|
||||||
|
userIdx: index("post_user_idx").on(t.userId),
|
||||||
|
createdAtIdx: index("post_created_at_idx").on(t.createdAt),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
export const postRelations = relations(posts, ({ one }) => ({
|
||||||
|
user: one(users, {
|
||||||
|
fields: [posts.userId],
|
||||||
|
references: [users.id],
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export type Post = typeof posts.$inferSelect;
|
||||||
|
export type NewPost = typeof posts.$inferInsert;
|
||||||
|
|
||||||
|
export const vwUserSessions = pgView("vw_user_sessions", { id: varchar({ length: 255 }),
|
||||||
|
userId: varchar("user_id", { length: 21 }),
|
||||||
|
uId: varchar("u_id", { length: 21 }),
|
||||||
|
uEmail: varchar("u_email", { length: 255 }),
|
||||||
|
expiresAt: timestamp("expires_at", { withTimezone: true, mode: 'string' }),
|
||||||
|
createdAt: timestamp("created_at", { mode: 'string' }),
|
||||||
|
updatedAt: timestamp("updated_at", { mode: 'string' }),
|
||||||
|
}).existing();
|
||||||
|
//as(sql`SELECT s.id, s.user_id, u.id AS u_id, u.email AS u_email, s.expires_at, s.created_at, s.updated_at FROM sessions s, users u WHERE s.user_id::text = u.id::text`);
|
||||||
|
|
||||||
|
// Default Drizzle File
|
||||||
|
|
||||||
|
// import { pgTable, serial, text, integer, timestamp } from "drizzle-orm/pg-core";
|
||||||
|
|
||||||
|
// export const products = pgTable("products", {
|
||||||
|
// id: serial("id").primaryKey(),
|
||||||
|
// name: text("name").notNull(),
|
||||||
|
// description: text("description"),
|
||||||
|
// price: integer("price"),
|
||||||
|
// createdAt: timestamp("created_at").defaultNow(),
|
||||||
|
// // Add more fields as needed
|
||||||
|
// });
|
||||||
|
|
||||||
|
export const affiliateCategoryMap = pgTable("affiliate_category_map", {
|
||||||
|
id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "affiliate_category_map_id_seq", startWith: 1, increment: 1 }),
|
||||||
|
feedname: varchar("feedname", { length: 100 }).notNull(),
|
||||||
|
affiliatecategory: varchar("affiliatecategory", { length: 255 }).notNull(),
|
||||||
|
buildercategoryid: integer("buildercategoryid").notNull(),
|
||||||
|
notes: varchar("notes", { length: 255 }),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const product_categories = pgTable("product_categories", {
|
||||||
|
id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "product_categories_id_seq", startWith: 1, increment: 1 }),
|
||||||
|
name: varchar({ length: 100 }).notNull(),
|
||||||
|
parent_category_id: integer("parent_category_id"),
|
||||||
|
type: varchar({ length: 50 }),
|
||||||
|
sort_order: integer("sort_order"),
|
||||||
|
created_at: timestamp("created_at", { mode: 'string' }).defaultNow(),
|
||||||
|
updated_at: timestamp("updated_at", { mode: 'string' }).defaultNow(),
|
||||||
|
});
|
||||||
659
src/db/schema.ts
659
src/db/schema.ts
@@ -1,571 +1,108 @@
|
|||||||
import { pgTableCreator, integer, varchar, text, numeric, timestamp, unique, check, date, boolean, uuid, bigint, real, doublePrecision, primaryKey, pgView, index, serial } from "drizzle-orm/pg-core";
|
import { pgTable, foreignKey, serial, varchar, integer, doublePrecision, timestamp, unique, text, numeric, boolean, jsonb } from "drizzle-orm/pg-core"
|
||||||
import { relations, sql } from "drizzle-orm";
|
import { sql } from "drizzle-orm"
|
||||||
import { DATABASE_PREFIX as prefix } from "@/lib/constants";
|
|
||||||
|
|
||||||
export const pgTable = pgTableCreator((name) => (prefix == "" || prefix == null) ? name: `${prefix}_${name}`);
|
|
||||||
///
|
|
||||||
export const products = pgTable("products", {
|
export const productCategoryMappings = pgTable("product_category_mappings", {
|
||||||
id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "products_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }),
|
id: serial().primaryKey().notNull(),
|
||||||
name: varchar({ length: 255 }).notNull(),
|
feedName: varchar("feed_name", { length: 255 }),
|
||||||
description: text().notNull(),
|
feedCategoryValue: varchar("feed_category_value", { length: 255 }),
|
||||||
price: numeric().notNull(),
|
canonicalCategoryId: integer("canonical_category_id"),
|
||||||
resellerId: integer("reseller_id").notNull(),
|
confidenceScore: doublePrecision("confidence_score"),
|
||||||
categoryId: integer("category_id").notNull(),
|
lastReviewedBy: varchar("last_reviewed_by", { length: 255 }),
|
||||||
stockQty: integer("stock_qty").default(0),
|
lastReviewedAt: timestamp("last_reviewed_at", { mode: 'string' }),
|
||||||
updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(),
|
}, (table) => [
|
||||||
createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(),
|
foreignKey({
|
||||||
deletedAt: timestamp("deleted_at", { mode: 'string' }),
|
columns: [table.canonicalCategoryId],
|
||||||
});
|
foreignColumns: [categories.id],
|
||||||
|
name: "product_category_mappings_canonical_category_id_fkey"
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
export const categories = pgTable("categories", {
|
export const categories = pgTable("categories", {
|
||||||
id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "categories_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }),
|
id: serial().primaryKey().notNull(),
|
||||||
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 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 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(),
|
name: varchar({ length: 255 }).notNull(),
|
||||||
|
parentId: integer("parent_id"),
|
||||||
|
slug: varchar({ length: 255 }).notNull(),
|
||||||
|
}, (table) => [
|
||||||
|
foreignKey({
|
||||||
|
columns: [table.parentId],
|
||||||
|
foreignColumns: [table.id],
|
||||||
|
name: "categories_parent_id_fkey"
|
||||||
|
}),
|
||||||
|
unique("categories_slug_key").on(table.slug),
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const products = pgTable("products", {
|
||||||
|
id: serial().primaryKey().notNull(),
|
||||||
|
name: varchar({ length: 255 }).notNull(),
|
||||||
|
brand: varchar({ length: 255 }),
|
||||||
description: text(),
|
description: text(),
|
||||||
updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(),
|
upc: varchar({ length: 32 }),
|
||||||
createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(),
|
mpn: varchar({ length: 64 }),
|
||||||
deletedAt: timestamp("deleted_at", { mode: 'string' }),
|
canonicalCategoryId: integer("canonical_category_id"),
|
||||||
uuid: uuid().defaultRandom(),
|
createdAt: timestamp("created_at", { mode: 'string' }).defaultNow(),
|
||||||
}, (table) => {
|
updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow(),
|
||||||
return {
|
}, (table) => [
|
||||||
buildsUuidUnique: unique("builds_uuid_unique").on(table.uuid),
|
foreignKey({
|
||||||
}
|
columns: [table.canonicalCategoryId],
|
||||||
});
|
foreignColumns: [categories.id],
|
||||||
|
name: "products_canonical_category_id_fkey"
|
||||||
export const bb_products = pgTable("bb_products", {
|
|
||||||
uuid: uuid().defaultRandom().primaryKey().notNull(),
|
|
||||||
upc: varchar("UPC", { length: 100 }),
|
|
||||||
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: 500 }),
|
|
||||||
department: varchar("DEPARTMENT", { length: 100 }),
|
|
||||||
category: varchar("CATEGORY", { length: 100 }),
|
|
||||||
subcategory: varchar("SUBCATEGORY", { length: 100 }),
|
|
||||||
thumbUrl: varchar("THUMB_URL", { length: 500 }),
|
|
||||||
imageUrl: varchar("IMAGE_URL", { length: 500 }),
|
|
||||||
buyLink: varchar("BUY_LINK", { length: 500 }),
|
|
||||||
keywords: varchar("KEYWORDS", { length: 500 }),
|
|
||||||
reviews: varchar("REVIEWS", { length: 500 }),
|
|
||||||
retailPrice: varchar("RETAIL_PRICE", { length: 50 }),
|
|
||||||
salePrice: varchar("SALE_PRICE", { length: 50 }),
|
|
||||||
brandPageLink: varchar("BRAND_PAGE_LINK", { length: 500 }),
|
|
||||||
brandLogoImage: varchar("BRAND_LOGO_IMAGE", { length: 500 }),
|
|
||||||
productPageViewTracking: varchar("PRODUCT_PAGE_VIEW_TRACKING", { length: 500 }),
|
|
||||||
parentGroupId: varchar("PARENT_GROUP_ID", { length: 200 }),
|
|
||||||
fineline: varchar("FINELINE", { length: 200 }),
|
|
||||||
superfineline: varchar("SUPERFINELINE", { length: 200 }),
|
|
||||||
modelnumber: varchar("MODELNUMBER", { length: 100 }),
|
|
||||||
caliber: varchar("CALIBER", { length: 200 }),
|
|
||||||
mediumImageUrl: varchar("MEDIUM_IMAGE_URL", { length: 500 }),
|
|
||||||
productContentWidget: varchar("PRODUCT_CONTENT_WIDGET", { length: 500 }),
|
|
||||||
googleCategorization: varchar("GOOGLE_CATEGORIZATION", { length: 500 }),
|
|
||||||
itemBasedCommission: varchar("ITEM_BASED_COMMISSION", { length: 500 }),
|
|
||||||
itemBasedCommissionRate: varchar("ITEM_BASED_COMMISSION RATE", { length: 50 }),
|
|
||||||
updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(),
|
|
||||||
createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(),
|
|
||||||
deletedAt: timestamp("deleted_at", { mode: 'string' }),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const psa_old = pgTable("psa_old", {
|
|
||||||
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 psa = pgTable("psa", {
|
|
||||||
id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "psa_id_seq", startWith: 1, increment: 1, minValue: 1, maxValue: 2147483647, cache: 1 }),
|
|
||||||
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 verificationTokens = pgTable("verificationTokens", {
|
|
||||||
identifier: varchar("identifier").notNull(),
|
|
||||||
token: varchar("token").notNull(),
|
|
||||||
expires: timestamp("expires").notNull(),
|
|
||||||
});
|
|
||||||
|
|
||||||
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 {
|
|
||||||
authenticatorUserIdCredentialIdPk: primaryKey({ columns: [table.credentialId, table.userId], name: "authenticator_userId_credentialID_pk"}),
|
|
||||||
authenticatorCredentialIdUnique: unique("authenticator_credentialID_unique").on(table.credentialId),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export const accounts = pgTable("accounts", {
|
|
||||||
id: uuid("id").primaryKey().defaultRandom(),
|
|
||||||
uuid: uuid("uuid").defaultRandom(),
|
|
||||||
userId: uuid("user_id").notNull(),
|
|
||||||
type: varchar("type").notNull(),
|
|
||||||
provider: text().notNull(),
|
|
||||||
providerAccountId: varchar("provider_account_id").notNull(),
|
|
||||||
refreshToken: text("refresh_token"),
|
|
||||||
accessToken: text("access_token"),
|
|
||||||
expiresAt: integer("expires_at"),
|
|
||||||
tokenType: varchar("token_type"),
|
|
||||||
idToken: text("id_token"),
|
|
||||||
sessionState: varchar("session_state"),
|
|
||||||
scope: text(),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/* export const vw_accounts = pgView("vw_accounts", {
|
|
||||||
uuid: uuid().defaultRandom(),
|
|
||||||
userId: text("user_id").notNull(),
|
|
||||||
type: text().notNull(),
|
|
||||||
provider: text().notNull(),
|
|
||||||
providerAccountId: text("provider_account_id").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"),
|
|
||||||
first_name: text("first_name"),
|
|
||||||
last_name: text("last_name"),
|
|
||||||
|
|
||||||
},) */
|
|
||||||
|
|
||||||
/* From here down is the authentication library Lusia tables */
|
|
||||||
|
|
||||||
export const users = pgTable("user",
|
|
||||||
{
|
|
||||||
id: varchar("id", { length: 21 }).primaryKey(),
|
|
||||||
name: varchar("name"),
|
|
||||||
username: varchar({ length: 50 }),
|
|
||||||
discordId: varchar("discord_id", { length: 255 }).unique(),
|
|
||||||
email: varchar("email", { length: 255 }).unique().notNull(),
|
|
||||||
emailVerified: boolean("email_verified").default(false).notNull(),
|
|
||||||
hashedPassword: varchar("hashed_password", { length: 255 }),
|
|
||||||
first_name: varchar("first_name", { length: 50 }),
|
|
||||||
last_name: varchar("last_name", { length: 50 }),
|
|
||||||
full_name: varchar("full_name", { length: 50 }),
|
|
||||||
profilePicture: varchar("profile_picture", { length: 255 }),
|
|
||||||
image: text("image"),
|
|
||||||
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' }),
|
|
||||||
buildPrivacySetting: text("build_privacy_setting").default('public'),
|
|
||||||
uuid: uuid().defaultRandom(),
|
|
||||||
avatar: varchar("avatar", { length: 255 }),
|
|
||||||
stripeSubscriptionId: varchar("stripe_subscription_id", { length: 191 }),
|
|
||||||
stripePriceId: varchar("stripe_price_id", { length: 191 }),
|
|
||||||
stripeCustomerId: varchar("stripe_customer_id", { length: 191 }),
|
|
||||||
stripeCurrentPeriodEnd: timestamp("stripe_current_period_end"),
|
|
||||||
}, (table) => ({
|
|
||||||
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])`),
|
|
||||||
emailIdx: index("user_email_idx").on(table.email),
|
|
||||||
discordIdx: index("user_discord_idx").on(table.discordId),
|
|
||||||
}),
|
}),
|
||||||
);
|
]);
|
||||||
export type User = typeof users.$inferSelect;
|
|
||||||
export type NewUser = typeof users.$inferInsert;
|
|
||||||
|
|
||||||
export const session = pgTable(
|
export const offers = pgTable("offers", {
|
||||||
"session",
|
id: serial().primaryKey().notNull(),
|
||||||
{
|
productId: integer("product_id"),
|
||||||
sessionToken: varchar("sessionToken", { length: 255 }).primaryKey(),
|
feedName: varchar("feed_name", { length: 255 }).notNull(),
|
||||||
userId: varchar("userId", { length: 21 }).notNull(),
|
feedSku: varchar("feed_sku", { length: 255 }),
|
||||||
expires: timestamp("expires", { withTimezone: true, mode: "date" }).notNull(),
|
price: numeric({ precision: 10, scale: 2 }),
|
||||||
}
|
url: text(),
|
||||||
);
|
inStock: boolean("in_stock"),
|
||||||
|
vendor: varchar({ length: 255 }),
|
||||||
|
lastSeenAt: timestamp("last_seen_at", { mode: 'string' }).defaultNow(),
|
||||||
|
rawData: jsonb("raw_data"),
|
||||||
|
}, (table) => [
|
||||||
|
foreignKey({
|
||||||
|
columns: [table.productId],
|
||||||
|
foreignColumns: [products.id],
|
||||||
|
name: "offers_product_id_fkey"
|
||||||
|
}).onDelete("cascade"),
|
||||||
|
unique("offers_product_id_feed_name_feed_sku_key").on(table.productId, table.feedName, table.feedSku),
|
||||||
|
unique("offers_feed_unique").on(table.feedName, table.feedSku),
|
||||||
|
]);
|
||||||
|
|
||||||
export const emailVerificationCodes = pgTable(
|
export const offerPriceHistory = pgTable("offer_price_history", {
|
||||||
"email_verification_codes",
|
id: serial().primaryKey().notNull(),
|
||||||
{
|
offerId: integer("offer_id"),
|
||||||
id: serial("id").primaryKey(),
|
price: numeric({ precision: 10, scale: 2 }).notNull(),
|
||||||
userId: varchar("user_id", { length: 21 }).unique().notNull(),
|
seenAt: timestamp("seen_at", { mode: 'string' }).defaultNow(),
|
||||||
email: varchar("email", { length: 255 }).notNull(),
|
}, (table) => [
|
||||||
code: varchar("code", { length: 8 }).notNull(),
|
foreignKey({
|
||||||
expiresAt: timestamp("expires_at", { withTimezone: true, mode: "date" }).notNull(),
|
columns: [table.offerId],
|
||||||
},
|
foreignColumns: [offers.id],
|
||||||
(t) => ({
|
name: "offer_price_history_offer_id_fkey"
|
||||||
userIdx: index("verification_code_user_idx").on(t.userId),
|
}).onDelete("cascade"),
|
||||||
emailIdx: index("verification_code_email_idx").on(t.email),
|
]);
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
export const passwordResetTokens = pgTable(
|
export const feeds = pgTable("feeds", {
|
||||||
"password_reset_tokens",
|
id: serial().primaryKey().notNull(),
|
||||||
{
|
name: varchar({ length: 255 }).notNull(),
|
||||||
id: varchar("id", { length: 40 }).primaryKey(),
|
url: text(),
|
||||||
userId: varchar("user_id", { length: 21 }).notNull(),
|
lastImportedAt: timestamp("last_imported_at", { mode: 'string' }),
|
||||||
expiresAt: timestamp("expires_at", { withTimezone: true, mode: "date" }).notNull(),
|
}, (table) => [
|
||||||
},
|
unique("feeds_name_key").on(table.name),
|
||||||
(t) => ({
|
]);
|
||||||
userIdx: index("password_token_user_idx").on(t.userId),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
export const posts = pgTable(
|
export const productAttributes = pgTable("product_attributes", {
|
||||||
"posts",
|
id: serial().primaryKey().notNull(),
|
||||||
{
|
productId: integer("product_id"),
|
||||||
id: varchar("id", { length: 15 }).primaryKey(),
|
name: varchar({ length: 255 }).notNull(),
|
||||||
userId: varchar("user_id", { length: 255 }).notNull(),
|
value: varchar({ length: 255 }).notNull(),
|
||||||
title: varchar("title", { length: 255 }).notNull(),
|
}, (table) => [
|
||||||
excerpt: varchar("excerpt", { length: 255 }).notNull(),
|
foreignKey({
|
||||||
content: text("content").notNull(),
|
columns: [table.productId],
|
||||||
status: varchar("status", { length: 10, enum: ["draft", "published"] })
|
foreignColumns: [products.id],
|
||||||
.default("draft")
|
name: "product_attributes_product_id_fkey"
|
||||||
.notNull(),
|
}).onDelete("cascade"),
|
||||||
tags: varchar("tags", { length: 255 }),
|
]);
|
||||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
|
||||||
updatedAt: timestamp("updated_at", { mode: "date" }).$onUpdate(() => new Date()),
|
|
||||||
},
|
|
||||||
(t) => ({
|
|
||||||
userIdx: index("post_user_idx").on(t.userId),
|
|
||||||
createdAtIdx: index("post_created_at_idx").on(t.createdAt),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
export const postRelations = relations(posts, ({ one }) => ({
|
|
||||||
user: one(users, {
|
|
||||||
fields: [posts.userId],
|
|
||||||
references: [users.id],
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
export type Post = typeof posts.$inferSelect;
|
|
||||||
export type NewPost = typeof posts.$inferInsert;
|
|
||||||
|
|
||||||
export const vwUserSessions = pgView("vw_user_sessions", { id: varchar({ length: 255 }),
|
|
||||||
userId: varchar("user_id", { length: 21 }),
|
|
||||||
uId: varchar("u_id", { length: 21 }),
|
|
||||||
uEmail: varchar("u_email", { length: 255 }),
|
|
||||||
expiresAt: timestamp("expires_at", { withTimezone: true, mode: 'string' }),
|
|
||||||
createdAt: timestamp("created_at", { mode: 'string' }),
|
|
||||||
updatedAt: timestamp("updated_at", { mode: 'string' }),
|
|
||||||
}).existing();
|
|
||||||
//as(sql`SELECT s.id, s.user_id, u.id AS u_id, u.email AS u_email, s.expires_at, s.created_at, s.updated_at FROM sessions s, users u WHERE s.user_id::text = u.id::text`);
|
|
||||||
|
|
||||||
// Default Drizzle File
|
|
||||||
|
|
||||||
// import { pgTable, serial, text, integer, timestamp } from "drizzle-orm/pg-core";
|
|
||||||
|
|
||||||
// export const products = pgTable("products", {
|
|
||||||
// id: serial("id").primaryKey(),
|
|
||||||
// name: text("name").notNull(),
|
|
||||||
// description: text("description"),
|
|
||||||
// price: integer("price"),
|
|
||||||
// createdAt: timestamp("created_at").defaultNow(),
|
|
||||||
// // Add more fields as needed
|
|
||||||
// });
|
|
||||||
|
|
||||||
export const affiliateCategoryMap = pgTable("affiliate_category_map", {
|
|
||||||
id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "affiliate_category_map_id_seq", startWith: 1, increment: 1 }),
|
|
||||||
feedname: varchar("feedname", { length: 100 }).notNull(),
|
|
||||||
affiliatecategory: varchar("affiliatecategory", { length: 255 }).notNull(),
|
|
||||||
buildercategoryid: integer("buildercategoryid").notNull(),
|
|
||||||
notes: varchar("notes", { length: 255 }),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const product_categories = pgTable("product_categories", {
|
|
||||||
id: integer().primaryKey().generatedAlwaysAsIdentity({ name: "product_categories_id_seq", startWith: 1, increment: 1 }),
|
|
||||||
name: varchar({ length: 100 }).notNull(),
|
|
||||||
parent_category_id: integer("parent_category_id"),
|
|
||||||
type: varchar({ length: 50 }),
|
|
||||||
sort_order: integer("sort_order"),
|
|
||||||
created_at: timestamp("created_at", { mode: 'string' }).defaultNow(),
|
|
||||||
updated_at: timestamp("updated_at", { mode: 'string' }).defaultNow(),
|
|
||||||
});
|
|
||||||
|
|||||||
Reference in New Issue
Block a user