style: run prettier
All checks were successful
TrafficCue Server CI / check (push) Successful in 54s
TrafficCue Server CD / build (push) Successful in 2m0s

This commit is contained in:
2025-09-27 19:47:41 +02:00
parent 4d8c3aef68
commit 30334d13d1
4 changed files with 79 additions and 62 deletions

View File

@ -23,7 +23,7 @@ export class Store extends BaseEntity {
@Column({ @Column({
type: "enum", type: "enum",
enum: STORE_TYPE enum: STORE_TYPE,
}) })
type: StoreType; type: StoreType;

View File

@ -396,9 +396,7 @@ if (process.env.STORES_ENABLED) {
} }
const user = await User.findOneBy( const user = await User.findOneBy(
c.req.param("user") c.req.param("user") ? { username: c.req.param("user") } : { id: uid },
? { username: c.req.param("user") }
: { id: uid }
); );
if (!user) { if (!user) {
return c.json({ error: "Invalid user ID" }, 400); return c.json({ error: "Invalid user ID" }, 400);

View File

@ -2,19 +2,20 @@ import z from "zod";
import { Store, type StoreType } from "./entities/Stores"; import { Store, type StoreType } from "./entities/Stores";
import type { User } from "./entities/User"; import type { User } from "./entities/User";
export const locationStore = z.object({ export const locationStore = z
.object({
lat: z.number().min(-90).max(90), lat: z.number().min(-90).max(90),
lng: z.number().min(-180).max(180), lng: z.number().min(-180).max(180),
name: z.string().min(1).max(100) name: z.string().min(1).max(100),
}).strict(); })
.strict();
export const vehicleStore = z.object({ export const vehicleStore = z
.object({
name: z.string().min(1).max(100), name: z.string().min(1).max(100),
legalMaxSpeed: z.number().min(0).max(300), legalMaxSpeed: z.number().min(0).max(300),
actualMaxSpeed: z.number().min(0).max(300), actualMaxSpeed: z.number().min(0).max(300),
type: z.enum([ type: z.enum(["car", "truck", "motorcycle", "bicycle", "motor_scooter"]),
"car", "truck", "motorcycle", "bicycle", "motor_scooter"
]),
weight: z.number().min(0).max(100000).optional(), weight: z.number().min(0).max(100000).optional(),
width: z.number().min(0).max(10).optional(), width: z.number().min(0).max(10).optional(),
axisLoad: z.number().min(0).max(100000).optional(), axisLoad: z.number().min(0).max(100000).optional(),
@ -22,21 +23,28 @@ export const vehicleStore = z.object({
length: z.number().min(0).max(100).optional(), length: z.number().min(0).max(100).optional(),
emissionClass: z.string().min(1).max(50), emissionClass: z.string().min(1).max(50),
fuelType: z.enum(["petrol", "diesel", "electric"]), fuelType: z.enum(["petrol", "diesel", "electric"]),
preferredFuel: z.string().min(1).max(50) preferredFuel: z.string().min(1).max(50),
}).strict(); })
.strict();
export const routeStore = z.object({ export const routeStore = z.object({
locations: z.array(z.object({ locations: z.array(
z.object({
lat: z.number().min(-90).max(90), lat: z.number().min(-90).max(90),
lon: z.number().min(-180).max(180) lon: z.number().min(-180).max(180),
})), }),
legs: z.array(z.object({ ),
legs: z.array(
z.object({
shape: z.string(), shape: z.string(),
maneuvers: z.array(z.object({ maneuvers: z.array(
type: z.number() z.object({
})) type: z.number(),
})) }),
}) ),
}),
),
});
export const storeTypes: Record<StoreType, z.ZodSchema> = { export const storeTypes: Record<StoreType, z.ZodSchema> = {
location: locationStore, location: locationStore,
@ -45,19 +53,27 @@ export const storeTypes: Record<StoreType, z.ZodSchema> = {
}; };
export const SyncPayload = z.object({ export const SyncPayload = z.object({
changes: z.array(z.object({ changes: z.array(
z.object({
id: z.uuid(), id: z.uuid(),
operation: z.enum(["create", "update", "delete"]), operation: z.enum(["create", "update", "delete"]),
data: z.string(), data: z.string(),
modified_at: z.string().refine(val => !isNaN(Date.parse(val)), { message: "Invalid date" }), modified_at: z
.string()
.refine((val) => !isNaN(Date.parse(val)), { message: "Invalid date" }),
type: z.enum(["location", "vehicle", "route"]), type: z.enum(["location", "vehicle", "route"]),
name: z.string().min(1).max(100) name: z.string().min(1).max(100),
})), }),
stores: z.array(z.object({ ),
stores: z.array(
z.object({
id: z.uuid(), id: z.uuid(),
modified_at: z.string().refine(val => !isNaN(Date.parse(val)), { message: "Invalid date" }) modified_at: z
})) .string()
}) .refine((val) => !isNaN(Date.parse(val)), { message: "Invalid date" }),
}),
),
});
export type SyncPayload = z.infer<typeof SyncPayload>; export type SyncPayload = z.infer<typeof SyncPayload>;
@ -77,7 +93,10 @@ export async function sync(payload: SyncPayload, user: User) {
const changes: Store[] = []; const changes: Store[] = [];
// Apply changes from client // Apply changes from client
for (const change of payload.changes) { for (const change of payload.changes) {
const store = await Store.findOne({ where: { id: change.id }, relations: { user: true } }); const store = await Store.findOne({
where: { id: change.id },
relations: { user: true },
});
if (!verifyStoreData(change.type, change.data)) { if (!verifyStoreData(change.type, change.data)) {
// Invalid data // Invalid data
if (store) changes.push(store); // Send back the store to the client to overwrite their changes if (store) changes.push(store); // Send back the store to the client to overwrite their changes
@ -109,7 +128,7 @@ export async function sync(payload: SyncPayload, user: User) {
// Find stores that are out of date on the client // Find stores that are out of date on the client
const allStores = await Store.findBy({ user: { id: user.id } }); // TODO: include friends' public stores, TODO: use SQL query to only get modified stores const allStores = await Store.findBy({ user: { id: user.id } }); // TODO: include friends' public stores, TODO: use SQL query to only get modified stores
for (const store of allStores) { for (const store of allStores) {
const clientStore = payload.stores.find(s => s.id === store.id); const clientStore = payload.stores.find((s) => s.id === store.id);
if (!clientStore || new Date(clientStore.modified_at) < store.modified_at) { if (!clientStore || new Date(clientStore.modified_at) < store.modified_at) {
changes.push(store); // Client doesn't have this store or it's out of date changes.push(store); // Client doesn't have this store or it's out of date
} }