@@ -11,14 +11,17 @@ use crate::{
1111 models:: {
1212 self , DBOrganization , DBTeamMember , DBUser ,
1313 project_item:: ProjectBuilder , thread_item:: ThreadBuilder ,
14+ version_item:: VersionBuilder ,
1415 } ,
1516 redis:: RedisPool ,
1617 } ,
1718 models:: {
1819 exp:: { self , ProjectComponentKind , component:: ComponentRelationError } ,
1920 ids:: ProjectId ,
2021 pats:: Scopes ,
21- projects:: { MonetizationStatus , ProjectStatus } ,
22+ projects:: {
23+ MonetizationStatus , ProjectStatus , VersionStatus , VersionType ,
24+ } ,
2225 teams:: { OrganizationPermissions , ProjectPermissions } ,
2326 threads:: ThreadType ,
2427 v3:: user_limits:: UserLimits ,
@@ -233,12 +236,44 @@ pub async fn create(
233236 . wrap_internal_err ( "failed to generate project ID" ) ?
234237 . into ( ) ;
235238
236- // TODO: special-case server projects to be unmonetized
237- let monetization_status = if details. minecraft_server . is_some ( ) {
238- MonetizationStatus :: ForceDemonetized
239- } else {
240- MonetizationStatus :: Monetized
241- } ;
239+ // TODO: special casing certain components
240+ let mut monetization_status = MonetizationStatus :: Monetized ;
241+ let mut version_builder = None :: < VersionBuilder > ;
242+
243+ if details. minecraft_server . is_some ( ) {
244+ // servers are not part of the monetization pool;
245+ // they generate no payouts for their owners
246+ monetization_status = MonetizationStatus :: ForceDemonetized ;
247+
248+ // servers may never have a version added, if e.g. they are a vanilla server
249+ // but we need at least 1 version on this project for certain features,
250+ // like search indexing, to work.
251+ // so we generate a synthetic initial version.
252+ let version_id = models:: generate_version_id ( & mut txn)
253+ . await
254+ . wrap_internal_err ( "failed to generate project ID" ) ?;
255+ version_builder = Some ( VersionBuilder {
256+ version_id,
257+ project_id : project_id. into ( ) ,
258+ author_id : user. id . into ( ) ,
259+ name : "__synthetic" . into ( ) ,
260+ version_number : String :: new ( ) ,
261+ changelog : String :: new ( ) ,
262+ files : Vec :: new ( ) ,
263+ dependencies : Vec :: new ( ) ,
264+ loaders : Vec :: new ( ) ,
265+ version_fields : Vec :: new ( ) ,
266+ version_type : VersionType :: Release . to_string ( ) ,
267+ featured : false ,
268+ status : VersionStatus :: Listed ,
269+ requested_status : None ,
270+ ordering : None ,
271+ components : exp:: VersionCreate {
272+ base : None ,
273+ minecraft_java_server : None ,
274+ } ,
275+ } ) ;
276+ }
242277
243278 let project_builder = ProjectBuilder {
244279 project_id : project_id. into ( ) ,
@@ -268,6 +303,14 @@ pub async fn create(
268303 . insert ( & mut txn)
269304 . await
270305 . wrap_internal_err ( "failed to insert project" ) ?;
306+
307+ if let Some ( version_builder) = version_builder {
308+ version_builder
309+ . insert ( & mut txn)
310+ . await
311+ . wrap_internal_err ( "failed to insert initial version" ) ?;
312+ }
313+
271314 DBUser :: clear_project_cache ( & [ user. id . into ( ) ] , & redis)
272315 . await
273316 . wrap_internal_err ( "failed to clear user project cache" ) ?;
0 commit comments