diff --git a/drizzle/0016_lazy_kinsey_walden.sql b/drizzle/0016_lazy_kinsey_walden.sql new file mode 100644 index 0000000..4d1672d --- /dev/null +++ b/drizzle/0016_lazy_kinsey_walden.sql @@ -0,0 +1,32 @@ +CREATE TYPE "public"."market_order_status" AS ENUM('awaiting_approval', 'approved', 'fulfilled');--> statement-breakpoint +CREATE TABLE "market_item" ( + "id" serial PRIMARY KEY NOT NULL, + "createdBy" integer, + "name" text NOT NULL, + "description" text NOT NULL, + "image" text NOT NULL, + "minRequiredShopScore" integer DEFAULT 0 NOT NULL, + "minShopScore" integer NOT NULL, + "maxShopScore" integer NOT NULL, + "maxPrice" integer NOT NULL, + "minPrice" integer NOT NULL, + "isPublic" boolean DEFAULT false NOT NULL, + "deleted" boolean DEFAULT false NOT NULL, + "createdAt" timestamp DEFAULT now() NOT NULL, + "updatedAt" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "market_item_order" ( + "id" serial PRIMARY KEY NOT NULL, + "userId" integer, + "addressId" text NOT NULL, + "bricksPaid" integer NOT NULL, + "status" "market_order_status" DEFAULT 'awaiting_approval' NOT NULL, + "userNotes" text NOT NULL, + "notes" text NOT NULL, + "deleted" boolean DEFAULT false NOT NULL, + "createdAt" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +ALTER TABLE "market_item" ADD CONSTRAINT "market_item_createdBy_user_id_fk" FOREIGN KEY ("createdBy") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "market_item_order" ADD CONSTRAINT "market_item_order_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action; \ No newline at end of file diff --git a/drizzle/0017_long_greymalkin.sql b/drizzle/0017_long_greymalkin.sql new file mode 100644 index 0000000..a15f9d7 --- /dev/null +++ b/drizzle/0017_long_greymalkin.sql @@ -0,0 +1,2 @@ +ALTER TYPE "public"."market_order_status" ADD VALUE 'denied';--> statement-breakpoint +ALTER TYPE "public"."market_order_status" ADD VALUE 'refunded'; \ No newline at end of file diff --git a/drizzle/0018_sour_roughhouse.sql b/drizzle/0018_sour_roughhouse.sql new file mode 100644 index 0000000..4a680e5 --- /dev/null +++ b/drizzle/0018_sour_roughhouse.sql @@ -0,0 +1 @@ +ALTER TABLE "market_item_order" ALTER COLUMN "notes" DROP NOT NULL; \ No newline at end of file diff --git a/drizzle/0019_wide_gamora.sql b/drizzle/0019_wide_gamora.sql new file mode 100644 index 0000000..11031a9 --- /dev/null +++ b/drizzle/0019_wide_gamora.sql @@ -0,0 +1 @@ +ALTER TABLE "market_item_order" ALTER COLUMN "userId" SET NOT NULL; \ No newline at end of file diff --git a/drizzle/meta/0016_snapshot.json b/drizzle/meta/0016_snapshot.json new file mode 100644 index 0000000..2f3871d --- /dev/null +++ b/drizzle/meta/0016_snapshot.json @@ -0,0 +1,1099 @@ +{ + "id": "af6c7146-421a-48ea-88a9-7abbde335bb7", + "prevId": "1299d59c-43b6-46a5-9557-3c51b87eac07", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.devlog": { + "name": "devlog", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timeSpent": { + "name": "timeSpent", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "devlog_userId_user_id_fk": { + "name": "devlog_userId_user_id_fk", + "tableFrom": "devlog", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "devlog_projectId_project_id_fk": { + "name": "devlog_projectId_project_id_fk", + "tableFrom": "devlog", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.legion_review": { + "name": "legion_review", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "feedback": { + "name": "feedback", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "filamentUsed": { + "name": "filamentUsed", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "legion_action", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "legion_review_userId_user_id_fk": { + "name": "legion_review_userId_user_id_fk", + "tableFrom": "legion_review", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "legion_review_projectId_project_id_fk": { + "name": "legion_review_projectId_project_id_fk", + "tableFrom": "legion_review", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.market_item": { + "name": "market_item", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "minRequiredShopScore": { + "name": "minRequiredShopScore", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "minShopScore": { + "name": "minShopScore", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "maxShopScore": { + "name": "maxShopScore", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "maxPrice": { + "name": "maxPrice", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "minPrice": { + "name": "minPrice", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "isPublic": { + "name": "isPublic", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "market_item_createdBy_user_id_fk": { + "name": "market_item_createdBy_user_id_fk", + "tableFrom": "market_item", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.market_item_order": { + "name": "market_item_order", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "addressId": { + "name": "addressId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bricksPaid": { + "name": "bricksPaid", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "market_order_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'awaiting_approval'" + }, + "userNotes": { + "name": "userNotes", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "market_item_order_userId_user_id_fk": { + "name": "market_item_order_userId_user_id_fk", + "tableFrom": "market_item_order", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.project": { + "name": "project", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "editorFileType": { + "name": "editorFileType", + "type": "editor_file_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "editorUrl": { + "name": "editorUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uploadedFileUrl": { + "name": "uploadedFileUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "modelFile": { + "name": "modelFile", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'building'" + }, + "printedBy": { + "name": "printedBy", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "submittedToAirtable": { + "name": "submittedToAirtable", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "project_userId_user_id_fk": { + "name": "project_userId_user_id_fk", + "tableFrom": "project", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "project_printedBy_user_id_fk": { + "name": "project_printedBy_user_id_fk", + "tableFrom": "project", + "tableTo": "user", + "columnsFrom": [ + "printedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "session_userId_user_id_fk": { + "name": "session_userId_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ship": { + "name": "ship", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "editorFileType": { + "name": "editorFileType", + "type": "editor_file_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "editorUrl": { + "name": "editorUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uploadedFileUrl": { + "name": "uploadedFileUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "modelFile": { + "name": "modelFile", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "ship_userId_user_id_fk": { + "name": "ship_userId_user_id_fk", + "tableFrom": "ship", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "ship_projectId_project_id_fk": { + "name": "ship_projectId_project_id_fk", + "tableFrom": "ship", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.t1_review": { + "name": "t1_review", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "feedback": { + "name": "feedback", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "t1_review_action", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "t1_review_userId_user_id_fk": { + "name": "t1_review_userId_user_id_fk", + "tableFrom": "t1_review", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "t1_review_projectId_project_id_fk": { + "name": "t1_review_projectId_project_id_fk", + "tableFrom": "t1_review", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.t2_review": { + "name": "t2_review", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "feedback": { + "name": "feedback", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "currencyMultiplier": { + "name": "currencyMultiplier", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "t2_review_userId_user_id_fk": { + "name": "t2_review_userId_user_id_fk", + "tableFrom": "t2_review", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "t2_review_projectId_project_id_fk": { + "name": "t2_review_projectId_project_id_fk", + "tableFrom": "t2_review", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "idvId": { + "name": "idvId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "idvToken": { + "name": "idvToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "slackId": { + "name": "slackId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "profilePicture": { + "name": "profilePicture", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hackatimeTrust": { + "name": "hackatimeTrust", + "type": "hackatime_trust", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "trust": { + "name": "trust", + "type": "trust", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'blue'" + }, + "clay": { + "name": "clay", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "brick": { + "name": "brick", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "shopScore": { + "name": "shopScore", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "hasBasePrinter": { + "name": "hasBasePrinter", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "hasT1Review": { + "name": "hasT1Review", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "hasT2Review": { + "name": "hasT2Review", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "hasAdmin": { + "name": "hasAdmin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "isPrinter": { + "name": "isPrinter", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "lastLoginAt": { + "name": "lastLoginAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_idvId_unique": { + "name": "user_idvId_unique", + "nullsNotDistinct": false, + "columns": [ + "idvId" + ] + }, + "user_slackId_unique": { + "name": "user_slackId_unique", + "nullsNotDistinct": false, + "columns": [ + "slackId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.editor_file_type": { + "name": "editor_file_type", + "schema": "public", + "values": [ + "url", + "upload" + ] + }, + "public.hackatime_trust": { + "name": "hackatime_trust", + "schema": "public", + "values": [ + "green", + "blue", + "yellow", + "red" + ] + }, + "public.legion_action": { + "name": "legion_action", + "schema": "public", + "values": [ + "mark_for_printing", + "unmark_for_printing", + "print", + "add_comment", + "reject", + "already_printed" + ] + }, + "public.market_order_status": { + "name": "market_order_status", + "schema": "public", + "values": [ + "awaiting_approval", + "approved", + "fulfilled" + ] + }, + "public.project_audit_log_type": { + "name": "project_audit_log_type", + "schema": "public", + "values": [ + "create", + "update", + "delete" + ] + }, + "public.status": { + "name": "status", + "schema": "public", + "values": [ + "building", + "submitted", + "t1_approved", + "printing", + "printed", + "t2_approved", + "finalized", + "rejected", + "rejected_locked" + ] + }, + "public.t1_review_action": { + "name": "t1_review_action", + "schema": "public", + "values": [ + "approve", + "approve_no_print", + "add_comment", + "reject", + "reject_lock" + ] + }, + "public.trust": { + "name": "trust", + "schema": "public", + "values": [ + "green", + "blue", + "yellow", + "red" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/drizzle/meta/0017_snapshot.json b/drizzle/meta/0017_snapshot.json new file mode 100644 index 0000000..fa2bb6e --- /dev/null +++ b/drizzle/meta/0017_snapshot.json @@ -0,0 +1,1101 @@ +{ + "id": "c1769f02-cca9-40e9-afe3-ed329a1f74c7", + "prevId": "af6c7146-421a-48ea-88a9-7abbde335bb7", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.devlog": { + "name": "devlog", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timeSpent": { + "name": "timeSpent", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "devlog_userId_user_id_fk": { + "name": "devlog_userId_user_id_fk", + "tableFrom": "devlog", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "devlog_projectId_project_id_fk": { + "name": "devlog_projectId_project_id_fk", + "tableFrom": "devlog", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.legion_review": { + "name": "legion_review", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "feedback": { + "name": "feedback", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "filamentUsed": { + "name": "filamentUsed", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "legion_action", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "legion_review_userId_user_id_fk": { + "name": "legion_review_userId_user_id_fk", + "tableFrom": "legion_review", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "legion_review_projectId_project_id_fk": { + "name": "legion_review_projectId_project_id_fk", + "tableFrom": "legion_review", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.market_item": { + "name": "market_item", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "minRequiredShopScore": { + "name": "minRequiredShopScore", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "minShopScore": { + "name": "minShopScore", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "maxShopScore": { + "name": "maxShopScore", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "maxPrice": { + "name": "maxPrice", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "minPrice": { + "name": "minPrice", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "isPublic": { + "name": "isPublic", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "market_item_createdBy_user_id_fk": { + "name": "market_item_createdBy_user_id_fk", + "tableFrom": "market_item", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.market_item_order": { + "name": "market_item_order", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "addressId": { + "name": "addressId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bricksPaid": { + "name": "bricksPaid", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "market_order_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'awaiting_approval'" + }, + "userNotes": { + "name": "userNotes", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "market_item_order_userId_user_id_fk": { + "name": "market_item_order_userId_user_id_fk", + "tableFrom": "market_item_order", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.project": { + "name": "project", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "editorFileType": { + "name": "editorFileType", + "type": "editor_file_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "editorUrl": { + "name": "editorUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uploadedFileUrl": { + "name": "uploadedFileUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "modelFile": { + "name": "modelFile", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'building'" + }, + "printedBy": { + "name": "printedBy", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "submittedToAirtable": { + "name": "submittedToAirtable", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "project_userId_user_id_fk": { + "name": "project_userId_user_id_fk", + "tableFrom": "project", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "project_printedBy_user_id_fk": { + "name": "project_printedBy_user_id_fk", + "tableFrom": "project", + "tableTo": "user", + "columnsFrom": [ + "printedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "session_userId_user_id_fk": { + "name": "session_userId_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ship": { + "name": "ship", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "editorFileType": { + "name": "editorFileType", + "type": "editor_file_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "editorUrl": { + "name": "editorUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uploadedFileUrl": { + "name": "uploadedFileUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "modelFile": { + "name": "modelFile", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "ship_userId_user_id_fk": { + "name": "ship_userId_user_id_fk", + "tableFrom": "ship", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "ship_projectId_project_id_fk": { + "name": "ship_projectId_project_id_fk", + "tableFrom": "ship", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.t1_review": { + "name": "t1_review", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "feedback": { + "name": "feedback", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "t1_review_action", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "t1_review_userId_user_id_fk": { + "name": "t1_review_userId_user_id_fk", + "tableFrom": "t1_review", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "t1_review_projectId_project_id_fk": { + "name": "t1_review_projectId_project_id_fk", + "tableFrom": "t1_review", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.t2_review": { + "name": "t2_review", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "feedback": { + "name": "feedback", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "currencyMultiplier": { + "name": "currencyMultiplier", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "t2_review_userId_user_id_fk": { + "name": "t2_review_userId_user_id_fk", + "tableFrom": "t2_review", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "t2_review_projectId_project_id_fk": { + "name": "t2_review_projectId_project_id_fk", + "tableFrom": "t2_review", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "idvId": { + "name": "idvId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "idvToken": { + "name": "idvToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "slackId": { + "name": "slackId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "profilePicture": { + "name": "profilePicture", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hackatimeTrust": { + "name": "hackatimeTrust", + "type": "hackatime_trust", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "trust": { + "name": "trust", + "type": "trust", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'blue'" + }, + "clay": { + "name": "clay", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "brick": { + "name": "brick", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "shopScore": { + "name": "shopScore", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "hasBasePrinter": { + "name": "hasBasePrinter", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "hasT1Review": { + "name": "hasT1Review", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "hasT2Review": { + "name": "hasT2Review", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "hasAdmin": { + "name": "hasAdmin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "isPrinter": { + "name": "isPrinter", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "lastLoginAt": { + "name": "lastLoginAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_idvId_unique": { + "name": "user_idvId_unique", + "nullsNotDistinct": false, + "columns": [ + "idvId" + ] + }, + "user_slackId_unique": { + "name": "user_slackId_unique", + "nullsNotDistinct": false, + "columns": [ + "slackId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.editor_file_type": { + "name": "editor_file_type", + "schema": "public", + "values": [ + "url", + "upload" + ] + }, + "public.hackatime_trust": { + "name": "hackatime_trust", + "schema": "public", + "values": [ + "green", + "blue", + "yellow", + "red" + ] + }, + "public.legion_action": { + "name": "legion_action", + "schema": "public", + "values": [ + "mark_for_printing", + "unmark_for_printing", + "print", + "add_comment", + "reject", + "already_printed" + ] + }, + "public.market_order_status": { + "name": "market_order_status", + "schema": "public", + "values": [ + "awaiting_approval", + "approved", + "fulfilled", + "denied", + "refunded" + ] + }, + "public.project_audit_log_type": { + "name": "project_audit_log_type", + "schema": "public", + "values": [ + "create", + "update", + "delete" + ] + }, + "public.status": { + "name": "status", + "schema": "public", + "values": [ + "building", + "submitted", + "t1_approved", + "printing", + "printed", + "t2_approved", + "finalized", + "rejected", + "rejected_locked" + ] + }, + "public.t1_review_action": { + "name": "t1_review_action", + "schema": "public", + "values": [ + "approve", + "approve_no_print", + "add_comment", + "reject", + "reject_lock" + ] + }, + "public.trust": { + "name": "trust", + "schema": "public", + "values": [ + "green", + "blue", + "yellow", + "red" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/drizzle/meta/0018_snapshot.json b/drizzle/meta/0018_snapshot.json new file mode 100644 index 0000000..9268cb2 --- /dev/null +++ b/drizzle/meta/0018_snapshot.json @@ -0,0 +1,1101 @@ +{ + "id": "f03cfd63-e7c6-44fa-902c-2f9237b9ee96", + "prevId": "c1769f02-cca9-40e9-afe3-ed329a1f74c7", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.devlog": { + "name": "devlog", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timeSpent": { + "name": "timeSpent", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "devlog_userId_user_id_fk": { + "name": "devlog_userId_user_id_fk", + "tableFrom": "devlog", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "devlog_projectId_project_id_fk": { + "name": "devlog_projectId_project_id_fk", + "tableFrom": "devlog", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.legion_review": { + "name": "legion_review", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "feedback": { + "name": "feedback", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "filamentUsed": { + "name": "filamentUsed", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "legion_action", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "legion_review_userId_user_id_fk": { + "name": "legion_review_userId_user_id_fk", + "tableFrom": "legion_review", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "legion_review_projectId_project_id_fk": { + "name": "legion_review_projectId_project_id_fk", + "tableFrom": "legion_review", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.market_item": { + "name": "market_item", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "minRequiredShopScore": { + "name": "minRequiredShopScore", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "minShopScore": { + "name": "minShopScore", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "maxShopScore": { + "name": "maxShopScore", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "maxPrice": { + "name": "maxPrice", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "minPrice": { + "name": "minPrice", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "isPublic": { + "name": "isPublic", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "market_item_createdBy_user_id_fk": { + "name": "market_item_createdBy_user_id_fk", + "tableFrom": "market_item", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.market_item_order": { + "name": "market_item_order", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "addressId": { + "name": "addressId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bricksPaid": { + "name": "bricksPaid", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "market_order_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'awaiting_approval'" + }, + "userNotes": { + "name": "userNotes", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "market_item_order_userId_user_id_fk": { + "name": "market_item_order_userId_user_id_fk", + "tableFrom": "market_item_order", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.project": { + "name": "project", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "editorFileType": { + "name": "editorFileType", + "type": "editor_file_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "editorUrl": { + "name": "editorUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uploadedFileUrl": { + "name": "uploadedFileUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "modelFile": { + "name": "modelFile", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'building'" + }, + "printedBy": { + "name": "printedBy", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "submittedToAirtable": { + "name": "submittedToAirtable", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "project_userId_user_id_fk": { + "name": "project_userId_user_id_fk", + "tableFrom": "project", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "project_printedBy_user_id_fk": { + "name": "project_printedBy_user_id_fk", + "tableFrom": "project", + "tableTo": "user", + "columnsFrom": [ + "printedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "session_userId_user_id_fk": { + "name": "session_userId_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ship": { + "name": "ship", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "editorFileType": { + "name": "editorFileType", + "type": "editor_file_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "editorUrl": { + "name": "editorUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uploadedFileUrl": { + "name": "uploadedFileUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "modelFile": { + "name": "modelFile", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "ship_userId_user_id_fk": { + "name": "ship_userId_user_id_fk", + "tableFrom": "ship", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "ship_projectId_project_id_fk": { + "name": "ship_projectId_project_id_fk", + "tableFrom": "ship", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.t1_review": { + "name": "t1_review", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "feedback": { + "name": "feedback", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "t1_review_action", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "t1_review_userId_user_id_fk": { + "name": "t1_review_userId_user_id_fk", + "tableFrom": "t1_review", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "t1_review_projectId_project_id_fk": { + "name": "t1_review_projectId_project_id_fk", + "tableFrom": "t1_review", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.t2_review": { + "name": "t2_review", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "feedback": { + "name": "feedback", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "currencyMultiplier": { + "name": "currencyMultiplier", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "t2_review_userId_user_id_fk": { + "name": "t2_review_userId_user_id_fk", + "tableFrom": "t2_review", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "t2_review_projectId_project_id_fk": { + "name": "t2_review_projectId_project_id_fk", + "tableFrom": "t2_review", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "idvId": { + "name": "idvId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "idvToken": { + "name": "idvToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "slackId": { + "name": "slackId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "profilePicture": { + "name": "profilePicture", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hackatimeTrust": { + "name": "hackatimeTrust", + "type": "hackatime_trust", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "trust": { + "name": "trust", + "type": "trust", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'blue'" + }, + "clay": { + "name": "clay", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "brick": { + "name": "brick", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "shopScore": { + "name": "shopScore", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "hasBasePrinter": { + "name": "hasBasePrinter", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "hasT1Review": { + "name": "hasT1Review", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "hasT2Review": { + "name": "hasT2Review", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "hasAdmin": { + "name": "hasAdmin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "isPrinter": { + "name": "isPrinter", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "lastLoginAt": { + "name": "lastLoginAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_idvId_unique": { + "name": "user_idvId_unique", + "nullsNotDistinct": false, + "columns": [ + "idvId" + ] + }, + "user_slackId_unique": { + "name": "user_slackId_unique", + "nullsNotDistinct": false, + "columns": [ + "slackId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.editor_file_type": { + "name": "editor_file_type", + "schema": "public", + "values": [ + "url", + "upload" + ] + }, + "public.hackatime_trust": { + "name": "hackatime_trust", + "schema": "public", + "values": [ + "green", + "blue", + "yellow", + "red" + ] + }, + "public.legion_action": { + "name": "legion_action", + "schema": "public", + "values": [ + "mark_for_printing", + "unmark_for_printing", + "print", + "add_comment", + "reject", + "already_printed" + ] + }, + "public.market_order_status": { + "name": "market_order_status", + "schema": "public", + "values": [ + "awaiting_approval", + "approved", + "fulfilled", + "denied", + "refunded" + ] + }, + "public.project_audit_log_type": { + "name": "project_audit_log_type", + "schema": "public", + "values": [ + "create", + "update", + "delete" + ] + }, + "public.status": { + "name": "status", + "schema": "public", + "values": [ + "building", + "submitted", + "t1_approved", + "printing", + "printed", + "t2_approved", + "finalized", + "rejected", + "rejected_locked" + ] + }, + "public.t1_review_action": { + "name": "t1_review_action", + "schema": "public", + "values": [ + "approve", + "approve_no_print", + "add_comment", + "reject", + "reject_lock" + ] + }, + "public.trust": { + "name": "trust", + "schema": "public", + "values": [ + "green", + "blue", + "yellow", + "red" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/drizzle/meta/0019_snapshot.json b/drizzle/meta/0019_snapshot.json new file mode 100644 index 0000000..a1e85ba --- /dev/null +++ b/drizzle/meta/0019_snapshot.json @@ -0,0 +1,1101 @@ +{ + "id": "2406dbb1-cdda-4c04-b6f1-363172327705", + "prevId": "f03cfd63-e7c6-44fa-902c-2f9237b9ee96", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.devlog": { + "name": "devlog", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timeSpent": { + "name": "timeSpent", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "devlog_userId_user_id_fk": { + "name": "devlog_userId_user_id_fk", + "tableFrom": "devlog", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "devlog_projectId_project_id_fk": { + "name": "devlog_projectId_project_id_fk", + "tableFrom": "devlog", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.legion_review": { + "name": "legion_review", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "feedback": { + "name": "feedback", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "filamentUsed": { + "name": "filamentUsed", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "legion_action", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "legion_review_userId_user_id_fk": { + "name": "legion_review_userId_user_id_fk", + "tableFrom": "legion_review", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "legion_review_projectId_project_id_fk": { + "name": "legion_review_projectId_project_id_fk", + "tableFrom": "legion_review", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.market_item": { + "name": "market_item", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "minRequiredShopScore": { + "name": "minRequiredShopScore", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "minShopScore": { + "name": "minShopScore", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "maxShopScore": { + "name": "maxShopScore", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "maxPrice": { + "name": "maxPrice", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "minPrice": { + "name": "minPrice", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "isPublic": { + "name": "isPublic", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "market_item_createdBy_user_id_fk": { + "name": "market_item_createdBy_user_id_fk", + "tableFrom": "market_item", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.market_item_order": { + "name": "market_item_order", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "addressId": { + "name": "addressId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bricksPaid": { + "name": "bricksPaid", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "market_order_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'awaiting_approval'" + }, + "userNotes": { + "name": "userNotes", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "market_item_order_userId_user_id_fk": { + "name": "market_item_order_userId_user_id_fk", + "tableFrom": "market_item_order", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.project": { + "name": "project", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "editorFileType": { + "name": "editorFileType", + "type": "editor_file_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "editorUrl": { + "name": "editorUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uploadedFileUrl": { + "name": "uploadedFileUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "modelFile": { + "name": "modelFile", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'building'" + }, + "printedBy": { + "name": "printedBy", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "submittedToAirtable": { + "name": "submittedToAirtable", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "project_userId_user_id_fk": { + "name": "project_userId_user_id_fk", + "tableFrom": "project", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "project_printedBy_user_id_fk": { + "name": "project_printedBy_user_id_fk", + "tableFrom": "project", + "tableTo": "user", + "columnsFrom": [ + "printedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "session_userId_user_id_fk": { + "name": "session_userId_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ship": { + "name": "ship", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "editorFileType": { + "name": "editorFileType", + "type": "editor_file_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "editorUrl": { + "name": "editorUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uploadedFileUrl": { + "name": "uploadedFileUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "modelFile": { + "name": "modelFile", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "ship_userId_user_id_fk": { + "name": "ship_userId_user_id_fk", + "tableFrom": "ship", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "ship_projectId_project_id_fk": { + "name": "ship_projectId_project_id_fk", + "tableFrom": "ship", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.t1_review": { + "name": "t1_review", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "feedback": { + "name": "feedback", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "t1_review_action", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "t1_review_userId_user_id_fk": { + "name": "t1_review_userId_user_id_fk", + "tableFrom": "t1_review", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "t1_review_projectId_project_id_fk": { + "name": "t1_review_projectId_project_id_fk", + "tableFrom": "t1_review", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.t2_review": { + "name": "t2_review", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "feedback": { + "name": "feedback", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "currencyMultiplier": { + "name": "currencyMultiplier", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "t2_review_userId_user_id_fk": { + "name": "t2_review_userId_user_id_fk", + "tableFrom": "t2_review", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "t2_review_projectId_project_id_fk": { + "name": "t2_review_projectId_project_id_fk", + "tableFrom": "t2_review", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "idvId": { + "name": "idvId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "idvToken": { + "name": "idvToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "slackId": { + "name": "slackId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "profilePicture": { + "name": "profilePicture", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hackatimeTrust": { + "name": "hackatimeTrust", + "type": "hackatime_trust", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "trust": { + "name": "trust", + "type": "trust", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'blue'" + }, + "clay": { + "name": "clay", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "brick": { + "name": "brick", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "shopScore": { + "name": "shopScore", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "hasBasePrinter": { + "name": "hasBasePrinter", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "hasT1Review": { + "name": "hasT1Review", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "hasT2Review": { + "name": "hasT2Review", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "hasAdmin": { + "name": "hasAdmin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "isPrinter": { + "name": "isPrinter", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "lastLoginAt": { + "name": "lastLoginAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_idvId_unique": { + "name": "user_idvId_unique", + "nullsNotDistinct": false, + "columns": [ + "idvId" + ] + }, + "user_slackId_unique": { + "name": "user_slackId_unique", + "nullsNotDistinct": false, + "columns": [ + "slackId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.editor_file_type": { + "name": "editor_file_type", + "schema": "public", + "values": [ + "url", + "upload" + ] + }, + "public.hackatime_trust": { + "name": "hackatime_trust", + "schema": "public", + "values": [ + "green", + "blue", + "yellow", + "red" + ] + }, + "public.legion_action": { + "name": "legion_action", + "schema": "public", + "values": [ + "mark_for_printing", + "unmark_for_printing", + "print", + "add_comment", + "reject", + "already_printed" + ] + }, + "public.market_order_status": { + "name": "market_order_status", + "schema": "public", + "values": [ + "awaiting_approval", + "approved", + "fulfilled", + "denied", + "refunded" + ] + }, + "public.project_audit_log_type": { + "name": "project_audit_log_type", + "schema": "public", + "values": [ + "create", + "update", + "delete" + ] + }, + "public.status": { + "name": "status", + "schema": "public", + "values": [ + "building", + "submitted", + "t1_approved", + "printing", + "printed", + "t2_approved", + "finalized", + "rejected", + "rejected_locked" + ] + }, + "public.t1_review_action": { + "name": "t1_review_action", + "schema": "public", + "values": [ + "approve", + "approve_no_print", + "add_comment", + "reject", + "reject_lock" + ] + }, + "public.trust": { + "name": "trust", + "schema": "public", + "values": [ + "green", + "blue", + "yellow", + "red" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index a7d9ba3..36ecf62 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -113,6 +113,34 @@ "when": 1766163214868, "tag": "0015_flaky_james_howlett", "breakpoints": true + }, + { + "idx": 16, + "version": "7", + "when": 1766430469939, + "tag": "0016_lazy_kinsey_walden", + "breakpoints": true + }, + { + "idx": 17, + "version": "7", + "when": 1766436733390, + "tag": "0017_long_greymalkin", + "breakpoints": true + }, + { + "idx": 18, + "version": "7", + "when": 1766613036394, + "tag": "0018_sour_roughhouse", + "breakpoints": true + }, + { + "idx": 19, + "version": "7", + "when": 1766613085822, + "tag": "0019_wide_gamora", + "breakpoints": true } ] } \ No newline at end of file diff --git a/src/lib/server/db/schema.ts b/src/lib/server/db/schema.ts index 186e960..f34ab02 100644 --- a/src/lib/server/db/schema.ts +++ b/src/lib/server/db/schema.ts @@ -29,6 +29,7 @@ export const user = pgTable('user', { shopScore: real().notNull().default(0), hasBasePrinter: boolean().notNull().default(false), + // bricksSpentOnUpgrades: integer().notNull().default(0), hasT1Review: boolean().notNull().default(false), // Has access to t1 review hasT2Review: boolean().notNull().default(false), // Has access to t2 review @@ -203,6 +204,91 @@ export const devlog = pgTable('devlog', { updatedAt: timestamp().notNull().defaultNow() }); +// Market + +export const marketItem = pgTable('market_item', { + id: serial().primaryKey(), + createdBy: integer().references(() => user.id), + + name: text().notNull(), + description: text().notNull(), + image: text().notNull(), + + minRequiredShopScore: integer().notNull().default(0), + + minShopScore: integer().notNull(), + maxShopScore: integer().notNull(), // Score after which price becomes constant + maxPrice: integer().notNull(), + minPrice: integer().notNull(), + + isPublic: boolean().notNull().default(false), + + deleted: boolean().notNull().default(false), + createdAt: timestamp().notNull().defaultNow(), + updatedAt: timestamp().notNull().defaultNow() +}); + +export const marketOrderStatus = pgEnum('market_order_status', [ + 'awaiting_approval', + 'approved', + 'fulfilled', + 'denied', + 'refunded' +]); + +export const marketItemOrder = pgTable('market_item_order', { + id: serial().primaryKey(), + userId: integer().references(() => user.id).notNull(), + + addressId: text().notNull(), + bricksPaid: integer().notNull(), + + status: marketOrderStatus().notNull().default('awaiting_approval'), + userNotes: text().notNull(), + notes: text(), // stuff like tracking code, shown to user + + deleted: boolean().notNull().default(false), + createdAt: timestamp().notNull().defaultNow() +}); + +// export const marketBasePrinter = pgTable('market_base_printer', { +// id: serial().primaryKey(), +// createdBy: integer().references(() => user.id), + +// name: text().notNull(), +// description: text().notNull(), +// image: text().notNull(), + +// minRequiredShopScore: integer().notNull().default(0), +// isPublic: boolean().notNull().default(false), + +// deleted: boolean().notNull().default(false), +// createdAt: timestamp().notNull().defaultNow(), +// updatedAt: timestamp().notNull().defaultNow() +// }); + +// export const marketPrinterUpgrade = pgTable('market_printer_upgrade', { +// id: serial().primaryKey(), +// createdBy: integer().references(() => user.id), + +// name: text().notNull(), +// description: text().notNull(), +// image: text().notNull(), + +// minRequiredShopScore: integer().notNull().default(0), + +// minShopScore: integer().notNull(), +// maxShopScore: integer().notNull(), // Score after which price becomes constant +// maxPrice: integer().notNull(), +// minPrice: integer().notNull(), + +// isPublic: boolean().notNull().default(false), + +// deleted: boolean().notNull().default(false), +// createdAt: timestamp().notNull().defaultNow(), +// updatedAt: timestamp().notNull().defaultNow() +// }); + export type Session = typeof session.$inferSelect; export type User = typeof user.$inferSelect; export type Project = typeof project.$inferSelect; @@ -210,3 +296,5 @@ export type Project = typeof project.$inferSelect; export type T1Review = typeof t1Review.$inferSelect; export type LegionReview = typeof legionReview.$inferSelect; export type T2Review = typeof t2Review.$inferSelect; + +export type MarketItem = typeof marketItem.$inferSelect; diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 1677fae..d3d0eef 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -55,3 +55,26 @@ export default function fileSizeFromUrl(url: string): Promise { export function formatMinutes(mins: number | null) { return Math.floor((mins ?? 0) / 60) + 'h ' + Math.floor((mins ?? 0) % 60) + 'min'; } + +export function calculateMarketPrice( + minPrice: number, + maxPrice: number, + minShopScore: number, + maxShopScore: number, + userShopScore: number +) { + if (userShopScore <= minShopScore) { + return maxPrice; + } else if (userShopScore >= maxShopScore) { + return minPrice; + } else { + const priceDiff = maxPrice - minPrice; + const shopScoreDiff = maxShopScore - minShopScore; + const m = priceDiff / shopScoreDiff; // diff_y/diff_x + + const shopScoreRemainder = userShopScore - minShopScore; + + // y = -mx + c + return Math.round(-m * shopScoreRemainder + maxPrice); + } +} diff --git a/src/routes/auth/create-hackatime-account/+page.svelte b/src/routes/auth/create-hackatime-account/+page.svelte index e722062..62d3c53 100644 --- a/src/routes/auth/create-hackatime-account/+page.svelte +++ b/src/routes/auth/create-hackatime-account/+page.svelte @@ -7,7 +7,7 @@

Hackatime account not found

-

Make sure you have a Hackatime account associated with your Hack Club Auth or Slack account.

+

Make sure you have a Hackatime account associated with your Slack account.

Make one? Try again
\ No newline at end of file diff --git a/src/routes/dashboard/admin/admin/+page.server.ts b/src/routes/dashboard/admin/admin/+page.server.ts new file mode 100644 index 0000000..f3c1446 --- /dev/null +++ b/src/routes/dashboard/admin/admin/+page.server.ts @@ -0,0 +1,12 @@ +import { error } from '@sveltejs/kit'; + +export async function load({ locals }) { + if (!locals.user) { + throw error(500); + } + if (!locals.user.hasAdmin) { + throw error(403, { message: 'oi get out' }); + } + + return {}; +} diff --git a/src/routes/dashboard/admin/admin/+page.svelte b/src/routes/dashboard/admin/admin/+page.svelte index 3876834..06b91fc 100644 --- a/src/routes/dashboard/admin/admin/+page.svelte +++ b/src/routes/dashboard/admin/admin/+page.svelte @@ -1,6 +1,6 @@ @@ -29,5 +29,14 @@

Stats

+ +
+ +
+

Market

+
diff --git a/src/routes/dashboard/admin/admin/market/+page.server.ts b/src/routes/dashboard/admin/admin/market/+page.server.ts new file mode 100644 index 0000000..e415207 --- /dev/null +++ b/src/routes/dashboard/admin/admin/market/+page.server.ts @@ -0,0 +1,39 @@ +import { db } from '$lib/server/db/index.js'; +import { marketItem } from '$lib/server/db/schema.js'; +import { error } from '@sveltejs/kit'; +import { eq } from 'drizzle-orm'; +import type { Actions } from './$types'; + +export async function load({ locals }) { + if (!locals.user?.hasAdmin) { + throw error(403, { message: 'oi get out' }); + } + + const marketItems = await db.select().from(marketItem).where(eq(marketItem.deleted, false)); + + return { + marketItems + }; +} + +export const actions: Actions = { + delete: async ({ request, locals }) => { + if (!locals.user?.hasAdmin) { + throw error(403, { message: 'oi get out' }); + } + + const formData = await request.formData(); + const id = parseInt(formData.get('id')?.toString() || '0'); + + if (!id) { + throw error(400, { message: 'Missing item id' }); + } + + await db + .update(marketItem) + .set({ deleted: true, updatedAt: new Date() }) + .where(eq(marketItem.id, id)); + + return { success: true }; + } +}; diff --git a/src/routes/dashboard/admin/admin/market/+page.svelte b/src/routes/dashboard/admin/admin/market/+page.svelte new file mode 100644 index 0000000..4ebb74f --- /dev/null +++ b/src/routes/dashboard/admin/admin/market/+page.svelte @@ -0,0 +1,64 @@ + + + + +

Market

+ +
+ Add item +
+ +
+
+

Public

+ {#if publicItems.length === 0} +

No public items yet.

+ {:else} +
+ {#each publicItems as item (item.id)} + + {/each} +
+ {/if} +
+ +
+

Private

+ {#if privateItems.length === 0} +

Nothing to see here.

+ {:else} +
+ {#each privateItems as item (item.id)} + + {/each} +
+ {/if} +
+
diff --git a/src/routes/dashboard/admin/admin/market/MarketItem.svelte b/src/routes/dashboard/admin/admin/market/MarketItem.svelte new file mode 100644 index 0000000..2e4a587 --- /dev/null +++ b/src/routes/dashboard/admin/admin/market/MarketItem.svelte @@ -0,0 +1,22 @@ + + +
+
+ {item.name} +
+

{item.name}

+

{item.description}

+

Price: {item.maxPrice}-{item.minPrice}

+

+ Market score: {item.minRequiredShopScore}, {item.minShopScore}-{item.maxShopScore} +

+ + {#if showButtons} +
+ Edit + Delete +
+ {/if} +
diff --git a/src/routes/dashboard/admin/admin/market/item/[id]/delete/+page.server.ts b/src/routes/dashboard/admin/admin/market/item/[id]/delete/+page.server.ts new file mode 100644 index 0000000..4ec1e88 --- /dev/null +++ b/src/routes/dashboard/admin/admin/market/item/[id]/delete/+page.server.ts @@ -0,0 +1,52 @@ +import { db } from '$lib/server/db/index.js'; +import { marketItem } from '$lib/server/db/schema.js'; +import { error, redirect } from '@sveltejs/kit'; +import type { Actions } from './$types'; +import { eq, and } from 'drizzle-orm'; + +export async function load({ locals, params }) { + if (!locals.user?.hasAdmin) { + throw error(403, { message: 'oi get out' }); + } + + const id: number = parseInt(params.id); + + const [item] = await db + .select() + .from(marketItem) + .where(and(eq(marketItem.deleted, false), eq(marketItem.id, id))); + + if (!item) { + return error(404, { message: 'item not found' }); + } + + return { + marketItem: item + }; +} + +export const actions: Actions = { + default: async ({ locals, params }) => { + if (!locals.user?.hasAdmin) { + throw error(403, { message: 'oi get out' }); + } + + const id: number = parseInt(params.id); + + const [item] = await db + .select() + .from(marketItem) + .where(and(eq(marketItem.deleted, false), eq(marketItem.id, id))); + + if (!item) { + return error(404, { message: 'item not found' }); + } + + await db + .update(marketItem) + .set({ deleted: true, updatedAt: new Date() }) + .where(eq(marketItem.id, id)); + + return redirect(302, '/dashboard/admin/admin/market'); + } +}; diff --git a/src/routes/dashboard/admin/admin/market/item/[id]/delete/+page.svelte b/src/routes/dashboard/admin/admin/market/item/[id]/delete/+page.svelte new file mode 100644 index 0000000..133f51a --- /dev/null +++ b/src/routes/dashboard/admin/admin/market/item/[id]/delete/+page.svelte @@ -0,0 +1,35 @@ + + + + +

Delete market item

+ +
+ +
+ +
{ + formPending = true; + return async ({ update }) => { + await update(); + formPending = false; + }; + }} +> +

Are you sure you want to delete this? If possible, make it private instead.

+
+ Cancel + +
+
diff --git a/src/routes/dashboard/admin/admin/market/item/[id]/edit/+page.server.ts b/src/routes/dashboard/admin/admin/market/item/[id]/edit/+page.server.ts new file mode 100644 index 0000000..8a1deb9 --- /dev/null +++ b/src/routes/dashboard/admin/admin/market/item/[id]/edit/+page.server.ts @@ -0,0 +1,89 @@ +import { db } from '$lib/server/db/index.js'; +import { marketItem } from '$lib/server/db/schema.js'; +import { error, redirect } from '@sveltejs/kit'; +import type { Actions } from './$types'; +import { eq, and } from 'drizzle-orm'; + +export async function load({ locals, params }) { + if (!locals.user?.hasAdmin) { + throw error(403, { message: 'oi get out' }); + } + + const id: number = parseInt(params.id); + + const [item] = await db + .select() + .from(marketItem) + .where(and(eq(marketItem.deleted, false), eq(marketItem.id, id))); + + if (!item) { + return error(404, { message: 'item not found' }); + } + + return { + marketItem: item + }; +} + +export const actions: Actions = { + default: async ({ request, locals, params }) => { + if (!locals.user?.hasAdmin) { + throw error(403, { message: 'oi get out' }); + } + + const id: number = parseInt(params.id); + + const [item] = await db + .select() + .from(marketItem) + .where(and(eq(marketItem.deleted, false), eq(marketItem.id, id))); + + if (!item) { + return error(404, { message: 'item not found' }); + } + + const formData = await request.formData(); + const name = formData.get('name')?.toString(); + const description = formData.get('description')?.toString(); + const image = formData.get('image')?.toString(); + const minRequiredShopScore = parseInt(formData.get('minRequiredShopScore')?.toString() || '0'); + const minShopScore = parseInt(formData.get('minShopScore')?.toString() || '0'); + const maxShopScore = parseInt(formData.get('maxShopScore')?.toString() || '0'); + const minPrice = parseInt(formData.get('minPrice')?.toString() || '0'); + const maxPrice = parseInt(formData.get('maxPrice')?.toString() || '0'); + const isPublic = formData.get('isPublic') === 'on'; + + // Don't really need to implement proper validation, page is admins only + + if (!name || !description || !image) { + throw error(400, { message: 'Missing required fields' }); + } + + if (maxPrice < minPrice) { + throw error(400, { message: 'Max price must be greater than or equal to min price' }); + } + + if (maxShopScore < minShopScore) { + throw error(400, { + message: 'Max shop score must be greater than or equal to min shop score' + }); + } + + await db + .update(marketItem) + .set({ + name, + description, + image, + minRequiredShopScore, + minShopScore, + maxShopScore, + minPrice, + maxPrice, + isPublic + }) + .where(eq(marketItem.id, id)); + + return redirect(302, '/dashboard/admin/admin/market'); + } +}; diff --git a/src/routes/dashboard/admin/admin/market/item/[id]/edit/+page.svelte b/src/routes/dashboard/admin/admin/market/item/[id]/edit/+page.svelte new file mode 100644 index 0000000..aafe840 --- /dev/null +++ b/src/routes/dashboard/admin/admin/market/item/[id]/edit/+page.svelte @@ -0,0 +1,150 @@ + + + + +

Edit market item

+ +
+ +
+ +
{ + formPending = true; + return async ({ update }) => { + await update(); + formPending = false; + }; + }} +> + + + + + + + + +
+

Pricing

+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ + + +
+ + Cancel +
+
diff --git a/src/routes/dashboard/admin/admin/market/item/create/+page.server.ts b/src/routes/dashboard/admin/admin/market/item/create/+page.server.ts new file mode 100644 index 0000000..23b2462 --- /dev/null +++ b/src/routes/dashboard/admin/admin/market/item/create/+page.server.ts @@ -0,0 +1,62 @@ +import { db } from '$lib/server/db/index.js'; +import { marketItem } from '$lib/server/db/schema.js'; +import { error, redirect } from '@sveltejs/kit'; +import type { Actions } from './$types'; + +export async function load({ locals }) { + if (!locals.user?.hasAdmin) { + throw error(403, { message: 'oi get out' }); + } + + return {}; +} + +export const actions: Actions = { + default: async ({ request, locals }) => { + if (!locals.user?.hasAdmin) { + throw error(403, { message: 'oi get out' }); + } + + const formData = await request.formData(); + const name = formData.get('name')?.toString(); + const description = formData.get('description')?.toString(); + const image = formData.get('image')?.toString(); + const minRequiredShopScore = parseInt(formData.get('minRequiredShopScore')?.toString() || '0'); + const minShopScore = parseInt(formData.get('minShopScore')?.toString() || '0'); + const maxShopScore = parseInt(formData.get('maxShopScore')?.toString() || '0'); + const minPrice = parseInt(formData.get('minPrice')?.toString() || '0'); + const maxPrice = parseInt(formData.get('maxPrice')?.toString() || '0'); + const isPublic = formData.get('isPublic') === 'on'; + + // Don't need to implement proper validation, page is admins only + + if (!name || !description || !image) { + throw error(400, { message: 'Missing required fields' }); + } + + if (maxPrice < minPrice) { + throw error(400, { message: 'Max price must be greater than or equal to min price' }); + } + + if (maxShopScore < minShopScore) { + throw error(400, { + message: 'Max shop score must be greater than or equal to min shop score' + }); + } + + await db.insert(marketItem).values({ + createdBy: locals.user.id, + name, + description, + image, + minRequiredShopScore, + minShopScore, + maxShopScore, + minPrice, + maxPrice, + isPublic + }); + + return redirect(302, '/dashboard/admin/admin/market'); + } +}; diff --git a/src/routes/dashboard/admin/admin/market/item/create/+page.svelte b/src/routes/dashboard/admin/admin/market/item/create/+page.svelte new file mode 100644 index 0000000..2bc7af8 --- /dev/null +++ b/src/routes/dashboard/admin/admin/market/item/create/+page.svelte @@ -0,0 +1,139 @@ + + + + +

Add market item

+ +
{ + formPending = true; + return async ({ update }) => { + await update(); + formPending = false; + }; + }} +> + + + + + + + + +
+

Pricing

+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ + + +
+ + Cancel +
+
diff --git a/src/routes/dashboard/admin/admin/stats/+page.server.ts b/src/routes/dashboard/admin/admin/stats/+page.server.ts index 2156bfe..09cbd08 100644 --- a/src/routes/dashboard/admin/admin/stats/+page.server.ts +++ b/src/routes/dashboard/admin/admin/stats/+page.server.ts @@ -8,7 +8,7 @@ export async function load({ locals }) { throw error(500); } if (!locals.user.hasAdmin) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const [users] = await db diff --git a/src/routes/dashboard/admin/admin/users/+page.server.ts b/src/routes/dashboard/admin/admin/users/+page.server.ts index 37403cb..e728b17 100644 --- a/src/routes/dashboard/admin/admin/users/+page.server.ts +++ b/src/routes/dashboard/admin/admin/users/+page.server.ts @@ -8,7 +8,7 @@ export async function load({ locals }) { throw error(500); } if (!locals.user.hasAdmin) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const users = await db.select().from(user); @@ -24,7 +24,7 @@ export const actions = { throw error(500); } if (!locals.user.hasAdmin) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } await db.delete(session); diff --git a/src/routes/dashboard/admin/admin/users/+page.svelte b/src/routes/dashboard/admin/admin/users/+page.svelte index 9d85401..455aab6 100644 --- a/src/routes/dashboard/admin/admin/users/+page.svelte +++ b/src/routes/dashboard/admin/admin/users/+page.svelte @@ -13,7 +13,7 @@ let logoutEveryonePending = $state(false); - +
diff --git a/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts b/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts index 0e277c6..554a98f 100644 --- a/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts +++ b/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts @@ -18,7 +18,7 @@ export async function load({ locals, params }) { throw error(500); } if (!locals.user.hasAdmin) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const id: number = parseInt(params.id); @@ -49,7 +49,7 @@ export const actions = { throw error(500); } if (!locals.user.hasAdmin) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const id: number = parseInt(params.id); @@ -86,7 +86,7 @@ export const actions = { throw error(500); } if (!locals.user.hasAdmin) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const id: number = parseInt(params.id); @@ -137,7 +137,7 @@ export const actions = { throw error(500); } if (!locals.user.hasAdmin) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const id: number = parseInt(params.id); @@ -195,7 +195,7 @@ export const actions = { throw error(500); } if (!locals.user.hasAdmin) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const id: number = parseInt(params.id); @@ -221,7 +221,7 @@ export const actions = { throw error(500); } if (!locals.user.hasAdmin) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const id: number = parseInt(params.id); @@ -252,7 +252,7 @@ export const actions = { // Pretty important line if (!locals.user.hasAdmin) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const id: number = parseInt(params.id); diff --git a/src/routes/dashboard/admin/print/+page.server.ts b/src/routes/dashboard/admin/print/+page.server.ts index f246422..3b91488 100644 --- a/src/routes/dashboard/admin/print/+page.server.ts +++ b/src/routes/dashboard/admin/print/+page.server.ts @@ -10,7 +10,7 @@ export async function load({ locals }) { throw error(500); } if (!locals.user.isPrinter) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const projects = await getProjects(['t1_approved'], [], []); @@ -47,7 +47,7 @@ export const actions = { throw error(500); } if (!locals.user.isPrinter) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const data = await request.formData(); diff --git a/src/routes/dashboard/admin/print/[id]/+page.server.ts b/src/routes/dashboard/admin/print/[id]/+page.server.ts index 8eb27a6..a59be0a 100644 --- a/src/routes/dashboard/admin/print/[id]/+page.server.ts +++ b/src/routes/dashboard/admin/print/[id]/+page.server.ts @@ -12,7 +12,7 @@ export async function load({ locals, params }) { throw error(500); } if (!locals.user.isPrinter) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const id: number = parseInt(params.id); @@ -96,7 +96,7 @@ export const actions = { throw error(500); } if (!locals.user.isPrinter) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const currentlyPrinting = await getCurrentlyPrinting(locals.user); @@ -148,7 +148,7 @@ export const actions = { throw error(500); } if (!locals.user.isPrinter) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const id: number = parseInt(params.id); @@ -193,7 +193,7 @@ export const actions = { throw error(500); } if (!locals.user.isPrinter) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const currentlyPrinting = await getCurrentlyPrinting(locals.user); @@ -273,7 +273,7 @@ export const actions = { throw error(500); } if (!locals.user.isPrinter) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const id: number = parseInt(params.id); diff --git a/src/routes/dashboard/admin/review/+page.server.ts b/src/routes/dashboard/admin/review/+page.server.ts index 97dcaec..1abf3bf 100644 --- a/src/routes/dashboard/admin/review/+page.server.ts +++ b/src/routes/dashboard/admin/review/+page.server.ts @@ -9,7 +9,7 @@ export async function load({ locals }) { throw error(500); } if (!locals.user.hasT1Review) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const projects = await getProjects(['submitted'], [], []); @@ -43,7 +43,7 @@ export const actions = { throw error(500); } if (!locals.user.hasT1Review) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const data = await request.formData(); diff --git a/src/routes/dashboard/admin/review/[id]/+page.server.ts b/src/routes/dashboard/admin/review/[id]/+page.server.ts index 78d4594..3250951 100644 --- a/src/routes/dashboard/admin/review/[id]/+page.server.ts +++ b/src/routes/dashboard/admin/review/[id]/+page.server.ts @@ -11,7 +11,7 @@ export async function load({ locals, params }) { throw error(500); } if (!locals.user.hasT1Review) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const id: number = parseInt(params.id); @@ -89,7 +89,7 @@ export const actions = { throw error(500); } if (!locals.user.hasT1Review) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const id: number = parseInt(params.id); diff --git a/src/routes/dashboard/admin/ysws-review/+page.server.ts b/src/routes/dashboard/admin/ysws-review/+page.server.ts index 529f686..64b2711 100644 --- a/src/routes/dashboard/admin/ysws-review/+page.server.ts +++ b/src/routes/dashboard/admin/ysws-review/+page.server.ts @@ -9,7 +9,7 @@ export async function load({ locals }) { throw error(500); } if (!locals.user.hasT2Review) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const projects = await getProjects(['printed'], [], []); @@ -43,7 +43,7 @@ export const actions = { throw error(500); } if (!locals.user.hasT2Review) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const data = await request.formData(); diff --git a/src/routes/dashboard/admin/ysws-review/[id]/+page.server.ts b/src/routes/dashboard/admin/ysws-review/[id]/+page.server.ts index 29f4e69..d27142f 100644 --- a/src/routes/dashboard/admin/ysws-review/[id]/+page.server.ts +++ b/src/routes/dashboard/admin/ysws-review/[id]/+page.server.ts @@ -15,7 +15,7 @@ export async function load({ locals, params }) { throw error(500); } if (!locals.user.hasT2Review) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const id: number = parseInt(params.id); @@ -96,7 +96,7 @@ export const actions = { throw error(500); } if (!locals.user.hasT2Review) { - throw error(403, { message: 'get out, peasant' }); + throw error(403, { message: 'oi get out' }); } const id: number = parseInt(params.id); diff --git a/src/routes/dashboard/explore/+page.server.ts b/src/routes/dashboard/explore/+page.server.ts index 68871eb..3d2d4de 100644 --- a/src/routes/dashboard/explore/+page.server.ts +++ b/src/routes/dashboard/explore/+page.server.ts @@ -1,36 +1,12 @@ -import { db } from '$lib/server/db/index.js'; -import { devlog, project, user } from '$lib/server/db/schema.js'; -import { eq, desc } from 'drizzle-orm'; +import { DEVLOGS_PAGE_SIZE, fetchExploreDevlogs } from './devlogs.js'; -// TODO: pagination export async function load() { - const devlogs = await db - .select({ - devlog: { - id: devlog.id, - description: devlog.description, - image: devlog.image, - model: devlog.model, - timeSpent: devlog.timeSpent, - createdAt: devlog.createdAt - }, - project: { - id: project.id, - name: project.name - }, - user: { - id: user.id, - name: user.name - } - }) - .from(devlog) - .innerJoin(project, eq(devlog.projectId, project.id)) - .innerJoin(user, eq(devlog.userId, user.id)) - .where(eq(devlog.deleted, false)) - .orderBy(desc(devlog.createdAt)) - .limit(15); + const devlogs = await fetchExploreDevlogs(0); + const nextOffset = devlogs.length; - return { - devlogs - }; + return { + devlogs, + nextOffset, + hasMore: devlogs.length === DEVLOGS_PAGE_SIZE + }; } diff --git a/src/routes/dashboard/explore/+page.svelte b/src/routes/dashboard/explore/+page.svelte index a56b5ad..2ac2c3f 100644 --- a/src/routes/dashboard/explore/+page.svelte +++ b/src/routes/dashboard/explore/+page.svelte @@ -1,16 +1,84 @@

Explore

+
- {#if data.devlogs.length == 0} + {#if devlogs.length == 0}
No journal entries yet
{:else} - {#each data.devlogs as devlog} + {#each devlogs as devlog (devlog.devlog.id)} {/each} + +
+ + {#if loadingMore} +

Loading more...

+ {/if} + + {#if loadError} +
+ {loadError} + +
+ {/if} + + {#if !hasMore && !loadingMore} +

You're caught up.

+ {/if} {/if}
\ No newline at end of file diff --git a/src/routes/dashboard/explore/+server.ts b/src/routes/dashboard/explore/+server.ts new file mode 100644 index 0000000..5bb2f19 --- /dev/null +++ b/src/routes/dashboard/explore/+server.ts @@ -0,0 +1,20 @@ +import { json } from '@sveltejs/kit'; +import { DEVLOGS_PAGE_SIZE, fetchExploreDevlogs } from './devlogs.js'; + +export async function GET({ url }) { + const offsetParam = url.searchParams.get('offset'); + const offset = offsetParam ? Number.parseInt(offsetParam, 10) : 0; + + if (!Number.isFinite(offset) || offset < 0) { + return json({ error: 'Invalid offset' }, { status: 400 }); + } + + const devlogs = await fetchExploreDevlogs(offset); + const nextOffset = offset + devlogs.length; + + return json({ + devlogs, + nextOffset, + hasMore: devlogs.length === DEVLOGS_PAGE_SIZE + }); +} diff --git a/src/routes/dashboard/explore/devlogs.ts b/src/routes/dashboard/explore/devlogs.ts new file mode 100644 index 0000000..595fd32 --- /dev/null +++ b/src/routes/dashboard/explore/devlogs.ts @@ -0,0 +1,34 @@ +import { db } from '$lib/server/db/index.js'; +import { devlog, project, user } from '$lib/server/db/schema.js'; +import { desc, eq } from 'drizzle-orm'; + +export const DEVLOGS_PAGE_SIZE = 15; + +export async function fetchExploreDevlogs(offset: number, limit = DEVLOGS_PAGE_SIZE) { + return db + .select({ + devlog: { + id: devlog.id, + description: devlog.description, + image: devlog.image, + model: devlog.model, + timeSpent: devlog.timeSpent, + createdAt: devlog.createdAt + }, + project: { + id: project.id, + name: project.name + }, + user: { + id: user.id, + name: user.name + } + }) + .from(devlog) + .innerJoin(project, eq(devlog.projectId, project.id)) + .innerJoin(user, eq(devlog.userId, user.id)) + .where(eq(devlog.deleted, false)) + .orderBy(desc(devlog.createdAt), desc(devlog.id)) + .offset(offset) + .limit(limit); +} diff --git a/src/routes/dashboard/market/+page.server.ts b/src/routes/dashboard/market/+page.server.ts new file mode 100644 index 0000000..8ab074e --- /dev/null +++ b/src/routes/dashboard/market/+page.server.ts @@ -0,0 +1,48 @@ +import { db } from '$lib/server/db/index.js'; +import { marketItem } from '$lib/server/db/schema.js'; +import { calculateMarketPrice } from '$lib/utils'; +import { error } from '@sveltejs/kit'; +import { eq, and } from 'drizzle-orm'; + +export async function load({ locals }) { + if (!locals.user) { + throw error(500); + } + + const marketItems = await db + .select({ + id: marketItem.id, + name: marketItem.name, + description: marketItem.description, + image: marketItem.image, + minPrice: marketItem.minPrice, + maxPrice: marketItem.maxPrice, + minShopScore: marketItem.minShopScore, + maxShopScore: marketItem.maxShopScore, + minRequiredShopScore: marketItem.minRequiredShopScore + }) + .from(marketItem) + .where(and(eq(marketItem.deleted, false), eq(marketItem.isPublic, true))) + .orderBy(marketItem.maxPrice); + + const shopScore = locals.user.shopScore; + + const marketItemsWithPrice = marketItems + .map((item) => { + const computedPrice = calculateMarketPrice( + item.minPrice, + item.maxPrice, + item.minShopScore, + item.maxShopScore, + shopScore + ); + + const discountAmount = 1 - computedPrice / item.maxPrice; + return { ...item, computedPrice, discountAmount }; + }) + .sort((a, b) => a.computedPrice - b.computedPrice); + + return { + marketItems: marketItemsWithPrice + }; +} diff --git a/src/routes/dashboard/market/+page.svelte b/src/routes/dashboard/market/+page.svelte index 5bfdd80..2d531b8 100644 --- a/src/routes/dashboard/market/+page.svelte +++ b/src/routes/dashboard/market/+page.svelte @@ -1,66 +1,26 @@ -

Market

+

Market

-
-

The Market Opens In

-
-
- {timeLeft.days} - DAYS -
-
- {timeLeft.hours} - HOURS -
-
- {timeLeft.minutes} - MINS -
-
- {timeLeft.seconds} - SECS -
-
-
+{#if data.marketItems.length === 0} + +{:else} +

+ Market score: {data.user.shopScore} + (allows you to get stuff for cheaper and unlock more items!) +

- +
+ {#each data.marketItems as item (item.id)} + + {/each} +
+{/if} diff --git a/src/routes/dashboard/market/MarketItem.svelte b/src/routes/dashboard/market/MarketItem.svelte new file mode 100644 index 0000000..992cc27 --- /dev/null +++ b/src/routes/dashboard/market/MarketItem.svelte @@ -0,0 +1,53 @@ + + +
+
+ {item.name} +
+
+
+

{item.name}

+

{item.description}

+ {#if item.discountAmount > 0} +
+
{item.maxPrice} bricks
+
+ {item.computedPrice} bricks +
+
+
+
+ {Math.round(item.discountAmount * 100)}% off +
+
You save {item.maxPrice - item.computedPrice} bricks
+
+ {:else} +
{item.computedPrice} bricks
+ {/if} +
+ {#if showBuy} + + {/if} +
+
diff --git a/src/routes/dashboard/market/MarketTimer.svelte b/src/routes/dashboard/market/MarketTimer.svelte new file mode 100644 index 0000000..9aa1e6c --- /dev/null +++ b/src/routes/dashboard/market/MarketTimer.svelte @@ -0,0 +1,57 @@ + + +
+

The Market Opens In

+
+
+ {timeLeft.days} + DAYS +
+
+ {timeLeft.hours} + HOURS +
+
+ {timeLeft.minutes} + MINS +
+
+ {timeLeft.seconds} + SECS +
+
+
\ No newline at end of file diff --git a/src/routes/dashboard/market/item/[id]/+page.server.ts b/src/routes/dashboard/market/item/[id]/+page.server.ts new file mode 100644 index 0000000..cb3d970 --- /dev/null +++ b/src/routes/dashboard/market/item/[id]/+page.server.ts @@ -0,0 +1,148 @@ +import { db } from '$lib/server/db/index.js'; +import { marketItem, marketItemOrder, user } from '$lib/server/db/schema.js'; +import { decrypt } from '$lib/server/encryption'; +import { getUserData } from '$lib/server/idvUserData'; +import { calculateMarketPrice } from '$lib/utils'; +import { error, redirect } from '@sveltejs/kit'; +import { eq, and } from 'drizzle-orm'; +import type { Actions } from './$types'; + +export async function load({ locals, params }) { + if (!locals.user) { + throw error(500); + } + + const id: number = parseInt(params.id); + + const itemWithPrice = await getItemWithPrice(id, locals); + + let userDataError = false; + let addresses = null; + + if (locals.user.idvToken) { + const token = decrypt(locals.user.idvToken); + let userData = null; + + try { + userData = await getUserData(token); + } catch { + userDataError = true; + } + + addresses = userData?.addresses; + } else { + userDataError = true; + } + + return { + marketItem: itemWithPrice, + addresses, + userDataError + }; +} + +export const actions = { + default: async ({ locals, request, params }) => { + if (!locals.user) { + throw error(500); + } + + const id: number = parseInt(params.id); + + const data = await request.formData(); + const addressId = data.get('address')?.toString(); + const notes = data.get('notes')?.toString(); + + if (!addressId) { + throw error(400, { message: 'invalid address id' }); + } + + if (notes === null || notes === undefined || notes.length > 10000) { + throw error(400, { message: 'stop writing so much in notes' }); + } + + const itemWithPrice = await getItemWithPrice(id, locals); + + const token = decrypt(locals.user.idvToken!); + let userData = null; + + try { + userData = await getUserData(token); + } catch { + throw error(403, { message: 'failed to fetch address, try logging out and back in' }); + } + + const addresses: [{ id: string | null }] | null = userData?.addresses; + + if (!addresses || !addresses.length || addresses.length <= 0) { + throw error(400, { message: 'no addresses added on auth.hackclub.com' }); + } + + const address = addresses.find((addr) => addr.id! === addressId); + + if (!address) { + throw error(400, { message: 'chosen address not found' }); + } + + // Check if user can afford + if ( + itemWithPrice.computedPrice > locals.user.brick || + itemWithPrice.minRequiredShopScore > locals.user.shopScore + ) { + throw error(403, { message: "you can't afford this" }); + } + + await db + .update(user) + .set({ + brick: locals.user.brick - itemWithPrice.computedPrice + }) + .where(eq(user.id, locals.user.id)); + + await db.insert(marketItemOrder).values({ + userId: locals.user.id, + addressId, + bricksPaid: itemWithPrice.computedPrice, + userNotes: notes + }); + + // TODO: change this to orders page + return redirect(302, '/dashboard/market'); + } +} satisfies Actions; + +async function getItemWithPrice(id: number, locals: { user: { shopScore: number } | null }) { + const [item] = await db + .select({ + id: marketItem.id, + name: marketItem.name, + description: marketItem.description, + image: marketItem.image, + minPrice: marketItem.minPrice, + maxPrice: marketItem.maxPrice, + minShopScore: marketItem.minShopScore, + maxShopScore: marketItem.maxShopScore, + minRequiredShopScore: marketItem.minRequiredShopScore + }) + .from(marketItem) + .where(and(eq(marketItem.deleted, false), eq(marketItem.isPublic, true), eq(marketItem.id, id))) + .limit(1); + + if (!item) { + throw error(404, { message: 'market item not found' }); + } + + const shopScore = locals.user!.shopScore; + const computedPrice = calculateMarketPrice( + item.minPrice, + item.maxPrice, + item.minShopScore, + item.maxShopScore, + shopScore + ); + const discountAmount = 1 - computedPrice / item.maxPrice; + + const itemWithPrice = { ...item, computedPrice, discountAmount }; + + return itemWithPrice; +} diff --git a/src/routes/dashboard/market/item/[id]/+page.svelte b/src/routes/dashboard/market/item/[id]/+page.svelte new file mode 100644 index 0000000..6263c81 --- /dev/null +++ b/src/routes/dashboard/market/item/[id]/+page.svelte @@ -0,0 +1,104 @@ + + + + +

Buy?

+ +
+
+ +
+ +
+

Are you sure you want to buy this?

+

It'll cost you {data.marketItem.computedPrice} bricks

+ +
{ + formPending = true; + return async ({ update }) => { + await update(); + formPending = false; + }; + }} + > + + + + +
+ + +
+
+
diff --git a/src/routes/dashboard/users/[id]/+page.server.ts b/src/routes/dashboard/users/[id]/+page.server.ts index 9f2e2e2..eeae046 100644 --- a/src/routes/dashboard/users/[id]/+page.server.ts +++ b/src/routes/dashboard/users/[id]/+page.server.ts @@ -47,12 +47,14 @@ export async function load({ locals, params }) { slackId: requestedUser.slackId, profilePicture: requestedUser.profilePicture, name: requestedUser.name, - + isPrinter: requestedUser.isPrinter, hasT1Review: requestedUser.hasT1Review, hasT2Review: requestedUser.hasT2Review, hasAdmin: requestedUser.hasAdmin, + shopScore: requestedUser.shopScore, + createdAt: requestedUser.createdAt, lastLoginAt: requestedUser.id === locals.user?.id ? requestedUser.lastLoginAt : null }, diff --git a/src/routes/dashboard/users/[id]/+page.svelte b/src/routes/dashboard/users/[id]/+page.svelte index cba5280..14b5b27 100644 --- a/src/routes/dashboard/users/[id]/+page.svelte +++ b/src/routes/dashboard/users/[id]/+page.svelte @@ -34,6 +34,12 @@ {/if}

+

+ Market score: {data.requestedUser.shopScore} +

+