All checks were successful
Docker Deploy / build-and-push (push) Successful in 3m59s
68 lines
1.7 KiB
TypeScript
68 lines
1.7 KiB
TypeScript
import type { APIRoute } from "astro";
|
|
import { db } from "../../../db";
|
|
import { timeEntries, members } from "../../../db/schema";
|
|
import { eq, and, isNull } from "drizzle-orm";
|
|
import { nanoid } from "nanoid";
|
|
import { validateTimeEntryResources } from "../../../lib/validation";
|
|
|
|
export const POST: APIRoute = async ({ request, locals }) => {
|
|
if (!locals.user) return new Response("Unauthorized", { status: 401 });
|
|
|
|
const body = await request.json();
|
|
const description = body.description || "";
|
|
const clientId = body.clientId;
|
|
const tagId = body.tagId || null;
|
|
|
|
if (!clientId) {
|
|
return new Response("Client is required", { status: 400 });
|
|
}
|
|
|
|
const runningEntry = await db
|
|
.select()
|
|
.from(timeEntries)
|
|
.where(
|
|
and(eq(timeEntries.userId, locals.user.id), isNull(timeEntries.endTime)),
|
|
)
|
|
.get();
|
|
|
|
if (runningEntry) {
|
|
return new Response("Timer already running", { status: 400 });
|
|
}
|
|
|
|
const member = await db
|
|
.select()
|
|
.from(members)
|
|
.where(eq(members.userId, locals.user.id))
|
|
.limit(1)
|
|
.get();
|
|
if (!member) {
|
|
return new Response("No organization found", { status: 400 });
|
|
}
|
|
|
|
const validation = await validateTimeEntryResources({
|
|
organizationId: member.organizationId,
|
|
clientId,
|
|
tagId,
|
|
});
|
|
|
|
if (!validation.valid) {
|
|
return new Response(validation.error, { status: 400 });
|
|
}
|
|
|
|
const startTime = new Date();
|
|
const id = nanoid();
|
|
|
|
await db.insert(timeEntries).values({
|
|
id,
|
|
userId: locals.user.id,
|
|
organizationId: member.organizationId,
|
|
clientId,
|
|
tagId,
|
|
startTime,
|
|
description,
|
|
isManual: false,
|
|
});
|
|
|
|
return new Response(JSON.stringify({ id, startTime }), { status: 200 });
|
|
};
|