diff --git a/src/main/frontend/src/components/ProjectList.vue b/src/main/frontend/src/components/ProjectList.vue
index 8189a0894..76ea2cf0a 100644
--- a/src/main/frontend/src/components/ProjectList.vue
+++ b/src/main/frontend/src/components/ProjectList.vue
@@ -143,6 +143,13 @@
                 return Visibility.fromName(name);
             },
             tagsFromPromoted(promotedVersions) {
+                // TODO fix project return type stuff
+                if (true) {
+                  return [{
+                    name: "test", versions: [1.0], color: { background: "#F7Cf0D", foreground: "#333333" }
+                  }];
+                }
+
                 let tagsArray = [];
                 promotedVersions
                     .map(version => version.tags)
diff --git a/src/main/java/io/papermc/hangar/config/JDBIConfig.java b/src/main/java/io/papermc/hangar/config/JDBIConfig.java
index 5e2cd2be4..74dbe74df 100644
--- a/src/main/java/io/papermc/hangar/config/JDBIConfig.java
+++ b/src/main/java/io/papermc/hangar/config/JDBIConfig.java
@@ -5,8 +5,8 @@ import io.papermc.hangar.db.customtypes.JobState;
 import io.papermc.hangar.db.customtypes.LoggedAction;
 import io.papermc.hangar.db.customtypes.RoleCategory;
 import io.papermc.hangar.db.dao.HangarDao;
-import io.papermc.hangar.db.mappers.RoleMapper;
 import org.jdbi.v3.core.Jdbi;
+import org.jdbi.v3.core.mapper.RowMapper;
 import org.jdbi.v3.core.spi.JdbiPlugin;
 import org.jdbi.v3.core.statement.SqlLogger;
 import org.jdbi.v3.core.statement.StatementContext;
@@ -39,7 +39,7 @@ public class JDBIConfig {
     }
 
     @Bean
-    public Jdbi jdbi(DataSource dataSource, List<JdbiPlugin> jdbiPlugins) {
+    public Jdbi jdbi(DataSource dataSource, List<JdbiPlugin> jdbiPlugins, List<RowMapper> rowMappers) {
         SqlLogger myLogger = new SqlLogger() {
             @Override
             public void logAfterExecution(StatementContext context) {
@@ -49,13 +49,16 @@ public class JDBIConfig {
         TransactionAwareDataSourceProxy dataSourceProxy = new TransactionAwareDataSourceProxy(dataSource);
         Jdbi jdbi = Jdbi.create(dataSourceProxy);
 //        jdbi.setSqlLogger(myLogger); // TODO for debugging sql statements
-        jdbiPlugins.forEach(jdbi::installPlugin);
         PostgresTypes config = jdbi.getConfig(PostgresTypes.class);
-        jdbi.registerRowMapper(new RoleMapper());
+
+        jdbiPlugins.forEach(jdbi::installPlugin);
+        rowMappers.forEach(jdbi::registerRowMapper);
+
         config.registerCustomType(LoggedAction.class, "logged_action_type");
         config.registerCustomType(RoleCategory.class, "role_category");
         config.registerCustomType(JobState.class, "job_state");
         config.registerCustomType(JSONB.class, "jsonb");
+
         return jdbi;
     }
 
diff --git a/src/main/java/io/papermc/hangar/db/customtypes/JSONB.java b/src/main/java/io/papermc/hangar/db/customtypes/JSONB.java
index 5aa8e0d3a..1f1d0e075 100644
--- a/src/main/java/io/papermc/hangar/db/customtypes/JSONB.java
+++ b/src/main/java/io/papermc/hangar/db/customtypes/JSONB.java
@@ -1,14 +1,17 @@
 package io.papermc.hangar.db.customtypes;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ContainerNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.postgresql.util.PGobject;
 
 public class JSONB extends PGobject {
 
-    private transient ObjectNode json;
+    private transient JsonNode json;
 
     public JSONB(String value) {
         setType("jsonb");
@@ -16,7 +19,8 @@ public class JSONB extends PGobject {
         parseJson();
     }
 
-    public JSONB(ObjectNode json) {
+    @JsonCreator
+    public JSONB(JsonNode json) {
         setType("jsonb");
         this.value = json.toString();
         this.json = json;
@@ -26,6 +30,7 @@ public class JSONB extends PGobject {
         setType("jsonb");
     }
 
+    @JsonValue
     public JsonNode getJson() {
         return json;
     }
@@ -38,7 +43,7 @@ public class JSONB extends PGobject {
 
     private void parseJson() {
         try {
-            this.json = (ObjectNode) new ObjectMapper().readTree(value);
+            this.json = new ObjectMapper().readTree(value);
         } catch (JsonProcessingException | ClassCastException e) {
             e.printStackTrace();
         }
diff --git a/src/main/java/io/papermc/hangar/db/dao/api/ProjectApiDao.java b/src/main/java/io/papermc/hangar/db/dao/api/ProjectApiDao.java
index 955e1e5e9..83669f1b2 100644
--- a/src/main/java/io/papermc/hangar/db/dao/api/ProjectApiDao.java
+++ b/src/main/java/io/papermc/hangar/db/dao/api/ProjectApiDao.java
@@ -3,6 +3,8 @@ package io.papermc.hangar.db.dao.api;
 import io.papermc.hangar.model.Category;
 import io.papermc.hangar.model.generated.Project;
 import io.papermc.hangar.model.generated.Tag;
+
+import org.jdbi.v3.core.enums.EnumByOrdinal;
 import org.jdbi.v3.sqlobject.config.RegisterBeanMapper;
 import org.jdbi.v3.sqlobject.customizer.AllowUnusedBindings;
 import org.jdbi.v3.sqlobject.statement.SqlQuery;
diff --git a/src/main/java/io/papermc/hangar/db/mappers/RoleMapper.java b/src/main/java/io/papermc/hangar/db/mappers/RoleMapper.java
index ab806027c..74a402fc3 100644
--- a/src/main/java/io/papermc/hangar/db/mappers/RoleMapper.java
+++ b/src/main/java/io/papermc/hangar/db/mappers/RoleMapper.java
@@ -3,10 +3,12 @@ package io.papermc.hangar.db.mappers;
 import io.papermc.hangar.model.Role;
 import org.jdbi.v3.core.mapper.RowMapper;
 import org.jdbi.v3.core.statement.StatementContext;
+import org.springframework.stereotype.Component;
 
 import java.sql.ResultSet;
 import java.sql.SQLException;
 
+@Component
 public class RoleMapper implements RowMapper<Role> {
     @Override
     public Role map(ResultSet rs, StatementContext ctx) throws SQLException {
diff --git a/src/main/java/io/papermc/hangar/model/generated/Project.java b/src/main/java/io/papermc/hangar/model/generated/Project.java
index ca7b82b08..deece39a1 100644
--- a/src/main/java/io/papermc/hangar/model/generated/Project.java
+++ b/src/main/java/io/papermc/hangar/model/generated/Project.java
@@ -1,16 +1,20 @@
 package io.papermc.hangar.model.generated;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+import org.jdbi.v3.core.enums.EnumByOrdinal;
 import org.springframework.validation.annotation.Validated;
 
 import java.time.OffsetDateTime;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
+import java.util.StringJoiner;
 import javax.validation.Valid;
 import javax.validation.constraints.NotNull;
 
+import io.papermc.hangar.db.customtypes.JSONB;
 import io.papermc.hangar.model.Visibility;
 import io.swagger.annotations.ApiModelProperty;
 import io.papermc.hangar.model.Category;
@@ -34,7 +38,7 @@ public class Project {
 
     @JsonProperty("promoted_versions")
     @Valid
-    private List<PromotedVersion> promotedVersions = new ArrayList<>();
+    private JSONB /*List<PromotedVersion>*/ promotedVersions = new JSONB("[]"); // TODO back to list but fix jdbi
 
     @JsonProperty("stats")
     private ProjectStatsAll stats = null;
@@ -58,22 +62,24 @@ public class Project {
     private ProjectSettings settings = null;
 
     @JsonProperty("icon_url")
-    private String iconUrl = null;
+    private String iconUrl = "";
 
-    public Project createdAt(OffsetDateTime createdAt) {
-        this.createdAt = createdAt;
-        return this;
-    }
+    // dummy values, only used for db -> model
+    @JsonIgnore
+    private String ownerName;
+    @JsonIgnore
+    private Long views;
+    @JsonIgnore
+    private Long downloads;
+    @JsonIgnore
+    private Long recentViews;
+    @JsonIgnore
+    private Long recentDownloads;
+    @JsonIgnore
+    private Long stars;
+    @JsonIgnore
+    private Long watchers;
 
-    /**
-     * Get createdAt
-     *
-     * @return createdAt
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
-    @Valid
     public OffsetDateTime getCreatedAt() {
         return createdAt;
     }
@@ -82,19 +88,6 @@ public class Project {
         this.createdAt = createdAt;
     }
 
-    public Project pluginId(String pluginId) {
-        this.pluginId = pluginId;
-        return this;
-    }
-
-    /**
-     * Get pluginId
-     *
-     * @return pluginId
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
     public String getPluginId() {
         return pluginId;
     }
@@ -103,19 +96,6 @@ public class Project {
         this.pluginId = pluginId;
     }
 
-    public Project name(String name) {
-        this.name = name;
-        return this;
-    }
-
-    /**
-     * Get name
-     *
-     * @return name
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
     public String getName() {
         return name;
     }
@@ -124,21 +104,10 @@ public class Project {
         this.name = name;
     }
 
-    public Project namespace(ProjectNamespace namespace) {
-        this.namespace = namespace;
-        return this;
-    }
-
-    /**
-     * Get namespace
-     *
-     * @return namespace
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
-    @Valid
     public ProjectNamespace getNamespace() {
+        if (namespace == null) {
+            namespace = new ProjectNamespace().owner(ownerName).slug(name);
+        }
         return namespace;
     }
 
@@ -146,47 +115,18 @@ public class Project {
         this.namespace = namespace;
     }
 
-    public Project promotedVersions(List<PromotedVersion> promotedVersions) {
-        this.promotedVersions = promotedVersions;
-        return this;
-    }
-
-    public Project addPromotedVersionsItem(PromotedVersion promotedVersionsItem) {
-        this.promotedVersions.add(promotedVersionsItem);
-        return this;
-    }
-
-    /**
-     * Get promotedVersions
-     *
-     * @return promotedVersions
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-    @Valid
-    public List<PromotedVersion> getPromotedVersions() {
+    public JSONB /*List<PromotedVersion>*/ getPromotedVersions() {
         return promotedVersions;
     }
 
-    public void setPromotedVersions(List<PromotedVersion> promotedVersions) {
+    public void setPromotedVersions(JSONB /*List<PromotedVersion>*/ promotedVersions) {
         this.promotedVersions = promotedVersions;
     }
 
-    public Project stats(ProjectStatsAll stats) {
-        this.stats = stats;
-        return this;
-    }
-
-    /**
-     * Get stats
-     *
-     * @return stats
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
-    @Valid
     public ProjectStatsAll getStats() {
+        if (stats == null) {
+            stats = new ProjectStatsAll(views, downloads, recentViews, recentDownloads, stars, watchers);
+        }
         return stats;
     }
 
@@ -194,40 +134,16 @@ public class Project {
         this.stats = stats;
     }
 
-    public Project category(Category category) {
-        this.category = category;
-        return this;
-    }
-
-    /**
-     * Get category
-     *
-     * @return category
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
-    @Valid
+    @EnumByOrdinal
     public Category getCategory() {
         return category;
     }
 
+    @EnumByOrdinal
     public void setCategory(Category category) {
         this.category = category;
     }
 
-    public Project description(String description) {
-        this.description = description;
-        return this;
-    }
-
-    /**
-     * Get description
-     *
-     * @return description
-     **/
-    @ApiModelProperty(value = "")
-
     public String getDescription() {
         return description;
     }
@@ -236,20 +152,6 @@ public class Project {
         this.description = description;
     }
 
-    public Project lastUpdated(OffsetDateTime lastUpdated) {
-        this.lastUpdated = lastUpdated;
-        return this;
-    }
-
-    /**
-     * Get lastUpdated
-     *
-     * @return lastUpdated
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
-    @Valid
     public OffsetDateTime getLastUpdated() {
         return lastUpdated;
     }
@@ -258,41 +160,16 @@ public class Project {
         this.lastUpdated = lastUpdated;
     }
 
-    public Project visibility(Visibility visibility) {
-        this.visibility = visibility;
-        return this;
-    }
-
-    /**
-     * Get visibility
-     *
-     * @return visibility
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
+    @EnumByOrdinal
     public Visibility getVisibility() {
         return visibility;
     }
 
+    @EnumByOrdinal
     public void setVisibility(Visibility visibility) {
         this.visibility = visibility;
     }
 
-    public Project userActions(UserActions userActions) {
-        this.userActions = userActions;
-        return this;
-    }
-
-    /**
-     * Get userActions
-     *
-     * @return userActions
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
-    @Valid
     public UserActions getUserActions() {
         return userActions;
     }
@@ -301,20 +178,6 @@ public class Project {
         this.userActions = userActions;
     }
 
-    public Project settings(ProjectSettings settings) {
-        this.settings = settings;
-        return this;
-    }
-
-    /**
-     * Get settings
-     *
-     * @return settings
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
-    @Valid
     public ProjectSettings getSettings() {
         return settings;
     }
@@ -323,19 +186,6 @@ public class Project {
         this.settings = settings;
     }
 
-    public Project iconUrl(String iconUrl) {
-        this.iconUrl = iconUrl;
-        return this;
-    }
-
-    /**
-     * Get iconUrl
-     *
-     * @return iconUrl
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
     public String getIconUrl() {
         return iconUrl;
     }
@@ -344,65 +194,120 @@ public class Project {
         this.iconUrl = iconUrl;
     }
 
+    // dummy values below
+
+    public String getOwnerName() {
+        return ownerName;
+    }
+
+    public void setOwnerName(String ownerName) {
+        this.ownerName = ownerName;
+    }
+
+    public Long getViews() {
+        return views;
+    }
+
+    public void setViews(Long views) {
+        this.views = views;
+    }
+
+    public Long getDownloads() {
+        return downloads;
+    }
+
+    public void setDownloads(Long downloads) {
+        this.downloads = downloads;
+    }
+
+    public Long getRecentViews() {
+        return recentViews;
+    }
+
+    public void setRecentViews(Long recentViews) {
+        this.recentViews = recentViews;
+    }
+
+    public Long getRecentDownloads() {
+        return recentDownloads;
+    }
+
+    public void setRecentDownloads(Long recentDownloads) {
+        this.recentDownloads = recentDownloads;
+    }
+
+    public Long getStars() {
+        return stars;
+    }
+
+    public void setStars(Long stars) {
+        this.stars = stars;
+    }
+
+    public Long getWatchers() {
+        return watchers;
+    }
+
+    public void setWatchers(Long watchers) {
+        this.watchers = watchers;
+    }
 
     @Override
     public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
         Project project = (Project) o;
-        return Objects.equals(this.createdAt, project.createdAt) &&
-               Objects.equals(this.pluginId, project.pluginId) &&
-               Objects.equals(this.name, project.name) &&
-               Objects.equals(this.namespace, project.namespace) &&
-               Objects.equals(this.promotedVersions, project.promotedVersions) &&
-               Objects.equals(this.stats, project.stats) &&
-               Objects.equals(this.category, project.category) &&
-               Objects.equals(this.description, project.description) &&
-               Objects.equals(this.lastUpdated, project.lastUpdated) &&
-               Objects.equals(this.visibility, project.visibility) &&
-               Objects.equals(this.userActions, project.userActions) &&
-               Objects.equals(this.settings, project.settings) &&
-               Objects.equals(this.iconUrl, project.iconUrl);
+
+        if (!Objects.equals(createdAt, project.createdAt)) return false;
+        if (!Objects.equals(pluginId, project.pluginId)) return false;
+        if (!Objects.equals(name, project.name)) return false;
+        if (!Objects.equals(namespace, project.namespace)) return false;
+        if (!Objects.equals(promotedVersions, project.promotedVersions)) return false;
+        if (!Objects.equals(stats, project.stats)) return false;
+        if (category != project.category) return false;
+        if (!Objects.equals(description, project.description)) return false;
+        if (!Objects.equals(lastUpdated, project.lastUpdated)) return false;
+        if (visibility != project.visibility) return false;
+        if (!Objects.equals(userActions, project.userActions)) return false;
+        if (!Objects.equals(settings, project.settings)) return false;
+        return Objects.equals(iconUrl, project.iconUrl);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(createdAt, pluginId, name, namespace, promotedVersions, stats, category, description, lastUpdated, visibility, userActions, settings, iconUrl);
+        int result = createdAt != null ? createdAt.hashCode() : 0;
+        result = 31 * result + (pluginId != null ? pluginId.hashCode() : 0);
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        result = 31 * result + (namespace != null ? namespace.hashCode() : 0);
+        result = 31 * result + (promotedVersions != null ? promotedVersions.hashCode() : 0);
+        result = 31 * result + (stats != null ? stats.hashCode() : 0);
+        result = 31 * result + (category != null ? category.hashCode() : 0);
+        result = 31 * result + (description != null ? description.hashCode() : 0);
+        result = 31 * result + (lastUpdated != null ? lastUpdated.hashCode() : 0);
+        result = 31 * result + (visibility != null ? visibility.hashCode() : 0);
+        result = 31 * result + (userActions != null ? userActions.hashCode() : 0);
+        result = 31 * result + (settings != null ? settings.hashCode() : 0);
+        result = 31 * result + (iconUrl != null ? iconUrl.hashCode() : 0);
+        return result;
     }
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("class ModelsProtocolsAPIV2Project {\n");
-
-        sb.append("    createdAt: ").append(toIndentedString(createdAt)).append("\n");
-        sb.append("    pluginId: ").append(toIndentedString(pluginId)).append("\n");
-        sb.append("    name: ").append(toIndentedString(name)).append("\n");
-        sb.append("    namespace: ").append(toIndentedString(namespace)).append("\n");
-        sb.append("    promotedVersions: ").append(toIndentedString(promotedVersions)).append("\n");
-        sb.append("    stats: ").append(toIndentedString(stats)).append("\n");
-        sb.append("    category: ").append(toIndentedString(category)).append("\n");
-        sb.append("    description: ").append(toIndentedString(description)).append("\n");
-        sb.append("    lastUpdated: ").append(toIndentedString(lastUpdated)).append("\n");
-        sb.append("    visibility: ").append(toIndentedString(visibility)).append("\n");
-        sb.append("    userActions: ").append(toIndentedString(userActions)).append("\n");
-        sb.append("    settings: ").append(toIndentedString(settings)).append("\n");
-        sb.append("    iconUrl: ").append(toIndentedString(iconUrl)).append("\n");
-        sb.append("}");
-        return sb.toString();
-    }
-
-    /**
-     * Convert the given object to string with each line indented by 4 spaces (except the first line).
-     */
-    private String toIndentedString(Object o) {
-        if (o == null) {
-            return "null";
-        }
-        return o.toString().replace("\n", "\n    ");
+        return new StringJoiner(", ", Project.class.getSimpleName() + "[", "]")
+                .add("createdAt=" + createdAt)
+                .add("pluginId='" + pluginId + "'")
+                .add("name='" + name + "'")
+                .add("namespace=" + namespace)
+                .add("promotedVersions=" + promotedVersions)
+                .add("stats=" + stats)
+                .add("category=" + category)
+                .add("description='" + description + "'")
+                .add("lastUpdated=" + lastUpdated)
+                .add("visibility=" + visibility)
+                .add("userActions=" + userActions)
+                .add("settings=" + settings)
+                .add("iconUrl='" + iconUrl + "'")
+                .toString();
     }
 }
diff --git a/src/main/java/io/papermc/hangar/model/generated/ProjectStatsAll.java b/src/main/java/io/papermc/hangar/model/generated/ProjectStatsAll.java
index 6af4d9dcd..ba43cad38 100644
--- a/src/main/java/io/papermc/hangar/model/generated/ProjectStatsAll.java
+++ b/src/main/java/io/papermc/hangar/model/generated/ProjectStatsAll.java
@@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import org.springframework.validation.annotation.Validated;
 
 import java.util.Objects;
+import java.util.StringJoiner;
 import javax.validation.constraints.NotNull;
 
 import io.swagger.annotations.ApiModelProperty;
@@ -32,18 +33,18 @@ public class ProjectStatsAll {
     @JsonProperty("watchers")
     private Long watchers = null;
 
-    public ProjectStatsAll views(Long views) {
-        this.views = views;
-        return this;
+    public ProjectStatsAll() {
+        //
     }
 
-    /**
-     * Get views
-     *
-     * @return views
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
+    public ProjectStatsAll(Long views, Long downloads, Long recentViews, Long recentDownloads, Long stars, Long watchers) {
+        this.views = views;
+        this.downloads = downloads;
+        this.recentViews = recentViews;
+        this.recentDownloads = recentDownloads;
+        this.stars = stars;
+        this.watchers = watchers;
+    }
 
     public Long getViews() {
         return views;
@@ -53,19 +54,6 @@ public class ProjectStatsAll {
         this.views = views;
     }
 
-    public ProjectStatsAll downloads(Long downloads) {
-        this.downloads = downloads;
-        return this;
-    }
-
-    /**
-     * Get downloads
-     *
-     * @return downloads
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
     public Long getDownloads() {
         return downloads;
     }
@@ -74,19 +62,6 @@ public class ProjectStatsAll {
         this.downloads = downloads;
     }
 
-    public ProjectStatsAll recentViews(Long recentViews) {
-        this.recentViews = recentViews;
-        return this;
-    }
-
-    /**
-     * Get recentViews
-     *
-     * @return recentViews
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
     public Long getRecentViews() {
         return recentViews;
     }
@@ -95,19 +70,6 @@ public class ProjectStatsAll {
         this.recentViews = recentViews;
     }
 
-    public ProjectStatsAll recentDownloads(Long recentDownloads) {
-        this.recentDownloads = recentDownloads;
-        return this;
-    }
-
-    /**
-     * Get recentDownloads
-     *
-     * @return recentDownloads
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
     public Long getRecentDownloads() {
         return recentDownloads;
     }
@@ -116,20 +78,7 @@ public class ProjectStatsAll {
         this.recentDownloads = recentDownloads;
     }
 
-    public ProjectStatsAll stars(Long stars) {
-        this.stars = stars;
-        return this;
-    }
-
-    /**
-     * Get stars
-     *
-     * @return stars
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
-    public Long getStars() {
+   public Long getStars() {
         return stars;
     }
 
@@ -137,19 +86,6 @@ public class ProjectStatsAll {
         this.stars = stars;
     }
 
-    public ProjectStatsAll watchers(Long watchers) {
-        this.watchers = watchers;
-        return this;
-    }
-
-    /**
-     * Get watchers
-     *
-     * @return watchers
-     **/
-    @ApiModelProperty(required = true, value = "")
-    @NotNull
-
     public Long getWatchers() {
         return watchers;
     }
@@ -158,51 +94,41 @@ public class ProjectStatsAll {
         this.watchers = watchers;
     }
 
-
     @Override
     public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-        ProjectStatsAll projectStatsAll = (ProjectStatsAll) o;
-        return Objects.equals(this.views, projectStatsAll.views) &&
-               Objects.equals(this.downloads, projectStatsAll.downloads) &&
-               Objects.equals(this.recentViews, projectStatsAll.recentViews) &&
-               Objects.equals(this.recentDownloads, projectStatsAll.recentDownloads) &&
-               Objects.equals(this.stars, projectStatsAll.stars) &&
-               Objects.equals(this.watchers, projectStatsAll.watchers);
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ProjectStatsAll that = (ProjectStatsAll) o;
+
+        if (!Objects.equals(views, that.views)) return false;
+        if (!Objects.equals(downloads, that.downloads)) return false;
+        if (!Objects.equals(recentViews, that.recentViews)) return false;
+        if (!Objects.equals(recentDownloads, that.recentDownloads)) return false;
+        if (!Objects.equals(stars, that.stars)) return false;
+        return Objects.equals(watchers, that.watchers);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(views, downloads, recentViews, recentDownloads, stars, watchers);
+        int result = views != null ? views.hashCode() : 0;
+        result = 31 * result + (downloads != null ? downloads.hashCode() : 0);
+        result = 31 * result + (recentViews != null ? recentViews.hashCode() : 0);
+        result = 31 * result + (recentDownloads != null ? recentDownloads.hashCode() : 0);
+        result = 31 * result + (stars != null ? stars.hashCode() : 0);
+        result = 31 * result + (watchers != null ? watchers.hashCode() : 0);
+        return result;
     }
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("class ModelsProtocolsAPIV2ProjectStatsAll {\n");
-
-        sb.append("    views: ").append(toIndentedString(views)).append("\n");
-        sb.append("    downloads: ").append(toIndentedString(downloads)).append("\n");
-        sb.append("    recentViews: ").append(toIndentedString(recentViews)).append("\n");
-        sb.append("    recentDownloads: ").append(toIndentedString(recentDownloads)).append("\n");
-        sb.append("    stars: ").append(toIndentedString(stars)).append("\n");
-        sb.append("    watchers: ").append(toIndentedString(watchers)).append("\n");
-        sb.append("}");
-        return sb.toString();
-    }
-
-    /**
-     * Convert the given object to string with each line indented by 4 spaces (except the first line).
-     */
-    private String toIndentedString(Object o) {
-        if (o == null) {
-            return "null";
-        }
-        return o.toString().replace("\n", "\n    ");
+        return new StringJoiner(", ", ProjectStatsAll.class.getSimpleName() + "[", "]")
+                .add("views=" + views)
+                .add("downloads=" + downloads)
+                .add("recentViews=" + recentViews)
+                .add("recentDownloads=" + recentDownloads)
+                .add("stars=" + stars)
+                .add("watchers=" + watchers)
+                .toString();
     }
 }
diff --git a/src/main/java/io/papermc/hangar/service/project/ProjectService.java b/src/main/java/io/papermc/hangar/service/project/ProjectService.java
index 439f153c2..038215feb 100644
--- a/src/main/java/io/papermc/hangar/service/project/ProjectService.java
+++ b/src/main/java/io/papermc/hangar/service/project/ProjectService.java
@@ -169,7 +169,7 @@ public class ProjectService {
         projectNamespace.setSlug(projectsTable.getSlug());
         project.setNamespace(projectNamespace);
 
-        project.setPromotedVersions(new ArrayList<>()); // TODO implement
+//        project.setPromotedVersions(new ArrayList<>()); // TODO implement
         project.setStats(projectDao.get().getProjectStats(projectsTable.getId()));
         project.setCategory(projectsTable.getCategory());
         project.setDescription(projectsTable.getDescription());