feat: more work on stores
Some checks failed
TrafficCue Server CI / check (push) Failing after 56s
TrafficCue Server CD / build (push) Successful in 2m26s

This commit is contained in:
2025-09-26 20:08:40 +02:00
parent 8d2eb1d9da
commit c59df0bf6a
2 changed files with 18 additions and 2 deletions

View File

@ -65,5 +65,6 @@ You can run this yourself to host your own instance, or contribute to the offici
- `OIDC_JWKS_URL` (the JWKS/Certificate URL of your OIDC server) - `OIDC_JWKS_URL` (the JWKS/Certificate URL of your OIDC server)
- `REVIEWS_ENABLED` (optional, set to `true` to enable POI reviews by users, requires OIDC) - `REVIEWS_ENABLED` (optional, set to `true` to enable POI reviews by users, requires OIDC)
- `HAZARDS_ENABLED` (optional, set to `true` to enable hazard reporting by users, requires OIDC) - `HAZARDS_ENABLED` (optional, set to `true` to enable hazard reporting by users, requires OIDC)
- `STORES_ENALED` (optional, set to `true` to enable user stores, requires OIDC)
When configuring your OIDC server, make sure to enable Public Client and PCKE support. When configuring your OIDC server, make sure to enable Public Client and PCKE support.

View File

@ -49,7 +49,9 @@ export const SyncPayload = 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"]),
name: z.string().min(1).max(100)
})), })),
stores: z.array(z.object({ stores: z.array(z.object({
id: z.uuid(), id: z.uuid(),
@ -59,12 +61,25 @@ export const SyncPayload = z.object({
export type SyncPayload = z.infer<typeof SyncPayload>; export type SyncPayload = z.infer<typeof SyncPayload>;
// TODO: verify data
export async function sync(payload: SyncPayload, user: User) { 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.findOneBy({ id: change.id }); const store = await Store.findOneBy({ id: change.id });
if(!store) continue; if(!store) {
// Store doesn't exist, create it
const newStore = new Store();
newStore.id = change.id;
newStore.user = user;
newStore.data = change.data;
newStore.modified_at = new Date(change.modified_at);
newStore.created_at = new Date();
newStore.type = change.type;
newStore.name = change.name;
await newStore.save();
continue;
}
if(store.user.id !== user.id) { if(store.user.id !== user.id) {
// Not the owner of this store // Not the owner of this store
changes.push(store); // Send back the store to the client to overwrite their changes changes.push(store); // Send back the store to the client to overwrite their changes