11import { db } from '$lib/server/db/index.js' ;
2- import { devlog , project , clubMembership , club } from '$lib/server/db/schema.js' ;
2+ import { devlog , project , clubMembership , club , ship } from '$lib/server/db/schema.js' ;
33import { error , fail , redirect } from '@sveltejs/kit' ;
4- import { eq , and , or , sql } from 'drizzle-orm' ;
4+ import { eq , and , or , sql , desc } from 'drizzle-orm' ;
55import type { Actions } from './$types' ;
66import { sendSlackDM } from '$lib/server/slack.js' ;
77import { isValidUrl } from '$lib/utils' ;
@@ -10,8 +10,8 @@ import { extname } from 'path';
1010import { env } from '$env/dynamic/private' ;
1111import { PutObjectCommand } from '@aws-sdk/client-s3' ;
1212import { S3 } from '$lib/server/s3' ;
13- import { ship } from '$lib/server/db/schema.js' ;
1413import { sanitizeUrl } from '@braintree/sanitize-url' ;
14+ import { END_DATE } from '$lib/defs' ;
1515
1616export async function load ( { params, locals } ) {
1717 const id : number = parseInt ( params . id ) ;
@@ -74,7 +74,8 @@ export async function load({ params, locals }) {
7474
7575 return {
7676 project : queriedProject ,
77- clubMembership : membership . length > 0 ? membership [ 0 ] : null
77+ clubMembership : membership . length > 0 ? membership [ 0 ] : null ,
78+ lastIsClubsShip : await lastIsClubsShip ( id )
7879 } ;
7980}
8081
@@ -109,7 +110,7 @@ export const actions = {
109110 } ) ;
110111 }
111112
112- // Double dipping
113+ // Double dipping
113114 if ( doubleDippingWith !== 'none' && doubleDippingWith !== 'enclosure' ) {
114115 return error ( 400 ) ;
115116 }
@@ -233,6 +234,7 @@ export const actions = {
233234 name : project . name ,
234235 description : project . description ,
235236 url : project . url ,
237+ status : project . status ,
236238 timeSpent : sql < number > `COALESCE(SUM(${ devlog . timeSpent } ), 0)` ,
237239 devlogCount : sql < number > `COALESCE(COUNT(${ devlog . id } ), 0)`
238240 } )
@@ -267,6 +269,23 @@ export const actions = {
267269 return error ( 400 , { message : 'project must have a description' } ) ;
268270 }
269271
272+ // Get club ID if submitting as club
273+ let clubIdForShip : number | null = null ;
274+ if ( submitAsClub ) {
275+ const [ membership ] = await db
276+ . select ( { clubId : clubMembership . clubId } )
277+ . from ( clubMembership )
278+ . where ( eq ( clubMembership . userId , locals . user . id ) )
279+ . limit ( 1 ) ;
280+ if ( membership ) {
281+ clubIdForShip = membership . clubId ;
282+ }
283+ }
284+
285+ if ( END_DATE <= new Date ( ) && clubIdForShip === null && ( queriedProject . status === 'building' || await lastIsClubsShip ( id ) ) ) {
286+ return error ( 400 , { message : "can't submit individual project past end date" } ) ;
287+ }
288+
270289 // Editor file
271290 const editorFilePath = `ships/editor-files/${ crypto . randomUUID ( ) } ${ extname ( editorFile . name ) } ` ;
272291
@@ -299,7 +318,7 @@ export const actions = {
299318 uploadedFileUrl : editorFileExists ? editorFilePath : undefined ,
300319
301320 modelFile : modelPath ,
302- doubleDippingWith
321+ doubleDippingWith
303322 } )
304323 . where (
305324 and (
@@ -309,19 +328,6 @@ export const actions = {
309328 )
310329 ) ;
311330
312- // Get club ID if submitting as club
313- let clubIdForShip : number | null = null ;
314- if ( submitAsClub ) {
315- const [ membership ] = await db
316- . select ( { clubId : clubMembership . clubId } )
317- . from ( clubMembership )
318- . where ( eq ( clubMembership . userId , locals . user . id ) )
319- . limit ( 1 ) ;
320- if ( membership ) {
321- clubIdForShip = membership . clubId ;
322- }
323- }
324-
325331 await db . insert ( ship ) . values ( {
326332 userId : locals . user . id ,
327333 projectId : queriedProject . id ,
@@ -343,3 +349,18 @@ export const actions = {
343349 return redirect ( 303 , '/dashboard/projects' ) ;
344350 }
345351} satisfies Actions ;
352+
353+ async function lastIsClubsShip ( id : number ) {
354+ const [ latestShip ] = await db
355+ . select ( {
356+ clubId : ship . clubId
357+ } )
358+ . from ( ship )
359+ . where ( eq ( ship . projectId , id ) )
360+ . orderBy ( desc ( ship . timestamp ) )
361+ . limit ( 1 ) ;
362+
363+ if ( latestShip && latestShip . clubId ) return true ;
364+
365+ return false ;
366+ }
0 commit comments