mirror of
https://github.com/fergalmoran/kidarr-server.git
synced 2026-01-06 08:47:16 +00:00
Cleanup ping route
This commit is contained in:
@@ -1 +1,3 @@
|
|||||||
select * From pings
|
--select * From pings
|
||||||
|
|
||||||
|
SELECT * FROM children ORDER BY Id DESC
|
||||||
@@ -1,19 +1,30 @@
|
|||||||
import { db } from "@/server/db/index";
|
import { db } from "@/server/db/index";
|
||||||
import { eq, and } from "drizzle-orm";
|
import { eq, and } from "drizzle-orm";
|
||||||
import { getUserAuth } from "@/lib/auth/utils";
|
import { getUserAuth } from "@/lib/auth/utils";
|
||||||
import { type DeviceId, deviceIdSchema, devices } from "@/server/db/schema/devices";
|
import {
|
||||||
|
type DeviceId,
|
||||||
|
deviceIdSchema,
|
||||||
|
devices,
|
||||||
|
} from "@/server/db/schema/devices";
|
||||||
import { children } from "@/server/db/schema/children";
|
import { children } from "@/server/db/schema/children";
|
||||||
|
|
||||||
export const getDevices = async () => {
|
export const getDevices = async () => {
|
||||||
const { session } = await getUserAuth();
|
const { session } = await getUserAuth();
|
||||||
const d = await db.select({ device: devices, child: children }).from(devices).leftJoin(children, eq(devices.childId, children.id)).where(eq(devices.userId, session?.user.id!));
|
const d = await db
|
||||||
|
.select({ device: devices, child: children })
|
||||||
|
.from(devices)
|
||||||
|
.leftJoin(children, eq(devices.childId, children.id))
|
||||||
|
.where(eq(devices.userId, session?.user.id!));
|
||||||
return { devices: d };
|
return { devices: d };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDeviceById = async (id: DeviceId) => {
|
export const getDeviceById = async (id: DeviceId) => {
|
||||||
const { session } = await getUserAuth();
|
const { session } = await getUserAuth();
|
||||||
const { id: deviceId } = deviceIdSchema.parse({ id });
|
const { id: deviceId } = deviceIdSchema.parse({ id });
|
||||||
const [d] = await db.select().from(devices).where(and(eq(devices.id, deviceId), eq(devices.userId, session?.user.id!))).leftJoin(children, eq(devices.childId, children.id));
|
const [d] = await db
|
||||||
|
.select()
|
||||||
|
.from(devices)
|
||||||
|
.where(and(eq(devices.id, deviceId), eq(devices.userId, session?.user.id!)))
|
||||||
|
// .leftJoin(children, eq(devices.childId, children.id));
|
||||||
return { device: d };
|
return { device: d };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,24 @@
|
|||||||
import { db } from "@/server/db/index";
|
import { db } from "@/server/db/index";
|
||||||
import { and, eq } from "drizzle-orm";
|
import { and, eq } from "drizzle-orm";
|
||||||
import {
|
import {
|
||||||
PingId,
|
type PingId,
|
||||||
NewPingParams,
|
type NewPingParams,
|
||||||
UpdatePingParams,
|
type UpdatePingParams,
|
||||||
updatePingSchema,
|
updatePingSchema,
|
||||||
insertPingSchema,
|
insertPingSchema,
|
||||||
pings,
|
pings,
|
||||||
pingIdSchema
|
pingIdSchema,
|
||||||
} from "@/server/db/schema/pings";
|
} from "@/server/db/schema/pings";
|
||||||
import { getUserAuth } from "@/lib/auth/utils";
|
import { getUserAuth } from "@/lib/auth/utils";
|
||||||
|
|
||||||
export const createPing = async (ping: NewPingParams) => {
|
export const createPing = async (ping: NewPingParams) => {
|
||||||
const { session } = await getUserAuth();
|
const { session } = await getUserAuth();
|
||||||
const newPing = insertPingSchema.parse({ ...ping, userId: session?.user.id! });
|
const newPing = insertPingSchema.parse({
|
||||||
|
...ping,
|
||||||
|
userId: session?.user.id!,
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
const [p] = await db.insert(pings).values(newPing).returning();
|
const [p] = await db.insert(pings).values(newPing).returning();
|
||||||
return { ping: p };
|
return { ping: p };
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const message = (err as Error).message ?? "Error, please try again";
|
const message = (err as Error).message ?? "Error, please try again";
|
||||||
@@ -27,13 +30,16 @@ export const createPing = async (ping: NewPingParams) => {
|
|||||||
export const updatePing = async (id: PingId, ping: UpdatePingParams) => {
|
export const updatePing = async (id: PingId, ping: UpdatePingParams) => {
|
||||||
const { session } = await getUserAuth();
|
const { session } = await getUserAuth();
|
||||||
const { id: pingId } = pingIdSchema.parse({ id });
|
const { id: pingId } = pingIdSchema.parse({ id });
|
||||||
const newPing = updatePingSchema.parse({ ...ping, userId: session?.user.id! });
|
const newPing = updatePingSchema.parse({
|
||||||
|
...ping,
|
||||||
|
userId: session?.user.id!,
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
const [p] = await db
|
const [p] = await db
|
||||||
.update(pings)
|
.update(pings)
|
||||||
.set(newPing)
|
.set(newPing)
|
||||||
.where(and(eq(pings.id, pingId!), eq(pings.userId, session?.user.id!)))
|
.where(and(eq(pings.id, pingId), eq(pings.userId, session?.user.id!)))
|
||||||
.returning();
|
.returning();
|
||||||
return { ping: p };
|
return { ping: p };
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const message = (err as Error).message ?? "Error, please try again";
|
const message = (err as Error).message ?? "Error, please try again";
|
||||||
@@ -46,8 +52,10 @@ export const deletePing = async (id: PingId) => {
|
|||||||
const { session } = await getUserAuth();
|
const { session } = await getUserAuth();
|
||||||
const { id: pingId } = pingIdSchema.parse({ id });
|
const { id: pingId } = pingIdSchema.parse({ id });
|
||||||
try {
|
try {
|
||||||
const [p] = await db.delete(pings).where(and(eq(pings.id, pingId!), eq(pings.userId, session?.user.id!)))
|
const [p] = await db
|
||||||
.returning();
|
.delete(pings)
|
||||||
|
.where(and(eq(pings.id, pingId), eq(pings.userId, session?.user.id!)))
|
||||||
|
.returning();
|
||||||
return { ping: p };
|
return { ping: p };
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const message = (err as Error).message ?? "Error, please try again";
|
const message = (err as Error).message ?? "Error, please try again";
|
||||||
@@ -55,4 +63,3 @@ export const deletePing = async (id: PingId) => {
|
|||||||
throw { error: message };
|
throw { error: message };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
10
src/lib/api/responses.ts
Normal file
10
src/lib/api/responses.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { StatusCodes } from "http-status-codes";
|
||||||
|
|
||||||
|
export const notAuthorised = () =>
|
||||||
|
new Response("Not authorised", {
|
||||||
|
status: StatusCodes.BAD_REQUEST,
|
||||||
|
});
|
||||||
|
export const badRequest = (message: string) =>
|
||||||
|
new Response(message, {
|
||||||
|
status: StatusCodes.BAD_REQUEST,
|
||||||
|
});
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
import { db } from "@/server/db";
|
import { db } from "@/server/db";
|
||||||
import { StatusCodes } from "http-status-codes";
|
import { StatusCodes } from "http-status-codes";
|
||||||
import { ping } from "@/server/db/schema";
|
|
||||||
import { type NextApiResponseServerIo } from "@/lib/models/types/next-api-response-socket";
|
import { type NextApiResponseServerIo } from "@/lib/models/types/next-api-response-socket";
|
||||||
import { badRequest, notAuthorised } from "@/app/api/responses";
|
|
||||||
import { type NextApiRequest } from "next";
|
import { type NextApiRequest } from "next";
|
||||||
import type LocationUpdate from "@/lib/models/location-update";
|
import type LocationUpdate from "@/lib/models/location-update";
|
||||||
|
import { badRequest, notAuthorised } from "@/lib/api/responses";
|
||||||
|
import { getDeviceById } from "@/lib/api/devices/queries";
|
||||||
|
import { getChildById } from "@/lib/api/children/queries";
|
||||||
|
import { createPing } from "@/lib/api/pings/mutations";
|
||||||
|
|
||||||
type PingRequest = {
|
type PingRequest = {
|
||||||
coordinates: {
|
coordinates: {
|
||||||
@@ -27,26 +29,12 @@ export default async function POST(
|
|||||||
return notAuthorised();
|
return notAuthorised();
|
||||||
}
|
}
|
||||||
|
|
||||||
const device = await db.query.device.findFirst({
|
const device = (await getDeviceById(deviceId)).device;
|
||||||
where: (device, { and, eq }) =>
|
|
||||||
and(eq(device.deviceId, deviceId), eq(device.apiKey, apiKey)),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!device) {
|
if (!device) {
|
||||||
return notAuthorised();
|
return notAuthorised();
|
||||||
}
|
}
|
||||||
|
|
||||||
const child = await db.query.child.findFirst({
|
|
||||||
where: (child, { eq }) => eq(child.id, device.childId),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!child) {
|
|
||||||
return notAuthorised();
|
|
||||||
}
|
|
||||||
const user = await db.query.users.findFirst({
|
|
||||||
where: (user, { eq }) => eq(user.id, child.parentId),
|
|
||||||
});
|
|
||||||
|
|
||||||
const { coordinates } = req.body as PingRequest;
|
const { coordinates } = req.body as PingRequest;
|
||||||
|
|
||||||
// Check if coordinates exist in the headers
|
// Check if coordinates exist in the headers
|
||||||
@@ -54,23 +42,14 @@ export default async function POST(
|
|||||||
return badRequest("Invalid coordinates");
|
return badRequest("Invalid coordinates");
|
||||||
}
|
}
|
||||||
|
|
||||||
const location = await db.insert(ping).values({
|
const location = await createPing({
|
||||||
deviceId: device.id,
|
deviceId: device.id,
|
||||||
latitude: coordinates.latitude,
|
latitude: coordinates.latitude,
|
||||||
longitude: coordinates.longitude,
|
longitude: coordinates.longitude,
|
||||||
timestamp: new Date(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const update: LocationUpdate = {
|
console.log("ping-route", `ping:${device.id}`, location);
|
||||||
childId: child.id,
|
res?.socket?.server?.io?.emit(`ping:${device.id}`, location);
|
||||||
location: {
|
|
||||||
latitude: coordinates.latitude,
|
|
||||||
longitude: coordinates.longitude,
|
|
||||||
},
|
|
||||||
date: new Date(),
|
|
||||||
};
|
|
||||||
console.log("ping-route", `ping:${device.id}`, update);
|
|
||||||
res?.socket?.server?.io?.emit(`ping:${device.id}`, update);
|
|
||||||
// Send a response
|
// Send a response
|
||||||
return res.json({});
|
return res.json(location);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const pings = pgTable("pings", {
|
|||||||
.$defaultFn(() => randomUUID()),
|
.$defaultFn(() => randomUUID()),
|
||||||
latitude: real("latitude").notNull(),
|
latitude: real("latitude").notNull(),
|
||||||
longitude: real("longitude").notNull(),
|
longitude: real("longitude").notNull(),
|
||||||
timestamp: timestamp("timestamp").notNull(),
|
timestamp: timestamp("timestamp").notNull().defaultNow(),
|
||||||
deviceId: varchar("device_id", { length: 256 })
|
deviceId: varchar("device_id", { length: 256 })
|
||||||
.references(() => devices.id, { onDelete: "cascade" })
|
.references(() => devices.id, { onDelete: "cascade" })
|
||||||
.notNull(),
|
.notNull(),
|
||||||
@@ -34,11 +34,11 @@ export const insertPingSchema = createInsertSchema(pings);
|
|||||||
export const insertPingParams = createSelectSchema(pings, {
|
export const insertPingParams = createSelectSchema(pings, {
|
||||||
latitude: z.coerce.number(),
|
latitude: z.coerce.number(),
|
||||||
longitude: z.coerce.number(),
|
longitude: z.coerce.number(),
|
||||||
timestamp: z.coerce.string().min(1),
|
|
||||||
deviceId: z.coerce.string().min(1),
|
deviceId: z.coerce.string().min(1),
|
||||||
}).omit({
|
}).omit({
|
||||||
id: true,
|
id: true,
|
||||||
userId: true,
|
userId: true,
|
||||||
|
timestamp: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const updatePingSchema = createSelectSchema(pings);
|
export const updatePingSchema = createSelectSchema(pings);
|
||||||
@@ -46,10 +46,10 @@ export const updatePingSchema = createSelectSchema(pings);
|
|||||||
export const updatePingParams = createSelectSchema(pings, {
|
export const updatePingParams = createSelectSchema(pings, {
|
||||||
latitude: z.coerce.number(),
|
latitude: z.coerce.number(),
|
||||||
longitude: z.coerce.number(),
|
longitude: z.coerce.number(),
|
||||||
timestamp: z.coerce.string().min(1),
|
|
||||||
deviceId: z.coerce.string().min(1),
|
deviceId: z.coerce.string().min(1),
|
||||||
}).omit({
|
}).omit({
|
||||||
userId: true,
|
userId: true,
|
||||||
|
timestamp: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const pingIdSchema = updatePingSchema.pick({ id: true });
|
export const pingIdSchema = updatePingSchema.pick({ id: true });
|
||||||
|
|||||||
Reference in New Issue
Block a user