feat: pricing plan + usage page
This commit is contained in:
		
							parent
							
								
									14c3ca6bf5
								
							
						
					
					
						commit
						0f9e0c9c76
					
				
							
								
								
									
										
											BIN
										
									
								
								web/bun.lockb
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								web/bun.lockb
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										14
									
								
								web/drizzle/0035_fearless_golden_guardian.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								web/drizzle/0035_fearless_golden_guardian.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
CREATE TABLE IF NOT EXISTS "comfyui_deploy"."user_usage" (
 | 
			
		||||
	"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
 | 
			
		||||
	"org_id" text,
 | 
			
		||||
	"user_id" text NOT NULL,
 | 
			
		||||
	"usage_time" real DEFAULT 0 NOT NULL,
 | 
			
		||||
	"created_at" timestamp DEFAULT now() NOT NULL,
 | 
			
		||||
	"ended_at" timestamp DEFAULT now() NOT NULL
 | 
			
		||||
);
 | 
			
		||||
--> statement-breakpoint
 | 
			
		||||
DO $$ BEGIN
 | 
			
		||||
 ALTER TABLE "comfyui_deploy"."user_usage" ADD CONSTRAINT "user_usage_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "comfyui_deploy"."users"("id") ON DELETE cascade ON UPDATE no action;
 | 
			
		||||
EXCEPTION
 | 
			
		||||
 WHEN duplicate_object THEN null;
 | 
			
		||||
END $$;
 | 
			
		||||
							
								
								
									
										22
									
								
								web/drizzle/0036_flippant_meltdown.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								web/drizzle/0036_flippant_meltdown.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
DO $$ BEGIN
 | 
			
		||||
 CREATE TYPE "subscription_plan" AS ENUM('basic', 'pro', 'enterprise');
 | 
			
		||||
EXCEPTION
 | 
			
		||||
 WHEN duplicate_object THEN null;
 | 
			
		||||
END $$;
 | 
			
		||||
--> statement-breakpoint
 | 
			
		||||
DO $$ BEGIN
 | 
			
		||||
 CREATE TYPE "subscription_plan_status" AS ENUM('active', 'deleted', 'paused');
 | 
			
		||||
EXCEPTION
 | 
			
		||||
 WHEN duplicate_object THEN null;
 | 
			
		||||
END $$;
 | 
			
		||||
--> statement-breakpoint
 | 
			
		||||
CREATE TABLE IF NOT EXISTS "comfyui_deploy"."subscription_status" (
 | 
			
		||||
	"stripe_customer_id" text PRIMARY KEY NOT NULL,
 | 
			
		||||
	"user_id" text,
 | 
			
		||||
	"org_id" text,
 | 
			
		||||
	"plan" "subscription_plan" NOT NULL,
 | 
			
		||||
	"status" "subscription_plan_status" NOT NULL,
 | 
			
		||||
	"subscription_plan_id" text,
 | 
			
		||||
	"created_at" timestamp DEFAULT now() NOT NULL,
 | 
			
		||||
	"updated_at" timestamp DEFAULT now() NOT NULL
 | 
			
		||||
);
 | 
			
		||||
							
								
								
									
										3
									
								
								web/drizzle/0037_eager_cyclops.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/drizzle/0037_eager_cyclops.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
ALTER TABLE "comfyui_deploy"."subscription_status" RENAME COLUMN "subscription_plan_id" TO "subscription_id";--> statement-breakpoint
 | 
			
		||||
ALTER TABLE "comfyui_deploy"."subscription_status" ADD COLUMN "subscription_item_plan_id" text;--> statement-breakpoint
 | 
			
		||||
ALTER TABLE "comfyui_deploy"."subscription_status" ADD COLUMN "subscription_item_api_id" text;
 | 
			
		||||
							
								
								
									
										1
									
								
								web/drizzle/0038_yummy_darkhawk.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								web/drizzle/0038_yummy_darkhawk.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
ALTER TABLE "comfyui_deploy"."subscription_status" ADD COLUMN "cancel_at_period_end" boolean DEFAULT false;
 | 
			
		||||
							
								
								
									
										2
									
								
								web/drizzle/0039_nostalgic_lyja.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								web/drizzle/0039_nostalgic_lyja.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
ALTER TABLE "comfyui_deploy"."workflow_runs" ADD COLUMN "user_id" text;--> statement-breakpoint
 | 
			
		||||
ALTER TABLE "comfyui_deploy"."workflow_runs" ADD COLUMN "org_id" text;
 | 
			
		||||
							
								
								
									
										1
									
								
								web/drizzle/0040_salty_archangel.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								web/drizzle/0040_salty_archangel.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
ALTER TABLE "comfyui_deploy"."workflow_runs" ADD COLUMN "gpu" "machine_gpu";
 | 
			
		||||
							
								
								
									
										1
									
								
								web/drizzle/0041_thick_norrin_radd.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								web/drizzle/0041_thick_norrin_radd.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
