From d2bc3c18e0e82cbe1d66b3b03445df76ece684bf Mon Sep 17 00:00:00 2001 From: mircearoata Date: Tue, 8 Oct 2024 12:12:54 +0200 Subject: [PATCH] fix: mod creation with logo (#96) --- db/schema/mod.go | 2 +- generated/ent/internal/schema.go | 2 +- generated/ent/migrate/schema.go | 2 +- generated/ent/mod/where.go | 10 ++++++ generated/ent/mod_create.go | 31 +++++++++++++++-- generated/ent/mod_update.go | 18 ++++++++++ generated/ent/mutation.go | 19 +++++++++++ gql/resolver_mods.go | 33 ++++++++----------- .../20241008092121_nullable_mod_logo.down.sql | 2 ++ .../20241008092121_nullable_mod_logo.up.sql | 2 ++ migrations/sql/atlas.sum | 4 ++- 11 files changed, 98 insertions(+), 27 deletions(-) create mode 100644 migrations/sql/20241008092121_nullable_mod_logo.down.sql create mode 100644 migrations/sql/20241008092121_nullable_mod_logo.up.sql diff --git a/db/schema/mod.go b/db/schema/mod.go index 5d14a14..9e4ef29 100644 --- a/db/schema/mod.go +++ b/db/schema/mod.go @@ -26,7 +26,7 @@ func (Mod) Fields() []ent.Field { field.String("name").MaxLen(32), field.String("short_description").MaxLen(128), field.String("full_description"), - field.String("logo"), + field.String("logo").Optional(), field.String("logo_thumbhash").Optional(), field.String("source_url").Optional(), field.String("creator_id"), diff --git a/generated/ent/internal/schema.go b/generated/ent/internal/schema.go index a10e79a..232ecbe 100644 --- a/generated/ent/internal/schema.go +++ b/generated/ent/internal/schema.go @@ -6,4 +6,4 @@ // Package internal holds a loadable version of the latest schema. package internal -const Schema = "{\"Schema\":\"github.com/satisfactorymodding/smr-api/db/schema\",\"Package\":\"github.com/satisfactorymodding/smr-api/generated/ent\",\"Schemas\":[{\"name\":\"Announcement\",\"config\":{\"Table\":\"\"},\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"message\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"importance\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"Guide\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"user\",\"type\":\"User\",\"field\":\"user_id\",\"ref_name\":\"guides\",\"unique\":true,\"inverse\":true},{\"name\":\"tags\",\"type\":\"Tag\",\"through\":{\"N\":\"guide_tags\",\"T\":\"GuideTag\"}}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"user_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"name\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":32,\"validators\":1,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"short_description\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":128,\"validators\":1,\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"guide\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":3,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"views\",\"type\":{\"Type\":12,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":0,\"default_kind\":2,\"position\":{\"Index\":4,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"GuideTag\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"guide\",\"type\":\"Guide\",\"field\":\"guide_id\",\"unique\":true,\"required\":true},{\"name\":\"tag\",\"type\":\"Tag\",\"field\":\"tag_id\",\"unique\":true,\"required\":true}],\"fields\":[{\"name\":\"guide_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"tag_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}}],\"annotations\":{\"Fields\":{\"ID\":[\"guide_id\",\"tag_id\"],\"StructTag\":null}}},{\"name\":\"Mod\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"versions\",\"type\":\"Version\"},{\"name\":\"authors\",\"type\":\"User\",\"ref_name\":\"mods\",\"through\":{\"N\":\"user_mods\",\"T\":\"UserMod\"},\"inverse\":true},{\"name\":\"tags\",\"type\":\"Tag\",\"through\":{\"N\":\"mod_tags\",\"T\":\"ModTag\"}},{\"name\":\"dependents\",\"type\":\"Version\",\"ref_name\":\"dependencies\",\"through\":{\"N\":\"version_dependencies\",\"T\":\"VersionDependency\"},\"inverse\":true}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"name\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":32,\"validators\":1,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"short_description\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":128,\"validators\":1,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"full_description\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"logo\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":3,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"logo_thumbhash\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":4,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"source_url\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":5,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"creator_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":6,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"approved\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":7,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"views\",\"type\":{\"Type\":17,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":0,\"default_kind\":7,\"position\":{\"Index\":8,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"hotness\",\"type\":{\"Type\":17,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":0,\"default_kind\":7,\"position\":{\"Index\":9,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"popularity\",\"type\":{\"Type\":17,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":0,\"default_kind\":7,\"position\":{\"Index\":10,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"downloads\",\"type\":{\"Type\":17,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":0,\"default_kind\":7,\"position\":{\"Index\":11,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"denied\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":12,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"last_version_date\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":13,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"mod_reference\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":32,\"validators\":1,\"position\":{\"Index\":14,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"hidden\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":15,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"compatibility\",\"type\":{\"Type\":3,\"Ident\":\"*util.CompatibilityInfo\",\"PkgPath\":\"github.com/satisfactorymodding/smr-api/util\",\"PkgName\":\"util\",\"Nillable\":true,\"RType\":{\"Name\":\"CompatibilityInfo\",\"Ident\":\"util.CompatibilityInfo\",\"Kind\":22,\"PkgPath\":\"github.com/satisfactorymodding/smr-api/util\",\"Methods\":{}}},\"optional\":true,\"position\":{\"Index\":16,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"toggle_network_use\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":17,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"toggle_explicit_content\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":18,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]},{\"fields\":[\"last_version_date\"]},{\"unique\":true,\"fields\":[\"mod_reference\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"ModTag\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"mod\",\"type\":\"Mod\",\"field\":\"mod_id\",\"unique\":true,\"required\":true},{\"name\":\"tag\",\"type\":\"Tag\",\"field\":\"tag_id\",\"unique\":true,\"required\":true}],\"fields\":[{\"name\":\"mod_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"tag_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}}],\"annotations\":{\"Fields\":{\"ID\":[\"mod_id\",\"tag_id\"],\"StructTag\":null}}},{\"name\":\"SatisfactoryVersion\",\"config\":{\"Table\":\"\"},\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"version\",\"type\":{\"Type\":12,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"unique\":true,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"engine_version\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":16,\"default\":true,\"default_value\":\"4.26\",\"default_kind\":24,\"validators\":1,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}}]},{\"name\":\"Tag\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"mods\",\"type\":\"Mod\",\"ref_name\":\"tags\",\"through\":{\"N\":\"mod_tags\",\"T\":\"ModTag\"},\"inverse\":true},{\"name\":\"guides\",\"type\":\"Guide\",\"ref_name\":\"tags\",\"through\":{\"N\":\"guide_tags\",\"T\":\"GuideTag\"},\"inverse\":true}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"name\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":24,\"unique\":true,\"validators\":1,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"description\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":512,\"optional\":true,\"validators\":1,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"User\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"guides\",\"type\":\"Guide\"},{\"name\":\"sessions\",\"type\":\"UserSession\",\"storage_key\":{\"Table\":\"\",\"Symbols\":null,\"Columns\":[\"user_id\"]}},{\"name\":\"mods\",\"type\":\"Mod\",\"through\":{\"N\":\"user_mods\",\"T\":\"UserMod\"}},{\"name\":\"groups\",\"type\":\"UserGroup\"}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"email\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":256,\"validators\":1,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"username\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":32,\"validators\":1,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"avatar\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"avatar_thumbhash\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":3,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"joined_from\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":4,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"banned\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":5,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"rank\",\"type\":{\"Type\":12,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":1,\"default_kind\":2,\"position\":{\"Index\":6,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"github_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":16,\"optional\":true,\"validators\":1,\"position\":{\"Index\":7,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"google_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":32,\"optional\":true,\"validators\":1,\"position\":{\"Index\":8,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"facebook_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":128,\"optional\":true,\"validators\":1,\"position\":{\"Index\":9,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]},{\"unique\":true,\"fields\":[\"email\"]},{\"unique\":true,\"fields\":[\"github_id\"]},{\"unique\":true,\"fields\":[\"google_id\"]},{\"unique\":true,\"fields\":[\"facebook_id\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"UserGroup\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"user\",\"type\":\"User\",\"field\":\"user_id\",\"ref_name\":\"groups\",\"unique\":true,\"inverse\":true,\"required\":true}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"user_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":14,\"validators\":1,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"group_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":14,\"validators\":1,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]},{\"unique\":true,\"fields\":[\"user_id\",\"group_id\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"UserMod\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"user\",\"type\":\"User\",\"field\":\"user_id\",\"unique\":true,\"required\":true},{\"name\":\"mod\",\"type\":\"Mod\",\"field\":\"mod_id\",\"unique\":true,\"required\":true}],\"fields\":[{\"name\":\"user_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"mod_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"role\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}}],\"annotations\":{\"Fields\":{\"ID\":[\"user_id\",\"mod_id\"],\"StructTag\":null}}},{\"name\":\"UserSession\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"user\",\"type\":\"User\",\"ref_name\":\"sessions\",\"unique\":true,\"inverse\":true,\"required\":true}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"token\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":512,\"validators\":1,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"user_agent\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]},{\"unique\":true,\"fields\":[\"token\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"Version\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"mod\",\"type\":\"Mod\",\"field\":\"mod_id\",\"ref_name\":\"versions\",\"unique\":true,\"inverse\":true,\"required\":true},{\"name\":\"dependencies\",\"type\":\"Mod\",\"through\":{\"N\":\"version_dependencies\",\"T\":\"VersionDependency\"}},{\"name\":\"targets\",\"type\":\"VersionTarget\"},{\"name\":\"virustotal_results\",\"type\":\"VirustotalResult\"}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"mod_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"version\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":16,\"validators\":1,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"game_version\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"required_on_remote\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":true,\"default_kind\":1,\"position\":{\"Index\":3,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"changelog\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":4,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"downloads\",\"type\":{\"Type\":17,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":0,\"default_kind\":7,\"position\":{\"Index\":5,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"key\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":6,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"stability\",\"type\":{\"Type\":6,\"Ident\":\"util.Stability\",\"PkgPath\":\"github.com/satisfactorymodding/smr-api/util\",\"PkgName\":\"util\",\"Nillable\":false,\"RType\":{\"Name\":\"Stability\",\"Ident\":\"util.Stability\",\"Kind\":24,\"PkgPath\":\"github.com/satisfactorymodding/smr-api/util\",\"Methods\":{\"Values\":{\"In\":[],\"Out\":[{\"Name\":\"\",\"Ident\":\"[]string\",\"Kind\":23,\"PkgPath\":\"\",\"Methods\":null}]}}}},\"enums\":[{\"N\":\"release\",\"V\":\"release\"},{\"N\":\"beta\",\"V\":\"beta\"},{\"N\":\"alpha\",\"V\":\"alpha\"}],\"default\":true,\"default_value\":\"release\",\"default_kind\":24,\"position\":{\"Index\":7,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"approved\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":8,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"hotness\",\"type\":{\"Type\":17,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":0,\"default_kind\":7,\"position\":{\"Index\":9,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"denied\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":10,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"metadata\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":11,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"mod_reference\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":32,\"validators\":1,\"position\":{\"Index\":12,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"version_major\",\"type\":{\"Type\":12,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":13,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"version_minor\",\"type\":{\"Type\":12,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":14,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"version_patch\",\"type\":{\"Type\":12,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":15,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"size\",\"type\":{\"Type\":13,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":16,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"hash\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":64,\"optional\":true,\"validators\":2,\"position\":{\"Index\":17,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]},{\"fields\":[\"approved\"]},{\"fields\":[\"denied\"]},{\"fields\":[\"mod_id\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"VersionDependency\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"version\",\"type\":\"Version\",\"field\":\"version_id\",\"unique\":true,\"required\":true},{\"name\":\"mod\",\"type\":\"Mod\",\"field\":\"mod_id\",\"unique\":true,\"required\":true}],\"fields\":[{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"version_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"mod_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"condition\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":64,\"validators\":1,\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"optional\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":3,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}],\"annotations\":{\"Fields\":{\"ID\":[\"version_id\",\"mod_id\"],\"StructTag\":null}}},{\"name\":\"VersionTarget\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"version\",\"type\":\"Version\",\"field\":\"version_id\",\"ref_name\":\"targets\",\"unique\":true,\"inverse\":true,\"required\":true}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"version_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"target_name\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"key\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"hash\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":3,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"size\",\"type\":{\"Type\":13,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":4,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"unique\":true,\"fields\":[\"version_id\",\"target_name\"]}]},{\"name\":\"VirustotalResult\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"version\",\"type\":\"Version\",\"field\":\"version_id\",\"ref_name\":\"virustotal_results\",\"unique\":true,\"inverse\":true,\"required\":true}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"safe\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"hash\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":64,\"validators\":2,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"file_name\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"validators\":1,\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"version_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":14,\"validators\":2,\"position\":{\"Index\":3,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"safe\"]},{\"unique\":true,\"fields\":[\"hash\",\"version_id\"]},{\"fields\":[\"file_name\"]}]}],\"Features\":[\"sql/modifier\",\"intercept\",\"schema/snapshot\",\"sql/execquery\",\"sql/upsert\"]}" +const Schema = "{\"Schema\":\"github.com/satisfactorymodding/smr-api/db/schema\",\"Package\":\"github.com/satisfactorymodding/smr-api/generated/ent\",\"Schemas\":[{\"name\":\"Announcement\",\"config\":{\"Table\":\"\"},\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"message\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"importance\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"Guide\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"user\",\"type\":\"User\",\"field\":\"user_id\",\"ref_name\":\"guides\",\"unique\":true,\"inverse\":true},{\"name\":\"tags\",\"type\":\"Tag\",\"through\":{\"N\":\"guide_tags\",\"T\":\"GuideTag\"}}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"user_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"name\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":32,\"validators\":1,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"short_description\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":128,\"validators\":1,\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"guide\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":3,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"views\",\"type\":{\"Type\":12,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":0,\"default_kind\":2,\"position\":{\"Index\":4,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"GuideTag\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"guide\",\"type\":\"Guide\",\"field\":\"guide_id\",\"unique\":true,\"required\":true},{\"name\":\"tag\",\"type\":\"Tag\",\"field\":\"tag_id\",\"unique\":true,\"required\":true}],\"fields\":[{\"name\":\"guide_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"tag_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}}],\"annotations\":{\"Fields\":{\"ID\":[\"guide_id\",\"tag_id\"],\"StructTag\":null}}},{\"name\":\"Mod\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"versions\",\"type\":\"Version\"},{\"name\":\"authors\",\"type\":\"User\",\"ref_name\":\"mods\",\"through\":{\"N\":\"user_mods\",\"T\":\"UserMod\"},\"inverse\":true},{\"name\":\"tags\",\"type\":\"Tag\",\"through\":{\"N\":\"mod_tags\",\"T\":\"ModTag\"}},{\"name\":\"dependents\",\"type\":\"Version\",\"ref_name\":\"dependencies\",\"through\":{\"N\":\"version_dependencies\",\"T\":\"VersionDependency\"},\"inverse\":true}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"name\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":32,\"validators\":1,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"short_description\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":128,\"validators\":1,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"full_description\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"logo\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":3,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"logo_thumbhash\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":4,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"source_url\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":5,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"creator_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":6,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"approved\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":7,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"views\",\"type\":{\"Type\":17,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":0,\"default_kind\":7,\"position\":{\"Index\":8,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"hotness\",\"type\":{\"Type\":17,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":0,\"default_kind\":7,\"position\":{\"Index\":9,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"popularity\",\"type\":{\"Type\":17,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":0,\"default_kind\":7,\"position\":{\"Index\":10,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"downloads\",\"type\":{\"Type\":17,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":0,\"default_kind\":7,\"position\":{\"Index\":11,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"denied\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":12,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"last_version_date\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":13,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"mod_reference\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":32,\"validators\":1,\"position\":{\"Index\":14,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"hidden\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":15,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"compatibility\",\"type\":{\"Type\":3,\"Ident\":\"*util.CompatibilityInfo\",\"PkgPath\":\"github.com/satisfactorymodding/smr-api/util\",\"PkgName\":\"util\",\"Nillable\":true,\"RType\":{\"Name\":\"CompatibilityInfo\",\"Ident\":\"util.CompatibilityInfo\",\"Kind\":22,\"PkgPath\":\"github.com/satisfactorymodding/smr-api/util\",\"Methods\":{}}},\"optional\":true,\"position\":{\"Index\":16,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"toggle_network_use\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":17,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"toggle_explicit_content\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":18,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]},{\"fields\":[\"last_version_date\"]},{\"unique\":true,\"fields\":[\"mod_reference\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"ModTag\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"mod\",\"type\":\"Mod\",\"field\":\"mod_id\",\"unique\":true,\"required\":true},{\"name\":\"tag\",\"type\":\"Tag\",\"field\":\"tag_id\",\"unique\":true,\"required\":true}],\"fields\":[{\"name\":\"mod_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"tag_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}}],\"annotations\":{\"Fields\":{\"ID\":[\"mod_id\",\"tag_id\"],\"StructTag\":null}}},{\"name\":\"SatisfactoryVersion\",\"config\":{\"Table\":\"\"},\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"version\",\"type\":{\"Type\":12,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"unique\":true,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"engine_version\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":16,\"default\":true,\"default_value\":\"4.26\",\"default_kind\":24,\"validators\":1,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}}]},{\"name\":\"Tag\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"mods\",\"type\":\"Mod\",\"ref_name\":\"tags\",\"through\":{\"N\":\"mod_tags\",\"T\":\"ModTag\"},\"inverse\":true},{\"name\":\"guides\",\"type\":\"Guide\",\"ref_name\":\"tags\",\"through\":{\"N\":\"guide_tags\",\"T\":\"GuideTag\"},\"inverse\":true}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"name\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":24,\"unique\":true,\"validators\":1,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"description\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":512,\"optional\":true,\"validators\":1,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"User\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"guides\",\"type\":\"Guide\"},{\"name\":\"sessions\",\"type\":\"UserSession\",\"storage_key\":{\"Table\":\"\",\"Symbols\":null,\"Columns\":[\"user_id\"]}},{\"name\":\"mods\",\"type\":\"Mod\",\"through\":{\"N\":\"user_mods\",\"T\":\"UserMod\"}},{\"name\":\"groups\",\"type\":\"UserGroup\"}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"email\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":256,\"validators\":1,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"username\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":32,\"validators\":1,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"avatar\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"avatar_thumbhash\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":3,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"joined_from\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":4,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"banned\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":5,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"rank\",\"type\":{\"Type\":12,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":1,\"default_kind\":2,\"position\":{\"Index\":6,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"github_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":16,\"optional\":true,\"validators\":1,\"position\":{\"Index\":7,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"google_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":32,\"optional\":true,\"validators\":1,\"position\":{\"Index\":8,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"facebook_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":128,\"optional\":true,\"validators\":1,\"position\":{\"Index\":9,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]},{\"unique\":true,\"fields\":[\"email\"]},{\"unique\":true,\"fields\":[\"github_id\"]},{\"unique\":true,\"fields\":[\"google_id\"]},{\"unique\":true,\"fields\":[\"facebook_id\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"UserGroup\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"user\",\"type\":\"User\",\"field\":\"user_id\",\"ref_name\":\"groups\",\"unique\":true,\"inverse\":true,\"required\":true}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"user_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":14,\"validators\":1,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"group_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":14,\"validators\":1,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]},{\"unique\":true,\"fields\":[\"user_id\",\"group_id\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"UserMod\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"user\",\"type\":\"User\",\"field\":\"user_id\",\"unique\":true,\"required\":true},{\"name\":\"mod\",\"type\":\"Mod\",\"field\":\"mod_id\",\"unique\":true,\"required\":true}],\"fields\":[{\"name\":\"user_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"mod_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"role\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}}],\"annotations\":{\"Fields\":{\"ID\":[\"user_id\",\"mod_id\"],\"StructTag\":null}}},{\"name\":\"UserSession\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"user\",\"type\":\"User\",\"ref_name\":\"sessions\",\"unique\":true,\"inverse\":true,\"required\":true}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"token\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":512,\"validators\":1,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"user_agent\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]},{\"unique\":true,\"fields\":[\"token\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"Version\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"mod\",\"type\":\"Mod\",\"field\":\"mod_id\",\"ref_name\":\"versions\",\"unique\":true,\"inverse\":true,\"required\":true},{\"name\":\"dependencies\",\"type\":\"Mod\",\"through\":{\"N\":\"version_dependencies\",\"T\":\"VersionDependency\"}},{\"name\":\"targets\",\"type\":\"VersionTarget\"},{\"name\":\"virustotal_results\",\"type\":\"VirustotalResult\"}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}},{\"name\":\"mod_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"version\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":16,\"validators\":1,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"game_version\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"required_on_remote\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":true,\"default_kind\":1,\"position\":{\"Index\":3,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"changelog\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":4,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"downloads\",\"type\":{\"Type\":17,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":0,\"default_kind\":7,\"position\":{\"Index\":5,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"key\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":6,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"stability\",\"type\":{\"Type\":6,\"Ident\":\"util.Stability\",\"PkgPath\":\"github.com/satisfactorymodding/smr-api/util\",\"PkgName\":\"util\",\"Nillable\":false,\"RType\":{\"Name\":\"Stability\",\"Ident\":\"util.Stability\",\"Kind\":24,\"PkgPath\":\"github.com/satisfactorymodding/smr-api/util\",\"Methods\":{\"Values\":{\"In\":[],\"Out\":[{\"Name\":\"\",\"Ident\":\"[]string\",\"Kind\":23,\"PkgPath\":\"\",\"Methods\":null}]}}}},\"enums\":[{\"N\":\"release\",\"V\":\"release\"},{\"N\":\"beta\",\"V\":\"beta\"},{\"N\":\"alpha\",\"V\":\"alpha\"}],\"default\":true,\"default_value\":\"release\",\"default_kind\":24,\"position\":{\"Index\":7,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"approved\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":8,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"hotness\",\"type\":{\"Type\":17,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":0,\"default_kind\":7,\"position\":{\"Index\":9,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"denied\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":10,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"metadata\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":11,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"mod_reference\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":32,\"validators\":1,\"position\":{\"Index\":12,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"version_major\",\"type\":{\"Type\":12,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":13,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"version_minor\",\"type\":{\"Type\":12,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":14,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"version_patch\",\"type\":{\"Type\":12,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":15,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"size\",\"type\":{\"Type\":13,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":16,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"hash\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":64,\"optional\":true,\"validators\":2,\"position\":{\"Index\":17,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]},{\"fields\":[\"approved\"]},{\"fields\":[\"denied\"]},{\"fields\":[\"mod_id\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":2}]},{\"name\":\"VersionDependency\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"version\",\"type\":\"Version\",\"field\":\"version_id\",\"unique\":true,\"required\":true},{\"name\":\"mod\",\"type\":\"Mod\",\"field\":\"mod_id\",\"unique\":true,\"required\":true}],\"fields\":[{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"deleted_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"version_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"mod_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"condition\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":64,\"validators\":1,\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"optional\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":3,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"deleted_at\"]}],\"hooks\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}],\"interceptors\":[{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}],\"annotations\":{\"Fields\":{\"ID\":[\"version_id\",\"mod_id\"],\"StructTag\":null}}},{\"name\":\"VersionTarget\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"version\",\"type\":\"Version\",\"field\":\"version_id\",\"ref_name\":\"targets\",\"unique\":true,\"inverse\":true,\"required\":true}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"version_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"target_name\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"key\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"hash\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":3,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"size\",\"type\":{\"Type\":13,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"optional\":true,\"position\":{\"Index\":4,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"unique\":true,\"fields\":[\"version_id\",\"target_name\"]}]},{\"name\":\"VirustotalResult\",\"config\":{\"Table\":\"\"},\"edges\":[{\"name\":\"version\",\"type\":\"Version\",\"field\":\"version_id\",\"ref_name\":\"virustotal_results\",\"unique\":true,\"inverse\":true,\"required\":true}],\"fields\":[{\"name\":\"id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":0}},{\"name\":\"created_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"immutable\":true,\"position\":{\"Index\":0,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"updated_at\",\"type\":{\"Type\":2,\"Ident\":\"\",\"PkgPath\":\"time\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_kind\":19,\"update_default\":true,\"position\":{\"Index\":1,\"MixedIn\":true,\"MixinIndex\":1}},{\"name\":\"safe\",\"type\":{\"Type\":1,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"default\":true,\"default_value\":false,\"default_kind\":1,\"position\":{\"Index\":0,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"hash\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":64,\"validators\":2,\"position\":{\"Index\":1,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"file_name\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"validators\":1,\"position\":{\"Index\":2,\"MixedIn\":false,\"MixinIndex\":0}},{\"name\":\"version_id\",\"type\":{\"Type\":7,\"Ident\":\"\",\"PkgPath\":\"\",\"PkgName\":\"\",\"Nillable\":false,\"RType\":null},\"size\":14,\"validators\":2,\"position\":{\"Index\":3,\"MixedIn\":false,\"MixinIndex\":0}}],\"indexes\":[{\"fields\":[\"safe\"]},{\"unique\":true,\"fields\":[\"hash\",\"version_id\"]},{\"fields\":[\"file_name\"]}]}],\"Features\":[\"sql/modifier\",\"intercept\",\"schema/snapshot\",\"sql/execquery\",\"sql/upsert\"]}" diff --git a/generated/ent/migrate/schema.go b/generated/ent/migrate/schema.go index 3bcbe14..f84c046 100644 --- a/generated/ent/migrate/schema.go +++ b/generated/ent/migrate/schema.go @@ -97,7 +97,7 @@ var ( {Name: "name", Type: field.TypeString, Size: 32}, {Name: "short_description", Type: field.TypeString, Size: 128}, {Name: "full_description", Type: field.TypeString}, - {Name: "logo", Type: field.TypeString}, + {Name: "logo", Type: field.TypeString, Nullable: true}, {Name: "logo_thumbhash", Type: field.TypeString, Nullable: true}, {Name: "source_url", Type: field.TypeString, Nullable: true}, {Name: "creator_id", Type: field.TypeString}, diff --git a/generated/ent/mod/where.go b/generated/ent/mod/where.go index 9e58d4a..e5bd0df 100644 --- a/generated/ent/mod/where.go +++ b/generated/ent/mod/where.go @@ -550,6 +550,16 @@ func LogoHasSuffix(v string) predicate.Mod { return predicate.Mod(sql.FieldHasSuffix(FieldLogo, v)) } +// LogoIsNil applies the IsNil predicate on the "logo" field. +func LogoIsNil() predicate.Mod { + return predicate.Mod(sql.FieldIsNull(FieldLogo)) +} + +// LogoNotNil applies the NotNil predicate on the "logo" field. +func LogoNotNil() predicate.Mod { + return predicate.Mod(sql.FieldNotNull(FieldLogo)) +} + // LogoEqualFold applies the EqualFold predicate on the "logo" field. func LogoEqualFold(v string) predicate.Mod { return predicate.Mod(sql.FieldEqualFold(FieldLogo, v)) diff --git a/generated/ent/mod_create.go b/generated/ent/mod_create.go index bda3638..1ad9c12 100644 --- a/generated/ent/mod_create.go +++ b/generated/ent/mod_create.go @@ -93,6 +93,14 @@ func (mc *ModCreate) SetLogo(s string) *ModCreate { return mc } +// SetNillableLogo sets the "logo" field if the given value is not nil. +func (mc *ModCreate) SetNillableLogo(s *string) *ModCreate { + if s != nil { + mc.SetLogo(*s) + } + return mc +} + // SetLogoThumbhash sets the "logo_thumbhash" field. func (mc *ModCreate) SetLogoThumbhash(s string) *ModCreate { mc.mutation.SetLogoThumbhash(s) @@ -477,9 +485,6 @@ func (mc *ModCreate) check() error { if _, ok := mc.mutation.FullDescription(); !ok { return &ValidationError{Name: "full_description", err: errors.New(`ent: missing required field "Mod.full_description"`)} } - if _, ok := mc.mutation.Logo(); !ok { - return &ValidationError{Name: "logo", err: errors.New(`ent: missing required field "Mod.logo"`)} - } if _, ok := mc.mutation.CreatorID(); !ok { return &ValidationError{Name: "creator_id", err: errors.New(`ent: missing required field "Mod.creator_id"`)} } @@ -840,6 +845,12 @@ func (u *ModUpsert) UpdateLogo() *ModUpsert { return u } +// ClearLogo clears the value of the "logo" field. +func (u *ModUpsert) ClearLogo() *ModUpsert { + u.SetNull(mod.FieldLogo) + return u +} + // SetLogoThumbhash sets the "logo_thumbhash" field. func (u *ModUpsert) SetLogoThumbhash(v string) *ModUpsert { u.Set(mod.FieldLogoThumbhash, v) @@ -1210,6 +1221,13 @@ func (u *ModUpsertOne) UpdateLogo() *ModUpsertOne { }) } +// ClearLogo clears the value of the "logo" field. +func (u *ModUpsertOne) ClearLogo() *ModUpsertOne { + return u.Update(func(s *ModUpsert) { + s.ClearLogo() + }) +} + // SetLogoThumbhash sets the "logo_thumbhash" field. func (u *ModUpsertOne) SetLogoThumbhash(v string) *ModUpsertOne { return u.Update(func(s *ModUpsert) { @@ -1785,6 +1803,13 @@ func (u *ModUpsertBulk) UpdateLogo() *ModUpsertBulk { }) } +// ClearLogo clears the value of the "logo" field. +func (u *ModUpsertBulk) ClearLogo() *ModUpsertBulk { + return u.Update(func(s *ModUpsert) { + s.ClearLogo() + }) +} + // SetLogoThumbhash sets the "logo_thumbhash" field. func (u *ModUpsertBulk) SetLogoThumbhash(v string) *ModUpsertBulk { return u.Update(func(s *ModUpsert) { diff --git a/generated/ent/mod_update.go b/generated/ent/mod_update.go index b346a84..a69d414 100644 --- a/generated/ent/mod_update.go +++ b/generated/ent/mod_update.go @@ -115,6 +115,12 @@ func (mu *ModUpdate) SetNillableLogo(s *string) *ModUpdate { return mu } +// ClearLogo clears the value of the "logo" field. +func (mu *ModUpdate) ClearLogo() *ModUpdate { + mu.mutation.ClearLogo() + return mu +} + // SetLogoThumbhash sets the "logo_thumbhash" field. func (mu *ModUpdate) SetLogoThumbhash(s string) *ModUpdate { mu.mutation.SetLogoThumbhash(s) @@ -619,6 +625,9 @@ func (mu *ModUpdate) sqlSave(ctx context.Context) (n int, err error) { if value, ok := mu.mutation.Logo(); ok { _spec.SetField(mod.FieldLogo, field.TypeString, value) } + if mu.mutation.LogoCleared() { + _spec.ClearField(mod.FieldLogo, field.TypeString) + } if value, ok := mu.mutation.LogoThumbhash(); ok { _spec.SetField(mod.FieldLogoThumbhash, field.TypeString, value) } @@ -984,6 +993,12 @@ func (muo *ModUpdateOne) SetNillableLogo(s *string) *ModUpdateOne { return muo } +// ClearLogo clears the value of the "logo" field. +func (muo *ModUpdateOne) ClearLogo() *ModUpdateOne { + muo.mutation.ClearLogo() + return muo +} + // SetLogoThumbhash sets the "logo_thumbhash" field. func (muo *ModUpdateOne) SetLogoThumbhash(s string) *ModUpdateOne { muo.mutation.SetLogoThumbhash(s) @@ -1518,6 +1533,9 @@ func (muo *ModUpdateOne) sqlSave(ctx context.Context) (_node *Mod, err error) { if value, ok := muo.mutation.Logo(); ok { _spec.SetField(mod.FieldLogo, field.TypeString, value) } + if muo.mutation.LogoCleared() { + _spec.ClearField(mod.FieldLogo, field.TypeString) + } if value, ok := muo.mutation.LogoThumbhash(); ok { _spec.SetField(mod.FieldLogoThumbhash, field.TypeString, value) } diff --git a/generated/ent/mutation.go b/generated/ent/mutation.go index e59e0e6..b74b67d 100644 --- a/generated/ent/mutation.go +++ b/generated/ent/mutation.go @@ -2345,9 +2345,22 @@ func (m *ModMutation) OldLogo(ctx context.Context) (v string, err error) { return oldValue.Logo, nil } +// ClearLogo clears the value of the "logo" field. +func (m *ModMutation) ClearLogo() { + m.logo = nil + m.clearedFields[mod.FieldLogo] = struct{}{} +} + +// LogoCleared returns if the "logo" field was cleared in this mutation. +func (m *ModMutation) LogoCleared() bool { + _, ok := m.clearedFields[mod.FieldLogo] + return ok +} + // ResetLogo resets all changes to the "logo" field. func (m *ModMutation) ResetLogo() { m.logo = nil + delete(m.clearedFields, mod.FieldLogo) } // SetLogoThumbhash sets the "logo_thumbhash" field. @@ -3691,6 +3704,9 @@ func (m *ModMutation) ClearedFields() []string { if m.FieldCleared(mod.FieldDeletedAt) { fields = append(fields, mod.FieldDeletedAt) } + if m.FieldCleared(mod.FieldLogo) { + fields = append(fields, mod.FieldLogo) + } if m.FieldCleared(mod.FieldLogoThumbhash) { fields = append(fields, mod.FieldLogoThumbhash) } @@ -3720,6 +3736,9 @@ func (m *ModMutation) ClearField(name string) error { case mod.FieldDeletedAt: m.ClearDeletedAt() return nil + case mod.FieldLogo: + m.ClearLogo() + return nil case mod.FieldLogoThumbhash: m.ClearLogoThumbhash() return nil diff --git a/gql/resolver_mods.go b/gql/resolver_mods.go index 4be30e7..c3fb480 100644 --- a/gql/resolver_mods.go +++ b/gql/resolver_mods.go @@ -80,23 +80,6 @@ func (r *mutationResolver) CreateMod(ctx context.Context, newMod generated.NewMo dbMod.SetCreatorID(user.ID) - var logoData []byte - var thumbHash string - - if newMod.Logo != nil { - file, err := io.ReadAll(newMod.Logo.File) - if err != nil { - return nil, fmt.Errorf("failed to read logo file: %w", err) - } - - logoData, thumbHash, err = converter.ConvertAnyImageToWebp(ctx, file) - if err != nil { - return nil, fmt.Errorf("failed to convert logo file: %w", err) - } - } else { - dbMod.SetLogo("") - } - // Allow only new 4 mods per 24h existingMods, err := db.From(ctx).Mod.Query(). Order(mod.ByCreatedAt(sql.OrderAsc())). @@ -136,12 +119,22 @@ func (r *mutationResolver) CreateMod(ctx context.Context, newMod generated.NewMo return nil, err } - if logoData != nil { + if newMod.Logo != nil { + file, err := io.ReadAll(newMod.Logo.File) + if err != nil { + return nil, fmt.Errorf("failed to read logo file: %w", err) + } + + logoData, thumbHash, err := converter.ConvertAnyImageToWebp(ctx, file) + if err != nil { + return nil, fmt.Errorf("failed to convert logo file: %w", err) + } + logoKey, err := storage.UploadModLogo(ctx, resultMod.ID, bytes.NewReader(logoData)) if err == nil { resultMod, err = resultMod.Update(). SetLogo(storage.GenerateDownloadLink(ctx, logoKey)). - SetNillableLogoThumbhash(util.ContainsOrNil(thumbHash)). + SetLogoThumbhash(thumbHash). Save(ctx) if err != nil { return nil, err @@ -208,7 +201,7 @@ func (r *mutationResolver) UpdateMod(ctx context.Context, modID string, updateMo dbUpdate.SetLogo(storage.GenerateDownloadLink(ctx, logoKey)) dbUpdate.SetLogoThumbhash(thumbHash) } else { - dbUpdate.SetLogo("") + dbUpdate.ClearLogo() dbUpdate.ClearLogoThumbhash() } } diff --git a/migrations/sql/20241008092121_nullable_mod_logo.down.sql b/migrations/sql/20241008092121_nullable_mod_logo.down.sql new file mode 100644 index 0000000..608748e --- /dev/null +++ b/migrations/sql/20241008092121_nullable_mod_logo.down.sql @@ -0,0 +1,2 @@ +-- reverse: modify "mods" table +ALTER TABLE "mods" ALTER COLUMN "logo" SET NOT NULL; diff --git a/migrations/sql/20241008092121_nullable_mod_logo.up.sql b/migrations/sql/20241008092121_nullable_mod_logo.up.sql new file mode 100644 index 0000000..3d4a731 --- /dev/null +++ b/migrations/sql/20241008092121_nullable_mod_logo.up.sql @@ -0,0 +1,2 @@ +-- modify "mods" table +ALTER TABLE "mods" ALTER COLUMN "logo" DROP NOT NULL; diff --git a/migrations/sql/atlas.sum b/migrations/sql/atlas.sum index 5b7094b..e9b312c 100644 --- a/migrations/sql/atlas.sum +++ b/migrations/sql/atlas.sum @@ -1,4 +1,4 @@ -h1:EOAzeUdvTGahAD3VGUxcEW7xEMJthrP36wbaIBYE6Fs= +h1:NVXwUmNMPEOBFBSqgQGuw/OMarJOpSsxkE/8o1qQH3k= 000001_create_initial_tables.down.sql h1:QcXXwE8ir3PM3vZjQfBihY55WiuLYjN8pbbk/L6U+bs= 000001_create_initial_tables.up.sql h1:EfAqETefs7TW9BDVS4ukiB7wUFs+HQzVdc3qHhdAFd4= 000002_create_user_group_table.down.sql h1:uJjRbQ3H7yvPGNXLD5iSPmderEoWhCNGdsqN8yqBIRY= @@ -77,3 +77,5 @@ h1:EOAzeUdvTGahAD3VGUxcEW7xEMJthrP36wbaIBYE6Fs= 20241002191358_state_fix.up.sql h1:4bVw9fxEP9MrHBSYuRF3vFCgaWF79EUeacD3e+vSQR4= 20241003161005_create_virustotal_results_table.down.sql h1:BPUQ6UnWq6Inwz2GhZLoy4/QghPhClf1PlfZHis92P4= 20241003161005_create_virustotal_results_table.up.sql h1:mXMWj998hZ59bbkZYIbbyxU9foptzWuXHnlS2UuY4bY= +20241008092121_nullable_mod_logo.down.sql h1:vKZrz/FqaaQctvzrTR0EvQcyQ6ENWgTbcud7q2/NvnY= +20241008092121_nullable_mod_logo.up.sql h1:7ePponYitScS4NnMP+hRoEAKnvPPpbCHXMxilYzfmD8=