diff --git a/drizzle/0025_add_claimed_at.sql b/drizzle/0025_add_claimed_at.sql deleted file mode 100644 index 3a6c38f..0000000 --- a/drizzle/0025_add_claimed_at.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "project" ADD COLUMN "claimedAt" timestamp; diff --git a/server.js b/server.js index 8f88a46..c3af060 100644 --- a/server.js +++ b/server.js @@ -1,29 +1,16 @@ import express from 'express'; import { handler } from './build/handler.js'; -import { CronJob } from 'cron'; +// import { CronJob } from 'cron'; -// Run daily at midnight UTC to unclaim expired print claims (older than 7 days) -new CronJob( - '0 0 * * *', // Every day at midnight - async function () { - try { - const baseUrl = process.env.PUBLIC_BASE_URL || `http://localhost:${process.env.PORT ?? 3000}`; - const response = await fetch(`${baseUrl}/api/cron/unclaim-expired`, { - method: 'POST', - headers: { - Authorization: `Bearer ${process.env.APP_SECRET_KEY}` - } - }); - const result = await response.json(); - console.log(`[Cron] Unclaimed ${result.unclaimedCount} expired print claims`); - } catch (error) { - console.error('[Cron] Failed to unclaim expired prints:', error); - } - }, - null, - true, - 'UTC' -); +// new CronJob( +// '* * * * * *', // cronTime +// function () { +// console.log('You will see this message every second'); +// }, // onTick +// null, // onComplete +// true, // start +// 'Europe/London' // timeZone +// ); const app = express(); diff --git a/src/lib/server/db/schema.ts b/src/lib/server/db/schema.ts index 18ae15a..2f4591e 100644 --- a/src/lib/server/db/schema.ts +++ b/src/lib/server/db/schema.ts @@ -84,7 +84,6 @@ export const project = pgTable('project', { status: projectStatusEnum().notNull().default('building'), printedBy: integer().references(() => user.id), - claimedAt: timestamp(), // When the project was claimed for printing submittedToAirtable: boolean().default(false), diff --git a/src/routes/api/cron/unclaim-expired/+server.ts b/src/routes/api/cron/unclaim-expired/+server.ts deleted file mode 100644 index ea3eba9..0000000 --- a/src/routes/api/cron/unclaim-expired/+server.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { json, error } from '@sveltejs/kit'; -import { env } from '$env/dynamic/private'; -import { db } from '$lib/server/db/index.js'; -import { project, legionReview } from '$lib/server/db/schema.js'; -import { eq, and, lt, isNotNull } from 'drizzle-orm'; - -const CLAIM_EXPIRY_DAYS = 7; - -export async function POST({ request }) { - const authHeader = request.headers.get('Authorization'); - const expectedToken = `Bearer ${env.APP_SECRET_KEY}`; - - if (!authHeader || authHeader !== expectedToken) { - throw error(401, { message: 'Unauthorized' }); - } - - const expiryDate = new Date(); - expiryDate.setDate(expiryDate.getDate() - CLAIM_EXPIRY_DAYS); - - // Find all projects that are in 'printing' status with claimedAt older than 7 days - const expiredClaims = await db - .select({ - id: project.id, - name: project.name, - printedBy: project.printedBy, - claimedAt: project.claimedAt - }) - .from(project) - .where( - and( - eq(project.status, 'printing'), - eq(project.deleted, false), - isNotNull(project.claimedAt), - lt(project.claimedAt, expiryDate) - ) - ); - - // Unclaim each expired project - for (const expiredProject of expiredClaims) { - if (expiredProject.printedBy) { - await db.insert(legionReview).values({ - projectId: expiredProject.id, - userId: expiredProject.printedBy, - action: 'unmark_for_printing', - notes: 'Auto-unclaimed after 7 days without printing' - }); - } - - await db - .update(project) - .set({ - status: 't1_approved', - printedBy: null, - claimedAt: null - }) - .where(eq(project.id, expiredProject.id)); - } - - return json({ - success: true, - unclaimedCount: expiredClaims.length, - unclaimed: expiredClaims.map((p) => ({ id: p.id, name: p.name })) - }); -} diff --git a/src/routes/dashboard/admin/print/[id]/+page.server.ts b/src/routes/dashboard/admin/print/[id]/+page.server.ts index 21a5ab7..a59be0a 100644 --- a/src/routes/dashboard/admin/print/[id]/+page.server.ts +++ b/src/routes/dashboard/admin/print/[id]/+page.server.ts @@ -5,6 +5,7 @@ import { eq, and, asc, sql } from 'drizzle-orm'; import type { Actions } from './$types'; import { sendSlackDM } from '$lib/server/slack.js'; import { getReviewHistory } from '../../getReviewHistory.server'; +import { getCurrentlyPrinting } from '../utils.server'; export async function load({ locals, params }) { if (!locals.user) { @@ -79,10 +80,13 @@ export async function load({ locals, params }) { .where(and(eq(devlog.projectId, queriedProject.project.id), eq(devlog.deleted, false))) .orderBy(asc(devlog.createdAt)); + const currentlyPrinting = await getCurrentlyPrinting(locals.user); + return { project: queriedProject, devlogs, - reviews: await getReviewHistory(id) + reviews: await getReviewHistory(id), + currentlyPrinting }; } @@ -95,8 +99,16 @@ export const actions = { throw error(403, { message: 'oi get out' }); } + const currentlyPrinting = await getCurrentlyPrinting(locals.user); + const id: number = parseInt(params.id); + if (currentlyPrinting && currentlyPrinting.id !== id) { + return error(400, { + message: 'you are already printing something else right now' + }); + } + const [queriedProject] = await db .select({ id: project.id, @@ -124,8 +136,7 @@ export const actions = { .update(project) .set({ status: 'printing', - printedBy: locals.user.id, - claimedAt: new Date() + printedBy: locals.user.id }) .where(eq(project.id, id)); @@ -170,8 +181,7 @@ export const actions = { .update(project) .set({ status: 't1_approved', - printedBy: null, - claimedAt: null + printedBy: null }) .where(eq(project.id, id)); @@ -186,13 +196,20 @@ export const actions = { throw error(403, { message: 'oi get out' }); } + const currentlyPrinting = await getCurrentlyPrinting(locals.user); + const id: number = parseInt(params.id); + if (!currentlyPrinting || currentlyPrinting.id !== id) { + return error(400, { + message: "you can only print a project if you've marked it as you're printing it" + }); + } + const [queriedProject] = await db .select({ id: project.id, - status: project.status, - printedBy: project.printedBy + status: project.status }) .from(project) .where(and(eq(project.id, id), eq(project.deleted, false))) @@ -206,12 +223,6 @@ export const actions = { return error(403, { message: 'project is not marked as currently printing' }); } - if (queriedProject.printedBy !== locals.user.id) { - return error(400, { - message: "you can only print a project if you've marked it as you're printing it" - }); - } - const data = await request.formData(); const filamentUsed = data.get('filament'); const notes = data.get('notes')?.toString(); @@ -241,8 +252,7 @@ export const actions = { await db .update(project) .set({ - status: 'printed', - claimedAt: null + status: 'printed' }) .where(eq(project.id, id)); diff --git a/src/routes/dashboard/admin/print/[id]/+page.svelte b/src/routes/dashboard/admin/print/[id]/+page.svelte index 47ef0ec..cf8ad38 100644 --- a/src/routes/dashboard/admin/print/[id]/+page.svelte +++ b/src/routes/dashboard/admin/print/[id]/+page.svelte @@ -112,9 +112,9 @@

Printering area

- {#if data.project.project.status === 't1_approved' || (data.project.project.status === 'printing' && data.project.project.printedBy === data.user.id)} + {#if (data.project.project.status === 't1_approved' && !data.currentlyPrinting) || (data.project.project.status === 'printing' && data.project.project.printedBy === data.user.id)}
- {#if data.project.project.status === 't1_approved'} + {#if data.project.project.status === 't1_approved' && !data.currentlyPrinting}