diff --git a/.env b/.env index 239dd2eba..df667700c 100644 --- a/.env +++ b/.env @@ -38,9 +38,10 @@ VIDEO_RELEVANCE_VIEWS_TICK=50 # views weight, # comments weight, # rections weights, -# [joystream creation weight, YT creation weight] +# [joystream creation weight, YT creation weight], +# Default channel weight/bias # ] -RELEVANCE_WEIGHTS="[1, 0.03, 0.3, 0.5, [7,3]]" +RELEVANCE_WEIGHTS="[1, 0.03, 0.3, 0.5, [7,3], 1]" MAX_CACHED_ENTITIES=1000 APP_PRIVATE_KEY=this-is-not-so-secret-change-it SESSION_EXPIRY_AFTER_INACTIVITY_MINUTES=60 @@ -59,4 +60,4 @@ SENDGRID_FROM_EMAIL=gateway@example.com # Debug settings SQD_DEBUG=api:* -OPENAPI_PLAYGROUND=true \ No newline at end of file +OPENAPI_PLAYGROUND=true diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a836ba3f..26f3c1c81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 3.1.0 + +- Adds supports for new permissions model for gateway operator users. Now the root user can assign/revoke operator permission/s to users using `grantPermissions` & `revokePermissions` mutations +- Adds new `setVideoWeights` operator mutation to set weight/bias for any channel/s which will be used to calculate the Atlas homepage video relevance scores + # 3.0.4 ### Misc diff --git a/db/migrations/1699504891472-Data.js b/db/migrations/1699504891472-Data.js new file mode 100644 index 000000000..9f122e6b0 --- /dev/null +++ b/db/migrations/1699504891472-Data.js @@ -0,0 +1,415 @@ +module.exports = class Data1699504891472 { + name = 'Data1699504891472' + + async up(db) { + await db.query(`CREATE TABLE "channel_follow" ("id" character varying NOT NULL, "user_id" character varying, "channel_id" text NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_9410df2b9a316af3f0d216f9487" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_822778b4b1ea8e3b60b127cb8b" ON "channel_follow" ("user_id") `) + await db.query(`CREATE INDEX "IDX_9bc0651dda94437ec18764a260" ON "channel_follow" ("channel_id") `) + await db.query(`CREATE TABLE "video_view_event" ("id" character varying NOT NULL, "video_id" text NOT NULL, "user_id" character varying, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_2efd85597a6a7a704fc4d0f7701" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_2e29fba63e12a2b1818e0782d7" ON "video_view_event" ("video_id") `) + await db.query(`CREATE INDEX "IDX_31e1e798ec387ad905cf98d33b" ON "video_view_event" ("user_id") `) + await db.query(`CREATE TABLE "report" ("id" character varying NOT NULL, "user_id" character varying, "channel_id" text, "video_id" text, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "rationale" text NOT NULL, CONSTRAINT "PK_99e4d0bea58cba73c57f935a546" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_c6686efa4cd49fa9a429f01bac" ON "report" ("user_id") `) + await db.query(`CREATE INDEX "IDX_893057921f4b5cc37a0ef36684" ON "report" ("channel_id") `) + await db.query(`CREATE INDEX "IDX_f732b6f82095a935db68c9491f" ON "report" ("video_id") `) + await db.query(`CREATE TABLE "nft_featuring_request" ("id" character varying NOT NULL, "user_id" character varying, "nft_id" text NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "rationale" text NOT NULL, CONSTRAINT "PK_d0b1ccb74336b30b9575387d328" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_519be2a41216c278c35f254dcb" ON "nft_featuring_request" ("user_id") `) + await db.query(`CREATE INDEX "IDX_76d87e26cce72ac2e7ffa28dfb" ON "nft_featuring_request" ("nft_id") `) + await db.query(`CREATE TABLE "user" ("id" character varying NOT NULL, "is_root" boolean NOT NULL, "permissions" character varying(34) array, CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "storage_bucket" ("id" character varying NOT NULL, "operator_status" jsonb NOT NULL, "accepting_new_bags" boolean NOT NULL, "data_objects_size_limit" numeric NOT NULL, "data_object_count_limit" numeric NOT NULL, "data_objects_count" numeric NOT NULL, "data_objects_size" numeric NOT NULL, CONSTRAINT "PK_97cd0c3fe7f51e34216822e5f91" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "storage_bucket_bag" ("id" character varying NOT NULL, "storage_bucket_id" character varying, "bag_id" character varying, CONSTRAINT "StorageBucketBag_storageBucket_bag" UNIQUE ("storage_bucket_id", "bag_id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "PK_9d54c04557134225652d566cc82" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_aaf00b2c7d0cba49f97da14fbb" ON "storage_bucket_bag" ("bag_id") `) + await db.query(`CREATE INDEX "IDX_4c475f6c9300284b095859eec3" ON "storage_bucket_bag" ("storage_bucket_id", "bag_id") `) + await db.query(`CREATE TABLE "distribution_bucket_family" ("id" character varying NOT NULL, CONSTRAINT "PK_8cb7454d1ec34b0d3bb7ecdee4e" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "distribution_bucket_operator" ("id" character varying NOT NULL, "distribution_bucket_id" character varying, "worker_id" integer NOT NULL, "status" character varying(7) NOT NULL, CONSTRAINT "PK_03b87e6e972f414bab94c142285" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_678dc5427cdde0cd4fef2c07a4" ON "distribution_bucket_operator" ("distribution_bucket_id") `) + await db.query(`CREATE TABLE "distribution_bucket" ("id" character varying NOT NULL, "family_id" character varying, "bucket_index" integer NOT NULL, "accepting_new_bags" boolean NOT NULL, "distributing" boolean NOT NULL, CONSTRAINT "PK_c90d25fff461f2f5fa9082e2fb7" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_8cb7454d1ec34b0d3bb7ecdee4" ON "distribution_bucket" ("family_id") `) + await db.query(`CREATE TABLE "distribution_bucket_bag" ("id" character varying NOT NULL, "distribution_bucket_id" character varying, "bag_id" character varying, CONSTRAINT "DistributionBucketBag_distributionBucket_bag" UNIQUE ("distribution_bucket_id", "bag_id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "PK_02cb97c17ccabf42e8f5154d002" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_a9810100aee7584680f197c8ff" ON "distribution_bucket_bag" ("bag_id") `) + await db.query(`CREATE INDEX "IDX_32e552d352848d64ab82d38e9a" ON "distribution_bucket_bag" ("distribution_bucket_id", "bag_id") `) + await db.query(`CREATE TABLE "storage_bag" ("id" character varying NOT NULL, "owner" jsonb NOT NULL, CONSTRAINT "PK_242aecdc788d9b22bcbb9ade19a" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "storage_data_object" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, "is_accepted" boolean NOT NULL, "size" numeric NOT NULL, "storage_bag_id" character varying, "ipfs_hash" text NOT NULL, "type" jsonb, "state_bloat_bond" numeric NOT NULL, "unset_at" TIMESTAMP WITH TIME ZONE, "resolved_urls" text array NOT NULL, CONSTRAINT "PK_61f224a4aef08f580a5ab4aadf0" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_ff8014300b8039dbaed764f51b" ON "storage_data_object" ("storage_bag_id") `) + await db.query(`CREATE TABLE "banned_member" ("id" character varying NOT NULL, "member_id" character varying, "channel_id" character varying, CONSTRAINT "BannedMember_member_channel" UNIQUE ("member_id", "channel_id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "PK_ebdf9a9c6d88f1116a5f2d0815d" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_ed36c6c26bf5410796c2fc21f7" ON "banned_member" ("channel_id") `) + await db.query(`CREATE INDEX "IDX_f29ff095bdb945975deca021ad" ON "banned_member" ("member_id", "channel_id") `) + await db.query(`CREATE TABLE "app" ("id" character varying NOT NULL, "name" text NOT NULL, "owner_member_id" character varying, "website_url" text, "use_uri" text, "small_icon" text, "medium_icon" text, "big_icon" text, "one_liner" text, "description" text, "terms_of_service" text, "platforms" text array, "category" text, "auth_key" text, CONSTRAINT "App_name" UNIQUE ("name") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "PK_9478629fc093d229df09e560aea" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_f36adbb7b096ceeb6f3e80ad14" ON "app" ("name") `) + await db.query(`CREATE INDEX "IDX_c9cc395bbc485f70a15be64553" ON "app" ("owner_member_id") `) + await db.query(`CREATE TABLE "channel" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, "owner_member_id" character varying, "title" text, "description" text, "cover_photo_id" character varying, "avatar_photo_id" character varying, "is_public" boolean, "is_censored" boolean NOT NULL, "is_excluded" boolean NOT NULL, "language" text, "created_in_block" integer NOT NULL, "reward_account" text NOT NULL, "channel_state_bloat_bond" numeric NOT NULL, "follows_num" integer NOT NULL, "video_views_num" integer NOT NULL, "entry_app_id" character varying, "total_videos_created" integer NOT NULL, "cumulative_reward_claimed" numeric NOT NULL, "cumulative_reward" numeric NOT NULL, "channel_weight" numeric, CONSTRAINT "PK_590f33ee6ee7d76437acf362e39" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_25c85bc448b5e236a4c1a5f789" ON "channel" ("owner_member_id") `) + await db.query(`CREATE INDEX "IDX_a77e12f3d8c6ced020e179a5e9" ON "channel" ("cover_photo_id") `) + await db.query(`CREATE INDEX "IDX_6997e94413b3f2f25a84e4a96f" ON "channel" ("avatar_photo_id") `) + await db.query(`CREATE INDEX "IDX_e58a2e1d78b8eccf40531a7fdb" ON "channel" ("language") `) + await db.query(`CREATE INDEX "IDX_118ecfa0199aeb5a014906933e" ON "channel" ("entry_app_id") `) + await db.query(`CREATE TABLE "video_featured_in_category" ("id" character varying NOT NULL, "video_id" character varying, "category_id" character varying, "video_cut_url" text, CONSTRAINT "VideoFeaturedInCategory_category_video" UNIQUE ("category_id", "video_id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "PK_f84d38b5cdb7567ac04d6e9d209" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_7b16ddad43901921a8d3c8eab7" ON "video_featured_in_category" ("video_id") `) + await db.query(`CREATE INDEX "IDX_6d0917e1ac0cc06c8075bcf256" ON "video_featured_in_category" ("category_id", "video_id") `) + await db.query(`CREATE TABLE "video_category" ("id" character varying NOT NULL, "name" text, "description" text, "parent_category_id" character varying, "is_supported" boolean NOT NULL, "created_in_block" integer NOT NULL, CONSTRAINT "PK_2a5c61f32e9636ee10821e9a58d" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_cbe7e5d162a819e4ee2e2f6105" ON "video_category" ("name") `) + await db.query(`CREATE INDEX "IDX_da26b34f037c0d59d3c0d0646e" ON "video_category" ("parent_category_id") `) + await db.query(`CREATE TABLE "license" ("id" character varying NOT NULL, "code" integer, "attribution" text, "custom_text" text, CONSTRAINT "PK_f168ac1ca5ba87286d03b2ef905" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "video_subtitle" ("id" character varying NOT NULL, "video_id" character varying, "type" text NOT NULL, "language" text, "mime_type" text NOT NULL, "asset_id" character varying, CONSTRAINT "PK_2ac3e585fc608e673e7fbf94d8e" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_2203674f18d8052ed6bac39625" ON "video_subtitle" ("video_id") `) + await db.query(`CREATE INDEX "IDX_ffa63c28188eecc32af921bfc3" ON "video_subtitle" ("language") `) + await db.query(`CREATE INDEX "IDX_b6eabfb8de4128b28d73681020" ON "video_subtitle" ("asset_id") `) + await db.query(`CREATE TABLE "comment_reaction" ("id" character varying NOT NULL, "reaction_id" integer NOT NULL, "member_id" character varying, "comment_id" character varying, "video_id" character varying, CONSTRAINT "PK_87f27d282c06eb61b1e0cde2d24" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_15080d9fb7cf8b563103dd9d90" ON "comment_reaction" ("member_id") `) + await db.query(`CREATE INDEX "IDX_962582f04d3f639e33f43c54bb" ON "comment_reaction" ("comment_id") `) + await db.query(`CREATE INDEX "IDX_d7995b1d57614a6fbd0c103874" ON "comment_reaction" ("video_id") `) + await db.query(`CREATE TABLE "comment" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, "author_id" character varying, "text" text NOT NULL, "video_id" character varying, "status" character varying(9) NOT NULL, "reactions_count_by_reaction_id" jsonb, "parent_comment_id" character varying, "replies_count" integer NOT NULL, "reactions_count" integer NOT NULL, "reactions_and_replies_count" integer NOT NULL, "is_edited" boolean NOT NULL, "is_excluded" boolean NOT NULL, CONSTRAINT "PK_0b0e4bbc8415ec426f87f3a88e2" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_3ce66469b26697baa097f8da92" ON "comment" ("author_id") `) + await db.query(`CREATE INDEX "IDX_1ff03403fd31dfeaba0623a89c" ON "comment" ("video_id") `) + await db.query(`CREATE INDEX "IDX_c3c2abe750c76c7c8e305f71f2" ON "comment" ("status") `) + await db.query(`CREATE INDEX "IDX_ac69bddf8202b7c0752d9dc8f3" ON "comment" ("parent_comment_id") `) + await db.query(`CREATE TABLE "video_reaction" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, "reaction" character varying(6) NOT NULL, "member_id" character varying, "video_id" character varying, CONSTRAINT "PK_504876585c394f4ab33665dd44b" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_73dda64f53bbc7ec7035d5e7f0" ON "video_reaction" ("member_id") `) + await db.query(`CREATE INDEX "IDX_436a3836eb47acb5e1e3c88dde" ON "video_reaction" ("video_id") `) + await db.query(`CREATE TABLE "video" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, "channel_id" character varying, "category_id" character varying, "title" text, "description" text, "duration" integer, "thumbnail_photo_id" character varying, "language" text, "has_marketing" boolean, "published_before_joystream" TIMESTAMP WITH TIME ZONE, "is_public" boolean, "is_censored" boolean NOT NULL, "is_excluded" boolean NOT NULL, "is_explicit" boolean, "license_id" character varying, "media_id" character varying, "video_state_bloat_bond" numeric NOT NULL, "created_in_block" integer NOT NULL, "is_comment_section_enabled" boolean NOT NULL, "pinned_comment_id" character varying, "comments_count" integer NOT NULL, "is_reaction_feature_enabled" boolean NOT NULL, "reactions_count_by_reaction_id" jsonb, "reactions_count" integer NOT NULL, "views_num" integer NOT NULL, "entry_app_id" character varying, "yt_video_id" text, "video_relevance" numeric NOT NULL, CONSTRAINT "PK_1a2f3856250765d72e7e1636c8e" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_81b11ef99a9db9ef1aed040d75" ON "video" ("channel_id") `) + await db.query(`CREATE INDEX "IDX_2a5c61f32e9636ee10821e9a58" ON "video" ("category_id") `) + await db.query(`CREATE INDEX "IDX_8530d052cc79b420f7ce2b4e09" ON "video" ("thumbnail_photo_id") `) + await db.query(`CREATE INDEX "IDX_75fbab42a4cb18371b6d5004b0" ON "video" ("language") `) + await db.query(`CREATE INDEX "IDX_3ec633ae5d0477f512b4ed957d" ON "video" ("license_id") `) + await db.query(`CREATE INDEX "IDX_2db879ed42e3308fe65e679672" ON "video" ("media_id") `) + await db.query(`CREATE INDEX "IDX_54f88a7decf7d22fd9bd9fa439" ON "video" ("pinned_comment_id") `) + await db.query(`CREATE INDEX "IDX_6c49ad08c44d36d11f77c426e4" ON "video" ("entry_app_id") `) + await db.query(`CREATE INDEX "IDX_f33816960d690ac836f5d5c28a" ON "video" ("video_relevance") `) + await db.query(`CREATE TABLE "bid" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, "auction_id" character varying, "nft_id" character varying, "bidder_id" character varying, "amount" numeric NOT NULL, "is_canceled" boolean NOT NULL, "created_in_block" integer NOT NULL, "index_in_block" integer NOT NULL, "previous_top_bid_id" character varying, CONSTRAINT "PK_ed405dda320051aca2dcb1a50bb" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_9e594e5a61c0f3cb25679f6ba8" ON "bid" ("auction_id") `) + await db.query(`CREATE INDEX "IDX_3caf2d6b31d2fe45a2b85b8191" ON "bid" ("nft_id") `) + await db.query(`CREATE INDEX "IDX_e7618559409a903a897164156b" ON "bid" ("bidder_id") `) + await db.query(`CREATE INDEX "IDX_32cb73025ec49c87f4c594a265" ON "bid" ("previous_top_bid_id") `) + await db.query(`CREATE TABLE "owned_nft" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, "video_id" character varying NOT NULL, "owner" jsonb NOT NULL, "transactional_status" jsonb, "creator_royalty" numeric, "last_sale_price" numeric, "last_sale_date" TIMESTAMP WITH TIME ZONE, "is_featured" boolean NOT NULL, CONSTRAINT "OwnedNft_video" UNIQUE ("video_id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "REL_466896e39b9ec953f4f2545622" UNIQUE ("video_id"), CONSTRAINT "PK_5e0c289b350e863668fff44bb56" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_466896e39b9ec953f4f2545622" ON "owned_nft" ("video_id") `) + await db.query(`CREATE TABLE "auction" ("id" character varying NOT NULL, "nft_id" character varying, "winning_member_id" character varying, "starting_price" numeric NOT NULL, "buy_now_price" numeric, "auction_type" jsonb NOT NULL, "top_bid_id" character varying, "starts_at_block" integer NOT NULL, "ended_at_block" integer, "is_canceled" boolean NOT NULL, "is_completed" boolean NOT NULL, CONSTRAINT "PK_9dc876c629273e71646cf6dfa67" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_cfb47e97e60c9d1462576f85a8" ON "auction" ("nft_id") `) + await db.query(`CREATE INDEX "IDX_a3127ec87cccc5696b92cac4e0" ON "auction" ("winning_member_id") `) + await db.query(`CREATE INDEX "IDX_1673ad4b059742fbabfc40b275" ON "auction" ("top_bid_id") `) + await db.query(`CREATE TABLE "auction_whitelisted_member" ("id" character varying NOT NULL, "auction_id" character varying, "member_id" character varying, CONSTRAINT "AuctionWhitelistedMember_auction_member" UNIQUE ("auction_id", "member_id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "PK_f20264ca8e878696fbc25f11bd5" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_d5ae4854487c7658b64225be30" ON "auction_whitelisted_member" ("member_id") `) + await db.query(`CREATE INDEX "IDX_5468573a96fa51c03743de5912" ON "auction_whitelisted_member" ("auction_id", "member_id") `) + await db.query(`CREATE TABLE "membership" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, "handle" text NOT NULL, "handle_raw" text NOT NULL, "controller_account" text NOT NULL, "total_channels_created" integer NOT NULL, CONSTRAINT "Membership_handleRaw" UNIQUE ("handle_raw") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "PK_83c1afebef3059472e7c37e8de8" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_0c5b879f9f2ca57a774f74f7f0" ON "membership" ("handle_raw") `) + await db.query(`CREATE TABLE "account" ("id" character varying NOT NULL, "user_id" character varying NOT NULL, "email" text NOT NULL, "is_email_confirmed" boolean NOT NULL, "is_blocked" boolean NOT NULL, "registered_at" TIMESTAMP WITH TIME ZONE NOT NULL, "membership_id" character varying NOT NULL, "joystream_account" text NOT NULL, CONSTRAINT "Account_joystreamAccount" UNIQUE ("joystream_account") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "Account_membership" UNIQUE ("membership_id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "Account_email" UNIQUE ("email") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "Account_user" UNIQUE ("user_id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "REL_efef1e5fdbe318a379c06678c5" UNIQUE ("user_id"), CONSTRAINT "REL_601b93655bcbe73cb58d8c80cd" UNIQUE ("membership_id"), CONSTRAINT "PK_54115ee388cdb6d86bb4bf5b2ea" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_efef1e5fdbe318a379c06678c5" ON "account" ("user_id") `) + await db.query(`CREATE INDEX "IDX_4c8f96ccf523e9a3faefd5bdd4" ON "account" ("email") `) + await db.query(`CREATE INDEX "IDX_601b93655bcbe73cb58d8c80cd" ON "account" ("membership_id") `) + await db.query(`CREATE INDEX "IDX_df4da05a7a80c1afd18b8f0990" ON "account" ("joystream_account") `) + await db.query(`CREATE TABLE "encryption_artifacts" ("id" character varying NOT NULL, "account_id" character varying NOT NULL, "cipher_iv" text NOT NULL, "encrypted_seed" text NOT NULL, CONSTRAINT "EncryptionArtifacts_account" UNIQUE ("account_id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "REL_ec8f68a544aadc4fbdadefe4a0" UNIQUE ("account_id"), CONSTRAINT "PK_6441471581ba6d149ad75655bd0" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_ec8f68a544aadc4fbdadefe4a0" ON "encryption_artifacts" ("account_id") `) + await db.query(`CREATE TABLE "session" ("id" character varying NOT NULL, "browser" text NOT NULL, "os" text NOT NULL, "device" text NOT NULL, "device_type" text, "user_id" character varying, "account_id" character varying, "ip" text NOT NULL, "started_at" TIMESTAMP WITH TIME ZONE NOT NULL, "expiry" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_f55da76ac1c3ac420f444d2ff11" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_30e98e8746699fb9af235410af" ON "session" ("user_id") `) + await db.query(`CREATE INDEX "IDX_fae5a6b4a57f098e9af8520d49" ON "session" ("account_id") `) + await db.query(`CREATE INDEX "IDX_213b5a19bfdbe0ab6e06b1dede" ON "session" ("ip") `) + await db.query(`CREATE TABLE "session_encryption_artifacts" ("id" character varying NOT NULL, "session_id" character varying NOT NULL, "cipher_iv" text NOT NULL, "cipher_key" text NOT NULL, CONSTRAINT "SessionEncryptionArtifacts_session" UNIQUE ("session_id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "REL_3612880efd8926a17eba5ab0e1" UNIQUE ("session_id"), CONSTRAINT "PK_e328da2643599e265a848219885" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_3612880efd8926a17eba5ab0e1" ON "session_encryption_artifacts" ("session_id") `) + await db.query(`CREATE TABLE "token" ("id" character varying NOT NULL, "type" character varying(18) NOT NULL, "issued_at" TIMESTAMP WITH TIME ZONE NOT NULL, "expiry" TIMESTAMP WITH TIME ZONE NOT NULL, "issued_for_id" character varying, CONSTRAINT "PK_82fae97f905930df5d62a702fc9" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_a6fe18c105f85a63d761ccb078" ON "token" ("issued_for_id") `) + await db.query(`CREATE TABLE "event" ("id" character varying NOT NULL, "in_block" integer NOT NULL, "in_extrinsic" text, "index_in_block" integer NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "data" jsonb NOT NULL, CONSTRAINT "PK_30c2f3bbaf6d34a55f8ae6e4614" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_8f3f220c4e717207d841d4e6d4" ON "event" ("in_extrinsic") `) + await db.query(`CREATE TABLE "notification" ("id" character varying NOT NULL, "member_id" character varying, "event_id" character varying, CONSTRAINT "PK_705b6c7cdf9b2c2ff7ac7872cb7" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_ac8de39626657d3c0e909d9d82" ON "notification" ("member_id") `) + await db.query(`CREATE INDEX "IDX_122be1f0696e0255acf95f9e33" ON "notification" ("event_id") `) + await db.query(`CREATE TABLE "nft_history_entry" ("id" character varying NOT NULL, "nft_id" character varying, "event_id" character varying, CONSTRAINT "PK_9018e80b335a965a54959c4c6e2" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_57f51d35ecab042478fe2e31c1" ON "nft_history_entry" ("nft_id") `) + await db.query(`CREATE INDEX "IDX_d1a28b178f5d028d048d40ce20" ON "nft_history_entry" ("event_id") `) + await db.query(`CREATE TABLE "nft_activity" ("id" character varying NOT NULL, "member_id" character varying, "event_id" character varying, CONSTRAINT "PK_1553b1bbf8000039875a6e31536" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_18a65713a9fd0715c7a980f5d5" ON "nft_activity" ("member_id") `) + await db.query(`CREATE INDEX "IDX_94d325a753f2c08fdd416eb095" ON "nft_activity" ("event_id") `) + await db.query(`CREATE TABLE "video_hero" ("id" character varying NOT NULL, "video_id" character varying, "hero_title" text NOT NULL, "hero_video_cut_url" text NOT NULL, "hero_poster_url" text NOT NULL, "activated_at" TIMESTAMP WITH TIME ZONE, CONSTRAINT "PK_f3b63979879773378afac0b9495" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_9feac5d9713a9f07e32eb8ba7a" ON "video_hero" ("video_id") `) + await db.query(`CREATE TABLE "video_media_encoding" ("id" character varying NOT NULL, "codec_name" text, "container" text, "mime_media_type" text, CONSTRAINT "PK_52e25874f8d8a381e154d1125e0" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "video_media_metadata" ("id" character varying NOT NULL, "encoding_id" character varying, "pixel_width" integer, "pixel_height" integer, "size" numeric, "video_id" character varying NOT NULL, "created_in_block" integer NOT NULL, CONSTRAINT "VideoMediaMetadata_video" UNIQUE ("video_id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "REL_4dc101240e8e1536b770aee202" UNIQUE ("video_id"), CONSTRAINT "PK_86a13815734e589cd86d0465e2d" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_5944dc5896cb16bd395414a0ce" ON "video_media_metadata" ("encoding_id") `) + await db.query(`CREATE INDEX "IDX_4dc101240e8e1536b770aee202" ON "video_media_metadata" ("video_id") `) + await db.query(`CREATE TABLE "gateway_config" ("id" character varying NOT NULL, "value" text NOT NULL, "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_db1fa5a857fb6292eee4c493e6f" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "storage_bucket_operator_metadata" ("id" character varying NOT NULL, "storage_bucket_id" character varying NOT NULL, "node_endpoint" text, "node_location" jsonb, "extra" text, CONSTRAINT "StorageBucketOperatorMetadata_storageBucket" UNIQUE ("storage_bucket_id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "REL_7beffc9530b3f307bc1169cb52" UNIQUE ("storage_bucket_id"), CONSTRAINT "PK_9846a397400ae1a39b21fbd02d4" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_7beffc9530b3f307bc1169cb52" ON "storage_bucket_operator_metadata" ("storage_bucket_id") `) + await db.query(`CREATE TABLE "distribution_bucket_family_metadata" ("id" character varying NOT NULL, "family_id" character varying NOT NULL, "region" text, "description" text, "areas" jsonb, "latency_test_targets" text array, CONSTRAINT "DistributionBucketFamilyMetadata_family" UNIQUE ("family_id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "REL_dd93ca0ea24f3e7a02f11c4c14" UNIQUE ("family_id"), CONSTRAINT "PK_df7a270835bb313d3ef17bdee2f" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_dd93ca0ea24f3e7a02f11c4c14" ON "distribution_bucket_family_metadata" ("family_id") `) + await db.query(`CREATE INDEX "IDX_5510d3b244a63d6ec702faa426" ON "distribution_bucket_family_metadata" ("region") `) + await db.query(`CREATE TABLE "distribution_bucket_operator_metadata" ("id" character varying NOT NULL, "distirbution_bucket_operator_id" character varying NOT NULL, "node_endpoint" text, "node_location" jsonb, "extra" text, CONSTRAINT "DistributionBucketOperatorMetadata_distirbutionBucketOperator" UNIQUE ("distirbution_bucket_operator_id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "REL_69ec9bdc975b95f7dff94a7106" UNIQUE ("distirbution_bucket_operator_id"), CONSTRAINT "PK_9bbecaa12f30e3826922688274f" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_69ec9bdc975b95f7dff94a7106" ON "distribution_bucket_operator_metadata" ("distirbution_bucket_operator_id") `) + await db.query(`CREATE TABLE "curator_group" ("id" character varying NOT NULL, "is_active" boolean NOT NULL, CONSTRAINT "PK_0b4c0ab279d72bcbf4e16b65ff1" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "curator" ("id" character varying NOT NULL, CONSTRAINT "PK_5791051a62d2c2dfc593d38ab57" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "member_metadata" ("id" character varying NOT NULL, "name" text, "avatar" jsonb, "about" text, "member_id" character varying NOT NULL, CONSTRAINT "MemberMetadata_member" UNIQUE ("member_id") DEFERRABLE INITIALLY DEFERRED, CONSTRAINT "REL_e7e4d350f82ae2383894f465ed" UNIQUE ("member_id"), CONSTRAINT "PK_d3fcc374696465f3c0ac3ba8708" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_e7e4d350f82ae2383894f465ed" ON "member_metadata" ("member_id") `) + await db.query(`CREATE TABLE "next_entity_id" ("entity_name" character varying NOT NULL, "next_id" bigint NOT NULL, CONSTRAINT "PK_09a3b40db622a65096e7344d7ae" PRIMARY KEY ("entity_name"))`) + await db.query(`ALTER TABLE "channel_follow" ADD CONSTRAINT "FK_822778b4b1ea8e3b60b127cb8b1" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video_view_event" ADD CONSTRAINT "FK_31e1e798ec387ad905cf98d33b0" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "report" ADD CONSTRAINT "FK_c6686efa4cd49fa9a429f01bac8" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "nft_featuring_request" ADD CONSTRAINT "FK_519be2a41216c278c35f254dcba" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "storage_bucket_bag" ADD CONSTRAINT "FK_791e2f82e3919ffcef8712aa1b9" FOREIGN KEY ("storage_bucket_id") REFERENCES "storage_bucket"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "storage_bucket_bag" ADD CONSTRAINT "FK_aaf00b2c7d0cba49f97da14fbba" FOREIGN KEY ("bag_id") REFERENCES "storage_bag"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "distribution_bucket_operator" ADD CONSTRAINT "FK_678dc5427cdde0cd4fef2c07a43" FOREIGN KEY ("distribution_bucket_id") REFERENCES "distribution_bucket"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "distribution_bucket" ADD CONSTRAINT "FK_8cb7454d1ec34b0d3bb7ecdee4e" FOREIGN KEY ("family_id") REFERENCES "distribution_bucket_family"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "distribution_bucket_bag" ADD CONSTRAINT "FK_8a807921f1aae60d4ba94895826" FOREIGN KEY ("distribution_bucket_id") REFERENCES "distribution_bucket"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "distribution_bucket_bag" ADD CONSTRAINT "FK_a9810100aee7584680f197c8ff0" FOREIGN KEY ("bag_id") REFERENCES "storage_bag"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "storage_data_object" ADD CONSTRAINT "FK_ff8014300b8039dbaed764f51bc" FOREIGN KEY ("storage_bag_id") REFERENCES "storage_bag"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "banned_member" ADD CONSTRAINT "FK_b94ea874da235d9b6fbc35cf58e" FOREIGN KEY ("member_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "banned_member" ADD CONSTRAINT "FK_ed36c6c26bf5410796c2fc21f74" FOREIGN KEY ("channel_id") REFERENCES "channel"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "app" ADD CONSTRAINT "FK_c9cc395bbc485f70a15be64553e" FOREIGN KEY ("owner_member_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "channel" ADD CONSTRAINT "FK_25c85bc448b5e236a4c1a5f7895" FOREIGN KEY ("owner_member_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "channel" ADD CONSTRAINT "FK_a77e12f3d8c6ced020e179a5e94" FOREIGN KEY ("cover_photo_id") REFERENCES "storage_data_object"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "channel" ADD CONSTRAINT "FK_6997e94413b3f2f25a84e4a96f8" FOREIGN KEY ("avatar_photo_id") REFERENCES "storage_data_object"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "channel" ADD CONSTRAINT "FK_118ecfa0199aeb5a014906933e8" FOREIGN KEY ("entry_app_id") REFERENCES "app"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video_featured_in_category" ADD CONSTRAINT "FK_7b16ddad43901921a8d3c8eab71" FOREIGN KEY ("video_id") REFERENCES "video"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video_featured_in_category" ADD CONSTRAINT "FK_0e6bb49ce9d022cd872f3ab4288" FOREIGN KEY ("category_id") REFERENCES "video_category"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video_category" ADD CONSTRAINT "FK_da26b34f037c0d59d3c0d0646e9" FOREIGN KEY ("parent_category_id") REFERENCES "video_category"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video_subtitle" ADD CONSTRAINT "FK_2203674f18d8052ed6bac396252" FOREIGN KEY ("video_id") REFERENCES "video"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video_subtitle" ADD CONSTRAINT "FK_b6eabfb8de4128b28d73681020f" FOREIGN KEY ("asset_id") REFERENCES "storage_data_object"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "comment_reaction" ADD CONSTRAINT "FK_15080d9fb7cf8b563103dd9d900" FOREIGN KEY ("member_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "comment_reaction" ADD CONSTRAINT "FK_962582f04d3f639e33f43c54bbc" FOREIGN KEY ("comment_id") REFERENCES "comment"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "comment_reaction" ADD CONSTRAINT "FK_d7995b1d57614a6fbd0c103874d" FOREIGN KEY ("video_id") REFERENCES "video"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "comment" ADD CONSTRAINT "FK_3ce66469b26697baa097f8da923" FOREIGN KEY ("author_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "comment" ADD CONSTRAINT "FK_1ff03403fd31dfeaba0623a89cf" FOREIGN KEY ("video_id") REFERENCES "video"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "comment" ADD CONSTRAINT "FK_ac69bddf8202b7c0752d9dc8f32" FOREIGN KEY ("parent_comment_id") REFERENCES "comment"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video_reaction" ADD CONSTRAINT "FK_73dda64f53bbc7ec7035d5e7f09" FOREIGN KEY ("member_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video_reaction" ADD CONSTRAINT "FK_436a3836eb47acb5e1e3c88ddea" FOREIGN KEY ("video_id") REFERENCES "video"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video" ADD CONSTRAINT "FK_81b11ef99a9db9ef1aed040d750" FOREIGN KEY ("channel_id") REFERENCES "channel"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video" ADD CONSTRAINT "FK_2a5c61f32e9636ee10821e9a58d" FOREIGN KEY ("category_id") REFERENCES "video_category"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video" ADD CONSTRAINT "FK_8530d052cc79b420f7ce2b4e09d" FOREIGN KEY ("thumbnail_photo_id") REFERENCES "storage_data_object"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video" ADD CONSTRAINT "FK_3ec633ae5d0477f512b4ed957d6" FOREIGN KEY ("license_id") REFERENCES "license"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video" ADD CONSTRAINT "FK_2db879ed42e3308fe65e6796729" FOREIGN KEY ("media_id") REFERENCES "storage_data_object"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video" ADD CONSTRAINT "FK_54f88a7decf7d22fd9bd9fa439a" FOREIGN KEY ("pinned_comment_id") REFERENCES "comment"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video" ADD CONSTRAINT "FK_6c49ad08c44d36d11f77c426e43" FOREIGN KEY ("entry_app_id") REFERENCES "app"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "bid" ADD CONSTRAINT "FK_9e594e5a61c0f3cb25679f6ba8d" FOREIGN KEY ("auction_id") REFERENCES "auction"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "bid" ADD CONSTRAINT "FK_3caf2d6b31d2fe45a2b85b81912" FOREIGN KEY ("nft_id") REFERENCES "owned_nft"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "bid" ADD CONSTRAINT "FK_e7618559409a903a897164156b7" FOREIGN KEY ("bidder_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "bid" ADD CONSTRAINT "FK_32cb73025ec49c87f4c594a265f" FOREIGN KEY ("previous_top_bid_id") REFERENCES "bid"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "owned_nft" ADD CONSTRAINT "FK_466896e39b9ec953f4f2545622d" FOREIGN KEY ("video_id") REFERENCES "video"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "auction" ADD CONSTRAINT "FK_cfb47e97e60c9d1462576f85a88" FOREIGN KEY ("nft_id") REFERENCES "owned_nft"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "auction" ADD CONSTRAINT "FK_a3127ec87cccc5696b92cac4e09" FOREIGN KEY ("winning_member_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "auction" ADD CONSTRAINT "FK_1673ad4b059742fbabfc40b275c" FOREIGN KEY ("top_bid_id") REFERENCES "bid"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "auction_whitelisted_member" ADD CONSTRAINT "FK_aad797677bc7c7c7dc1f1d397f5" FOREIGN KEY ("auction_id") REFERENCES "auction"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "auction_whitelisted_member" ADD CONSTRAINT "FK_d5ae4854487c7658b64225be305" FOREIGN KEY ("member_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "account" ADD CONSTRAINT "FK_efef1e5fdbe318a379c06678c51" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "account" ADD CONSTRAINT "FK_601b93655bcbe73cb58d8c80cd3" FOREIGN KEY ("membership_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "encryption_artifacts" ADD CONSTRAINT "FK_ec8f68a544aadc4fbdadefe4a0a" FOREIGN KEY ("account_id") REFERENCES "account"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "session" ADD CONSTRAINT "FK_30e98e8746699fb9af235410aff" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "session" ADD CONSTRAINT "FK_fae5a6b4a57f098e9af8520d499" FOREIGN KEY ("account_id") REFERENCES "account"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "session_encryption_artifacts" ADD CONSTRAINT "FK_3612880efd8926a17eba5ab0e1a" FOREIGN KEY ("session_id") REFERENCES "session"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "token" ADD CONSTRAINT "FK_a6fe18c105f85a63d761ccb0780" FOREIGN KEY ("issued_for_id") REFERENCES "account"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_ac8de39626657d3c0e909d9d82f" FOREIGN KEY ("member_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_122be1f0696e0255acf95f9e336" FOREIGN KEY ("event_id") REFERENCES "event"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "nft_history_entry" ADD CONSTRAINT "FK_57f51d35ecab042478fe2e31c19" FOREIGN KEY ("nft_id") REFERENCES "owned_nft"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "nft_history_entry" ADD CONSTRAINT "FK_d1a28b178f5d028d048d40ce208" FOREIGN KEY ("event_id") REFERENCES "event"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "nft_activity" ADD CONSTRAINT "FK_18a65713a9fd0715c7a980f5d54" FOREIGN KEY ("member_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "nft_activity" ADD CONSTRAINT "FK_94d325a753f2c08fdd416eb095f" FOREIGN KEY ("event_id") REFERENCES "event"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video_hero" ADD CONSTRAINT "FK_9feac5d9713a9f07e32eb8ba7a1" FOREIGN KEY ("video_id") REFERENCES "video"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video_media_metadata" ADD CONSTRAINT "FK_5944dc5896cb16bd395414a0ce0" FOREIGN KEY ("encoding_id") REFERENCES "video_media_encoding"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "video_media_metadata" ADD CONSTRAINT "FK_4dc101240e8e1536b770aee202a" FOREIGN KEY ("video_id") REFERENCES "video"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "storage_bucket_operator_metadata" ADD CONSTRAINT "FK_7beffc9530b3f307bc1169cb524" FOREIGN KEY ("storage_bucket_id") REFERENCES "storage_bucket"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "distribution_bucket_family_metadata" ADD CONSTRAINT "FK_dd93ca0ea24f3e7a02f11c4c149" FOREIGN KEY ("family_id") REFERENCES "distribution_bucket_family"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "distribution_bucket_operator_metadata" ADD CONSTRAINT "FK_69ec9bdc975b95f7dff94a71069" FOREIGN KEY ("distirbution_bucket_operator_id") REFERENCES "distribution_bucket_operator"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + await db.query(`ALTER TABLE "member_metadata" ADD CONSTRAINT "FK_e7e4d350f82ae2383894f465ede" FOREIGN KEY ("member_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED`) + } + + async down(db) { + await db.query(`DROP TABLE "channel_follow"`) + await db.query(`DROP INDEX "public"."IDX_822778b4b1ea8e3b60b127cb8b"`) + await db.query(`DROP INDEX "public"."IDX_9bc0651dda94437ec18764a260"`) + await db.query(`DROP TABLE "video_view_event"`) + await db.query(`DROP INDEX "public"."IDX_2e29fba63e12a2b1818e0782d7"`) + await db.query(`DROP INDEX "public"."IDX_31e1e798ec387ad905cf98d33b"`) + await db.query(`DROP TABLE "report"`) + await db.query(`DROP INDEX "public"."IDX_c6686efa4cd49fa9a429f01bac"`) + await db.query(`DROP INDEX "public"."IDX_893057921f4b5cc37a0ef36684"`) + await db.query(`DROP INDEX "public"."IDX_f732b6f82095a935db68c9491f"`) + await db.query(`DROP TABLE "nft_featuring_request"`) + await db.query(`DROP INDEX "public"."IDX_519be2a41216c278c35f254dcb"`) + await db.query(`DROP INDEX "public"."IDX_76d87e26cce72ac2e7ffa28dfb"`) + await db.query(`DROP TABLE "user"`) + await db.query(`DROP TABLE "storage_bucket"`) + await db.query(`DROP TABLE "storage_bucket_bag"`) + await db.query(`DROP INDEX "public"."IDX_aaf00b2c7d0cba49f97da14fbb"`) + await db.query(`DROP INDEX "public"."IDX_4c475f6c9300284b095859eec3"`) + await db.query(`DROP TABLE "distribution_bucket_family"`) + await db.query(`DROP TABLE "distribution_bucket_operator"`) + await db.query(`DROP INDEX "public"."IDX_678dc5427cdde0cd4fef2c07a4"`) + await db.query(`DROP TABLE "distribution_bucket"`) + await db.query(`DROP INDEX "public"."IDX_8cb7454d1ec34b0d3bb7ecdee4"`) + await db.query(`DROP TABLE "distribution_bucket_bag"`) + await db.query(`DROP INDEX "public"."IDX_a9810100aee7584680f197c8ff"`) + await db.query(`DROP INDEX "public"."IDX_32e552d352848d64ab82d38e9a"`) + await db.query(`DROP TABLE "storage_bag"`) + await db.query(`DROP TABLE "storage_data_object"`) + await db.query(`DROP INDEX "public"."IDX_ff8014300b8039dbaed764f51b"`) + await db.query(`DROP TABLE "banned_member"`) + await db.query(`DROP INDEX "public"."IDX_ed36c6c26bf5410796c2fc21f7"`) + await db.query(`DROP INDEX "public"."IDX_f29ff095bdb945975deca021ad"`) + await db.query(`DROP TABLE "app"`) + await db.query(`DROP INDEX "public"."IDX_f36adbb7b096ceeb6f3e80ad14"`) + await db.query(`DROP INDEX "public"."IDX_c9cc395bbc485f70a15be64553"`) + await db.query(`DROP TABLE "channel"`) + await db.query(`DROP INDEX "public"."IDX_25c85bc448b5e236a4c1a5f789"`) + await db.query(`DROP INDEX "public"."IDX_a77e12f3d8c6ced020e179a5e9"`) + await db.query(`DROP INDEX "public"."IDX_6997e94413b3f2f25a84e4a96f"`) + await db.query(`DROP INDEX "public"."IDX_e58a2e1d78b8eccf40531a7fdb"`) + await db.query(`DROP INDEX "public"."IDX_118ecfa0199aeb5a014906933e"`) + await db.query(`DROP TABLE "video_featured_in_category"`) + await db.query(`DROP INDEX "public"."IDX_7b16ddad43901921a8d3c8eab7"`) + await db.query(`DROP INDEX "public"."IDX_6d0917e1ac0cc06c8075bcf256"`) + await db.query(`DROP TABLE "video_category"`) + await db.query(`DROP INDEX "public"."IDX_cbe7e5d162a819e4ee2e2f6105"`) + await db.query(`DROP INDEX "public"."IDX_da26b34f037c0d59d3c0d0646e"`) + await db.query(`DROP TABLE "license"`) + await db.query(`DROP TABLE "video_subtitle"`) + await db.query(`DROP INDEX "public"."IDX_2203674f18d8052ed6bac39625"`) + await db.query(`DROP INDEX "public"."IDX_ffa63c28188eecc32af921bfc3"`) + await db.query(`DROP INDEX "public"."IDX_b6eabfb8de4128b28d73681020"`) + await db.query(`DROP TABLE "comment_reaction"`) + await db.query(`DROP INDEX "public"."IDX_15080d9fb7cf8b563103dd9d90"`) + await db.query(`DROP INDEX "public"."IDX_962582f04d3f639e33f43c54bb"`) + await db.query(`DROP INDEX "public"."IDX_d7995b1d57614a6fbd0c103874"`) + await db.query(`DROP TABLE "comment"`) + await db.query(`DROP INDEX "public"."IDX_3ce66469b26697baa097f8da92"`) + await db.query(`DROP INDEX "public"."IDX_1ff03403fd31dfeaba0623a89c"`) + await db.query(`DROP INDEX "public"."IDX_c3c2abe750c76c7c8e305f71f2"`) + await db.query(`DROP INDEX "public"."IDX_ac69bddf8202b7c0752d9dc8f3"`) + await db.query(`DROP TABLE "video_reaction"`) + await db.query(`DROP INDEX "public"."IDX_73dda64f53bbc7ec7035d5e7f0"`) + await db.query(`DROP INDEX "public"."IDX_436a3836eb47acb5e1e3c88dde"`) + await db.query(`DROP TABLE "video"`) + await db.query(`DROP INDEX "public"."IDX_81b11ef99a9db9ef1aed040d75"`) + await db.query(`DROP INDEX "public"."IDX_2a5c61f32e9636ee10821e9a58"`) + await db.query(`DROP INDEX "public"."IDX_8530d052cc79b420f7ce2b4e09"`) + await db.query(`DROP INDEX "public"."IDX_75fbab42a4cb18371b6d5004b0"`) + await db.query(`DROP INDEX "public"."IDX_3ec633ae5d0477f512b4ed957d"`) + await db.query(`DROP INDEX "public"."IDX_2db879ed42e3308fe65e679672"`) + await db.query(`DROP INDEX "public"."IDX_54f88a7decf7d22fd9bd9fa439"`) + await db.query(`DROP INDEX "public"."IDX_6c49ad08c44d36d11f77c426e4"`) + await db.query(`DROP INDEX "public"."IDX_f33816960d690ac836f5d5c28a"`) + await db.query(`DROP TABLE "bid"`) + await db.query(`DROP INDEX "public"."IDX_9e594e5a61c0f3cb25679f6ba8"`) + await db.query(`DROP INDEX "public"."IDX_3caf2d6b31d2fe45a2b85b8191"`) + await db.query(`DROP INDEX "public"."IDX_e7618559409a903a897164156b"`) + await db.query(`DROP INDEX "public"."IDX_32cb73025ec49c87f4c594a265"`) + await db.query(`DROP TABLE "owned_nft"`) + await db.query(`DROP INDEX "public"."IDX_466896e39b9ec953f4f2545622"`) + await db.query(`DROP TABLE "auction"`) + await db.query(`DROP INDEX "public"."IDX_cfb47e97e60c9d1462576f85a8"`) + await db.query(`DROP INDEX "public"."IDX_a3127ec87cccc5696b92cac4e0"`) + await db.query(`DROP INDEX "public"."IDX_1673ad4b059742fbabfc40b275"`) + await db.query(`DROP TABLE "auction_whitelisted_member"`) + await db.query(`DROP INDEX "public"."IDX_d5ae4854487c7658b64225be30"`) + await db.query(`DROP INDEX "public"."IDX_5468573a96fa51c03743de5912"`) + await db.query(`DROP TABLE "membership"`) + await db.query(`DROP INDEX "public"."IDX_0c5b879f9f2ca57a774f74f7f0"`) + await db.query(`DROP TABLE "account"`) + await db.query(`DROP INDEX "public"."IDX_efef1e5fdbe318a379c06678c5"`) + await db.query(`DROP INDEX "public"."IDX_4c8f96ccf523e9a3faefd5bdd4"`) + await db.query(`DROP INDEX "public"."IDX_601b93655bcbe73cb58d8c80cd"`) + await db.query(`DROP INDEX "public"."IDX_df4da05a7a80c1afd18b8f0990"`) + await db.query(`DROP TABLE "encryption_artifacts"`) + await db.query(`DROP INDEX "public"."IDX_ec8f68a544aadc4fbdadefe4a0"`) + await db.query(`DROP TABLE "session"`) + await db.query(`DROP INDEX "public"."IDX_30e98e8746699fb9af235410af"`) + await db.query(`DROP INDEX "public"."IDX_fae5a6b4a57f098e9af8520d49"`) + await db.query(`DROP INDEX "public"."IDX_213b5a19bfdbe0ab6e06b1dede"`) + await db.query(`DROP TABLE "session_encryption_artifacts"`) + await db.query(`DROP INDEX "public"."IDX_3612880efd8926a17eba5ab0e1"`) + await db.query(`DROP TABLE "token"`) + await db.query(`DROP INDEX "public"."IDX_a6fe18c105f85a63d761ccb078"`) + await db.query(`DROP TABLE "event"`) + await db.query(`DROP INDEX "public"."IDX_8f3f220c4e717207d841d4e6d4"`) + await db.query(`DROP TABLE "notification"`) + await db.query(`DROP INDEX "public"."IDX_ac8de39626657d3c0e909d9d82"`) + await db.query(`DROP INDEX "public"."IDX_122be1f0696e0255acf95f9e33"`) + await db.query(`DROP TABLE "nft_history_entry"`) + await db.query(`DROP INDEX "public"."IDX_57f51d35ecab042478fe2e31c1"`) + await db.query(`DROP INDEX "public"."IDX_d1a28b178f5d028d048d40ce20"`) + await db.query(`DROP TABLE "nft_activity"`) + await db.query(`DROP INDEX "public"."IDX_18a65713a9fd0715c7a980f5d5"`) + await db.query(`DROP INDEX "public"."IDX_94d325a753f2c08fdd416eb095"`) + await db.query(`DROP TABLE "video_hero"`) + await db.query(`DROP INDEX "public"."IDX_9feac5d9713a9f07e32eb8ba7a"`) + await db.query(`DROP TABLE "video_media_encoding"`) + await db.query(`DROP TABLE "video_media_metadata"`) + await db.query(`DROP INDEX "public"."IDX_5944dc5896cb16bd395414a0ce"`) + await db.query(`DROP INDEX "public"."IDX_4dc101240e8e1536b770aee202"`) + await db.query(`DROP TABLE "gateway_config"`) + await db.query(`DROP TABLE "storage_bucket_operator_metadata"`) + await db.query(`DROP INDEX "public"."IDX_7beffc9530b3f307bc1169cb52"`) + await db.query(`DROP TABLE "distribution_bucket_family_metadata"`) + await db.query(`DROP INDEX "public"."IDX_dd93ca0ea24f3e7a02f11c4c14"`) + await db.query(`DROP INDEX "public"."IDX_5510d3b244a63d6ec702faa426"`) + await db.query(`DROP TABLE "distribution_bucket_operator_metadata"`) + await db.query(`DROP INDEX "public"."IDX_69ec9bdc975b95f7dff94a7106"`) + await db.query(`DROP TABLE "curator_group"`) + await db.query(`DROP TABLE "curator"`) + await db.query(`DROP TABLE "member_metadata"`) + await db.query(`DROP INDEX "public"."IDX_e7e4d350f82ae2383894f465ed"`) + await db.query(`DROP TABLE "next_entity_id"`) + await db.query(`ALTER TABLE "channel_follow" DROP CONSTRAINT "FK_822778b4b1ea8e3b60b127cb8b1"`) + await db.query(`ALTER TABLE "video_view_event" DROP CONSTRAINT "FK_31e1e798ec387ad905cf98d33b0"`) + await db.query(`ALTER TABLE "report" DROP CONSTRAINT "FK_c6686efa4cd49fa9a429f01bac8"`) + await db.query(`ALTER TABLE "nft_featuring_request" DROP CONSTRAINT "FK_519be2a41216c278c35f254dcba"`) + await db.query(`ALTER TABLE "storage_bucket_bag" DROP CONSTRAINT "FK_791e2f82e3919ffcef8712aa1b9"`) + await db.query(`ALTER TABLE "storage_bucket_bag" DROP CONSTRAINT "FK_aaf00b2c7d0cba49f97da14fbba"`) + await db.query(`ALTER TABLE "distribution_bucket_operator" DROP CONSTRAINT "FK_678dc5427cdde0cd4fef2c07a43"`) + await db.query(`ALTER TABLE "distribution_bucket" DROP CONSTRAINT "FK_8cb7454d1ec34b0d3bb7ecdee4e"`) + await db.query(`ALTER TABLE "distribution_bucket_bag" DROP CONSTRAINT "FK_8a807921f1aae60d4ba94895826"`) + await db.query(`ALTER TABLE "distribution_bucket_bag" DROP CONSTRAINT "FK_a9810100aee7584680f197c8ff0"`) + await db.query(`ALTER TABLE "storage_data_object" DROP CONSTRAINT "FK_ff8014300b8039dbaed764f51bc"`) + await db.query(`ALTER TABLE "banned_member" DROP CONSTRAINT "FK_b94ea874da235d9b6fbc35cf58e"`) + await db.query(`ALTER TABLE "banned_member" DROP CONSTRAINT "FK_ed36c6c26bf5410796c2fc21f74"`) + await db.query(`ALTER TABLE "app" DROP CONSTRAINT "FK_c9cc395bbc485f70a15be64553e"`) + await db.query(`ALTER TABLE "channel" DROP CONSTRAINT "FK_25c85bc448b5e236a4c1a5f7895"`) + await db.query(`ALTER TABLE "channel" DROP CONSTRAINT "FK_a77e12f3d8c6ced020e179a5e94"`) + await db.query(`ALTER TABLE "channel" DROP CONSTRAINT "FK_6997e94413b3f2f25a84e4a96f8"`) + await db.query(`ALTER TABLE "channel" DROP CONSTRAINT "FK_118ecfa0199aeb5a014906933e8"`) + await db.query(`ALTER TABLE "video_featured_in_category" DROP CONSTRAINT "FK_7b16ddad43901921a8d3c8eab71"`) + await db.query(`ALTER TABLE "video_featured_in_category" DROP CONSTRAINT "FK_0e6bb49ce9d022cd872f3ab4288"`) + await db.query(`ALTER TABLE "video_category" DROP CONSTRAINT "FK_da26b34f037c0d59d3c0d0646e9"`) + await db.query(`ALTER TABLE "video_subtitle" DROP CONSTRAINT "FK_2203674f18d8052ed6bac396252"`) + await db.query(`ALTER TABLE "video_subtitle" DROP CONSTRAINT "FK_b6eabfb8de4128b28d73681020f"`) + await db.query(`ALTER TABLE "comment_reaction" DROP CONSTRAINT "FK_15080d9fb7cf8b563103dd9d900"`) + await db.query(`ALTER TABLE "comment_reaction" DROP CONSTRAINT "FK_962582f04d3f639e33f43c54bbc"`) + await db.query(`ALTER TABLE "comment_reaction" DROP CONSTRAINT "FK_d7995b1d57614a6fbd0c103874d"`) + await db.query(`ALTER TABLE "comment" DROP CONSTRAINT "FK_3ce66469b26697baa097f8da923"`) + await db.query(`ALTER TABLE "comment" DROP CONSTRAINT "FK_1ff03403fd31dfeaba0623a89cf"`) + await db.query(`ALTER TABLE "comment" DROP CONSTRAINT "FK_ac69bddf8202b7c0752d9dc8f32"`) + await db.query(`ALTER TABLE "video_reaction" DROP CONSTRAINT "FK_73dda64f53bbc7ec7035d5e7f09"`) + await db.query(`ALTER TABLE "video_reaction" DROP CONSTRAINT "FK_436a3836eb47acb5e1e3c88ddea"`) + await db.query(`ALTER TABLE "video" DROP CONSTRAINT "FK_81b11ef99a9db9ef1aed040d750"`) + await db.query(`ALTER TABLE "video" DROP CONSTRAINT "FK_2a5c61f32e9636ee10821e9a58d"`) + await db.query(`ALTER TABLE "video" DROP CONSTRAINT "FK_8530d052cc79b420f7ce2b4e09d"`) + await db.query(`ALTER TABLE "video" DROP CONSTRAINT "FK_3ec633ae5d0477f512b4ed957d6"`) + await db.query(`ALTER TABLE "video" DROP CONSTRAINT "FK_2db879ed42e3308fe65e6796729"`) + await db.query(`ALTER TABLE "video" DROP CONSTRAINT "FK_54f88a7decf7d22fd9bd9fa439a"`) + await db.query(`ALTER TABLE "video" DROP CONSTRAINT "FK_6c49ad08c44d36d11f77c426e43"`) + await db.query(`ALTER TABLE "bid" DROP CONSTRAINT "FK_9e594e5a61c0f3cb25679f6ba8d"`) + await db.query(`ALTER TABLE "bid" DROP CONSTRAINT "FK_3caf2d6b31d2fe45a2b85b81912"`) + await db.query(`ALTER TABLE "bid" DROP CONSTRAINT "FK_e7618559409a903a897164156b7"`) + await db.query(`ALTER TABLE "bid" DROP CONSTRAINT "FK_32cb73025ec49c87f4c594a265f"`) + await db.query(`ALTER TABLE "owned_nft" DROP CONSTRAINT "FK_466896e39b9ec953f4f2545622d"`) + await db.query(`ALTER TABLE "auction" DROP CONSTRAINT "FK_cfb47e97e60c9d1462576f85a88"`) + await db.query(`ALTER TABLE "auction" DROP CONSTRAINT "FK_a3127ec87cccc5696b92cac4e09"`) + await db.query(`ALTER TABLE "auction" DROP CONSTRAINT "FK_1673ad4b059742fbabfc40b275c"`) + await db.query(`ALTER TABLE "auction_whitelisted_member" DROP CONSTRAINT "FK_aad797677bc7c7c7dc1f1d397f5"`) + await db.query(`ALTER TABLE "auction_whitelisted_member" DROP CONSTRAINT "FK_d5ae4854487c7658b64225be305"`) + await db.query(`ALTER TABLE "account" DROP CONSTRAINT "FK_efef1e5fdbe318a379c06678c51"`) + await db.query(`ALTER TABLE "account" DROP CONSTRAINT "FK_601b93655bcbe73cb58d8c80cd3"`) + await db.query(`ALTER TABLE "encryption_artifacts" DROP CONSTRAINT "FK_ec8f68a544aadc4fbdadefe4a0a"`) + await db.query(`ALTER TABLE "session" DROP CONSTRAINT "FK_30e98e8746699fb9af235410aff"`) + await db.query(`ALTER TABLE "session" DROP CONSTRAINT "FK_fae5a6b4a57f098e9af8520d499"`) + await db.query(`ALTER TABLE "session_encryption_artifacts" DROP CONSTRAINT "FK_3612880efd8926a17eba5ab0e1a"`) + await db.query(`ALTER TABLE "token" DROP CONSTRAINT "FK_a6fe18c105f85a63d761ccb0780"`) + await db.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_ac8de39626657d3c0e909d9d82f"`) + await db.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_122be1f0696e0255acf95f9e336"`) + await db.query(`ALTER TABLE "nft_history_entry" DROP CONSTRAINT "FK_57f51d35ecab042478fe2e31c19"`) + await db.query(`ALTER TABLE "nft_history_entry" DROP CONSTRAINT "FK_d1a28b178f5d028d048d40ce208"`) + await db.query(`ALTER TABLE "nft_activity" DROP CONSTRAINT "FK_18a65713a9fd0715c7a980f5d54"`) + await db.query(`ALTER TABLE "nft_activity" DROP CONSTRAINT "FK_94d325a753f2c08fdd416eb095f"`) + await db.query(`ALTER TABLE "video_hero" DROP CONSTRAINT "FK_9feac5d9713a9f07e32eb8ba7a1"`) + await db.query(`ALTER TABLE "video_media_metadata" DROP CONSTRAINT "FK_5944dc5896cb16bd395414a0ce0"`) + await db.query(`ALTER TABLE "video_media_metadata" DROP CONSTRAINT "FK_4dc101240e8e1536b770aee202a"`) + await db.query(`ALTER TABLE "storage_bucket_operator_metadata" DROP CONSTRAINT "FK_7beffc9530b3f307bc1169cb524"`) + await db.query(`ALTER TABLE "distribution_bucket_family_metadata" DROP CONSTRAINT "FK_dd93ca0ea24f3e7a02f11c4c149"`) + await db.query(`ALTER TABLE "distribution_bucket_operator_metadata" DROP CONSTRAINT "FK_69ec9bdc975b95f7dff94a71069"`) + await db.query(`ALTER TABLE "member_metadata" DROP CONSTRAINT "FK_e7e4d350f82ae2383894f465ede"`) + } +} diff --git a/package-lock.json b/package-lock.json index 3b555cea1..6da78c6a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orion", - "version": "3.0.2", + "version": "3.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "orion", - "version": "3.0.2", + "version": "3.1.0", "hasInstallScript": true, "dependencies": { "@joystream/js": "^1.4.0", diff --git a/package.json b/package.json index 97346d2a0..1eb163535 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orion", - "version": "3.0.4", + "version": "3.1.0", "engines": { "node": ">=16" }, diff --git a/schema/auth.graphql b/schema/auth.graphql index c11f4479d..184c31de0 100644 --- a/schema/auth.graphql +++ b/schema/auth.graphql @@ -2,6 +2,7 @@ enum OperatorPermission { GRANT_OPERATOR_PERMISSIONS REVOKE_OPERATOR_PERMISSIONS SET_VIDEO_WEIGHTS + SET_CHANNEL_WEIGHTS SET_KILL_SWITCH SET_VIDEO_VIEW_PER_USER_TIME_LIMIT SET_VIDEO_HERO diff --git a/schema/channels.graphql b/schema/channels.graphql index 7702cffdb..90ff95bb1 100644 --- a/schema/channels.graphql +++ b/schema/channels.graphql @@ -64,6 +64,9 @@ type Channel @entity { "Cumulative rewards paid to this channel" cumulativeReward: BigInt! + + "Weight/Bias of the channel affecting video relevance in the Homepage" + channelWeight: Float } type BannedMember @entity @index(fields: ["member", "channel"], unique: true) { diff --git a/src/server-extension/resolvers/AdminResolver/index.ts b/src/server-extension/resolvers/AdminResolver/index.ts index 1eabc6997..ba390c7a6 100644 --- a/src/server-extension/resolvers/AdminResolver/index.ts +++ b/src/server-extension/resolvers/AdminResolver/index.ts @@ -10,9 +10,10 @@ import { getResolveTree } from '@subsquid/openreader/lib/util/resolve-tree' import { GraphQLResolveInfo } from 'graphql' import 'reflect-metadata' import { Args, Ctx, Info, Mutation, Query, Resolver, UseMiddleware } from 'type-graphql' -import { EntityManager, In, Not } from 'typeorm' +import { EntityManager, In, Not, UpdateResult } from 'typeorm' import { videoRelevanceManager } from '../../../mappings/utils' import { + Channel, OperatorPermission, User, Video, @@ -27,6 +28,7 @@ import { OperatorOnly } from '../middleware' import { model } from '../model' import { AppActionSignatureInput, + ChannelWeight, ExcludableContentType, ExcludeContentArgs, ExcludeContentResult, @@ -39,6 +41,7 @@ import { RevokeOperatorPermissionsInput, SetCategoryFeaturedVideosArgs, SetCategoryFeaturedVideosResult, + SetChannelsWeightsArgs, SetFeaturedNftsInput, SetFeaturedNftsResult, SetKillSwitchInput, @@ -105,6 +108,7 @@ export class AdminResolver { args.commentsWeight, args.reactionsWeight, [args.joysteamTimestampSubWeight, args.ytTimestampSubWeight], + args.defaultChannelWeight, ], em ) @@ -112,6 +116,39 @@ export class AdminResolver { return { isApplied: true } } + @UseMiddleware(OperatorOnly(OperatorPermission.SET_CHANNEL_WEIGHTS)) + @Mutation(() => [ChannelWeight]) + async setChannelsWeights(@Args() { inputs }: SetChannelsWeightsArgs): Promise { + const em = await this.em() + + const results: ChannelWeight[] = [] + + // Process each SetChannelWeightInput + for (const weightInput of inputs) { + const { channelId, weight } = weightInput + + // Update the channel weight in the database + const updateResult: UpdateResult = await em.transaction( + async (transactionalEntityManager) => { + return transactionalEntityManager + .createQueryBuilder() + .update(Channel) + .set({ channelWeight: weight }) + .where('id = :id', { id: channelId }) + .execute() + } + ) + + // Push the result into the results array + results.push({ + channelId, + isApplied: !!updateResult.affected, + }) + } + + return results + } + @UseMiddleware(OperatorOnly(OperatorPermission.SET_KILL_SWITCH)) @Mutation(() => KillSwitch) async setKillSwitch(@Args() args: SetKillSwitchInput): Promise { diff --git a/src/server-extension/resolvers/AdminResolver/types.ts b/src/server-extension/resolvers/AdminResolver/types.ts index da71320e0..3fc4021c7 100644 --- a/src/server-extension/resolvers/AdminResolver/types.ts +++ b/src/server-extension/resolvers/AdminResolver/types.ts @@ -21,6 +21,9 @@ export class SetVideoWeightsInput { @Field(() => Float, { nullable: false }) ytTimestampSubWeight!: number + + @Field(() => Float, { nullable: false }) + defaultChannelWeight!: number } @ObjectType() @@ -29,6 +32,30 @@ export class VideoWeights { isApplied!: boolean } +@InputType() +export class ChannelWeightInput { + @Field(() => String, { nullable: false }) + channelId!: string + + @Field(() => Float, { nullable: false }) + weight!: number +} + +@ArgsType() +export class SetChannelsWeightsArgs { + @Field(() => [ChannelWeightInput], { nullable: false }) + inputs!: ChannelWeightInput[] +} + +@ObjectType() +export class ChannelWeight { + @Field(() => String, { nullable: false }) + channelId!: string + + @Field(() => Boolean, { nullable: false }) + isApplied!: boolean +} + @ArgsType() export class SetKillSwitchInput { @Field(() => Boolean, { nullable: false }) diff --git a/src/utils/VideoRelevanceManager.ts b/src/utils/VideoRelevanceManager.ts index d7ee0e676..deb09d40c 100644 --- a/src/utils/VideoRelevanceManager.ts +++ b/src/utils/VideoRelevanceManager.ts @@ -31,21 +31,25 @@ export class VideoRelevanceManager { commentsWeight, reactionsWeight, [joystreamTimestampWeight, ytTimestampWeight] = [7, 3], + defaultChannelWeight, ] = await config.get(ConfigVariable.RelevanceWeights, em) await em.query(` WITH weighted_timestamp AS ( SELECT - id, + "video"."id", ( - extract(epoch from created_at)*${joystreamTimestampWeight} + - COALESCE(extract(epoch from published_before_joystream), extract(epoch from created_at))*${ytTimestampWeight} - ) / ${joystreamTimestampWeight + ytTimestampWeight} as wtEpoch + extract(epoch from video.created_at)*${joystreamTimestampWeight} + + COALESCE(extract(epoch from video.published_before_joystream), extract(epoch from video.created_at))*${ytTimestampWeight} + ) / ${joystreamTimestampWeight} + ${ytTimestampWeight} as wtEpoch, + "channel"."channel_weight" as CW FROM "video" + INNER JOIN + "channel" ON "video"."channel_id" = "channel"."id" ${ forceUpdateAll ? '' - : `WHERE "id" IN (${[...this.videosToUpdate.values()] + : `WHERE "video"."id" IN (${[...this.videosToUpdate.values()] .map((id) => `'${id}'`) .join(', ')})` } @@ -54,10 +58,12 @@ export class VideoRelevanceManager { "video" SET "video_relevance" = ROUND( - (extract(epoch from now()) - wtEpoch) / (60 * 60 * 24) * ${newnessWeight * -1} + + ( + (extract(epoch from now()) - wtEpoch) / ${NEWNESS_SECONDS_DIVIDER} * ${newnessWeight * -1} + (views_num * ${viewsWeight}) + (comments_count * ${commentsWeight}) + - (reactions_count * ${reactionsWeight}), + (reactions_count * ${reactionsWeight}) + ) * COALESCE(CW, ${defaultChannelWeight}), 2) FROM weighted_timestamp diff --git a/src/utils/config.ts b/src/utils/config.ts index 9c358cf87..8228a65ed 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -47,7 +47,8 @@ export const configVariables = { [ConfigVariable.KillSwitch]: boolType, [ConfigVariable.VideoViewPerUserTimeLimit]: intType, [ConfigVariable.VideoRelevanceViewsTick]: intType, - [ConfigVariable.RelevanceWeights]: jsonType<[number, number, number, number, [number, number]]>(), + [ConfigVariable.RelevanceWeights]: + jsonType<[number, number, number, number, [number, number], number]>(), [ConfigVariable.AppPrivateKey]: stringType, [ConfigVariable.SessionMaxDurationHours]: intType, [ConfigVariable.SessionExpiryAfterInactivityMinutes]: intType, diff --git a/src/utils/offchainState.ts b/src/utils/offchainState.ts index 064297c71..2a168e180 100644 --- a/src/utils/offchainState.ts +++ b/src/utils/offchainState.ts @@ -1,10 +1,10 @@ -import { EntityManager } from 'typeorm' -import fs from 'fs' -import path from 'path' import { createLogger } from '@subsquid/logger' import assert from 'assert' -import { uniqueId } from './crypto' +import fs from 'fs' +import path from 'path' +import { EntityManager } from 'typeorm' import { NextEntityId } from '../model' +import { uniqueId } from './crypto' const DEFAULT_EXPORT_PATH = path.resolve(__dirname, '../../db/export/export.json') @@ -22,7 +22,7 @@ const exportedStateMap = { User: true, Account: true, Token: true, - Channel: ['is_excluded', 'video_views_num', 'follows_num'], + Channel: ['is_excluded', 'video_views_num', 'follows_num', 'channel_weight'], Video: ['is_excluded', 'views_num'], Comment: ['is_excluded'], OwnedNft: ['is_featured'], @@ -80,6 +80,7 @@ export class OffchainState { '3.0.2': ['Account'], '3.0.3': ['Account'], '3.0.4': ['Account'], + '3.1.0': ['Account'], } private migrations: Migrations = {