From f04dc2991588ca7ec183335b871bc7683abacb18 Mon Sep 17 00:00:00 2001 From: Jamal Soueidan Date: Tue, 24 Oct 2023 09:35:17 +0200 Subject: [PATCH 1/3] feat(customer): add customer availability, booking, location, product, and schedule functions This commit adds new files and functions related to customer availability, booking, location, product, and schedule. It includes the following changes: - Added customer-availability.function.ts file with the CustomerAvailabilityControllerGet function. - Added customer-booking.function.ts file with the CustomerBookingControllerGet and CustomerBookingControllerList functions. - Added customer-location.function.ts file with the CustomerLocationControllerAdd, CustomerLocationControllerCreate, CustomerLocationControllerGetAll, CustomerLocationControllerGetAllOrigins, CustomerLocationControllerGetOne, CustomerLocationControllerRemove, CustomerLocationControllerSetDefault, and CustomerLocationControllerUpdate functions. - Added customer-product.function.ts file with the CustomerProductsControllerList, CustomerProductControllerDestroy, CustomerProductControllerGet, and CustomerProductControllerUpsert functions. - Added customer-schedule.function.ts file with the CustomerScheduleControllerCreate, CustomerScheduleControllerDestroy, CustomerScheduleControllerGet, Customer chore(get.spec.ts): update import path for CustomerScheduleServiceCreate in get.spec.ts chore(upsert.spec.ts): update import path for CustomerScheduleServiceCreate in upsert.spec.ts chore(list-ids.spec.ts): update import path for CustomerScheduleServiceCreate in list-ids.spec.ts chore(list.spec.ts): update import path for CustomerScheduleServiceCreate in list.spec.ts chore(create.ts): update import path for CustomerScheduleServiceCreate in create.ts chore(destroy.spec.ts): update import path for CustomerScheduleServiceCreate in destroy.spec.ts chore(destroy.ts): update import path for CustomerScheduleServiceDestroy in destroy.ts chore(get.spec.ts): update import path for CustomerScheduleServiceCreate in get.spec.ts chore(get.ts): update import path for CustomerScheduleServiceGet in get.ts chore(list.spec.ts): update import path for CustomerScheduleServiceList in list.spec.ts chore(list.ts feat(schedule): add create, destroy, get, and getWithCustomer services feat(schedule/create): add CustomerScheduleServiceCreate function feat(schedule/destroy): add CustomerScheduleServiceDestroy function feat(schedule/get): add CustomerScheduleServiceGet function feat(schedule/getWithCustomer): add CustomerScheduleServiceGetWithCustomer function test(schedule/create.spec): add tests for CustomerScheduleServiceCreate function test(schedule/destroy.spec): add tests for CustomerScheduleServiceDestroy function test(schedule/get.spec): add tests for CustomerScheduleServiceGet function test(schedule/get-with-customer.spec): add tests for CustomerScheduleServiceGetWithCustomer function feat(schedule): add list, update, and get-with-customer services feat(schedule/list): add service to retrieve all schedules for a customerId feat(schedule/update): add service to update a schedule feat(schedule/get-with-customer): add service to retrieve a schedule with customer information fix(schedule): fix import path in user/services/schedule.spec.ts fix(availability): fix import path in generate-availability.ts --- .../customer-availability.function.ts | 12 ++ src/functions/customer-booking.function.ts | 22 ++ src/functions/customer-location.function.ts | 70 ++++++ src/functions/customer-product.function.ts | 46 ++++ src/functions/customer-schedule.function.ts | 54 +++++ src/functions/customer.function.ts | 200 ------------------ .../controllers/product/destroy.spec.ts | 2 +- .../customer/controllers/product/get.spec.ts | 2 +- .../controllers/product/upsert.spec.ts | 2 +- .../controllers/products/list-ids.spec.ts | 2 +- .../controllers/products/list.spec.ts | 2 +- .../customer/controllers/schedule/create.ts | 2 +- .../controllers/schedule/destroy.spec.ts | 2 +- .../customer/controllers/schedule/destroy.ts | 2 +- .../customer/controllers/schedule/get.spec.ts | 2 +- .../customer/controllers/schedule/get.ts | 2 +- .../controllers/schedule/list.spec.ts | 2 +- .../customer/controllers/schedule/list.ts | 2 +- .../controllers/schedule/update.spec.ts | 2 +- .../customer/controllers/schedule/update.ts | 2 +- .../customer/controllers/slot/update.spec.ts | 2 +- .../customer/services/availability.ts | 2 +- .../customer/services/product.spec.ts | 6 +- .../customer/services/schedule.spec.ts | 169 --------------- src/functions/customer/services/schedule.ts | 170 --------------- .../customer/services/schedule/create.spec.ts | 18 ++ .../customer/services/schedule/create.ts | 27 +++ .../services/schedule/destroy.spec.ts | 22 ++ .../customer/services/schedule/destroy.ts | 15 ++ .../schedule/get-with-customer.spec.ts | 65 ++++++ .../services/schedule/get-with-customer.ts | 71 +++++++ .../customer/services/schedule/get.spec.ts | 35 +++ .../customer/services/schedule/get.ts | 28 +++ .../customer/services/schedule/list.spec.ts | 18 ++ .../customer/services/schedule/list.ts | 9 + .../customer/services/schedule/update.spec.ts | 48 +++++ .../customer/services/schedule/update.ts | 32 +++ src/functions/user/services/schedule.spec.ts | 2 +- .../availability/generate-availability.ts | 5 +- 39 files changed, 614 insertions(+), 562 deletions(-) create mode 100644 src/functions/customer-availability.function.ts create mode 100644 src/functions/customer-booking.function.ts create mode 100644 src/functions/customer-location.function.ts create mode 100644 src/functions/customer-product.function.ts create mode 100644 src/functions/customer-schedule.function.ts delete mode 100644 src/functions/customer/services/schedule.spec.ts delete mode 100644 src/functions/customer/services/schedule.ts create mode 100644 src/functions/customer/services/schedule/create.spec.ts create mode 100644 src/functions/customer/services/schedule/create.ts create mode 100644 src/functions/customer/services/schedule/destroy.spec.ts create mode 100644 src/functions/customer/services/schedule/destroy.ts create mode 100644 src/functions/customer/services/schedule/get-with-customer.spec.ts create mode 100644 src/functions/customer/services/schedule/get-with-customer.ts create mode 100644 src/functions/customer/services/schedule/get.spec.ts create mode 100644 src/functions/customer/services/schedule/get.ts create mode 100644 src/functions/customer/services/schedule/list.spec.ts create mode 100644 src/functions/customer/services/schedule/list.ts create mode 100644 src/functions/customer/services/schedule/update.spec.ts create mode 100644 src/functions/customer/services/schedule/update.ts diff --git a/src/functions/customer-availability.function.ts b/src/functions/customer-availability.function.ts new file mode 100644 index 00000000..fd8d15d8 --- /dev/null +++ b/src/functions/customer-availability.function.ts @@ -0,0 +1,12 @@ +import "module-alias/register"; + +import { app } from "@azure/functions"; + +import { CustomerAvailabilityControllerGet } from "./customer/controllers/availability"; + +app.http("customerAvailabilityGet", { + methods: ["POST"], + authLevel: "anonymous", + route: "customer/{customerId?}/availability/{locationId?}/get", + handler: CustomerAvailabilityControllerGet, +}); diff --git a/src/functions/customer-booking.function.ts b/src/functions/customer-booking.function.ts new file mode 100644 index 00000000..2eb99ff6 --- /dev/null +++ b/src/functions/customer-booking.function.ts @@ -0,0 +1,22 @@ +import "module-alias/register"; + +import { app } from "@azure/functions"; + +import { + CustomerBookingControllerGet, + CustomerBookingControllerList, +} from "./customer/controllers/booking"; + +app.http("customerBookingGet", { + methods: ["GET"], + authLevel: "anonymous", + route: "customer/{customerId?}/booking/{orderId?}", + handler: CustomerBookingControllerGet, +}); + +app.http("customerBookingList", { + methods: ["GET"], + authLevel: "anonymous", + route: "customer/{customerId?}/bookings", + handler: CustomerBookingControllerList, +}); diff --git a/src/functions/customer-location.function.ts b/src/functions/customer-location.function.ts new file mode 100644 index 00000000..4aea38ef --- /dev/null +++ b/src/functions/customer-location.function.ts @@ -0,0 +1,70 @@ +import "module-alias/register"; + +import { app } from "@azure/functions"; + +import { + CustomerLocationControllerAdd, + CustomerLocationControllerCreate, + CustomerLocationControllerGetAll, + CustomerLocationControllerGetAllOrigins, + CustomerLocationControllerGetOne, + CustomerLocationControllerRemove, + CustomerLocationControllerSetDefault, + CustomerLocationControllerUpdate, +} from "./customer/controllers/location"; + +app.http("customerLocationGetAllOrigins", { + methods: ["GET"], + authLevel: "anonymous", + route: "customer/{customerId}/locations/get-all-origins", + handler: CustomerLocationControllerGetAllOrigins, +}); + +app.http("customerLocationList", { + methods: ["GET"], + authLevel: "anonymous", + route: "customer/{customerId}/locations", + handler: CustomerLocationControllerGetAll, +}); + +app.http("customerLocationGet", { + methods: ["GET"], + authLevel: "anonymous", + route: "customer/{customerId}/location/{locationId}", + handler: CustomerLocationControllerGetOne, +}); + +app.http("customerLocationUpdate", { + methods: ["PUT"], + authLevel: "anonymous", + route: "customer/{customerId}/location/{locationId?}", + handler: CustomerLocationControllerUpdate, +}); + +app.http("customerLocationCreate", { + methods: ["POST"], + authLevel: "anonymous", + route: "customer/{customerId}/locations", + handler: CustomerLocationControllerCreate, +}); + +app.http("customerLocationAdd", { + methods: ["POST"], + authLevel: "anonymous", + route: "customer/{customerId}/location/{locationId}", + handler: CustomerLocationControllerAdd, +}); + +app.http("customerLocationRemove", { + methods: ["DELETE"], + authLevel: "anonymous", + route: "customer/{customerId}/location/{locationId}", + handler: CustomerLocationControllerRemove, +}); + +app.http("customerLocationSetDefault", { + methods: ["PUT"], + authLevel: "anonymous", + route: "customer/{customerId}/location/{locationId}/setDefault", + handler: CustomerLocationControllerSetDefault, +}); diff --git a/src/functions/customer-product.function.ts b/src/functions/customer-product.function.ts new file mode 100644 index 00000000..a5f114de --- /dev/null +++ b/src/functions/customer-product.function.ts @@ -0,0 +1,46 @@ +import "module-alias/register"; +import { CustomerProductsControllerList } from "./customer/controllers/products/list"; + +import { app } from "@azure/functions"; + +import { + CustomerProductControllerDestroy, + CustomerProductControllerGet, + CustomerProductControllerUpsert, +} from "./customer/controllers/product"; +import { CustomerProductsControllerListIds } from "./customer/controllers/products"; + +app.http("customerProductsListIds", { + methods: ["GET"], + authLevel: "anonymous", + route: "customer/{customerId?}/products/ids", + handler: CustomerProductsControllerListIds, +}); + +app.http("customerProductsList", { + methods: ["GET"], + authLevel: "anonymous", + route: "customer/{customerId?}/products", + handler: CustomerProductsControllerList, +}); + +app.http("customerProductUpsert", { + methods: ["PUT"], + authLevel: "anonymous", + route: "customer/{customerId?}/product/{productId?}", + handler: CustomerProductControllerUpsert, +}); + +app.http("customerProductGet", { + methods: ["GET"], + authLevel: "anonymous", + route: "customer/{customerId?}/product/{productId?}", + handler: CustomerProductControllerGet, +}); + +app.http("customerProductDestroy", { + methods: ["DELETE"], + authLevel: "anonymous", + route: "customer/{customerId?}/product/{productId?}", + handler: CustomerProductControllerDestroy, +}); diff --git a/src/functions/customer-schedule.function.ts b/src/functions/customer-schedule.function.ts new file mode 100644 index 00000000..afedcf5d --- /dev/null +++ b/src/functions/customer-schedule.function.ts @@ -0,0 +1,54 @@ +import "module-alias/register"; + +import { app } from "@azure/functions"; + +import { + CustomerScheduleControllerCreate, + CustomerScheduleControllerDestroy, + CustomerScheduleControllerGet, + CustomerScheduleControllerList, + CustomerScheduleControllerUpdate, +} from "./customer/controllers/schedule"; +import { CustomerScheduleSlotControllerUpdate } from "./customer/controllers/slot"; + +app.http("customerScheduleDestroy", { + methods: ["DELETE"], + authLevel: "anonymous", + route: "customer/{customerId?}/schedule/{scheduleId?}", + handler: CustomerScheduleControllerDestroy, +}); + +app.http("customerScheduleCreate", { + methods: ["POST"], + authLevel: "anonymous", + route: "customer/{customerId?}/schedule", + handler: CustomerScheduleControllerCreate, +}); + +app.http("customerScheduleUpdate", { + methods: ["PUT"], + authLevel: "anonymous", + route: "customer/{customerId?}/schedule/{scheduleId?}", + handler: CustomerScheduleControllerUpdate, +}); + +app.http("customerScheduleGet", { + methods: ["GET"], + authLevel: "anonymous", + route: "customer/{customerId?}/schedule/{scheduleId?}", + handler: CustomerScheduleControllerGet, +}); + +app.http("customerScheduleList", { + methods: ["GET"], + authLevel: "anonymous", + route: "customer/{customerId?}/schedules", + handler: CustomerScheduleControllerList, +}); + +app.http("customerScheduleSlotUpdate", { + methods: ["PUT"], + authLevel: "anonymous", + route: "customer/{customerId?}/schedule/{scheduleId?}/slots", + handler: CustomerScheduleSlotControllerUpdate, +}); diff --git a/src/functions/customer.function.ts b/src/functions/customer.function.ts index 3bcc4399..bf00090e 100644 --- a/src/functions/customer.function.ts +++ b/src/functions/customer.function.ts @@ -1,13 +1,7 @@ import "module-alias/register"; -import { CustomerProductsControllerList } from "./customer/controllers/products/list"; import { app } from "@azure/functions"; -import { CustomerAvailabilityControllerGet } from "./customer/controllers/availability"; -import { - CustomerBookingControllerGet, - CustomerBookingControllerList, -} from "./customer/controllers/booking"; import { CustomerControllerGet, CustomerControllerIsBusiness, @@ -15,30 +9,6 @@ import { CustomerControllerUpdate, CustomerControllerUpsert, } from "./customer/controllers/customer"; -import { - CustomerLocationControllerAdd, - CustomerLocationControllerCreate, - CustomerLocationControllerGetAll, - CustomerLocationControllerGetAllOrigins, - CustomerLocationControllerGetOne, - CustomerLocationControllerRemove, - CustomerLocationControllerSetDefault, - CustomerLocationControllerUpdate, -} from "./customer/controllers/location"; -import { - CustomerProductControllerDestroy, - CustomerProductControllerGet, - CustomerProductControllerUpsert, -} from "./customer/controllers/product"; -import { CustomerProductsControllerListIds } from "./customer/controllers/products"; -import { - CustomerScheduleControllerCreate, - CustomerScheduleControllerDestroy, - CustomerScheduleControllerGet, - CustomerScheduleControllerList, - CustomerScheduleControllerUpdate, -} from "./customer/controllers/schedule"; -import { CustomerScheduleSlotControllerUpdate } from "./customer/controllers/slot"; /* Customer */ @@ -76,173 +46,3 @@ app.http("customerStatus", { route: "customer/{customerId?}/status", handler: CustomerControllerStatus, }); - -/* **************** */ -/* Customer/Product */ -/* **************** */ - -app.http("customerProductsListIds", { - methods: ["GET"], - authLevel: "anonymous", - route: "customer/{customerId?}/products/ids", - handler: CustomerProductsControllerListIds, -}); - -app.http("customerProductsList", { - methods: ["GET"], - authLevel: "anonymous", - route: "customer/{customerId?}/products", - handler: CustomerProductsControllerList, -}); - -app.http("customerAvailabilityGet", { - methods: ["POST"], - authLevel: "anonymous", - route: "customer/{customerId?}/availability/{locationId?}/get", - handler: CustomerAvailabilityControllerGet, -}); - -app.http("customerProductUpsert", { - methods: ["PUT"], - authLevel: "anonymous", - route: "customer/{customerId?}/product/{productId?}", - handler: CustomerProductControllerUpsert, -}); - -app.http("customerProductGet", { - methods: ["GET"], - authLevel: "anonymous", - route: "customer/{customerId?}/product/{productId?}", - handler: CustomerProductControllerGet, -}); - -app.http("customerProductDestroy", { - methods: ["DELETE"], - authLevel: "anonymous", - route: "customer/{customerId?}/product/{productId?}", - handler: CustomerProductControllerDestroy, -}); - -/* ******* */ -/* Booking */ -/* ******* */ - -app.http("customerBookingGet", { - methods: ["GET"], - authLevel: "anonymous", - route: "customer/{customerId?}/booking/{orderId?}", - handler: CustomerBookingControllerGet, -}); - -app.http("customerBookingList", { - methods: ["GET"], - authLevel: "anonymous", - route: "customer/{customerId?}/bookings", - handler: CustomerBookingControllerList, -}); - -/* ******* */ -/* Location */ -/* ******* */ - -app.http("customerLocationGetAllOrigins", { - methods: ["GET"], - authLevel: "anonymous", - route: "customer/{customerId}/locations/get-all-origins", - handler: CustomerLocationControllerGetAllOrigins, -}); - -app.http("customerLocationList", { - methods: ["GET"], - authLevel: "anonymous", - route: "customer/{customerId}/locations", - handler: CustomerLocationControllerGetAll, -}); - -app.http("customerLocationGet", { - methods: ["GET"], - authLevel: "anonymous", - route: "customer/{customerId}/location/{locationId}", - handler: CustomerLocationControllerGetOne, -}); - -app.http("customerLocationUpdate", { - methods: ["PUT"], - authLevel: "anonymous", - route: "customer/{customerId}/location/{locationId?}", - handler: CustomerLocationControllerUpdate, -}); - -app.http("customerLocationCreate", { - methods: ["POST"], - authLevel: "anonymous", - route: "customer/{customerId}/locations", - handler: CustomerLocationControllerCreate, -}); - -app.http("customerLocationAdd", { - methods: ["POST"], - authLevel: "anonymous", - route: "customer/{customerId}/location/{locationId}", - handler: CustomerLocationControllerAdd, -}); - -app.http("customerLocationRemove", { - methods: ["DELETE"], - authLevel: "anonymous", - route: "customer/{customerId}/location/{locationId}", - handler: CustomerLocationControllerRemove, -}); - -app.http("customerLocationSetDefault", { - methods: ["PUT"], - authLevel: "anonymous", - route: "customer/{customerId}/location/{locationId}/setDefault", - handler: CustomerLocationControllerSetDefault, -}); - -/* ******** */ -/* Schedule -/* ******** */ - -app.http("customerScheduleDestroy", { - methods: ["DELETE"], - authLevel: "anonymous", - route: "customer/{customerId?}/schedule/{scheduleId?}", - handler: CustomerScheduleControllerDestroy, -}); - -app.http("customerScheduleCreate", { - methods: ["POST"], - authLevel: "anonymous", - route: "customer/{customerId?}/schedule", - handler: CustomerScheduleControllerCreate, -}); - -app.http("customerScheduleUpdate", { - methods: ["PUT"], - authLevel: "anonymous", - route: "customer/{customerId?}/schedule/{scheduleId?}", - handler: CustomerScheduleControllerUpdate, -}); - -app.http("customerScheduleGet", { - methods: ["GET"], - authLevel: "anonymous", - route: "customer/{customerId?}/schedule/{scheduleId?}", - handler: CustomerScheduleControllerGet, -}); - -app.http("customerScheduleList", { - methods: ["GET"], - authLevel: "anonymous", - route: "customer/{customerId?}/schedules", - handler: CustomerScheduleControllerList, -}); - -app.http("customerScheduleSlotUpdate", { - methods: ["PUT"], - authLevel: "anonymous", - route: "customer/{customerId?}/schedule/{scheduleId?}/slots", - handler: CustomerScheduleSlotControllerUpdate, -}); diff --git a/src/functions/customer/controllers/product/destroy.spec.ts b/src/functions/customer/controllers/product/destroy.spec.ts index affdd2c8..02569bfe 100644 --- a/src/functions/customer/controllers/product/destroy.spec.ts +++ b/src/functions/customer/controllers/product/destroy.spec.ts @@ -9,7 +9,7 @@ import { import { omitObjectIdProps } from "~/library/jest/helpers"; import { CustomerProductServiceUpsert } from "../../services/product"; -import { CustomerScheduleServiceCreate } from "../../services/schedule"; +import { CustomerScheduleServiceCreate } from "../../services/schedule/create"; import { CustomerProductControllerDestroy, CustomerProductControllerDestroyRequest, diff --git a/src/functions/customer/controllers/product/get.spec.ts b/src/functions/customer/controllers/product/get.spec.ts index 2344d300..942d16ec 100644 --- a/src/functions/customer/controllers/product/get.spec.ts +++ b/src/functions/customer/controllers/product/get.spec.ts @@ -8,7 +8,7 @@ import { createHttpRequest, } from "~/library/jest/azure"; import { CustomerProductServiceUpsert } from "../../services/product"; -import { CustomerScheduleServiceCreate } from "../../services/schedule"; +import { CustomerScheduleServiceCreate } from "../../services/schedule/create"; import { CustomerProductControllerGet, CustomerProductControllerGetRequest, diff --git a/src/functions/customer/controllers/product/upsert.spec.ts b/src/functions/customer/controllers/product/upsert.spec.ts index 65047944..8ce09a76 100644 --- a/src/functions/customer/controllers/product/upsert.spec.ts +++ b/src/functions/customer/controllers/product/upsert.spec.ts @@ -7,7 +7,7 @@ import { } from "~/library/jest/azure"; import { ScheduleProduct, TimeUnit } from "~/functions/schedule"; -import { CustomerScheduleServiceCreate } from "../../services/schedule"; +import { CustomerScheduleServiceCreate } from "../../services/schedule/create"; import { CustomerProductControllerUpsert, CustomerProductControllerUpsertRequest, diff --git a/src/functions/customer/controllers/products/list-ids.spec.ts b/src/functions/customer/controllers/products/list-ids.spec.ts index b8fec2c5..d3a47818 100644 --- a/src/functions/customer/controllers/products/list-ids.spec.ts +++ b/src/functions/customer/controllers/products/list-ids.spec.ts @@ -7,7 +7,7 @@ import { createContext, createHttpRequest, } from "~/library/jest/azure"; -import { CustomerScheduleServiceCreate } from "../../services/schedule"; +import { CustomerScheduleServiceCreate } from "../../services/schedule/create"; import { CustomerProductsControllerListIds, CustomerProductsControllerListIdsRequest, diff --git a/src/functions/customer/controllers/products/list.spec.ts b/src/functions/customer/controllers/products/list.spec.ts index 32ffc337..e0005963 100644 --- a/src/functions/customer/controllers/products/list.spec.ts +++ b/src/functions/customer/controllers/products/list.spec.ts @@ -9,7 +9,7 @@ import { } from "~/library/jest/azure"; import { CustomerProductServiceUpsert } from "../../services/product"; -import { CustomerScheduleServiceCreate } from "../../services/schedule"; +import { CustomerScheduleServiceCreate } from "../../services/schedule/create"; import { CustomerProductsControllerList, CustomerProductsControllerListRequest, diff --git a/src/functions/customer/controllers/schedule/create.ts b/src/functions/customer/controllers/schedule/create.ts index 0de7216e..14557fb3 100644 --- a/src/functions/customer/controllers/schedule/create.ts +++ b/src/functions/customer/controllers/schedule/create.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { ScheduleZodSchema } from "~/functions/schedule"; import { _ } from "~/library/handler"; -import { CustomerScheduleServiceCreate } from "../../services/schedule"; +import { CustomerScheduleServiceCreate } from "../../services/schedule/create"; export type CustomerScheduleControllerCreateRequest = { query: z.infer; diff --git a/src/functions/customer/controllers/schedule/destroy.spec.ts b/src/functions/customer/controllers/schedule/destroy.spec.ts index 1bc29dab..08708690 100644 --- a/src/functions/customer/controllers/schedule/destroy.spec.ts +++ b/src/functions/customer/controllers/schedule/destroy.spec.ts @@ -4,7 +4,7 @@ import { createContext, createHttpRequest, } from "~/library/jest/azure"; -import { CustomerScheduleServiceCreate } from "../../services/schedule"; +import { CustomerScheduleServiceCreate } from "../../services/schedule/create"; import { CustomerScheduleControllerDestroy, CustomerScheduleControllerDestroyRequest, diff --git a/src/functions/customer/controllers/schedule/destroy.ts b/src/functions/customer/controllers/schedule/destroy.ts index e96dfe4e..66e93dfb 100644 --- a/src/functions/customer/controllers/schedule/destroy.ts +++ b/src/functions/customer/controllers/schedule/destroy.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { ScheduleZodSchema } from "~/functions/schedule/schedule.types"; import { _ } from "~/library/handler"; -import { CustomerScheduleServiceDestroy } from "../../services/schedule"; +import { CustomerScheduleServiceDestroy } from "../../services/schedule/destroy"; export type CustomerScheduleControllerDestroyRequest = { query: z.infer; diff --git a/src/functions/customer/controllers/schedule/get.spec.ts b/src/functions/customer/controllers/schedule/get.spec.ts index f47c9b4c..e1e9d745 100644 --- a/src/functions/customer/controllers/schedule/get.spec.ts +++ b/src/functions/customer/controllers/schedule/get.spec.ts @@ -5,7 +5,7 @@ import { createContext, createHttpRequest, } from "~/library/jest/azure"; -import { CustomerScheduleServiceCreate } from "../../services/schedule"; +import { CustomerScheduleServiceCreate } from "../../services/schedule/create"; import { CustomerScheduleControllerGet, CustomerScheduleControllerGetRequest, diff --git a/src/functions/customer/controllers/schedule/get.ts b/src/functions/customer/controllers/schedule/get.ts index 0bd8b477..069c67d9 100644 --- a/src/functions/customer/controllers/schedule/get.ts +++ b/src/functions/customer/controllers/schedule/get.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { ScheduleZodSchema } from "~/functions/schedule"; import { _ } from "~/library/handler"; -import { CustomerScheduleServiceGet } from "../../services/schedule"; +import { CustomerScheduleServiceGet } from "../../services/schedule/get"; export type CustomerScheduleControllerGetRequest = { query: z.infer; diff --git a/src/functions/customer/controllers/schedule/list.spec.ts b/src/functions/customer/controllers/schedule/list.spec.ts index c59a8385..def5d69b 100644 --- a/src/functions/customer/controllers/schedule/list.spec.ts +++ b/src/functions/customer/controllers/schedule/list.spec.ts @@ -6,7 +6,7 @@ import { createHttpRequest, } from "~/library/jest/azure"; -import { CustomerScheduleServiceCreate } from "../../services/schedule"; +import { CustomerScheduleServiceCreate } from "../../services/schedule/create"; import { CustomerScheduleControllerList, CustomerScheduleControllerListRequest, diff --git a/src/functions/customer/controllers/schedule/list.ts b/src/functions/customer/controllers/schedule/list.ts index 695e912a..ef93afa7 100644 --- a/src/functions/customer/controllers/schedule/list.ts +++ b/src/functions/customer/controllers/schedule/list.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { ScheduleZodSchema } from "~/functions/schedule/schedule.types"; import { _ } from "~/library/handler"; -import { CustomerScheduleServiceList } from "../../services/schedule"; +import { CustomerScheduleServiceList } from "../../services/schedule/list"; export type CustomerScheduleControllerListRequest = { query: z.infer; diff --git a/src/functions/customer/controllers/schedule/update.spec.ts b/src/functions/customer/controllers/schedule/update.spec.ts index c7bdedf4..dfc170a5 100644 --- a/src/functions/customer/controllers/schedule/update.spec.ts +++ b/src/functions/customer/controllers/schedule/update.spec.ts @@ -6,7 +6,7 @@ import { createHttpRequest, } from "~/library/jest/azure"; -import { CustomerScheduleServiceCreate } from "../../services/schedule"; +import { CustomerScheduleServiceCreate } from "../../services/schedule/create"; import { CustomerScheduleControllerUpdate, CustomerScheduleControllerUpdateRequest, diff --git a/src/functions/customer/controllers/schedule/update.ts b/src/functions/customer/controllers/schedule/update.ts index 40a2ad4c..023947c5 100644 --- a/src/functions/customer/controllers/schedule/update.ts +++ b/src/functions/customer/controllers/schedule/update.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { ScheduleZodSchema } from "~/functions/schedule/schedule.types"; import { _ } from "~/library/handler"; -import { CustomerScheduleServiceUpdate } from "../../services/schedule"; +import { CustomerScheduleServiceUpdate } from "../../services/schedule/update"; export type CustomerScheduleControllerUpdateRequest = { query: z.infer; diff --git a/src/functions/customer/controllers/slot/update.spec.ts b/src/functions/customer/controllers/slot/update.spec.ts index ae75d22a..91024ece 100644 --- a/src/functions/customer/controllers/slot/update.spec.ts +++ b/src/functions/customer/controllers/slot/update.spec.ts @@ -6,7 +6,7 @@ import { createHttpRequest, } from "~/library/jest/azure"; -import { CustomerScheduleServiceCreate } from "../../services/schedule"; +import { CustomerScheduleServiceCreate } from "../../services/schedule/create"; import { CustomerScheduleSlotControllerUpdate, CustomerScheduleSlotControllerUpdateRequest, diff --git a/src/functions/customer/services/availability.ts b/src/functions/customer/services/availability.ts index b7f21494..a6300705 100644 --- a/src/functions/customer/services/availability.ts +++ b/src/functions/customer/services/availability.ts @@ -6,7 +6,7 @@ import { findStartAndEndDate } from "~/library/availability/find-start-end-date- import { generateAvailability } from "~/library/availability/generate-availability"; import { removeBookedSlots } from "~/library/availability/remove-booked-slots"; import { CustomerBookingServiceGetBooked } from "./booking"; -import { CustomerScheduleServiceGetWithCustomer } from "./schedule"; +import { CustomerScheduleServiceGetWithCustomer } from "./schedule/get-with-customer"; export type CustomerAvailabilityServiceGetProps = { customerId: Schedule["customerId"]; diff --git a/src/functions/customer/services/product.spec.ts b/src/functions/customer/services/product.spec.ts index ab1cc5fd..d3f7196b 100644 --- a/src/functions/customer/services/product.spec.ts +++ b/src/functions/customer/services/product.spec.ts @@ -12,10 +12,8 @@ import { CustomerProductsServiceList, CustomerProductsServiceListIds, } from "./product"; -import { - CustomerScheduleServiceCreate, - CustomerScheduleServiceGet, -} from "./schedule"; +import { CustomerScheduleServiceCreate } from "./schedule/create"; +import { CustomerScheduleServiceGet } from "./schedule/get"; require("~/library/jest/mongoose/mongodb.jest"); diff --git a/src/functions/customer/services/schedule.spec.ts b/src/functions/customer/services/schedule.spec.ts deleted file mode 100644 index 0ad80af7..00000000 --- a/src/functions/customer/services/schedule.spec.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { NotFoundError } from "~/library/handler"; -import { arrayElements, createUser } from "~/library/jest/helpers"; -import { createSchedule } from "~/library/jest/helpers/schedule"; -import { - CustomerScheduleServiceCreate, - CustomerScheduleServiceDestroy, - CustomerScheduleServiceGet, - CustomerScheduleServiceGetWithCustomer, - CustomerScheduleServiceGetWithCustomerResponse, - CustomerScheduleServiceList, - CustomerScheduleServiceUpdate, -} from "./schedule"; - -require("~/library/jest/mongoose/mongodb.jest"); - -describe("CustomerScheduleService", () => { - const customerId = 123; - const name = "Test Schedule"; - - it("should create a new schedule", async () => { - const newSchedule = await CustomerScheduleServiceCreate({ - name, - customerId, - }); - - expect(newSchedule.name).toEqual(name); - expect(newSchedule.customerId).toEqual(customerId); - }); - - it("should delete an existing schedule", async () => { - const newSchedule = await CustomerScheduleServiceCreate({ - name, - customerId, - }); - const deleteResult = await CustomerScheduleServiceDestroy({ - scheduleId: newSchedule._id, - customerId: newSchedule.customerId, - }); - - expect(deleteResult.deletedCount).toEqual(1); - }); - - it("should update schedule", async () => { - const newSchedule = await CustomerScheduleServiceCreate({ - name, - customerId, - }); - const updatedScheduleName = "Updated Test Schedule"; - - const updatedSchedule = await CustomerScheduleServiceUpdate( - { - scheduleId: newSchedule._id, - customerId: newSchedule.customerId, - }, - { - name: updatedScheduleName, - } - ); - expect(updatedSchedule).toMatchObject({ - name: updatedScheduleName, - }); - }); - - it("should throw NotFoundError when trying to update schedule that is not found", async () => { - const newSchedule = await CustomerScheduleServiceCreate({ - name, - customerId, - }); - const updatedScheduleName = "Updated Test Schedule"; - - await expect( - CustomerScheduleServiceUpdate( - { scheduleId: newSchedule._id, customerId: 0 }, - { - name: updatedScheduleName, - } - ) - ).rejects.toThrow(NotFoundError); - }); - - it("should return all schedules for a customerId", async () => { - await CustomerScheduleServiceCreate({ name, customerId }); - await CustomerScheduleServiceCreate({ name: "asd", customerId: 123 }); - - const schedules = await CustomerScheduleServiceList({ customerId }); - - expect(schedules.length).toEqual(2); - }); - - it("should return a specific schedule", async () => { - const newSchedule = await CustomerScheduleServiceCreate({ - name, - customerId, - }); - const retrievedSchedule = await CustomerScheduleServiceGet({ - scheduleId: newSchedule._id, - customerId: newSchedule.customerId, - }); - - expect(retrievedSchedule._id.toString()).toEqual( - newSchedule._id.toString() - ); - }); - - it("should throw NotFoundError when trying to get schedule that is not found", async () => { - const newSchedule = await CustomerScheduleServiceCreate({ - name, - customerId, - }); - await expect( - CustomerScheduleServiceGet({ scheduleId: newSchedule._id, customerId: 0 }) - ).rejects.toThrow(NotFoundError); - }); - - it("should return schedule with customer", async () => { - await createUser({ customerId }); - - // test with one known productId and one unknown - const schedule1 = await createSchedule( - { - customerId, - }, - { - totalProducts: 3, - days: ["monday", "tuesday"], - locations: [], - } - ); - - let productIds = arrayElements( - schedule1.products.map((p) => p.productId), - 1 - ); - - await expect( - CustomerScheduleServiceGetWithCustomer({ - customerId, - productIds: [...productIds, 1], - }) - ).rejects.toThrow(NotFoundError); - - // test with real productIds - const schedule2 = await createSchedule( - { - customerId, - }, - { - totalProducts: 3, - days: ["wednesday", "thursday"], - locations: [], - } - ); - - productIds = arrayElements( - schedule2.products.map((p) => p.productId), - 2 - ); - - const schedule: CustomerScheduleServiceGetWithCustomerResponse = - await CustomerScheduleServiceGetWithCustomer({ - customerId, - productIds, - }); - - schedule.products.forEach((product) => { - expect(productIds).toContain(product.productId); - }); - }); -}); diff --git a/src/functions/customer/services/schedule.ts b/src/functions/customer/services/schedule.ts deleted file mode 100644 index da5d5c79..00000000 --- a/src/functions/customer/services/schedule.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { Schedule, ScheduleModel, ScheduleProduct } from "~/functions/schedule"; -import { NotFoundError } from "~/library/handler"; - -type CustomerScheduleServiceCreateBody = Pick & - Pick, "products">; - -export const CustomerScheduleServiceCreate = async ( - props: CustomerScheduleServiceCreateBody -) => { - const newSchedule = new ScheduleModel({ - ...props, - slots: [ - { - day: "monday", - intervals: [ - { - from: "8:00", - to: "16:00", - }, - ], - }, - ], - }); - return newSchedule.save(); -}; - -type CustomerScheduleServiceDestroyProps = { - scheduleId: Schedule["_id"]; - customerId: Schedule["customerId"]; -}; - -export const CustomerScheduleServiceDestroy = async ( - props: CustomerScheduleServiceDestroyProps -) => { - return ScheduleModel.deleteOne({ - _id: props.scheduleId, - customerId: props.customerId, - }); -}; - -type ScheduleServiceUpdateProps = { - scheduleId: Schedule["_id"]; - customerId: Schedule["customerId"]; -}; - -type CustomerScheduleServiceUpdateBody = Pick; - -export const CustomerScheduleServiceUpdate = async ( - filter: ScheduleServiceUpdateProps, - body: CustomerScheduleServiceUpdateBody -) => { - const updatedSchedule = await ScheduleModel.findOneAndUpdate( - { _id: filter.scheduleId, customerId: filter.customerId }, - body, - { - new: true, - } - ).orFail( - new NotFoundError([ - { - code: "custom", - message: "SCHEDULE_NOT_FOUND", - path: ["schedule"], - }, - ]) - ); - - return updatedSchedule; -}; - -type CustomerScheduleServiceListProps = Pick; - -export const CustomerScheduleServiceList = async ( - filter: CustomerScheduleServiceListProps -) => { - return ScheduleModel.find(filter).sort("created_at").lean(); -}; - -type CustomerScheduleServiceGetProps = { - scheduleId: Schedule["_id"]; - customerId: Schedule["customerId"]; -}; - -export const CustomerScheduleServiceGet = async ( - filter: CustomerScheduleServiceGetProps -) => { - const schedule = await ScheduleModel.findOne({ - _id: filter.scheduleId, - customerId: filter.customerId, - }) - .lean() - .orFail( - new NotFoundError([ - { - code: "custom", - message: "SCHEDULE_NOT_FOUND", - path: ["schedule"], - }, - ]) - ); - - return schedule; -}; - -export type CustomerScheduleServiceGetWithCustomerProps = { - customerId: Schedule["customerId"]; - productIds: Array; -}; - -export type CustomerScheduleServiceGetWithCustomerResponse = Schedule & { - customer: { - fullname: string; - }; -}; - -export const CustomerScheduleServiceGetWithCustomer = async ( - props: CustomerScheduleServiceGetWithCustomerProps -) => { - const schedules = await ScheduleModel.aggregate([ - { - $match: { - customerId: props.customerId, - "products.productId": { $all: props.productIds }, - }, - }, - { $unwind: "$products" }, - { $match: { "products.productId": { $in: props.productIds } } }, - { - $group: { - _id: "$_id", - name: { $first: "$name" }, - slots: { $first: "$slots" }, - customerId: { $first: "$customerId" }, - products: { $push: "$products" }, - }, - }, - { - $lookup: { - from: "User", - localField: "customerId", - foreignField: "customerId", - as: "customer", - }, - }, - { $unwind: "$customer" }, - { - $project: { - name: 1, - customerId: 1, - slots: 1, - products: 1, - customer: { - fullname: 1, - }, - }, - }, - ]); - - if (!schedules || schedules.length === 0) { - throw new NotFoundError([ - { - code: "custom", - message: "PRODUCTS_NOT_FOUND", - path: ["productIds"], - }, - ]); - } - - return schedules[0]; -}; diff --git a/src/functions/customer/services/schedule/create.spec.ts b/src/functions/customer/services/schedule/create.spec.ts new file mode 100644 index 00000000..6310d89f --- /dev/null +++ b/src/functions/customer/services/schedule/create.spec.ts @@ -0,0 +1,18 @@ +import { CustomerScheduleServiceCreate } from "./create"; + +require("~/library/jest/mongoose/mongodb.jest"); + +describe("CustomerScheduleServiceCreate", () => { + const customerId = 123; + const name = "Test Schedule"; + + it("should create a new schedule", async () => { + const newSchedule = await CustomerScheduleServiceCreate({ + name, + customerId, + }); + + expect(newSchedule.name).toEqual(name); + expect(newSchedule.customerId).toEqual(customerId); + }); +}); diff --git a/src/functions/customer/services/schedule/create.ts b/src/functions/customer/services/schedule/create.ts new file mode 100644 index 00000000..42a32dfb --- /dev/null +++ b/src/functions/customer/services/schedule/create.ts @@ -0,0 +1,27 @@ +import { Schedule, ScheduleModel } from "~/functions/schedule"; + +export type CustomerScheduleServiceCreateBody = Pick< + Schedule, + "name" | "customerId" +> & + Pick, "products">; + +export const CustomerScheduleServiceCreate = async ( + props: CustomerScheduleServiceCreateBody +) => { + const newSchedule = new ScheduleModel({ + ...props, + slots: [ + { + day: "monday", + intervals: [ + { + from: "8:00", + to: "16:00", + }, + ], + }, + ], + }); + return newSchedule.save(); +}; diff --git a/src/functions/customer/services/schedule/destroy.spec.ts b/src/functions/customer/services/schedule/destroy.spec.ts new file mode 100644 index 00000000..d7256c9b --- /dev/null +++ b/src/functions/customer/services/schedule/destroy.spec.ts @@ -0,0 +1,22 @@ +import { CustomerScheduleServiceCreate } from "./create"; +import { CustomerScheduleServiceDestroy } from "./destroy"; + +require("~/library/jest/mongoose/mongodb.jest"); + +describe("CustomerScheduleServiceDestroy", () => { + const customerId = 123; + const name = "Test Schedule"; + + it("should delete an existing schedule", async () => { + const newSchedule = await CustomerScheduleServiceCreate({ + name, + customerId, + }); + const deleteResult = await CustomerScheduleServiceDestroy({ + scheduleId: newSchedule._id, + customerId: newSchedule.customerId, + }); + + expect(deleteResult.deletedCount).toEqual(1); + }); +}); diff --git a/src/functions/customer/services/schedule/destroy.ts b/src/functions/customer/services/schedule/destroy.ts new file mode 100644 index 00000000..711d5c93 --- /dev/null +++ b/src/functions/customer/services/schedule/destroy.ts @@ -0,0 +1,15 @@ +import { Schedule, ScheduleModel } from "~/functions/schedule"; + +export type CustomerScheduleServiceDestroyProps = { + scheduleId: Schedule["_id"]; + customerId: Schedule["customerId"]; +}; + +export const CustomerScheduleServiceDestroy = async ( + props: CustomerScheduleServiceDestroyProps +) => { + return ScheduleModel.deleteOne({ + _id: props.scheduleId, + customerId: props.customerId, + }); +}; diff --git a/src/functions/customer/services/schedule/get-with-customer.spec.ts b/src/functions/customer/services/schedule/get-with-customer.spec.ts new file mode 100644 index 00000000..ae0a1937 --- /dev/null +++ b/src/functions/customer/services/schedule/get-with-customer.spec.ts @@ -0,0 +1,65 @@ +import { NotFoundError } from "~/library/handler"; +import { arrayElements, createUser } from "~/library/jest/helpers"; +import { createSchedule } from "~/library/jest/helpers/schedule"; +import { CustomerScheduleServiceGetWithCustomer } from "./get-with-customer"; + +require("~/library/jest/mongoose/mongodb.jest"); + +describe("CustomerScheduleServiceGetWithCustomer", () => { + const customerId = 123; + const name = "Test Schedule"; + + it("should return schedule with customer", async () => { + await createUser({ customerId }); + + // test with one known productId and one unknown + const schedule1 = await createSchedule( + { + customerId, + }, + { + totalProducts: 3, + days: ["monday", "tuesday"], + locations: [], + } + ); + + let productIds = arrayElements( + schedule1.products.map((p) => p.productId), + 1 + ); + + await expect( + CustomerScheduleServiceGetWithCustomer({ + customerId, + productIds: [...productIds, 1], + }) + ).rejects.toThrow(NotFoundError); + + // test with real productIds + const schedule2 = await createSchedule( + { + customerId, + }, + { + totalProducts: 3, + days: ["wednesday", "thursday"], + locations: [], + } + ); + + productIds = arrayElements( + schedule2.products.map((p) => p.productId), + 2 + ); + + const schedule = await CustomerScheduleServiceGetWithCustomer({ + customerId, + productIds, + }); + + schedule.products.forEach((product) => { + expect(productIds).toContain(product.productId); + }); + }); +}); diff --git a/src/functions/customer/services/schedule/get-with-customer.ts b/src/functions/customer/services/schedule/get-with-customer.ts new file mode 100644 index 00000000..aa998d9e --- /dev/null +++ b/src/functions/customer/services/schedule/get-with-customer.ts @@ -0,0 +1,71 @@ +import { Schedule, ScheduleModel, ScheduleProduct } from "~/functions/schedule"; +import { User } from "~/functions/user"; +import { NotFoundError } from "~/library/handler"; + +export type CustomerScheduleServiceGetWithCustomerProps = { + customerId: Schedule["customerId"]; + productIds: Array; +}; + +export type CustomerScheduleServiceGetWithCustomerResponse = Schedule & { + customer: Pick; +}; + +export const CustomerScheduleServiceGetWithCustomer = async ( + props: CustomerScheduleServiceGetWithCustomerProps +) => { + const schedules = + await ScheduleModel.aggregate( + [ + { + $match: { + customerId: props.customerId, + "products.productId": { $all: props.productIds }, + }, + }, + { $unwind: "$products" }, + { $match: { "products.productId": { $in: props.productIds } } }, + { + $group: { + _id: "$_id", + name: { $first: "$name" }, + slots: { $first: "$slots" }, + customerId: { $first: "$customerId" }, + products: { $push: "$products" }, + }, + }, + { + $lookup: { + from: "User", + localField: "customerId", + foreignField: "customerId", + as: "customer", + }, + }, + { $unwind: "$customer" }, + { + $project: { + name: 1, + customerId: 1, + slots: 1, + products: 1, + customer: { + fullname: 1, + }, + }, + }, + ] + ); + + if (!schedules || schedules.length === 0) { + throw new NotFoundError([ + { + code: "custom", + message: "PRODUCTS_NOT_FOUND", + path: ["productIds"], + }, + ]); + } + + return schedules[0]; +}; diff --git a/src/functions/customer/services/schedule/get.spec.ts b/src/functions/customer/services/schedule/get.spec.ts new file mode 100644 index 00000000..39626e06 --- /dev/null +++ b/src/functions/customer/services/schedule/get.spec.ts @@ -0,0 +1,35 @@ +import { NotFoundError } from "~/library/handler"; +import { CustomerScheduleServiceCreate } from "./create"; +import { CustomerScheduleServiceGet } from "./get"; + +require("~/library/jest/mongoose/mongodb.jest"); + +describe("CustomerScheduleServiceGet", () => { + const customerId = 123; + const name = "Test Schedule"; + + it("should return a specific schedule", async () => { + const newSchedule = await CustomerScheduleServiceCreate({ + name, + customerId, + }); + const retrievedSchedule = await CustomerScheduleServiceGet({ + scheduleId: newSchedule._id, + customerId: newSchedule.customerId, + }); + + expect(retrievedSchedule._id.toString()).toEqual( + newSchedule._id.toString() + ); + }); + + it("should throw NotFoundError when trying to get schedule that is not found", async () => { + const newSchedule = await CustomerScheduleServiceCreate({ + name, + customerId, + }); + await expect( + CustomerScheduleServiceGet({ scheduleId: newSchedule._id, customerId: 0 }) + ).rejects.toThrow(NotFoundError); + }); +}); diff --git a/src/functions/customer/services/schedule/get.ts b/src/functions/customer/services/schedule/get.ts new file mode 100644 index 00000000..2c14e7fb --- /dev/null +++ b/src/functions/customer/services/schedule/get.ts @@ -0,0 +1,28 @@ +import { Schedule, ScheduleModel } from "~/functions/schedule"; +import { NotFoundError } from "~/library/handler"; + +export type CustomerScheduleServiceGetProps = { + scheduleId: Schedule["_id"]; + customerId: Schedule["customerId"]; +}; + +export const CustomerScheduleServiceGet = async ( + filter: CustomerScheduleServiceGetProps +) => { + const schedule = await ScheduleModel.findOne({ + _id: filter.scheduleId, + customerId: filter.customerId, + }) + .lean() + .orFail( + new NotFoundError([ + { + code: "custom", + message: "SCHEDULE_NOT_FOUND", + path: ["schedule"], + }, + ]) + ); + + return schedule; +}; diff --git a/src/functions/customer/services/schedule/list.spec.ts b/src/functions/customer/services/schedule/list.spec.ts new file mode 100644 index 00000000..28405643 --- /dev/null +++ b/src/functions/customer/services/schedule/list.spec.ts @@ -0,0 +1,18 @@ +import { CustomerScheduleServiceCreate } from "./create"; +import { CustomerScheduleServiceList } from "./list"; + +require("~/library/jest/mongoose/mongodb.jest"); + +describe("CustomerScheduleServiceList", () => { + const customerId = 123; + const name = "Test Schedule"; + + it("should return all schedules for a customerId", async () => { + await CustomerScheduleServiceCreate({ name, customerId }); + await CustomerScheduleServiceCreate({ name: "asd", customerId: 123 }); + + const schedules = await CustomerScheduleServiceList({ customerId }); + + expect(schedules.length).toEqual(2); + }); +}); diff --git a/src/functions/customer/services/schedule/list.ts b/src/functions/customer/services/schedule/list.ts new file mode 100644 index 00000000..2853f67c --- /dev/null +++ b/src/functions/customer/services/schedule/list.ts @@ -0,0 +1,9 @@ +import { Schedule, ScheduleModel } from "~/functions/schedule"; + +export type CustomerScheduleServiceListProps = Pick; + +export const CustomerScheduleServiceList = async ( + filter: CustomerScheduleServiceListProps +) => { + return ScheduleModel.find(filter).sort("created_at").lean(); +}; diff --git a/src/functions/customer/services/schedule/update.spec.ts b/src/functions/customer/services/schedule/update.spec.ts new file mode 100644 index 00000000..9c4e7d68 --- /dev/null +++ b/src/functions/customer/services/schedule/update.spec.ts @@ -0,0 +1,48 @@ +import { NotFoundError } from "~/library/handler"; +import { CustomerScheduleServiceCreate } from "./create"; +import { CustomerScheduleServiceUpdate } from "./update"; + +require("~/library/jest/mongoose/mongodb.jest"); + +describe("CustomerScheduleServiceUpdate", () => { + const customerId = 123; + const name = "Test Schedule"; + + it("should update schedule", async () => { + const newSchedule = await CustomerScheduleServiceCreate({ + name, + customerId, + }); + const updatedScheduleName = "Updated Test Schedule"; + + const updatedSchedule = await CustomerScheduleServiceUpdate( + { + scheduleId: newSchedule._id, + customerId: newSchedule.customerId, + }, + { + name: updatedScheduleName, + } + ); + expect(updatedSchedule).toMatchObject({ + name: updatedScheduleName, + }); + }); + + it("should throw NotFoundError when trying to update schedule that is not found", async () => { + const newSchedule = await CustomerScheduleServiceCreate({ + name, + customerId, + }); + const updatedScheduleName = "Updated Test Schedule"; + + await expect( + CustomerScheduleServiceUpdate( + { scheduleId: newSchedule._id, customerId: 0 }, + { + name: updatedScheduleName, + } + ) + ).rejects.toThrow(NotFoundError); + }); +}); diff --git a/src/functions/customer/services/schedule/update.ts b/src/functions/customer/services/schedule/update.ts new file mode 100644 index 00000000..b14f3454 --- /dev/null +++ b/src/functions/customer/services/schedule/update.ts @@ -0,0 +1,32 @@ +import { Schedule, ScheduleModel } from "~/functions/schedule"; +import { NotFoundError } from "~/library/handler"; + +export type ScheduleServiceUpdateProps = { + scheduleId: Schedule["_id"]; + customerId: Schedule["customerId"]; +}; + +export type CustomerScheduleServiceUpdateBody = Pick; + +export const CustomerScheduleServiceUpdate = async ( + filter: ScheduleServiceUpdateProps, + body: CustomerScheduleServiceUpdateBody +) => { + const updatedSchedule = await ScheduleModel.findOneAndUpdate( + { _id: filter.scheduleId, customerId: filter.customerId }, + body, + { + new: true, + } + ).orFail( + new NotFoundError([ + { + code: "custom", + message: "SCHEDULE_NOT_FOUND", + path: ["schedule"], + }, + ]) + ); + + return updatedSchedule; +}; diff --git a/src/functions/user/services/schedule.spec.ts b/src/functions/user/services/schedule.spec.ts index cc7efff9..12100504 100644 --- a/src/functions/user/services/schedule.spec.ts +++ b/src/functions/user/services/schedule.spec.ts @@ -1,5 +1,5 @@ import { faker } from "@faker-js/faker"; -import { CustomerScheduleServiceCreate } from "~/functions/customer/services/schedule"; +import { CustomerScheduleServiceCreate } from "~/functions/customer/services/schedule/create"; import { LocationTypes } from "~/functions/location"; import { createUser } from "~/library/jest/helpers"; import { createLocation } from "~/library/jest/helpers/location"; diff --git a/src/library/availability/generate-availability.ts b/src/library/availability/generate-availability.ts index f5fb3539..f54d32ec 100644 --- a/src/library/availability/generate-availability.ts +++ b/src/library/availability/generate-availability.ts @@ -9,14 +9,15 @@ import { import { utcToZonedTime } from "date-fns-tz"; import { enUS } from "date-fns/locale"; import { Availability } from "~/functions/availability"; -import { CustomerScheduleServiceGetWithCustomerResponse } from "~/functions/customer/services/schedule"; + import { LookupServiceCreate } from "~/functions/lookup"; import { calculateMaxNoticeAndMinBookingPeriod } from "./calculate-max-notice-and-min-booking-period"; +import { CustomerScheduleServiceGetWithCustomer } from "~/functions/customer/services/schedule/get-with-customer"; import { generateEndDate, generateStartDate } from "./start-end-date"; export type GenerateAvailabilityProps = { - schedule: CustomerScheduleServiceGetWithCustomerResponse; + schedule: Awaited>; lookup?: Awaited>; startDate: string; }; From 54fbf958aeff6d620a437e7011bdc83b90be36a8 Mon Sep 17 00:00:00 2001 From: Jamal Soueidan Date: Tue, 24 Oct 2023 22:43:15 +0200 Subject: [PATCH 2/3] chore(deploy-azure-functions-production.yml): Update workflow name and add configuration comments chore(deploy-azure-functions-production.yml): Set environment to dev chore(deploy-azure-functions-production.yml): Update GitHub Actions checkout action version chore(deploy-azure-functions-production.yml): Update Node.js setup action version and use environment variable for node version chore(deploy-azure-functions-production.yml): Update project dependencies resolution and build steps chore(deploy-azure-functions-production.yml): Update Azure Functions action version and use environment variables for app name and package path chore(deploy-azure-functions-production.yml): Update publish profile secret name chore(package.json): Update build script to use tsconfig.build.json feat(tsconfig.build.json): Add tsconfig.build.json file to exclude spec files from build --- .../deploy-azure-functions-production.yml | 49 +++++++++++++------ package.json | 2 +- tsconfig.build.json | 4 ++ 3 files changed, 38 insertions(+), 17 deletions(-) create mode 100644 tsconfig.build.json diff --git a/.github/workflows/deploy-azure-functions-production.yml b/.github/workflows/deploy-azure-functions-production.yml index 8688c2be..b8c31aa8 100644 --- a/.github/workflows/deploy-azure-functions-production.yml +++ b/.github/workflows/deploy-azure-functions-production.yml @@ -1,32 +1,49 @@ -name: Deploy to Azure Function App (Production) +name: Deploy Node.js project to Azure Function App on: push: branches: - main +# CONFIGURATION +# For help, go to https://github.com/Azure/Actions +# +# 1. Set up the following secrets in your repository: +# AZURE_FUNCTIONAPP_PUBLISH_PROFILE +# +# 2. Change these variables for your configuration: + +env: + AZURE_FUNCTIONAPP_NAME: "booking-shopify-api" # set this to your function app name on Azure + AZURE_FUNCTIONAPP_PACKAGE_PATH: "." # set this to the path to your function app project, defaults to the repository root + NODE_VERSION: "18.x" # set this to the node version to use (e.g. '8.x', '10.x', '12.x') + jobs: build-and-deploy: runs-on: ubuntu-latest - + environment: dev steps: - - name: Checkout code - uses: actions/checkout@v2 + - name: "Checkout GitHub Action" + uses: actions/checkout@v3 - - name: Set up Node.js - uses: actions/setup-node@v2 + - name: Setup Node ${{ env.NODE_VERSION }} Environment + uses: actions/setup-node@v3 with: - node-version: 18 - - - name: Install dependencies - run: npm ci + node-version: ${{ env.NODE_VERSION }} - - name: Build - run: npm run build + - name: "Resolve Project Dependencies Using Npm" + shell: bash + run: | + pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}' + npm install + npm run build --if-present + npm run test --if-present + popd - - name: Deploy to Azure Function App - uses: azure/functions-action@v1 + - name: "Run Azure Functions Action" + uses: Azure/functions-action@v1 + id: fa with: - app-name: booking-shopify-api - package: . + app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }} + package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} publish-profile: ${{ secrets.AZURE_FUNCTION_APP_PUBLISH_PROFILE_PRODUCTION }} diff --git a/package.json b/package.json index 816073d5..6a22a122 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ }, "scripts": { "prebuild": "npm run clean", - "build": "tsc", + "build": "tsc --project tsconfig.build.json", "watch": "tsc -w", "clean": "rimraf dist", "prestart": "npm run clean && npm run build", diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 00000000..8c0f74bb --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["**/*.spec.ts"] +} From 1d9c5bcd8a20c4334b74c4143225fd0acbec16e8 Mon Sep 17 00:00:00 2001 From: Jamal Soueidan Date: Tue, 24 Oct 2023 22:43:23 +0200 Subject: [PATCH 3/3] chore(deploy-azure-functions-production.yml): remove npm run test command from build step --- .github/workflows/deploy-azure-functions-production.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/deploy-azure-functions-production.yml b/.github/workflows/deploy-azure-functions-production.yml index b8c31aa8..e0b2b5c9 100644 --- a/.github/workflows/deploy-azure-functions-production.yml +++ b/.github/workflows/deploy-azure-functions-production.yml @@ -37,7 +37,6 @@ jobs: pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}' npm install npm run build --if-present - npm run test --if-present popd - name: "Run Azure Functions Action"