From 792911e3b5373702a64ae071d839cca0d014b89f Mon Sep 17 00:00:00 2001 From: RikoAppDev Date: Tue, 9 Apr 2024 17:00:33 +0200 Subject: [PATCH 01/10] on map event location endpoint --- src/endpoints/events/onMap.ts | 30 ++++++++++++++++++++++++++++++ src/index.ts | 2 ++ 2 files changed, 32 insertions(+) create mode 100644 src/endpoints/events/onMap.ts diff --git a/src/endpoints/events/onMap.ts b/src/endpoints/events/onMap.ts new file mode 100644 index 0000000..7617d1c --- /dev/null +++ b/src/endpoints/events/onMap.ts @@ -0,0 +1,30 @@ +import { PrismaClient } from "@prisma/client"; +import { Request, Response } from "express"; +import { ThrowNotFound } from "../../errorResponses/notFound404"; +import { ThrowInternalServerError } from "../../errorResponses/internalServer500"; + +const prisma = new PrismaClient(); + +export const getOnMap = async (req: Request, res: Response) => { + try { + const eventsLocations = await prisma.event.findMany({ + select: { + id: true, + Location: { + select: { + locationLat: true, + locationLon: true + } + } + } + }); + + if (eventsLocations.length == 0) { + return ThrowNotFound(res); + } + + return res.status(200).send({ events: eventsLocations }); + } catch (error) { + return ThrowInternalServerError(res); + } +}; diff --git a/src/index.ts b/src/index.ts index 4e73585..a295366 100644 --- a/src/index.ts +++ b/src/index.ts @@ -30,6 +30,7 @@ import { signOffEvent } from "./endpoints/events/[eventId]/signOffEvent"; import { getEventWorkers } from "./endpoints/events/[eventId]/workers"; import { getAssignedCategories } from "./endpoints/events/categories"; import { endEvent } from "./endpoints/events/[eventId]/endEvent"; +import { getOnMap } from "./endpoints/events/onMap"; const prisma = new PrismaClient(); @@ -106,6 +107,7 @@ const runServer = () => { app.get("/events/active", getActiveEvent); app.get("/events/my", getMyEvents); app.get("/events/categories", getAssignedCategories); + app.get("/events/onMap", getOnMap); app.get("/events/:eventId", getEventDetail); app.delete("/events/:eventId", softDelEvent); From 9097e481a8881d93db0522fdc0aa5fdadda0c9b7 Mon Sep 17 00:00:00 2001 From: martinvanco Date: Tue, 9 Apr 2024 19:10:55 +0200 Subject: [PATCH 02/10] seeder update --- prisma/seed.ts | 35 ++++++++++++++++++++++++++++------- src/.DS_Store | Bin 0 -> 6148 bytes 2 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 src/.DS_Store diff --git a/prisma/seed.ts b/prisma/seed.ts index 93b2160..d38bfa3 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -98,6 +98,21 @@ function slugify(title: string) { .toLowerCase(); // Convert to lowercase } +function generateNearbyCoordinate( + centerLat: number, + centerLon: number, + radius = 0.01 +) { + return { + latitude: + centerLat + + faker.number.float() * radius * (faker.datatype.boolean() ? 1 : -1), + longitude: + centerLon + + faker.number.float() * radius * (faker.datatype.boolean() ? 1 : -1) + }; +} + async function main() { const fruitsAndVegetablesEmojis: { emoji: string; @@ -160,13 +175,19 @@ async function main() { await prisma.location.createMany({ data: Array(15) .fill("") - .map((_, i) => ({ - name: faker.company.name(), - address: faker.location.streetAddress(), - city: faker.location.city(), - locationLat: faker.location.latitude({ max: 180, min: -180 }), - locationLon: faker.location.longitude({ max: 180, min: -180 }) - })) + .map((_, i) => { + const { latitude, longitude } = generateNearbyCoordinate( + 48.934328, + 18.160032 + ); + return { + name: faker.company.name(), + address: faker.location.streetAddress(), + city: faker.location.city(), + locationLat: latitude, + locationLon: longitude + }; + }) }); const locations = await prisma.location.findMany({ select: { id: true } }); diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..cea041ccfed74c7b4779cdfbc9fda5c9e0265e17 GIT binary patch literal 6148 zcmeHK%SyyR5UkccL=@Sh7h%32;2*?gJ?vF~K-Y*UArV*6WA1*8pQzQ{qikZ%BGMgt zs%NHaCMn1~0LbFGJ^|(c3c8|bFk#v}*|n3CXGF0vI^3bf6E>@6VxYg+r0>3m8@_do z2W-86cfD@9HG5T>cY66@#t1kh@eH7pbe1ww&PAQYHTfP1!DvF{jVC=d#S0^bVg`jF^~ zRmR@YmJSwn1t97%+KjOtn3a<}fS_KrG=wi}%o2LTf#icsJe6!-+(fkr$4 literal 0 HcmV?d00001 From ce868d73230762f6388b2786e05446fcae217fc5 Mon Sep 17 00:00:00 2001 From: martinvanco Date: Wed, 10 Apr 2024 10:27:09 +0200 Subject: [PATCH 03/10] code fixing --- prisma/dbml/schema.dbml | 1 - .../migration.sql | 8 +++++++ prisma/schema.prisma | 23 +++++++++---------- prisma/seed.ts | 2 +- .../events/[eventId]/signForEvent.ts | 7 +++++- src/endpoints/events/my.ts | 15 ++++++++---- 6 files changed, 36 insertions(+), 20 deletions(-) create mode 100644 prisma/migrations/20240410082629_removed_virification_token_field/migration.sql diff --git a/prisma/dbml/schema.dbml b/prisma/dbml/schema.dbml index 2e265e6..6681448 100644 --- a/prisma/dbml/schema.dbml +++ b/prisma/dbml/schema.dbml @@ -8,7 +8,6 @@ Table User { createdAt DateTime [default: `now()`, not null] password String [not null] name String [not null] - verificationToken String phoneNumber String type AccountType avatarURL String diff --git a/prisma/migrations/20240410082629_removed_virification_token_field/migration.sql b/prisma/migrations/20240410082629_removed_virification_token_field/migration.sql new file mode 100644 index 0000000..2335fc5 --- /dev/null +++ b/prisma/migrations/20240410082629_removed_virification_token_field/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - You are about to drop the column `verificationToken` on the `User` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "User" DROP COLUMN "verificationToken"; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 40a0149..b2c5011 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -56,18 +56,17 @@ enum ColorVariant { } model User { - id String @id @default(cuid()) - email String @unique - createdAt DateTime @default(now()) - password String - name String - verificationToken String? - phoneNumber String? - type AccountType? - avatarURL String? - EventAssignment EventAssignment[] - AnnouncementItem AnnouncementItem[] - Event Event[] + id String @id @default(cuid()) + email String @unique + createdAt DateTime @default(now()) + password String + name String + phoneNumber String? + type AccountType? + avatarURL String? + EventAssignment EventAssignment[] + AnnouncementItem AnnouncementItem[] + Event Event[] } model Location { diff --git a/prisma/seed.ts b/prisma/seed.ts index d38bfa3..5ad84b6 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -101,7 +101,7 @@ function slugify(title: string) { function generateNearbyCoordinate( centerLat: number, centerLon: number, - radius = 0.01 + radius = 0.1 ) { return { latitude: diff --git a/src/endpoints/events/[eventId]/signForEvent.ts b/src/endpoints/events/[eventId]/signForEvent.ts index 331491e..80e6fbd 100644 --- a/src/endpoints/events/[eventId]/signForEvent.ts +++ b/src/endpoints/events/[eventId]/signForEvent.ts @@ -65,7 +65,12 @@ export const signForEvent = async (req: Request, res: Response) => { } }, where: { - id: eventId + id: eventId, + EventAssignment: { + every: { + assignmentStatus: EventAssignmentStatus.ACTIVE + } + } } }); diff --git a/src/endpoints/events/my.ts b/src/endpoints/events/my.ts index 1995a5b..754e141 100644 --- a/src/endpoints/events/my.ts +++ b/src/endpoints/events/my.ts @@ -1,4 +1,8 @@ -import { AccountType, PrismaClient } from "@prisma/client"; +import { + AccountType, + EventAssignmentStatus, + PrismaClient +} from "@prisma/client"; import { Request, Response } from "express"; import { ThrowNotFound } from "../../errorResponses/notFound404"; import { ThrowInternalServerError } from "../../errorResponses/internalServer500"; @@ -48,7 +52,8 @@ export const getMyEvents = async (req: Request, res: Response) => { : { EventAssignment: { some: { - userId: userData.id + userId: userData.id, + assignmentStatus: EventAssignmentStatus.ACTIVE } } }) @@ -66,9 +71,9 @@ export const getMyEvents = async (req: Request, res: Response) => { ] }); - if (events.length == 0) { - return ThrowNotFound(res); - } + // if (events.length == 0) { + // return ThrowNotFound(res); + // } return res.status(200).send({ events: events }); } catch (error) { From 87afe36aaf6e3d1daa22b3449405290896ba1ddb Mon Sep 17 00:00:00 2001 From: RikoAppDev Date: Wed, 10 Apr 2024 16:01:18 +0200 Subject: [PATCH 04/10] seed organizer to harvester change --- prisma/seed.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prisma/seed.ts b/prisma/seed.ts index 5ad84b6..febcd74 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -214,7 +214,7 @@ async function main() { { length: faker.number.int({ min: 0, max: event.capacity }) }, async () => prisma.user.create({ - data: getRandomUser("ORGANISER", 1)[0], + data: getRandomUser("HARVESTER", 1)[0], select: { id: true } }) ); @@ -269,7 +269,7 @@ async function main() { }); const workerId = await prisma.user.create({ - data: getRandomUser("ORGANISER", 1, "worker1@grabit.sk")[0], + data: getRandomUser("HARVESTER", 1, "worker1@grabit.sk")[0], select: { id: true } From 02059117787d7cc22d5bf4fb2c068385d3d9b2bd Mon Sep 17 00:00:00 2001 From: RikoAppDev Date: Thu, 11 Apr 2024 00:05:53 +0200 Subject: [PATCH 05/10] update attendance endpoint --- @types/event.ts | 9 +- .../events/[eventId]/updateAttendance.ts | 125 ++++++++++++++++++ src/index.ts | 2 + 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 src/endpoints/events/[eventId]/updateAttendance.ts diff --git a/@types/event.ts b/@types/event.ts index d63e7da..d0702b5 100644 --- a/@types/event.ts +++ b/@types/event.ts @@ -1,4 +1,4 @@ -import { HarmonogramItem, SallaryType } from "@prisma/client"; +import { EventPresenceStatus, SallaryType } from "@prisma/client"; /** * Request @@ -54,3 +54,10 @@ export interface CreateHarmonogramItemData { from: string; to: string; } + +export interface AttendanceItemData { + userID: string; + presenceStatus: EventPresenceStatus; + arrivedAt: string; + leftAt: string; +} diff --git a/src/endpoints/events/[eventId]/updateAttendance.ts b/src/endpoints/events/[eventId]/updateAttendance.ts new file mode 100644 index 0000000..41381da --- /dev/null +++ b/src/endpoints/events/[eventId]/updateAttendance.ts @@ -0,0 +1,125 @@ +import { EventPresenceStatus, EventStatus, PrismaClient } from "@prisma/client"; +import { Request, Response } from "express"; +import { ThrowInternalServerError } from "../../../errorResponses/internalServer500"; +import { ThrowNotFound } from "../../../errorResponses/notFound404"; +import { ThrowForbidden } from "../../../errorResponses/forbidden403"; +import { AttendanceItemData } from "../../../../@types/event"; +import * as Yup from "yup"; +import { ThrowBadRequest } from "../../../errorResponses/badRequest400"; +import { UserDecodedData } from "../../../../@types/jwtToken"; + +const prisma = new PrismaClient(); + +function validateAttendance(workers: Array) { + for (const worker of workers) { + if (worker.presenceStatus === "PRESENT") { + if (!worker.arrivedAt) { + return false; + } + if (worker.leftAt) { + return false; + } + } else if (worker.presenceStatus === "LEFT") { + if (!worker.arrivedAt || !worker.leftAt) { + return false; + } + if (Date.parse(worker.arrivedAt) > Date.parse(worker.leftAt)) { + return false; + } + } + } + return true; +} + +export const eventUpdateAttendance = async (req: Request, res: Response) => { + const { eventId } = req.params; + const userData = req.user as UserDecodedData; + const data = req.body as { workers: Array }; + + if (userData.role !== "ORGANISER") { + return ThrowForbidden(res); + } + + const validationSchema = Yup.object>({ + userID: Yup.string().required(), + presenceStatus: Yup.string() + .oneOf([ + EventPresenceStatus.DID_NOT_ARRIVE, + EventPresenceStatus.LEFT, + EventPresenceStatus.NOT_PRESENT, + EventPresenceStatus.PRESENT + ]) + .required(), + arrivedAt: Yup.string(), + leftAt: Yup.string() + }); + + try { + data.workers.map((worker) => { + validationSchema.validateSync(worker, { + abortEarly: false + }); + }); + } catch (error) { + return ThrowBadRequest(res); + } + + if (!validateAttendance(data.workers)) { + return ThrowBadRequest(res); + } + + try { + const event = await prisma.event.findUnique({ + where: { + id: eventId, + status: EventStatus.PROGRESS + } + }); + + if (!event) { + return ThrowNotFound(res); + } + + const assignments = await prisma.eventAssignment.findMany({ + where: { + eventId: eventId, + event: { + status: EventStatus.PROGRESS + } + } + }); + + if (assignments.length == 0) { + await prisma.eventAssignment.createMany({ + data: data.workers.map((worker) => ({ + eventId: eventId, + userId: worker.userID, + arrivedAt: worker.arrivedAt, + leftAt: worker.leftAt, + presenceStatus: worker.presenceStatus + })) + }); + } else { + data.workers.map(async (worker) => { + await prisma.eventAssignment.updateMany({ + where: { + userId: worker.userID, + eventId: eventId, + event: { + status: EventStatus.PROGRESS + } + }, + data: { + arrivedAt: worker.arrivedAt, + leftAt: worker.leftAt, + presenceStatus: worker.presenceStatus + } + }); + }); + } + + return res.status(200).json(); + } catch (error) { + return ThrowInternalServerError(res); + } +}; diff --git a/src/index.ts b/src/index.ts index 24faae1..f430eca 100644 --- a/src/index.ts +++ b/src/index.ts @@ -34,6 +34,7 @@ import { getEventWorkers } from "./endpoints/events/[eventId]/workers"; import { getAssignedCategories } from "./endpoints/events/categories"; import { endEvent } from "./endpoints/events/[eventId]/endEvent"; import { getOnMap } from "./endpoints/events/onMap"; +import { eventUpdateAttendance } from "./endpoints/events/[eventId]/updateAttendance"; const prisma = new PrismaClient(); @@ -132,6 +133,7 @@ const runServer = () => { app.post("/events/:eventId/endEvent", endEvent); app.get("/events/:eventId/attendance", eventWorkersAttendance); + app.put("/events/:eventId/updateAttendance", eventUpdateAttendance); app.post("/events/:eventId/signFor", signForEvent); app.post("/events/:eventId/signOff", signOffEvent); From f03371783e22244d52512187957e9f3270c3b6bc Mon Sep 17 00:00:00 2001 From: martinvanco Date: Thu, 11 Apr 2024 01:46:11 +0200 Subject: [PATCH 06/10] update seeder, end event stats calculation --- prisma/dbml/schema.dbml | 1 + .../migration.sql | 2 + prisma/schema.prisma | 1 + prisma/seed.ts | 79 ++++++++++++++++--- src/endpoints/events/[eventId]/endEvent.ts | 42 +++++++++- src/endpoints/events/[eventId]/uploadImage.ts | 2 - src/index.ts | 6 +- 7 files changed, 113 insertions(+), 20 deletions(-) create mode 100644 prisma/migrations/20240410230439_working_hours_sum_field/migration.sql diff --git a/prisma/dbml/schema.dbml b/prisma/dbml/schema.dbml index 6681448..5c3d9cf 100644 --- a/prisma/dbml/schema.dbml +++ b/prisma/dbml/schema.dbml @@ -65,6 +65,7 @@ Table EventAssignment { arrivedAt DateTime leftAt DateTime presenceStatus EventPresenceStatus [not null, default: 'NOT_PRESENT'] + hoursWorked Int } Table EventCategory { diff --git a/prisma/migrations/20240410230439_working_hours_sum_field/migration.sql b/prisma/migrations/20240410230439_working_hours_sum_field/migration.sql new file mode 100644 index 0000000..1a6a9ac --- /dev/null +++ b/prisma/migrations/20240410230439_working_hours_sum_field/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "EventAssignment" ADD COLUMN "hoursWorked" INTEGER; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index b2c5011..d7d9608 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -120,6 +120,7 @@ model EventAssignment { arrivedAt DateTime? leftAt DateTime? presenceStatus EventPresenceStatus @default(NOT_PRESENT) + hoursWorked Int? } model EventCategory { diff --git a/prisma/seed.ts b/prisma/seed.ts index febcd74..da57955 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -2,6 +2,8 @@ import { AccountType, ColorVariant, Event, + EventAssignmentStatus, + EventPresenceStatus, EventStatus, PrismaClient, SallaryType, @@ -30,11 +32,17 @@ const getRandomimage = () => max: 1000 })}/1280/720`; -const getRandomUser = (type: AccountType, n: number, email?: string) => { +const getRandomUser = ( + type: AccountType, + n: number, + email?: string, + id?: string +) => { return Array(n) .fill("") .map((_, i) => { return { + id: id ? id : undefined, email: email ? email : faker.internet.email(), name: faker.person.fullName(), phoneNumber: faker.phone.number(), @@ -45,15 +53,18 @@ const getRandomUser = (type: AccountType, n: number, email?: string) => { }); }; -const getRandomEventData = () => { +const getRandomEventData = (capacity?: number, id?: string) => { const sallaryType = faker.datatype.boolean() ? SallaryType.GOODS : SallaryType.MONEY; const ret = { - capacity: faker.number.int({ min: 5, max: 10 }), + id: id ? id : undefined, + capacity: capacity ? capacity : faker.number.int({ min: 5, max: 10 }), description: faker.commerce.productDescription(), - happeningAt: faker.date.future(), + happeningAt: moment(faker.date.soon()) + .set("hour", faker.number.int({ min: 6, max: 10 })) + .toDate(), name: faker.commerce.productName(), sallaryType: sallaryType, sallaryAmount: @@ -165,9 +176,9 @@ async function main() { await prisma.user.createMany({ data: [ - ...getRandomUser("ORGANISER", 1, "admin1@grabit.sk"), - ...getRandomUser("ORGANISER", 1, "admin2@grabit.sk"), - ...getRandomUser("ORGANISER", 1, "admin3@grabit.sk") + ...getRandomUser("ORGANISER", 1, "admin1@grabit.sk", "admin1"), + ...getRandomUser("ORGANISER", 1, "admin2@grabit.sk", "admin2"), + ...getRandomUser("ORGANISER", 1, "admin3@grabit.sk", "admin3") ] }); const adminUsers = await prisma.user.findMany({ select: { id: true } }); @@ -269,7 +280,12 @@ async function main() { }); const workerId = await prisma.user.create({ - data: getRandomUser("HARVESTER", 1, "worker1@grabit.sk")[0], + data: getRandomUser( + "HARVESTER", + 1, + "worker1@grabit.sk", + "harvester1" + )[0], select: { id: true } @@ -279,7 +295,11 @@ async function main() { data: { userId: adminUsers[0].id, locationId: locations[0].id, - ...{ ...getRandomEventData(), status: "PROGRESS" } + ...{ + ...getRandomEventData(15, "liveEventId"), + status: "PROGRESS", + happeningAt: moment().set("hours", 7).toDate() + } }, select: { id: true, @@ -299,7 +319,7 @@ async function main() { const userIds = await Promise.all(userPromises); - await Promise.all( + const assignments = await Promise.all( userIds.map((user) => prisma.eventAssignment.create({ data: { @@ -317,6 +337,45 @@ async function main() { } }); + await Promise.all( + assignments.map((assignment) => { + const statusChangeTo = faker.helpers.arrayElement([ + EventPresenceStatus.PRESENT, + EventPresenceStatus.LEFT, + EventPresenceStatus.DID_NOT_ARRIVE + ]); + + const arrivedAt = [ + EventPresenceStatus.PRESENT.toString(), + EventPresenceStatus.LEFT.toString() + ].includes(statusChangeTo) + ? moment(liveEvent.happeningAt) + .add(faker.number.int({ min: 2, max: 45 }), "minutes") + .toDate() + : undefined; + + const leftAt = [EventPresenceStatus.LEFT.toString()].includes( + statusChangeTo + ) + ? moment(arrivedAt) + .add(faker.number.int({ min: 2, max: 12 }), "hours") + .add(faker.number.int({ min: 2, max: 45 }), "minutes") + .toDate() + : undefined; + + return prisma.eventAssignment.update({ + data: { + presenceStatus: statusChangeTo, + arrivedAt: arrivedAt, + leftAt: leftAt + }, + where: { + id: assignment.id + } + }); + }) + ); + await Promise.all( Array(5) .fill("") diff --git a/src/endpoints/events/[eventId]/endEvent.ts b/src/endpoints/events/[eventId]/endEvent.ts index 20b7eb6..a5bee63 100644 --- a/src/endpoints/events/[eventId]/endEvent.ts +++ b/src/endpoints/events/[eventId]/endEvent.ts @@ -1,5 +1,6 @@ import { AccountType, + EventAssignmentStatus, EventPresenceStatus, EventStatus, PrismaClient @@ -9,6 +10,7 @@ import { ThrowInternalServerError } from "../../../errorResponses/internalServer import { ThrowNotFound } from "../../../errorResponses/notFound404"; import { UserDecodedData } from "../../../../@types/jwtToken"; import { ThrowForbidden } from "../../../errorResponses/forbidden403"; +import moment from "moment"; const prisma = new PrismaClient(); @@ -33,9 +35,20 @@ export const endEvent = async (req: Request, res: Response) => { return ThrowNotFound(res); } + const qwe = await prisma.eventAssignment.findMany({ + where: { + eventId: eventId, + presenceStatus: { + in: [EventPresenceStatus.LEFT] + } + } + }); + await prisma.eventAssignment.updateMany({ where: { - eventId: eventId + eventId: eventId, + presenceStatus: EventPresenceStatus.PRESENT, + assignmentStatus: EventAssignmentStatus.ACTIVE }, data: { presenceStatus: EventPresenceStatus.LEFT, @@ -43,6 +56,31 @@ export const endEvent = async (req: Request, res: Response) => { } }); + const assignmentIds = await prisma.eventAssignment.findMany({ + where: { + presenceStatus: EventPresenceStatus.LEFT, + assignmentStatus: EventAssignmentStatus.ACTIVE + } + }); + + await Promise.all( + assignmentIds.map((assignment) => { + const hours_worked = + moment(assignment.leftAt).diff( + moment(assignment.arrivedAt), + "hours" + ) + 1; + prisma.eventAssignment.update({ + where: { + id: assignment.id + }, + data: { + hoursWorked: hours_worked > 0 ? hours_worked : 0 + } + }); + }) + ); + await prisma.event.update({ where: { id: eventId @@ -52,8 +90,6 @@ export const endEvent = async (req: Request, res: Response) => { } }); - // TODO: calculate insights for the company about sallary for each worker - return res.status(200).send(); } catch (error) { return ThrowInternalServerError(res); diff --git a/src/endpoints/events/[eventId]/uploadImage.ts b/src/endpoints/events/[eventId]/uploadImage.ts index 0cea240..143c2b8 100644 --- a/src/endpoints/events/[eventId]/uploadImage.ts +++ b/src/endpoints/events/[eventId]/uploadImage.ts @@ -10,8 +10,6 @@ import { ThrowBadRequest } from "../../../errorResponses/badRequest400"; const prisma = new PrismaClient(); export const uploadEventImage = async (req: Request, res: Response) => { - const { eventId } = req.params; - const storage = new Storage({ projectId: "mtaa-2024", keyFilename: "google-cloud-key.json" diff --git a/src/index.ts b/src/index.ts index f430eca..821023f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -116,11 +116,7 @@ const runServer = () => { app.get("/events/:eventId", getEventDetail); - app.post( - "/events/:eventId/uploadImage", - multer().single("image"), - uploadEventImage - ); + app.post("/events/uploadImage", multer().single("image"), uploadEventImage); app.delete("/events/:eventId", softDelEvent); app.post("/events/create", createEvent); From 3838895f7b92928c6083115105942865c0d32e62 Mon Sep 17 00:00:00 2001 From: martinvanco Date: Thu, 11 Apr 2024 13:15:37 +0200 Subject: [PATCH 07/10] live data, reporting --- src/endpoints/events/[eventId]/endEvent.ts | 5 +- src/endpoints/events/[eventId]/live.ts | 71 +++++++++++++++++++ src/endpoints/events/[eventId]/reporting.ts | 78 +++++++++++++++++++++ src/index.ts | 29 ++++---- 4 files changed, 168 insertions(+), 15 deletions(-) create mode 100644 src/endpoints/events/[eventId]/live.ts create mode 100644 src/endpoints/events/[eventId]/reporting.ts diff --git a/src/endpoints/events/[eventId]/endEvent.ts b/src/endpoints/events/[eventId]/endEvent.ts index a5bee63..493647d 100644 --- a/src/endpoints/events/[eventId]/endEvent.ts +++ b/src/endpoints/events/[eventId]/endEvent.ts @@ -64,13 +64,14 @@ export const endEvent = async (req: Request, res: Response) => { }); await Promise.all( - assignmentIds.map((assignment) => { + assignmentIds.map(async (assignment) => { const hours_worked = moment(assignment.leftAt).diff( moment(assignment.arrivedAt), "hours" ) + 1; - prisma.eventAssignment.update({ + console.log(assignment, hours_worked); + await prisma.eventAssignment.update({ where: { id: assignment.id }, diff --git a/src/endpoints/events/[eventId]/live.ts b/src/endpoints/events/[eventId]/live.ts new file mode 100644 index 0000000..dcbaf63 --- /dev/null +++ b/src/endpoints/events/[eventId]/live.ts @@ -0,0 +1,71 @@ +import { + AccountType, + EventAssignmentStatus, + EventPresenceStatus, + EventStatus, + PrismaClient +} from "@prisma/client"; +import { Request, Response } from "express"; +import { ThrowInternalServerError } from "../../../errorResponses/internalServer500"; +import { ThrowNotFound } from "../../../errorResponses/notFound404"; +import { UserDecodedData } from "../../../../@types/jwtToken"; +import { ThrowForbidden } from "../../../errorResponses/forbidden403"; + +const prisma = new PrismaClient(); + +export const getLiveEventData = async (req: Request, res: Response) => { + const { eventId } = req.params; + const userData = req.user as UserDecodedData; + + try { + const event = await prisma.event.findUnique({ + where: { + id: eventId, + status: EventStatus.PROGRESS, + OR: [ + { + userId: userData.id // event created by user + }, + { + EventAssignment: { + some: { + userId: userData.id, + assignmentStatus: EventAssignmentStatus.ACTIVE, + presenceStatus: EventPresenceStatus.PRESENT + } + } + } + ] + } + }); + + if (!event) { + return ThrowNotFound(res); + } + + const harmonogramItems = await prisma.harmonogramItem.findMany({ + where: { + eventId: eventId + }, + orderBy: { + from: "asc" + } + }); + + const announcementItems = await prisma.announcementItem.findMany({ + where: { + eventId: eventId + }, + orderBy: { + createdAt: "asc" + } + }); + + return res.status(200).send({ + announcementItems, + harmonogramItems + }); + } catch (error) { + return ThrowInternalServerError(res); + } +}; diff --git a/src/endpoints/events/[eventId]/reporting.ts b/src/endpoints/events/[eventId]/reporting.ts new file mode 100644 index 0000000..5e1a062 --- /dev/null +++ b/src/endpoints/events/[eventId]/reporting.ts @@ -0,0 +1,78 @@ +import { + AccountType, + EventAssignmentStatus, + EventPresenceStatus, + EventStatus, + PrismaClient +} from "@prisma/client"; +import { Request, Response } from "express"; +import { ThrowInternalServerError } from "../../../errorResponses/internalServer500"; +import { ThrowNotFound } from "../../../errorResponses/notFound404"; +import { UserDecodedData } from "../../../../@types/jwtToken"; +import { ThrowForbidden } from "../../../errorResponses/forbidden403"; + +const prisma = new PrismaClient(); + +export const getEventReporting = async (req: Request, res: Response) => { + const { eventId } = req.params; + const userData = req.user as UserDecodedData; + + try { + const event = await prisma.event.findUnique({ + where: { + id: eventId, + status: EventStatus.ARCHIVED, + OR: [ + { + userId: userData.id // event created by user + }, + { + EventAssignment: { + some: { + userId: userData.id, + assignmentStatus: EventAssignmentStatus.ACTIVE, + presenceStatus: EventPresenceStatus.LEFT + } + } + } + ] + } + }); + + if (!event) { + return ThrowNotFound(res); + } + + const reporting = await prisma.eventAssignment.findMany({ + where: { + eventId: eventId, + event: { + status: EventStatus.ARCHIVED + }, + assignmentStatus: EventAssignmentStatus.ACTIVE, + presenceStatus: EventPresenceStatus.LEFT, + + ...(userData.role === AccountType.HARVESTER && { + userId: userData.id + }) + }, + select: { + arrivedAt: true, + leftAt: true, + hoursWorked: true, + user: { + select: { + id: true, + name: true + } + } + } + }); + + return res.status(200).send({ + reportingItems: reporting + }); + } catch (error) { + return ThrowInternalServerError(res); + } +}; diff --git a/src/index.ts b/src/index.ts index 821023f..ee6f4e7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,6 @@ import express, { NextFunction, Request, Response, json } from "express"; -import passport from "passport"; -import { Strategy as JwtStrategy, ExtractJwt } from "passport-jwt"; import "dotenv/config"; -import { AccountType, PrismaClient } from "@prisma/client"; -import md5 from "md5"; +import { PrismaClient } from "@prisma/client"; import jwt from "jsonwebtoken"; const morgan = require("morgan"); import { login } from "./endpoints/login"; @@ -35,6 +32,9 @@ import { getAssignedCategories } from "./endpoints/events/categories"; import { endEvent } from "./endpoints/events/[eventId]/endEvent"; import { getOnMap } from "./endpoints/events/onMap"; import { eventUpdateAttendance } from "./endpoints/events/[eventId]/updateAttendance"; +import { ThrowNotFound } from "./errorResponses/notFound404"; +import { getLiveEventData } from "./endpoints/events/[eventId]/live"; +import { getEventReporting } from "./endpoints/events/[eventId]/reporting"; const prisma = new PrismaClient(); @@ -94,11 +94,12 @@ const runServer = () => { app.use("/openapi", swaggerUi.serve, swaggerUi.setup(swaggerDocument)); app.use(morgan("dev")); - app.get("/hello", async (req, res) => { - const v = await prisma.$queryRawUnsafe("select version();"); - res.json({ response: v }); + app.get("/", async (req, res) => { + res.json({ response: "Hello World!" }); }); + app.get("/openapi", swaggerUi.setup(swaggerDocument)); + app.post("/login", login); app.post("/createAccount", createAccount); @@ -113,18 +114,14 @@ const runServer = () => { app.get("/events/my", getMyEvents); app.get("/events/categories", getAssignedCategories); app.get("/events/onMap", getOnMap); + app.post("/events/uploadImage", multer().single("image"), uploadEventImage); + app.post("/events/create", createEvent); app.get("/events/:eventId", getEventDetail); - - app.post("/events/uploadImage", multer().single("image"), uploadEventImage); app.delete("/events/:eventId", softDelEvent); - - app.post("/events/create", createEvent); app.put("/events/:eventId/update", updateEvent); - app.get("/events/:eventId/workers", getEventWorkers); - app.get("/openapi", swaggerUi.setup(swaggerDocument)); app.put("/events/:eventId/startEvent", startEvent); app.post("/events/:eventId/endEvent", endEvent); @@ -132,6 +129,12 @@ const runServer = () => { app.put("/events/:eventId/updateAttendance", eventUpdateAttendance); app.post("/events/:eventId/signFor", signForEvent); app.post("/events/:eventId/signOff", signOffEvent); + app.get("/events/:eventId/live", getLiveEventData); + app.get("/events/:eventId/reporting", getEventReporting); + + app.use((req, res, next) => { + return ThrowNotFound(res); + }); app.listen(PORT, () => { console.log(`App listening on http://localhost:${PORT}`); From 52bd1c802779ce840da4b230cd72808523d37e04 Mon Sep 17 00:00:00 2001 From: martinvanco Date: Thu, 11 Apr 2024 14:39:33 +0200 Subject: [PATCH 08/10] delete user --- prisma/dbml/schema.dbml | 1 + .../migration.sql | 2 ++ prisma/schema.prisma | 1 + src/endpoints/user/deleteAccount.ts | 35 +++++++++++++++++++ src/index.ts | 2 ++ 5 files changed, 41 insertions(+) create mode 100644 prisma/migrations/20240411123158_soft_delete_user/migration.sql create mode 100644 src/endpoints/user/deleteAccount.ts diff --git a/prisma/dbml/schema.dbml b/prisma/dbml/schema.dbml index 5c3d9cf..4ed5919 100644 --- a/prisma/dbml/schema.dbml +++ b/prisma/dbml/schema.dbml @@ -6,6 +6,7 @@ Table User { id String [pk] email String [unique, not null] createdAt DateTime [default: `now()`, not null] + deletedAt DateTime password String [not null] name String [not null] phoneNumber String diff --git a/prisma/migrations/20240411123158_soft_delete_user/migration.sql b/prisma/migrations/20240411123158_soft_delete_user/migration.sql new file mode 100644 index 0000000..52261bb --- /dev/null +++ b/prisma/migrations/20240411123158_soft_delete_user/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "deletedAt" TIMESTAMP(3); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index d7d9608..d27778d 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -59,6 +59,7 @@ model User { id String @id @default(cuid()) email String @unique createdAt DateTime @default(now()) + deletedAt DateTime? password String name String phoneNumber String? diff --git a/src/endpoints/user/deleteAccount.ts b/src/endpoints/user/deleteAccount.ts new file mode 100644 index 0000000..095c237 --- /dev/null +++ b/src/endpoints/user/deleteAccount.ts @@ -0,0 +1,35 @@ +import { PrismaClient } from "@prisma/client"; +import { Request, Response } from "express"; +import { ThrowBadRequest } from "../../errorResponses/badRequest400"; +import { UserDecodedData } from "../../../@types/jwtToken"; +import { ThrowInternalServerError } from "../../errorResponses/internalServer500"; +import { ThrowNotFound } from "../../errorResponses/notFound404"; + +const prisma = new PrismaClient(); + +export const deleteAccount = async (req: Request, res: Response) => { + const userData = req.user as UserDecodedData; + try { + const user = await prisma.user.update({ + where: { + id: userData.id + }, + data: { + avatarURL: "", + email: "unknown@grabit.sk", + name: "Unknown user", + phoneNumber: "unknown", + deletedAt: new Date() + } + }); + + if (!user) { + return ThrowNotFound(res); + } + } catch (error) { + console.log(error); + ThrowInternalServerError(res); + return; + } + res.status(200).send(); +}; diff --git a/src/index.ts b/src/index.ts index ee6f4e7..af5d284 100644 --- a/src/index.ts +++ b/src/index.ts @@ -35,6 +35,7 @@ import { eventUpdateAttendance } from "./endpoints/events/[eventId]/updateAttend import { ThrowNotFound } from "./errorResponses/notFound404"; import { getLiveEventData } from "./endpoints/events/[eventId]/live"; import { getEventReporting } from "./endpoints/events/[eventId]/reporting"; +import { deleteAccount } from "./endpoints/user/deleteAccount"; const prisma = new PrismaClient(); @@ -106,6 +107,7 @@ const runServer = () => { app.get("/user/", getUser); app.put("/user/editAccount", editAccount); app.get("/user/verifyToken", verifyToken); + app.delete("/user", deleteAccount); app.get("/events", getEvents); app.get("/events/latest", getLatestEvents); From f8c4ff8c2893535d8a4a13fc3af7c968f3ba20de Mon Sep 17 00:00:00 2001 From: martinvanco Date: Thu, 11 Apr 2024 14:44:25 +0200 Subject: [PATCH 09/10] disable login for deleted user --- src/endpoints/login.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/endpoints/login.ts b/src/endpoints/login.ts index 4545c5b..7576c21 100644 --- a/src/endpoints/login.ts +++ b/src/endpoints/login.ts @@ -20,7 +20,8 @@ export const login = async (req: Request, res: Response) => { try { const user = await prisma.user.findFirst({ where: { - email: email + email: email, + deletedAt: null }, select: { id: true, From b4c41244a96b70d9667290116021f7e359c96030 Mon Sep 17 00:00:00 2001 From: martinvanco Date: Thu, 11 Apr 2024 14:48:13 +0200 Subject: [PATCH 10/10] swagger update --- .DS_Store | Bin 0 -> 6148 bytes src/swagger.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5172429f264de2441865cb4700216d4256da9242 GIT binary patch literal 6148 zcmeH~J!%6%427R!7lt%jx}3%b$PET#pTHLgIFQEJ;E>dF^gR7ES*H$5cmnB-G%I%Z zD|S`@Z2$T80!#olbXV*=%*>dt@PRwdU#I)^a=X5>;#J@&VrHyNnC;iLL0pQvfVyTmjO&;ssLc!1UOG})p;=82 zR;?Ceh}WZ?+UmMqI#RP8R>OzYoz15hnq@nzF`-!xQ4j$Um=RcIKKc27r2jVm&svm< zfC&6E0=7P!4tu^-ovjbA=k?dB`g+i*aXG_}p8zI)6mRKa+;6_1_R^8c3Qa!(fk8n8 H{*=HsM+*^= literal 0 HcmV?d00001 diff --git a/src/swagger.json b/src/swagger.json index 8920472..c83c1c6 100644 --- a/src/swagger.json +++ b/src/swagger.json @@ -1 +1 @@ -{"openapi":"3.0.1","info":{"title":"API","description":"","version":"1.0.0"},"tags":[],"paths":{"/events/latest":{"get":{"summary":"/events/latest","deprecated":false,"description":"","tags":[],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/EventCard"}}},"required":["events"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/login":{"post":{"summary":"/login","deprecated":false,"description":"","tags":[],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","faker":"admin1@grabit.com"},"password":{"type":"string","faker":"password123"}},"required":["email","password"]},"example":""}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"email":{"type":"string"},"accountType":{"type":"string","enum":["HARVESTER","ORGANISER"]},"name":{"type":"string"},"phoneNumber":{"type":"string","nullable":true}},"required":["token","email","accountType","name"]},"examples":{"1":{"summary":"Success","value":{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImNsdWJncHQyajAwMHNtMnQ4czl1MTF1ZHkiLCJyb2xlIjoiT1JHQU5JU0VSIiwiaWF0IjoxNzExNjU2MjY4LCJleHAiOjE3MTE3NDI2Njh9.ycica3zI-ICN9AGbiB8X40iRy7Uug4RbdkSZ7PvfcJA","email":"admin1@grabit.sk","accountType":"ORGANISER","name":"Leonard Homenick","phoneNumber":"377-409-0332 x981"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"User not found","value":{"code":"USER_NOT_FOUND","message":"User not found"}},"2":{"summary":"Wrong password","value":{"code":"WRONG_PASSWORD","message":"Wrong password"}}}}}},"404":{"description":"Record Not Found","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Record not found","value":{"message":"Wrong email address","code":"WRONG_EMAIL"}}}}}}},"security":[]}},"/user/editAccount":{"put":{"summary":"/user/editAccount","deprecated":false,"description":"","tags":[],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"phoneNumber":{"type":"string"}},"required":["name"]}}}},"responses":{"200":{"description":"Success","content":{"*/*":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/nearby":{"get":{"summary":"/events/nearby","deprecated":false,"description":"","tags":[],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"lat":{"type":"number","format":"float","minimum":-180,"maximum":180},"lon":{"type":"number","minimum":-180,"maximum":180,"format":"float"}},"required":["lon","lat"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/EventCard"}}},"required":["events"]},"examples":{"1":{"summary":"Success","value":{"events":[{"id":"clufwukav001bh2plbo8x0aht","name":"Electronic Wooden Keyboard","happeningAt":"2025-02-25T15:25:44.396Z","thumbnailURL":"https://picsum.photos/seed/791/1280/720","Location":{"id":"clufwukaj000wh2pltbm0cm71","locationLat":103.4928,"locationLon":-48.041,"address":"4961 Grange Avenue","city":"Tryciatown","name":"Steuber, Conn and Dooley"},"sallaryType":"GOODS","status":"CREATED","sallaryAmount":0.2,"sallaryProductName":"Handcrafted Bronze Mouse","sallaryUnit":"ml","EventCategoryRelation":[{"EventCategory":{"id":"clufwuk9o000ah2pll5sw1x4z","name":"Broskyňa","icon":"🍑","colorVariant":"ORANGE"}},{"EventCategory":{"id":"clufwuk9o000ah2pll5sw1x4z","name":"Broskyňa","icon":"🍑","colorVariant":"ORANGE"}},{"EventCategory":{"id":"clufwuk9o000fh2ploo10ialt","name":"Rajčina","icon":"🍅","colorVariant":"CHERRY"}}],"User":{"name":"Teresa Larson"}},{"id":"clufwukav001mh2plufg1ab33","name":"Handcrafted Rubber Salad","happeningAt":"2024-09-12T13:29:13.653Z","thumbnailURL":"https://picsum.photos/seed/463/1280/720","Location":{"id":"clufwukaj0017h2plia71s1sl","locationLat":58.3093,"locationLon":179.8429,"address":"49388 Jake Pass","city":"Kohlerport","name":"Russel, Koepp and Zieme"},"sallaryType":"MONEY","status":"CREATED","sallaryAmount":6.5,"sallaryProductName":null,"sallaryUnit":null,"EventCategoryRelation":[{"EventCategory":{"id":"clufwuk9o0008h2pli1zt4bow","name":"Čučoriedky","icon":"🫐","colorVariant":"LEMON"}},{"EventCategory":{"id":"clufwuk9o0006h2plczrbrq0z","name":"Hrozno","icon":"🍇","colorVariant":"LIME"}}],"User":{"name":"Saul Abbott"}},{"id":"clufwukav001nh2pldmln26sl","name":"Handcrafted Rubber Sausages","happeningAt":"2025-03-11T17:56:23.447Z","thumbnailURL":"https://picsum.photos/seed/913/1280/720","Location":{"id":"clufwukaj0018h2pl377kl15p","locationLat":86.2392,"locationLon":154.2931,"address":"929 Schaden Keys","city":"East Katherine","name":"Herzog, Hettinger and Rippin"},"sallaryType":"GOODS","status":"CREATED","sallaryAmount":1,"sallaryProductName":"Refined Rubber Mouse","sallaryUnit":"mg","EventCategoryRelation":[{"EventCategory":{"id":"clufwuk9o0007h2pl4si1pdnf","name":"Jahoda","icon":"🍓","colorVariant":"CHERRY"}},{"EventCategory":{"id":"clufwuk9o000bh2plpxndfmvw","name":"Mango","icon":"🥭","colorVariant":"LIME"}},{"EventCategory":{"id":"clufwuk9o000dh2pls9stowox","name":"Kokos","icon":"🥥","colorVariant":"APPLE"}}],"User":{"name":"Teresa Larson"}},{"id":"clufwukav001eh2pl3uqnagm8","name":"Intelligent Concrete Fish","happeningAt":"2024-04-16T18:41:50.255Z","thumbnailURL":"https://picsum.photos/seed/380/1280/720","Location":{"id":"clufwukaj000zh2pl08vjpmvv","locationLat":68.6195,"locationLon":-167.343,"address":"976 Harrison Street","city":"Considineside","name":"Lueilwitz and Sons"},"sallaryType":"GOODS","status":"CREATED","sallaryAmount":0.8,"sallaryProductName":"Practical Granite Chips","sallaryUnit":"kg","EventCategoryRelation":[{"EventCategory":{"id":"clufwuk9o000ph2plz2bphtsh","name":"Cibuľa","icon":"🧅","colorVariant":"LIME"}},{"EventCategory":{"id":"clufwuk9o000ih2plomjac7d1","name":"Brokolica","icon":"🥦","colorVariant":"APPLE"}},{"EventCategory":{"id":"clufwuk9o0003h2pl6tirr7op","name":"Citron","icon":"🍋","colorVariant":"LIME"}}],"User":{"name":"Teresa Larson"}},{"id":"clufwukav001lh2pl5fwntxd8","name":"Modern Bronze Soap","happeningAt":"2024-04-23T06:07:47.989Z","thumbnailURL":"https://picsum.photos/seed/169/1280/720","Location":{"id":"clufwukaj0016h2plr5ov92c5","locationLat":117.806,"locationLon":-64.8481,"address":"82861 White Wells","city":"East Letabury","name":"Bins - Johns"},"sallaryType":"GOODS","status":"CREATED","sallaryAmount":1.2,"sallaryProductName":"Rustic Fresh Pizza","sallaryUnit":"kg","EventCategoryRelation":[{"EventCategory":{"id":"clufwuk9o000bh2plpxndfmvw","name":"Mango","icon":"🥭","colorVariant":"LIME"}}],"User":{"name":"Mrs. Samantha Ratke"}}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventID}/uploadImage":{"post":{"summary":"/events/{eventID}/uploadImage","deprecated":false,"description":"","tags":[],"parameters":[{"name":"eventID","in":"path","description":"","required":true,"example":"id1234","schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"image":{"description":"Event image that we want to upload","example":"file:///Users/martinvanco/Documents/FIIT/2_ROC/MTAA/mtaa-2024-fronted/composeApp/src/commonMain/composeResources/drawable/placeholder.png","type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"imageURL":{"type":"string"}},"required":["imageURL"]},"examples":{"1":{"summary":"Success","value":{"imageURL":"https://loremflickr.com/640/480/nature"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"SERVER_ERROR","message":"That's not your fault, we are working on repair."}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}":{"get":{"summary":"/events/{eventId}","deprecated":false,"description":"","tags":[],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uu"},"name":{"type":"string"},"description":{"type":"string"},"happeningAt":{"type":"string","format":"date"},"thumbnailURL":{"type":"string","format":"url"},"capacity":{"type":"integer","minimum":0},"Location":{"$ref":"#/components/schemas/Location"},"sallaryType":{"type":"string","enum":["MONEY","GOODS"]},"sallaryAmount":{"type":"number","format":"float"},"sallaryUnit":{"type":"string","nullable":true},"sallaryProductName":{"type":"string","nullable":true},"toolingRequired":{"type":"string","nullable":true},"toolingProvided":{"type":"string","nullable":true},"status":{"type":"string","default":"'CREATED'","enum":["CREATED","PROGRESS","ARCHIVED","CANCELLED"]},"User":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"EventCategoryRelation":{"type":"array","items":{"type":"object","properties":{"EventCategory":{"type":"object","properties":{"id":{"type":"string","description":"ID","format":"uu"},"name":{"type":"string"},"icon":{"type":"string"},"colorVariant":{"type":"string","enum":["CHERRY","LEMON","LIME","APPLE","ORANGE"]}},"description":"ID","required":["id","name","icon","colorVariant"]}},"required":["EventCategory"]}},"_count":{"type":"object","properties":{"EventAssignment":{"type":"integer","minimum":0}},"required":["EventAssignment"]}},"required":["id","name","description","happeningAt","capacity","Location","sallaryType","sallaryAmount","status","User","EventCategoryRelation","_count"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]},"delete":{"summary":"/events/{eventId}","deprecated":false,"description":"","tags":[],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"*/*":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/createAccount":{"post":{"summary":"/createAccount","deprecated":false,"description":"","tags":[],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"password":{"type":"string"},"name":{"type":"string"},"accountType":{"type":"string","enum":["HARVESTER","ORGANISER"]},"phoneNumber":{"type":"string","nullable":true}},"required":["email","password","name","accountType"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"},"phoneNumber":{"type":"string","nullable":true},"accountType":{"type":"string","enum":["HARVESTER","ORGANISER"]},"token":{"type":"string"}},"required":["email","name","accountType","token"]},"examples":{"1":{"summary":"Success","value":{"email":"Ova.Pollich@yahoo.com","name":"accusamus fugiat explicabo","phoneNumber":"958-309-6630 x4687","accountType":"ORGANISER","token":"cillum culpa id ut exercitation"}}}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Email exists","value":{"message":"Email already in use","code":"EMAIL_IN_USE"}}}}}}},"security":[]}},"/events/active":{"get":{"summary":"/events/active","deprecated":false,"description":"","tags":[],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"thumbnailURL":{"type":"string","format":"url","nullable":true},"User":{"type":"object","properties":{"name":{"type":"string","description":"name"}},"required":["name"]}},"required":["id","name","User"]},"examples":{"1":{"summary":"Success","value":{"id":"clufwukd5004kh2pl8zap41c9","thumbnailURL":"https://picsum.photos/seed/637/1280/720","name":"Tasty Cotton Pizza","User":{"name":"Greg Quitzon"}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/":{"get":{"summary":"/events/","deprecated":false,"description":"","tags":[],"parameters":[{"name":"limit","in":"query","description":"Number of posts","required":false,"example":"","schema":{"type":"string"}},{"name":"categoryID","in":"query","description":"cantegory ID","required":false,"example":"","schema":{"type":"string"}},{"name":"priceType","in":"query","description":"MONEY | BARTER","required":false,"example":"","schema":{"type":"string"}},{"name":"distance","in":"query","description":"Radius in km","required":false,"example":"","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/EventCard"}}},"required":["items"]}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid Input","value":{"code":"INVALID_QUERY","message":"Invalid query. Check the parameters."}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"No posts found","value":{"code":"NO_POSTS_FOUND","message":"No posts matching your request."}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"SERVER_ERROR","message":"That's not your fault, we are working on repair."}}}}}}},"security":[{"bearer":[]}]}},"/user/verifyToken":{"get":{"summary":"/user/verifyToken","deprecated":false,"description":"","tags":[],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{},"required":["01HQXZRBF1TF1ZRJMK56SP5718"]}}}},"responses":{"200":{"description":"Success","content":{"*/*":{"schema":{"type":"object","properties":{}},"examples":{"1":{"summary":"Success","value":""}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/signFor":{"post":{"summary":"/events/{eventId}/signFor","deprecated":false,"description":"","tags":[],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/user":{"get":{"summary":"/user","deprecated":false,"description":"","tags":[],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"avatarURL":{"type":"string"},"createdAt":{"default":"CURRENT_TIMESTAMP","type":"string"},"phoneNumber":{"type":"string"},"type":{"type":"string","enum":["WORKER","COMPANY"]}},"required":["id","email","name","createdAt","type"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/signOff":{"post":{"summary":"/events/{eventId}/signOff","deprecated":false,"description":"","tags":[],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/updateAttendance":{"put":{"summary":"/events/{eventId}/updateAttendance","deprecated":false,"description":"","tags":[],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"presenceStatus":{"type":"string"},"userID":{"type":"string"},"arrivedAt":{"type":"string"},"leftAt":{"type":"string"}},"required":["presenceStatus","userID","arrivedAt","leftAt"]}}},"required":["items"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/endEvent":{"post":{"summary":"/events/{eventId}/endEvent","deprecated":false,"description":"Sets the event status to ENDED - marks all workers attendance to LEFT and calculates insights for the company about sallary for each worker.","tags":[],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/startEvent":{"put":{"summary":"/events/{eventId}/startEvent","deprecated":false,"description":"Sets the event status to LIVE - notifying all workers.","tags":[],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"*/*":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/create":{"post":{"summary":"/events/create","deprecated":false,"description":"","tags":[],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"happeningAt":{"type":"string","format":"date"},"capacity":{"type":"integer","minimum":0},"sallaryType":{"type":"string","enum":["MONEY","GOODS"]},"sallaryAmount":{"type":"number","format":"float"},"sallaryProductName":{"type":"string"},"sallaryUnit":{"type":"string"},"categories":{"type":"array","items":{"type":"string"}},"toolingRequired":{"type":"string"},"toolingProvided":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"thumbnailURL":{"type":"string","format":"url"},"location":{"type":"object","properties":{"locationLat":{"type":"number"},"locationLon":{"type":"number"},"address":{"type":"string"},"city":{"type":"string"},"name":{"type":"string"}},"required":["locationLat","locationLon","address","city"]},"harmonogramItems":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"from":{"type":"string","format":"time","examples":["12:00"]},"to":{"type":"string","format":"time","examples":["12:00"]}},"required":["title","from","to","description"]}}},"required":["happeningAt","capacity","sallaryType","name","location","sallaryAmount"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"eventId":{"type":"string"}},"required":["eventId"]}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/update":{"put":{"summary":"/events/{eventId}/update","deprecated":false,"description":"","tags":[],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"happeningAt":{"type":"string","format":"date"},"capacity":{"type":"integer","minimum":0,"maximum":2147483647},"sallaryType":{"type":"string","enum":["MONEY","GOODS"]},"sallaryAmount":{"type":"number","format":"float","minimum":0},"sallaryProductName":{"type":"string"},"sallaryUnit":{"type":"string"},"categories":{"type":"array","items":{"type":"string"}},"toolingRequired":{"type":"string"},"toolingProvided":{"type":"string"},"description":{"type":"string"},"thumbnailURL":{"type":"string","format":"url"},"location":{"type":"object","properties":{"locationLat":{"type":"number","format":"float","minimum":-180,"maximum":180},"locationLon":{"type":"number","format":"float","minimum":-180,"maximum":180,"title":""},"address":{"type":"string"},"city":{"type":"string"},"name":{"type":"string"}},"required":["locationLat","locationLon","address","city"]},"harmonogramItems":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"If harmonogram item is new, id is \"new\""},"title":{"type":"string"},"description":{"type":"string"},"from":{"type":"string","format":"time","examples":["12:00"]},"to":{"type":"string","format":"time","examples":["12:00"]}},"required":["title","from","to","description","id"]}}},"required":["happeningAt","capacity","sallaryType","location","sallaryAmount"]}}}},"responses":{"200":{"description":"Success","content":{"*/*":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/live":{"get":{"summary":"/events/{eventId}/live","deprecated":false,"description":"","tags":[],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/workers/{userId}":{"get":{"summary":"/events/{eventId}/workers/{userId}","deprecated":false,"description":"","tags":[],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}},{"name":"userId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string"},"phoneNumber":{"type":"string"},"":{"type":"string"}},"required":["name","email","phoneNumber",""]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"SERVER_ERROR","message":"That's not your fault, we are working on repair."}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/workers":{"get":{"summary":"/events/{eventId}/workers","deprecated":false,"description":"","tags":[],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"workers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string"},"signedForAt":{"type":"string","format":"date"},"status":{"type":"string","enum":["ACTIVE","SIGNED_OFF"]}},"required":["name","email","signedForAt","status"]}}},"required":["workers"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"SERVER_ERROR","message":"That's not your fault, we are working on repair."}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/attendance":{"get":{"summary":"/events/{eventId}/attendance","deprecated":false,"description":"","tags":[],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"workers":{"type":"array","items":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"assignmentStatus":{"type":"string","enum":["ACTIVE","SIGNED_OFF"]},"attendanceStatus":{"type":"string","enum":["NOT_PRESENT","DID_NOT_ARRIVE","PRESENT","LEFT"]},"arrived_at":{"type":"string","format":"date","nullable":true},"left_at":{"type":"string","format":"date","nullable":true}},"required":["attendanceStatus","arrived_at","left_at","assignmentStatus","user"]}}},"required":["workers"]},"examples":{"1":{"summary":"Success","value":{"workers":[{"user":{"id":"cluhgramk008fr032gpm60bdf","name":"Charlene Yundt"},"assignmentStatus":"ACTIVE","presenceStatus":"NOT_PRESENT","arrivedAt":null,"leftAt":null},{"user":{"id":"cluhgramk008hr032i960ess0","name":"Roxanne Kuphal IV"},"assignmentStatus":"ACTIVE","presenceStatus":"NOT_PRESENT","arrivedAt":null,"leftAt":null},{"user":{"id":"cluhgramk008gr032sg02za9a","name":"Ms. Sophie DuBuque"},"assignmentStatus":"ACTIVE","presenceStatus":"NOT_PRESENT","arrivedAt":null,"leftAt":null},{"user":{"id":"cluhgralj0036r032f0bv5pmf","name":"Darla McCullough"},"assignmentStatus":"ACTIVE","presenceStatus":"NOT_PRESENT","arrivedAt":null,"leftAt":null},{"user":{"id":"cluhgramk008ir0320fe5fkal","name":"Anne Powlowski"},"assignmentStatus":"SIGNED_OFF","presenceStatus":"LEFT","arrivedAt":null,"leftAt":null},{"user":{"id":"cluhgramk008cr032e0znk7dg","name":"Dominick Carroll"},"assignmentStatus":"ACTIVE","presenceStatus":"PRESENT","arrivedAt":null,"leftAt":null}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"SERVER_ERROR","message":"That's not your fault, we are working on repair."}}}}}}},"security":[{"bearer":[]}]},"put":{"summary":"/events/{eventId}/attendance","deprecated":false,"description":"","tags":[],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"workers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"attendanceStatus":{"type":"string","enum":["NOT_PRESENT","PRESENT","LEFT"]},"arrived_at":{"type":"string","format":"date","nullable":true},"left_at":{"type":"string","format":"date","nullable":true}},"required":["attendanceStatus","id","arrived_at","left_at"]}}},"required":["workers"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"SERVER_ERROR","message":"That's not your fault, we are working on repair."}}}}}}},"security":[{"bearer":[]}]}}},"components":{"schemas":{"Category":{"type":"object","properties":{"id":{"type":"string","description":"ID","format":"uu"},"name":{"type":"string"},"icon":{"type":"string"},"colorVariant":{"type":"string","enum":["CHERRY","LEMON","LIME","APPLE","ORANGE"]}},"required":["id","name","icon","colorVariant"]},"Location":{"properties":{"locationLat":{"type":"number","minimum":-180,"maximum":180},"locationLon":{"type":"number","minimum":-180,"maximum":180},"address":{"type":"string"},"city":{"type":"string"},"name":{"type":"string"}},"type":"object","required":["locationLat","locationLon","address","city"]},"EventCard":{"type":"object","properties":{"id":{"type":"string","format":"uu"},"name":{"type":"string"},"happeningAt":{"type":"string","format":"date"},"thumbnailURL":{"type":"string","format":"url"},"Location":{"$ref":"#/components/schemas/Location"},"sallaryType":{"type":"string","enum":["MONEY","GOODS"]},"sallaryAmount":{"type":"number","format":"float"},"sallaryUnit":{"type":"string","nullable":true},"sallaryProductName":{"type":"string","nullable":true},"status":{"type":"string","default":"'CREATED'","enum":["CREATED","PROGRESS","ARCHIVED","CANCELLED"]},"User":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"EventCategoryRelation":{"type":"array","items":{"type":"object","properties":{"EventCategory":{"$ref":"#/components/schemas/Category"}},"required":["EventCategory"]}}},"required":["id","name","happeningAt","sallaryType","status","sallaryAmount","User","Location","EventCategoryRelation"]},"_rismaMigrations":{"properties":{"id":{"type":"string","maxLength":36},"checksum":{"type":"string","maxLength":64},"finished_at":{"type":"string"},"migration_name":{"type":"string","maxLength":255},"logs":{"type":"string"},"rolled_back_at":{"type":"string"},"started_at":{"default":"now()","type":"string"},"applied_steps_count":{"default":"0","type":"integer","minimum":-2147483648,"maximum":2147483647}},"type":"object","required":["id","checksum","migration_name","started_at","applied_steps_count"]},"User":{"properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"avatarURL":{"type":"string"},"createdAt":{"default":"CURRENT_TIMESTAMP","type":"string"},"phoneNumber":{"type":"string"},"type":{"type":"string","enum":["WORKER","COMPANY"]},"verificationToken":{"type":"string"},"password":{"type":"string"}},"type":"object","required":["id","email","name","createdAt","type","password"]},"HarmonogramItem":{"properties":{"id":{"type":"string"},"createdAt":{"default":"CURRENT_TIMESTAMP","type":"string"},"from":{"type":"string"},"to":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"eventId":{"type":"string"}},"type":"object","required":["id","createdAt","from","to","title","eventId"]},"EventCategoryRelation":{"properties":{"id":{"type":"string"},"eventId":{"type":"string"},"eventCategoryId":{"type":"string"}},"type":"object","required":["id","eventId","eventCategoryId"]},"EventCategory":{"properties":{"id":{"type":"string"},"createdAt":{"default":"CURRENT_TIMESTAMP","type":"string"},"name":{"type":"string"},"icon":{"type":"string"}},"type":"object","required":["id","createdAt","name","icon"]},"EventAssignment":{"properties":{"id":{"type":"string"},"createdAt":{"default":"CURRENT_TIMESTAMP","type":"string"},"userId":{"type":"string"},"eventId":{"type":"string"},"assignmentStatus":{"type":"string","default":"'Active'","enum":["ACTIVE","SIGNED_OFF"]},"arrivedAt":{"type":"string"},"leftAt":{"type":"string"},"presenceStatus":{"type":"string","enum":["NOT_PRESENT","PRESENT","LEFT"]}},"type":"object","required":["id","createdAt","userId","eventId","assignmentStatus","presenceStatus"]},"Event":{"type":"object","properties":{"id":{"type":"string","format":"uu"},"name":{"type":"string"},"description":{"type":"string"},"happeningAt":{"type":"string","format":"date"},"thumbnailURL":{"type":"string","format":"url"},"capacity":{"type":"integer","minimum":0},"Location":{"$ref":"#/components/schemas/Location"},"sallaryType":{"type":"string","enum":["MONEY","GOODS"]},"sallaryAmount":{"type":"number","format":"float"},"sallaryUnit":{"type":"string","nullable":true},"sallaryProductName":{"type":"string","nullable":true},"toolingRequired":{"type":"string","nullable":true},"toolingProvided":{"type":"string","nullable":true},"status":{"type":"string","default":"'CREATED'","enum":["CREATED","PROGRESS","ARCHIVED","CANCELLED"]},"User":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"EventCategoryRelation":{"type":"array","items":{"type":"object","properties":{"EventCategory":{"type":"object","properties":{"id":{"type":"string","description":"ID","format":"uu"},"name":{"type":"string"},"icon":{"type":"string"},"colorVariant":{"type":"string","enum":["CHERRY","LEMON","LIME","APPLE","ORANGE"]}},"description":"ID","required":["id","name","icon","colorVariant"]}},"required":["EventCategory"]}},"_count":{"type":"object","properties":{"EventAssignment":{"type":"integer","minimum":0}},"required":["EventAssignment"]}},"required":["id","name","happeningAt","sallaryType","status","sallaryAmount","User","Location","EventCategoryRelation","description","capacity","_count"]},"AnnouncementItem":{"properties":{"id":{"type":"string"},"createdAt":{"default":"CURRENT_TIMESTAMP","type":"string"},"eventId":{"type":"string"},"userId":{"type":"string"},"message":{"type":"string"}},"type":"object","required":["id","createdAt","eventId","userId","message"]}},"securitySchemes":{"bearer":{"type":"http","scheme":"bearer"}}},"servers":[{"url":"http://localhost:3000","description":"Develop Env"}]} \ No newline at end of file +{"openapi":"3.0.1","info":{"title":"API","description":"","version":"1.0.0"},"tags":[{"name":"Event"},{"name":"User"},{"name":"UserActions"}],"paths":{"/events/latest":{"get":{"summary":"Get latest events","deprecated":false,"description":"Returns a list of 5 most recently created events","tags":["Event"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/EventCard"}}},"required":["events"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/login":{"post":{"summary":"Login","deprecated":false,"description":"This endpoint generates a token for user that submits correct credentials.","tags":["User"],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","faker":"admin1@grabit.com"},"password":{"type":"string","faker":"password123"}},"required":["email","password"]},"example":""}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"email":{"type":"string"},"accountType":{"type":"string","enum":["HARVESTER","ORGANISER"]},"name":{"type":"string"},"phoneNumber":{"type":"string","nullable":true}},"required":["token","email","accountType","name"]},"examples":{"1":{"summary":"Success","value":{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImNsdWJncHQyajAwMHNtMnQ4czl1MTF1ZHkiLCJyb2xlIjoiT1JHQU5JU0VSIiwiaWF0IjoxNzExNjU2MjY4LCJleHAiOjE3MTE3NDI2Njh9.ycica3zI-ICN9AGbiB8X40iRy7Uug4RbdkSZ7PvfcJA","email":"admin1@grabit.sk","accountType":"ORGANISER","name":"Leonard Homenick","phoneNumber":"377-409-0332 x981"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"User not found","value":{"code":"USER_NOT_FOUND","message":"User not found"}},"2":{"summary":"Wrong password","value":{"code":"WRONG_PASSWORD","message":"Wrong password"}}}}}},"404":{"description":"Record Not Found","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Record not found","value":{"message":"Wrong email address","code":"WRONG_EMAIL"}}}}}}},"security":[]}},"/events/categories":{"get":{"summary":"List of categories assigned to at least one event","deprecated":false,"description":"Get a list of categories that were assigned to at least one event along with the number of events assigned to the event.","tags":["Event"],"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"categories":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"icon":{"type":"string"},"colorVariant":{"type":"string","enum":["CHERRY","LEMON","LIME","APPLE","ORANGE"]},"_count":{"type":"object","properties":{"EventCategoryRelation":{"type":"integer"}},"required":["EventCategoryRelation"]}},"required":["id","name","icon","colorVariant","_count"]}}},"required":["categories"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"SERVER_ERROR","message":"That's not your fault, we are working on repair."}}}}}}},"security":[{"bearer":[]}]}},"/user/editAccount":{"put":{"summary":"Edit account","deprecated":false,"description":"Allows users to edit their account information","tags":["User"],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"phoneNumber":{"type":"string"}},"required":["name"]}}}},"responses":{"200":{"description":"Success","content":{"*/*":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/my":{"get":{"summary":"My events","deprecated":false,"description":"Returns a list of events. If user is ORGANISER, query contains all events that were created by user. If the user is HARVESTER, the endpoint returns list of events, to which user signed to.","tags":["Event"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/EventCard"}}},"required":["events"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/nearby":{"get":{"summary":"Get events nearby","deprecated":false,"description":"Endpoint that returns events that are in 30km radius from users location.","tags":["Event"],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"lat":{"type":"number","format":"float","minimum":-180,"maximum":180},"lon":{"type":"number","minimum":-180,"maximum":180,"format":"float"}},"required":["lon","lat"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/EventCard"}}},"required":["events"]},"examples":{"1":{"summary":"Success","value":{"events":[{"id":"clufwukav001bh2plbo8x0aht","name":"Electronic Wooden Keyboard","happeningAt":"2025-02-25T15:25:44.396Z","thumbnailURL":"https://picsum.photos/seed/791/1280/720","Location":{"id":"clufwukaj000wh2pltbm0cm71","locationLat":103.4928,"locationLon":-48.041,"address":"4961 Grange Avenue","city":"Tryciatown","name":"Steuber, Conn and Dooley"},"sallaryType":"GOODS","status":"CREATED","sallaryAmount":0.2,"sallaryProductName":"Handcrafted Bronze Mouse","sallaryUnit":"ml","EventCategoryRelation":[{"EventCategory":{"id":"clufwuk9o000ah2pll5sw1x4z","name":"Broskyňa","icon":"🍑","colorVariant":"ORANGE"}},{"EventCategory":{"id":"clufwuk9o000ah2pll5sw1x4z","name":"Broskyňa","icon":"🍑","colorVariant":"ORANGE"}},{"EventCategory":{"id":"clufwuk9o000fh2ploo10ialt","name":"Rajčina","icon":"🍅","colorVariant":"CHERRY"}}],"User":{"name":"Teresa Larson"}},{"id":"clufwukav001mh2plufg1ab33","name":"Handcrafted Rubber Salad","happeningAt":"2024-09-12T13:29:13.653Z","thumbnailURL":"https://picsum.photos/seed/463/1280/720","Location":{"id":"clufwukaj0017h2plia71s1sl","locationLat":58.3093,"locationLon":179.8429,"address":"49388 Jake Pass","city":"Kohlerport","name":"Russel, Koepp and Zieme"},"sallaryType":"MONEY","status":"CREATED","sallaryAmount":6.5,"sallaryProductName":null,"sallaryUnit":null,"EventCategoryRelation":[{"EventCategory":{"id":"clufwuk9o0008h2pli1zt4bow","name":"Čučoriedky","icon":"🫐","colorVariant":"LEMON"}},{"EventCategory":{"id":"clufwuk9o0006h2plczrbrq0z","name":"Hrozno","icon":"🍇","colorVariant":"LIME"}}],"User":{"name":"Saul Abbott"}},{"id":"clufwukav001nh2pldmln26sl","name":"Handcrafted Rubber Sausages","happeningAt":"2025-03-11T17:56:23.447Z","thumbnailURL":"https://picsum.photos/seed/913/1280/720","Location":{"id":"clufwukaj0018h2pl377kl15p","locationLat":86.2392,"locationLon":154.2931,"address":"929 Schaden Keys","city":"East Katherine","name":"Herzog, Hettinger and Rippin"},"sallaryType":"GOODS","status":"CREATED","sallaryAmount":1,"sallaryProductName":"Refined Rubber Mouse","sallaryUnit":"mg","EventCategoryRelation":[{"EventCategory":{"id":"clufwuk9o0007h2pl4si1pdnf","name":"Jahoda","icon":"🍓","colorVariant":"CHERRY"}},{"EventCategory":{"id":"clufwuk9o000bh2plpxndfmvw","name":"Mango","icon":"🥭","colorVariant":"LIME"}},{"EventCategory":{"id":"clufwuk9o000dh2pls9stowox","name":"Kokos","icon":"🥥","colorVariant":"APPLE"}}],"User":{"name":"Teresa Larson"}},{"id":"clufwukav001eh2pl3uqnagm8","name":"Intelligent Concrete Fish","happeningAt":"2024-04-16T18:41:50.255Z","thumbnailURL":"https://picsum.photos/seed/380/1280/720","Location":{"id":"clufwukaj000zh2pl08vjpmvv","locationLat":68.6195,"locationLon":-167.343,"address":"976 Harrison Street","city":"Considineside","name":"Lueilwitz and Sons"},"sallaryType":"GOODS","status":"CREATED","sallaryAmount":0.8,"sallaryProductName":"Practical Granite Chips","sallaryUnit":"kg","EventCategoryRelation":[{"EventCategory":{"id":"clufwuk9o000ph2plz2bphtsh","name":"Cibuľa","icon":"🧅","colorVariant":"LIME"}},{"EventCategory":{"id":"clufwuk9o000ih2plomjac7d1","name":"Brokolica","icon":"🥦","colorVariant":"APPLE"}},{"EventCategory":{"id":"clufwuk9o0003h2pl6tirr7op","name":"Citron","icon":"🍋","colorVariant":"LIME"}}],"User":{"name":"Teresa Larson"}},{"id":"clufwukav001lh2pl5fwntxd8","name":"Modern Bronze Soap","happeningAt":"2024-04-23T06:07:47.989Z","thumbnailURL":"https://picsum.photos/seed/169/1280/720","Location":{"id":"clufwukaj0016h2plr5ov92c5","locationLat":117.806,"locationLon":-64.8481,"address":"82861 White Wells","city":"East Letabury","name":"Bins - Johns"},"sallaryType":"GOODS","status":"CREATED","sallaryAmount":1.2,"sallaryProductName":"Rustic Fresh Pizza","sallaryUnit":"kg","EventCategoryRelation":[{"EventCategory":{"id":"clufwuk9o000bh2plpxndfmvw","name":"Mango","icon":"🥭","colorVariant":"LIME"}}],"User":{"name":"Mrs. Samantha Ratke"}}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/uploadImage":{"post":{"summary":"Upload image","deprecated":false,"description":"Upload image, and get an public URL.","tags":["Event"],"parameters":[],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"image":{"description":"Event image that we want to upload","example":"file:///Users/martinvanco/Documents/FIIT/2_ROC/MTAA/mtaa-2024-fronted/composeApp/src/commonMain/composeResources/drawable/placeholder.png","type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"imageURL":{"type":"string"}},"required":["imageURL"]},"examples":{"1":{"summary":"Success","value":{"imageURL":"https://loremflickr.com/640/480/nature"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"SERVER_ERROR","message":"That's not your fault, we are working on repair."}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}":{"get":{"summary":"Get event details","deprecated":false,"description":"Returns all avaliable informations about an event.","tags":["Event"],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"example":"","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uu"},"name":{"type":"string"},"description":{"type":"string"},"happeningAt":{"type":"string","format":"date"},"thumbnailURL":{"type":"string","format":"url"},"capacity":{"type":"integer","minimum":0},"Location":{"$ref":"#/components/schemas/Location"},"sallaryType":{"type":"string","enum":["MONEY","GOODS"]},"sallaryAmount":{"type":"number","format":"float"},"sallaryUnit":{"type":"string","nullable":true},"sallaryProductName":{"type":"string","nullable":true},"toolingRequired":{"type":"string","nullable":true},"toolingProvided":{"type":"string","nullable":true},"status":{"type":"string","default":"'CREATED'","enum":["CREATED","PROGRESS","ARCHIVED","CANCELLED"]},"User":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"EventCategoryRelation":{"type":"array","items":{"type":"object","properties":{"EventCategory":{"type":"object","properties":{"id":{"type":"string","description":"ID","format":"uu"},"name":{"type":"string"},"icon":{"type":"string"},"colorVariant":{"type":"string","enum":["CHERRY","LEMON","LIME","APPLE","ORANGE"]}},"description":"ID","required":["id","name","icon","colorVariant"]}},"required":["EventCategory"]}},"_count":{"type":"object","properties":{"EventAssignment":{"type":"integer","minimum":0}},"required":["EventAssignment"]},"isOwnedByUser":{"type":"boolean"},"isUserSignedIn":{"type":"boolean"}},"required":["id","name","description","happeningAt","capacity","Location","sallaryType","sallaryAmount","status","User","EventCategoryRelation","_count","isOwnedByUser","isUserSignedIn"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]},"delete":{"summary":"Cancel event","deprecated":false,"description":"Endpoint avaliable for organisers to cancell event that they created.","tags":["Event"],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"*/*":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/onMap":{"get":{"summary":"Points on map","deprecated":false,"description":"Get all event ids along with their qordinates on map. This specific endpoint is used for displaying events on map.","tags":["Event"],"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"Location":{"type":"object","properties":{"locationLat":{"type":"number"},"locationLon":{"type":"number"}},"required":["locationLat","locationLon"]}},"required":["id","Location"]}}},"required":["events"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"SERVER_ERROR","message":"That's not your fault, we are working on repair."}}}}}}},"security":[{"bearer":[]}]}},"/createAccount":{"post":{"summary":"Create account","deprecated":false,"description":"Create a new account of specified type: ORGANISER / HARVESTER","tags":["User"],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"password":{"type":"string"},"name":{"type":"string"},"accountType":{"type":"string","enum":["HARVESTER","ORGANISER"]},"phoneNumber":{"type":"string","nullable":true}},"required":["email","password","name","accountType"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"},"phoneNumber":{"type":"string","nullable":true},"accountType":{"type":"string","enum":["HARVESTER","ORGANISER"]},"token":{"type":"string"}},"required":["email","name","accountType","token"]},"examples":{"1":{"summary":"Success","value":{"email":"Ova.Pollich@yahoo.com","name":"accusamus fugiat explicabo","phoneNumber":"958-309-6630 x4687","accountType":"ORGANISER","token":"cillum culpa id ut exercitation"}}}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Email exists","value":{"message":"Email already in use","code":"EMAIL_IN_USE"}}}}}}},"security":[]}},"/events/active":{"get":{"summary":"Get active event","deprecated":false,"description":"This endpoint returns an event that is currently in progress for a certain user. \n- If user is organiser, it returns event created by user that has \"IN_PROGRESS\" status.\n- If user is harvester, it returns event with \"IN_PROGRESS\" status that user is signed for.\n\nIf there is no event like this, endpoint returns 404 Not Found.","tags":["Event"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"thumbnailURL":{"type":"string","format":"url","nullable":true},"User":{"type":"object","properties":{"name":{"type":"string","description":"name"}},"required":["name"]}},"required":["id","name","User"]},"examples":{"1":{"summary":"Success","value":{"id":"clufwukd5004kh2pl8zap41c9","thumbnailURL":"https://picsum.photos/seed/637/1280/720","name":"Tasty Cotton Pizza","User":{"name":"Greg Quitzon"}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/user/verifyToken":{"get":{"summary":"Verify token","deprecated":false,"description":"Endpoint verifies if provided token is valid","tags":["User"],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{},"required":["01HQXZRBF1TF1ZRJMK56SP5718"]}}}},"responses":{"200":{"description":"Success","content":{"*/*":{"schema":{"type":"object","properties":{}},"examples":{"1":{"summary":"Success","value":""}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}}},"security":[{"bearer":[]}]}},"/events/":{"get":{"summary":"Get all events","deprecated":false,"description":"Get all events that are in status \"CREATED\". This filters out events that were cancelled, are already in progress or are archived.","tags":["Event"],"parameters":[{"name":"limit","in":"query","description":"Number of posts","required":false,"example":"","schema":{"type":"string"}},{"name":"categoryID","in":"query","description":"cantegory ID","required":false,"example":"","schema":{"type":"string"}},{"name":"priceType","in":"query","description":"MONEY | GOODS","required":false,"example":"","schema":{"type":"string"}},{"name":"distance","in":"query","description":"Radius in km","required":false,"example":"","schema":{"type":"integer"}},{"name":"lat","in":"query","description":"latitude","required":false,"example":"","schema":{"type":"number","minimum":-180,"maximum":180,"format":"float"}},{"name":"lon","in":"query","description":"longitude","required":false,"example":"","schema":{"type":"number","format":"float","minimum":-180,"maximum":180}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/EventCard"}}},"required":["events"]}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid Input","value":{"code":"INVALID_QUERY","message":"Invalid query. Check the parameters."}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"No posts found","value":{"code":"NO_POSTS_FOUND","message":"No posts matching your request."}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"SERVER_ERROR","message":"That's not your fault, we are working on repair."}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/signFor":{"post":{"summary":"Sign for event","deprecated":false,"description":"This endpoint is avaliable for HARVESTERS only. It allows them to sign for an event.","tags":["UserActions"],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"*/*":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/signOff":{"post":{"summary":"Sign off event","deprecated":false,"description":"This endpoint is avaliable for HARVESTERS only. It allows them to sign off an event.","tags":["UserActions"],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"*/*":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/user":{"delete":{"summary":"Delete user account","deprecated":false,"description":"","tags":[],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"SERVER_ERROR","message":"That's not your fault, we are working on repair."}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/updateAttendance":{"put":{"summary":"Update event attendance","deprecated":false,"description":"This event has to be in IN_PROGRESS status. This endpoint is only avaliable to organiser who created the event.","tags":["UserActions"],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"workers":{"type":"array","items":{"type":"object","properties":{"userID":{"type":"string"},"presenceStatus":{"type":"string"},"arrivedAt":{"type":"string"},"leftAt":{"type":"string"}},"required":["userID","presenceStatus"]}}},"required":["workers"]},"example":{"workers":[{"userID":"clutvexj9002l10vy9igdy2qw","presenceStatus":"PRESENT","arrivedAt":"2024-04-09T19:05:25.417Z","leftAt":"2024-04-09T23:49:55.223Z"},{"userID":"clutvexj9002k10vyujbo31w6","presenceStatus":"PRESENT","arrivedAt":"2024-04-10T13:27:34.870Z","leftAt":"2024-04-09T22:39:13.219Z"}]}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"title":"","type":"undefined"}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/endEvent":{"post":{"summary":"End event","deprecated":false,"description":"Sets the event status to ARCHIVED - marks all workers attendance to LEFT and calculates insights for the company about sallary for each worker.","tags":["UserActions"],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"*/*":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/startEvent":{"put":{"summary":"Start event","deprecated":false,"description":"This endpoint is avaliable for ORGANISERS only. It allows them to start event.","tags":["UserActions"],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"*/*":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/create":{"post":{"summary":"Create event","deprecated":false,"description":"Endpoint avaliable for organisers, to create a new event.","tags":["Event"],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"happeningAt":{"type":"string","format":"date"},"capacity":{"type":"integer","minimum":0},"sallaryType":{"type":"string","enum":["MONEY","GOODS"]},"sallaryAmount":{"type":"number","format":"float"},"sallaryProductName":{"type":"string"},"sallaryUnit":{"type":"string"},"categories":{"type":"array","items":{"type":"string"}},"toolingRequired":{"type":"string"},"toolingProvided":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"thumbnailURL":{"type":"string","format":"url"},"location":{"type":"object","properties":{"locationLat":{"type":"number"},"locationLon":{"type":"number"},"address":{"type":"string"},"city":{"type":"string"},"name":{"type":"string"}},"required":["locationLat","locationLon","address","city"]},"harmonogramItems":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"from":{"type":"string","format":"time","examples":["12:00"]},"to":{"type":"string","format":"time","examples":["12:00"]}},"required":["title","from","to","description"]}}},"required":["happeningAt","capacity","sallaryType","name","location","sallaryAmount"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"eventId":{"type":"string"}},"required":["eventId"]}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/update":{"put":{"summary":"Update event","deprecated":false,"description":"Endpoint avaliable for organisers to update event data that they created.","tags":["Event"],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"happeningAt":{"type":"string","format":"date"},"capacity":{"type":"integer","minimum":0,"maximum":2147483647},"sallaryType":{"type":"string","enum":["MONEY","GOODS"]},"sallaryAmount":{"type":"number","format":"float","minimum":0},"sallaryProductName":{"type":"string"},"sallaryUnit":{"type":"string"},"categories":{"type":"array","items":{"type":"string"}},"toolingRequired":{"type":"string"},"toolingProvided":{"type":"string"},"description":{"type":"string"},"thumbnailURL":{"type":"string","format":"url"},"location":{"type":"object","properties":{"locationLat":{"type":"number","format":"float","minimum":-180,"maximum":180},"locationLon":{"type":"number","format":"float","minimum":-180,"maximum":180,"title":""},"address":{"type":"string"},"city":{"type":"string"},"name":{"type":"string"}},"required":["locationLat","locationLon","address","city"]},"harmonogramItems":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"If harmonogram item is new, id is \"new\""},"title":{"type":"string"},"description":{"type":"string"},"from":{"type":"string","format":"time","examples":["12:00"]},"to":{"type":"string","format":"time","examples":["12:00"]}},"required":["title","from","to","description","id"]}}},"required":["happeningAt","capacity","sallaryType","location","sallaryAmount"]}}}},"responses":{"200":{"description":"Success","content":{"*/*":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Invalid input format","value":{"code":"INVALID_REQUEST","message":"Invalid request params"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"404":{"description":"Record not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"NOT_FOUND","message":"Record not found"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/live":{"get":{"summary":"In progress event data","deprecated":false,"description":"This endpoint returns harmonogram items and announcement items to the user. \nThis endpoint works only:\n- for events in \"IN_PROGRESS\" status\n- for organisers who created the event\n- for harvesters who are signed for the event","tags":["Event"],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"announcementItems":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string","format":"date"},"eventId":{"type":"string"},"userId":{"type":"string"},"message":{"type":"string"}},"required":["id","createdAt","eventId","userId","message"]}},"harmonogramItems":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string","format":"date"},"from":{"type":"string","format":"time"},"to":{"type":"string","format":"time"},"title":{"type":"string"},"description":{"type":"string"},"eventId":{"type":"string"}},"required":["id","createdAt","from","to","title","description","eventId"]}}},"required":["announcementItems","harmonogramItems"]},"examples":{"1":{"summary":"Success","value":{"announcementItems":[{"id":"cluv30sgp00dn5ohvj17nctbz","createdAt":"2024-04-11T06:02:50.257Z","eventId":"liveEventId","userId":"admin1","message":"Curia adipisci inventore despecto vulgo."},{"id":"cluv30sgp00e05ohvoza7ujh5","createdAt":"2024-04-11T07:21:25.257Z","eventId":"liveEventId","userId":"admin1","message":"Auditor argentum cetera."},{"id":"cluv30sgp00dm5ohvgbliuzk0","createdAt":"2024-04-11T08:46:29.257Z","eventId":"liveEventId","userId":"admin1","message":"Vomica totam crux."},{"id":"cluv30sgp00dp5ohv2yw38vfe","createdAt":"2024-04-11T09:28:37.257Z","eventId":"liveEventId","userId":"admin1","message":"Tametsi clarus cur cado officia ago cresco administratio solitudo auditor."},{"id":"cluv30sgp00do5ohv4dr0tla7","createdAt":"2024-04-11T10:39:21.257Z","eventId":"liveEventId","userId":"admin1","message":"Aptus undique tabesco administratio atque aut coadunatio astrum coadunatio."},{"id":"cluv30sgp00dr5ohvtlokauwz","createdAt":"2024-04-11T11:33:55.257Z","eventId":"liveEventId","userId":"admin1","message":"Argumentum volutabrum creptio vacuus provident decor clibanus clementia usque cumque."},{"id":"cluv30sgp00dv5ohvcw546f6h","createdAt":"2024-04-11T12:26:18.257Z","eventId":"liveEventId","userId":"admin1","message":"Velit colo sopor vilitas."},{"id":"cluv30sgp00dx5ohvwc2ud56g","createdAt":"2024-04-11T13:55:13.257Z","eventId":"liveEventId","userId":"admin1","message":"Bellum decerno crastinus absorbeo vespillo."},{"id":"cluv30sgp00dw5ohvlcgufwiz","createdAt":"2024-04-11T14:52:36.257Z","eventId":"liveEventId","userId":"admin1","message":"Tutamen non delectus templum saepe."},{"id":"cluv30sgp00e15ohvwbze4o3u","createdAt":"2024-04-11T15:05:43.257Z","eventId":"liveEventId","userId":"admin1","message":"Theca adulescens abstergo baiulus carpo tametsi correptius."}],"harmonogramItems":[{"id":"cluv30sgn00dc5ohvkvbsk6pk","createdAt":"2024-04-11T10:14:03.288Z","from":"08:04","to":"09:04","title":"victoria decipio decretum","description":"Ter aiunt ulterius defungo advenio clam odit cunctatio articulus. Tener calco cognatus defetiscor amissio asper. Decumbo admiratio stillicidium conatus antea callide amplexus.","eventId":"liveEventId"},{"id":"cluv30sgn00dd5ohvxgnawtvq","createdAt":"2024-04-11T10:14:03.288Z","from":"09:04","to":"10:04","title":"neque compello commodi","description":"Adicio quaerat spero maiores vulgo adfero vester. Accusantium desparatus vox aranea sequi uberrime. Voro substantia claustrum versus deleo maxime corrigo aedificium cupressus.","eventId":"liveEventId"},{"id":"cluv30sgn00de5ohvr3vqh1iv","createdAt":"2024-04-11T10:14:03.288Z","from":"10:04","to":"11:04","title":"vobis centum nihil","description":"Templum sub itaque terebro quaerat tego ago correptius. Pectus tepesco benevolentia audeo substantia curo aspernatur cura repellat. Sustineo chirographum credo sponte subnecto cultellus.","eventId":"liveEventId"},{"id":"cluv30sgn00df5ohv291zr5td","createdAt":"2024-04-11T10:14:03.288Z","from":"11:04","to":"12:04","title":"decretum pariatur teres creptio tenuis ait verecundia cruentus universe","description":"Cotidie urbs acceptus comitatus tum contra sustineo. Cras decumbo vicissitudo. Templum tondeo sopor consuasor.","eventId":"liveEventId"},{"id":"cluv30sgn00dh5ohvsxx8y2ie","createdAt":"2024-04-11T10:14:03.288Z","from":"12:04","to":"13:04","title":"quisquam volutabrum exercitationem carbo","description":"Arma vos doloremque quisquam appello adicio volup. Talus sufficio clibanus solio. Claro corrupti acceptus aliqua aranea argumentum derideo adfectus similique sumptus.","eventId":"liveEventId"}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/reporting":{"get":{"summary":"Get event reporting","deprecated":false,"description":"Get summary of number of hours the workers worked during event.\n- If user is ORGANISER - get all users who shosed up on event and get information about their working hours\n- If user is HARVESTER - get information about the specific harvesters working hours","tags":["Event"],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"reportingItems":{"type":"array","items":{"type":"object","properties":{"arrivedAt":{"type":"string"},"leftAt":{"type":"string"},"hoursWorked":{"type":"integer"},"user":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"required":["arrivedAt","leftAt","hoursWorked","user"]}}},"required":["reportingItems"]},"examples":{"1":{"summary":"Success","value":{"reportingItems":[{"arrivedAt":"2024-04-11T05:29:42.464Z","leftAt":"2024-04-11T11:09:49.808Z","hoursWorked":6,"user":{"id":"cluv4sn80008l11w15l5uc8im","name":"Mr. Irving Leffler"}},{"arrivedAt":"2024-04-11T05:22:42.464Z","leftAt":"2024-04-11T13:45:42.464Z","hoursWorked":9,"user":{"id":"cluv4sn80008h11w1z0rdntga","name":"Jerry Boehm"}},{"arrivedAt":"2024-04-11T05:35:42.464Z","leftAt":"2024-04-11T11:43:42.464Z","hoursWorked":7,"user":{"id":"cluv4sn80008m11w1lro6311n","name":"Sonia Maggio"}},{"arrivedAt":"2024-04-11T05:34:42.464Z","leftAt":"2024-04-11T11:09:49.808Z","hoursWorked":6,"user":{"id":"cluv4sn81008t11w1nd3qsw1l","name":"Jeffery MacGyver"}},{"arrivedAt":"2024-04-11T05:34:42.464Z","leftAt":"2024-04-11T07:34:42.464Z","hoursWorked":3,"user":{"id":"harvester1","name":"Lana Beatty Sr."}},{"arrivedAt":"2024-04-11T05:35:42.464Z","leftAt":"2024-04-11T11:09:49.808Z","hoursWorked":6,"user":{"id":"cluv4sn80008p11w1wy03b543","name":"Sergio Bernhard"}},{"arrivedAt":"2024-04-11T05:28:42.464Z","leftAt":"2024-04-11T11:09:49.808Z","hoursWorked":6,"user":{"id":"cluv4sn80008n11w1917szb1s","name":"Betsy Nicolas MD"}}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/workers":{"get":{"summary":"List of signed in workers","deprecated":false,"description":"Get information about users who signed in for certain event. This endpoint is only avaliable for organiser that created certain event.\nEvent has to be in CREATED status.","tags":["Event"],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"workers":{"type":"array","items":{"type":"object","properties":{"assignmentStatus":{"type":"string","enum":["ACTIVE","SIGNED_OFF"]},"createdAt":{"type":"string","format":"date"},"user":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string"},"phoneNumber":{"type":"string","nullable":true}},"required":["name","email","phoneNumber"]}},"required":["assignmentStatus","createdAt","user"]}}},"required":["workers"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"SERVER_ERROR","message":"That's not your fault, we are working on repair."}}}}}}},"security":[{"bearer":[]}]}},"/events/{eventId}/attendance":{"get":{"summary":"Event attendance","deprecated":false,"description":"Get attendance data of a certain event. This event has to be in IN_PROGRESS status. This endpoint is only avaliable to organiser who created the event.","tags":["Event"],"parameters":[{"name":"eventId","in":"path","description":"","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"workers":{"type":"array","items":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"assignmentStatus":{"type":"string","enum":["ACTIVE","SIGNED_OFF"]},"attendanceStatus":{"type":"string","enum":["NOT_PRESENT","DID_NOT_ARRIVE","PRESENT","LEFT"]},"arrived_at":{"type":"string","format":"date","nullable":true},"left_at":{"type":"string","format":"date","nullable":true}},"required":["attendanceStatus","arrived_at","left_at","assignmentStatus","user"]}}},"required":["workers"]},"examples":{"1":{"summary":"Success","value":{"workers":[{"user":{"id":"cluhgramk008fr032gpm60bdf","name":"Charlene Yundt"},"assignmentStatus":"ACTIVE","presenceStatus":"NOT_PRESENT","arrivedAt":null,"leftAt":null},{"user":{"id":"cluhgramk008hr032i960ess0","name":"Roxanne Kuphal IV"},"assignmentStatus":"ACTIVE","presenceStatus":"NOT_PRESENT","arrivedAt":null,"leftAt":null},{"user":{"id":"cluhgramk008gr032sg02za9a","name":"Ms. Sophie DuBuque"},"assignmentStatus":"ACTIVE","presenceStatus":"NOT_PRESENT","arrivedAt":null,"leftAt":null},{"user":{"id":"cluhgralj0036r032f0bv5pmf","name":"Darla McCullough"},"assignmentStatus":"ACTIVE","presenceStatus":"NOT_PRESENT","arrivedAt":null,"leftAt":null},{"user":{"id":"cluhgramk008ir0320fe5fkal","name":"Anne Powlowski"},"assignmentStatus":"SIGNED_OFF","presenceStatus":"LEFT","arrivedAt":null,"leftAt":null},{"user":{"id":"cluhgramk008cr032e0znk7dg","name":"Dominick Carroll"},"assignmentStatus":"ACTIVE","presenceStatus":"PRESENT","arrivedAt":null,"leftAt":null}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"","type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]},"examples":{"1":{"summary":"Unauthorized","value":{"message":"Unauthorized","code":"UNAUTHORIZED"}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"examples":{"1":{"summary":"Record not found","value":{"code":"SERVER_ERROR","message":"That's not your fault, we are working on repair."}}}}}}},"security":[{"bearer":[]}]}}},"components":{"schemas":{"Category":{"type":"object","properties":{"id":{"type":"string","description":"ID","format":"uu"},"name":{"type":"string"},"icon":{"type":"string"},"colorVariant":{"type":"string","enum":["CHERRY","LEMON","LIME","APPLE","ORANGE"]}},"required":["id","name","icon","colorVariant"]},"Location":{"properties":{"locationLat":{"type":"number","minimum":-180,"maximum":180},"locationLon":{"type":"number","minimum":-180,"maximum":180},"address":{"type":"string"},"city":{"type":"string"},"name":{"type":"string"}},"type":"object","required":["locationLat","locationLon","address","city"]},"EventCard":{"type":"object","properties":{"id":{"type":"string","format":"uu"},"name":{"type":"string"},"happeningAt":{"type":"string","format":"date"},"thumbnailURL":{"type":"string","format":"url"},"Location":{"$ref":"#/components/schemas/Location"},"sallaryType":{"type":"string","enum":["MONEY","GOODS"]},"sallaryAmount":{"type":"number","format":"float"},"sallaryUnit":{"type":"string","nullable":true},"sallaryProductName":{"type":"string","nullable":true},"status":{"type":"string","default":"'CREATED'","enum":["CREATED","PROGRESS","ARCHIVED","CANCELLED"]},"User":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"EventCategoryRelation":{"type":"array","items":{"type":"object","properties":{"EventCategory":{"$ref":"#/components/schemas/Category"}},"required":["EventCategory"]}}},"required":["id","name","happeningAt","sallaryType","status","sallaryAmount","User","Location","EventCategoryRelation"]},"User":{"properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"avatarURL":{"type":"string"},"createdAt":{"default":"CURRENT_TIMESTAMP","type":"string"},"phoneNumber":{"type":"string"},"type":{"type":"string","enum":["WORKER","COMPANY"]},"verificationToken":{"type":"string"},"password":{"type":"string"}},"type":"object","required":["id","email","name","createdAt","type","password"]},"HarmonogramItem":{"properties":{"createdAt":{"default":"CURRENT_TIMESTAMP","type":"string"},"from":{"type":"string"},"to":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"}},"type":"object","required":["createdAt","from","to","title"]},"Event":{"type":"object","properties":{"id":{"type":"string","format":"uu"},"name":{"type":"string"},"description":{"type":"string"},"happeningAt":{"type":"string","format":"date"},"thumbnailURL":{"type":"string","format":"url"},"capacity":{"type":"integer","minimum":0},"Location":{"$ref":"#/components/schemas/Location"},"sallaryType":{"type":"string","enum":["MONEY","GOODS"]},"sallaryAmount":{"type":"number","format":"float"},"sallaryUnit":{"type":"string","nullable":true},"sallaryProductName":{"type":"string","nullable":true},"toolingRequired":{"type":"string","nullable":true},"toolingProvided":{"type":"string","nullable":true},"status":{"type":"string","default":"'CREATED'","enum":["CREATED","PROGRESS","ARCHIVED","CANCELLED"]},"User":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"EventCategoryRelation":{"type":"array","items":{"type":"object","properties":{"EventCategory":{"type":"object","properties":{"id":{"type":"string","description":"ID","format":"uu"},"name":{"type":"string"},"icon":{"type":"string"},"colorVariant":{"type":"string","enum":["CHERRY","LEMON","LIME","APPLE","ORANGE"]}},"description":"ID","required":["id","name","icon","colorVariant"]}},"required":["EventCategory"]}},"_count":{"type":"object","properties":{"EventAssignment":{"type":"integer","minimum":0}},"required":["EventAssignment"]},"isOwnedByUser":{"type":"boolean"},"isUserSignedIn":{"type":"boolean"}},"required":["id","name","happeningAt","sallaryType","status","sallaryAmount","User","Location","EventCategoryRelation","description","capacity","_count","isOwnedByUser","isUserSignedIn"]},"AnnouncementItem":{"properties":{"id":{"type":"string"},"createdAt":{"default":"CURRENT_TIMESTAMP","type":"string"},"eventId":{"type":"string"},"userId":{"type":"string"},"message":{"type":"string"}},"type":"object","required":["id","createdAt","eventId","userId","message"]}},"securitySchemes":{"bearer":{"type":"http","scheme":"bearer"}}},"servers":[]} \ No newline at end of file