From 60aae30ab096b045afad29a14fec83f239fd5f73 Mon Sep 17 00:00:00 2001 From: Arca Ege Cengiz Date: Mon, 12 Jan 2026 00:21:07 +0000 Subject: [PATCH 1/3] Improve server side validation for order admin page --- .../admin/admin/orders/[id]/+page.server.ts | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/routes/dashboard/admin/admin/orders/[id]/+page.server.ts b/src/routes/dashboard/admin/admin/orders/[id]/+page.server.ts index 8fb97da..04d4d7b 100644 --- a/src/routes/dashboard/admin/admin/orders/[id]/+page.server.ts +++ b/src/routes/dashboard/admin/admin/orders/[id]/+page.server.ts @@ -108,7 +108,13 @@ export const actions = { .from(marketItemOrder) .leftJoin(marketItem, eq(marketItem.id, marketItemOrder.marketItemId)) .leftJoin(user, eq(user.id, marketItemOrder.userId)) - .where(and(eq(marketItemOrder.id, id), eq(marketItemOrder.deleted, false))) + .where( + and( + eq(marketItemOrder.id, id), + eq(marketItemOrder.deleted, false), + eq(marketItemOrder.status, 'awaiting_approval') + ) + ) .limit(1); if (!orderData) { @@ -162,7 +168,13 @@ export const actions = { .from(marketItemOrder) .leftJoin(marketItem, eq(marketItem.id, marketItemOrder.marketItemId)) .leftJoin(user, eq(user.id, marketItemOrder.userId)) - .where(and(eq(marketItemOrder.id, id), eq(marketItemOrder.deleted, false))) + .where( + and( + eq(marketItemOrder.id, id), + eq(marketItemOrder.deleted, false), + eq(marketItemOrder.status, 'awaiting_approval') + ) + ) .limit(1); if (!orderData) { @@ -220,7 +232,13 @@ export const actions = { .from(marketItemOrder) .leftJoin(marketItem, eq(marketItem.id, marketItemOrder.marketItemId)) .leftJoin(user, eq(user.id, marketItemOrder.userId)) - .where(and(eq(marketItemOrder.id, id), eq(marketItemOrder.deleted, false))) + .where( + and( + eq(marketItemOrder.id, id), + eq(marketItemOrder.deleted, false), + eq(marketItemOrder.status, 'awaiting_approval') + ) + ) .limit(1); if (!orderData) { From 60efbe29ccd87daa864e3880b7a69f3c93cba41f Mon Sep 17 00:00:00 2001 From: Arca Ege Cengiz Date: Mon, 12 Jan 2026 01:04:27 +0000 Subject: [PATCH 2/3] Add referral system --- drizzle/0027_motionless_colossus.sql | 1 + drizzle/meta/0027_snapshot.json | 1254 +++++++++++++++++ drizzle/meta/_journal.json | 7 + src/lib/server/db/schema.ts | 10 +- src/routes/+page.svelte | 7 + src/routes/auth/callback/+server.ts | 3 + .../admin/admin/users/[id]/+page.svelte | 3 + 7 files changed, 1282 insertions(+), 3 deletions(-) create mode 100644 drizzle/0027_motionless_colossus.sql create mode 100644 drizzle/meta/0027_snapshot.json diff --git a/drizzle/0027_motionless_colossus.sql b/drizzle/0027_motionless_colossus.sql new file mode 100644 index 0000000..4d7cdef --- /dev/null +++ b/drizzle/0027_motionless_colossus.sql @@ -0,0 +1 @@ +ALTER TABLE "user" ADD COLUMN "referralId" text; \ No newline at end of file diff --git a/drizzle/meta/0027_snapshot.json b/drizzle/meta/0027_snapshot.json new file mode 100644 index 0000000..2b6c35e --- /dev/null +++ b/drizzle/meta/0027_snapshot.json @@ -0,0 +1,1254 @@ +{ + "id": "1843b2fe-285f-4ca2-9169-6869508c379d", + "prevId": "d7a8ece8-d669-4251-96f7-6b98213f328c", + "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.impersonate_audit_log": { + "name": "impersonate_audit_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "adminUserId": { + "name": "adminUserId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "targetUserId": { + "name": "targetUserId", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "impersonate_audit_log_adminUserId_user_id_fk": { + "name": "impersonate_audit_log_adminUserId_user_id_fk", + "tableFrom": "impersonate_audit_log", + "tableTo": "user", + "columnsFrom": [ + "adminUserId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "impersonate_audit_log_targetUserId_user_id_fk": { + "name": "impersonate_audit_log_targetUserId_user_id_fk", + "tableFrom": "impersonate_audit_log", + "tableTo": "user", + "columnsFrom": [ + "targetUserId" + ], + "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 + }, + "marketItemId": { + "name": "marketItemId", + "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" + }, + "market_item_order_marketItemId_market_item_id_fk": { + "name": "market_item_order_marketItemId_market_item_id_fk", + "tableFrom": "market_item_order", + "tableTo": "market_item", + "columnsFrom": [ + "marketItemId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ovenpheus_log": { + "name": "ovenpheus_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "clay": { + "name": "clay", + "type": "real", + "primaryKey": false, + "notNull": true + }, + "bricksReceived": { + "name": "bricksReceived", + "type": "real", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "ovenpheus_log_userId_user_id_fk": { + "name": "ovenpheus_log_userId_user_id_fk", + "tableFrom": "ovenpheus_log", + "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 + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "shopScoreMultiplier": { + "name": "shopScoreMultiplier", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 25 + }, + "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 + }, + "referralId": { + "name": "referralId", + "type": "text", + "primaryKey": false, + "notNull": 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", + "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 e960053..70c211b 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -190,6 +190,13 @@ "when": 1768171539001, "tag": "0026_wealthy_shinko_yamashiro", "breakpoints": true + }, + { + "idx": 27, + "version": "7", + "when": 1768175514843, + "tag": "0027_motionless_colossus", + "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 8481c2b..ec7afc7 100644 --- a/src/lib/server/db/schema.ts +++ b/src/lib/server/db/schema.ts @@ -38,6 +38,8 @@ export const user = pgTable('user', { isPrinter: boolean().notNull().default(false), // Is a printer + referralId: text(), + createdAt: timestamp().notNull().defaultNow(), // Account creation timestamp lastLoginAt: timestamp().notNull().defaultNow() // Last login timestamp }); @@ -236,7 +238,7 @@ export const ovenpheusLog = pgTable('ovenpheus_log', { clay: real().notNull(), bricksReceived: real().notNull(), - timestamp: timestamp().notNull().defaultNow(), + timestamp: timestamp().notNull().defaultNow() }); export const marketOrderStatus = pgEnum('market_order_status', [ @@ -248,7 +250,9 @@ export const marketOrderStatus = pgEnum('market_order_status', [ export const marketItemOrder = pgTable('market_item_order', { id: serial().primaryKey(), - userId: integer().references(() => user.id).notNull(), + userId: integer() + .references(() => user.id) + .notNull(), marketItemId: integer().references(() => marketItem.id), addressId: text().notNull(), @@ -256,7 +260,7 @@ export const marketItemOrder = pgTable('market_item_order', { status: marketOrderStatus().notNull().default('awaiting_approval'), userNotes: text().notNull(), - notes: text(), // stuff like tracking code, shown to user + notes: text(), // stuff like tracking code, shown to user deleted: boolean().notNull().default(false), createdAt: timestamp().notNull().defaultNow() diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 0d97f91..3a68258 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -28,6 +28,13 @@ const scene = new THREE.Scene(); onMount(() => { + const urlParams = new URLSearchParams(window.location.search); + const ref = urlParams.get('ref'); + + if (ref) { + document.cookie = 'ref=' + ref + '; path=/'; + } + if (!model) { return; } diff --git a/src/routes/auth/callback/+server.ts b/src/routes/auth/callback/+server.ts index 4297b6b..63c4ac9 100644 --- a/src/routes/auth/callback/+server.ts +++ b/src/routes/auth/callback/+server.ts @@ -156,6 +156,8 @@ export async function GET(event) { env.SUPER_ADMIN_SLACK_ID.length > 0 && slack_id === env.SUPER_ADMIN_SLACK_ID; + const ref = event.cookies.get('ref'); + if (databaseUser) { // Update user (update name and profile picture and lastLoginAt on login) await db @@ -180,6 +182,7 @@ export async function GET(event) { createdAt: new Date(Date.now()), lastLoginAt: new Date(Date.now()), hackatimeTrust, + referralId: ref, hasT1Review: isSuperAdmin, hasT2Review: isSuperAdmin, diff --git a/src/routes/dashboard/admin/admin/users/[id]/+page.svelte b/src/routes/dashboard/admin/admin/users/[id]/+page.svelte index 3e49332..c5372b7 100644 --- a/src/routes/dashboard/admin/admin/users/[id]/+page.svelte +++ b/src/routes/dashboard/admin/admin/users/[id]/+page.svelte @@ -131,6 +131,9 @@ {data.devlogCount} + + {user.referralId ?? 'None'} +

Currency stuff

From b1f1e72ddb85215f986abc3ef75f2d0f702aa216 Mon Sep 17 00:00:00 2001 From: Arca Ege Cengiz Date: Mon, 12 Jan 2026 22:51:06 +0000 Subject: [PATCH 3/3] Fix the table of air and add pyramid scheme --- package-lock.json | 28 +++++++- src/routes/auth/callback/+server.ts | 14 +++- .../admin/ysws-review/[id]/+page.server.ts | 71 ++++++++++++------- .../projects/[id]/delete/+page.server.ts | 43 ++++++++--- .../dashboard/projects/create/+page.server.ts | 25 +++++++ 5 files changed, 146 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index 626ab37..f6c020c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -984,6 +984,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -3027,6 +3028,7 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=8.0.0" } @@ -3048,6 +3050,7 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.2.0.tgz", "integrity": "sha512-qRkLWiUEZNAmYapZ7KGS5C4OmBLcP/H2foXeOEaowYCR0wi89fHejrfYfbuLVCMLp/dWZXKvQusdbUEZjERfwQ==", "license": "Apache-2.0", + "peer": true, "engines": { "node": "^18.19.0 || >=20.6.0" }, @@ -3060,6 +3063,7 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, @@ -3075,6 +3079,7 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.208.0.tgz", "integrity": "sha512-Eju0L4qWcQS+oXxi6pgh7zvE2byogAkcsVv0OjHF/97iOz1N/aKE6etSGowYkie+YA1uo6DNwdSxaaNnLvcRlA==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@opentelemetry/api-logs": "0.208.0", "import-in-the-middle": "^2.0.0", @@ -3462,6 +3467,7 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.2.0.tgz", "integrity": "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/semantic-conventions": "^1.29.0" @@ -3478,6 +3484,7 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.2.0.tgz", "integrity": "sha512-xWQgL0Bmctsalg6PaXExmzdedSp3gyKV8mQBwK/j9VGdCDu2fmXIb2gAehBKbkXCpJ4HPkgv3QfoJWRT4dHWbw==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", @@ -3495,6 +3502,7 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=14" } @@ -5301,6 +5309,7 @@ "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.47.0.tgz", "integrity": "sha512-mznN01MBXtr4T7X/E3ENkhF6GzqxTxL6/whG3OzCzUu8G8KYRNiCdoxLMVWAHJx/mDMPP3XAeKCMZHF/Xd/CDw==", "license": "MIT", + "peer": true, "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.5", @@ -5339,6 +5348,7 @@ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.1.tgz", "integrity": "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==", "license": "MIT", + "peer": true, "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", "debug": "^4.4.1", @@ -5845,6 +5855,7 @@ "integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.1", "@typescript-eslint/types": "8.46.1", @@ -6100,6 +6111,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -6376,6 +6388,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", @@ -6989,6 +7002,7 @@ "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -7085,6 +7099,7 @@ "integrity": "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -9384,6 +9399,7 @@ "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz", "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==", "license": "MIT", + "peer": true, "dependencies": { "pg-connection-string": "^2.9.1", "pg-pool": "^3.10.1", @@ -9505,6 +9521,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -9677,6 +9694,7 @@ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -9693,6 +9711,7 @@ "integrity": "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ==", "dev": true, "license": "MIT", + "peer": true, "peerDependencies": { "prettier": "^3.0.0", "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" @@ -9998,6 +10017,7 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz", "integrity": "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==", "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -10575,6 +10595,7 @@ "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.40.1.tgz", "integrity": "sha512-0R3t2oiLxJNJb2buz61MNfPdkjeyj2qTCM7TtIv/4ZfF12zD7Ig8iIo+C8febroy+9S4QJ7qfijtearSdO/1ww==", "license": "MIT", + "peer": true, "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", @@ -10667,7 +10688,8 @@ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.14.tgz", "integrity": "sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/tapable": { "version": "2.3.0", @@ -10832,6 +10854,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -10890,6 +10913,7 @@ "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.21.tgz", "integrity": "sha512-Wj7/AMtE9MRnAXa6Su3Lk0LNCfqDYgfwVjwRFVum9U7wsto1imuHqk4kTm7Jni+5A0Hn7dttL6O/zjvUvoo+8A==", "license": "MIT", + "peer": true, "dependencies": { "defu": "^6.1.4", "exsolve": "^1.0.7", @@ -11040,6 +11064,7 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.10.tgz", "integrity": "sha512-CmuvUBzVJ/e3HGxhg6cYk88NGgTnBoOo7ogtfJJ0fefUWAxN/WDSUa50o+oVBxuIhO8FoEZW0j2eW7sfjs5EtA==", "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -11615,6 +11640,7 @@ "integrity": "sha512-HwaJmXO3M1r4S8x2ea2vy8Rw/y/38HRQuK/gNDRQ7w9cJXn6xSl1sIIqKCffULSUjul3wV3I3Nd/GfbmsRReEA==", "hasInstallScript": true, "license": "Apache-2.0", + "peer": true, "bin": { "workerd": "bin/workerd" }, diff --git a/src/routes/auth/callback/+server.ts b/src/routes/auth/callback/+server.ts index 63c4ac9..46375d0 100644 --- a/src/routes/auth/callback/+server.ts +++ b/src/routes/auth/callback/+server.ts @@ -12,6 +12,7 @@ import { } from '$lib/server/auth.js'; import { encrypt } from '$lib/server/encryption.js'; import { getUserData } from '$lib/server/idvUserData'; +import { airtableBase } from '$lib/server/airtable'; export async function GET(event) { const url = event.url; @@ -52,7 +53,7 @@ export async function GET(event) { return redirect(302, '/auth/failed'); } - const { id, slack_id, ysws_eligible } = userData; + const { id, slack_id, first_name, last_name, primary_email, ysws_eligible } = userData; if (!ysws_eligible) { return redirect(302, '/auth/ineligible'); @@ -195,6 +196,17 @@ export async function GET(event) { // Something went _really_ wrong return error(500); } + + if (ref && airtableBase) { + await airtableBase('tblwUPbRqbRBnQl7G').create({ + fldMYF9BuxKbRuSJt: first_name + ' ' + last_name, // Name + fldXbtQyDOFpWwGBQ: databaseUser.id, // User ID + fldkTgzCj0sz01QQM: primary_email, // Email + fldeNiHX4OhZEDWM5: 0, // Project count + fld1Sssrs7K69cN0i: 0, // Verified ship count + fldaPDWM3wrIYOAEf: ref // Referral code + }); + } } const sessionToken = generateSessionToken(); 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 43a2768..7966396 100644 --- a/src/routes/dashboard/admin/ysws-review/[id]/+page.server.ts +++ b/src/routes/dashboard/admin/ysws-review/[id]/+page.server.ts @@ -237,37 +237,58 @@ export const actions = { queriedProject.timeSpent / 60 )}h ${queriedProject.timeSpent % 60}min, each one with a 3d model file to show progress.\nAll journals can be found here: https://construct.hackclub.com/dashboard/projects/${queriedProject.project.id}`; - await airtableBase('YSWS Project Submission').create({ - 'Code URL': repoUrl ?? '', - 'Playable URL': queriedProject.project.url ?? '', - Description: queriedProject.project.description ?? '', - - 'First Name': first_name ?? '', - 'Last Name': last_name ?? '', - Email: primary_email ?? '', - Birthday: birthday ?? '', - 'Address (Line 1)': address?.line_1 ?? '', - City: address?.city ?? '', - 'State / Province': address?.state ?? '', - Country: address?.country ?? '', - 'ZIP / Postal Code': address?.postal_code ?? '', - - 'Hours estimate': queriedProject.timeSpent / 60, - 'Optional - Override Hours Spent': queriedProject.timeSpent / 60, - 'Optional - Override Hours Spent Justification': notes - ? notes + '\n' + justificationAppend - : justificationAppend, - Screenshot: [ + await airtableBase('tblBQ2aKCQanXJSaa').create({ + fld9BIrlDRnjVL6Ui: repoUrl ?? '', + fldPrLiLa12h50Pfy: queriedProject.project.url ?? '', + fldIFFkfSli8AFMbD: queriedProject.project.description ?? '', + + fldaQ63WIIhwzJkzv: first_name ?? '', + fldrz5U1lHDLNgsIH: last_name ?? '', + fldYCGOtjaGdTkmzR: primary_email ?? '', + fldKVDqNLSfo4rI6z: birthday ?? '', + fldDtPb8zPM4CZS2s: address?.line_1 ?? '', + fldgduLK4ImVTE4Ro: address?.line_2 ?? '', + fldQoWAVX33mOdLrz: address?.city ?? '', + fldYeXjXlNueOhoLw: address?.state ?? '', + fldSDMKS7YLgmAs07: address?.country ?? '', + fld00PyO4JOklsDxj: address?.postal_code ?? '', + + fldoOwpxxFpwu49lF: queriedProject.timeSpent / 60, + fldvLn9Rh9X9To51y: queriedProject.timeSpent / 60, + fldkai7CLWixkJlc2: notes ? notes + '\n' + justificationAppend : justificationAppend, + fldCUW9JyeauwmyLZ: [ { url: imageUrlString } // eslint-disable-next-line @typescript-eslint/no-explicit-any ] as any, - 'Slack Username': queriedProject.user?.name, - idv_rec: queriedProject.user?.idvId, - 'Identity Verified': true, - 'Temp hold': false + fld9TiRu0JTKaqCbA: queriedProject.user?.name, + fld1xMv37PLYw0MbZ: queriedProject.user?.idvId, + fldoe0vNhq3NDzEUo: true, + fldADmpBlSo84dNNM: false }); + + const records = await airtableBase('tblwUPbRqbRBnQl7G') + .select({ + maxRecords: 1, + view: 'Grid view', + filterByFormula: '{fldXbtQyDOFpWwGBQ} = ' + locals.user.id + }) + .firstPage(); + + if (records.length > 0) { + const record = records[0]; + const verifiedShipCount = (record.get('Verified Ship Count') ?? 0) as number; + + await airtableBase('tblwUPbRqbRBnQl7G').update([ + { + id: record.id, + fields: { + fld1Sssrs7K69cN0i: verifiedShipCount + 1 + } + } + ]); + } } await db.insert(t2Review).values({ diff --git a/src/routes/dashboard/projects/[id]/delete/+page.server.ts b/src/routes/dashboard/projects/[id]/delete/+page.server.ts index 2855ef7..d40332f 100644 --- a/src/routes/dashboard/projects/[id]/delete/+page.server.ts +++ b/src/routes/dashboard/projects/[id]/delete/+page.server.ts @@ -3,6 +3,7 @@ import { devlog, project } from '$lib/server/db/schema.js'; import { error, redirect } from '@sveltejs/kit'; import { eq, and, or, sql } from 'drizzle-orm'; import type { Actions } from './$types'; +import { airtableBase } from '$lib/server/airtable'; export async function load({ params, locals }) { const id: number = parseInt(params.id); @@ -36,7 +37,14 @@ export async function load({ params, locals }) { or(eq(project.status, 'building'), eq(project.status, 'rejected')) ) ) - .groupBy(project.id, project.name, project.description, project.url, project.createdAt, project.status) + .groupBy( + project.id, + project.name, + project.description, + project.url, + project.createdAt, + project.status + ) .limit(1); if (!queriedProject) { @@ -73,6 +81,30 @@ export const actions = { throw error(404); } + if (airtableBase) { + const records = await airtableBase('tblwUPbRqbRBnQl7G') + .select({ + maxRecords: 1, + view: 'Grid view', + filterByFormula: '{fldXbtQyDOFpWwGBQ} = ' + locals.user.id + }) + .firstPage(); + + if (records.length > 0) { + const record = records[0]; + const projectCount = (record.get('Project Count') ?? 0) as number; + + await airtableBase('tblwUPbRqbRBnQl7G').update([ + { + id: record.id, + fields: { + fldeNiHX4OhZEDWM5: projectCount - 1 + } + } + ]); + } + } + // Delete project await db .update(project) @@ -87,7 +119,7 @@ export const actions = { eq(project.deleted, false) ) ); - + // Mark all associated devlogs as deleted await db .update(devlog) @@ -95,12 +127,7 @@ export const actions = { deleted: true, updatedAt: new Date(Date.now()) }) - .where( - and( - eq(devlog.projectId, queriedProject.id), - eq(devlog.userId, locals.user.id), - ) - ); + .where(and(eq(devlog.projectId, queriedProject.id), eq(devlog.userId, locals.user.id))); return redirect(303, '/dashboard/projects'); } diff --git a/src/routes/dashboard/projects/create/+page.server.ts b/src/routes/dashboard/projects/create/+page.server.ts index 6a6c12e..0063bfd 100644 --- a/src/routes/dashboard/projects/create/+page.server.ts +++ b/src/routes/dashboard/projects/create/+page.server.ts @@ -2,6 +2,7 @@ import { db } from '$lib/server/db/index.js'; import { project } from '$lib/server/db/schema.js'; import { error, fail, redirect } from '@sveltejs/kit'; import type { Actions } from './$types'; +import { airtableBase } from '$lib/server/airtable'; export const actions = { default: async ({ request, locals }) => { @@ -28,6 +29,30 @@ export const actions = { }); } + if (airtableBase) { + const records = await airtableBase('tblwUPbRqbRBnQl7G') + .select({ + maxRecords: 1, + view: 'Grid view', + filterByFormula: '{fldXbtQyDOFpWwGBQ} = ' + locals.user.id + }) + .firstPage(); + + if (records.length > 0) { + const record = records[0]; + const projectCount = (record.get('Project Count') ?? 0) as number; + + await airtableBase('tblwUPbRqbRBnQl7G').update([ + { + id: record.id, + fields: { + fldeNiHX4OhZEDWM5: projectCount + 1 + } + } + ]); + } + } + const [addedProject] = await db .insert(project) .values({