ALTER TABLE "comfyui_deploy"."workflow_runs" ADD COLUMN "machine_type" "machine_type";
 | 
			
		||||
							
								
								
									
										894
									
								
								web/drizzle/meta/0035_snapshot.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										894
									
								
								web/drizzle/meta/0035_snapshot.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,894 @@
 | 
			
		||||
{
 | 
			
		||||
  "id": "2b2a5d0a-2494-45ea-9d4a-58a70df97829",
 | 
			
		||||
  "prevId": "8d654f92-7f7e-420f-bbd3-73b6b27adf35",
 | 
			
		||||
  "version": "5",
 | 
			
		||||
  "dialect": "pg",
 | 
			
		||||
  "tables": {
 | 
			
		||||
    "api_keys": {
 | 
			
		||||
      "name": "api_keys",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "key": {
 | 
			
		||||
          "name": "key",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "revoked": {
 | 
			
		||||
          "name": "revoked",
 | 
			
		||||
          "type": "boolean",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "api_keys_user_id_users_id_fk": {
 | 
			
		||||
          "name": "api_keys_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "api_keys",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {
 | 
			
		||||
        "api_keys_key_unique": {
 | 
			
		||||
          "name": "api_keys_key_unique",
 | 
			
		||||
          "nullsNotDistinct": false,
 | 
			
		||||
          "columns": [
 | 
			
		||||
            "key"
 | 
			
		||||
          ]
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "auth_requests": {
 | 
			
		||||
      "name": "auth_requests",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "request_id": {
 | 
			
		||||
          "name": "request_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "api_hash": {
 | 
			
		||||
          "name": "api_hash",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "expired_date": {
 | 
			
		||||
          "name": "expired_date",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {},
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "deployments": {
 | 
			
		||||
      "name": "deployments",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_version_id": {
 | 
			
		||||
          "name": "workflow_version_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_id": {
 | 
			
		||||
          "name": "workflow_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "machine_id": {
 | 
			
		||||
          "name": "machine_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "share_slug": {
 | 
			
		||||
          "name": "share_slug",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "description": {
 | 
			
		||||
          "name": "description",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "showcase_media": {
 | 
			
		||||
          "name": "showcase_media",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "environment": {
 | 
			
		||||
          "name": "environment",
 | 
			
		||||
          "type": "deployment_environment",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "deployments_user_id_users_id_fk": {
 | 
			
		||||
          "name": "deployments_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "deployments_workflow_version_id_workflow_versions_id_fk": {
 | 
			
		||||
          "name": "deployments_workflow_version_id_workflow_versions_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "workflow_versions",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_version_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "no action",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "deployments_workflow_id_workflows_id_fk": {
 | 
			
		||||
          "name": "deployments_workflow_id_workflows_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "workflows",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "deployments_machine_id_machines_id_fk": {
 | 
			
		||||
          "name": "deployments_machine_id_machines_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "machines",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "machine_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "no action",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {
 | 
			
		||||
        "deployments_share_slug_unique": {
 | 
			
		||||
          "name": "deployments_share_slug_unique",
 | 
			
		||||
          "nullsNotDistinct": false,
 | 
			
		||||
          "columns": [
 | 
			
		||||
            "share_slug"
 | 
			
		||||
          ]
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machines": {
 | 
			
		||||
      "name": "machines",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "endpoint": {
 | 
			
		||||
          "name": "endpoint",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "disabled": {
 | 
			
		||||
          "name": "disabled",
 | 
			
		||||
          "type": "boolean",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": false
 | 
			
		||||
        },
 | 
			
		||||
        "auth_token": {
 | 
			
		||||
          "name": "auth_token",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "type": {
 | 
			
		||||
          "name": "type",
 | 
			
		||||
          "type": "machine_type",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'classic'"
 | 
			
		||||
        },
 | 
			
		||||
        "status": {
 | 
			
		||||
          "name": "status",
 | 
			
		||||
          "type": "machine_status",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'ready'"
 | 
			
		||||
        },
 | 
			
		||||
        "snapshot": {
 | 
			
		||||
          "name": "snapshot",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "models": {
 | 
			
		||||
          "name": "models",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "gpu": {
 | 
			
		||||
          "name": "gpu",
 | 
			
		||||
          "type": "machine_gpu",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "build_machine_instance_id": {
 | 
			
		||||
          "name": "build_machine_instance_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "build_log": {
 | 
			
		||||
          "name": "build_log",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "machines_user_id_users_id_fk": {
 | 
			
		||||
          "name": "machines_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "machines",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "user_usage": {
 | 
			
		||||
      "name": "user_usage",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "usage_time": {
 | 
			
		||||
          "name": "usage_time",
 | 
			
		||||
          "type": "real",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": 0
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "ended_at": {
 | 
			
		||||
          "name": "ended_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "user_usage_user_id_users_id_fk": {
 | 
			
		||||
          "name": "user_usage_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "user_usage",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "users": {
 | 
			
		||||
      "name": "users",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "username": {
 | 
			
		||||
          "name": "username",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {},
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_run_outputs": {
 | 
			
		||||
      "name": "workflow_run_outputs",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "run_id": {
 | 
			
		||||
          "name": "run_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "data": {
 | 
			
		||||
          "name": "data",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflow_run_outputs_run_id_workflow_runs_id_fk": {
 | 
			
		||||
          "name": "workflow_run_outputs_run_id_workflow_runs_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_run_outputs",
 | 
			
		||||
          "tableTo": "workflow_runs",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "run_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_runs": {
 | 
			
		||||
      "name": "workflow_runs",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_version_id": {
 | 
			
		||||
          "name": "workflow_version_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_inputs": {
 | 
			
		||||
          "name": "workflow_inputs",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_id": {
 | 
			
		||||
          "name": "workflow_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "machine_id": {
 | 
			
		||||
          "name": "machine_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "origin": {
 | 
			
		||||
          "name": "origin",
 | 
			
		||||
          "type": "workflow_run_origin",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'api'"
 | 
			
		||||
        },
 | 
			
		||||
        "status": {
 | 
			
		||||
          "name": "status",
 | 
			
		||||
          "type": "workflow_run_status",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'not-started'"
 | 
			
		||||
        },
 | 
			
		||||
        "ended_at": {
 | 
			
		||||
          "name": "ended_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "started_at": {
 | 
			
		||||
          "name": "started_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflow_runs_workflow_version_id_workflow_versions_id_fk": {
 | 
			
		||||
          "name": "workflow_runs_workflow_version_id_workflow_versions_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_runs",
 | 
			
		||||
          "tableTo": "workflow_versions",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_version_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "set null",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_runs_workflow_id_workflows_id_fk": {
 | 
			
		||||
          "name": "workflow_runs_workflow_id_workflows_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_runs",
 | 
			
		||||
          "tableTo": "workflows",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_runs_machine_id_machines_id_fk": {
 | 
			
		||||
          "name": "workflow_runs_machine_id_machines_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_runs",
 | 
			
		||||
          "tableTo": "machines",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "machine_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "set null",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflows": {
 | 
			
		||||
      "name": "workflows",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflows_user_id_users_id_fk": {
 | 
			
		||||
          "name": "workflows_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "workflows",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_versions": {
 | 
			
		||||
      "name": "workflow_versions",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "workflow_id": {
 | 
			
		||||
          "name": "workflow_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow": {
 | 
			
		||||
          "name": "workflow",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_api": {
 | 
			
		||||
          "name": "workflow_api",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "version": {
 | 
			
		||||
          "name": "version",
 | 
			
		||||
          "type": "integer",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "snapshot": {
 | 
			
		||||
          "name": "snapshot",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflow_versions_workflow_id_workflows_id_fk": {
 | 
			
		||||
          "name": "workflow_versions_workflow_id_workflows_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_versions",
 | 
			
		||||
          "tableTo": "workflows",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "enums": {
 | 
			
		||||
    "deployment_environment": {
 | 
			
		||||
      "name": "deployment_environment",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "staging": "staging",
 | 
			
		||||
        "production": "production",
 | 
			
		||||
        "public-share": "public-share"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machine_gpu": {
 | 
			
		||||
      "name": "machine_gpu",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "T4": "T4",
 | 
			
		||||
        "A10G": "A10G",
 | 
			
		||||
        "A100": "A100"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machine_status": {
 | 
			
		||||
      "name": "machine_status",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "ready": "ready",
 | 
			
		||||
        "building": "building",
 | 
			
		||||
        "error": "error"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machine_type": {
 | 
			
		||||
      "name": "machine_type",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "classic": "classic",
 | 
			
		||||
        "runpod-serverless": "runpod-serverless",
 | 
			
		||||
        "modal-serverless": "modal-serverless",
 | 
			
		||||
        "comfy-deploy-serverless": "comfy-deploy-serverless"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_run_origin": {
 | 
			
		||||
      "name": "workflow_run_origin",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "manual": "manual",
 | 
			
		||||
        "api": "api",
 | 
			
		||||
        "public-share": "public-share"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_run_status": {
 | 
			
		||||
      "name": "workflow_run_status",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "not-started": "not-started",
 | 
			
		||||
        "running": "running",
 | 
			
		||||
        "uploading": "uploading",
 | 
			
		||||
        "success": "success",
 | 
			
		||||
        "failed": "failed"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "schemas": {
 | 
			
		||||
    "comfyui_deploy": "comfyui_deploy"
 | 
			
		||||
  },
 | 
			
		||||
  "_meta": {
 | 
			
		||||
    "schemas": {},
 | 
			
		||||
    "tables": {},
 | 
			
		||||
    "columns": {}
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										970
									
								
								web/drizzle/meta/0036_snapshot.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										970
									
								
								web/drizzle/meta/0036_snapshot.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,970 @@
 | 
			
		||||
{
 | 
			
		||||
  "id": "4db08fc3-2444-42da-b742-f1832ad8caf1",
 | 
			
		||||
  "prevId": "2b2a5d0a-2494-45ea-9d4a-58a70df97829",
 | 
			
		||||
  "version": "5",
 | 
			
		||||
  "dialect": "pg",
 | 
			
		||||
  "tables": {
 | 
			
		||||
    "api_keys": {
 | 
			
		||||
      "name": "api_keys",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "key": {
 | 
			
		||||
          "name": "key",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "revoked": {
 | 
			
		||||
          "name": "revoked",
 | 
			
		||||
          "type": "boolean",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "api_keys_user_id_users_id_fk": {
 | 
			
		||||
          "name": "api_keys_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "api_keys",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {
 | 
			
		||||
        "api_keys_key_unique": {
 | 
			
		||||
          "name": "api_keys_key_unique",
 | 
			
		||||
          "nullsNotDistinct": false,
 | 
			
		||||
          "columns": [
 | 
			
		||||
            "key"
 | 
			
		||||
          ]
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "auth_requests": {
 | 
			
		||||
      "name": "auth_requests",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "request_id": {
 | 
			
		||||
          "name": "request_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "api_hash": {
 | 
			
		||||
          "name": "api_hash",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "expired_date": {
 | 
			
		||||
          "name": "expired_date",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {},
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "deployments": {
 | 
			
		||||
      "name": "deployments",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_version_id": {
 | 
			
		||||
          "name": "workflow_version_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_id": {
 | 
			
		||||
          "name": "workflow_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "machine_id": {
 | 
			
		||||
          "name": "machine_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "share_slug": {
 | 
			
		||||
          "name": "share_slug",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "description": {
 | 
			
		||||
          "name": "description",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "showcase_media": {
 | 
			
		||||
          "name": "showcase_media",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "environment": {
 | 
			
		||||
          "name": "environment",
 | 
			
		||||
          "type": "deployment_environment",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "deployments_user_id_users_id_fk": {
 | 
			
		||||
          "name": "deployments_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "deployments_workflow_version_id_workflow_versions_id_fk": {
 | 
			
		||||
          "name": "deployments_workflow_version_id_workflow_versions_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "workflow_versions",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_version_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "no action",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "deployments_workflow_id_workflows_id_fk": {
 | 
			
		||||
          "name": "deployments_workflow_id_workflows_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "workflows",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "deployments_machine_id_machines_id_fk": {
 | 
			
		||||
          "name": "deployments_machine_id_machines_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "machines",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "machine_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "no action",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {
 | 
			
		||||
        "deployments_share_slug_unique": {
 | 
			
		||||
          "name": "deployments_share_slug_unique",
 | 
			
		||||
          "nullsNotDistinct": false,
 | 
			
		||||
          "columns": [
 | 
			
		||||
            "share_slug"
 | 
			
		||||
          ]
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machines": {
 | 
			
		||||
      "name": "machines",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "endpoint": {
 | 
			
		||||
          "name": "endpoint",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "disabled": {
 | 
			
		||||
          "name": "disabled",
 | 
			
		||||
          "type": "boolean",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": false
 | 
			
		||||
        },
 | 
			
		||||
        "auth_token": {
 | 
			
		||||
          "name": "auth_token",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "type": {
 | 
			
		||||
          "name": "type",
 | 
			
		||||
          "type": "machine_type",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'classic'"
 | 
			
		||||
        },
 | 
			
		||||
        "status": {
 | 
			
		||||
          "name": "status",
 | 
			
		||||
          "type": "machine_status",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'ready'"
 | 
			
		||||
        },
 | 
			
		||||
        "snapshot": {
 | 
			
		||||
          "name": "snapshot",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "models": {
 | 
			
		||||
          "name": "models",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "gpu": {
 | 
			
		||||
          "name": "gpu",
 | 
			
		||||
          "type": "machine_gpu",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "build_machine_instance_id": {
 | 
			
		||||
          "name": "build_machine_instance_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "build_log": {
 | 
			
		||||
          "name": "build_log",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "machines_user_id_users_id_fk": {
 | 
			
		||||
          "name": "machines_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "machines",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "subscription_status": {
 | 
			
		||||
      "name": "subscription_status",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "stripe_customer_id": {
 | 
			
		||||
          "name": "stripe_customer_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "plan": {
 | 
			
		||||
          "name": "plan",
 | 
			
		||||
          "type": "subscription_plan",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "status": {
 | 
			
		||||
          "name": "status",
 | 
			
		||||
          "type": "subscription_plan_status",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "subscription_plan_id": {
 | 
			
		||||
          "name": "subscription_plan_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {},
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "user_usage": {
 | 
			
		||||
      "name": "user_usage",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "usage_time": {
 | 
			
		||||
          "name": "usage_time",
 | 
			
		||||
          "type": "real",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": 0
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "ended_at": {
 | 
			
		||||
          "name": "ended_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "user_usage_user_id_users_id_fk": {
 | 
			
		||||
          "name": "user_usage_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "user_usage",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "users": {
 | 
			
		||||
      "name": "users",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "username": {
 | 
			
		||||
          "name": "username",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {},
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_run_outputs": {
 | 
			
		||||
      "name": "workflow_run_outputs",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "run_id": {
 | 
			
		||||
          "name": "run_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "data": {
 | 
			
		||||
          "name": "data",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflow_run_outputs_run_id_workflow_runs_id_fk": {
 | 
			
		||||
          "name": "workflow_run_outputs_run_id_workflow_runs_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_run_outputs",
 | 
			
		||||
          "tableTo": "workflow_runs",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "run_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_runs": {
 | 
			
		||||
      "name": "workflow_runs",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_version_id": {
 | 
			
		||||
          "name": "workflow_version_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_inputs": {
 | 
			
		||||
          "name": "workflow_inputs",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_id": {
 | 
			
		||||
          "name": "workflow_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "machine_id": {
 | 
			
		||||
          "name": "machine_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "origin": {
 | 
			
		||||
          "name": "origin",
 | 
			
		||||
          "type": "workflow_run_origin",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'api'"
 | 
			
		||||
        },
 | 
			
		||||
        "status": {
 | 
			
		||||
          "name": "status",
 | 
			
		||||
          "type": "workflow_run_status",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'not-started'"
 | 
			
		||||
        },
 | 
			
		||||
        "ended_at": {
 | 
			
		||||
          "name": "ended_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "started_at": {
 | 
			
		||||
          "name": "started_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflow_runs_workflow_version_id_workflow_versions_id_fk": {
 | 
			
		||||
          "name": "workflow_runs_workflow_version_id_workflow_versions_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_runs",
 | 
			
		||||
          "tableTo": "workflow_versions",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_version_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "set null",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_runs_workflow_id_workflows_id_fk": {
 | 
			
		||||
          "name": "workflow_runs_workflow_id_workflows_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_runs",
 | 
			
		||||
          "tableTo": "workflows",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_runs_machine_id_machines_id_fk": {
 | 
			
		||||
          "name": "workflow_runs_machine_id_machines_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_runs",
 | 
			
		||||
          "tableTo": "machines",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "machine_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "set null",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflows": {
 | 
			
		||||
      "name": "workflows",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflows_user_id_users_id_fk": {
 | 
			
		||||
          "name": "workflows_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "workflows",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_versions": {
 | 
			
		||||
      "name": "workflow_versions",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "workflow_id": {
 | 
			
		||||
          "name": "workflow_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow": {
 | 
			
		||||
          "name": "workflow",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_api": {
 | 
			
		||||
          "name": "workflow_api",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "version": {
 | 
			
		||||
          "name": "version",
 | 
			
		||||
          "type": "integer",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "snapshot": {
 | 
			
		||||
          "name": "snapshot",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflow_versions_workflow_id_workflows_id_fk": {
 | 
			
		||||
          "name": "workflow_versions_workflow_id_workflows_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_versions",
 | 
			
		||||
          "tableTo": "workflows",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "enums": {
 | 
			
		||||
    "deployment_environment": {
 | 
			
		||||
      "name": "deployment_environment",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "staging": "staging",
 | 
			
		||||
        "production": "production",
 | 
			
		||||
        "public-share": "public-share"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machine_gpu": {
 | 
			
		||||
      "name": "machine_gpu",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "T4": "T4",
 | 
			
		||||
        "A10G": "A10G",
 | 
			
		||||
        "A100": "A100"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machine_status": {
 | 
			
		||||
      "name": "machine_status",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "ready": "ready",
 | 
			
		||||
        "building": "building",
 | 
			
		||||
        "error": "error"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machine_type": {
 | 
			
		||||
      "name": "machine_type",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "classic": "classic",
 | 
			
		||||
        "runpod-serverless": "runpod-serverless",
 | 
			
		||||
        "modal-serverless": "modal-serverless",
 | 
			
		||||
        "comfy-deploy-serverless": "comfy-deploy-serverless"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "subscription_plan": {
 | 
			
		||||
      "name": "subscription_plan",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "basic": "basic",
 | 
			
		||||
        "pro": "pro",
 | 
			
		||||
        "enterprise": "enterprise"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "subscription_plan_status": {
 | 
			
		||||
      "name": "subscription_plan_status",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "active": "active",
 | 
			
		||||
        "deleted": "deleted",
 | 
			
		||||
        "paused": "paused"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_run_origin": {
 | 
			
		||||
      "name": "workflow_run_origin",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "manual": "manual",
 | 
			
		||||
        "api": "api",
 | 
			
		||||
        "public-share": "public-share"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_run_status": {
 | 
			
		||||
      "name": "workflow_run_status",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "not-started": "not-started",
 | 
			
		||||
        "running": "running",
 | 
			
		||||
        "uploading": "uploading",
 | 
			
		||||
        "success": "success",
 | 
			
		||||
        "failed": "failed"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "schemas": {
 | 
			
		||||
    "comfyui_deploy": "comfyui_deploy"
 | 
			
		||||
  },
 | 
			
		||||
  "_meta": {
 | 
			
		||||
    "schemas": {},
 | 
			
		||||
    "tables": {},
 | 
			
		||||
    "columns": {}
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										984
									
								
								web/drizzle/meta/0037_snapshot.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										984
									
								
								web/drizzle/meta/0037_snapshot.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,984 @@
 | 
			
		||||
{
 | 
			
		||||
  "id": "cde8f758-0055-4326-981d-293ac84db54a",
 | 
			
		||||
  "prevId": "4db08fc3-2444-42da-b742-f1832ad8caf1",
 | 
			
		||||
  "version": "5",
 | 
			
		||||
  "dialect": "pg",
 | 
			
		||||
  "tables": {
 | 
			
		||||
    "api_keys": {
 | 
			
		||||
      "name": "api_keys",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "key": {
 | 
			
		||||
          "name": "key",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "revoked": {
 | 
			
		||||
          "name": "revoked",
 | 
			
		||||
          "type": "boolean",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "api_keys_user_id_users_id_fk": {
 | 
			
		||||
          "name": "api_keys_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "api_keys",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {
 | 
			
		||||
        "api_keys_key_unique": {
 | 
			
		||||
          "name": "api_keys_key_unique",
 | 
			
		||||
          "nullsNotDistinct": false,
 | 
			
		||||
          "columns": [
 | 
			
		||||
            "key"
 | 
			
		||||
          ]
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "auth_requests": {
 | 
			
		||||
      "name": "auth_requests",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "request_id": {
 | 
			
		||||
          "name": "request_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "api_hash": {
 | 
			
		||||
          "name": "api_hash",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "expired_date": {
 | 
			
		||||
          "name": "expired_date",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {},
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "deployments": {
 | 
			
		||||
      "name": "deployments",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_version_id": {
 | 
			
		||||
          "name": "workflow_version_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_id": {
 | 
			
		||||
          "name": "workflow_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "machine_id": {
 | 
			
		||||
          "name": "machine_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "share_slug": {
 | 
			
		||||
          "name": "share_slug",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "description": {
 | 
			
		||||
          "name": "description",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "showcase_media": {
 | 
			
		||||
          "name": "showcase_media",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "environment": {
 | 
			
		||||
          "name": "environment",
 | 
			
		||||
          "type": "deployment_environment",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "deployments_user_id_users_id_fk": {
 | 
			
		||||
          "name": "deployments_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "deployments_workflow_version_id_workflow_versions_id_fk": {
 | 
			
		||||
          "name": "deployments_workflow_version_id_workflow_versions_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "workflow_versions",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_version_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "no action",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "deployments_workflow_id_workflows_id_fk": {
 | 
			
		||||
          "name": "deployments_workflow_id_workflows_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "workflows",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "deployments_machine_id_machines_id_fk": {
 | 
			
		||||
          "name": "deployments_machine_id_machines_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "machines",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "machine_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "no action",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {
 | 
			
		||||
        "deployments_share_slug_unique": {
 | 
			
		||||
          "name": "deployments_share_slug_unique",
 | 
			
		||||
          "nullsNotDistinct": false,
 | 
			
		||||
          "columns": [
 | 
			
		||||
            "share_slug"
 | 
			
		||||
          ]
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machines": {
 | 
			
		||||
      "name": "machines",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "endpoint": {
 | 
			
		||||
          "name": "endpoint",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "disabled": {
 | 
			
		||||
          "name": "disabled",
 | 
			
		||||
          "type": "boolean",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": false
 | 
			
		||||
        },
 | 
			
		||||
        "auth_token": {
 | 
			
		||||
          "name": "auth_token",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "type": {
 | 
			
		||||
          "name": "type",
 | 
			
		||||
          "type": "machine_type",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'classic'"
 | 
			
		||||
        },
 | 
			
		||||
        "status": {
 | 
			
		||||
          "name": "status",
 | 
			
		||||
          "type": "machine_status",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'ready'"
 | 
			
		||||
        },
 | 
			
		||||
        "snapshot": {
 | 
			
		||||
          "name": "snapshot",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "models": {
 | 
			
		||||
          "name": "models",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "gpu": {
 | 
			
		||||
          "name": "gpu",
 | 
			
		||||
          "type": "machine_gpu",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "build_machine_instance_id": {
 | 
			
		||||
          "name": "build_machine_instance_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "build_log": {
 | 
			
		||||
          "name": "build_log",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "machines_user_id_users_id_fk": {
 | 
			
		||||
          "name": "machines_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "machines",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "subscription_status": {
 | 
			
		||||
      "name": "subscription_status",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "stripe_customer_id": {
 | 
			
		||||
          "name": "stripe_customer_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "plan": {
 | 
			
		||||
          "name": "plan",
 | 
			
		||||
          "type": "subscription_plan",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "status": {
 | 
			
		||||
          "name": "status",
 | 
			
		||||
          "type": "subscription_plan_status",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "subscription_id": {
 | 
			
		||||
          "name": "subscription_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "subscription_item_plan_id": {
 | 
			
		||||
          "name": "subscription_item_plan_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "subscription_item_api_id": {
 | 
			
		||||
          "name": "subscription_item_api_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {},
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "user_usage": {
 | 
			
		||||
      "name": "user_usage",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "usage_time": {
 | 
			
		||||
          "name": "usage_time",
 | 
			
		||||
          "type": "real",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": 0
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "ended_at": {
 | 
			
		||||
          "name": "ended_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "user_usage_user_id_users_id_fk": {
 | 
			
		||||
          "name": "user_usage_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "user_usage",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "users": {
 | 
			
		||||
      "name": "users",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "username": {
 | 
			
		||||
          "name": "username",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {},
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_run_outputs": {
 | 
			
		||||
      "name": "workflow_run_outputs",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "run_id": {
 | 
			
		||||
          "name": "run_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "data": {
 | 
			
		||||
          "name": "data",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflow_run_outputs_run_id_workflow_runs_id_fk": {
 | 
			
		||||
          "name": "workflow_run_outputs_run_id_workflow_runs_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_run_outputs",
 | 
			
		||||
          "tableTo": "workflow_runs",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "run_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_runs": {
 | 
			
		||||
      "name": "workflow_runs",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_version_id": {
 | 
			
		||||
          "name": "workflow_version_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_inputs": {
 | 
			
		||||
          "name": "workflow_inputs",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_id": {
 | 
			
		||||
          "name": "workflow_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "machine_id": {
 | 
			
		||||
          "name": "machine_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "origin": {
 | 
			
		||||
          "name": "origin",
 | 
			
		||||
          "type": "workflow_run_origin",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'api'"
 | 
			
		||||
        },
 | 
			
		||||
        "status": {
 | 
			
		||||
          "name": "status",
 | 
			
		||||
          "type": "workflow_run_status",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'not-started'"
 | 
			
		||||
        },
 | 
			
		||||
        "ended_at": {
 | 
			
		||||
          "name": "ended_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "started_at": {
 | 
			
		||||
          "name": "started_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflow_runs_workflow_version_id_workflow_versions_id_fk": {
 | 
			
		||||
          "name": "workflow_runs_workflow_version_id_workflow_versions_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_runs",
 | 
			
		||||
          "tableTo": "workflow_versions",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_version_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "set null",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_runs_workflow_id_workflows_id_fk": {
 | 
			
		||||
          "name": "workflow_runs_workflow_id_workflows_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_runs",
 | 
			
		||||
          "tableTo": "workflows",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_runs_machine_id_machines_id_fk": {
 | 
			
		||||
          "name": "workflow_runs_machine_id_machines_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_runs",
 | 
			
		||||
          "tableTo": "machines",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "machine_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "set null",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflows": {
 | 
			
		||||
      "name": "workflows",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflows_user_id_users_id_fk": {
 | 
			
		||||
          "name": "workflows_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "workflows",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_versions": {
 | 
			
		||||
      "name": "workflow_versions",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "workflow_id": {
 | 
			
		||||
          "name": "workflow_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow": {
 | 
			
		||||
          "name": "workflow",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_api": {
 | 
			
		||||
          "name": "workflow_api",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "version": {
 | 
			
		||||
          "name": "version",
 | 
			
		||||
          "type": "integer",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "snapshot": {
 | 
			
		||||
          "name": "snapshot",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflow_versions_workflow_id_workflows_id_fk": {
 | 
			
		||||
          "name": "workflow_versions_workflow_id_workflows_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_versions",
 | 
			
		||||
          "tableTo": "workflows",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "enums": {
 | 
			
		||||
    "deployment_environment": {
 | 
			
		||||
      "name": "deployment_environment",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "staging": "staging",
 | 
			
		||||
        "production": "production",
 | 
			
		||||
        "public-share": "public-share"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machine_gpu": {
 | 
			
		||||
      "name": "machine_gpu",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "T4": "T4",
 | 
			
		||||
        "A10G": "A10G",
 | 
			
		||||
        "A100": "A100"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machine_status": {
 | 
			
		||||
      "name": "machine_status",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "ready": "ready",
 | 
			
		||||
        "building": "building",
 | 
			
		||||
        "error": "error"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machine_type": {
 | 
			
		||||
      "name": "machine_type",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "classic": "classic",
 | 
			
		||||
        "runpod-serverless": "runpod-serverless",
 | 
			
		||||
        "modal-serverless": "modal-serverless",
 | 
			
		||||
        "comfy-deploy-serverless": "comfy-deploy-serverless"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "subscription_plan": {
 | 
			
		||||
      "name": "subscription_plan",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "basic": "basic",
 | 
			
		||||
        "pro": "pro",
 | 
			
		||||
        "enterprise": "enterprise"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "subscription_plan_status": {
 | 
			
		||||
      "name": "subscription_plan_status",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "active": "active",
 | 
			
		||||
        "deleted": "deleted",
 | 
			
		||||
        "paused": "paused"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_run_origin": {
 | 
			
		||||
      "name": "workflow_run_origin",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "manual": "manual",
 | 
			
		||||
        "api": "api",
 | 
			
		||||
        "public-share": "public-share"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_run_status": {
 | 
			
		||||
      "name": "workflow_run_status",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "not-started": "not-started",
 | 
			
		||||
        "running": "running",
 | 
			
		||||
        "uploading": "uploading",
 | 
			
		||||
        "success": "success",
 | 
			
		||||
        "failed": "failed"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "schemas": {
 | 
			
		||||
    "comfyui_deploy": "comfyui_deploy"
 | 
			
		||||
  },
 | 
			
		||||
  "_meta": {
 | 
			
		||||
    "schemas": {},
 | 
			
		||||
    "tables": {},
 | 
			
		||||
    "columns": {
 | 
			
		||||
      "\"comfyui_deploy\".\"subscription_status\".\"subscription_plan_id\"": "\"comfyui_deploy\".\"subscription_status\".\"subscription_id\""
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										989
									
								
								web/drizzle/meta/0038_snapshot.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										989
									
								
								web/drizzle/meta/0038_snapshot.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,989 @@
 | 
			
		||||
{
 | 
			
		||||
  "id": "bd893271-b9ea-4832-a3e8-a6970b9f20d9",
 | 
			
		||||
  "prevId": "cde8f758-0055-4326-981d-293ac84db54a",
 | 
			
		||||
  "version": "5",
 | 
			
		||||
  "dialect": "pg",
 | 
			
		||||
  "tables": {
 | 
			
		||||
    "api_keys": {
 | 
			
		||||
      "name": "api_keys",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "key": {
 | 
			
		||||
          "name": "key",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "revoked": {
 | 
			
		||||
          "name": "revoked",
 | 
			
		||||
          "type": "boolean",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "api_keys_user_id_users_id_fk": {
 | 
			
		||||
          "name": "api_keys_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "api_keys",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {
 | 
			
		||||
        "api_keys_key_unique": {
 | 
			
		||||
          "name": "api_keys_key_unique",
 | 
			
		||||
          "nullsNotDistinct": false,
 | 
			
		||||
          "columns": [
 | 
			
		||||
            "key"
 | 
			
		||||
          ]
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "auth_requests": {
 | 
			
		||||
      "name": "auth_requests",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "request_id": {
 | 
			
		||||
          "name": "request_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "api_hash": {
 | 
			
		||||
          "name": "api_hash",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "expired_date": {
 | 
			
		||||
          "name": "expired_date",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {},
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "deployments": {
 | 
			
		||||
      "name": "deployments",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_version_id": {
 | 
			
		||||
          "name": "workflow_version_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_id": {
 | 
			
		||||
          "name": "workflow_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "machine_id": {
 | 
			
		||||
          "name": "machine_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "share_slug": {
 | 
			
		||||
          "name": "share_slug",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "description": {
 | 
			
		||||
          "name": "description",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "showcase_media": {
 | 
			
		||||
          "name": "showcase_media",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "environment": {
 | 
			
		||||
          "name": "environment",
 | 
			
		||||
          "type": "deployment_environment",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "deployments_user_id_users_id_fk": {
 | 
			
		||||
          "name": "deployments_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "deployments_workflow_version_id_workflow_versions_id_fk": {
 | 
			
		||||
          "name": "deployments_workflow_version_id_workflow_versions_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "workflow_versions",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_version_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "no action",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "deployments_workflow_id_workflows_id_fk": {
 | 
			
		||||
          "name": "deployments_workflow_id_workflows_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "workflows",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "deployments_machine_id_machines_id_fk": {
 | 
			
		||||
          "name": "deployments_machine_id_machines_id_fk",
 | 
			
		||||
          "tableFrom": "deployments",
 | 
			
		||||
          "tableTo": "machines",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "machine_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "no action",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {
 | 
			
		||||
        "deployments_share_slug_unique": {
 | 
			
		||||
          "name": "deployments_share_slug_unique",
 | 
			
		||||
          "nullsNotDistinct": false,
 | 
			
		||||
          "columns": [
 | 
			
		||||
            "share_slug"
 | 
			
		||||
          ]
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machines": {
 | 
			
		||||
      "name": "machines",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "endpoint": {
 | 
			
		||||
          "name": "endpoint",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "disabled": {
 | 
			
		||||
          "name": "disabled",
 | 
			
		||||
          "type": "boolean",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": false
 | 
			
		||||
        },
 | 
			
		||||
        "auth_token": {
 | 
			
		||||
          "name": "auth_token",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "type": {
 | 
			
		||||
          "name": "type",
 | 
			
		||||
          "type": "machine_type",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'classic'"
 | 
			
		||||
        },
 | 
			
		||||
        "status": {
 | 
			
		||||
          "name": "status",
 | 
			
		||||
          "type": "machine_status",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'ready'"
 | 
			
		||||
        },
 | 
			
		||||
        "snapshot": {
 | 
			
		||||
          "name": "snapshot",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "models": {
 | 
			
		||||
          "name": "models",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "gpu": {
 | 
			
		||||
          "name": "gpu",
 | 
			
		||||
          "type": "machine_gpu",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "build_machine_instance_id": {
 | 
			
		||||
          "name": "build_machine_instance_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "build_log": {
 | 
			
		||||
          "name": "build_log",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "machines_user_id_users_id_fk": {
 | 
			
		||||
          "name": "machines_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "machines",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "subscription_status": {
 | 
			
		||||
      "name": "subscription_status",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "stripe_customer_id": {
 | 
			
		||||
          "name": "stripe_customer_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "plan": {
 | 
			
		||||
          "name": "plan",
 | 
			
		||||
          "type": "subscription_plan",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "status": {
 | 
			
		||||
          "name": "status",
 | 
			
		||||
          "type": "subscription_plan_status",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "subscription_id": {
 | 
			
		||||
          "name": "subscription_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "subscription_item_plan_id": {
 | 
			
		||||
          "name": "subscription_item_plan_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "subscription_item_api_id": {
 | 
			
		||||
          "name": "subscription_item_api_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "cancel_at_period_end": {
 | 
			
		||||
          "name": "cancel_at_period_end",
 | 
			
		||||
          "type": "boolean",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false,
 | 
			
		||||
          "default": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {},
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "user_usage": {
 | 
			
		||||
      "name": "user_usage",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "usage_time": {
 | 
			
		||||
          "name": "usage_time",
 | 
			
		||||
          "type": "real",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": 0
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "ended_at": {
 | 
			
		||||
          "name": "ended_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "user_usage_user_id_users_id_fk": {
 | 
			
		||||
          "name": "user_usage_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "user_usage",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "users": {
 | 
			
		||||
      "name": "users",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "username": {
 | 
			
		||||
          "name": "username",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {},
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_run_outputs": {
 | 
			
		||||
      "name": "workflow_run_outputs",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "run_id": {
 | 
			
		||||
          "name": "run_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "data": {
 | 
			
		||||
          "name": "data",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflow_run_outputs_run_id_workflow_runs_id_fk": {
 | 
			
		||||
          "name": "workflow_run_outputs_run_id_workflow_runs_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_run_outputs",
 | 
			
		||||
          "tableTo": "workflow_runs",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "run_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_runs": {
 | 
			
		||||
      "name": "workflow_runs",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_version_id": {
 | 
			
		||||
          "name": "workflow_version_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_inputs": {
 | 
			
		||||
          "name": "workflow_inputs",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_id": {
 | 
			
		||||
          "name": "workflow_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "machine_id": {
 | 
			
		||||
          "name": "machine_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "origin": {
 | 
			
		||||
          "name": "origin",
 | 
			
		||||
          "type": "workflow_run_origin",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'api'"
 | 
			
		||||
        },
 | 
			
		||||
        "status": {
 | 
			
		||||
          "name": "status",
 | 
			
		||||
          "type": "workflow_run_status",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "'not-started'"
 | 
			
		||||
        },
 | 
			
		||||
        "ended_at": {
 | 
			
		||||
          "name": "ended_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "started_at": {
 | 
			
		||||
          "name": "started_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflow_runs_workflow_version_id_workflow_versions_id_fk": {
 | 
			
		||||
          "name": "workflow_runs_workflow_version_id_workflow_versions_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_runs",
 | 
			
		||||
          "tableTo": "workflow_versions",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_version_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "set null",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_runs_workflow_id_workflows_id_fk": {
 | 
			
		||||
          "name": "workflow_runs_workflow_id_workflows_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_runs",
 | 
			
		||||
          "tableTo": "workflows",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_runs_machine_id_machines_id_fk": {
 | 
			
		||||
          "name": "workflow_runs_machine_id_machines_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_runs",
 | 
			
		||||
          "tableTo": "machines",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "machine_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "set null",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflows": {
 | 
			
		||||
      "name": "workflows",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "user_id": {
 | 
			
		||||
          "name": "user_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "org_id": {
 | 
			
		||||
          "name": "org_id",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "name": {
 | 
			
		||||
          "name": "name",
 | 
			
		||||
          "type": "text",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflows_user_id_users_id_fk": {
 | 
			
		||||
          "name": "workflows_user_id_users_id_fk",
 | 
			
		||||
          "tableFrom": "workflows",
 | 
			
		||||
          "tableTo": "users",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "user_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_versions": {
 | 
			
		||||
      "name": "workflow_versions",
 | 
			
		||||
      "schema": "comfyui_deploy",
 | 
			
		||||
      "columns": {
 | 
			
		||||
        "workflow_id": {
 | 
			
		||||
          "name": "workflow_id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "id": {
 | 
			
		||||
          "name": "id",
 | 
			
		||||
          "type": "uuid",
 | 
			
		||||
          "primaryKey": true,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "gen_random_uuid()"
 | 
			
		||||
        },
 | 
			
		||||
        "workflow": {
 | 
			
		||||
          "name": "workflow",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "workflow_api": {
 | 
			
		||||
          "name": "workflow_api",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "version": {
 | 
			
		||||
          "name": "version",
 | 
			
		||||
          "type": "integer",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true
 | 
			
		||||
        },
 | 
			
		||||
        "snapshot": {
 | 
			
		||||
          "name": "snapshot",
 | 
			
		||||
          "type": "jsonb",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": false
 | 
			
		||||
        },
 | 
			
		||||
        "created_at": {
 | 
			
		||||
          "name": "created_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        },
 | 
			
		||||
        "updated_at": {
 | 
			
		||||
          "name": "updated_at",
 | 
			
		||||
          "type": "timestamp",
 | 
			
		||||
          "primaryKey": false,
 | 
			
		||||
          "notNull": true,
 | 
			
		||||
          "default": "now()"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "indexes": {},
 | 
			
		||||
      "foreignKeys": {
 | 
			
		||||
        "workflow_versions_workflow_id_workflows_id_fk": {
 | 
			
		||||
          "name": "workflow_versions_workflow_id_workflows_id_fk",
 | 
			
		||||
          "tableFrom": "workflow_versions",
 | 
			
		||||
          "tableTo": "workflows",
 | 
			
		||||
          "columnsFrom": [
 | 
			
		||||
            "workflow_id"
 | 
			
		||||
          ],
 | 
			
		||||
          "columnsTo": [
 | 
			
		||||
            "id"
 | 
			
		||||
          ],
 | 
			
		||||
          "onDelete": "cascade",
 | 
			
		||||
          "onUpdate": "no action"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "compositePrimaryKeys": {},
 | 
			
		||||
      "uniqueConstraints": {}
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "enums": {
 | 
			
		||||
    "deployment_environment": {
 | 
			
		||||
      "name": "deployment_environment",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "staging": "staging",
 | 
			
		||||
        "production": "production",
 | 
			
		||||
        "public-share": "public-share"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machine_gpu": {
 | 
			
		||||
      "name": "machine_gpu",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "T4": "T4",
 | 
			
		||||
        "A10G": "A10G",
 | 
			
		||||
        "A100": "A100"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machine_status": {
 | 
			
		||||
      "name": "machine_status",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "ready": "ready",
 | 
			
		||||
        "building": "building",
 | 
			
		||||
        "error": "error"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "machine_type": {
 | 
			
		||||
      "name": "machine_type",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "classic": "classic",
 | 
			
		||||
        "runpod-serverless": "runpod-serverless",
 | 
			
		||||
        "modal-serverless": "modal-serverless",
 | 
			
		||||
        "comfy-deploy-serverless": "comfy-deploy-serverless"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "subscription_plan": {
 | 
			
		||||
      "name": "subscription_plan",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "basic": "basic",
 | 
			
		||||
        "pro": "pro",
 | 
			
		||||
        "enterprise": "enterprise"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "subscription_plan_status": {
 | 
			
		||||
      "name": "subscription_plan_status",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "active": "active",
 | 
			
		||||
        "deleted": "deleted",
 | 
			
		||||
        "paused": "paused"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_run_origin": {
 | 
			
		||||
      "name": "workflow_run_origin",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "manual": "manual",
 | 
			
		||||
        "api": "api",
 | 
			
		||||
        "public-share": "public-share"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "workflow_run_status": {
 | 
			
		||||
      "name": "workflow_run_status",
 | 
			
		||||
      "values": {
 | 
			
		||||
        "not-started": "not-started",
 | 
			
		||||
        "running": "running",
 | 
			
		||||
        "uploading": "uploading",
 | 
			
		||||
        "success": "success",
 | 
			
		||||
        "failed": "failed"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "schemas": {
 | 
			
		||||
    "comfyui_deploy": "comfyui_deploy"
 | 
			
		||||
  },
 | 
			
		||||
  "_meta": {
 | 
			
		||||
    "schemas": {},
 | 
			
		||||
    "tables": {},
 | 
			
		||||
    "columns": {}
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1001
									
								
								web/drizzle/meta/0039_snapshot.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1001
									
								
								web/drizzle/meta/0039_snapshot.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1007
									
								
								web/drizzle/meta/0040_snapshot.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1007
									
								
								web/drizzle/meta/0040_snapshot.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1013
									
								
								web/drizzle/meta/0041_snapshot.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1013
									
								
								web/drizzle/meta/0041_snapshot.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -246,6 +246,55 @@
 | 
			
		||||
      "when": 1705902960991,
 | 
			
		||||
      "tag": "0034_even_lady_ursula",
 | 
			
		||||
      "breakpoints": true
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "idx": 35,
 | 
			
		||||
      "version": "5",
 | 
			
		||||
      "when": 1705981452482,
 | 
			
		||||
      "tag": "0035_fearless_golden_guardian",
 | 
			
		||||
      "breakpoints": true
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "idx": 36,
 | 
			
		||||
      "version": "5",
 | 
			
		||||
      "when": 1706081335387,
 | 
			
		||||
      "tag": "0036_flippant_meltdown",
 | 
			
		||||
      "breakpoints": true
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "idx": 37,
 | 
			
		||||
      "version": "5",
 | 
			
		||||
      "when": 1706086271525,
 | 
			
		||||
      "tag": "0037_eager_cyclops",
 | 
			
		||||
      "breakpoints": true
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "idx": 38,
 | 
			
		||||
      "version": "5",
 | 
			
		||||
      "when": 1706095853896,
 | 
			
		||||
      "tag": "0038_yummy_darkhawk",
 | 
			
		||||
      "breakpoints": true
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "idx": 39,
 | 
			
		||||
      "version": "5",
 | 
			
		||||
      "when": 1706109812261,
 | 
			
		||||
      "tag": "0039_nostalgic_lyja",
 | 
			
		||||
      "breakpoints": true
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "idx": 40,
 | 
			
		||||
      "version": "5",
 | 
			
		||||
      "when": 1706110859352,
 | 
			
		||||
      "tag": "0040_salty_archangel",
 | 
			
		||||
      "breakpoints": true
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "idx": 41,
 | 
			
		||||
      "version": "5",
 | 
			
		||||
      "when": 1706111421524,
 | 
			
		||||
      "tag": "0041_thick_norrin_radd",
 | 
			
		||||
      "breakpoints": true
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -37,6 +37,7 @@
 | 
			
		||||
    "@radix-ui/react-dropdown-menu": "^2.0.6",
 | 
			
		||||
    "@radix-ui/react-label": "^2.0.2",
 | 
			
		||||
    "@radix-ui/react-popover": "^1.0.7",
 | 
			
		||||
    "@radix-ui/react-progress": "^1.0.3",
 | 
			
		||||
    "@radix-ui/react-radio-group": "^1.1.3",
 | 
			
		||||
    "@radix-ui/react-scroll-area": "^1.0.5",
 | 
			
		||||
    "@radix-ui/react-select": "^2.0.0",
 | 
			
		||||
@ -47,6 +48,7 @@
 | 
			
		||||
    "@radix-ui/react-toggle": "^1.0.3",
 | 
			
		||||
    "@radix-ui/react-tooltip": "^1.0.7",
 | 
			
		||||
    "@sindresorhus/slugify": "^2.2.1",
 | 
			
		||||
    "@stripe/stripe-js": "^2.4.0",
 | 
			
		||||
    "@tailwindcss/typography": "^0.5.10",
 | 
			
		||||
    "@tanstack/react-table": "^8.10.7",
 | 
			
		||||
    "@tanstack/react-virtual": "beta",
 | 
			
		||||
@ -95,6 +97,7 @@
 | 
			
		||||
    "shikiji": "^0.9.3",
 | 
			
		||||
    "simple-functional-loader": "^1.2.1",
 | 
			
		||||
    "sonner": "^1.2.4",
 | 
			
		||||
    "stripe": "^14.13.0",
 | 
			
		||||
    "swagger-ui-react": "^5.11.0",
 | 
			
		||||
    "swr": "^2.2.4",
 | 
			
		||||
    "tailwind-merge": "^2.1.0",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										175
									
								
								web/src/app/(app)/api/stripe/callback/route.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								web/src/app/(app)/api/stripe/callback/route.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,175 @@
 | 
			
		||||
import { auth, clerkClient } from "@clerk/nextjs";
 | 
			
		||||
import { headers } from "next/headers";
 | 
			
		||||
import { redirect } from "next/navigation";
 | 
			
		||||
import { stripe } from "../../../../../server/stripe";
 | 
			
		||||
import { NextResponse } from "next/server";
 | 
			
		||||
import { db } from "@/db/db";
 | 
			
		||||
import { subscriptionStatusTable } from "@/db/schema";
 | 
			
		||||
import { eq } from "drizzle-orm";
 | 
			
		||||
 | 
			
		||||
const secret = process.env.STRIPE_WEBHOOK_SECRET || "";
 | 
			
		||||
 | 
			
		||||
export async function POST(req: Request) {
 | 
			
		||||
  try {
 | 
			
		||||
    const body = await req.text();
 | 
			
		||||
 | 
			
		||||
    const signature = headers().get("stripe-signature");
 | 
			
		||||
 | 
			
		||||
    if (!signature)
 | 
			
		||||
      return new NextResponse("Signature not found.", {
 | 
			
		||||
        status: 500,
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    const event = stripe.webhooks.constructEvent(body, signature, secret);
 | 
			
		||||
 | 
			
		||||
    console.log(event);
 | 
			
		||||
 | 
			
		||||
    if (event.type === "checkout.session.completed") {
 | 
			
		||||
      if (!event.data.object.customer_details?.email) {
 | 
			
		||||
        throw new Error(`missing user email, ${event.id}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const userId = event.data.object.metadata?.userId;
 | 
			
		||||
      const plan = event.data.object.metadata?.plan;
 | 
			
		||||
      if (!userId) {
 | 
			
		||||
        throw new Error(`missing itinerary_id on metadata, ${event.id}`);
 | 
			
		||||
      }
 | 
			
		||||
      if (!plan) {
 | 
			
		||||
        throw new Error(`missing plan on metadata, ${event.id}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const orgId = event.data.object.metadata?.orgId;
 | 
			
		||||
 | 
			
		||||
      const customerId =
 | 
			
		||||
        typeof event.data.object.customer == "string"
 | 
			
		||||
          ? event.data.object.customer
 | 
			
		||||
          : event.data.object.customer?.id;
 | 
			
		||||
      const subscriptionId =
 | 
			
		||||
        typeof event.data.object.subscription == "string"
 | 
			
		||||
          ? event.data.object.subscription
 | 
			
		||||
          : event.data.object.subscription?.id;
 | 
			
		||||
 | 
			
		||||
      if (!customerId) {
 | 
			
		||||
        throw new Error(`missing customerId, ${event.id}`);
 | 
			
		||||
      }
 | 
			
		||||
      if (!subscriptionId) {
 | 
			
		||||
        throw new Error(`missing subscriptionId, ${event.id}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const items = await stripe.subscriptionItems.list({
 | 
			
		||||
        subscription: subscriptionId,
 | 
			
		||||
        limit: 5,
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      // getting the subscription item id for the api plan
 | 
			
		||||
      const subscription_item_api_id = items.data.find(
 | 
			
		||||
        (x) => x.price.id === process.env.STRIPE_PR_API,
 | 
			
		||||
      )?.id;
 | 
			
		||||
 | 
			
		||||
      // the plan could be either pro or enterprise
 | 
			
		||||
      const subscription_item_plan_id =
 | 
			
		||||
        items.data.find((x) => x.price.id === process.env.STRIPE_PR_PRO)?.id ??
 | 
			
		||||
        items.data.find((x) => x.price.id === process.env.STRIPE_PR_ENTERPRISE)
 | 
			
		||||
          ?.id;
 | 
			
		||||
 | 
			
		||||
      if (!subscription_item_api_id) {
 | 
			
		||||
        throw new Error(
 | 
			
		||||
          `missing plan on subscription_item_api_id, ${event.id}`,
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
      if (!subscription_item_plan_id) {
 | 
			
		||||
        throw new Error(
 | 
			
		||||
          `missing plan on subscription_item_plan_id, ${event.id}`,
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      console.log(items);
 | 
			
		||||
 | 
			
		||||
      await db
 | 
			
		||||
        .insert(subscriptionStatusTable)
 | 
			
		||||
        .values({
 | 
			
		||||
          stripe_customer_id: customerId,
 | 
			
		||||
          org_id: orgId,
 | 
			
		||||
          user_id: userId,
 | 
			
		||||
          subscription_id: subscriptionId,
 | 
			
		||||
          plan: plan as "pro" | "enterprise" | "basic",
 | 
			
		||||
          status: "active",
 | 
			
		||||
          subscription_item_api_id: subscription_item_api_id,
 | 
			
		||||
          subscription_item_plan_id: subscription_item_plan_id,
 | 
			
		||||
        })
 | 
			
		||||
        .onConflictDoNothing();
 | 
			
		||||
 | 
			
		||||
      // updateDatabase(event.data.object.metadata.itinerary_id);
 | 
			
		||||
      // sendEmail(event.data.object.customer_details.email);
 | 
			
		||||
    } else if (event.type === "customer.subscription.paused") {
 | 
			
		||||
      const customerId =
 | 
			
		||||
        typeof event.data.object.customer == "string"
 | 
			
		||||
          ? event.data.object.customer
 | 
			
		||||
          : event.data.object.customer?.id;
 | 
			
		||||
 | 
			
		||||
      if (!customerId) {
 | 
			
		||||
        throw new Error(`missing customerId, ${event.id}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      await db
 | 
			
		||||
        .update(subscriptionStatusTable)
 | 
			
		||||
        .set({ status: "paused" })
 | 
			
		||||
        .where(eq(subscriptionStatusTable.stripe_customer_id, customerId));
 | 
			
		||||
    } else if (event.type === "customer.subscription.resumed") {
 | 
			
		||||
      const customerId =
 | 
			
		||||
        typeof event.data.object.customer == "string"
 | 
			
		||||
          ? event.data.object.customer
 | 
			
		||||
          : event.data.object.customer?.id;
 | 
			
		||||
 | 
			
		||||
      if (!customerId) {
 | 
			
		||||
        throw new Error(`missing customerId, ${event.id}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      await db
 | 
			
		||||
        .update(subscriptionStatusTable)
 | 
			
		||||
        .set({ status: "active" })
 | 
			
		||||
        .where(eq(subscriptionStatusTable.stripe_customer_id, customerId));
 | 
			
		||||
    } else if (event.type === "customer.subscription.deleted") {
 | 
			
		||||
      const customerId =
 | 
			
		||||
        typeof event.data.object.customer == "string"
 | 
			
		||||
          ? event.data.object.customer
 | 
			
		||||
          : event.data.object.customer?.id;
 | 
			
		||||
 | 
			
		||||
      if (!customerId) {
 | 
			
		||||
        throw new Error(`missing customerId, ${event.id}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      await db
 | 
			
		||||
        .update(subscriptionStatusTable)
 | 
			
		||||
        .set({ status: "deleted" })
 | 
			
		||||
        .where(eq(subscriptionStatusTable.stripe_customer_id, customerId));
 | 
			
		||||
    } else if (event.type === "customer.subscription.updated") {
 | 
			
		||||
      const customerId =
 | 
			
		||||
        typeof event.data.object.customer == "string"
 | 
			
		||||
          ? event.data.object.customer
 | 
			
		||||
          : event.data.object.customer?.id;
 | 
			
		||||
 | 
			
		||||
      if (!customerId) {
 | 
			
		||||
        throw new Error(`missing customerId, ${event.id}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const cancel_at_period_end = event.data.object.cancel_at_period_end;
 | 
			
		||||
 | 
			
		||||
      await db
 | 
			
		||||
        .update(subscriptionStatusTable)
 | 
			
		||||
        .set({ cancel_at_period_end: cancel_at_period_end })
 | 
			
		||||
        .where(eq(subscriptionStatusTable.stripe_customer_id, customerId));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NextResponse.json({ result: event, ok: true });
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    console.error(error);
 | 
			
		||||
    return NextResponse.json(
 | 
			
		||||
      {
 | 
			
		||||
        message: `Something went wrong: ${error}`,
 | 
			
		||||
        ok: false,
 | 
			
		||||
      },
 | 
			
		||||
      { status: 500 },
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								web/src/app/(app)/api/stripe/checkout/route.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								web/src/app/(app)/api/stripe/checkout/route.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,46 @@
 | 
			
		||||
import { stripe } from "@/server/stripe";
 | 
			
		||||
import { createCheckout } from "@/server/linkToPricing";
 | 
			
		||||
import { auth, clerkClient } from "@clerk/nextjs";
 | 
			
		||||
import { redirect } from "next/navigation";
 | 
			
		||||
import { getUrlServerSide } from "@/server/getUrlServerSide";
 | 
			
		||||
 | 
			
		||||
export async function GET(req: Request) {
 | 
			
		||||
  const { userId, orgId } = auth();
 | 
			
		||||
 | 
			
		||||
  const plan = new URL(req.url).searchParams.get("plan");
 | 
			
		||||
 | 
			
		||||
  if (!userId) return redirect("/");
 | 
			
		||||
  if (!plan) return redirect("/pricing");
 | 
			
		||||
 | 
			
		||||
  const user = await clerkClient.users.getUser(userId);
 | 
			
		||||
 | 
			
		||||
  const mapping = {
 | 
			
		||||
    pro: process.env.STRIPE_PR_PRO,
 | 
			
		||||
    enterprise: process.env.STRIPE_PR_ENTERPRISE,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const api = process.env.STRIPE_PR_API;
 | 
			
		||||
 | 
			
		||||
  const session = await stripe.checkout.sessions.create({
 | 
			
		||||
    success_url: getUrlServerSide(),
 | 
			
		||||
    line_items: [
 | 
			
		||||
      {
 | 
			
		||||
        price: mapping[plan as "pro" | "enterprise"],
 | 
			
		||||
        quantity: 1,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        price: api,
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
    metadata: {
 | 
			
		||||
      userId: userId,
 | 
			
		||||
      orgId: orgId ?? null,
 | 
			
		||||
      plan: plan,
 | 
			
		||||
    },
 | 
			
		||||
    client_reference_id: orgId ?? userId,
 | 
			
		||||
    customer_email: user.emailAddresses[0].emailAddress,
 | 
			
		||||
    mode: "subscription",
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  if (session.url) redirect(session.url);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								web/src/app/(app)/api/stripe/dashboard/route.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								web/src/app/(app)/api/stripe/dashboard/route.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
import { stripe } from "@/server/stripe";
 | 
			
		||||
import { createCheckout } from "@/server/linkToPricing";
 | 
			
		||||
import { auth, clerkClient } from "@clerk/nextjs";
 | 
			
		||||
import { redirect } from "next/navigation";
 | 
			
		||||
import { getUrlServerSide } from "@/server/getUrlServerSide";
 | 
			
		||||
import { db } from "@/db/db";
 | 
			
		||||
import { and, eq, isNull } from "drizzle-orm";
 | 
			
		||||
import { subscriptionStatusTable } from "@/db/schema";
 | 
			
		||||
import { getCurrentPlan } from "@/server/getCurrentPlan";
 | 
			
		||||
 | 
			
		||||
export async function GET(req: Request) {
 | 
			
		||||
  const { userId, orgId } = auth();
 | 
			
		||||
 | 
			
		||||
  if (!userId) return redirect("/");
 | 
			
		||||
 | 
			
		||||
  const change = new URL(req.url).searchParams.get("change");
 | 
			
		||||
 | 
			
		||||
  const sub = await getCurrentPlan({
 | 
			
		||||
    org_id: orgId,
 | 
			
		||||
    user_id: userId,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  if (!sub) return redirect("/pricing");
 | 
			
		||||
 | 
			
		||||
  const session = await stripe.billingPortal.sessions.create({
 | 
			
		||||
    customer: sub.stripe_customer_id,
 | 
			
		||||
    return_url: getUrlServerSide() + "/pricing",
 | 
			
		||||
    // flow_data:
 | 
			
		||||
    //   change === "true" && sub.subscription_id
 | 
			
		||||
    //     ? {
 | 
			
		||||
    //         type: "subscription_update",
 | 
			
		||||
    //         subscription_update: {
 | 
			
		||||
    //           subscription: sub.subscription_id,
 | 
			
		||||
    //         },
 | 
			
		||||
    //       }
 | 
			
		||||
    //     : undefined,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  redirect(session.url);
 | 
			
		||||
  // if (session.url) redirect(session.url);
 | 
			
		||||
}
 | 
			
		||||
@ -6,8 +6,8 @@ import {
 | 
			
		||||
  workflowRunsTable,
 | 
			
		||||
  workflowTable,
 | 
			
		||||
} from "@/db/schema";
 | 
			
		||||
import { getDuration } from "@/lib/getRelativeTime";
 | 
			
		||||
import { getSubscription, setUsage } from "@/server/linkToPricing";
 | 
			
		||||
import { getCurrentPlan } from "@/server/getCurrentPlan";
 | 
			
		||||
import { stripe } from "@/server/stripe";
 | 
			
		||||
import { eq } from "drizzle-orm";
 | 
			
		||||
import { NextResponse } from "next/server";
 | 
			
		||||
import { z } from "zod";
 | 
			
		||||
@ -34,21 +34,51 @@ export async function POST(request: Request) {
 | 
			
		||||
      data: output_data,
 | 
			
		||||
    });
 | 
			
		||||
  } else if (status) {
 | 
			
		||||
    const workflow_run = await db
 | 
			
		||||
    const [workflow_run] = await db
 | 
			
		||||
      .update(workflowRunsTable)
 | 
			
		||||
      .set({
 | 
			
		||||
        status: status,
 | 
			
		||||
        ended_at:
 | 
			
		||||
          status === "success" || status === "failed" ? new Date() : null,
 | 
			
		||||
      })
 | 
			
		||||
      .where(eq(workflowRunsTable.id, run_id));
 | 
			
		||||
      .where(eq(workflowRunsTable.id, run_id))
 | 
			
		||||
      .returning();
 | 
			
		||||
 | 
			
		||||
    // get data from workflowRunsTable
 | 
			
		||||
    const userUsageTime = await importUserUsageData(run_id);
 | 
			
		||||
    // Need to filter out only comfy deploy serverless
 | 
			
		||||
    // Also multiply with the gpu selection
 | 
			
		||||
    if (workflow_run.machine_type == "comfy-deploy-serverless") {
 | 
			
		||||
      if (
 | 
			
		||||
        (status === "success" || status === "failed") &&
 | 
			
		||||
        workflow_run.user_id
 | 
			
		||||
      ) {
 | 
			
		||||
        const sub = await getCurrentPlan({
 | 
			
		||||
          user_id: workflow_run.user_id,
 | 
			
		||||
          org_id: workflow_run.org_id,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    if (userUsageTime) {
 | 
			
		||||
      // get the usage_time from userUsage
 | 
			
		||||
      await addSubscriptionUnit(userUsageTime);
 | 
			
		||||
        if (sub && sub.subscription_item_api_id && workflow_run.ended_at) {
 | 
			
		||||
          let durationInSec = Math.abs(
 | 
			
		||||
            (workflow_run.ended_at.getTime() -
 | 
			
		||||
              workflow_run.created_at.getTime()) /
 | 
			
		||||
              1000,
 | 
			
		||||
          );
 | 
			
		||||
          durationInSec = Math.ceil(durationInSec);
 | 
			
		||||
          switch (workflow_run.gpu) {
 | 
			
		||||
            case "A100":
 | 
			
		||||
              durationInSec *= 7;
 | 
			
		||||
              break;
 | 
			
		||||
            case "A10G":
 | 
			
		||||
              durationInSec *= 4;
 | 
			
		||||
              break;
 | 
			
		||||
          }
 | 
			
		||||
          await stripe.subscriptionItems.createUsageRecord(
 | 
			
		||||
            sub.subscription_item_api_id,
 | 
			
		||||
            {
 | 
			
		||||
              quantity: durationInSec,
 | 
			
		||||
            },
 | 
			
		||||
          );
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -64,50 +94,6 @@ export async function POST(request: Request) {
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      status: 200,
 | 
			
		||||
    }
 | 
			
		||||
    },
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function addSubscriptionUnit(userUsageTime: number) {
 | 
			
		||||
  const subscription = await getSubscription();
 | 
			
		||||
 | 
			
		||||
  // round up userUsageTime to the nearest integer
 | 
			
		||||
  const roundedUsageTime = Math.ceil(userUsageTime);
 | 
			
		||||
 | 
			
		||||
  if (subscription) {
 | 
			
		||||
    const usage = await setUsage(
 | 
			
		||||
      subscription.data[0].attributes.first_subscription_item.id,
 | 
			
		||||
      roundedUsageTime
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function importUserUsageData(run_id: string) {
 | 
			
		||||
  const workflowRuns = await db.query.workflowRunsTable.findFirst({
 | 
			
		||||
    where: eq(workflowRunsTable.id, run_id),
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  if (!workflowRuns?.workflow_id) return;
 | 
			
		||||
 | 
			
		||||
  // find if workflowTable id column contains workflowRunsTable workflow_id
 | 
			
		||||
  const workflow = await db.query.workflowTable.findFirst({
 | 
			
		||||
    where: eq(workflowTable.id, workflowRuns.workflow_id),
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  if (workflowRuns?.ended_at === null || workflow == null) return;
 | 
			
		||||
 | 
			
		||||
  const usageTime = parseFloat(
 | 
			
		||||
    getDuration((workflowRuns?.ended_at - workflowRuns?.started_at) / 1000)
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  // add data to userUsageTable
 | 
			
		||||
  const user_usage = await db.insert(userUsageTable).values({
 | 
			
		||||
    user_id: workflow.user_id,
 | 
			
		||||
    created_at: workflowRuns.ended_at,
 | 
			
		||||
    org_id: workflow.org_id,
 | 
			
		||||
    ended_at: workflowRuns.ended_at,
 | 
			
		||||
    usage_time: usageTime,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return usageTime;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,81 +0,0 @@
 | 
			
		||||
const people = [
 | 
			
		||||
  {
 | 
			
		||||
    name: "Nvidia T4 GPU",
 | 
			
		||||
    gpu: "1x",
 | 
			
		||||
    ram: "16GB",
 | 
			
		||||
    price: "$0.000225/sec",
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: "Nvidia A40 GPU",
 | 
			
		||||
    gpu: "1x",
 | 
			
		||||
    ram: "48GB",
 | 
			
		||||
    price: "$0.000575/sec",
 | 
			
		||||
  },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export function GpuPricingPlan() {
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="flex justify-center w-full py-8">
 | 
			
		||||
      <div className="w-full max-w-4xl">
 | 
			
		||||
        <table className="min-w-full divide-y divide-gray-300">
 | 
			
		||||
          <thead>
 | 
			
		||||
            <tr>
 | 
			
		||||
              <th
 | 
			
		||||
                scope="col"
 | 
			
		||||
                className="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6"
 | 
			
		||||
              >
 | 
			
		||||
                GPU
 | 
			
		||||
              </th>
 | 
			
		||||
              <th
 | 
			
		||||
                scope="col"
 | 
			
		||||
                className="hidden px-3 py-3.5 text-left text-sm font-semibold text-gray-900 lg:table-cell"
 | 
			
		||||
              >
 | 
			
		||||
                No.
 | 
			
		||||
              </th>
 | 
			
		||||
              <th
 | 
			
		||||
                scope="col"
 | 
			
		||||
                className="hidden px-3 py-3.5 text-left text-sm font-semibold text-gray-900 sm:table-cell"
 | 
			
		||||
              >
 | 
			
		||||
                RAM
 | 
			
		||||
              </th>
 | 
			
		||||
              <th
 | 
			
		||||
                scope="col"
 | 
			
		||||
                className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
 | 
			
		||||
              >
 | 
			
		||||
                Price
 | 
			
		||||
              </th>
 | 
			
		||||
            </tr>
 | 
			
		||||
          </thead>
 | 
			
		||||
          <tbody className="divide-y divide-gray-200 bg-white">
 | 
			
		||||
            {people.map((person) => (
 | 
			
		||||
              <tr key={person.ram} className="even:bg-gray-50">
 | 
			
		||||
                <td className="w-full max-w-0 py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:w-auto sm:max-w-none sm:pl-6">
 | 
			
		||||
                  {person.name}
 | 
			
		||||
                  <dl className="font-normal lg:hidden">
 | 
			
		||||
                    <dt className="sr-only">No.</dt>
 | 
			
		||||
                    <dd className="mt-1 truncate text-gray-700">
 | 
			
		||||
                      {person.gpu}
 | 
			
		||||
                    </dd>
 | 
			
		||||
                    <dt className="sr-only sm:hidden">RAM</dt>
 | 
			
		||||
                    <dd className="mt-1 truncate text-gray-500 sm:hidden">
 | 
			
		||||
                      {person.ram}
 | 
			
		||||
                    </dd>
 | 
			
		||||
                  </dl>
 | 
			
		||||
                </td>
 | 
			
		||||
                <td className="hidden px-3 py-4 text-sm text-gray-500 lg:table-cell">
 | 
			
		||||
                  {person.gpu}
 | 
			
		||||
                </td>
 | 
			
		||||
                <td className="hidden px-3 py-4 text-sm text-gray-500 sm:table-cell">
 | 
			
		||||
                  {person.ram}
 | 
			
		||||
                </td>
 | 
			
		||||
                <td className="px-3 py-4 text-sm text-gray-500">
 | 
			
		||||
                  {person.price}
 | 
			
		||||
                </td>
 | 
			
		||||
              </tr>
 | 
			
		||||
            ))}
 | 
			
		||||
          </tbody>
 | 
			
		||||
        </table>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
@ -1,157 +0,0 @@
 | 
			
		||||
import { checkMarkIcon, crossMarkIcon } from "../const/Icon";
 | 
			
		||||
import { cn } from "@/lib/utils";
 | 
			
		||||
import { getPricing } from "@/server/linkToPricing";
 | 
			
		||||
import { useEffect, useState } from "react";
 | 
			
		||||
 | 
			
		||||
type Tier = {
 | 
			
		||||
  name: string;
 | 
			
		||||
  id: string;
 | 
			
		||||
  href: string;
 | 
			
		||||
  priceMonthly: string;
 | 
			
		||||
  description: string;
 | 
			
		||||
  features: string[];
 | 
			
		||||
  featured: boolean;
 | 
			
		||||
  priority?: TierPriority;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum TierPriority {
 | 
			
		||||
  Free = "free",
 | 
			
		||||
  Pro = "pro",
 | 
			
		||||
  Enterprise = "enterprise",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default function PricingList() {
 | 
			
		||||
  const [productTiers, setProductTiers] = useState<Tier[]>();
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    (async () => {
 | 
			
		||||
      const product = await getPricing();
 | 
			
		||||
 | 
			
		||||
      if (!product) return;
 | 
			
		||||
 | 
			
		||||
      const newProductTiers: Tier[] = product.data.map((item) => {
 | 
			
		||||
        // Create a new DOMParser instance
 | 
			
		||||
        const parser = new DOMParser();
 | 
			
		||||
        // Parse the description HTML string to a new document
 | 
			
		||||
        const doc = parser.parseFromString(
 | 
			
		||||
          item.attributes.description,
 | 
			
		||||
          "text/html"
 | 
			
		||||
        );
 | 
			
		||||
        // Extract the description and features
 | 
			
		||||
        const description = doc.querySelector("p")?.textContent || "";
 | 
			
		||||
        const features = Array.from(doc.querySelectorAll("ul > li")).map(
 | 
			
		||||
          (li) => li.textContent || ""
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
          name: item.attributes.name,
 | 
			
		||||
          id: item.id,
 | 
			
		||||
          href: item.attributes.buy_now_url,
 | 
			
		||||
          priceMonthly:
 | 
			
		||||
            item.attributes.price_formatted.split("/")[0] == "Usage-based"
 | 
			
		||||
              ? "$20.00"
 | 
			
		||||
              : item.attributes.price_formatted.split("/")[0],
 | 
			
		||||
          description: description,
 | 
			
		||||
          features: features,
 | 
			
		||||
 | 
			
		||||
          // if name contains pro, it's featured
 | 
			
		||||
          featured: item.attributes.name.toLowerCase().includes("pro"),
 | 
			
		||||
 | 
			
		||||
          // give priority if name contain in enum
 | 
			
		||||
          priority: Object.values(TierPriority).find((priority) =>
 | 
			
		||||
            item.attributes.name.toLowerCase().includes(priority)
 | 
			
		||||
          ),
 | 
			
		||||
        };
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      // sort newProductTiers by priority
 | 
			
		||||
      newProductTiers.sort((a, b) => {
 | 
			
		||||
        if (!a.priority) return 1;
 | 
			
		||||
        if (!b.priority) return -1;
 | 
			
		||||
        return (
 | 
			
		||||
          Object.values(TierPriority).indexOf(a.priority) -
 | 
			
		||||
          Object.values(TierPriority).indexOf(b.priority)
 | 
			
		||||
        );
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      setProductTiers(newProductTiers);
 | 
			
		||||
    })();
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="relative isolate px-6 py-24 lg:px-8">
 | 
			
		||||
      <div className="mx-auto max-w-2xl text-center lg:max-w-4xl">
 | 
			
		||||
        <h2 className="text-base font-semibold leading-7 text-indigo-600">
 | 
			
		||||
          Pricing
 | 
			
		||||
        </h2>
 | 
			
		||||
        <p className="mt-2 text-4xl font-bold tracking-tight text-gray-900 sm:text-5xl">
 | 
			
		||||
          The right price for you, whoever you are
 | 
			
		||||
        </p>
 | 
			
		||||
      </div>
 | 
			
		||||
      <p className="mx-auto mt-6 max-w-2xl text-center text-lg leading-8 text-gray-600">
 | 
			
		||||
        Qui iusto aut est earum eos quae. Eligendi est at nam aliquid ad quo
 | 
			
		||||
        reprehenderit in aliquid fugiat dolorum voluptatibus.
 | 
			
		||||
      </p>
 | 
			
		||||
      <div className="mx-auto mt-16 grid max-w-lg grid-cols-1 items-center gap-y-6 sm:mt-20 sm:gap-y-0 lg:max-w-4xl lg:grid-cols-2 xl:max-w-6xl xl:grid-cols-3">
 | 
			
		||||
        {productTiers &&
 | 
			
		||||
          productTiers.map((tier, tierIdx) => (
 | 
			
		||||
            <div
 | 
			
		||||
              key={tier.id}
 | 
			
		||||
              className={cn(
 | 
			
		||||
                tier.featured
 | 
			
		||||
                  ? "relative bg-white shadow-2xl"
 | 
			
		||||
                  : "bg-white/60 sm:mx-8 lg:mx-0",
 | 
			
		||||
                tier.featured
 | 
			
		||||
                  ? ""
 | 
			
		||||
                  : tierIdx === 0
 | 
			
		||||
                  ? "rounded-t-3xl sm:rounded-b-none lg:rounded-tr-none lg:rounded-bl-3xl"
 | 
			
		||||
                  : "sm:rounded-t-none lg:rounded-tr-3xl lg:rounded-bl-none",
 | 
			
		||||
                "rounded-3xl p-8 ring-1 ring-gray-900/10 sm:p-10"
 | 
			
		||||
              )}
 | 
			
		||||
            >
 | 
			
		||||
              <h3
 | 
			
		||||
                id={tier.id}
 | 
			
		||||
                className="text-base font-semibold leading-7 text-indigo-600"
 | 
			
		||||
              >
 | 
			
		||||
                {tier.name}
 | 
			
		||||
              </h3>
 | 
			
		||||
              <p className="mt-4 flex items-baseline gap-x-2">
 | 
			
		||||
                <span className="text-5xl font-bold tracking-tight text-gray-900">
 | 
			
		||||
                  {tier.priceMonthly}
 | 
			
		||||
                </span>
 | 
			
		||||
                <span className="text-base text-gray-500">/month</span>
 | 
			
		||||
              </p>
 | 
			
		||||
              <p className="mt-6 text-base leading-7 text-gray-600">
 | 
			
		||||
                {tier.description}
 | 
			
		||||
              </p>
 | 
			
		||||
              <ul
 | 
			
		||||
                role="list"
 | 
			
		||||
                className="mt-8 space-y-3 text-sm leading-6 text-gray-600 sm:mt-10"
 | 
			
		||||
              >
 | 
			
		||||
                {tier.features.map((feature) => (
 | 
			
		||||
                  <li key={feature} className="flex gap-x-3">
 | 
			
		||||
                    <div className="flex justify-center items-center">
 | 
			
		||||
                      {feature.includes("[x]") ? crossMarkIcon : checkMarkIcon}
 | 
			
		||||
                    </div>
 | 
			
		||||
                    {feature.replace("[x]", "")}
 | 
			
		||||
                  </li>
 | 
			
		||||
                ))}
 | 
			
		||||
              </ul>
 | 
			
		||||
              <a
 | 
			
		||||
                href={tier.href}
 | 
			
		||||
                aria-describedby={tier.id}
 | 
			
		||||
                className={cn(
 | 
			
		||||
                  tier.featured
 | 
			
		||||
                    ? "bg-indigo-600 text-white shadow hover:bg-indigo-500"
 | 
			
		||||
                    : "text-indigo-600 ring-1 ring-inset ring-indigo-200 hover:ring-indigo-300",
 | 
			
		||||
                  "mt-8 block rounded-md py-2.5 px-3.5 text-center text-sm font-semibold focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 sm:mt-10"
 | 
			
		||||
                )}
 | 
			
		||||
              >
 | 
			
		||||
                Get started today
 | 
			
		||||
              </a>
 | 
			
		||||
            </div>
 | 
			
		||||
          ))}
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
@ -1,37 +0,0 @@
 | 
			
		||||
export const checkMarkIcon = (
 | 
			
		||||
  <svg
 | 
			
		||||
    className="h-5 w-5 flex-shrink-0 text-green-500"
 | 
			
		||||
    xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
    viewBox="0 0 20 20"
 | 
			
		||||
    fill="currentColor"
 | 
			
		||||
    aria-hidden="true"
 | 
			
		||||
  >
 | 
			
		||||
    <path
 | 
			
		||||
      fillRule="evenodd"
 | 
			
		||||
      d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z"
 | 
			
		||||
      clipRule="evenodd"
 | 
			
		||||
    />
 | 
			
		||||
  </svg>
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const crossMarkIcon = (
 | 
			
		||||
  <svg
 | 
			
		||||
    xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
    x="0px"
 | 
			
		||||
    y="0px"
 | 
			
		||||
    width="20"
 | 
			
		||||
    height="20"
 | 
			
		||||
    viewBox="0 0 48 48"
 | 
			
		||||
  >
 | 
			
		||||
    <path
 | 
			
		||||
      fill="#F44336"
 | 
			
		||||
      d="M21.5 4.5H26.501V43.5H21.5z"
 | 
			
		||||
      transform="rotate(45.001 24 24)"
 | 
			
		||||
    />
 | 
			
		||||
    <path
 | 
			
		||||
      fill="#F44336"
 | 
			
		||||
      d="M21.5 4.5H26.5V43.501H21.5z"
 | 
			
		||||
      transform="rotate(135.008 24 24)"
 | 
			
		||||
    />
 | 
			
		||||
  </svg>
 | 
			
		||||
);
 | 
			
		||||
@ -1,13 +1,9 @@
 | 
			
		||||
"use client";
 | 
			
		||||
 | 
			
		||||
import { GpuPricingPlan } from "@/app/(app)/pricing/components/gpuPricingTable";
 | 
			
		||||
import PricingList from "@/app/(app)/pricing/components/pricePlanList";
 | 
			
		||||
import PricingList from "@/components/PricingPlan";
 | 
			
		||||
 | 
			
		||||
export default function Home() {
 | 
			
		||||
  return (
 | 
			
		||||
    <div>
 | 
			
		||||
      <PricingList />
 | 
			
		||||
      <GpuPricingPlan />
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,19 +1,19 @@
 | 
			
		||||
// app/providers.tsx
 | 
			
		||||
'use client'
 | 
			
		||||
import posthog from 'posthog-js'
 | 
			
		||||
import { PostHogProvider } from 'posthog-js/react'
 | 
			
		||||
"use client";
 | 
			
		||||
import posthog from "posthog-js";
 | 
			
		||||
import { PostHogProvider } from "posthog-js/react";
 | 
			
		||||
 | 
			
		||||
if (typeof window !== 'undefined') {
 | 
			
		||||
if (typeof window !== "undefined") {
 | 
			
		||||
  posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
 | 
			
		||||
    api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
 | 
			
		||||
    capture_pageview: false // Disable automatic pageview capture, as we capture manually
 | 
			
		||||
  })
 | 
			
		||||
    capture_pageview: false, // Disable automatic pageview capture, as we capture manually
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function PHProvider({
 | 
			
		||||
  children,
 | 
			
		||||
}: {
 | 
			
		||||
  children: React.ReactNode
 | 
			
		||||
  children: React.ReactNode;
 | 
			
		||||
}) {
 | 
			
		||||
  return <PostHogProvider client={posthog}>{children}</PostHogProvider>
 | 
			
		||||
  return <PostHogProvider client={posthog}>{children}</PostHogProvider>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								web/src/app/(app)/usage/loading.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								web/src/app/(app)/usage/loading.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
"use client";
 | 
			
		||||
 | 
			
		||||
import { LoadingPageWrapper } from "@/components/LoadingWrapper";
 | 
			
		||||
import { usePathname } from "next/navigation";
 | 
			
		||||
 | 
			
		||||
export default function Loading() {
 | 
			
		||||
  const pathName = usePathname();
 | 
			
		||||
  return <LoadingPageWrapper className="h-full" tag={pathName.toLowerCase()} />;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										57
									
								
								web/src/app/(app)/usage/page.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								web/src/app/(app)/usage/page.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,57 @@
 | 
			
		||||
import PricingList from "@/components/PricingPlan";
 | 
			
		||||
import { Badge } from "@/components/ui/badge";
 | 
			
		||||
import {
 | 
			
		||||
  Card,
 | 
			
		||||
  CardContent,
 | 
			
		||||
  CardDescription,
 | 
			
		||||
  CardHeader,
 | 
			
		||||
  CardTitle,
 | 
			
		||||
} from "@/components/ui/card";
 | 
			
		||||
import { Progress } from "@/components/ui/progress";
 | 
			
		||||
import { getCurrentPlanWithAuth } from "@/server/getCurrentPlan";
 | 
			
		||||
import { stripe } from "@/server/stripe";
 | 
			
		||||
 | 
			
		||||
const freeTierSeconds = 30000;
 | 
			
		||||
 | 
			
		||||
export default async function Home() {
 | 
			
		||||
  const sub = await getCurrentPlanWithAuth();
 | 
			
		||||
 | 
			
		||||
  const data = sub?.subscription_item_api_id
 | 
			
		||||
    ? await stripe.subscriptionItems.listUsageRecordSummaries(
 | 
			
		||||
        sub?.subscription_item_api_id,
 | 
			
		||||
      )
 | 
			
		||||
    : null;
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="mt-4 flex items-center justify-center">
 | 
			
		||||
      <Card className="p-4 w-full max-w-[600px]">
 | 
			
		||||
        <CardHeader>
 | 
			
		||||
          <CardTitle>Account Usage</CardTitle>
 | 
			
		||||
          <CardDescription>View you account usage</CardDescription>
 | 
			
		||||
          <Badge className="w-fit">{sub?.plan}</Badge>
 | 
			
		||||
        </CardHeader>
 | 
			
		||||
        {data && (
 | 
			
		||||
          <CardContent className="text-sm flex flex-col gap-2">
 | 
			
		||||
            <div className="flex justify-between gap-2">
 | 
			
		||||
              <span>Current free gpu usage:</span>
 | 
			
		||||
              {
 | 
			
		||||
                <div className="flex gap-2">
 | 
			
		||||
                  <Badge>
 | 
			
		||||
                    {data.data[0].total_usage}s /{Math.floor(freeTierSeconds)}s
 | 
			
		||||
                  </Badge>
 | 
			
		||||
                  <Badge>
 | 
			
		||||
                    {Math.floor(data.data[0].total_usage / 60 / 60)}hr /
 | 
			
		||||
                    {Math.floor(freeTierSeconds / 60 / 60)}hr
 | 
			
		||||
                  </Badge>
 | 
			
		||||
                </div>
 | 
			
		||||
              }
 | 
			
		||||
            </div>
 | 
			
		||||
            <Progress
 | 
			
		||||
              value={(data.data[0].total_usage / freeTierSeconds) * 100}
 | 
			
		||||
            ></Progress>
 | 
			
		||||
          </CardContent>
 | 
			
		||||
        )}
 | 
			
		||||
      </Card>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
@ -91,13 +91,22 @@ export function Navbar() {
 | 
			
		||||
      <div className="flex flex-row items-center gap-2">
 | 
			
		||||
        {isDesktop && <NavbarMenu />}
 | 
			
		||||
        {pricingPlanFlagEnable && (
 | 
			
		||||
          <Button
 | 
			
		||||
            asChild
 | 
			
		||||
            variant="link"
 | 
			
		||||
            className="rounded-full aspect-square p-2 mr-4"
 | 
			
		||||
          >
 | 
			
		||||
            <a href="/pricing">Pricing</a>
 | 
			
		||||
          </Button>
 | 
			
		||||
          <>
 | 
			
		||||
            <Button
 | 
			
		||||
              asChild
 | 
			
		||||
              variant="link"
 | 
			
		||||
              className="rounded-full aspect-square p-2 mr-4"
 | 
			
		||||
            >
 | 
			
		||||
              <a href="/pricing">Pricing</a>
 | 
			
		||||
            </Button>
 | 
			
		||||
            <Button
 | 
			
		||||
              asChild
 | 
			
		||||
              variant="link"
 | 
			
		||||
              className="rounded-full aspect-square p-2 mr-4"
 | 
			
		||||
            >
 | 
			
		||||
              <a href="/usage">Usage</a>
 | 
			
		||||
            </Button>
 | 
			
		||||
          </>
 | 
			
		||||
        )}
 | 
			
		||||
        <Button
 | 
			
		||||
          asChild
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										381
									
								
								web/src/components/PricingPlan.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										381
									
								
								web/src/components/PricingPlan.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,381 @@
 | 
			
		||||
import {
 | 
			
		||||
  Tooltip,
 | 
			
		||||
  TooltipContent,
 | 
			
		||||
  TooltipTrigger,
 | 
			
		||||
} from "@/components/ui/tooltip";
 | 
			
		||||
import { cn } from "@/lib/utils";
 | 
			
		||||
import { Check, Info, Minus } from "lucide-react";
 | 
			
		||||
 | 
			
		||||
import { Fragment } from "react";
 | 
			
		||||
import { auth } from "@clerk/nextjs";
 | 
			
		||||
import { subscriptionPlanStatus } from "@/db/schema";
 | 
			
		||||
import { getCurrentPlan } from "../server/getCurrentPlan";
 | 
			
		||||
 | 
			
		||||
const tiers = [
 | 
			
		||||
  {
 | 
			
		||||
    name: "Basic",
 | 
			
		||||
    id: "basic",
 | 
			
		||||
    // href: "/api/checkout?plan=basic",
 | 
			
		||||
    href: "/workflows",
 | 
			
		||||
    priceMonthly: "$0",
 | 
			
		||||
    description: "Instant Comfy UI API",
 | 
			
		||||
    mostPopular: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: "Pro",
 | 
			
		||||
    id: "pro",
 | 
			
		||||
    href: "/api/stripe/checkout?plan=pro",
 | 
			
		||||
    priceMonthly: "$20",
 | 
			
		||||
    description: "Accelerate Comfy UI",
 | 
			
		||||
    mostPopular: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: "Enterprise",
 | 
			
		||||
    id: "enterprise",
 | 
			
		||||
    href: "/api/stripe/checkout?plan=enterprise",
 | 
			
		||||
    priceMonthly: "$100",
 | 
			
		||||
    description: "Scale your Products",
 | 
			
		||||
    mostPopular: true,
 | 
			
		||||
  },
 | 
			
		||||
];
 | 
			
		||||
const sections = [
 | 
			
		||||
  {
 | 
			
		||||
    name: "Features",
 | 
			
		||||
    features: [
 | 
			
		||||
      {
 | 
			
		||||
        name: "GPU",
 | 
			
		||||
        tiers: { Basic: "T4", Pro: "T4, A10G", Enterprise: "T4, A10G, A100" },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: "Compute Credit",
 | 
			
		||||
        tiers: {
 | 
			
		||||
          Basic: (
 | 
			
		||||
            <Tooltip>
 | 
			
		||||
              <TooltipTrigger className="flex items-center justify-center gap-2">
 | 
			
		||||
                30k secs free + usage <Info size={14} />
 | 
			
		||||
              </TooltipTrigger>
 | 
			
		||||
              <TooltipContent>
 | 
			
		||||
                <ul className="flex flex-col items-start justify-start">
 | 
			
		||||
                  GPU Price /s = $0.00015
 | 
			
		||||
                  <li>- T4 Multiplier = x1</li>
 | 
			
		||||
                </ul>
 | 
			
		||||
              </TooltipContent>
 | 
			
		||||
            </Tooltip>
 | 
			
		||||
          ),
 | 
			
		||||
          Pro: (
 | 
			
		||||
            <Tooltip>
 | 
			
		||||
              <TooltipTrigger className="flex items-center justify-center gap-2">
 | 
			
		||||
                30k secs free + usage <Info size={14} />
 | 
			
		||||
              </TooltipTrigger>
 | 
			
		||||
              <TooltipContent>
 | 
			
		||||
                <ul className="flex flex-col items-start justify-start">
 | 
			
		||||
                  GPU Price /s = $0.00015
 | 
			
		||||
                  <li>- T4 Multiplier = x1</li>
 | 
			
		||||
                  <li>- A10G Multiplier = x4</li>
 | 
			
		||||
                </ul>
 | 
			
		||||
              </TooltipContent>
 | 
			
		||||
            </Tooltip>
 | 
			
		||||
          ),
 | 
			
		||||
          Enterprise: (
 | 
			
		||||
            <Tooltip>
 | 
			
		||||
              <TooltipTrigger className="flex items-center justify-center gap-2">
 | 
			
		||||
                30k secs free + usage <Info size={14} />
 | 
			
		||||
              </TooltipTrigger>
 | 
			
		||||
              <TooltipContent>
 | 
			
		||||
                <ul className="flex flex-col items-start justify-start">
 | 
			
		||||
                  GPU Price /s = $0.00015
 | 
			
		||||
                  <li>- T4 Multiplier = x1</li>
 | 
			
		||||
                  <li>- A10G Multiplier = x4</li>
 | 
			
		||||
                  <li>- A100 Multiplier = x7</li>
 | 
			
		||||
                </ul>
 | 
			
		||||
              </TooltipContent>
 | 
			
		||||
            </Tooltip>
 | 
			
		||||
          ),
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: "Workflows",
 | 
			
		||||
        tiers: { Basic: "2", Pro: "25", Enterprise: "Unlimited" },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: "Serverless Machines",
 | 
			
		||||
        tiers: { Basic: "2", Pro: "10", Enterprise: "Unlimited" },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: "Outputs Storage",
 | 
			
		||||
        tiers: { Basic: "2 GB", Pro: "10 GB", Enterprise: "Unlimited" },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: "Dedicated Support",
 | 
			
		||||
        tiers: { Enterprise: true },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: "Private Model Hosting",
 | 
			
		||||
        tiers: { Enterprise: "Coming Soon" },
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export default async function PricingList() {
 | 
			
		||||
  const { userId, orgId } = auth();
 | 
			
		||||
 | 
			
		||||
  if (!userId) {
 | 
			
		||||
    return <>No user id</>;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const sub = await getCurrentPlan({ user_id: userId, org_id: orgId });
 | 
			
		||||
 | 
			
		||||
  const getHrefFromTier = (tier: (typeof tiers)[0]) => {
 | 
			
		||||
    if (sub?.status == "active") {
 | 
			
		||||
      if (tier.id == sub?.plan) return "/api/stripe/dashboard";
 | 
			
		||||
      // This is actually cancelled
 | 
			
		||||
      if (sub.cancel_at_period_end) return tier.href;
 | 
			
		||||
      return "/api/stripe/dashboard?change=true";
 | 
			
		||||
    } else {
 | 
			
		||||
      return tier.href;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
  const getNameFromTier = (tier: (typeof tiers)[0]) => {
 | 
			
		||||
    if (tier.id == sub?.plan && sub.status == "active") {
 | 
			
		||||
      return sub.cancel_at_period_end ? (
 | 
			
		||||
        <>
 | 
			
		||||
          Current <span className="text-2xs"> - Ending this period</span>
 | 
			
		||||
        </>
 | 
			
		||||
      ) : (
 | 
			
		||||
        "Current"
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    if (sub?.status == "active") {
 | 
			
		||||
      return "Get Started";
 | 
			
		||||
    } else {
 | 
			
		||||
      return "Get Started";
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="bg-white py-24 sm:py-32">
 | 
			
		||||
      <div className="mx-auto max-w-7xl px-6 lg:px-8">
 | 
			
		||||
        <div className="mx-auto max-w-4xl text-center">
 | 
			
		||||
          <h2 className="text-base font-semibold leading-7 text-indigo-600">
 | 
			
		||||
            Pricing
 | 
			
		||||
          </h2>
 | 
			
		||||
          <p className="mt-2 text-4xl font-bold tracking-tight text-gray-900 sm:text-5xl">
 | 
			
		||||
            Turn any workflow into API
 | 
			
		||||
          </p>
 | 
			
		||||
        </div>
 | 
			
		||||
        <p className="mx-auto mt-6 max-w-2xl text-center text-lg leading-8 text-gray-600">
 | 
			
		||||
          ComfyDeploy is now under technical preview.
 | 
			
		||||
        </p>
 | 
			
		||||
 | 
			
		||||
        {/* xs to lg */}
 | 
			
		||||
        <div className="mx-auto mt-12 max-w-md space-y-8 sm:mt-16 lg:hidden">
 | 
			
		||||
          {tiers.map((tier) => (
 | 
			
		||||
            <section
 | 
			
		||||
              key={tier.id}
 | 
			
		||||
              className={cn(
 | 
			
		||||
                tier.mostPopular
 | 
			
		||||
                  ? "rounded-xl bg-gray-400/5 ring-1 ring-inset ring-gray-200"
 | 
			
		||||
                  : "",
 | 
			
		||||
                "p-8",
 | 
			
		||||
              )}
 | 
			
		||||
            >
 | 
			
		||||
              <h3
 | 
			
		||||
                id={tier.id}
 | 
			
		||||
                className="text-sm font-semibold leading-6 text-gray-900"
 | 
			
		||||
              >
 | 
			
		||||
                {tier.name}
 | 
			
		||||
              </h3>
 | 
			
		||||
              <p className="mt-2 flex items-baseline gap-x-1 text-gray-900">
 | 
			
		||||
                <span className="text-4xl font-bold">{tier.priceMonthly}</span>
 | 
			
		||||
                <span className="text-sm font-semibold">/month</span>
 | 
			
		||||
              </p>
 | 
			
		||||
              <br></br>
 | 
			
		||||
              <div className="text-xl font-semibold">{tier.description}</div>
 | 
			
		||||
              <a
 | 
			
		||||
                href={getHrefFromTier(tier)}
 | 
			
		||||
                aria-describedby={tier.id}
 | 
			
		||||
                className={cn(
 | 
			
		||||
                  tier.mostPopular
 | 
			
		||||
                    ? "bg-indigo-600 text-white hover:bg-indigo-500"
 | 
			
		||||
                    : "text-indigo-600 ring-1 ring-inset ring-indigo-200 hover:ring-indigo-300",
 | 
			
		||||
                  "mt-8 block rounded-md py-2 px-3 text-center text-sm font-semibold leading-6 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600",
 | 
			
		||||
                )}
 | 
			
		||||
              >
 | 
			
		||||
                {getNameFromTier(tier)}
 | 
			
		||||
              </a>
 | 
			
		||||
              <ul
 | 
			
		||||
                role="list"
 | 
			
		||||
                className="mt-10 space-y-4 text-sm leading-6 text-gray-900"
 | 
			
		||||
              >
 | 
			
		||||
                {sections.map((section) => (
 | 
			
		||||
                  <li key={section.name}>
 | 
			
		||||
                    <ul role="list" className="space-y-4">
 | 
			
		||||
                      {section.features.map((feature) =>
 | 
			
		||||
                        feature.tiers[tier.name] ? (
 | 
			
		||||
                          <li key={feature.name} className="flex gap-x-3">
 | 
			
		||||
                            <Check
 | 
			
		||||
                              className="h-6 w-5 flex-none text-indigo-600"
 | 
			
		||||
                              aria-hidden="true"
 | 
			
		||||
                            />
 | 
			
		||||
                            <span>
 | 
			
		||||
                              {feature.name}{" "}
 | 
			
		||||
                              {typeof feature.tiers[tier.name] === "string" ? (
 | 
			
		||||
                                <span className="text-sm leading-6 text-gray-500">
 | 
			
		||||
                                  ({feature.tiers[tier.name]})
 | 
			
		||||
                                </span>
 | 
			
		||||
                              ) : null}
 | 
			
		||||
                            </span>
 | 
			
		||||
                          </li>
 | 
			
		||||
                        ) : null,
 | 
			
		||||
                      )}
 | 
			
		||||
                    </ul>
 | 
			
		||||
                  </li>
 | 
			
		||||
                ))}
 | 
			
		||||
              </ul>
 | 
			
		||||
            </section>
 | 
			
		||||
          ))}
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        {/* lg+ */}
 | 
			
		||||
        <div className="isolate mt-20 hidden lg:block border-gray-100 border p-6 shadow-md rounded-lg">
 | 
			
		||||
          <div className="relative -mx-8">
 | 
			
		||||
            {tiers.some((tier) => tier.mostPopular) ? (
 | 
			
		||||
              <div className="absolute inset-x-4 inset-y-0 -z-10 flex">
 | 
			
		||||
                <div
 | 
			
		||||
                  className="flex w-1/4 px-4"
 | 
			
		||||
                  aria-hidden="true"
 | 
			
		||||
                  style={{
 | 
			
		||||
                    marginLeft: `${
 | 
			
		||||
                      (tiers.findIndex((tier) => tier.mostPopular) + 1) * 25
 | 
			
		||||
                    }%`,
 | 
			
		||||
                  }}
 | 
			
		||||
                >
 | 
			
		||||
                  <div className="w-full rounded-t-xl border-x border-t border-gray-900/10 bg-gray-400/5" />
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
            ) : null}
 | 
			
		||||
            <table className="w-full table-fixed border-separate border-spacing-x-8 text-left">
 | 
			
		||||
              <caption className="sr-only">Pricing plan comparison</caption>
 | 
			
		||||
              <colgroup>
 | 
			
		||||
                <col className="w-1/4" />
 | 
			
		||||
                <col className="w-1/4" />
 | 
			
		||||
                <col className="w-1/4" />
 | 
			
		||||
                <col className="w-1/4" />
 | 
			
		||||
              </colgroup>
 | 
			
		||||
              <thead>
 | 
			
		||||
                <tr>
 | 
			
		||||
                  <td />
 | 
			
		||||
                  {tiers.map((tier) => (
 | 
			
		||||
                    <th
 | 
			
		||||
                      key={tier.id}
 | 
			
		||||
                      scope="col"
 | 
			
		||||
                      className="px-6 pt-6 xl:px-8 xl:pt-8"
 | 
			
		||||
                    >
 | 
			
		||||
                      <div className="text-sm font-semibold leading-7 text-gray-900">
 | 
			
		||||
                        {tier.name}
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </th>
 | 
			
		||||
                  ))}
 | 
			
		||||
                </tr>
 | 
			
		||||
              </thead>
 | 
			
		||||
              <tbody>
 | 
			
		||||
                <tr>
 | 
			
		||||
                  <th scope="row">
 | 
			
		||||
                    <span className="sr-only">Price</span>
 | 
			
		||||
                  </th>
 | 
			
		||||
                  {tiers.map((tier) => (
 | 
			
		||||
                    <td key={tier.id} className="px-6 pt-2 xl:px-8">
 | 
			
		||||
                      <div className="flex items-baseline gap-x-1 text-gray-900">
 | 
			
		||||
                        <span className="text-4xl font-bold">
 | 
			
		||||
                          {tier.priceMonthly}
 | 
			
		||||
                        </span>
 | 
			
		||||
                        <span className="text-sm font-semibold leading-6">
 | 
			
		||||
                          /month
 | 
			
		||||
                        </span>
 | 
			
		||||
                      </div>
 | 
			
		||||
                      <br></br>
 | 
			
		||||
                      <div className="text-md font-semibold">
 | 
			
		||||
                        {tier.description}
 | 
			
		||||
                      </div>
 | 
			
		||||
                      <a
 | 
			
		||||
                        href={getHrefFromTier(tier)}
 | 
			
		||||
                        className={cn(
 | 
			
		||||
                          tier.mostPopular
 | 
			
		||||
                            ? "bg-indigo-600 text-white hover:bg-indigo-500"
 | 
			
		||||
                            : "text-indigo-600 ring-1 ring-inset ring-indigo-200 hover:ring-indigo-300",
 | 
			
		||||
                          "mt-8 block rounded-md py-2 px-3 text-center text-sm font-semibold leading-6 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600",
 | 
			
		||||
                        )}
 | 
			
		||||
                      >
 | 
			
		||||
                        {getNameFromTier(tier)}
 | 
			
		||||
                      </a>
 | 
			
		||||
                    </td>
 | 
			
		||||
                  ))}
 | 
			
		||||
                </tr>
 | 
			
		||||
                {sections.map((section, sectionIdx) => (
 | 
			
		||||
                  <Fragment key={section.name}>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                      <th
 | 
			
		||||
                        scope="colgroup"
 | 
			
		||||
                        colSpan={4}
 | 
			
		||||
                        className={cn(
 | 
			
		||||
                          sectionIdx === 0 ? "pt-8" : "pt-16",
 | 
			
		||||
                          "pb-4 text-sm font-semibold leading-6 text-gray-900",
 | 
			
		||||
                        )}
 | 
			
		||||
                      >
 | 
			
		||||
                        {section.name}
 | 
			
		||||
                        <div className="absolute inset-x-8 mt-4 h-px bg-gray-900/10" />
 | 
			
		||||
                      </th>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    {section.features.map((feature) => (
 | 
			
		||||
                      <tr key={feature.name}>
 | 
			
		||||
                        <th
 | 
			
		||||
                          scope="row"
 | 
			
		||||
                          className="py-4 text-sm font-normal leading-6 text-gray-900"
 | 
			
		||||
                        >
 | 
			
		||||
                          {feature.name}
 | 
			
		||||
                          <div className="absolute inset-x-8 mt-4 h-px bg-gray-900/5" />
 | 
			
		||||
                        </th>
 | 
			
		||||
                        {tiers.map((tier) => (
 | 
			
		||||
                          <td key={tier.id} className="px-6 py-4 xl:px-8">
 | 
			
		||||
                            {typeof feature.tiers[tier.name] === "string" ||
 | 
			
		||||
                            typeof feature.tiers[tier.name] === "object" ? (
 | 
			
		||||
                              <div className="flex items-center justify-center text-center text-sm leading-6 text-gray-500">
 | 
			
		||||
                                {feature.tiers[tier.name]}
 | 
			
		||||
                              </div>
 | 
			
		||||
                            ) : (
 | 
			
		||||
                              <>
 | 
			
		||||
                                {feature.tiers[tier.name] === true ? (
 | 
			
		||||
                                  <Check
 | 
			
		||||
                                    className="mx-auto h-5 w-5 text-indigo-600"
 | 
			
		||||
                                    aria-hidden="true"
 | 
			
		||||
                                  />
 | 
			
		||||
                                ) : (
 | 
			
		||||
                                  <Minus
 | 
			
		||||
                                    className="mx-auto h-5 w-5 text-gray-400"
 | 
			
		||||
                                    aria-hidden="true"
 | 
			
		||||
                                  />
 | 
			
		||||
                                )}
 | 
			
		||||
 | 
			
		||||
                                <span className="sr-only">
 | 
			
		||||
                                  {feature.tiers[tier.name] === true
 | 
			
		||||
                                    ? "Included"
 | 
			
		||||
                                    : "Not included"}{" "}
 | 
			
		||||
                                  in {tier.name}
 | 
			
		||||
                                </span>
 | 
			
		||||
                              </>
 | 
			
		||||
                            )}
 | 
			
		||||
                          </td>
 | 
			
		||||
                        ))}
 | 
			
		||||
                      </tr>
 | 
			
		||||
                    ))}
 | 
			
		||||
                  </Fragment>
 | 
			
		||||
                ))}
 | 
			
		||||
              </tbody>
 | 
			
		||||
            </table>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								web/src/components/ui/progress.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								web/src/components/ui/progress.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
			
		||||
"use client"
 | 
			
		||||
 | 
			
		||||
import * as React from "react"
 | 
			
		||||
import * as ProgressPrimitive from "@radix-ui/react-progress"
 | 
			
		||||
 | 
			
		||||
import { cn } from "@/lib/utils"
 | 
			
		||||
 | 
			
		||||
const Progress = React.forwardRef<
 | 
			
		||||
  React.ElementRef<typeof ProgressPrimitive.Root>,
 | 
			
		||||
  React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
 | 
			
		||||
>(({ className, value, ...props }, ref) => (
 | 
			
		||||
  <ProgressPrimitive.Root
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "relative h-4 w-full overflow-hidden rounded-full bg-secondary",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props}
 | 
			
		||||
  >
 | 
			
		||||
    <ProgressPrimitive.Indicator
 | 
			
		||||
      className="h-full w-full flex-1 bg-primary transition-all"
 | 
			
		||||
      style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
 | 
			
		||||
    />
 | 
			
		||||
  </ProgressPrimitive.Root>
 | 
			
		||||
))
 | 
			
		||||
Progress.displayName = ProgressPrimitive.Root.displayName
 | 
			
		||||
 | 
			
		||||
export { Progress }
 | 
			
		||||
@ -82,6 +82,7 @@ export const workflowVersionTable = dbSchema.table("workflow_versions", {
 | 
			
		||||
  created_at: timestamp("created_at").defaultNow().notNull(),
 | 
			
		||||
  updated_at: timestamp("updated_at").defaultNow().notNull(),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const workflowVersionSchema = createSelectSchema(workflowVersionTable);
 | 
			
		||||
 | 
			
		||||
export const workflowVersionRelations = relations(
 | 
			
		||||
@ -158,6 +159,10 @@ export const workflowRunsTable = dbSchema.table("workflow_runs", {
 | 
			
		||||
  ended_at: timestamp("ended_at"),
 | 
			
		||||
  created_at: timestamp("created_at").defaultNow().notNull(),
 | 
			
		||||
  started_at: timestamp("started_at"),
 | 
			
		||||
  gpu: machineGPUOptions("gpu"),
 | 
			
		||||
  machine_type: machinesType("machine_type"),
 | 
			
		||||
  user_id: text("user_id"),
 | 
			
		||||
  org_id: text("org_id"),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const workflowRunRelations = relations(
 | 
			
		||||
@ -358,6 +363,32 @@ export const authRequestsTable = dbSchema.table("auth_requests", {
 | 
			
		||||
  updated_at: timestamp("updated_at").defaultNow().notNull(),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const subscriptionPlan = pgEnum("subscription_plan", [
 | 
			
		||||
  "basic",
 | 
			
		||||
  "pro",
 | 
			
		||||
  "enterprise",
 | 
			
		||||
]);
 | 
			
		||||
 | 
			
		||||
export const subscriptionPlanStatus = pgEnum("subscription_plan_status", [
 | 
			
		||||
  "active",
 | 
			
		||||
  "deleted",
 | 
			
		||||
  "paused",
 | 
			
		||||
]);
 | 
			
		||||
 | 
			
		||||
export const subscriptionStatusTable = dbSchema.table("subscription_status", {
 | 
			
		||||
  stripe_customer_id: text("stripe_customer_id").primaryKey().notNull(),
 | 
			
		||||
  user_id: text("user_id"),
 | 
			
		||||
  org_id: text("org_id"),
 | 
			
		||||
  plan: subscriptionPlan("plan").notNull(),
 | 
			
		||||
  status: subscriptionPlanStatus("status").notNull(),
 | 
			
		||||
  subscription_id: text("subscription_id"),
 | 
			
		||||
  subscription_item_plan_id: text("subscription_item_plan_id"),
 | 
			
		||||
  subscription_item_api_id: text("subscription_item_api_id"),
 | 
			
		||||
  cancel_at_period_end: boolean("cancel_at_period_end").default(false),
 | 
			
		||||
  created_at: timestamp("created_at").defaultNow().notNull(),
 | 
			
		||||
  updated_at: timestamp("updated_at").defaultNow().notNull(),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export type UserType = InferSelectModel<typeof usersTable>;
 | 
			
		||||
export type WorkflowType = InferSelectModel<typeof workflowTable>;
 | 
			
		||||
export type MachineType = InferSelectModel<typeof machinesTable>;
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import { z } from "zod";
 | 
			
		||||
export const APIKeyBodyRequest = z.object({
 | 
			
		||||
  user_id: z.string().optional().nullable(),
 | 
			
		||||
  org_id: z.string().optional().nullable(),
 | 
			
		||||
  iat: z.number(),
 | 
			
		||||
  iat: z.number().optional(),
 | 
			
		||||
  exp: z.number().optional(),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -66,7 +66,12 @@ export const createRun = withServerPromise(
 | 
			
		||||
      throw new Error("Workflow version not found");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (apiUser)
 | 
			
		||||
    let { userId, orgId } = auth();
 | 
			
		||||
 | 
			
		||||
    // If is API user, check if they have access to the workflow
 | 
			
		||||
    if (apiUser) {
 | 
			
		||||
      userId = apiUser.user_id ?? null;
 | 
			
		||||
      orgId = apiUser.org_id;
 | 
			
		||||
      if (apiUser.org_id) {
 | 
			
		||||
        // is org api call, check org only
 | 
			
		||||
        if (apiUser.org_id != workflow_version_data.workflow.org_id) {
 | 
			
		||||
@ -81,6 +86,7 @@ export const createRun = withServerPromise(
 | 
			
		||||
          throw new Error("Workflow not found");
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const workflow_api = workflow_version_data.workflow_api;
 | 
			
		||||
 | 
			
		||||
@ -114,6 +120,10 @@ export const createRun = withServerPromise(
 | 
			
		||||
        workflow_inputs: inputs,
 | 
			
		||||
        machine_id: machine.id,
 | 
			
		||||
        origin: runOrigin,
 | 
			
		||||
        org_id: orgId,
 | 
			
		||||
        user_id: userId,
 | 
			
		||||
        gpu: machine.gpu,
 | 
			
		||||
        machine_type: machine.type,
 | 
			
		||||
      })
 | 
			
		||||
      .returning();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,16 +6,13 @@ import jwt from "jsonwebtoken";
 | 
			
		||||
import { getOrgOrUserDisplayName } from "@/server/getOrgOrUserDisplayName";
 | 
			
		||||
import { withServerPromise } from "@/server/withServerPromise";
 | 
			
		||||
import "server-only";
 | 
			
		||||
import { headers } from "next/headers";
 | 
			
		||||
import { getUrlServerSide } from "./getUrlServerSide";
 | 
			
		||||
 | 
			
		||||
export const editWorkflowOnMachine = withServerPromise(
 | 
			
		||||
  async (workflow_version_id: string, machine_id: string) => {
 | 
			
		||||
    const { userId, orgId } = auth();
 | 
			
		||||
 | 
			
		||||
    const headersList = headers();
 | 
			
		||||
    const host = headersList.get("host") || "";
 | 
			
		||||
    const protocol = headersList.get("x-forwarded-proto") || "";
 | 
			
		||||
    const domain = `${protocol}://${host}`;
 | 
			
		||||
    const domain = getUrlServerSide();
 | 
			
		||||
 | 
			
		||||
    if (!userId) {
 | 
			
		||||
      throw new Error("No user id");
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										32
									
								
								web/src/server/getCurrentPlan.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								web/src/server/getCurrentPlan.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
import { db } from "@/db/db";
 | 
			
		||||
import { and, desc, eq, isNull } from "drizzle-orm";
 | 
			
		||||
import { subscriptionStatusTable } from "@/db/schema";
 | 
			
		||||
import { APIKeyUserType } from "@/server/APIKeyBodyRequest";
 | 
			
		||||
import { auth } from "@clerk/nextjs";
 | 
			
		||||
 | 
			
		||||
export async function getCurrentPlanWithAuth() {
 | 
			
		||||
  const { userId, orgId } = auth();
 | 
			
		||||
 | 
			
		||||
  const sub = await getCurrentPlan({
 | 
			
		||||
    org_id: orgId,
 | 
			
		||||
    user_id: userId,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return sub;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getCurrentPlan({ user_id, org_id }: APIKeyUserType) {
 | 
			
		||||
  if (!user_id) throw new Error("No user id");
 | 
			
		||||
 | 
			
		||||
  const sub = await db.query.subscriptionStatusTable.findFirst({
 | 
			
		||||
    where: and(
 | 
			
		||||
      eq(subscriptionStatusTable.user_id, user_id),
 | 
			
		||||
      org_id
 | 
			
		||||
        ? eq(subscriptionStatusTable.org_id, org_id)
 | 
			
		||||
        : isNull(subscriptionStatusTable.org_id),
 | 
			
		||||
    ),
 | 
			
		||||
    orderBy: desc(subscriptionStatusTable.created_at),
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return sub;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								web/src/server/getUrlServerSide.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								web/src/server/getUrlServerSide.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
import { headers } from "next/headers";
 | 
			
		||||
 | 
			
		||||
export function getUrlServerSide() {
 | 
			
		||||
  const headersList = headers();
 | 
			
		||||
  const host = headersList.get("host") || "";
 | 
			
		||||
  const protocol = headersList.get("x-forwarded-proto") || "";
 | 
			
		||||
  const domain = `${protocol}://${host}`;
 | 
			
		||||
 | 
			
		||||
  return domain;
 | 
			
		||||
}
 | 
			
		||||
@ -1,45 +0,0 @@
 | 
			
		||||
"use server";
 | 
			
		||||
 | 
			
		||||
import { LemonSqueezy } from "@lemonsqueezy/lemonsqueezy.js";
 | 
			
		||||
import "server-only";
 | 
			
		||||
 | 
			
		||||
const ls = new LemonSqueezy(process.env.LEMONSQUEEZY_API_KEY || "");
 | 
			
		||||
 | 
			
		||||
export async function getPricing() {
 | 
			
		||||
  const products = await ls.getProducts();
 | 
			
		||||
 | 
			
		||||
  return products;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getUsage() {
 | 
			
		||||
  const usageRecord = await ls.getUsageRecords();
 | 
			
		||||
 | 
			
		||||
  return usageRecord;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function setUsage(id: number, quantity: number) {
 | 
			
		||||
  const setUsage = await ls.createUsageRecord({
 | 
			
		||||
    subscriptionItemId: id,
 | 
			
		||||
    quantity: quantity,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return setUsage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getSubscription() {
 | 
			
		||||
  const subscription = await ls.getSubscriptions();
 | 
			
		||||
 | 
			
		||||
  return subscription;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getSubscriptionItem() {
 | 
			
		||||
  const subscriptionItem = await ls.getSubscriptionItems();
 | 
			
		||||
 | 
			
		||||
  return subscriptionItem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getUserData() {
 | 
			
		||||
  const user = await ls.getUser();
 | 
			
		||||
 | 
			
		||||
  return user;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								web/src/server/stripe.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/src/server/stripe.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
import Stripe from "stripe";
 | 
			
		||||
 | 
			
		||||
export const stripe = new Stripe(process.env.STRIPE_API_KEY!);
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user