102 lines
3.9 KiB
TypeScript
102 lines
3.9 KiB
TypeScript
import { TRPCError } from "@trpc/server";
|
|
import { and, asc, desc, eq, inArray, notExists } from "drizzle-orm";
|
|
import { z } from "zod";
|
|
|
|
import { DatabaseError, ErrorCodes } from "@lifetracker/db";
|
|
import { colors, metrics } from "@lifetracker/db/schema";
|
|
import { zMetricSchema, zMeasurementSchema } from "@lifetracker/shared/types/metrics";
|
|
import type { Context } from "../index";
|
|
import { authedProcedure, router } from "../index";
|
|
import { zColorSchema } from "@lifetracker/shared/types/colors";
|
|
import { titleCase } from "title-case";
|
|
|
|
export const metricsAppRouter = router({
|
|
list: authedProcedure
|
|
.output(z.array(zMetricSchema))
|
|
.query(async ({ ctx }) => {
|
|
const dbMeasurements = await ctx.db
|
|
.select()
|
|
.from(metrics)
|
|
.where(eq(metrics.userId, ctx.user.id))
|
|
.orderBy(asc(metrics.name))
|
|
;
|
|
|
|
return dbMeasurements;
|
|
}),
|
|
create: authedProcedure
|
|
.input(zMetricSchema)
|
|
.output(zMetricSchema)
|
|
.mutation(async ({ input, ctx }) => {
|
|
return ctx.db.transaction(async (trx) => {
|
|
try {
|
|
const result = await trx
|
|
.insert(metrics)
|
|
.values({
|
|
name: titleCase(input.name),
|
|
userId: ctx.user!.id,
|
|
unit: input.unit ?? null,
|
|
type: input.type,
|
|
description: input.description ?? null,
|
|
icon: input.icon,
|
|
})
|
|
.returning();
|
|
return result[0];
|
|
} catch (e) {
|
|
if (e instanceof DatabaseError) {
|
|
if (e.code == ErrorCodes.UNIQUE_VIOLATION) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "This metric already exists",
|
|
});
|
|
}
|
|
}
|
|
throw new TRPCError({
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
message: "Something went wrong",
|
|
});
|
|
}
|
|
});
|
|
}),
|
|
update: authedProcedure
|
|
.input(zMetricSchema)
|
|
.output(zMetricSchema)
|
|
.mutation(async ({ input, ctx }) => {
|
|
return ctx.db.transaction(async (trx) => {
|
|
try {
|
|
const result = await trx
|
|
.update(metrics)
|
|
.set({
|
|
name: input.name,
|
|
unit: input.unit ?? null,
|
|
type: input.type,
|
|
description: input.description ?? null,
|
|
icon: input.icon,
|
|
})
|
|
.where(eq(metrics.id, input.id))
|
|
.returning();
|
|
return result[0];
|
|
} catch (e) {
|
|
throw new TRPCError({
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
message: "Something went wrong",
|
|
});
|
|
}
|
|
});
|
|
}),
|
|
delete: authedProcedure
|
|
.input(z.object({ id: z.string() }))
|
|
.mutation(async ({ input, ctx }) => {
|
|
return ctx.db.transaction(async (trx) => {
|
|
try {
|
|
const result = await trx
|
|
.delete(metrics)
|
|
.where(and(eq(metrics.id, input.id), eq(metrics.userId, ctx.user!.id)))
|
|
} catch (e) {
|
|
throw new TRPCError({
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
message: "Something went wrong",
|
|
});
|
|
}
|
|
});
|
|
}),
|
|
}); |