@goweekdays/core 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -11596,10 +11596,15 @@ __export(src_exports, {
11596
11596
  XENDIT_SECRET_KEY: () => XENDIT_SECRET_KEY,
11597
11597
  addressSchema: () => addressSchema,
11598
11598
  isDev: () => isDev,
11599
+ modelInventory: () => modelInventory,
11599
11600
  modelProperty: () => modelProperty,
11601
+ modelUnitType: () => modelUnitType,
11600
11602
  schema: () => schema,
11603
+ schemaInventory: () => schemaInventory,
11601
11604
  schemaProperty: () => schemaProperty,
11602
11605
  schemaPropertyUpdate: () => schemaPropertyUpdate,
11606
+ schemaUnitType: () => schemaUnitType,
11607
+ schemaUnitTypeUpdate: () => schemaUnitTypeUpdate,
11603
11608
  useAddressController: () => useAddressController,
11604
11609
  useAddressRepo: () => useAddressRepo,
11605
11610
  useAuthController: () => useAuthController,
@@ -11611,6 +11616,8 @@ __export(src_exports, {
11611
11616
  useFileController: () => useFileController,
11612
11617
  useFileRepo: () => useFileRepo,
11613
11618
  useFileService: () => useFileService,
11619
+ useInventoryController: () => useInventoryController,
11620
+ useInventoryRepo: () => useInventoryRepo,
11614
11621
  useInvoiceController: () => useInvoiceController,
11615
11622
  useInvoiceModel: () => useInvoiceModel,
11616
11623
  useInvoiceRepo: () => useInvoiceRepo,
@@ -11642,6 +11649,8 @@ __export(src_exports, {
11642
11649
  useSubscriptionRepo: () => useSubscriptionRepo,
11643
11650
  useSubscriptionService: () => useSubscriptionService,
11644
11651
  useTokenRepo: () => useTokenRepo,
11652
+ useUnitTypeController: () => useUnitTypeController,
11653
+ useUnitTypeRepo: () => useUnitTypeRepo,
11645
11654
  useUserController: () => useUserController,
11646
11655
  useUserRepo: () => useUserRepo,
11647
11656
  useUserService: () => useUserService,
@@ -25735,8 +25744,8 @@ var schemaProperty = import_joi28.default.object({
25735
25744
  amenities: import_joi28.default.array().items(import_joi28.default.string().trim()).optional(),
25736
25745
  numberOfFloors: import_joi28.default.string().trim().required(),
25737
25746
  floorLabels: import_joi28.default.string().optional().allow(""),
25738
- coverPhoto: import_joi28.default.object({}),
25739
- photoGallery: import_joi28.default.array().items(import_joi28.default.object({})),
25747
+ coverPhoto: import_joi28.default.string().optional().allow("", null),
25748
+ photoGallery: import_joi28.default.array().items(import_joi28.default.string()),
25740
25749
  stayType: import_joi28.default.string().trim().required(),
25741
25750
  createdAt: import_joi28.default.date().optional(),
25742
25751
  updatedAt: import_joi28.default.date().optional(),
@@ -25777,6 +25786,7 @@ function modelProperty(value) {
25777
25786
  coverPhoto: value.coverPhoto,
25778
25787
  photoGallery: value.photoGallery ?? [],
25779
25788
  stayType: value.stayType,
25789
+ status: value.status ?? "active",
25780
25790
  createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
25781
25791
  updatedAt: value.updatedAt,
25782
25792
  deletedAt: value.deletedAt
@@ -25946,7 +25956,7 @@ function usePropertyRepo() {
25946
25956
  });
25947
25957
  return cached;
25948
25958
  }
25949
- const property = await collection.findOne({});
25959
+ const property = await collection.findOne({ _id });
25950
25960
  if (!property) {
25951
25961
  throw new import_utils84.BadRequestError("Property not found.");
25952
25962
  }
@@ -26085,11 +26095,737 @@ function usePropertyController() {
26085
26095
  };
26086
26096
  }
26087
26097
 
26088
- // src/controllers/util.controller.ts
26098
+ // src/models/unit-type.model.ts
26099
+ var import_utils86 = require("@goweekdays/utils");
26089
26100
  var import_joi30 = __toESM(require("joi"));
26101
+ var import_mongodb36 = require("mongodb");
26102
+ var schemaUnitType = import_joi30.default.object({
26103
+ unitName: import_joi30.default.string().trim().required(),
26104
+ unitDescription: import_joi30.default.string().trim().required(),
26105
+ maxOccupants: import_joi30.default.number().required(),
26106
+ amenities: import_joi30.default.array().items(import_joi30.default.string().trim()).optional(),
26107
+ pricePerNight: import_joi30.default.string().trim().required(),
26108
+ pricePerMonth: import_joi30.default.string().trim().required(),
26109
+ imageGallery: import_joi30.default.array().items(import_joi30.default.string()),
26110
+ propertyId: import_joi30.default.string().trim().required(),
26111
+ createdAt: import_joi30.default.date().optional(),
26112
+ updatedAt: import_joi30.default.date().optional(),
26113
+ deletedAt: import_joi30.default.date().optional()
26114
+ });
26115
+ var schemaUnitTypeUpdate = import_joi30.default.object({
26116
+ unitName: import_joi30.default.string().trim().required(),
26117
+ unitDescription: import_joi30.default.string().trim().required(),
26118
+ maxOccupants: import_joi30.default.number().required(),
26119
+ amenities: import_joi30.default.array().items(import_joi30.default.string().trim()).optional(),
26120
+ pricePerNight: import_joi30.default.string().trim().required(),
26121
+ pricePerMonth: import_joi30.default.string().trim().required(),
26122
+ imageGallery: import_joi30.default.array().items(import_joi30.default.string()),
26123
+ propertyId: import_joi30.default.string().trim().required(),
26124
+ createdAt: import_joi30.default.date().optional(),
26125
+ updatedAt: import_joi30.default.date().optional(),
26126
+ deletedAt: import_joi30.default.date().optional()
26127
+ });
26128
+ function modelUnitType(value) {
26129
+ const { error } = schemaUnitType.validate(value);
26130
+ if (error) {
26131
+ throw new import_utils86.BadRequestError(`Invalid unit type data: ${error.message}`);
26132
+ }
26133
+ if (!value._id) {
26134
+ try {
26135
+ value._id = new import_mongodb36.ObjectId();
26136
+ } catch (error2) {
26137
+ throw new import_utils86.BadRequestError("Invalid unit type ID.");
26138
+ }
26139
+ }
26140
+ try {
26141
+ value.propertyId = new import_mongodb36.ObjectId(value.propertyId);
26142
+ } catch (error2) {
26143
+ throw new import_utils86.BadRequestError("Invalid Property ID");
26144
+ }
26145
+ return {
26146
+ _id: value._id,
26147
+ unitName: value.unitName,
26148
+ unitDescription: value.unitDescription,
26149
+ maxOccupants: value.maxOccupants,
26150
+ amenities: value.amenities ?? [],
26151
+ pricePerNight: value.pricePerNight,
26152
+ pricePerMonth: value.pricePerMonth,
26153
+ imageGallery: value.imageGallery,
26154
+ propertyId: value.propertyId,
26155
+ status: value.status ?? "active",
26156
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
26157
+ updatedAt: value.updatedAt,
26158
+ deletedAt: value.deletedAt
26159
+ };
26160
+ }
26161
+
26162
+ // src/repositories/unit-type.repository.ts
26163
+ var import_utils87 = require("@goweekdays/utils");
26164
+ var import_mongodb37 = require("mongodb");
26165
+ function useUnitTypeRepo() {
26166
+ const db = import_utils87.useAtlas.getDb();
26167
+ if (!db) {
26168
+ throw new import_utils87.BadRequestError("Unable to connect to server.");
26169
+ }
26170
+ const namespace_collection = "unitTypes";
26171
+ const collection = db.collection(namespace_collection);
26172
+ const { getCache, setCache, delNamespace } = (0, import_utils87.useCache)(namespace_collection);
26173
+ function delCachedData() {
26174
+ delNamespace().then(() => {
26175
+ import_utils87.logger.log({
26176
+ level: "info",
26177
+ message: `Cache namespace cleared for ${namespace_collection}`
26178
+ });
26179
+ }).catch((err) => {
26180
+ import_utils87.logger.log({
26181
+ level: "error",
26182
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
26183
+ });
26184
+ });
26185
+ }
26186
+ async function createIndex() {
26187
+ try {
26188
+ await collection.createIndexes([
26189
+ { key: { unitName: 1 } },
26190
+ { key: { maxOccupants: 1 } },
26191
+ { key: { propertyId: 1 } },
26192
+ {
26193
+ key: {
26194
+ unitName: "text",
26195
+ maxOccupants: "text",
26196
+ propertyId: "text"
26197
+ },
26198
+ name: "unitTypeTextSearch"
26199
+ }
26200
+ ]);
26201
+ } catch (error) {
26202
+ throw new import_utils87.BadRequestError(
26203
+ `Failed to create index on unit types: ${error.message}`
26204
+ );
26205
+ }
26206
+ }
26207
+ async function add(value, session) {
26208
+ try {
26209
+ value = modelUnitType(value);
26210
+ const res = await collection.insertOne(value, { session });
26211
+ delCachedData();
26212
+ return res.insertedId;
26213
+ } catch (error) {
26214
+ throw new import_utils87.BadRequestError(`Failed to create unit type: ${error.message}`);
26215
+ }
26216
+ }
26217
+ async function deleteById(_id) {
26218
+ try {
26219
+ _id = new import_mongodb37.ObjectId(_id);
26220
+ } catch (error) {
26221
+ throw new import_utils87.BadRequestError("Invalid ID.");
26222
+ }
26223
+ try {
26224
+ const res = await collection.deleteOne({ _id });
26225
+ delCachedData();
26226
+ return res;
26227
+ } catch (error) {
26228
+ throw new import_utils87.InternalServerError("Failed to delete unit type.");
26229
+ }
26230
+ }
26231
+ async function getAll({
26232
+ page = 1,
26233
+ limit = 20,
26234
+ status = "active",
26235
+ search = ""
26236
+ } = {}) {
26237
+ page = page > 0 ? page - 1 : 0;
26238
+ const query = { status };
26239
+ const cacheKeyOptions = {
26240
+ action: "getAll",
26241
+ page,
26242
+ limit,
26243
+ status
26244
+ };
26245
+ if (search) {
26246
+ query.$text = { $search: search };
26247
+ cacheKeyOptions.search = search;
26248
+ }
26249
+ const cacheKey = (0, import_utils87.makeCacheKey)(namespace_collection, cacheKeyOptions);
26250
+ try {
26251
+ const cached = await getCache(cacheKey);
26252
+ if (cached) {
26253
+ import_utils87.logger.log({
26254
+ level: "info",
26255
+ message: `Cache hit for getAll: ${cacheKey}`
26256
+ });
26257
+ return cached;
26258
+ }
26259
+ const items = await collection.aggregate([
26260
+ { $match: query },
26261
+ { $skip: page * limit },
26262
+ { $limit: limit }
26263
+ ]).toArray();
26264
+ const length = await collection.countDocuments(query);
26265
+ const data = (0, import_utils87.paginate)(items, page, limit, length);
26266
+ setCache(cacheKey, data, 300).then(() => {
26267
+ import_utils87.logger.log({
26268
+ level: "info",
26269
+ message: `Cache set for getAll: ${cacheKey}`
26270
+ });
26271
+ }).catch((err) => {
26272
+ import_utils87.logger.log({
26273
+ level: "error",
26274
+ message: `Failed to set cache: ${err.message}`
26275
+ });
26276
+ });
26277
+ return data;
26278
+ } catch (error) {
26279
+ throw new import_utils87.InternalServerError(
26280
+ `Failed to fetch unit-types: ${error.message}`
26281
+ );
26282
+ }
26283
+ }
26284
+ async function getById(_id) {
26285
+ try {
26286
+ _id = new import_mongodb37.ObjectId(_id);
26287
+ } catch (error) {
26288
+ throw new import_utils87.BadRequestError("Invalid ID.");
26289
+ }
26290
+ const cacheKey = (0, import_utils87.makeCacheKey)(namespace_collection, { _id: String(_id) });
26291
+ try {
26292
+ const cached = await getCache(cacheKey);
26293
+ if (cached) {
26294
+ import_utils87.logger.log({
26295
+ level: "info",
26296
+ message: `Cache hit for getById: ${cacheKey}`
26297
+ });
26298
+ return cached;
26299
+ }
26300
+ const unitType = await collection.findOne({ _id });
26301
+ if (!unitType) {
26302
+ throw new import_utils87.BadRequestError("Unit-type not found.");
26303
+ }
26304
+ setCache(cacheKey, unitType, 300).then(() => {
26305
+ import_utils87.logger.log({
26306
+ level: "info",
26307
+ message: `Cache set for getById: ${cacheKey}`
26308
+ });
26309
+ }).catch((err) => {
26310
+ import_utils87.logger.log({
26311
+ level: "error",
26312
+ message: `Failed to set cache: ${err.message}`
26313
+ });
26314
+ });
26315
+ return unitType;
26316
+ } catch (error) {
26317
+ if (error instanceof import_utils87.BadRequestError) {
26318
+ throw error;
26319
+ }
26320
+ throw new import_utils87.InternalServerError(
26321
+ `Failed to fetch unit-type: ${error.message}`
26322
+ );
26323
+ }
26324
+ }
26325
+ async function getByPropertyId(propertyId) {
26326
+ try {
26327
+ const unitTypes = await collection.find({ propertyId, status: "active" }).toArray();
26328
+ return unitTypes;
26329
+ } catch (error) {
26330
+ throw new import_utils87.InternalServerError(
26331
+ `Failed to fetch unit types: ${error.message}`
26332
+ );
26333
+ }
26334
+ }
26335
+ async function updateById(_id, value, session) {
26336
+ try {
26337
+ _id = new import_mongodb37.ObjectId(_id);
26338
+ } catch (error2) {
26339
+ throw new import_utils87.BadRequestError("Invalid ID.");
26340
+ }
26341
+ const { error } = schemaUnitTypeUpdate.validate(value);
26342
+ if (error) {
26343
+ throw new import_utils87.BadRequestError(
26344
+ `Invalid unit type data: ${error.message}. Repository validation.`
26345
+ );
26346
+ }
26347
+ try {
26348
+ value.updatedAt = /* @__PURE__ */ new Date();
26349
+ const res = await collection.updateOne(
26350
+ { _id },
26351
+ { $set: value },
26352
+ { session }
26353
+ );
26354
+ delCachedData();
26355
+ return res;
26356
+ } catch (error2) {
26357
+ throw new import_utils87.InternalServerError("Failed to update unit-type.");
26358
+ }
26359
+ }
26360
+ return {
26361
+ createIndex,
26362
+ add,
26363
+ getAll,
26364
+ getById,
26365
+ getByPropertyId,
26366
+ deleteById,
26367
+ updateById
26368
+ };
26369
+ }
26370
+
26371
+ // src/controllers/unit-type.controller.ts
26372
+ var import_utils88 = require("@goweekdays/utils");
26373
+ var import_joi31 = __toESM(require("joi"));
26374
+ function useUnitTypeController() {
26375
+ const { add: _add, getAll: _getAll, getById: _getById, updateById: _updateById, getByPropertyId: _getByPropertyId, deleteById: _deleteById } = useUnitTypeRepo();
26376
+ async function add(req, res, next) {
26377
+ const value = req.body;
26378
+ const { error } = schemaUnitType.validate(value);
26379
+ if (error) {
26380
+ next(new import_utils88.BadRequestError(error.message));
26381
+ return;
26382
+ }
26383
+ try {
26384
+ const id = await _add(value);
26385
+ res.json({ message: "Successfully added unit type.", id });
26386
+ return;
26387
+ } catch (error2) {
26388
+ next(error2);
26389
+ }
26390
+ }
26391
+ async function getAll(req, res, next) {
26392
+ const validation = import_joi31.default.object({
26393
+ page: import_joi31.default.number().integer().min(1).default(1),
26394
+ limit: import_joi31.default.number().integer().min(1).max(100).default(10),
26395
+ search: import_joi31.default.string().trim().allow("").default(""),
26396
+ status: import_joi31.default.string().default("active")
26397
+ });
26398
+ const { error, value } = validation.validate(req.query);
26399
+ if (error) {
26400
+ next(new import_utils88.BadRequestError(error.message));
26401
+ return;
26402
+ }
26403
+ try {
26404
+ const unitType = await _getAll(value);
26405
+ res.json(unitType);
26406
+ return;
26407
+ } catch (error2) {
26408
+ next(error2);
26409
+ }
26410
+ }
26411
+ async function getById(req, res, next) {
26412
+ const { id } = req.params;
26413
+ if (!id) {
26414
+ next(new import_utils88.BadRequestError("Unit Type ID is required."));
26415
+ return;
26416
+ }
26417
+ try {
26418
+ const unitType = await _getById(id);
26419
+ res.json(unitType);
26420
+ return;
26421
+ } catch (error) {
26422
+ next(error);
26423
+ }
26424
+ }
26425
+ async function getByPropertyId(req, res, next) {
26426
+ const { id } = req.params;
26427
+ if (!id) {
26428
+ next(new import_utils88.BadRequestError("Property ID is required."));
26429
+ return;
26430
+ }
26431
+ try {
26432
+ const unitType = await _getByPropertyId(id);
26433
+ res.json(unitType);
26434
+ return;
26435
+ } catch (error) {
26436
+ next(error);
26437
+ }
26438
+ }
26439
+ async function updateById(req, res, next) {
26440
+ const _id = req.params.id ?? "";
26441
+ const idValidation = import_joi31.default.object({
26442
+ _id: import_joi31.default.string().required()
26443
+ });
26444
+ const { error: idValidationError } = idValidation.validate({ _id });
26445
+ if (idValidationError) {
26446
+ throw new import_utils88.BadRequestError(`Invalid ID`);
26447
+ }
26448
+ const value = req.body;
26449
+ const { error } = schemaUnitTypeUpdate.validate(value);
26450
+ if (error) {
26451
+ throw new import_utils88.BadRequestError(`Invalid unit type data: ${error.message}`);
26452
+ }
26453
+ try {
26454
+ const result = await _updateById(_id, req.body);
26455
+ res.json({ message: "Successfully updated unit type.", result });
26456
+ } catch (error2) {
26457
+ next(error2);
26458
+ }
26459
+ }
26460
+ async function deleteById(req, res, next) {
26461
+ const id = req.params.id;
26462
+ if (!id) {
26463
+ next(new import_utils88.BadRequestError("Unit Type ID is required."));
26464
+ return;
26465
+ }
26466
+ try {
26467
+ const message = await _deleteById(id);
26468
+ res.json(message);
26469
+ return;
26470
+ } catch (error) {
26471
+ next(error);
26472
+ }
26473
+ }
26474
+ return {
26475
+ add,
26476
+ getAll,
26477
+ getById,
26478
+ updateById,
26479
+ deleteById,
26480
+ getByPropertyId
26481
+ };
26482
+ }
26483
+
26484
+ // src/models/units-inventory.model.ts
26485
+ var import_utils89 = require("@goweekdays/utils");
26486
+ var import_joi32 = __toESM(require("joi"));
26487
+ var import_mongodb38 = require("mongodb");
26488
+ var schemaInventory = import_joi32.default.object({
26489
+ unitNumber: import_joi32.default.string().trim().required(),
26490
+ floorNumber: import_joi32.default.string().trim().required(),
26491
+ propertyId: import_joi32.default.string().trim().required(),
26492
+ unitTypeId: import_joi32.default.string().trim().required(),
26493
+ ownerId: import_joi32.default.string().trim().required(),
26494
+ pricePerNight: import_joi32.default.string().trim().required(),
26495
+ pricePerMonth: import_joi32.default.string().trim().required(),
26496
+ status: import_joi32.default.string().valid("available", "reserved", "occupied", "maintenance", "blocked").optional().default("available"),
26497
+ availableDays: import_joi32.default.array().items(import_joi32.default.string().trim()).required(),
26498
+ createdAt: import_joi32.default.date().optional().allow(null, ""),
26499
+ updatedAt: import_joi32.default.date().optional().allow(null, ""),
26500
+ deletedAt: import_joi32.default.date().optional().allow(null, "")
26501
+ });
26502
+ function modelInventory(value) {
26503
+ const { error } = schemaInventory.validate(value);
26504
+ if (error) {
26505
+ throw new import_utils89.BadRequestError(`Invalid inventory data: ${error.message}`);
26506
+ }
26507
+ if (!value._id) {
26508
+ try {
26509
+ value._id = new import_mongodb38.ObjectId();
26510
+ } catch (error2) {
26511
+ throw new import_utils89.BadRequestError("Invalid inventory ID.");
26512
+ }
26513
+ }
26514
+ try {
26515
+ value.propertyId = new import_mongodb38.ObjectId(value.propertyId);
26516
+ } catch (error2) {
26517
+ throw new import_utils89.BadRequestError("Invalid Property ID");
26518
+ }
26519
+ try {
26520
+ value.unitTypeId = new import_mongodb38.ObjectId(value.unitTypeId);
26521
+ } catch (error2) {
26522
+ throw new import_utils89.BadRequestError("Invalid Unit Type ID");
26523
+ }
26524
+ return {
26525
+ _id: value._id,
26526
+ unitNumber: value.unitNumber,
26527
+ floorNumber: value.floorNumber,
26528
+ propertyId: value.propertyId,
26529
+ unitTypeId: value.unitTypeId,
26530
+ ownerId: value.ownerId,
26531
+ pricePerNight: value.pricePerNight,
26532
+ pricePerMonth: value.pricePerMonth,
26533
+ status: value.status ?? "available",
26534
+ availableDays: value.availableDays,
26535
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
26536
+ updatedAt: value.updatedAt,
26537
+ deletedAt: value.deletedAt
26538
+ };
26539
+ }
26540
+
26541
+ // src/repositories/units-inventory.repository.ts
26542
+ var import_utils90 = require("@goweekdays/utils");
26543
+ var import_mongodb39 = require("mongodb");
26544
+ function useInventoryRepo() {
26545
+ const db = import_utils90.useAtlas.getDb();
26546
+ if (!db) {
26547
+ throw new import_utils90.BadRequestError("Unable to connect to server.");
26548
+ }
26549
+ const namespace_collection = "inventories";
26550
+ const collection = db.collection(namespace_collection);
26551
+ const { getCache, setCache, delNamespace } = (0, import_utils90.useCache)(namespace_collection);
26552
+ function delCachedData() {
26553
+ delNamespace().then(() => {
26554
+ import_utils90.logger.log({
26555
+ level: "info",
26556
+ message: `Cache namespace cleared for ${namespace_collection}`
26557
+ });
26558
+ }).catch((err) => {
26559
+ import_utils90.logger.log({
26560
+ level: "error",
26561
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
26562
+ });
26563
+ });
26564
+ }
26565
+ async function getAll({
26566
+ page = 1,
26567
+ limit = 20,
26568
+ status = "available",
26569
+ search = ""
26570
+ } = {}) {
26571
+ page = page > 0 ? page - 1 : 0;
26572
+ const query = { status };
26573
+ const cacheKeyOptions = {
26574
+ action: "getAll",
26575
+ page,
26576
+ limit,
26577
+ status
26578
+ };
26579
+ if (search) {
26580
+ query.$text = { $search: search };
26581
+ cacheKeyOptions.search = search;
26582
+ }
26583
+ const cacheKey = (0, import_utils90.makeCacheKey)(namespace_collection, cacheKeyOptions);
26584
+ try {
26585
+ const cached = await getCache(cacheKey);
26586
+ if (cached) {
26587
+ import_utils90.logger.log({
26588
+ level: "info",
26589
+ message: `Cache hit for getAll: ${cacheKey}`
26590
+ });
26591
+ return cached;
26592
+ }
26593
+ const items = await collection.aggregate([
26594
+ { $match: query },
26595
+ { $skip: page * limit },
26596
+ { $limit: limit }
26597
+ ]).toArray();
26598
+ const length = await collection.countDocuments(query);
26599
+ const data = (0, import_utils90.paginate)(items, page, limit, length);
26600
+ setCache(cacheKey, data, 300).then(() => {
26601
+ import_utils90.logger.log({
26602
+ level: "info",
26603
+ message: `Cache set for getAll: ${cacheKey}`
26604
+ });
26605
+ }).catch((err) => {
26606
+ import_utils90.logger.log({
26607
+ level: "error",
26608
+ message: `Failed to set cache: ${err.message}`
26609
+ });
26610
+ });
26611
+ return data;
26612
+ } catch (error) {
26613
+ throw new import_utils90.InternalServerError(
26614
+ `Failed to fetch inventories: ${error.message}`
26615
+ );
26616
+ }
26617
+ }
26618
+ async function getById(_id) {
26619
+ try {
26620
+ _id = new import_mongodb39.ObjectId(_id);
26621
+ } catch (error) {
26622
+ throw new import_utils90.BadRequestError("Invalid ID.");
26623
+ }
26624
+ const cacheKey = (0, import_utils90.makeCacheKey)(namespace_collection, { _id: String(_id) });
26625
+ try {
26626
+ const cached = await getCache(cacheKey);
26627
+ if (cached) {
26628
+ import_utils90.logger.log({
26629
+ level: "info",
26630
+ message: `Cache hit for getById: ${cacheKey}`
26631
+ });
26632
+ return cached;
26633
+ }
26634
+ const inventory = await collection.findOne({});
26635
+ if (!inventory) {
26636
+ throw new import_utils90.BadRequestError("Inventory not found.");
26637
+ }
26638
+ setCache(cacheKey, inventory, 300).then(() => {
26639
+ import_utils90.logger.log({
26640
+ level: "info",
26641
+ message: `Cache set for getById: ${cacheKey}`
26642
+ });
26643
+ }).catch((err) => {
26644
+ import_utils90.logger.log({
26645
+ level: "error",
26646
+ message: `Failed to set cache: ${err.message}`
26647
+ });
26648
+ });
26649
+ return inventory;
26650
+ } catch (error) {
26651
+ if (error instanceof import_utils90.BadRequestError) {
26652
+ throw error;
26653
+ }
26654
+ throw new import_utils90.InternalServerError(
26655
+ `Failed to fetch inventory: ${error.message}`
26656
+ );
26657
+ }
26658
+ }
26659
+ async function createIndex() {
26660
+ }
26661
+ async function add(value, session) {
26662
+ try {
26663
+ value = modelInventory(value);
26664
+ const res = await collection.insertOne(value, { session });
26665
+ delCachedData();
26666
+ return res.insertedId;
26667
+ } catch (error) {
26668
+ throw new import_utils90.BadRequestError(`Failed to create inventory: ${error.message}`);
26669
+ }
26670
+ }
26671
+ async function updateById(_id, value, session) {
26672
+ try {
26673
+ _id = new import_mongodb39.ObjectId(_id);
26674
+ } catch (error2) {
26675
+ throw new import_utils90.BadRequestError("Invalid ID.");
26676
+ }
26677
+ const { error } = schemaInventory.validate(value);
26678
+ if (error) {
26679
+ throw new import_utils90.BadRequestError(
26680
+ `Invalid unit-inventory data: ${error.message}. Repository validation.`
26681
+ );
26682
+ }
26683
+ try {
26684
+ value.updatedAt = /* @__PURE__ */ new Date();
26685
+ const res = await collection.updateOne(
26686
+ { _id },
26687
+ { $set: value },
26688
+ { session }
26689
+ );
26690
+ delCachedData();
26691
+ return res;
26692
+ } catch (error2) {
26693
+ throw new import_utils90.InternalServerError("Failed to update unit-inventory.");
26694
+ }
26695
+ }
26696
+ async function deleteById(_id) {
26697
+ try {
26698
+ _id = new import_mongodb39.ObjectId(_id);
26699
+ } catch (error) {
26700
+ throw new import_utils90.BadRequestError("Invalid ID.");
26701
+ }
26702
+ try {
26703
+ const res = await collection.deleteOne({ _id });
26704
+ delCachedData();
26705
+ return res;
26706
+ } catch (error) {
26707
+ throw new import_utils90.InternalServerError("Failed to delete unit-inventory.");
26708
+ }
26709
+ }
26710
+ return {
26711
+ createIndex,
26712
+ add,
26713
+ getAll,
26714
+ getById,
26715
+ deleteById,
26716
+ updateById
26717
+ };
26718
+ }
26719
+
26720
+ // src/controllers/units-inventory.controller.ts
26721
+ var import_utils91 = require("@goweekdays/utils");
26722
+ var import_joi33 = __toESM(require("joi"));
26723
+ function useInventoryController() {
26724
+ const {
26725
+ add: _add,
26726
+ getAll: _getAll,
26727
+ getById: _getById,
26728
+ updateById: _updateById,
26729
+ deleteById: _deleteById
26730
+ } = useInventoryRepo();
26731
+ async function getAll(req, res, next) {
26732
+ const validation = import_joi33.default.object({
26733
+ page: import_joi33.default.number().integer().min(1).default(1),
26734
+ limit: import_joi33.default.number().integer().min(1).max(100).default(10),
26735
+ search: import_joi33.default.string().trim().allow("").default(""),
26736
+ status: import_joi33.default.string().default("available")
26737
+ });
26738
+ const { error, value } = validation.validate(req.query);
26739
+ if (error) {
26740
+ next(new import_utils91.BadRequestError(error.message));
26741
+ return;
26742
+ }
26743
+ try {
26744
+ const inventory = await _getAll(value);
26745
+ res.json(inventory);
26746
+ return;
26747
+ } catch (error2) {
26748
+ next(error2);
26749
+ }
26750
+ }
26751
+ async function getById(req, res, next) {
26752
+ const { id } = req.params;
26753
+ if (!id) {
26754
+ next(new import_utils91.BadRequestError("Inventory ID is required."));
26755
+ return;
26756
+ }
26757
+ try {
26758
+ const inventory = await _getById(id);
26759
+ res.json(inventory);
26760
+ return;
26761
+ } catch (error) {
26762
+ next(error);
26763
+ }
26764
+ }
26765
+ async function add(req, res, next) {
26766
+ const value = req.body;
26767
+ const { error } = schemaInventory.validate(value);
26768
+ if (error) {
26769
+ next(new import_utils91.BadRequestError(error.message));
26770
+ return;
26771
+ }
26772
+ try {
26773
+ const id = await _add(value);
26774
+ res.json({ message: "Successfully added inventory.", id });
26775
+ return;
26776
+ } catch (error2) {
26777
+ next(error2);
26778
+ }
26779
+ }
26780
+ async function updateById(req, res, next) {
26781
+ const _id = req.params.id ?? "";
26782
+ const idValidation = import_joi33.default.object({
26783
+ _id: import_joi33.default.string().required()
26784
+ });
26785
+ const { error: idValidationError } = idValidation.validate({ _id });
26786
+ if (idValidationError) {
26787
+ throw new import_utils91.BadRequestError(`Invalid ID`);
26788
+ }
26789
+ const value = req.body;
26790
+ const { error } = schemaInventory.validate(value);
26791
+ if (error) {
26792
+ throw new import_utils91.BadRequestError(`Invalid inventory data: ${error.message}`);
26793
+ }
26794
+ try {
26795
+ const result = await _updateById(_id, req.body);
26796
+ res.json({ message: "Successfully updated inventory.", result });
26797
+ } catch (error2) {
26798
+ next(error2);
26799
+ }
26800
+ }
26801
+ async function deleteById(req, res, next) {
26802
+ const id = req.params.id;
26803
+ if (!id) {
26804
+ next(new import_utils91.BadRequestError("Inventory ID is required."));
26805
+ return;
26806
+ }
26807
+ try {
26808
+ const message = await _deleteById(id);
26809
+ res.json(message);
26810
+ return;
26811
+ } catch (error) {
26812
+ next(error);
26813
+ }
26814
+ }
26815
+ return {
26816
+ add,
26817
+ getAll,
26818
+ getById,
26819
+ updateById,
26820
+ deleteById
26821
+ };
26822
+ }
26823
+
26824
+ // src/controllers/util.controller.ts
26825
+ var import_joi34 = __toESM(require("joi"));
26090
26826
 
26091
26827
  // src/services/github.service.ts
26092
- var import_utils86 = require("@goweekdays/utils");
26828
+ var import_utils92 = require("@goweekdays/utils");
26093
26829
  var import_rest = require("@octokit/rest");
26094
26830
  var import_libsodium_wrappers = __toESM(require("libsodium-wrappers"));
26095
26831
  function useGitHubService() {
@@ -26103,23 +26839,23 @@ function useGitHubService() {
26103
26839
  try {
26104
26840
  const { data: repoData } = await octokit.repos.get({ owner, repo });
26105
26841
  if (!repoData.permissions?.admin) {
26106
- throw new import_utils86.BadRequestError(
26842
+ throw new import_utils92.BadRequestError(
26107
26843
  "You do not have admin access to this repository."
26108
26844
  );
26109
26845
  }
26110
26846
  } catch (error) {
26111
26847
  if (error.status === 404) {
26112
- throw new import_utils86.BadRequestError(
26848
+ throw new import_utils92.BadRequestError(
26113
26849
  "Repository not found or you don't have access to it."
26114
26850
  );
26115
26851
  } else if (error.status === 401) {
26116
- throw new import_utils86.BadRequestError(
26852
+ throw new import_utils92.BadRequestError(
26117
26853
  "Invalid GitHub token or insufficient permissions."
26118
26854
  );
26119
26855
  } else if (error.message.includes("admin access")) {
26120
26856
  throw error;
26121
26857
  } else {
26122
- throw new import_utils86.BadRequestError(
26858
+ throw new import_utils92.BadRequestError(
26123
26859
  `Failed to check repository permissions: ${error.message}`
26124
26860
  );
26125
26861
  }
@@ -26168,7 +26904,7 @@ function useGitHubService() {
26168
26904
  key_id: publicKeyRes.key_id
26169
26905
  });
26170
26906
  } catch (encryptionError) {
26171
- throw new import_utils86.BadRequestError(
26907
+ throw new import_utils92.BadRequestError(
26172
26908
  `Failed to encrypt secret '${key}': ${encryptionError.message}`
26173
26909
  );
26174
26910
  }
@@ -26198,22 +26934,22 @@ function useGitHubService() {
26198
26934
  }
26199
26935
  return `Successfully set ${lines.length} ${type} variables/secrets in environment '${environment}'`;
26200
26936
  } catch (error) {
26201
- if (error instanceof import_utils86.AppError)
26937
+ if (error instanceof import_utils92.AppError)
26202
26938
  throw error;
26203
26939
  if (error.status === 422) {
26204
- throw new import_utils86.BadRequestError(
26940
+ throw new import_utils92.BadRequestError(
26205
26941
  `GitHub API validation error: ${error.message}`
26206
26942
  );
26207
26943
  } else if (error.status === 404) {
26208
- throw new import_utils86.BadRequestError("Environment or repository not found.");
26944
+ throw new import_utils92.BadRequestError("Environment or repository not found.");
26209
26945
  } else if (error.status === 403) {
26210
- throw new import_utils86.BadRequestError(
26946
+ throw new import_utils92.BadRequestError(
26211
26947
  "Forbidden: Insufficient permissions or rate limit exceeded."
26212
26948
  );
26213
26949
  } else if (error.message.includes("admin access") || error.message.includes("permissions")) {
26214
26950
  throw error;
26215
26951
  } else {
26216
- throw new import_utils86.BadRequestError(
26952
+ throw new import_utils92.BadRequestError(
26217
26953
  `Failed to set GitHub variables: ${error.message}`
26218
26954
  );
26219
26955
  }
@@ -26225,7 +26961,7 @@ function useGitHubService() {
26225
26961
  }
26226
26962
 
26227
26963
  // src/controllers/util.controller.ts
26228
- var import_utils87 = require("@goweekdays/utils");
26964
+ var import_utils93 = require("@goweekdays/utils");
26229
26965
  function useUtilController() {
26230
26966
  async function healthCheck(req, res, next) {
26231
26967
  try {
@@ -26241,32 +26977,32 @@ function useUtilController() {
26241
26977
  }
26242
26978
  });
26243
26979
  } catch (error) {
26244
- import_utils87.logger.error("Health check failed", { error: error.message });
26245
- next(new import_utils87.InternalServerError("Health check failed"));
26980
+ import_utils93.logger.error("Health check failed", { error: error.message });
26981
+ next(new import_utils93.InternalServerError("Health check failed"));
26246
26982
  }
26247
26983
  }
26248
26984
  async function setGitHubVariables(req, res, next) {
26249
26985
  try {
26250
26986
  const { githubToken, repoUrl, environment, type, keyValues } = req.body;
26251
- const validation = import_joi30.default.object({
26252
- githubToken: import_joi30.default.string().required().messages({
26987
+ const validation = import_joi34.default.object({
26988
+ githubToken: import_joi34.default.string().required().messages({
26253
26989
  "string.empty": "GitHub token is required",
26254
26990
  "any.required": "GitHub token is required"
26255
26991
  }),
26256
- repoUrl: import_joi30.default.string().uri().required().messages({
26992
+ repoUrl: import_joi34.default.string().uri().required().messages({
26257
26993
  "string.empty": "Repository URL is required",
26258
26994
  "string.uri": "Repository URL must be a valid URL",
26259
26995
  "any.required": "Repository URL is required"
26260
26996
  }),
26261
- environment: import_joi30.default.string().required().messages({
26997
+ environment: import_joi34.default.string().required().messages({
26262
26998
  "string.empty": "Environment name is required",
26263
26999
  "any.required": "Environment name is required"
26264
27000
  }),
26265
- type: import_joi30.default.string().valid("env", "secret").required().messages({
27001
+ type: import_joi34.default.string().valid("env", "secret").required().messages({
26266
27002
  "any.only": 'Type must be either "env" or "secret"',
26267
27003
  "any.required": "Type is required"
26268
27004
  }),
26269
- keyValues: import_joi30.default.string().required().messages({
27005
+ keyValues: import_joi34.default.string().required().messages({
26270
27006
  "string.empty": "Key-value pairs are required",
26271
27007
  "any.required": "Key-value pairs are required"
26272
27008
  })
@@ -26279,13 +27015,13 @@ function useUtilController() {
26279
27015
  keyValues
26280
27016
  });
26281
27017
  if (error) {
26282
- next(new import_utils87.BadRequestError(error.message));
27018
+ next(new import_utils93.BadRequestError(error.message));
26283
27019
  return;
26284
27020
  }
26285
27021
  const repoUrlPattern = /github\.com[:\/]([^\/]+)\/(.+)\.git$/;
26286
27022
  if (!repoUrlPattern.test(repoUrl)) {
26287
27023
  next(
26288
- new import_utils87.BadRequestError(
27024
+ new import_utils93.BadRequestError(
26289
27025
  "Invalid GitHub repository URL format. Expected format: https://github.com/owner/repo.git"
26290
27026
  )
26291
27027
  );
@@ -26297,7 +27033,7 @@ function useUtilController() {
26297
27033
  );
26298
27034
  if (invalidLines.length > 0) {
26299
27035
  next(
26300
- new import_utils87.BadRequestError(
27036
+ new import_utils93.BadRequestError(
26301
27037
  "Invalid key-value format. Each pair should be in format: KEY=value. Pairs can be separated by newlines, spaces, or tabs."
26302
27038
  )
26303
27039
  );
@@ -26311,7 +27047,7 @@ function useUtilController() {
26311
27047
  type,
26312
27048
  keyValues
26313
27049
  });
26314
- import_utils87.logger.info(`GitHub variables set successfully`, {
27050
+ import_utils93.logger.info(`GitHub variables set successfully`, {
26315
27051
  repoUrl,
26316
27052
  environment,
26317
27053
  type,
@@ -26328,15 +27064,15 @@ function useUtilController() {
26328
27064
  }
26329
27065
  });
26330
27066
  } catch (error) {
26331
- import_utils87.logger.error("Failed to set GitHub variables", {
27067
+ import_utils93.logger.error("Failed to set GitHub variables", {
26332
27068
  error: error.message,
26333
27069
  stack: error.stack
26334
27070
  });
26335
- if (error instanceof import_utils87.AppError) {
27071
+ if (error instanceof import_utils93.AppError) {
26336
27072
  next(error);
26337
27073
  } else {
26338
27074
  next(
26339
- new import_utils87.InternalServerError(
27075
+ new import_utils93.InternalServerError(
26340
27076
  `Failed to set GitHub variables: ${error.message}`
26341
27077
  )
26342
27078
  );
@@ -26404,10 +27140,15 @@ function useUtilController() {
26404
27140
  XENDIT_SECRET_KEY,
26405
27141
  addressSchema,
26406
27142
  isDev,
27143
+ modelInventory,
26407
27144
  modelProperty,
27145
+ modelUnitType,
26408
27146
  schema,
27147
+ schemaInventory,
26409
27148
  schemaProperty,
26410
27149
  schemaPropertyUpdate,
27150
+ schemaUnitType,
27151
+ schemaUnitTypeUpdate,
26411
27152
  useAddressController,
26412
27153
  useAddressRepo,
26413
27154
  useAuthController,
@@ -26419,6 +27160,8 @@ function useUtilController() {
26419
27160
  useFileController,
26420
27161
  useFileRepo,
26421
27162
  useFileService,
27163
+ useInventoryController,
27164
+ useInventoryRepo,
26422
27165
  useInvoiceController,
26423
27166
  useInvoiceModel,
26424
27167
  useInvoiceRepo,
@@ -26450,6 +27193,8 @@ function useUtilController() {
26450
27193
  useSubscriptionRepo,
26451
27194
  useSubscriptionService,
26452
27195
  useTokenRepo,
27196
+ useUnitTypeController,
27197
+ useUnitTypeRepo,
26453
27198
  useUserController,
26454
27199
  useUserRepo,
26455
27200
  useUserService,