From 85477aba9d1d6a7beb87d570f7b81a175321c8f8 Mon Sep 17 00:00:00 2001 From: bennykok Date: Fri, 26 Jan 2024 10:08:37 +0800 Subject: [PATCH] Squashed commit of the following: commit c36b0ec0b374dd8ccbee3a6044ee7e3f1fefe368 Author: Nicholas Koben Kao Date: Thu Jan 25 17:54:54 2024 -0800 nits on wording and removing link to broken storage/:id page commit 0777fdcf7b0002244bc713199d3d64eea6b6061e Author: Nicholas Koben Kao Date: Thu Jan 25 17:23:55 2024 -0800 builder update config and such commit 958b795bb2b6ac27ce33c5729ef265b068420e1a Author: Nicholas Koben Kao Date: Thu Jan 25 17:23:43 2024 -0800 rename all from checkponit to model commit 7a9c5636e73bd005499b141a4dd382db5672c962 Author: Nicholas Koben Kao Date: Thu Jan 25 16:51:59 2024 -0800 rename for consistency commit 48bebbafab9a95388817df97c15f8ea97e0fea75 Author: Nicholas Koben Kao Date: Thu Jan 25 16:18:36 2024 -0800 bulider commit 81dacd9af457886f2f027994d225a7748c738abb Author: Nicholas Koben Kao Date: Thu Jan 25 16:17:56 2024 -0800 different types of models --- builder/modal-builder/.env.example | 3 +- builder/modal-builder/src/main.py | 64 +- builder/modal-builder/src/template/config.py | 4 +- .../src/template/data/extra_model_paths.yaml | 8 + .../src/template/volume_setup.py | 4 +- .../src/volume-builder/config.py | 12 +- web/drizzle/0043_dapper_santa_claus.sql | 7 + web/drizzle/0044_married_malcolm_colcord.sql | 26 + web/drizzle/meta/0043_snapshot.json | 1288 ++++++++++++++++ web/drizzle/meta/0044_snapshot.json | 1293 +++++++++++++++++ web/drizzle/meta/_journal.json | 14 + web/src/app/(app)/api/volume-upload/route.ts | 22 +- web/src/app/(app)/storage/page.tsx | 16 +- .../{CheckpointList.tsx => ModelList.tsx} | 162 ++- .../{checkpoint-input.tsx => model-input.tsx} | 4 +- web/src/db/schema.ts | 51 +- web/src/server/addCheckpointSchema.tsx | 5 - web/src/server/addCivitaiModelSchema.tsx | 5 + web/src/server/curdMachine.ts | 6 +- .../{curdCheckpoint.ts => curdModel.ts} | 110 +- ...serCheckpoints.tsx => getAllUserModel.tsx} | 15 +- web/src/types/civitai.ts | 35 +- 22 files changed, 2919 insertions(+), 235 deletions(-) create mode 100644 web/drizzle/0043_dapper_santa_claus.sql create mode 100644 web/drizzle/0044_married_malcolm_colcord.sql create mode 100644 web/drizzle/meta/0043_snapshot.json create mode 100644 web/drizzle/meta/0044_snapshot.json rename web/src/components/{CheckpointList.tsx => ModelList.tsx} (73%) rename web/src/components/custom-form/{checkpoint-input.tsx => model-input.tsx} (95%) delete mode 100644 web/src/server/addCheckpointSchema.tsx create mode 100644 web/src/server/addCivitaiModelSchema.tsx rename web/src/server/{curdCheckpoint.ts => curdModel.ts} (71%) rename web/src/server/{getAllUserCheckpoints.tsx => getAllUserModel.tsx} (64%) diff --git a/builder/modal-builder/.env.example b/builder/modal-builder/.env.example index 806c98c..16d715c 100644 --- a/builder/modal-builder/.env.example +++ b/builder/modal-builder/.env.example @@ -3,4 +3,5 @@ MODAL_TOKEN_SECRET= CIVITAI_API_KEY= # On production set to False -DEPLOY_TEST_FLAG=True \ No newline at end of file +DEPLOY_TEST_FLAG=True +CIVITAI_API_KEY= diff --git a/builder/modal-builder/src/main.py b/builder/modal-builder/src/main.py index 46787de..2776836 100644 --- a/builder/modal-builder/src/main.py +++ b/builder/modal-builder/src/main.py @@ -177,7 +177,7 @@ class Item(BaseModel): snapshot: Snapshot models: List[Model] callback_url: str - checkpoint_volume_name: str + model_volume_name: str gpu: GPUType = Field(default=GPUType.T4) @field_validator('gpu') @@ -227,24 +227,31 @@ async def websocket_endpoint(websocket: WebSocket, machine_id: str): # return {"Hello": "World"} +# definition based on web schema class UploadType(str, Enum): checkpoint = "checkpoint" + lora = "lora" + embedding = "embedding" class UploadBody(BaseModel): download_url: str volume_name: str volume_id: str - checkpoint_id: str + model_id: str upload_type: UploadType callback_url: str +# based on ComfyUI's model dir, and our mappings in ./src/template/data/extra_model_paths.yaml UPLOAD_TYPE_DIR_MAP = { - UploadType.checkpoint: "checkpoints" + UploadType.checkpoint: "checkpoints", + UploadType.lora: "loras", + UploadType.embedding: "embeddings", } + @app.post("/upload-volume") -async def upload_checkpoint(body: UploadBody): +async def upload_model(body: UploadBody): global last_activity_time last_activity_time = time.time() logger.info(f"Extended inactivity time to {global_timeout}") @@ -254,6 +261,7 @@ async def upload_checkpoint(body: UploadBody): # check that this return JSONResponse(status_code=200, content={"message": "Volume uploading", "build_machine_instance_id": fly_instance_id}) + async def upload_logic(body: UploadBody): folder_path = f"/app/builds/{body.volume_id}" @@ -270,7 +278,7 @@ async def upload_logic(body: UploadBody): }, "callback_url": body.callback_url, "callback_body": { - "checkpoint_id": body.checkpoint_id, + "model_id": body.model_id, "volume_id": body.volume_id, "folder_path": upload_path, }, @@ -279,51 +287,11 @@ async def upload_logic(body: UploadBody): with open(f"{folder_path}/config.py", "w") as f: f.write("config = " + json.dumps(config)) - process = await asyncio.subprocess.create_subprocess_shell( + await asyncio.subprocess.create_subprocess_shell( f"modal run app.py", - # stdout=asyncio.subprocess.PIPE, - # stderr=asyncio.subprocess.PIPE, cwd=folder_path, env={**os.environ, "COLUMNS": "10000"} ) - - # error_logs = [] - # async def read_stream(stream): - # while True: - # line = await stream.readline() - # if line: - # l = line.decode('utf-8').strip() - # error_logs.append(l) - # logger.error(l) - # error_logs.append({ - # "logs": l, - # "timestamp": time.time() - # }) - # else: - # break - - # stderr_read_task = asyncio.create_task(read_stream(process.stderr)) - # - # await asyncio.wait([stderr_read_task]) - # await process.wait() - - # if process.returncode != 0: - # error_logs.append({"logs": "Unable to upload volume.", "timestamp": time.time()}) - # # Error handling: send POST request to callback URL with error details - # requests.post(body.callback_url, json={ - # "volume_id": body.volume_id, - # "checkpoint_id": body.checkpoint_id, - # "folder_path": upload_path, - # "error_logs": json.dumps(error_logs), - # "status": "failed" - # }) - # - # requests.post(body.callback_url, json={ - # "checkpoint_id": body.checkpoint_id, - # "volume_id": body.volume_id, - # "folder_path": upload_path, - # "status": "success" - # }) @app.post("/create") async def create_machine(item: Item): @@ -414,8 +382,8 @@ async def build_logic(item: Item): "name": item.name, "deploy_test": os.environ.get("DEPLOY_TEST_FLAG", "False"), "gpu": item.gpu, - "public_checkpoint_volume": "model-store", - "private_checkpoint_volume": item.checkpoint_volume_name + "public_model_volume": "model-store", + "private_model_volume": item.model_volume_name } with open(f"{folder_path}/config.py", "w") as f: f.write("config = " + json.dumps(config)) diff --git a/builder/modal-builder/src/template/config.py b/builder/modal-builder/src/template/config.py index a651642..492426c 100644 --- a/builder/modal-builder/src/template/config.py +++ b/builder/modal-builder/src/template/config.py @@ -2,6 +2,6 @@ config = { "name": "my-app", "deploy_test": "True", "gpu": "T4", - "public_checkpoint_volume": "model-store", - "private_checkpoint_volume": "private-model-store" + "public_model_volume": "model-store", + "private_model_volume": "private-model-store" } diff --git a/builder/modal-builder/src/template/data/extra_model_paths.yaml b/builder/modal-builder/src/template/data/extra_model_paths.yaml index 66f758e..c3869f3 100644 --- a/builder/modal-builder/src/template/data/extra_model_paths.yaml +++ b/builder/modal-builder/src/template/data/extra_model_paths.yaml @@ -13,3 +13,11 @@ public: private: base_path: /private_models/ checkpoints: checkpoints + clip: clip + clip_vision: clip_vision + configs: configs + controlnet: controlnet + embeddings: embeddings + loras: loras + upscale_models: upscale_models + vae: vae diff --git a/builder/modal-builder/src/template/volume_setup.py b/builder/modal-builder/src/template/volume_setup.py index fb50e9f..feeff21 100644 --- a/builder/modal-builder/src/template/volume_setup.py +++ b/builder/modal-builder/src/template/volume_setup.py @@ -1,8 +1,8 @@ import modal from config import config -public_model_volume = modal.Volume.persisted(config["public_checkpoint_volume"]) -private_volume = modal.Volume.persisted(config["private_checkpoint_volume"]) +public_model_volume = modal.Volume.persisted(config["public_model_volume"]) +private_volume = modal.Volume.persisted(config["private_model_volume"]) PUBLIC_BASEMODEL_DIR = "/public_models" PRIVATE_BASEMODEL_DIR = "/private_models" diff --git a/builder/modal-builder/src/volume-builder/config.py b/builder/modal-builder/src/volume-builder/config.py index 3abfeac..1bb8508 100644 --- a/builder/modal-builder/src/volume-builder/config.py +++ b/builder/modal-builder/src/volume-builder/config.py @@ -1,18 +1,18 @@ config = { "volume_names": { - "test": { - "download_url": "https://pub-6230db03dc3a4861a9c3e55145ceda44.r2.dev/openpose-pose (1).png", - "folder_path": "images" + "user4": { + "download_url": "https://civitai.com/api/download/models/11745", + "folder_path": "checkpoints" } }, "volume_paths": { - "test": "/volumes/something" + "user4": "/volumes/something", }, "callback_url": "", "callback_body": { - "checkpoint_id": "", + "model_id": "", "volume_id": "", - "folder_path": "images", + "folder_path": "checkpoints", }, "civitai_api_key": "", } diff --git a/web/drizzle/0043_dapper_santa_claus.sql b/web/drizzle/0043_dapper_santa_claus.sql new file mode 100644 index 0000000..1bf96ef --- /dev/null +++ b/web/drizzle/0043_dapper_santa_claus.sql @@ -0,0 +1,7 @@ +DO $$ BEGIN + CREATE TYPE "model_type" AS ENUM('checkpoint', 'lora', 'embedding', 'vae'); +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +ALTER TABLE "comfyui_deploy"."checkpoints" ADD COLUMN "model_type" "model_type" NOT NULL; \ No newline at end of file diff --git a/web/drizzle/0044_married_malcolm_colcord.sql b/web/drizzle/0044_married_malcolm_colcord.sql new file mode 100644 index 0000000..6cbf557 --- /dev/null +++ b/web/drizzle/0044_married_malcolm_colcord.sql @@ -0,0 +1,26 @@ +ALTER TABLE "comfyui_deploy"."checkpoints" RENAME TO "models";--> statement-breakpoint +ALTER TABLE "comfyui_deploy"."checkpoint_volume" RENAME TO "user_volume";--> statement-breakpoint +ALTER TABLE "comfyui_deploy"."models" RENAME COLUMN "checkpoint_volume_id" TO "user_volume_id";--> statement-breakpoint +ALTER TABLE "comfyui_deploy"."models" DROP CONSTRAINT "checkpoints_user_id_users_id_fk"; +--> statement-breakpoint +ALTER TABLE "comfyui_deploy"."models" DROP CONSTRAINT "checkpoints_checkpoint_volume_id_checkpoint_volume_id_fk"; +--> statement-breakpoint +ALTER TABLE "comfyui_deploy"."user_volume" DROP CONSTRAINT "checkpoint_volume_user_id_users_id_fk"; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "comfyui_deploy"."models" ADD CONSTRAINT "models_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "comfyui_deploy"."users"("id") ON DELETE no action ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "comfyui_deploy"."models" ADD CONSTRAINT "models_user_volume_id_user_volume_id_fk" FOREIGN KEY ("user_volume_id") REFERENCES "comfyui_deploy"."user_volume"("id") ON DELETE cascade ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "comfyui_deploy"."user_volume" ADD CONSTRAINT "user_volume_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "comfyui_deploy"."users"("id") ON DELETE no action ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; diff --git a/web/drizzle/meta/0043_snapshot.json b/web/drizzle/meta/0043_snapshot.json new file mode 100644 index 0000000..e916560 --- /dev/null +++ b/web/drizzle/meta/0043_snapshot.json @@ -0,0 +1,1288 @@ +{ + "id": "ca4e598d-4205-4e48-a5d2-4202d38a8b5c", + "prevId": "4bbd69a1-bb1f-467b-a6d8-8412142c4c32", + "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": {} + }, + "checkpoints": { + "name": "checkpoints", + "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": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "checkpoint_volume_id": { + "name": "checkpoint_volume_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "model_name": { + "name": "model_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "folder_path": { + "name": "folder_path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "civitai_id": { + "name": "civitai_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "civitai_version_id": { + "name": "civitai_version_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "civitai_url": { + "name": "civitai_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "civitai_download_url": { + "name": "civitai_download_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "civitai_model_response": { + "name": "civitai_model_response", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "hf_url": { + "name": "hf_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "s3_url": { + "name": "s3_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "client_url": { + "name": "client_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_public": { + "name": "is_public", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "status": { + "name": "status", + "type": "resource_upload", + "primaryKey": false, + "notNull": true, + "default": "'started'" + }, + "upload_machine_id": { + "name": "upload_machine_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "upload_type": { + "name": "upload_type", + "type": "model_upload_type", + "primaryKey": false, + "notNull": true + }, + "model_type": { + "name": "model_type", + "type": "model_type", + "primaryKey": false, + "notNull": true + }, + "error_log": { + "name": "error_log", + "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": { + "checkpoints_user_id_users_id_fk": { + "name": "checkpoints_user_id_users_id_fk", + "tableFrom": "checkpoints", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "checkpoints_checkpoint_volume_id_checkpoint_volume_id_fk": { + "name": "checkpoints_checkpoint_volume_id_checkpoint_volume_id_fk", + "tableFrom": "checkpoints", + "tableTo": "checkpoint_volume", + "columnsFrom": [ + "checkpoint_volume_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "checkpoint_volume": { + "name": "checkpoint_volume", + "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": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "volume_name": { + "name": "volume_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()" + }, + "disabled": { + "name": "disabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "checkpoint_volume_user_id_users_id_fk": { + "name": "checkpoint_volume_user_id_users_id_fk", + "tableFrom": "checkpoint_volume", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "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 + }, + "gpu": { + "name": "gpu", + "type": "machine_gpu", + "primaryKey": false, + "notNull": false + }, + "machine_type": { + "name": "machine_type", + "type": "machine_type", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "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" + } + }, + "model_type": { + "name": "model_type", + "values": { + "checkpoint": "checkpoint", + "lora": "lora", + "embedding": "embedding", + "vae": "vae" + } + }, + "model_upload_type": { + "name": "model_upload_type", + "values": { + "civitai": "civitai", + "huggingface": "huggingface", + "other": "other" + } + }, + "resource_upload": { + "name": "resource_upload", + "values": { + "started": "started", + "success": "success", + "failed": "failed" + } + }, + "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": {} + } +} \ No newline at end of file diff --git a/web/drizzle/meta/0044_snapshot.json b/web/drizzle/meta/0044_snapshot.json new file mode 100644 index 0000000..19506af --- /dev/null +++ b/web/drizzle/meta/0044_snapshot.json @@ -0,0 +1,1293 @@ +{ + "id": "21883be1-791d-462f-94b1-a990074aefef", + "prevId": "ca4e598d-4205-4e48-a5d2-4202d38a8b5c", + "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": {} + }, + "models": { + "name": "models", + "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": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_volume_id": { + "name": "user_volume_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "model_name": { + "name": "model_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "folder_path": { + "name": "folder_path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "civitai_id": { + "name": "civitai_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "civitai_version_id": { + "name": "civitai_version_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "civitai_url": { + "name": "civitai_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "civitai_download_url": { + "name": "civitai_download_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "civitai_model_response": { + "name": "civitai_model_response", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "hf_url": { + "name": "hf_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "s3_url": { + "name": "s3_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "client_url": { + "name": "client_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_public": { + "name": "is_public", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "status": { + "name": "status", + "type": "resource_upload", + "primaryKey": false, + "notNull": true, + "default": "'started'" + }, + "upload_machine_id": { + "name": "upload_machine_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "upload_type": { + "name": "upload_type", + "type": "model_upload_type", + "primaryKey": false, + "notNull": true + }, + "model_type": { + "name": "model_type", + "type": "model_type", + "primaryKey": false, + "notNull": true + }, + "error_log": { + "name": "error_log", + "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": { + "models_user_id_users_id_fk": { + "name": "models_user_id_users_id_fk", + "tableFrom": "models", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "models_user_volume_id_user_volume_id_fk": { + "name": "models_user_volume_id_user_volume_id_fk", + "tableFrom": "models", + "tableTo": "user_volume", + "columnsFrom": [ + "user_volume_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": {} + }, + "user_volume": { + "name": "user_volume", + "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": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "volume_name": { + "name": "volume_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()" + }, + "disabled": { + "name": "disabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_volume_user_id_users_id_fk": { + "name": "user_volume_user_id_users_id_fk", + "tableFrom": "user_volume", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "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 + }, + "gpu": { + "name": "gpu", + "type": "machine_gpu", + "primaryKey": false, + "notNull": false + }, + "machine_type": { + "name": "machine_type", + "type": "machine_type", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "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" + } + }, + "model_type": { + "name": "model_type", + "values": { + "checkpoint": "checkpoint", + "lora": "lora", + "embedding": "embedding", + "vae": "vae" + } + }, + "model_upload_type": { + "name": "model_upload_type", + "values": { + "civitai": "civitai", + "huggingface": "huggingface", + "other": "other" + } + }, + "resource_upload": { + "name": "resource_upload", + "values": { + "started": "started", + "success": "success", + "failed": "failed" + } + }, + "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": { + "\"comfyui_deploy\".\"checkpoints\"": "\"comfyui_deploy\".\"models\"", + "\"comfyui_deploy\".\"checkpoint_volume\"": "\"comfyui_deploy\".\"user_volume\"" + }, + "columns": { + "\"comfyui_deploy\".\"models\".\"checkpoint_volume_id\"": "\"comfyui_deploy\".\"models\".\"user_volume_id\"" + } + } +} \ No newline at end of file diff --git a/web/drizzle/meta/_journal.json b/web/drizzle/meta/_journal.json index 19546f0..43e5ee9 100644 --- a/web/drizzle/meta/_journal.json +++ b/web/drizzle/meta/_journal.json @@ -302,6 +302,20 @@ "when": 1706164614659, "tag": "0042_windy_madelyne_pryor", "breakpoints": true + }, + { + "idx": 43, + "version": "5", + "when": 1706225960550, + "tag": "0043_dapper_santa_claus", + "breakpoints": true + }, + { + "idx": 44, + "version": "5", + "when": 1706230304140, + "tag": "0044_married_malcolm_colcord", + "breakpoints": true } ] } \ No newline at end of file diff --git a/web/src/app/(app)/api/volume-upload/route.ts b/web/src/app/(app)/api/volume-upload/route.ts index b21741e..e4a2fe3 100644 --- a/web/src/app/(app)/api/volume-upload/route.ts +++ b/web/src/app/(app)/api/volume-upload/route.ts @@ -1,15 +1,15 @@ import { parseDataSafe } from "../../../../lib/parseDataSafe"; import { db } from "@/db/db"; -import { checkpointTable, machinesTable } from "@/db/schema"; +import { modelTable } from "@/db/schema"; import { eq } from "drizzle-orm"; import { NextResponse } from "next/server"; import { z } from "zod"; const Request = z.object({ volume_id: z.string(), - checkpoint_id: z.string(), + model_id: z.string(), folder_path: z.string().optional(), - status: z.enum(['success', 'failed']), + status: z.enum(["success", "failed"]), error_log: z.string().optional(), timeout: z.number().optional(), }); @@ -18,30 +18,30 @@ export async function POST(request: Request) { const [data, error] = await parseDataSafe(Request, request); if (!data || error) return error; - const { checkpoint_id, error_log, status, folder_path } = data; - console.log( checkpoint_id, error_log, status, folder_path ) + const { model_id, error_log, status, folder_path } = data; + console.log(model_id, error_log, status, folder_path); if (status === "success") { await db - .update(checkpointTable) + .update(modelTable) .set({ status: "success", folder_path, updated_at: new Date(), // build_log: build_log, }) - .where(eq(checkpointTable.id, checkpoint_id)); + .where(eq(modelTable.id, model_id)); } else { await db - .update(checkpointTable) + .update(modelTable) .set({ status: "failed", - error_log, + error_log, updated_at: new Date(), // status: "error", // build_log: build_log, }) - .where(eq(checkpointTable.id, checkpoint_id)); + .where(eq(modelTable.id, model_id)); } return NextResponse.json( @@ -50,6 +50,6 @@ export async function POST(request: Request) { }, { status: 200, - } + }, ); } diff --git a/web/src/app/(app)/storage/page.tsx b/web/src/app/(app)/storage/page.tsx index c17cc9b..42cedc4 100644 --- a/web/src/app/(app)/storage/page.tsx +++ b/web/src/app/(app)/storage/page.tsx @@ -1,14 +1,14 @@ import { setInitialUserData } from "../../../lib/setInitialUserData"; import { auth } from "@clerk/nextjs"; import { clerkClient } from "@clerk/nextjs/server"; -import { CheckpointList } from "@/components/CheckpointList"; -import { getAllUserCheckpoints } from "@/server/getAllUserCheckpoints"; +import { ModelList } from "@/components/ModelList"; +import { getAllUserModels } from "@/server/getAllUserModel"; export default function Page() { - return ; + return ; } -async function CheckpointListServer() { +async function ModelListServer() { const { userId } = auth(); if (!userId) { @@ -21,15 +21,15 @@ async function CheckpointListServer() { await setInitialUserData(userId); } - const checkpoints = await getAllUserCheckpoints(); + const models = await getAllUserModels(); - if (!checkpoints) { - return
No checkpoints found
; + if (!models) { + return
No models found
; } return (
- +
); } diff --git a/web/src/components/CheckpointList.tsx b/web/src/components/ModelList.tsx similarity index 73% rename from web/src/components/CheckpointList.tsx rename to web/src/components/ModelList.tsx index a0fce75..b68a367 100644 --- a/web/src/components/CheckpointList.tsx +++ b/web/src/components/ModelList.tsx @@ -4,7 +4,7 @@ import { getRelativeTime } from "../lib/getRelativeTime"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; -import { InsertModal, UpdateModal } from "./InsertModal"; +import { InsertModal } from "./InsertModal"; import { Input } from "@/components/ui/input"; import { ScrollArea } from "@/components/ui/scroll-area"; import { @@ -15,7 +15,7 @@ import { TableHeader, TableRow, } from "@/components/ui/table"; -import type { getAllUserCheckpoints } from "@/server/getAllUserCheckpoints"; +import type { getAllUserModels as getAllUserModels } from "@/server/getAllUserModel"; import type { ColumnDef, ColumnFiltersState, @@ -32,23 +32,22 @@ import { } from "@tanstack/react-table"; import { ArrowUpDown } from "lucide-react"; import * as React from "react"; -import { addCivitaiCheckpoint } from "@/server/curdCheckpoint"; -import { addCivitaiCheckpointSchema } from "@/server/addCheckpointSchema"; +import { addCivitaiModel } from "@/server/curdModel"; +import { addCivitaiModelSchema } from "@/server/addCivitaiModelSchema"; +import { modelEnumType } from "@/db/schema"; -export type CheckpointItemList = NonNullable< - Awaited> +export type ModelItemList = NonNullable< + Awaited> >[0]; -export const columns: ColumnDef[] = [ +export const columns: ColumnDef[] = [ { accessorKey: "id", id: "select", header: ({ table }) => ( table.toggleAllPageRowsSelected(!!value)} aria-label="Select all" /> @@ -77,22 +76,23 @@ export const columns: ColumnDef[] = [ ); }, cell: ({ row }) => { - const checkpoint = row.original; + const model = row.original; return ( - + { + /* + href={`/storage/${model.id}`} // TODO + >*/ + } {row.original.model_name} - {checkpoint.is_public ? ( - Public - ) : ( - Private - )} - + {model.is_public + ? Public + : Private} + ); }, }, @@ -111,7 +111,11 @@ export const columns: ColumnDef[] = [ }, cell: ({ row }) => { return ( - + {row.original.status} ); @@ -167,6 +171,35 @@ export const columns: ColumnDef[] = [ return {row.original.upload_type}; }, }, + { + accessorKey: "model_type", + header: ({ column }) => { + return ( + + ); + }, + cell: ({ row }) => { + const model_type_map: Record = { + "checkpoint": "amber", + "lora": "green", + "embedding": "violet", + "vae": "teal", + }; + + function getBadgeColor(modelType: modelEnumType) { + return model_type_map[modelType] || "default"; + } + + const color = getBadgeColor(row.original.model_type); + return {row.original.model_type}; + }, + }, { accessorKey: "date", sortingFn: "datetime", @@ -221,13 +254,14 @@ export const columns: ColumnDef[] = [ // }, ]; -export function CheckpointList({ data }: { data: CheckpointItemList[] }) { +export function ModelList({ data }: { data: ModelItemList[] }) { const [sorting, setSorting] = React.useState([]); const [columnFilters, setColumnFilters] = React.useState( - [] + [], ); - const [columnVisibility, setColumnVisibility] = - React.useState({}); + const [columnVisibility, setColumnVisibility] = React.useState< + VisibilityState + >({}); const [rowSelection, setRowSelection] = React.useState({}); const table = useReactTable({ @@ -254,10 +288,10 @@ export function CheckpointList({ data }: { data: CheckpointItemList[] }) {
- table.getColumn("name")?.setFilterValue(event.target.value) - } + table.getColumn("model_name")?.setFilterValue(event.target.value)} className="max-w-sm" />
@@ -268,17 +302,17 @@ export function CheckpointList({ data }: { data: CheckpointItemList[] }) { // TODO: limitations based on plan } tooltip={"Add models using their civitai url!"} - title="Civitai Checkpoint" + title="Add a Civitai Model" description="Pick a model from civitai" - serverAction={addCivitaiCheckpoint} - formSchema={addCivitaiCheckpointSchema} + serverAction={addCivitaiModel} + formSchema={addCivitaiModelSchema} fieldConfig={{ civitai_url: { fieldType: "fallback", inputProps: { required: true }, description: ( <> - Pick a checkpoint from{" "} + Pick a model from{" "} { return ( - {header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext() - )} + {header.isPlaceholder ? null : flexRender( + header.column.columnDef.header, + header.getContext(), + )} ); })} @@ -315,32 +347,34 @@ export function CheckpointList({ data }: { data: CheckpointItemList[] }) { ))} - {table.getRowModel().rows?.length ? ( - table.getRowModel().rows.map((row) => ( - - {row.getVisibleCells().map((cell) => ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext() - )} - - ))} + {table.getRowModel().rows?.length + ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ))} + + )) + ) + : ( + + + No results. + - )) - ) : ( - - - No results. - - - )} + )} diff --git a/web/src/components/custom-form/checkpoint-input.tsx b/web/src/components/custom-form/model-input.tsx similarity index 95% rename from web/src/components/custom-form/checkpoint-input.tsx rename to web/src/components/custom-form/model-input.tsx index 9a21cb9..66cf7f5 100644 --- a/web/src/components/custom-form/checkpoint-input.tsx +++ b/web/src/components/custom-form/model-input.tsx @@ -7,7 +7,7 @@ import AutoFormInput from "../ui/auto-form/fields/input"; import { useDebouncedCallback } from "use-debounce"; import { CivitaiModelResponse } from "@/types/civitai"; import { z } from "zod"; -import { insertCivitaiCheckpointSchema } from "@/db/schema"; +import { insertCivitaiModelSchema } from "@/db/schema"; function getUrl(civitai_url: string) { // expect to be a URL to be https://civitai.com/models/36520 @@ -33,7 +33,7 @@ export default function AutoFormCheckpointInput( const handleSearch = useDebouncedCallback((search) => { const validationResult = - insertCivitaiCheckpointSchema.shape.civitai_url.safeParse(search); + insertCivitaiModelSchema.shape.civitai_url.safeParse(search); if (!validationResult.success) { console.error(validationResult.error); // Optionally set an error state here diff --git a/web/src/db/schema.ts b/web/src/db/schema.ts index da3433c..5a560a3 100644 --- a/web/src/db/schema.ts +++ b/web/src/db/schema.ts @@ -12,7 +12,7 @@ import { real, } from "drizzle-orm/pg-core"; import { createInsertSchema, createSelectSchema } from "drizzle-zod"; -import { z } from "zod"; +import { TypeOf, z } from "zod"; export const dbSchema = pgSchema("comfyui_deploy"); @@ -376,15 +376,25 @@ export const modelUploadType = pgEnum("model_upload_type", [ "other", ]); -export const checkpointTable = dbSchema.table("checkpoints", { +// https://www.answeroverflow.com/m/1125106227387584552 +const modelTypes = [ + "checkpoint", + "lora", + "embedding", + "vae", +] as const +export const modelType = pgEnum("model_type", modelTypes); +export type modelEnumType = typeof modelTypes[number] + +export const modelTable = dbSchema.table("models", { id: uuid("id").primaryKey().defaultRandom().notNull(), - user_id: text("user_id").references(() => usersTable.id, {}), // perhaps a "special" user_id for global checkpoints + user_id: text("user_id").references(() => usersTable.id, {}), // perhaps a "special" user_id for global models org_id: text("org_id"), description: text("description"), - checkpoint_volume_id: uuid("checkpoint_volume_id") + user_volume_id: uuid("user_volume_id") .notNull() - .references(() => checkpointVolumeTable.id, { + .references(() => userVolume.id, { onDelete: "cascade", }) .notNull(), @@ -408,12 +418,13 @@ export const checkpointTable = dbSchema.table("checkpoints", { status: resourceUpload("status").notNull().default("started"), upload_machine_id: text("upload_machine_id"), // TODO: review if actually needed upload_type: modelUploadType("upload_type").notNull(), + model_type: modelType("model_type").notNull(), error_log: text("error_log"), created_at: timestamp("created_at").defaultNow().notNull(), updated_at: timestamp("updated_at").defaultNow().notNull(), }); -export const checkpointVolumeTable = dbSchema.table("checkpoint_volume", { +export const userVolume = dbSchema.table("user_volume", { id: uuid("id").primaryKey().defaultRandom().notNull(), user_id: text("user_id").references(() => usersTable.id, { // onDelete: "cascade", @@ -425,23 +436,23 @@ export const checkpointVolumeTable = dbSchema.table("checkpoint_volume", { disabled: boolean("disabled").default(false).notNull(), }); -export const checkpointRelations = relations(checkpointTable, ({ one }) => ({ +export const modelRelations = relations(modelTable, ({ one }) => ({ user: one(usersTable, { - fields: [checkpointTable.user_id], + fields: [modelTable.user_id], references: [usersTable.id], }), - volume: one(checkpointVolumeTable, { - fields: [checkpointTable.checkpoint_volume_id], - references: [checkpointVolumeTable.id], + volume: one(userVolume, { + fields: [modelTable.user_volume_id], + references: [userVolume.id], }), })); -export const checkpointVolumeRelations = relations( - checkpointVolumeTable, +export const modalVolumeRelations = relations( + userVolume, ({ many, one }) => ({ - checkpoint: many(checkpointTable), + model: many(modelTable), user: one(usersTable, { - fields: [checkpointVolumeTable.user_id], + fields: [userVolume.user_id], references: [usersTable.id], }), }) @@ -473,8 +484,8 @@ export const subscriptionStatusTable = dbSchema.table("subscription_status", { updated_at: timestamp("updated_at").defaultNow().notNull(), }); -export const insertCivitaiCheckpointSchema = createInsertSchema( - checkpointTable, +export const insertCivitaiModelSchema = createInsertSchema( + modelTable, { civitai_url: (schema) => schema.civitai_url @@ -491,8 +502,8 @@ export type WorkflowType = InferSelectModel; export type MachineType = InferSelectModel; export type WorkflowVersionType = InferSelectModel; export type DeploymentType = InferSelectModel; -export type CheckpointType = InferSelectModel; -export type CheckpointVolumeType = InferSelectModel< - typeof checkpointVolumeTable +export type ModelType = InferSelectModel; +export type UserVolumeType = InferSelectModel< + typeof userVolume >; export type UserUsageType = InferSelectModel; diff --git a/web/src/server/addCheckpointSchema.tsx b/web/src/server/addCheckpointSchema.tsx deleted file mode 100644 index b83f5a3..0000000 --- a/web/src/server/addCheckpointSchema.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { insertCivitaiCheckpointSchema } from "@/db/schema"; - -export const addCivitaiCheckpointSchema = insertCivitaiCheckpointSchema.pick({ - civitai_url: true, -}); diff --git a/web/src/server/addCivitaiModelSchema.tsx b/web/src/server/addCivitaiModelSchema.tsx new file mode 100644 index 0000000..3f205eb --- /dev/null +++ b/web/src/server/addCivitaiModelSchema.tsx @@ -0,0 +1,5 @@ +import { insertCivitaiModelSchema } from "@/db/schema"; + +export const addCivitaiModelSchema = insertCivitaiModelSchema.pick({ + civitai_url: true, +}); diff --git a/web/src/server/curdMachine.ts b/web/src/server/curdMachine.ts index 77fea3b..cbe58b8 100644 --- a/web/src/server/curdMachine.ts +++ b/web/src/server/curdMachine.ts @@ -15,7 +15,7 @@ import { headers } from "next/headers"; import { redirect } from "next/navigation"; import "server-only"; import type { z } from "zod"; -import { retrieveCheckpointVolumes } from "./curdCheckpoint"; +import { retrieveModelVolumes } from "./curdModel"; export async function getMachines() { const { userId, orgId } = auth(); @@ -190,7 +190,7 @@ async function _buildMachine( throw new Error("No domain"); } - const volumes = await retrieveCheckpointVolumes(); + const volumes = await retrieveModelVolumes(); // Call remote builder const result = await fetch(`${process.env.MODAL_BUILDER_URL!}/create`, { method: "POST", @@ -204,7 +204,7 @@ async function _buildMachine( callback_url: `${protocol}://${domain}/api/machine-built`, models: data.models, //JSON.parse(data.models as string), gpu: data.gpu && data.gpu.length > 0 ? data.gpu : "T4", - checkpoint_volume_name: volumes[0].volume_name, + model_volume_name: volumes[0].volume_name, }), }); diff --git a/web/src/server/curdCheckpoint.ts b/web/src/server/curdModel.ts similarity index 71% rename from web/src/server/curdCheckpoint.ts rename to web/src/server/curdModel.ts index 3c01532..cd22d16 100644 --- a/web/src/server/curdCheckpoint.ts +++ b/web/src/server/curdModel.ts @@ -2,92 +2,91 @@ import { auth } from "@clerk/nextjs"; import { - checkpointTable, - CheckpointType, - checkpointVolumeTable, - CheckpointVolumeType, + modelTable, + ModelType, + userVolume, + UserVolumeType, } from "@/db/schema"; import { withServerPromise } from "./withServerPromise"; import { db } from "@/db/db"; import type { z } from "zod"; import { headers } from "next/headers"; -import { addCivitaiCheckpointSchema } from "./addCheckpointSchema"; +import { addCivitaiModelSchema } from "./addCivitaiModelSchema"; import { and, eq, isNull } from "drizzle-orm"; -import { CivitaiModelResponse } from "@/types/civitai"; +import { CivitaiModelResponse, getModelTypeDetails } from "@/types/civitai"; -export async function getCheckpoints() { +export async function getModel() { const { userId, orgId } = auth(); if (!userId) throw new Error("No user id"); - const checkpoints = await db + const models = await db .select() - .from(checkpointTable) + .from(modelTable) .where( orgId - ? eq(checkpointTable.org_id, orgId) + ? eq(modelTable.org_id, orgId) // make sure org_id is null : and( - eq(checkpointTable.user_id, userId), - isNull(checkpointTable.org_id), + eq(modelTable.user_id, userId), + isNull(modelTable.org_id), ), ); - return checkpoints; + return models; } -export async function getCheckpointById(id: string) { +export async function getModelById(id: string) { const { userId, orgId } = auth(); if (!userId) throw new Error("No user id"); - const checkpoint = await db + const model = await db .select() - .from(checkpointTable) + .from(modelTable) .where( and( - orgId ? eq(checkpointTable.org_id, orgId) : and( - eq(checkpointTable.user_id, userId), - isNull(checkpointTable.org_id), + orgId ? eq(modelTable.org_id, orgId) : and( + eq(modelTable.user_id, userId), + isNull(modelTable.org_id), ), - eq(checkpointTable.id, id), + eq(modelTable.id, id), ), ); - return checkpoint[0]; + return model[0]; } -export async function getCheckpointVolumes() { +export async function getModelVolumes() { const { userId, orgId } = auth(); if (!userId) throw new Error("No user id"); const volume = await db .select() - .from(checkpointVolumeTable) + .from(userVolume) .where( and( orgId - ? eq(checkpointVolumeTable.org_id, orgId) + ? eq(userVolume.org_id, orgId) // make sure org_id is null : and( - eq(checkpointVolumeTable.user_id, userId), - isNull(checkpointVolumeTable.org_id), + eq(userVolume.user_id, userId), + isNull(userVolume.org_id), ), - eq(checkpointVolumeTable.disabled, false), + eq(userVolume.disabled, false), ), ); return volume; } -export async function retrieveCheckpointVolumes() { - let volumes = await getCheckpointVolumes(); +export async function retrieveModelVolumes() { + let volumes = await getModelVolumes(); if (volumes.length === 0) { // create volume if not already created - volumes = await addCheckpointVolume(); + volumes = await addModelVolume(); } return volumes; } -export async function addCheckpointVolume() { +export async function addModelVolume() { const { userId, orgId } = auth(); if (!userId) throw new Error("No user id"); - // Insert the new checkpointVolume into the checkpointVolumeTable const insertedVolume = await db - .insert(checkpointVolumeTable) + .insert(userVolume) .values({ user_id: userId, org_id: orgId, @@ -111,8 +110,8 @@ function getUrl(civitai_url: string) { return { url: baseUrl + modelId, modelVersionId }; } -export const addCivitaiCheckpoint = withServerPromise( - async (data: z.infer) => { +export const addCivitaiModel = withServerPromise( + async (data: z.infer) => { const { userId, orgId } = auth(); if (!data.civitai_url) return { error: "no civitai_url" }; @@ -145,17 +144,22 @@ export const addCivitaiCheckpoint = withServerPromise( selectedModelVersionId = selectedModelVersion?.id.toString(); } - const checkpointVolumes = await getCheckpointVolumes(); + const userVolume = await getModelVolumes(); let cVolume; - if (checkpointVolumes.length === 0) { - const volume = await addCheckpointVolume(); + if (userVolume.length === 0) { + const volume = await addModelVolume(); cVolume = volume[0]; } else { - cVolume = checkpointVolumes[0]; + cVolume = userVolume[0]; + } + + const model_type = getModelTypeDetails(civitaiModelRes.type); + if (!model_type) { + return } const a = await db - .insert(checkpointTable) + .insert(modelTable) .values({ user_id: userId, org_id: orgId, @@ -166,15 +170,15 @@ export const addCivitaiCheckpoint = withServerPromise( civitai_url: data.civitai_url, civitai_download_url: selectedModelVersion.files[0].downloadUrl, civitai_model_response: civitaiModelRes, - checkpoint_volume_id: cVolume.id, + user_volume_id: cVolume.id, + model_type, updated_at: new Date(), }) .returning(); const b = a[0]; - await uploadCheckpoint(data, b, cVolume); - // redirect(`/checkpoints/${b.id}`); + await uploadModel(data, b, cVolume); }, ); @@ -213,10 +217,10 @@ export const addCivitaiCheckpoint = withServerPromise( // }, // ); -async function uploadCheckpoint( - data: z.infer, - c: CheckpointType, - v: CheckpointVolumeType, +async function uploadModel( + data: z.infer, + c: ModelType, + v: UserVolumeType, ) { const headersList = headers(); @@ -239,9 +243,9 @@ async function uploadCheckpoint( download_url: c.civitai_download_url, volume_name: v.volume_name, volume_id: v.id, - checkpoint_id: c.id, + model_id: c.id, callback_url: `${protocol}://${domain}/api/volume-upload`, - upload_type: "checkpoint" + upload_type: c.model_type, }), }, ); @@ -249,23 +253,23 @@ async function uploadCheckpoint( if (!result.ok) { const error_log = await result.text(); await db - .update(checkpointTable) + .update(modelTable) .set({ ...data, status: "failed", error_log: error_log, }) - .where(eq(checkpointTable.id, c.id)); + .where(eq(modelTable.id, c.id)); throw new Error(`Error: ${result.statusText} ${error_log}`); } else { // setting the build machine id const json = await result.json(); await db - .update(checkpointTable) + .update(modelTable) .set({ ...data, upload_machine_id: json.build_machine_instance_id, }) - .where(eq(checkpointTable.id, c.id)); + .where(eq(modelTable.id, c.id)); } } diff --git a/web/src/server/getAllUserCheckpoints.tsx b/web/src/server/getAllUserModel.tsx similarity index 64% rename from web/src/server/getAllUserCheckpoints.tsx rename to web/src/server/getAllUserModel.tsx index a12a668..192d968 100644 --- a/web/src/server/getAllUserCheckpoints.tsx +++ b/web/src/server/getAllUserModel.tsx @@ -1,18 +1,18 @@ import { db } from "@/db/db"; import { - checkpointTable, + modelTable, } from "@/db/schema"; import { auth } from "@clerk/nextjs"; import { and, desc, eq, isNull } from "drizzle-orm"; -export async function getAllUserCheckpoints() { +export async function getAllUserModels() { const { userId, orgId } = await auth(); if (!userId) { return null; } - const checkpoints = await db.query.checkpointTable.findMany({ + const models = await db.query.modelTable.findMany({ with: { user: { columns: { @@ -28,14 +28,15 @@ export async function getAllUserCheckpoints() { civitai_model_response: true, is_public: true, upload_type: true, + model_type: true, status: true, }, - orderBy: desc(checkpointTable.updated_at), + orderBy: desc(modelTable.updated_at), where: orgId != undefined - ? eq(checkpointTable.org_id, orgId) - : and(eq(checkpointTable.user_id, userId), isNull(checkpointTable.org_id)), + ? eq(modelTable.org_id, orgId) + : and(eq(modelTable.user_id, userId), isNull(modelTable.org_id)), }); - return checkpoints; + return models; } diff --git a/web/src/types/civitai.ts b/web/src/types/civitai.ts index 5e57ed0..52b54b2 100644 --- a/web/src/types/civitai.ts +++ b/web/src/types/civitai.ts @@ -1,4 +1,5 @@ -import { z } from "zod"; +import { TypeOf, z } from "zod"; +import { modelEnumType } from "@/db/schema"; // from chatgpt https://chat.openai.com/share/4985d20b-30b1-4a28-87f6-6ebf84a1040e @@ -110,12 +111,21 @@ export const statsSchema = z.object({ tippedAmountCount: z.number(), }); +const civitaiModelType = z.enum([ + "Checkpoint", + "TextualInversion", + "Hypernetwork", + "AestheticGradient", + "LORA", + "Controlnet", + "Poses", +]); + export const CivitaiModelResponse = z.object({ id: z.number(), name: z.string().nullish(), description: z.string().nullish(), - // type: z.enum(["Checkpoint", "Lora"]), // TODO: this will be important to know - type: z.string(), + type: civitaiModelType, poi: z.boolean().nullish(), nsfw: z.boolean().nullish(), allowNoCredit: z.boolean().nullish(), @@ -127,3 +137,22 @@ export const CivitaiModelResponse = z.object({ tags: z.array(z.string()).nullish(), modelVersions: z.array(modelVersionSchema), }); + +export function getModelTypeDetails( + modelType: typeof civitaiModelType["_type"], +): modelEnumType | undefined { + switch (modelType) { + case "Checkpoint": + return "checkpoint" + case "TextualInversion": + return "embedding" + case "LORA": + return "lora" + case "AestheticGradient": + case "Hypernetwork": + case "Controlnet": + case "Poses": + default: + return undefined; + } +}