@goweekdays/core 0.0.1

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 ADDED
@@ -0,0 +1,4580 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __defProps = Object.defineProperties;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
+ var __getProtoOf = Object.getPrototypeOf;
10
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
12
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
+ var __spreadValues = (a, b) => {
14
+ for (var prop in b || (b = {}))
15
+ if (__hasOwnProp.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ if (__getOwnPropSymbols)
18
+ for (var prop of __getOwnPropSymbols(b)) {
19
+ if (__propIsEnum.call(b, prop))
20
+ __defNormalProp(a, prop, b[prop]);
21
+ }
22
+ return a;
23
+ };
24
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
25
+ var __export = (target, all) => {
26
+ for (var name in all)
27
+ __defProp(target, name, { get: all[name], enumerable: true });
28
+ };
29
+ var __copyProps = (to, from, except, desc) => {
30
+ if (from && typeof from === "object" || typeof from === "function") {
31
+ for (let key of __getOwnPropNames(from))
32
+ if (!__hasOwnProp.call(to, key) && key !== except)
33
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
34
+ }
35
+ return to;
36
+ };
37
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
38
+ // If the importer is in node compatibility mode or this is not an ESM
39
+ // file that has been converted to a CommonJS file using a Babel-
40
+ // compatible transform (i.e. "__esModule" has not been set), then set
41
+ // "default" to the CommonJS "module.exports" for node compatibility.
42
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
43
+ mod
44
+ ));
45
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
46
+ var __async = (__this, __arguments, generator) => {
47
+ return new Promise((resolve, reject) => {
48
+ var fulfilled = (value) => {
49
+ try {
50
+ step(generator.next(value));
51
+ } catch (e) {
52
+ reject(e);
53
+ }
54
+ };
55
+ var rejected = (value) => {
56
+ try {
57
+ step(generator.throw(value));
58
+ } catch (e) {
59
+ reject(e);
60
+ }
61
+ };
62
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
63
+ step((generator = generator.apply(__this, __arguments)).next());
64
+ });
65
+ };
66
+
67
+ // src/index.ts
68
+ var src_exports = {};
69
+ __export(src_exports, {
70
+ ACCESS_TOKEN_EXPIRY: () => ACCESS_TOKEN_EXPIRY,
71
+ ACCESS_TOKEN_SECRET: () => ACCESS_TOKEN_SECRET,
72
+ APP_ACCOUNT: () => APP_ACCOUNT,
73
+ AppError: () => AppError,
74
+ BadRequestError: () => BadRequestError,
75
+ DEFAULT_USER_EMAIL: () => DEFAULT_USER_EMAIL,
76
+ DEFAULT_USER_FIRST_NAME: () => DEFAULT_USER_FIRST_NAME,
77
+ DEFAULT_USER_LAST_NAME: () => DEFAULT_USER_LAST_NAME,
78
+ DEFAULT_USER_PASSWORD: () => DEFAULT_USER_PASSWORD,
79
+ InternalServerError: () => InternalServerError,
80
+ MAILER_EMAIL: () => MAILER_EMAIL,
81
+ MAILER_PASSWORD: () => MAILER_PASSWORD,
82
+ MAILER_TRANSPORT_HOST: () => MAILER_TRANSPORT_HOST,
83
+ MAILER_TRANSPORT_PORT: () => MAILER_TRANSPORT_PORT,
84
+ MAILER_TRANSPORT_SECURE: () => MAILER_TRANSPORT_SECURE,
85
+ MCapBldgAct: () => MCapBldgAct,
86
+ MComment: () => MComment,
87
+ MEntity: () => MEntity,
88
+ MFile: () => MFile,
89
+ MONGO_DB: () => MONGO_DB,
90
+ MONGO_URI: () => MONGO_URI,
91
+ MRole: () => MRole,
92
+ MToken: () => MToken,
93
+ MUser: () => MUser,
94
+ MUserRole: () => MUserRole,
95
+ MVerification: () => MVerification,
96
+ MWorkflow: () => MWorkflow,
97
+ NotFoundError: () => NotFoundError,
98
+ PORT: () => PORT,
99
+ REDIS_HOST: () => REDIS_HOST,
100
+ REDIS_PASSWORD: () => REDIS_PASSWORD,
101
+ REDIS_PORT: () => REDIS_PORT,
102
+ REFRESH_TOKEN_EXPIRY: () => REFRESH_TOKEN_EXPIRY,
103
+ REFRESH_TOKEN_SECRET: () => REFRESH_TOKEN_SECRET,
104
+ SECRET_KEY: () => SECRET_KEY,
105
+ SPACES_ACCESS_KEY: () => SPACES_ACCESS_KEY,
106
+ SPACES_BUCKET: () => SPACES_BUCKET,
107
+ SPACES_ENDPOINT: () => SPACES_ENDPOINT,
108
+ SPACES_REGION: () => SPACES_REGION,
109
+ SPACES_SECRET_KEY: () => SPACES_SECRET_KEY,
110
+ UnauthorizedError: () => UnauthorizedError,
111
+ VERIFICATION_FORGET_PASSWORD_DURATION: () => VERIFICATION_FORGET_PASSWORD_DURATION,
112
+ VERIFICATION_USER_INVITE_DURATION: () => VERIFICATION_USER_INVITE_DURATION,
113
+ authMiddleware: () => authMiddleware,
114
+ comparePassword: () => comparePassword,
115
+ compileHandlebar: () => compileHandlebar,
116
+ errorHandler: () => errorHandler,
117
+ generateToken: () => generateToken,
118
+ getDirectory: () => getDirectory,
119
+ hashPassword: () => hashPassword,
120
+ initRedisClient: () => initRedisClient,
121
+ isDev: () => isDev,
122
+ logger: () => logger,
123
+ paginate: () => paginate,
124
+ prependZeros: () => prependZeros,
125
+ toObjectId: () => toObjectId,
126
+ useAtlas: () => useAtlas,
127
+ useAuthController: () => useAuthController,
128
+ useAuthService: () => useAuthService,
129
+ useCapBldgActController: () => useCapBldgActController,
130
+ useCapBldgActRepo: () => useCapBldgActRepo,
131
+ useCapBldgActService: () => useCapBldgActService,
132
+ useCommentController: () => useCommentController,
133
+ useCommentRepo: () => useCommentRepo,
134
+ useCommentService: () => useCommentService,
135
+ useEntityController: () => useEntityController,
136
+ useEntityRepo: () => useEntityRepo,
137
+ useEntityService: () => useEntityService,
138
+ useFileController: () => useFileController,
139
+ useFileRepo: () => useFileRepo,
140
+ useFileService: () => useFileService,
141
+ useMailer: () => useMailer,
142
+ useRedisClient: () => useRedisClient,
143
+ useRoleController: () => useRoleController,
144
+ useRoleRepo: () => useRoleRepo,
145
+ useRoleService: () => useRoleService,
146
+ useS3: () => useS3,
147
+ useTokenRepo: () => useTokenRepo,
148
+ useUserController: () => useUserController,
149
+ useUserRepo: () => useUserRepo,
150
+ useUserService: () => useUserService,
151
+ useVerificationController: () => useVerificationController,
152
+ useVerificationRepo: () => useVerificationRepo,
153
+ useVerificationService: () => useVerificationService,
154
+ useWorkflowController: () => useWorkflowController,
155
+ useWorkflowRepo: () => useWorkflowRepo,
156
+ useWorkflowService: () => useWorkflowService
157
+ });
158
+ module.exports = __toCommonJS(src_exports);
159
+
160
+ // src/utils/error.ts
161
+ var AppError = class extends Error {
162
+ constructor(message, statusCode, isOperational = true) {
163
+ super(message);
164
+ Object.setPrototypeOf(this, new.target.prototype);
165
+ this.statusCode = statusCode;
166
+ this.isOperational = isOperational;
167
+ Error.captureStackTrace(this);
168
+ }
169
+ };
170
+ var BadRequestError = class extends AppError {
171
+ constructor(message = "Bad Request") {
172
+ super(message, 400);
173
+ }
174
+ };
175
+ var UnauthorizedError = class extends AppError {
176
+ constructor(message = "Unauthorized") {
177
+ super(message, 401);
178
+ }
179
+ };
180
+ var NotFoundError = class extends AppError {
181
+ constructor(message = "Not Found") {
182
+ super(message, 404);
183
+ }
184
+ };
185
+ var InternalServerError = class extends AppError {
186
+ constructor(message = "Internal Server Error") {
187
+ super(message, 500);
188
+ }
189
+ };
190
+
191
+ // src/utils/logger.ts
192
+ var winston = __toESM(require("winston"));
193
+ var logger = winston.createLogger({
194
+ level: "info",
195
+ format: winston.format.combine(winston.format.timestamp(), winston.format.json()),
196
+ transports: [
197
+ // File transport (optional)
198
+ new winston.transports.File({ filename: "error.log", level: "error" }),
199
+ new winston.transports.File({ filename: "combined.log" })
200
+ ]
201
+ });
202
+
203
+ // src/utils/errorHandler.middleware.ts
204
+ var errorHandler = (err, req, res, next) => {
205
+ if (err.isOperational) {
206
+ res.status(err.statusCode).json({
207
+ status: "error",
208
+ message: err.message
209
+ });
210
+ return;
211
+ } else {
212
+ logger.log({ level: "error", message: err.message });
213
+ res.status(500).json({
214
+ status: "error",
215
+ message: "Internal Server Error"
216
+ });
217
+ return;
218
+ }
219
+ };
220
+
221
+ // src/utils/authorization.middleware.ts
222
+ var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
223
+ function authMiddleware(access_token_secret = "") {
224
+ return (req, res, next) => {
225
+ if (!access_token_secret) {
226
+ res.status(401).json({ message: "Access token secret is required" });
227
+ return;
228
+ }
229
+ const authorization = req.headers["authorization"];
230
+ const token = authorization && authorization.split(" ")[1];
231
+ if (!token) {
232
+ res.status(401).json({ message: "Unauthorized" });
233
+ return;
234
+ }
235
+ import_jsonwebtoken.default.verify(token, access_token_secret, (err, user) => {
236
+ if (err) {
237
+ res.status(401).json({ message: "Authorization token expired" });
238
+ return;
239
+ }
240
+ req.headers["user"] = user.user;
241
+ next();
242
+ });
243
+ };
244
+ }
245
+
246
+ // src/utils/hash-password.ts
247
+ var import_bcrypt = __toESM(require("bcrypt"));
248
+ var saltRounds = 10;
249
+ function hashPassword(password) {
250
+ return __async(this, null, function* () {
251
+ try {
252
+ return yield import_bcrypt.default.hash(password, saltRounds);
253
+ } catch (error) {
254
+ throw new Error("Failed to hash password.");
255
+ }
256
+ });
257
+ }
258
+
259
+ // src/utils/compare-password.ts
260
+ var import_bcrypt2 = __toESM(require("bcrypt"));
261
+ function comparePassword(password, hashedPassword) {
262
+ return __async(this, null, function* () {
263
+ return new Promise((resolve) => {
264
+ import_bcrypt2.default.compare(password, hashedPassword, (err, result) => {
265
+ if (err) {
266
+ resolve(false);
267
+ }
268
+ resolve(result);
269
+ });
270
+ });
271
+ });
272
+ }
273
+
274
+ // src/utils/mailer.ts
275
+ var import_nodemailer = require("nodemailer");
276
+ var useMailer = class {
277
+ constructor(config2) {
278
+ this.config = config2;
279
+ this.transporter = (0, import_nodemailer.createTransport)({
280
+ host: config2.host,
281
+ port: config2.port,
282
+ secure: config2.secure,
283
+ auth: {
284
+ user: config2.email,
285
+ pass: config2.password
286
+ }
287
+ });
288
+ }
289
+ sendMail(_0) {
290
+ return __async(this, arguments, function* ({
291
+ to,
292
+ subject,
293
+ text,
294
+ html,
295
+ sender
296
+ }) {
297
+ const mailOptions = {
298
+ from: sender ? `${sender} <${this.config.email}>` : this.config.email,
299
+ to,
300
+ subject
301
+ };
302
+ if (text) {
303
+ mailOptions.text = text;
304
+ }
305
+ if (html) {
306
+ mailOptions.html = html;
307
+ }
308
+ try {
309
+ yield this.transporter.sendMail(mailOptions);
310
+ return "Email sent successfully";
311
+ } catch (error) {
312
+ return Promise.reject(error);
313
+ }
314
+ });
315
+ }
316
+ };
317
+
318
+ // src/utils/generate-token.ts
319
+ var import_jsonwebtoken2 = __toESM(require("jsonwebtoken"));
320
+ function generateToken({ metadata = {}, secret = "", options = {} } = {}) {
321
+ if (!secret)
322
+ throw new Error("Missing secret.");
323
+ return import_jsonwebtoken2.default.sign(metadata, secret, options);
324
+ }
325
+
326
+ // src/utils/paginate.ts
327
+ function paginate(items, page = 0, limit = 10, length) {
328
+ if (length === 0) {
329
+ return {
330
+ items: [],
331
+ pages: 0,
332
+ pageRange: `0-0 of 0`
333
+ };
334
+ }
335
+ const startIndex = page * limit + 1;
336
+ const endIndex = Math.min(startIndex + limit - 1, length);
337
+ return {
338
+ items,
339
+ pages: Math.ceil(length / limit),
340
+ pageRange: `${startIndex}-${endIndex} of ${length}`
341
+ };
342
+ }
343
+
344
+ // src/utils/redis.ts
345
+ var import_redis = require("redis");
346
+
347
+ // src/config.ts
348
+ var dotenv = __toESM(require("dotenv"));
349
+ dotenv.config();
350
+ var MONGO_URI = process.env.MONGO_URI || "mongodb://localhost:27017";
351
+ var MONGO_DB = process.env.MONGO_DB || "default";
352
+ var PORT = Number(process.env.PORT || 3001);
353
+ var SECRET_KEY = process.env.SECRET_KEY;
354
+ var isDev = process.env.NODE_ENV !== "production";
355
+ var MAILER_TRANSPORT_HOST = process.env.MAILER_TRANSPORT_HOST;
356
+ var MAILER_TRANSPORT_PORT = Number(
357
+ process.env.MAILER_TRANSPORT_PORT || 465
358
+ );
359
+ var MAILER_TRANSPORT_SECURE = process.env.MAILER_TRANSPORT_SECURE === "true";
360
+ var MAILER_EMAIL = process.env.MAILER_EMAIL;
361
+ var MAILER_PASSWORD = process.env.MAILER_PASSWORD;
362
+ var ACCESS_TOKEN_SECRET = process.env.ACCESS_TOKEN_SECRET || "access_token_secret";
363
+ var REFRESH_TOKEN_SECRET = process.env.REFRESH_TOKEN_SECRET || "refresh_token_secret";
364
+ var ACCESS_TOKEN_EXPIRY = process.env.ACCESS_TOKEN_EXPIRY || "15s";
365
+ var REFRESH_TOKEN_EXPIRY = process.env.REFRESH_TOKEN_EXPIRY || "30d";
366
+ var APP_ACCOUNT = process.env.APP_ACCOUNT || "http://localhost:3000";
367
+ var VERIFICATION_FORGET_PASSWORD_DURATION = process.env.VERIFICATION_FORGET_PASSWORD_DURATION || "10 minutes";
368
+ var VERIFICATION_USER_INVITE_DURATION = process.env.VERIFICATION_USER_INVITE_DURATION || "3 days";
369
+ var REDIS_HOST = process.env.REDIS_HOST;
370
+ var REDIS_PORT = Number(process.env.REDIS_PORT || 6379);
371
+ var REDIS_PASSWORD = process.env.REDIS_PASSWORD;
372
+ var DEFAULT_USER_EMAIL = process.env.DEFAULT_USER_EMAIL;
373
+ var DEFAULT_USER_PASSWORD = process.env.DEFAULT_USER_PASSWORD;
374
+ var DEFAULT_USER_FIRST_NAME = process.env.DEFAULT_USER_FIRST_NAME;
375
+ var DEFAULT_USER_LAST_NAME = process.env.DEFAULT_USER_LAST_NAME;
376
+ var SPACES_ACCESS_KEY = process.env.SPACES_ACCESS_KEY;
377
+ var SPACES_SECRET_KEY = process.env.SPACES_SECRET_KEY;
378
+ var SPACES_ENDPOINT = process.env.SPACES_ENDPOINT;
379
+ var SPACES_REGION = process.env.SPACES_REGION;
380
+ var SPACES_BUCKET = process.env.SPACES_BUCKET;
381
+
382
+ // src/utils/redis.ts
383
+ var redisClient;
384
+ function initRedisClient() {
385
+ return __async(this, null, function* () {
386
+ redisClient = yield (0, import_redis.createClient)({
387
+ password: REDIS_PASSWORD,
388
+ socket: {
389
+ host: REDIS_HOST,
390
+ port: REDIS_PORT
391
+ }
392
+ });
393
+ });
394
+ }
395
+ function useRedisClient() {
396
+ return redisClient;
397
+ }
398
+
399
+ // src/utils/compile-handlebar.ts
400
+ var import_handlebars = __toESM(require("handlebars"));
401
+ var import_fs = __toESM(require("fs"));
402
+ function compileHandlebar({ context = {}, filePath = "" } = {}) {
403
+ const templateSource = import_fs.default.readFileSync(filePath, "utf8");
404
+ const template = import_handlebars.default.compile(templateSource);
405
+ return template(context);
406
+ }
407
+
408
+ // src/utils/get-directory.ts
409
+ var import_path = __toESM(require("path"));
410
+ function getDirectory(directory, filePath) {
411
+ return import_path.default.resolve(directory, `${filePath}.hbs`);
412
+ }
413
+
414
+ // src/utils/s3.ts
415
+ var import_client_s3 = require("@aws-sdk/client-s3");
416
+ var import_stream = require("stream");
417
+ var useS3 = class {
418
+ constructor(config2) {
419
+ this.config = config2;
420
+ this.client = new import_client_s3.S3Client({
421
+ endpoint: config2.endpoint,
422
+ region: config2.region,
423
+ credentials: {
424
+ accessKeyId: config2.accessKeyId,
425
+ secretAccessKey: config2.secretAccessKey
426
+ },
427
+ forcePathStyle: false
428
+ // Optional, based on usage
429
+ });
430
+ }
431
+ uploadObject(_0) {
432
+ return __async(this, arguments, function* ({
433
+ key,
434
+ body,
435
+ metadata = {},
436
+ contentType
437
+ }) {
438
+ const buffer = import_stream.Readable.from(body);
439
+ try {
440
+ yield this.client.send(new import_client_s3.PutObjectCommand({
441
+ Bucket: this.config.bucket,
442
+ Key: key,
443
+ Body: buffer,
444
+ ACL: "public-read",
445
+ Metadata: metadata,
446
+ ContentType: contentType,
447
+ ContentLength: Buffer.byteLength(body)
448
+ }));
449
+ return "Successfully uploaded file.";
450
+ } catch (error) {
451
+ return Promise.reject(error);
452
+ }
453
+ });
454
+ }
455
+ deleteObject(key = "") {
456
+ return __async(this, null, function* () {
457
+ try {
458
+ yield this.client.send(new import_client_s3.DeleteObjectCommand({ Key: key, Bucket: this.config.bucket }));
459
+ return "Successfully deleted file.";
460
+ } catch (error) {
461
+ return Promise.reject(error);
462
+ }
463
+ });
464
+ }
465
+ };
466
+
467
+ // src/utils/atlas.ts
468
+ var import_mongodb = require("mongodb");
469
+ var useAtlas = class {
470
+ // Initialize the MongoDB connection with the provided config
471
+ static initialize(config2) {
472
+ return __async(this, null, function* () {
473
+ if (this.client) {
474
+ console.warn(`Client is already initialized. Skipping initialization.`);
475
+ return;
476
+ }
477
+ const { uri, db } = config2;
478
+ this.client = new import_mongodb.MongoClient(uri, { maxPoolSize: 10, maxIdleTimeMS: 6e4, connectTimeoutMS: 6e4 });
479
+ try {
480
+ yield this.client.connect();
481
+ this.database = this.client.db(db);
482
+ console.log(`Connected to database "${db}".`);
483
+ } catch (error) {
484
+ this.client = null;
485
+ throw error;
486
+ }
487
+ });
488
+ }
489
+ // Get the MongoDB client
490
+ static getClient() {
491
+ return this.client;
492
+ }
493
+ // Get the database
494
+ static getDb() {
495
+ return this.database;
496
+ }
497
+ // Close the connection
498
+ static close() {
499
+ return __async(this, null, function* () {
500
+ if (this.client) {
501
+ yield this.client.close();
502
+ this.client = null;
503
+ this.database = null;
504
+ console.log(`Closed connection to the database.`);
505
+ } else {
506
+ console.warn(`No client is currently initialized.`);
507
+ }
508
+ });
509
+ }
510
+ };
511
+ useAtlas.client = null;
512
+ useAtlas.database = null;
513
+
514
+ // src/utils/prepend-zero.ts
515
+ function prependZeros(value, length = 6) {
516
+ let numberStr = value.toString();
517
+ let numZeros = Math.max(0, length - numberStr.length);
518
+ return numberStr.padStart(numZeros + numberStr.length, "0");
519
+ }
520
+
521
+ // src/utils/to-object-id.ts
522
+ var import_mongodb2 = require("mongodb");
523
+ function toObjectId(value) {
524
+ if (!value) {
525
+ throw new BadRequestError("Valid is required.");
526
+ }
527
+ const instanceOfObjectId = value instanceof import_mongodb2.ObjectId;
528
+ if (!instanceOfObjectId) {
529
+ const isValidHex = /^[0-9a-fA-F]{24}$/.test(value);
530
+ if (!isValidHex) {
531
+ throw new BadRequestError("Invalid value, expecting a hex value.");
532
+ }
533
+ }
534
+ try {
535
+ return new import_mongodb2.ObjectId(value);
536
+ } catch (error) {
537
+ throw new BadRequestError("Invalid ID.");
538
+ }
539
+ }
540
+
541
+ // src/models/verification.model.ts
542
+ var import_mongodb3 = require("mongodb");
543
+ var MVerification = class {
544
+ constructor(value) {
545
+ var _a, _b, _c, _d, _e, _f, _g, _h;
546
+ this._id = (_a = value._id) != null ? _a : new import_mongodb3.ObjectId();
547
+ this.type = (_b = value.type) != null ? _b : "";
548
+ this.email = (_c = value.email) != null ? _c : "";
549
+ this.metadata = (_d = value.metadata) != null ? _d : {};
550
+ this.status = (_e = value.status) != null ? _e : "pending";
551
+ this.createdAt = (_f = value.createdAt) != null ? _f : /* @__PURE__ */ new Date();
552
+ this.updatedAt = (_g = value.updatedAt) != null ? _g : null;
553
+ this.expireAt = (_h = value.expireAt) != null ? _h : new Date(Date.now() + 3600 * 1e3);
554
+ }
555
+ };
556
+
557
+ // src/repositories/verification.repository.ts
558
+ var import_utils = require("@goweekdays/utils");
559
+ var import_mongodb4 = require("mongodb");
560
+ function useVerificationRepo() {
561
+ const db = import_utils.useAtlas.getDb();
562
+ if (!db) {
563
+ throw new import_utils.InternalServerError("Unable to connect to server.");
564
+ }
565
+ const collection = db.collection("verifications");
566
+ function createTextIndex() {
567
+ return __async(this, null, function* () {
568
+ try {
569
+ yield collection.createIndex({
570
+ email: "text"
571
+ });
572
+ } catch (error) {
573
+ throw new Error("Failed to create text index on email.");
574
+ }
575
+ });
576
+ }
577
+ function add(value, session) {
578
+ return __async(this, null, function* () {
579
+ value = new MVerification(value);
580
+ try {
581
+ const res = yield collection.insertOne(value, { session });
582
+ return res.insertedId;
583
+ } catch (error) {
584
+ import_utils.logger.log({
585
+ level: "info",
586
+ message: String(error)
587
+ });
588
+ throw new import_utils.InternalServerError("Server internal error.");
589
+ }
590
+ });
591
+ }
592
+ function getById(_id) {
593
+ return __async(this, null, function* () {
594
+ try {
595
+ _id = new import_mongodb4.ObjectId(_id);
596
+ } catch (error) {
597
+ throw new import_utils.BadRequestError("Invalid ID.");
598
+ }
599
+ try {
600
+ return yield collection.findOne({ _id });
601
+ } catch (error) {
602
+ throw new import_utils.InternalServerError(
603
+ "Internal server error, failed to retrieve verification."
604
+ );
605
+ }
606
+ });
607
+ }
608
+ function getVerifications() {
609
+ return __async(this, arguments, function* ({
610
+ search = "",
611
+ page = 1,
612
+ limit = 10,
613
+ sort = {},
614
+ status = "active",
615
+ type = ""
616
+ } = {}) {
617
+ page = page > 0 ? page - 1 : 0;
618
+ const query = { status };
619
+ sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
620
+ if (search) {
621
+ query.$text = { $search: search };
622
+ }
623
+ if (type) {
624
+ query.type = type;
625
+ }
626
+ try {
627
+ const items = yield collection.aggregate([
628
+ { $match: query },
629
+ { $sort: sort },
630
+ { $skip: page * limit },
631
+ { $limit: limit },
632
+ {
633
+ $project: {
634
+ _id: 1,
635
+ createdAt: 1,
636
+ email: 1,
637
+ type: 1,
638
+ metadata: 1,
639
+ status: 1
640
+ }
641
+ }
642
+ ]).toArray();
643
+ const length = yield collection.countDocuments(query);
644
+ return (0, import_utils.paginate)(items, page, limit, length);
645
+ } catch (error) {
646
+ import_utils.logger.log({ level: "error", message: `${error}` });
647
+ throw error;
648
+ }
649
+ });
650
+ }
651
+ function getByIdByType(type) {
652
+ return __async(this, null, function* () {
653
+ try {
654
+ return yield collection.find({ type }).toArray();
655
+ } catch (error) {
656
+ return Promise.reject(error);
657
+ }
658
+ });
659
+ }
660
+ function updateStatusById(_id, status, session) {
661
+ return __async(this, null, function* () {
662
+ try {
663
+ _id = new import_mongodb4.ObjectId(_id);
664
+ } catch (error) {
665
+ throw new import_utils.BadRequestError("Invalid ID.");
666
+ }
667
+ try {
668
+ return yield collection.updateOne(
669
+ { _id },
670
+ { $set: { status, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
671
+ { session }
672
+ );
673
+ } catch (error) {
674
+ throw new import_utils.InternalServerError("Error updating verification status.");
675
+ }
676
+ });
677
+ }
678
+ return {
679
+ createTextIndex,
680
+ add,
681
+ getVerifications,
682
+ getById,
683
+ getByIdByType,
684
+ updateStatusById
685
+ };
686
+ }
687
+
688
+ // src/services/verification.service.ts
689
+ var import_utils4 = require("@goweekdays/utils");
690
+
691
+ // src/repositories/user.repository.ts
692
+ var import_mongodb6 = require("mongodb");
693
+
694
+ // src/models/user.model.ts
695
+ var import_mongodb5 = require("mongodb");
696
+ var import_utils2 = require("@goweekdays/utils");
697
+ var MUserRole = class {
698
+ constructor(value) {
699
+ var _a, _b, _c, _d;
700
+ this.name = (_a = value.name) != null ? _a : "";
701
+ this.app = (_b = value.app) != null ? _b : "";
702
+ this.role = (_c = value.role) != null ? _c : "";
703
+ this.status = (_d = value.status) != null ? _d : "active";
704
+ }
705
+ };
706
+ var MUser = class {
707
+ constructor(value) {
708
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
709
+ this._id = (_a = value._id) != null ? _a : new import_mongodb5.ObjectId();
710
+ this.email = (_b = value.email) != null ? _b : "";
711
+ this.password = (_c = value.password) != null ? _c : "";
712
+ this.prefix = (_d = value.prefix) != null ? _d : "";
713
+ this.firstName = (_e = value.firstName) != null ? _e : "";
714
+ this.middleName = (_f = value.middleName) != null ? _f : "";
715
+ this.lastName = (_g = value.lastName) != null ? _g : "";
716
+ this.suffix = (_h = value.suffix) != null ? _h : "";
717
+ this.birthMonth = (_i = value.birthMonth) != null ? _i : "";
718
+ this.birthDay = (_j = value.birthDay) != null ? _j : 0;
719
+ this.birthYear = (_k = value.birthYear) != null ? _k : 0;
720
+ this.gender = (_l = value.gender) != null ? _l : "";
721
+ this.type = (_m = value.type) != null ? _m : "";
722
+ this.roles = (_n = value.roles) != null ? _n : [];
723
+ if (value.roles && value.roles.length) {
724
+ value.roles.forEach((role) => {
725
+ var _a2;
726
+ try {
727
+ role.role = new import_mongodb5.ObjectId(role.role);
728
+ } catch (error) {
729
+ throw new import_utils2.BadRequestError("Invalid role ID.");
730
+ }
731
+ if (!role.app) {
732
+ throw new import_utils2.BadRequestError("App is required.");
733
+ }
734
+ if (!role.name) {
735
+ throw new import_utils2.BadRequestError("Name is required.");
736
+ }
737
+ role.status = (_a2 = role.status) != null ? _a2 : "active";
738
+ });
739
+ }
740
+ this.roles = (_o = value.roles) != null ? _o : [];
741
+ this.status = (_p = value.status) != null ? _p : "";
742
+ this.createdAt = (_q = value.createdAt) != null ? _q : (/* @__PURE__ */ new Date()).toISOString();
743
+ this.updatedAt = (_r = value.updatedAt) != null ? _r : "";
744
+ this.deletedAt = (_s = value.deletedAt) != null ? _s : "";
745
+ }
746
+ };
747
+
748
+ // src/repositories/user.repository.ts
749
+ var import_utils3 = require("@goweekdays/utils");
750
+ function useUserRepo() {
751
+ const db = import_utils3.useAtlas.getDb();
752
+ if (!db) {
753
+ throw new import_utils3.InternalServerError("Unable to connect to server.");
754
+ }
755
+ const collection = db.collection("users");
756
+ function createTextIndex() {
757
+ return __async(this, null, function* () {
758
+ try {
759
+ yield collection.createIndex({
760
+ firstName: "text",
761
+ middleName: "text",
762
+ lastName: "text",
763
+ email: "text"
764
+ });
765
+ } catch (error) {
766
+ throw new Error("Failed to create text index on email.");
767
+ }
768
+ });
769
+ }
770
+ function createUniqueIndex() {
771
+ return __async(this, null, function* () {
772
+ try {
773
+ yield collection.createIndex(
774
+ { email: 1, deletedAt: 1 },
775
+ { unique: true }
776
+ );
777
+ } catch (error) {
778
+ throw new Error("Failed to create unique index on email.");
779
+ }
780
+ });
781
+ }
782
+ function createUser(value, session) {
783
+ return __async(this, null, function* () {
784
+ try {
785
+ value = new MUser(value);
786
+ const res = yield collection.insertOne(value, { session });
787
+ return res.insertedId;
788
+ } catch (error) {
789
+ import_utils3.logger.log({ level: "error", message: `${error}` });
790
+ const isDuplicated = error.message.includes("duplicate");
791
+ if (isDuplicated) {
792
+ throw new import_utils3.BadRequestError("Item name already exists");
793
+ }
794
+ throw new import_utils3.InternalServerError("Internal server error.");
795
+ }
796
+ });
797
+ }
798
+ function getUserByEmail(email) {
799
+ return __async(this, null, function* () {
800
+ try {
801
+ return yield collection.findOne({ email });
802
+ } catch (error) {
803
+ throw new Error("Failed to get user by email.");
804
+ }
805
+ });
806
+ }
807
+ function getByEmailApp(email, app) {
808
+ return __async(this, null, function* () {
809
+ try {
810
+ return yield collection.findOne({ email, "roles.app": app });
811
+ } catch (error) {
812
+ throw new Error("Failed to get user by email.");
813
+ }
814
+ });
815
+ }
816
+ function getUserById(_id) {
817
+ return __async(this, null, function* () {
818
+ try {
819
+ _id = new import_mongodb6.ObjectId(_id);
820
+ } catch (error) {
821
+ throw new Error("Invalid user ID.");
822
+ }
823
+ try {
824
+ return yield collection.findOne({ _id });
825
+ } catch (error) {
826
+ throw new Error("Failed to get user by email.");
827
+ }
828
+ });
829
+ }
830
+ function getUsers() {
831
+ return __async(this, arguments, function* ({
832
+ search = "",
833
+ page = 1,
834
+ limit = 10,
835
+ sort = {},
836
+ status = "active",
837
+ type = ""
838
+ } = {}) {
839
+ page = page > 0 ? page - 1 : 0;
840
+ const query = { status };
841
+ sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
842
+ if (search) {
843
+ query.$text = { $search: search };
844
+ }
845
+ if (type) {
846
+ query.type = type;
847
+ }
848
+ try {
849
+ const items = yield collection.aggregate([
850
+ { $match: query },
851
+ { $sort: sort },
852
+ { $skip: page * limit },
853
+ { $limit: limit },
854
+ {
855
+ $project: {
856
+ _id: 1,
857
+ name: {
858
+ $concat: ["$firstName", " ", "$lastName"]
859
+ },
860
+ email: 1,
861
+ type: 1,
862
+ status: 1
863
+ }
864
+ }
865
+ ]).toArray();
866
+ const length = yield collection.countDocuments(query);
867
+ return (0, import_utils3.paginate)(items, page, limit, length);
868
+ } catch (error) {
869
+ import_utils3.logger.log({ level: "error", message: `${error}` });
870
+ throw error;
871
+ }
872
+ });
873
+ }
874
+ function updatePassword() {
875
+ return __async(this, arguments, function* ({ _id, password } = {}, session) {
876
+ try {
877
+ _id = new import_mongodb6.ObjectId(_id);
878
+ } catch (error) {
879
+ throw new Error("Invalid user ID.");
880
+ }
881
+ try {
882
+ return yield collection.updateOne(
883
+ { _id },
884
+ { $set: { password } },
885
+ { session }
886
+ );
887
+ } catch (error) {
888
+ throw new Error("Failed to update user password.");
889
+ }
890
+ });
891
+ }
892
+ function updateName() {
893
+ return __async(this, arguments, function* ({ _id, firstName, lastName } = {}, session) {
894
+ try {
895
+ _id = new import_mongodb6.ObjectId(_id);
896
+ } catch (error) {
897
+ throw new Error("Invalid user ID.");
898
+ }
899
+ try {
900
+ return yield collection.updateOne(
901
+ { _id },
902
+ { $set: { firstName, lastName } },
903
+ { session }
904
+ );
905
+ } catch (error) {
906
+ throw new Error("Failed to update user profile.");
907
+ }
908
+ });
909
+ }
910
+ function updateBirthday() {
911
+ return __async(this, arguments, function* ({ _id, month, day, year } = {}, session) {
912
+ try {
913
+ _id = new import_mongodb6.ObjectId(_id);
914
+ } catch (error) {
915
+ throw new Error("Invalid user ID.");
916
+ }
917
+ try {
918
+ return yield collection.updateOne(
919
+ { _id },
920
+ { $set: { birthMonth: month, birthDay: day, birthYear: year } },
921
+ { session }
922
+ );
923
+ } catch (error) {
924
+ throw new Error("Failed to update user birthday.");
925
+ }
926
+ });
927
+ }
928
+ function updateUserFieldById() {
929
+ return __async(this, arguments, function* ({ _id, field, value } = {}, session) {
930
+ const allowedFields = ["gender", "email", "contact", "profile"];
931
+ if (!allowedFields.includes(field)) {
932
+ throw new import_utils3.BadRequestError(
933
+ `Field "${field}" is not allowed to be updated.`
934
+ );
935
+ }
936
+ try {
937
+ _id = new import_mongodb6.ObjectId(_id);
938
+ } catch (error) {
939
+ throw new import_utils3.BadRequestError("Invalid ID.");
940
+ }
941
+ try {
942
+ yield collection.updateOne(
943
+ { _id },
944
+ { $set: { [field]: value } },
945
+ // Dynamically set the field
946
+ { session }
947
+ );
948
+ return `Successfully updated user ${field}.`;
949
+ } catch (error) {
950
+ throw new import_utils3.InternalServerError(`Failed to update user ${field}.`);
951
+ }
952
+ });
953
+ }
954
+ function addUserRole() {
955
+ return __async(this, arguments, function* ({ _id, role } = {}, session) {
956
+ try {
957
+ _id = new import_mongodb6.ObjectId(_id);
958
+ } catch (error) {
959
+ throw new import_utils3.BadRequestError("Invalid user ID.");
960
+ }
961
+ role = new MUserRole(role);
962
+ try {
963
+ yield collection.updateOne(
964
+ { _id, "roles.app": { $ne: role.app } },
965
+ // @ts-ignore
966
+ { $push: { roles: role } },
967
+ { session }
968
+ );
969
+ } catch (error) {
970
+ throw new import_utils3.InternalServerError("Failed to add user role.");
971
+ }
972
+ });
973
+ }
974
+ return {
975
+ createTextIndex,
976
+ createUniqueIndex,
977
+ createUser,
978
+ getUserByEmail,
979
+ getUserById,
980
+ getUsers,
981
+ updatePassword,
982
+ updateName,
983
+ updateBirthday,
984
+ updateUserFieldById,
985
+ addUserRole,
986
+ getByEmailApp
987
+ };
988
+ }
989
+
990
+ // src/services/verification.service.ts
991
+ function useVerificationService() {
992
+ const MailerConfig = {
993
+ host: MAILER_TRANSPORT_HOST,
994
+ port: MAILER_TRANSPORT_PORT,
995
+ secure: MAILER_TRANSPORT_SECURE,
996
+ email: MAILER_EMAIL,
997
+ password: MAILER_PASSWORD
998
+ };
999
+ const mailer = new import_utils4.useMailer(MailerConfig);
1000
+ const {
1001
+ add,
1002
+ getById: _getById,
1003
+ updateStatusById: _updateStatusById,
1004
+ getVerifications: _getVerifications
1005
+ } = useVerificationRepo();
1006
+ const { addUserRole, getUserByEmail, getByEmailApp } = useUserRepo();
1007
+ function createUserInvite(_0) {
1008
+ return __async(this, arguments, function* ({
1009
+ email,
1010
+ metadata
1011
+ }) {
1012
+ const value = {
1013
+ type: "user-invite",
1014
+ email,
1015
+ metadata,
1016
+ expireAt: new Date(
1017
+ (/* @__PURE__ */ new Date()).getTime() + 72 * 60 * 60 * 1e3
1018
+ ).toISOString(),
1019
+ // 72 hours (3 days) from now
1020
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
1021
+ };
1022
+ try {
1023
+ const user = yield getByEmailApp(email, metadata.app);
1024
+ if (user) {
1025
+ throw new import_utils4.BadRequestError(
1026
+ `User already a user in ${metadata.app} app.`
1027
+ );
1028
+ }
1029
+ const res = yield add(value);
1030
+ const dir = __dirname;
1031
+ const filePath = (0, import_utils4.getDirectory)(dir, "./public/handlebars/user-invite");
1032
+ const emailContent = (0, import_utils4.compileHandlebar)({
1033
+ context: {
1034
+ validity: VERIFICATION_USER_INVITE_DURATION,
1035
+ link: `${APP_ACCOUNT}/verify/invitation/${res}`
1036
+ },
1037
+ filePath
1038
+ });
1039
+ mailer.sendMail({
1040
+ to: email,
1041
+ subject: "User Invite",
1042
+ html: emailContent,
1043
+ sender: "Education Ecosystem"
1044
+ }).catch((error) => {
1045
+ import_utils4.logger.log({
1046
+ level: "error",
1047
+ message: `Error sending user invite email: ${error}`
1048
+ });
1049
+ });
1050
+ return res;
1051
+ } catch (error) {
1052
+ throw error;
1053
+ }
1054
+ });
1055
+ }
1056
+ function createForgetPassword(email) {
1057
+ return __async(this, null, function* () {
1058
+ const value = {
1059
+ type: "forget-password",
1060
+ email,
1061
+ expireAt: new Date((/* @__PURE__ */ new Date()).getTime() + 10 * 60 * 1e3).toISOString(),
1062
+ // 10 minutes from now
1063
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
1064
+ };
1065
+ try {
1066
+ const res = yield add(value);
1067
+ const dir = __dirname;
1068
+ const filePath = (0, import_utils4.getDirectory)(dir, "./public/handlebars/forget-password");
1069
+ const emailContent = (0, import_utils4.compileHandlebar)({
1070
+ context: {
1071
+ validity: VERIFICATION_FORGET_PASSWORD_DURATION,
1072
+ link: `${APP_ACCOUNT}/reset-password/${res}`
1073
+ },
1074
+ filePath
1075
+ });
1076
+ mailer.sendMail({ to: email, subject: "Forget Password", html: emailContent }).catch((error) => {
1077
+ import_utils4.logger.log({
1078
+ level: "error",
1079
+ message: `Error sending forget password email: ${error}`
1080
+ });
1081
+ });
1082
+ return res;
1083
+ } catch (error) {
1084
+ throw new import_utils4.InternalServerError("Error creating one-time password");
1085
+ }
1086
+ });
1087
+ }
1088
+ function getById(id) {
1089
+ return __async(this, null, function* () {
1090
+ try {
1091
+ const _id = yield _getById(id);
1092
+ if (!_id) {
1093
+ throw new import_utils4.NotFoundError("Verification not found.");
1094
+ }
1095
+ return _id;
1096
+ } catch (error) {
1097
+ throw error;
1098
+ }
1099
+ });
1100
+ }
1101
+ function getVerifications() {
1102
+ return __async(this, arguments, function* ({
1103
+ search = "",
1104
+ page = 1,
1105
+ status = "",
1106
+ type = "",
1107
+ limit = 10
1108
+ } = {}) {
1109
+ try {
1110
+ return yield _getVerifications({ search, page, status, type, limit });
1111
+ } catch (error) {
1112
+ throw error;
1113
+ }
1114
+ });
1115
+ }
1116
+ function errorByType(type, status) {
1117
+ if (type === "user-invite" && status === "expired") {
1118
+ throw new import_utils4.BadRequestError(
1119
+ "Invitation has already expired, please contact admin to resend the invitation."
1120
+ );
1121
+ }
1122
+ if (type === "user-invite" && status === "complete") {
1123
+ throw new import_utils4.BadRequestError(
1124
+ "User already registered, please login to continue."
1125
+ );
1126
+ }
1127
+ throw new import_utils4.BadRequestError("Invalid verification.");
1128
+ }
1129
+ function verify(id) {
1130
+ return __async(this, null, function* () {
1131
+ var _a, _b, _c, _d, _e, _f, _g;
1132
+ const session = (_a = import_utils4.useAtlas.getClient()) == null ? void 0 : _a.startSession();
1133
+ session == null ? void 0 : session.startTransaction();
1134
+ try {
1135
+ const _id = yield _getById(id);
1136
+ if (!_id) {
1137
+ throw new import_utils4.NotFoundError("Verification not found.");
1138
+ }
1139
+ if (_id.status === "expired") {
1140
+ errorByType(_id.type, "expired");
1141
+ }
1142
+ if (_id.status === "complete") {
1143
+ throw new import_utils4.BadRequestError("Verification already completed.");
1144
+ }
1145
+ const expiration = new Date(_id.expireAt).getTime();
1146
+ const now = (/* @__PURE__ */ new Date()).getTime();
1147
+ if (now > expiration) {
1148
+ yield _updateStatusById(id, "expired");
1149
+ errorByType(_id.type, "expired");
1150
+ }
1151
+ const user = yield getUserByEmail(_id.email);
1152
+ const appMember = (_b = user == null ? void 0 : user.roles) == null ? void 0 : _b.filter((i) => {
1153
+ var _a2;
1154
+ return i.app === ((_a2 = _id.metadata) == null ? void 0 : _a2.app);
1155
+ });
1156
+ if ((appMember == null ? void 0 : appMember.length) === 0 && user && _id.type === "user-invite") {
1157
+ yield addUserRole(
1158
+ {
1159
+ _id: (_c = user._id) == null ? void 0 : _c.toString(),
1160
+ role: {
1161
+ name: (_d = _id.metadata) == null ? void 0 : _d.name,
1162
+ app: (_e = _id.metadata) == null ? void 0 : _e.app,
1163
+ role: (_f = _id.metadata) == null ? void 0 : _f.role
1164
+ }
1165
+ },
1166
+ session
1167
+ );
1168
+ yield _updateStatusById(id, "complete", session);
1169
+ yield session == null ? void 0 : session.commitTransaction();
1170
+ return "Successfully added user role.";
1171
+ }
1172
+ if ((appMember == null ? void 0 : appMember.length) && _id.type === "user-invite") {
1173
+ yield _updateStatusById(id, "expired");
1174
+ throw new import_utils4.BadRequestError(
1175
+ `Invalid user invitation. User is already a user in the ${(_g = _id.metadata) == null ? void 0 : _g.app} app.`
1176
+ );
1177
+ }
1178
+ return _id;
1179
+ } catch (error) {
1180
+ yield session == null ? void 0 : session.abortTransaction();
1181
+ import_utils4.logger.log({
1182
+ level: "info",
1183
+ message: `Error verifying user invitation: ${error}`
1184
+ });
1185
+ throw error;
1186
+ } finally {
1187
+ session == null ? void 0 : session.endSession();
1188
+ }
1189
+ });
1190
+ }
1191
+ function cancelUserInvitation(id) {
1192
+ return __async(this, null, function* () {
1193
+ try {
1194
+ yield updateStatusById(id, "cancelled");
1195
+ } catch (error) {
1196
+ throw new import_utils4.InternalServerError(
1197
+ `Error cancelling user invitation: ${error}`
1198
+ );
1199
+ }
1200
+ });
1201
+ }
1202
+ function updateStatusById(_id, status) {
1203
+ return __async(this, null, function* () {
1204
+ try {
1205
+ yield _updateStatusById(_id, status);
1206
+ return "Successfully updated verification status.";
1207
+ } catch (error) {
1208
+ throw error;
1209
+ }
1210
+ });
1211
+ }
1212
+ return {
1213
+ createForgetPassword,
1214
+ createUserInvite,
1215
+ verify,
1216
+ getById,
1217
+ getVerifications,
1218
+ cancelUserInvitation,
1219
+ updateStatusById
1220
+ };
1221
+ }
1222
+
1223
+ // src/controllers/verification.controller.ts
1224
+ var import_utils5 = require("@goweekdays/utils");
1225
+ var import_joi = __toESM(require("joi"));
1226
+ var import_mongodb7 = require("mongodb");
1227
+ function useVerificationController() {
1228
+ const {
1229
+ createUserInvite: _createUserInvite,
1230
+ createForgetPassword: _createForgetPassword,
1231
+ cancelUserInvitation: _cancelUserInvitation,
1232
+ verify: _verify,
1233
+ getVerifications: _getVerifications
1234
+ } = useVerificationService();
1235
+ function createUserInvite(req, res, next) {
1236
+ return __async(this, null, function* () {
1237
+ var _a, _b, _c, _d;
1238
+ const email = (_a = req.body.email) != null ? _a : "";
1239
+ const app = (_b = req.body.app) != null ? _b : "";
1240
+ const role = (_c = req.body.role) != null ? _c : "";
1241
+ const name = (_d = req.body.name) != null ? _d : "";
1242
+ const validation = import_joi.default.object({
1243
+ email: import_joi.default.string().email().required(),
1244
+ app: import_joi.default.string().optional().allow("", null),
1245
+ role: import_joi.default.string().hex().optional().allow("", null),
1246
+ name: import_joi.default.string().optional().allow("", null)
1247
+ });
1248
+ const { error } = validation.validate({
1249
+ email,
1250
+ app,
1251
+ role,
1252
+ name
1253
+ });
1254
+ if (error) {
1255
+ next(new import_utils5.BadRequestError(error.message));
1256
+ return;
1257
+ }
1258
+ try {
1259
+ yield _createUserInvite({
1260
+ email,
1261
+ metadata: {
1262
+ app,
1263
+ role,
1264
+ name
1265
+ }
1266
+ });
1267
+ res.json({ message: "Successfully invited user." });
1268
+ return;
1269
+ } catch (error2) {
1270
+ console.log(error2);
1271
+ next(error2);
1272
+ }
1273
+ });
1274
+ }
1275
+ function createForgetPassword(req, res, next) {
1276
+ return __async(this, null, function* () {
1277
+ const email = req.body.email || "";
1278
+ const validation = import_joi.default.string().email().required();
1279
+ const { error } = validation.validate(email);
1280
+ if (error) {
1281
+ next(new import_utils5.BadRequestError(error.message));
1282
+ return;
1283
+ }
1284
+ try {
1285
+ yield _createForgetPassword(email);
1286
+ res.json({
1287
+ message: "Check your email to verify it before resetting your password."
1288
+ });
1289
+ return;
1290
+ } catch (error2) {
1291
+ if (error2 instanceof import_utils5.AppError) {
1292
+ next(error2);
1293
+ } else {
1294
+ next(new import_utils5.InternalServerError("An unexpected error occurred"));
1295
+ }
1296
+ }
1297
+ });
1298
+ }
1299
+ function getVerifications(req, res, next) {
1300
+ return __async(this, null, function* () {
1301
+ var _a, _b, _c;
1302
+ const status = (_a = req.query.status) != null ? _a : "";
1303
+ const search = (_b = req.query.search) != null ? _b : "";
1304
+ const page = (_c = Number(req.query.page)) != null ? _c : 1;
1305
+ const validation = import_joi.default.object({
1306
+ status: import_joi.default.string().required(),
1307
+ search: import_joi.default.string().optional().allow("", null),
1308
+ page: import_joi.default.number().required()
1309
+ });
1310
+ const { error } = validation.validate({ status, search, page });
1311
+ if (error) {
1312
+ next(new import_utils5.BadRequestError(error.message));
1313
+ return;
1314
+ }
1315
+ try {
1316
+ const items = yield _getVerifications({ status, search, page });
1317
+ res.json(items);
1318
+ return;
1319
+ } catch (error2) {
1320
+ next(error2);
1321
+ }
1322
+ });
1323
+ }
1324
+ function verify(req, res, next) {
1325
+ return __async(this, null, function* () {
1326
+ const id = req.params.id || "";
1327
+ const validation = import_joi.default.string().hex().required();
1328
+ const { error } = validation.validate(id);
1329
+ if (error) {
1330
+ next(new import_utils5.BadRequestError(error.message));
1331
+ return;
1332
+ }
1333
+ try {
1334
+ const message = yield _verify(id);
1335
+ res.json({ message });
1336
+ return;
1337
+ } catch (error2) {
1338
+ next(error2);
1339
+ }
1340
+ });
1341
+ }
1342
+ function cancelUserInvitation(req, res, next) {
1343
+ return __async(this, null, function* () {
1344
+ const otpId = req.params.id || "";
1345
+ const validation = import_joi.default.string().hex().required();
1346
+ const { error } = validation.validate(otpId);
1347
+ if (error) {
1348
+ next(new import_utils5.BadRequestError(error.message));
1349
+ return;
1350
+ }
1351
+ try {
1352
+ const otpObjectId = new import_mongodb7.ObjectId(otpId);
1353
+ yield _cancelUserInvitation(otpObjectId);
1354
+ return res.json({
1355
+ message: "User invite has been cancelled."
1356
+ });
1357
+ } catch (error2) {
1358
+ throw error2;
1359
+ }
1360
+ });
1361
+ }
1362
+ return {
1363
+ getVerifications,
1364
+ createUserInvite,
1365
+ createForgetPassword,
1366
+ verify,
1367
+ cancelUserInvitation
1368
+ };
1369
+ }
1370
+
1371
+ // src/models/token.model.ts
1372
+ var import_mongodb8 = require("mongodb");
1373
+ var MToken = class {
1374
+ constructor(value) {
1375
+ var _a, _b, _c;
1376
+ this.token = (_a = value.token) != null ? _a : "";
1377
+ this.user = (_b = value.user) != null ? _b : new import_mongodb8.ObjectId();
1378
+ this.createdAt = (_c = value.createdAt) != null ? _c : (/* @__PURE__ */ new Date()).toISOString();
1379
+ }
1380
+ };
1381
+
1382
+ // src/repositories/token.repository.ts
1383
+ var import_utils6 = require("@goweekdays/utils");
1384
+ var import_mongodb9 = require("mongodb");
1385
+ function useTokenRepo() {
1386
+ const db = import_utils6.useAtlas.getDb();
1387
+ if (!db) {
1388
+ throw new import_utils6.InternalServerError("Unable to connect to server.");
1389
+ }
1390
+ const collection = db.collection("tokens");
1391
+ function createToken() {
1392
+ return __async(this, arguments, function* ({ token, user } = {}) {
1393
+ try {
1394
+ user = new import_mongodb9.ObjectId(user);
1395
+ } catch (error) {
1396
+ return Promise.reject("Invalid user ID");
1397
+ }
1398
+ try {
1399
+ yield collection.insertOne({ token, user });
1400
+ return "Token created";
1401
+ } catch (error) {
1402
+ return Promise.reject(error);
1403
+ }
1404
+ });
1405
+ }
1406
+ function getToken(token) {
1407
+ return __async(this, null, function* () {
1408
+ try {
1409
+ return yield collection.findOne({ token });
1410
+ } catch (error) {
1411
+ return Promise.reject(error);
1412
+ }
1413
+ });
1414
+ }
1415
+ function deleteToken(token) {
1416
+ return __async(this, null, function* () {
1417
+ try {
1418
+ return yield collection.deleteOne({ token });
1419
+ } catch (error) {
1420
+ return Promise.reject(error);
1421
+ }
1422
+ });
1423
+ }
1424
+ return {
1425
+ createToken,
1426
+ getToken,
1427
+ deleteToken
1428
+ };
1429
+ }
1430
+
1431
+ // src/services/user.service.ts
1432
+ var import_utils8 = require("@goweekdays/utils");
1433
+
1434
+ // src/repositories/file.repository.ts
1435
+ var import_utils7 = require("@goweekdays/utils");
1436
+
1437
+ // src/models/file.model.ts
1438
+ var MFile = class {
1439
+ constructor(value) {
1440
+ var _a, _b, _c, _d;
1441
+ this._id = value._id;
1442
+ this.name = (_a = value.name) != null ? _a : "";
1443
+ this.type = (_b = value.type) != null ? _b : "public";
1444
+ this.status = (_c = value.status) != null ? _c : "active";
1445
+ this.createdAt = (_d = value.createdAt) != null ? _d : (/* @__PURE__ */ new Date()).toISOString();
1446
+ }
1447
+ };
1448
+
1449
+ // src/repositories/file.repository.ts
1450
+ var import_mongodb10 = require("mongodb");
1451
+ function useFileRepo() {
1452
+ const db = import_utils7.useAtlas.getDb();
1453
+ if (!db) {
1454
+ throw new import_utils7.InternalServerError("Unable to connect to server.");
1455
+ }
1456
+ const collection = db.collection("files");
1457
+ function createFile(value, session) {
1458
+ return __async(this, null, function* () {
1459
+ try {
1460
+ value = new MFile(value);
1461
+ const res = yield collection.insertOne(value, { session });
1462
+ return res.insertedId.toString();
1463
+ } catch (error) {
1464
+ throw new import_utils7.InternalServerError("Failed to create file.");
1465
+ }
1466
+ });
1467
+ }
1468
+ function deleteFileById(_id, session) {
1469
+ return __async(this, null, function* () {
1470
+ try {
1471
+ _id = new import_mongodb10.ObjectId(_id);
1472
+ } catch (error) {
1473
+ throw new import_utils7.BadRequestError("Invalid file id.");
1474
+ }
1475
+ try {
1476
+ yield collection.deleteOne({ _id }, { session });
1477
+ return "File deleted successfully";
1478
+ } catch (error) {
1479
+ throw new import_utils7.InternalServerError("Failed to delete file.");
1480
+ }
1481
+ });
1482
+ }
1483
+ function getAllDraftedFiles() {
1484
+ return __async(this, null, function* () {
1485
+ try {
1486
+ return yield collection.find({ $and: [{ status: "draft" }, { status: null }] }).toArray();
1487
+ } catch (error) {
1488
+ throw new import_utils7.InternalServerError("Failed to get drafted files.");
1489
+ }
1490
+ });
1491
+ }
1492
+ return {
1493
+ createFile,
1494
+ deleteFileById,
1495
+ getAllDraftedFiles
1496
+ };
1497
+ }
1498
+
1499
+ // src/services/user.service.ts
1500
+ function useUserService() {
1501
+ const {
1502
+ createUser: _createUser,
1503
+ getUserByEmail,
1504
+ getUserById: _getById,
1505
+ updateName: _updateName,
1506
+ updateBirthday: _updateBirthday,
1507
+ updateUserFieldById: _updateUserFieldById,
1508
+ getUsers: _getUsers
1509
+ } = useUserRepo();
1510
+ function getUserById(id) {
1511
+ return __async(this, null, function* () {
1512
+ try {
1513
+ return yield _getById(id);
1514
+ } catch (error) {
1515
+ throw new import_utils8.InternalServerError();
1516
+ }
1517
+ });
1518
+ }
1519
+ function getUsers() {
1520
+ return __async(this, arguments, function* ({
1521
+ search = "",
1522
+ page = 1,
1523
+ status = "",
1524
+ type = "",
1525
+ limit = 10
1526
+ } = {}) {
1527
+ try {
1528
+ return yield _getUsers({ search, page, status, type, limit });
1529
+ } catch (error) {
1530
+ throw error;
1531
+ }
1532
+ });
1533
+ }
1534
+ function createUser(value) {
1535
+ return __async(this, null, function* () {
1536
+ var _a;
1537
+ const session = (_a = import_utils8.useAtlas.getClient()) == null ? void 0 : _a.startSession();
1538
+ session == null ? void 0 : session.startTransaction();
1539
+ try {
1540
+ const _user = yield getUserByEmail(value.email);
1541
+ if (_user) {
1542
+ throw new import_utils8.BadRequestError(`User already exists: ${value.email}.`);
1543
+ }
1544
+ const hashedPassword = yield (0, import_utils8.hashPassword)(value.password);
1545
+ const user = {
1546
+ email: value.email,
1547
+ password: hashedPassword,
1548
+ prefix: value.prefix,
1549
+ firstName: value.firstName,
1550
+ middleName: value.middleName,
1551
+ lastName: value.lastName,
1552
+ suffix: value.suffix,
1553
+ type: value.type,
1554
+ roles: value.roles,
1555
+ status: "active",
1556
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1557
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1558
+ };
1559
+ const userId = yield _createUser(user, session);
1560
+ yield session == null ? void 0 : session.commitTransaction();
1561
+ return userId;
1562
+ } catch (error) {
1563
+ yield session == null ? void 0 : session.abortTransaction();
1564
+ throw error;
1565
+ } finally {
1566
+ session == null ? void 0 : session.endSession();
1567
+ }
1568
+ });
1569
+ }
1570
+ const { getById: _getVerificationById, updateStatusById: _updateStatusById } = useVerificationRepo();
1571
+ function createUserByInvite() {
1572
+ return __async(this, arguments, function* ({
1573
+ id = "",
1574
+ firstName = "",
1575
+ lastName = "",
1576
+ password = ""
1577
+ } = {}) {
1578
+ var _a, _b, _c, _d, _e, _f, _g;
1579
+ const session = (_a = import_utils8.useAtlas.getClient()) == null ? void 0 : _a.startSession();
1580
+ session == null ? void 0 : session.startTransaction();
1581
+ try {
1582
+ const invitation = yield _getVerificationById(id);
1583
+ if (!invitation || !((_b = invitation.metadata) == null ? void 0 : _b.app) || !((_c = invitation.metadata) == null ? void 0 : _c.role)) {
1584
+ throw new import_utils8.BadRequestError("Invalid invitation.");
1585
+ }
1586
+ if (invitation.status === "complete") {
1587
+ throw new import_utils8.BadRequestError("Invitation already used.");
1588
+ }
1589
+ const expired = new Date(invitation.expireAt) < /* @__PURE__ */ new Date();
1590
+ if (invitation.status === "expired" || expired) {
1591
+ throw new import_utils8.BadRequestError("Invitation expired.");
1592
+ }
1593
+ const email = invitation.email;
1594
+ const _user = yield getUserByEmail(invitation.email);
1595
+ if (_user) {
1596
+ throw new import_utils8.BadRequestError(`User already exists: ${email}.`);
1597
+ }
1598
+ const hashedPassword = yield (0, import_utils8.hashPassword)(password);
1599
+ const user = {
1600
+ email,
1601
+ password: hashedPassword,
1602
+ firstName,
1603
+ lastName,
1604
+ type: (_d = invitation.metadata) == null ? void 0 : _d.app,
1605
+ status: "active",
1606
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1607
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
1608
+ roles: [
1609
+ {
1610
+ name: (_e = invitation.metadata) == null ? void 0 : _e.name,
1611
+ app: (_f = invitation.metadata) == null ? void 0 : _f.app,
1612
+ role: (_g = invitation.metadata) == null ? void 0 : _g.role
1613
+ }
1614
+ ]
1615
+ };
1616
+ const userId = yield _createUser(user, session);
1617
+ yield _updateStatusById(id, "complete", session);
1618
+ yield session == null ? void 0 : session.commitTransaction();
1619
+ return userId;
1620
+ } catch (error) {
1621
+ yield session == null ? void 0 : session.abortTransaction();
1622
+ throw error;
1623
+ } finally {
1624
+ session == null ? void 0 : session.endSession();
1625
+ }
1626
+ });
1627
+ }
1628
+ const { verify, getById, updateStatusById } = useVerificationService();
1629
+ function resetPassword(id, newPassword, passwordConfirmation) {
1630
+ return __async(this, null, function* () {
1631
+ try {
1632
+ yield verify(id);
1633
+ } catch (error) {
1634
+ throw error;
1635
+ }
1636
+ if (newPassword !== passwordConfirmation) {
1637
+ throw new import_utils8.BadRequestError("Passwords do not match");
1638
+ }
1639
+ let hashedPassword;
1640
+ try {
1641
+ hashedPassword = yield (0, import_utils8.hashPassword)(newPassword);
1642
+ } catch (error) {
1643
+ throw new import_utils8.InternalServerError(`Error hashing password: ${error}`);
1644
+ }
1645
+ try {
1646
+ const otpDoc = yield getById(id);
1647
+ if (!otpDoc) {
1648
+ throw new import_utils8.NotFoundError("OTP not found");
1649
+ }
1650
+ if (otpDoc.status === "used") {
1651
+ throw new import_utils8.BadRequestError("Invalid OTP, already used.");
1652
+ }
1653
+ yield updateStatusById(id, "used");
1654
+ return "Updated password successfully";
1655
+ } catch (error) {
1656
+ throw error;
1657
+ }
1658
+ });
1659
+ }
1660
+ function updateName(_id, firstName, lastName) {
1661
+ return __async(this, null, function* () {
1662
+ var _a;
1663
+ if (!_id) {
1664
+ throw new import_utils8.BadRequestError("Invalid user ID");
1665
+ }
1666
+ if (!firstName) {
1667
+ throw new import_utils8.BadRequestError("Invalid firstName");
1668
+ }
1669
+ if (!lastName) {
1670
+ throw new import_utils8.BadRequestError("Invalid lastName");
1671
+ }
1672
+ const session = (_a = import_utils8.useAtlas.getClient()) == null ? void 0 : _a.startSession();
1673
+ session == null ? void 0 : session.startTransaction();
1674
+ try {
1675
+ yield _updateName({ _id, firstName, lastName }, session);
1676
+ yield session == null ? void 0 : session.commitTransaction();
1677
+ return "Successfully updated name.";
1678
+ } catch (error) {
1679
+ yield session == null ? void 0 : session.abortTransaction();
1680
+ throw error;
1681
+ } finally {
1682
+ session == null ? void 0 : session.endSession();
1683
+ }
1684
+ });
1685
+ }
1686
+ function updateBirthday(_id, month, day, year) {
1687
+ return __async(this, null, function* () {
1688
+ if (!_id) {
1689
+ throw new import_utils8.BadRequestError("Invalid user ID");
1690
+ }
1691
+ if (!month) {
1692
+ throw new import_utils8.BadRequestError("Invalid birth month.");
1693
+ }
1694
+ if (!day) {
1695
+ throw new import_utils8.BadRequestError("Invalid birthday.");
1696
+ }
1697
+ if (!year) {
1698
+ throw new import_utils8.BadRequestError("Invalid birth year.");
1699
+ }
1700
+ try {
1701
+ yield _updateBirthday({ _id, month, day, year });
1702
+ return "Successfully updated birthday.";
1703
+ } catch (error) {
1704
+ throw error;
1705
+ }
1706
+ });
1707
+ }
1708
+ function updateUserFieldById() {
1709
+ return __async(this, arguments, function* ({ _id, field, value } = {}) {
1710
+ try {
1711
+ return yield _updateUserFieldById({ _id, field, value });
1712
+ } catch (error) {
1713
+ throw error;
1714
+ }
1715
+ });
1716
+ }
1717
+ const { createFile: _createFile, deleteFileById } = useFileRepo();
1718
+ const s3 = new import_utils8.useS3({
1719
+ accessKeyId: SPACES_ACCESS_KEY,
1720
+ secretAccessKey: SPACES_SECRET_KEY,
1721
+ endpoint: SPACES_ENDPOINT,
1722
+ region: SPACES_REGION,
1723
+ bucket: SPACES_BUCKET
1724
+ });
1725
+ function updateUserProfile() {
1726
+ return __async(this, arguments, function* ({ file, user, previousProfile } = {}) {
1727
+ var _a;
1728
+ const session = (_a = import_utils8.useAtlas.getClient()) == null ? void 0 : _a.startSession();
1729
+ session == null ? void 0 : session.startTransaction();
1730
+ const _file = {
1731
+ name: file.originalname,
1732
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
1733
+ };
1734
+ try {
1735
+ const id = yield _createFile(_file, session);
1736
+ yield s3.uploadObject({
1737
+ key: id,
1738
+ body: file.buffer,
1739
+ contentType: file.mimetype
1740
+ });
1741
+ if (previousProfile) {
1742
+ yield deleteFileById(previousProfile, session);
1743
+ yield s3.deleteObject(previousProfile);
1744
+ }
1745
+ yield _updateUserFieldById(
1746
+ { _id: user, field: "profile", value: id },
1747
+ session
1748
+ );
1749
+ yield session == null ? void 0 : session.commitTransaction();
1750
+ return id;
1751
+ } catch (error) {
1752
+ yield session == null ? void 0 : session.abortTransaction();
1753
+ throw error;
1754
+ } finally {
1755
+ session == null ? void 0 : session.endSession();
1756
+ }
1757
+ });
1758
+ }
1759
+ return {
1760
+ getUserById,
1761
+ getUsers,
1762
+ createUser,
1763
+ resetPassword,
1764
+ updateName,
1765
+ updateBirthday,
1766
+ updateUserFieldById,
1767
+ updateUserProfile,
1768
+ createUserByInvite
1769
+ };
1770
+ }
1771
+
1772
+ // src/controllers/user.controller.ts
1773
+ var import_utils9 = require("@goweekdays/utils");
1774
+ var import_joi2 = __toESM(require("joi"));
1775
+ function useUserController() {
1776
+ const {
1777
+ getUserById: _getUserById,
1778
+ updateName: _updateName,
1779
+ updateBirthday: _updateBirthday,
1780
+ updateUserFieldById: _updateUserFieldById,
1781
+ updateUserProfile: _updateUserProfile,
1782
+ getUsers: _getUsers,
1783
+ createUserByInvite: _createUserByInvite
1784
+ } = useUserService();
1785
+ function getUsers(req, res, next) {
1786
+ return __async(this, null, function* () {
1787
+ var _a, _b, _c;
1788
+ const status = (_a = req.query.status) != null ? _a : "";
1789
+ const search = (_b = req.query.search) != null ? _b : "";
1790
+ const page = (_c = Number(req.query.page)) != null ? _c : 1;
1791
+ const validation = import_joi2.default.object({
1792
+ status: import_joi2.default.string().required(),
1793
+ search: import_joi2.default.string().optional().allow("", null),
1794
+ page: import_joi2.default.number().required()
1795
+ });
1796
+ const { error } = validation.validate({ status, search, page });
1797
+ if (error) {
1798
+ next(new import_utils9.BadRequestError(error.message));
1799
+ }
1800
+ try {
1801
+ const items = yield _getUsers({ status, search, page });
1802
+ res.json(items);
1803
+ return;
1804
+ } catch (error2) {
1805
+ next(error2);
1806
+ }
1807
+ });
1808
+ }
1809
+ function getUserById(req, res, next) {
1810
+ return __async(this, null, function* () {
1811
+ const id = req.params.id || "";
1812
+ const validation = import_joi2.default.string().hex().validate(id);
1813
+ if (validation.error) {
1814
+ throw new import_utils9.BadRequestError("Invalid id.");
1815
+ }
1816
+ try {
1817
+ const user = yield _getUserById(id);
1818
+ if (!user) {
1819
+ throw new import_utils9.BadRequestError("User not found.");
1820
+ }
1821
+ res.json(user);
1822
+ } catch (error) {
1823
+ next(error);
1824
+ }
1825
+ });
1826
+ }
1827
+ function updateName(req, res, next) {
1828
+ return __async(this, null, function* () {
1829
+ var _a, _b, _c;
1830
+ const id = (_a = req.headers.user) != null ? _a : "";
1831
+ const firstName = (_b = req.body.firstName) != null ? _b : "";
1832
+ const lastName = (_c = req.body.lastName) != null ? _c : "";
1833
+ const validation = import_joi2.default.object({
1834
+ firstName: import_joi2.default.string().required(),
1835
+ lastName: import_joi2.default.string().required()
1836
+ });
1837
+ const { error } = validation.validate({ firstName, lastName });
1838
+ if (error) {
1839
+ next(new import_utils9.BadRequestError(error.message));
1840
+ return;
1841
+ }
1842
+ try {
1843
+ const message = yield _updateName(id, firstName, lastName);
1844
+ res.json({ message });
1845
+ return;
1846
+ } catch (error2) {
1847
+ next(error2);
1848
+ }
1849
+ });
1850
+ }
1851
+ function updateBirthday(req, res, next) {
1852
+ return __async(this, null, function* () {
1853
+ var _a, _b, _c, _d;
1854
+ const id = (_a = req.headers.user) != null ? _a : "";
1855
+ const month = (_b = req.body.month) != null ? _b : "";
1856
+ const day = (_c = req.body.day) != null ? _c : 0;
1857
+ const year = (_d = req.body.year) != null ? _d : 0;
1858
+ const validation = import_joi2.default.object({
1859
+ month: import_joi2.default.string().required(),
1860
+ day: import_joi2.default.number().integer().min(1).max(31).required(),
1861
+ year: import_joi2.default.number().integer().min(1900).max((/* @__PURE__ */ new Date()).getFullYear()).required()
1862
+ });
1863
+ const { error } = validation.validate({ month, day, year });
1864
+ if (error) {
1865
+ next(new import_utils9.BadRequestError(error.message));
1866
+ return;
1867
+ }
1868
+ try {
1869
+ const message = yield _updateBirthday(id, month, day, year);
1870
+ res.json({ message });
1871
+ return;
1872
+ } catch (error2) {
1873
+ next(error2);
1874
+ }
1875
+ });
1876
+ }
1877
+ function updateUserFieldById(req, res, next) {
1878
+ return __async(this, null, function* () {
1879
+ const _id = req.params.id;
1880
+ const { field, value } = req.body;
1881
+ const validation = import_joi2.default.object({
1882
+ _id: import_joi2.default.string().hex().required(),
1883
+ field: import_joi2.default.string().valid("gender", "email", "contact", "profile").required(),
1884
+ value: import_joi2.default.alternatives().conditional("field", {
1885
+ is: "email",
1886
+ then: import_joi2.default.string().email().required(),
1887
+ otherwise: import_joi2.default.string().required()
1888
+ })
1889
+ });
1890
+ const { error } = validation.validate({ _id, field, value });
1891
+ if (error) {
1892
+ next(new import_utils9.BadRequestError(error.message));
1893
+ return;
1894
+ }
1895
+ try {
1896
+ const message = yield _updateUserFieldById({ _id, field, value });
1897
+ res.json({ message });
1898
+ } catch (error2) {
1899
+ next(error2);
1900
+ }
1901
+ });
1902
+ }
1903
+ function updateUserProfile(req, res, next) {
1904
+ return __async(this, null, function* () {
1905
+ var _a, _b;
1906
+ if (!req.file) {
1907
+ res.status(400).send("File is required!");
1908
+ return;
1909
+ }
1910
+ const previousProfile = (_a = req.body.previousProfile) != null ? _a : "";
1911
+ const validation = import_joi2.default.object({
1912
+ previousProfile: import_joi2.default.string().hex().optional().allow("", null)
1913
+ });
1914
+ const { error } = validation.validate({ previousProfile });
1915
+ if (error) {
1916
+ next(new import_utils9.BadRequestError(error.message));
1917
+ return;
1918
+ }
1919
+ const user = (_b = req.headers["user"]) != null ? _b : "";
1920
+ try {
1921
+ yield _updateUserProfile({
1922
+ file: req.file,
1923
+ user,
1924
+ previousProfile
1925
+ });
1926
+ res.json({ message: "Successfully updated profile picture." });
1927
+ return;
1928
+ } catch (error2) {
1929
+ if (error2 instanceof import_utils9.AppError) {
1930
+ next(error2);
1931
+ } else {
1932
+ next(new import_utils9.InternalServerError(error2));
1933
+ }
1934
+ }
1935
+ });
1936
+ }
1937
+ function createUserByInvite(req, res, next) {
1938
+ return __async(this, null, function* () {
1939
+ var _a, _b, _c, _d;
1940
+ const firstName = (_a = req.body.firstName) != null ? _a : "";
1941
+ const lastName = (_b = req.body.lastName) != null ? _b : "";
1942
+ const password = (_c = req.body.password) != null ? _c : "";
1943
+ const id = (_d = req.params.id) != null ? _d : "";
1944
+ const validation = import_joi2.default.object({
1945
+ firstName: import_joi2.default.string().required(),
1946
+ lastName: import_joi2.default.string().required(),
1947
+ password: import_joi2.default.string().required(),
1948
+ id: import_joi2.default.string().hex().required()
1949
+ });
1950
+ const { error } = validation.validate({
1951
+ firstName,
1952
+ lastName,
1953
+ password,
1954
+ id
1955
+ });
1956
+ if (error) {
1957
+ next(new import_utils9.BadRequestError(error.message));
1958
+ return;
1959
+ }
1960
+ try {
1961
+ yield _createUserByInvite({ firstName, lastName, password, id });
1962
+ res.json({ message: "Successfully created account." });
1963
+ return;
1964
+ } catch (error2) {
1965
+ next(error2);
1966
+ }
1967
+ });
1968
+ }
1969
+ return {
1970
+ getUsers,
1971
+ getUserById,
1972
+ updateName,
1973
+ updateBirthday,
1974
+ updateUserFieldById,
1975
+ updateUserProfile,
1976
+ createUserByInvite
1977
+ };
1978
+ }
1979
+
1980
+ // src/services/auth.service.ts
1981
+ var import_utils10 = require("@goweekdays/utils");
1982
+ var import_jsonwebtoken3 = __toESM(require("jsonwebtoken"));
1983
+ function useAuthService() {
1984
+ const expiresIn = "1m";
1985
+ function login() {
1986
+ return __async(this, arguments, function* ({ email, password } = {}) {
1987
+ var _a;
1988
+ if (!email) {
1989
+ throw new import_utils10.BadRequestError("Email is required");
1990
+ }
1991
+ if (!password) {
1992
+ throw new import_utils10.BadRequestError("Password is required");
1993
+ }
1994
+ let _user;
1995
+ try {
1996
+ _user = yield useUserRepo().getUserByEmail(email);
1997
+ } catch (error) {
1998
+ if (error instanceof import_utils10.AppError) {
1999
+ throw error;
2000
+ } else {
2001
+ throw new import_utils10.InternalServerError(`${error}`);
2002
+ }
2003
+ }
2004
+ if (!_user) {
2005
+ throw new import_utils10.NotFoundError(
2006
+ "Invalid user email. Please check your email and try again."
2007
+ );
2008
+ }
2009
+ if (_user.status === "suspended") {
2010
+ throw new import_utils10.BadRequestError(
2011
+ "Your account is currently suspended. Please contact support for assistance."
2012
+ );
2013
+ }
2014
+ const isPasswordValid = yield (0, import_utils10.comparePassword)(password, _user.password);
2015
+ if (!isPasswordValid) {
2016
+ throw new import_utils10.BadRequestError("Invalid password");
2017
+ }
2018
+ const metadata = { user: _user._id };
2019
+ let refreshToken2;
2020
+ try {
2021
+ refreshToken2 = (0, import_utils10.generateToken)({
2022
+ secret: REFRESH_TOKEN_SECRET,
2023
+ metadata,
2024
+ options: { expiresIn: "7d" }
2025
+ });
2026
+ } catch (error) {
2027
+ throw new import_utils10.BadRequestError("Error generating refresh token");
2028
+ }
2029
+ let accessToken;
2030
+ try {
2031
+ accessToken = (0, import_utils10.generateToken)({
2032
+ secret: ACCESS_TOKEN_SECRET,
2033
+ metadata,
2034
+ options: { expiresIn }
2035
+ });
2036
+ } catch (error) {
2037
+ throw new import_utils10.BadRequestError("Error generating access token");
2038
+ }
2039
+ const user = (_a = _user._id) != null ? _a : "";
2040
+ try {
2041
+ yield useTokenRepo().createToken({ token: refreshToken2, user });
2042
+ } catch (error) {
2043
+ throw new import_utils10.BadRequestError("Error creating refresh token");
2044
+ }
2045
+ return { accessToken, refreshToken: refreshToken2, id: _user._id };
2046
+ });
2047
+ }
2048
+ function refreshToken(token) {
2049
+ return __async(this, null, function* () {
2050
+ let decoded;
2051
+ try {
2052
+ decoded = yield import_jsonwebtoken3.default.verify(token, REFRESH_TOKEN_SECRET);
2053
+ } catch (error) {
2054
+ throw new import_utils10.BadRequestError("Invalid refresh token");
2055
+ }
2056
+ let _token;
2057
+ try {
2058
+ _token = yield useTokenRepo().getToken(token);
2059
+ if (!_token) {
2060
+ throw new import_utils10.NotFoundError("Invalid token");
2061
+ }
2062
+ } catch (error) {
2063
+ if (error instanceof import_utils10.AppError) {
2064
+ throw error;
2065
+ } else {
2066
+ throw new import_utils10.InternalServerError(`${error}`);
2067
+ }
2068
+ }
2069
+ let accessToken;
2070
+ try {
2071
+ accessToken = (0, import_utils10.generateToken)({
2072
+ secret: ACCESS_TOKEN_SECRET,
2073
+ metadata: { user: decoded.user },
2074
+ options: { expiresIn }
2075
+ });
2076
+ } catch (error) {
2077
+ throw new import_utils10.BadRequestError("Error generating access token");
2078
+ }
2079
+ return accessToken;
2080
+ });
2081
+ }
2082
+ function logout(token) {
2083
+ return __async(this, null, function* () {
2084
+ let _token;
2085
+ try {
2086
+ _token = yield useTokenRepo().getToken(token);
2087
+ if (!_token) {
2088
+ throw new import_utils10.NotFoundError("Invalid token");
2089
+ }
2090
+ } catch (error) {
2091
+ if (error instanceof import_utils10.AppError) {
2092
+ throw error;
2093
+ } else {
2094
+ throw new import_utils10.InternalServerError(`${error}`);
2095
+ }
2096
+ }
2097
+ try {
2098
+ yield useTokenRepo().deleteToken(token);
2099
+ } catch (error) {
2100
+ throw new import_utils10.InternalServerError("Error deleting token");
2101
+ }
2102
+ return "Logged out successfully";
2103
+ });
2104
+ }
2105
+ return {
2106
+ login,
2107
+ refreshToken,
2108
+ logout
2109
+ };
2110
+ }
2111
+
2112
+ // src/controllers/auth.controller.ts
2113
+ var import_joi3 = __toESM(require("joi"));
2114
+ var import_utils11 = require("@goweekdays/utils");
2115
+ function useAuthController() {
2116
+ function login(req, res, next) {
2117
+ return __async(this, null, function* () {
2118
+ const email = req.body.email;
2119
+ const password = req.body.password;
2120
+ const validation = import_joi3.default.object({
2121
+ email: import_joi3.default.string().email().required(),
2122
+ password: import_joi3.default.string().required()
2123
+ });
2124
+ const { error } = validation.validate({ email, password });
2125
+ if (error) {
2126
+ next(new import_utils11.BadRequestError(error.message));
2127
+ }
2128
+ try {
2129
+ const token = yield useAuthService().login({ email, password });
2130
+ res.json(token);
2131
+ } catch (error2) {
2132
+ if (error2 instanceof import_utils11.AppError) {
2133
+ next(error2);
2134
+ } else {
2135
+ next(new import_utils11.InternalServerError("An unexpected error occurred"));
2136
+ }
2137
+ }
2138
+ });
2139
+ }
2140
+ function refreshToken(req, res, next) {
2141
+ return __async(this, null, function* () {
2142
+ const refreshToken2 = req.body.token;
2143
+ if (!refreshToken2) {
2144
+ next(new import_utils11.BadRequestError("Refresh token is required"));
2145
+ return;
2146
+ }
2147
+ try {
2148
+ const newRefreshToken = yield useAuthService().refreshToken(refreshToken2);
2149
+ res.json({ token: newRefreshToken });
2150
+ } catch (error) {
2151
+ if (error instanceof import_utils11.AppError) {
2152
+ next(error);
2153
+ } else {
2154
+ next(new import_utils11.InternalServerError("An unexpected error occurred"));
2155
+ }
2156
+ }
2157
+ });
2158
+ }
2159
+ function logout(req, res, next) {
2160
+ return __async(this, null, function* () {
2161
+ const token = req.params.id || "";
2162
+ if (!token) {
2163
+ next(new import_utils11.BadRequestError("Token is required"));
2164
+ return;
2165
+ }
2166
+ try {
2167
+ yield useAuthService().logout(token);
2168
+ res.json({ message: "Logged out successfully" });
2169
+ } catch (error) {
2170
+ if (error instanceof import_utils11.AppError) {
2171
+ next(error);
2172
+ } else {
2173
+ next(new import_utils11.InternalServerError("An unexpected error occurred"));
2174
+ }
2175
+ }
2176
+ });
2177
+ }
2178
+ function resetPassword(req, res, next) {
2179
+ return __async(this, null, function* () {
2180
+ const otp = req.body.otp || "";
2181
+ const newPassword = req.body.newPassword || "";
2182
+ const passwordConfirmation = req.body.passwordConfirmation || "";
2183
+ const validation = import_joi3.default.object({
2184
+ otp: import_joi3.default.string().hex().required(),
2185
+ newPassword: import_joi3.default.string().required().min(8),
2186
+ passwordConfirmation: import_joi3.default.string().required().min(8)
2187
+ });
2188
+ const { error } = validation.validate({
2189
+ otp,
2190
+ newPassword,
2191
+ passwordConfirmation
2192
+ });
2193
+ if (error) {
2194
+ next(new import_utils11.BadRequestError(error.message));
2195
+ return;
2196
+ }
2197
+ try {
2198
+ const message = yield useUserService().resetPassword(
2199
+ otp,
2200
+ newPassword,
2201
+ passwordConfirmation
2202
+ );
2203
+ res.json({ message });
2204
+ return;
2205
+ } catch (error2) {
2206
+ next(error2);
2207
+ }
2208
+ });
2209
+ }
2210
+ return {
2211
+ login,
2212
+ refreshToken,
2213
+ logout,
2214
+ resetPassword
2215
+ };
2216
+ }
2217
+
2218
+ // src/models/role.model.ts
2219
+ var import_mongodb11 = require("mongodb");
2220
+ var MRole = class {
2221
+ constructor(value) {
2222
+ var _a, _b, _c, _d, _e, _f, _g, _h;
2223
+ if (typeof value._id === "string") {
2224
+ try {
2225
+ value._id = new import_mongodb11.ObjectId(value._id);
2226
+ } catch (error) {
2227
+ throw new Error("Invalid _id.");
2228
+ }
2229
+ }
2230
+ this._id = (_a = value._id) != null ? _a : new import_mongodb11.ObjectId();
2231
+ this.name = (_b = value.name) != null ? _b : "";
2232
+ this.permissions = (_c = value.permissions) != null ? _c : [];
2233
+ this.type = value.type ? value.type : "account";
2234
+ this.status = (_d = value.status) != null ? _d : "active";
2235
+ if (value.createdBy) {
2236
+ try {
2237
+ value.createdBy = new import_mongodb11.ObjectId(value.createdBy);
2238
+ } catch (error) {
2239
+ throw new Error("Invalid createdBy.");
2240
+ }
2241
+ }
2242
+ this.createdBy = (_e = value.createdBy) != null ? _e : "";
2243
+ this.createdAt = (_f = value.createdAt) != null ? _f : (/* @__PURE__ */ new Date()).toISOString();
2244
+ this.updatedAt = (_g = value.updatedAt) != null ? _g : "";
2245
+ this.deletedAt = (_h = value.deletedAt) != null ? _h : "";
2246
+ }
2247
+ };
2248
+
2249
+ // src/repositories/role.repository.ts
2250
+ var import_utils12 = require("@goweekdays/utils");
2251
+ var import_mongodb12 = require("mongodb");
2252
+ function useRoleRepo() {
2253
+ const db = import_utils12.useAtlas.getDb();
2254
+ if (!db) {
2255
+ throw new import_utils12.InternalServerError("Unable to connect to server.");
2256
+ }
2257
+ const collection = db.collection("roles");
2258
+ function createIndex() {
2259
+ return __async(this, null, function* () {
2260
+ try {
2261
+ yield collection.createIndex({ name: 1 });
2262
+ yield collection.createIndex({ type: 1 });
2263
+ yield collection.createIndex({ status: 1 });
2264
+ } catch (error) {
2265
+ throw new import_utils12.InternalServerError("Failed to create index on role.");
2266
+ }
2267
+ });
2268
+ }
2269
+ function createTextIndex() {
2270
+ return __async(this, null, function* () {
2271
+ try {
2272
+ yield collection.createIndex({ name: "text" });
2273
+ } catch (error) {
2274
+ throw new import_utils12.InternalServerError("Failed to create text index on role.");
2275
+ }
2276
+ });
2277
+ }
2278
+ function createUniqueIndex() {
2279
+ return __async(this, null, function* () {
2280
+ try {
2281
+ yield collection.createIndex({ name: 1, type: 1 }, { unique: true });
2282
+ } catch (error) {
2283
+ throw new import_utils12.InternalServerError("Failed to create unique index on role.");
2284
+ }
2285
+ });
2286
+ }
2287
+ function addRole(value, session) {
2288
+ return __async(this, null, function* () {
2289
+ value = new MRole(value);
2290
+ try {
2291
+ const res = yield collection.insertOne(value, { session });
2292
+ return res.insertedId;
2293
+ } catch (error) {
2294
+ import_utils12.logger.log({ level: "error", message: `${error}` });
2295
+ const isDuplicated = error.message.includes("duplicate");
2296
+ if (isDuplicated) {
2297
+ throw new import_utils12.BadRequestError("Item role already exists");
2298
+ }
2299
+ throw new import_utils12.InternalServerError("Failed to create role.");
2300
+ }
2301
+ });
2302
+ }
2303
+ function getRoleByUserId(value) {
2304
+ return __async(this, null, function* () {
2305
+ try {
2306
+ value = new import_mongodb12.ObjectId(value);
2307
+ } catch (error) {
2308
+ throw new import_utils12.BadRequestError("Invalid user ID.");
2309
+ }
2310
+ try {
2311
+ return yield collection.findOne({ user: value });
2312
+ } catch (error) {
2313
+ throw new import_utils12.InternalServerError("Failed to retrieve role by user ID.");
2314
+ }
2315
+ });
2316
+ }
2317
+ function getRoleById(_id) {
2318
+ return __async(this, null, function* () {
2319
+ try {
2320
+ _id = new import_mongodb12.ObjectId(_id);
2321
+ } catch (error) {
2322
+ throw new import_utils12.BadRequestError("Invalid ID.");
2323
+ }
2324
+ try {
2325
+ return yield collection.findOne({ _id });
2326
+ } catch (error) {
2327
+ throw new import_utils12.InternalServerError("Failed to retrieve role by ID.");
2328
+ }
2329
+ });
2330
+ }
2331
+ function getRoleByName(name) {
2332
+ return __async(this, null, function* () {
2333
+ if (!name) {
2334
+ throw new import_utils12.BadRequestError("Role name is required.");
2335
+ }
2336
+ try {
2337
+ return yield collection.findOne({ name });
2338
+ } catch (error) {
2339
+ throw new import_utils12.InternalServerError("Failed to retrieve role by name.");
2340
+ }
2341
+ });
2342
+ }
2343
+ function getRoles() {
2344
+ return __async(this, arguments, function* ({
2345
+ search = "",
2346
+ page = 1,
2347
+ limit = 10,
2348
+ sort = {},
2349
+ type = ""
2350
+ } = {}) {
2351
+ page = page > 0 ? page - 1 : 0;
2352
+ const query = { status: "active" };
2353
+ sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
2354
+ if (search) {
2355
+ query.$text = { $search: search };
2356
+ }
2357
+ if (type) {
2358
+ query.type = type;
2359
+ }
2360
+ try {
2361
+ const items = yield collection.aggregate([
2362
+ { $match: query },
2363
+ { $sort: sort },
2364
+ { $skip: page * limit },
2365
+ { $limit: limit }
2366
+ ]).toArray();
2367
+ const length = yield collection.countDocuments(query);
2368
+ return (0, import_utils12.paginate)(items, page, limit, length);
2369
+ } catch (error) {
2370
+ import_utils12.logger.log({ level: "error", message: `${error}` });
2371
+ throw error;
2372
+ }
2373
+ });
2374
+ }
2375
+ function updateRole(_id, value, session) {
2376
+ return __async(this, null, function* () {
2377
+ if (!_id) {
2378
+ throw new import_utils12.BadRequestError("Role ID is required.");
2379
+ }
2380
+ try {
2381
+ _id = new import_mongodb12.ObjectId(_id);
2382
+ } catch (error) {
2383
+ throw new import_utils12.BadRequestError("Invalid role ID.");
2384
+ }
2385
+ if (!value.name) {
2386
+ delete value.name;
2387
+ }
2388
+ if (!value.permissions) {
2389
+ delete value.permissions;
2390
+ }
2391
+ if (value.name || value.permissions) {
2392
+ try {
2393
+ yield collection.updateOne({ _id }, { $set: value }, { session });
2394
+ return "Successfully updated role.";
2395
+ } catch (error) {
2396
+ throw new import_utils12.InternalServerError("Failed to update role.");
2397
+ }
2398
+ } else {
2399
+ throw new import_utils12.BadRequestError("No fields to update.");
2400
+ }
2401
+ });
2402
+ }
2403
+ function deleteRole(_id, session) {
2404
+ return __async(this, null, function* () {
2405
+ try {
2406
+ _id = new import_mongodb12.ObjectId(_id);
2407
+ } catch (error) {
2408
+ throw new import_utils12.BadRequestError("Invalid ID.");
2409
+ }
2410
+ try {
2411
+ yield collection.deleteOne(
2412
+ { _id },
2413
+ {
2414
+ session
2415
+ }
2416
+ );
2417
+ return "Successfully deleted role.";
2418
+ } catch (error) {
2419
+ throw new import_utils12.InternalServerError("Failed to delete role.");
2420
+ }
2421
+ });
2422
+ }
2423
+ return {
2424
+ createIndex,
2425
+ createTextIndex,
2426
+ createUniqueIndex,
2427
+ addRole,
2428
+ getRoles,
2429
+ getRoleByUserId,
2430
+ getRoleById,
2431
+ getRoleByName,
2432
+ updateRole,
2433
+ deleteRole
2434
+ };
2435
+ }
2436
+
2437
+ // src/services/file.service.ts
2438
+ var import_utils13 = require("@goweekdays/utils");
2439
+ var import_node_cron = __toESM(require("node-cron"));
2440
+ function useFileService() {
2441
+ const {
2442
+ createFile: _createFile,
2443
+ deleteFileById,
2444
+ getAllDraftedFiles
2445
+ } = useFileRepo();
2446
+ const s3 = new import_utils13.useS3({
2447
+ accessKeyId: SPACES_ACCESS_KEY,
2448
+ secretAccessKey: SPACES_SECRET_KEY,
2449
+ endpoint: SPACES_ENDPOINT,
2450
+ region: SPACES_REGION,
2451
+ bucket: SPACES_BUCKET
2452
+ });
2453
+ function createFile(value) {
2454
+ return __async(this, null, function* () {
2455
+ var _a;
2456
+ const session = (_a = import_utils13.useAtlas.getClient()) == null ? void 0 : _a.startSession();
2457
+ session == null ? void 0 : session.startTransaction();
2458
+ const file = {
2459
+ name: value.originalname,
2460
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
2461
+ };
2462
+ try {
2463
+ const id = yield _createFile(file, session);
2464
+ yield s3.uploadObject({
2465
+ key: id,
2466
+ body: value.buffer,
2467
+ contentType: value.mimetype
2468
+ });
2469
+ yield session == null ? void 0 : session.commitTransaction();
2470
+ return id;
2471
+ } catch (error) {
2472
+ yield session == null ? void 0 : session.abortTransaction();
2473
+ throw error;
2474
+ } finally {
2475
+ session == null ? void 0 : session.endSession();
2476
+ }
2477
+ });
2478
+ }
2479
+ function deleteFile(id) {
2480
+ return __async(this, null, function* () {
2481
+ var _a;
2482
+ const session = (_a = import_utils13.useAtlas.getClient()) == null ? void 0 : _a.startSession();
2483
+ session == null ? void 0 : session.startTransaction();
2484
+ try {
2485
+ yield deleteFileById(id, session);
2486
+ yield s3.deleteObject(id);
2487
+ yield session == null ? void 0 : session.commitTransaction();
2488
+ return "File deleted successfully";
2489
+ } catch (error) {
2490
+ yield session == null ? void 0 : session.abortTransaction();
2491
+ throw error;
2492
+ } finally {
2493
+ session == null ? void 0 : session.endSession();
2494
+ }
2495
+ });
2496
+ }
2497
+ function deleteDraft() {
2498
+ import_node_cron.default.schedule("0 0 * * *", () => __async(this, null, function* () {
2499
+ const files = yield getAllDraftedFiles();
2500
+ for (let index = 0; index < files.length; index++) {
2501
+ const file = files[index];
2502
+ try {
2503
+ yield deleteFile(file._id.toString());
2504
+ yield import_utils13.logger.log({
2505
+ level: "info",
2506
+ message: "Successfully deleted draft files."
2507
+ });
2508
+ } catch (error) {
2509
+ import_utils13.logger.log({
2510
+ level: "info",
2511
+ message: "Successfully deleted draft files."
2512
+ });
2513
+ return;
2514
+ }
2515
+ }
2516
+ }));
2517
+ }
2518
+ return {
2519
+ createFile,
2520
+ deleteFile,
2521
+ deleteDraft
2522
+ };
2523
+ }
2524
+
2525
+ // src/controllers/file.controller.ts
2526
+ var import_utils14 = require("@goweekdays/utils");
2527
+ var import_joi4 = __toESM(require("joi"));
2528
+ function useFileController() {
2529
+ const { createFile, deleteFile: _deleteFile } = useFileService();
2530
+ function upload(req, res, next) {
2531
+ return __async(this, null, function* () {
2532
+ if (!req.file) {
2533
+ res.status(400).send("File is required!");
2534
+ return;
2535
+ }
2536
+ try {
2537
+ const id = yield createFile(req.file);
2538
+ res.json({ message: "Successfully uploaded file", id });
2539
+ return;
2540
+ } catch (error) {
2541
+ if (error instanceof import_utils14.AppError) {
2542
+ next(error);
2543
+ } else {
2544
+ next(new import_utils14.InternalServerError(error));
2545
+ }
2546
+ }
2547
+ });
2548
+ }
2549
+ function deleteFile(req, res, next) {
2550
+ return __async(this, null, function* () {
2551
+ const id = req.params.id;
2552
+ const validation = import_joi4.default.string().required();
2553
+ const { error } = validation.validate(id);
2554
+ if (error) {
2555
+ next(new import_utils14.BadRequestError(error.message));
2556
+ }
2557
+ try {
2558
+ const message = yield _deleteFile(id);
2559
+ res.json({ message });
2560
+ return;
2561
+ } catch (error2) {
2562
+ if (error2 instanceof import_utils14.AppError) {
2563
+ next(error2);
2564
+ } else {
2565
+ next(new import_utils14.InternalServerError(error2));
2566
+ }
2567
+ }
2568
+ });
2569
+ }
2570
+ return {
2571
+ upload,
2572
+ deleteFile
2573
+ };
2574
+ }
2575
+
2576
+ // src/services/role.service.ts
2577
+ function useRoleService() {
2578
+ const {
2579
+ addRole,
2580
+ getRoles: _getRoles,
2581
+ getRoleByUserId: _getRoleByUserId,
2582
+ getRoleById: _getRoleById,
2583
+ getRoleByName: _getRoleByName,
2584
+ updateRole: _updateRole,
2585
+ deleteRole: _deleteRole
2586
+ } = useRoleRepo();
2587
+ function createRole(value) {
2588
+ return __async(this, null, function* () {
2589
+ try {
2590
+ return yield addRole(value);
2591
+ } catch (error) {
2592
+ throw error;
2593
+ }
2594
+ });
2595
+ }
2596
+ function getRoles() {
2597
+ return __async(this, arguments, function* ({
2598
+ search = "",
2599
+ page = 1,
2600
+ limit = 10,
2601
+ type = ""
2602
+ } = {}) {
2603
+ try {
2604
+ return yield _getRoles({ search, page, limit, type });
2605
+ } catch (error) {
2606
+ throw error;
2607
+ }
2608
+ });
2609
+ }
2610
+ function getRoleByUserId(value) {
2611
+ return __async(this, null, function* () {
2612
+ try {
2613
+ return yield _getRoleByUserId(value);
2614
+ } catch (error) {
2615
+ throw error;
2616
+ }
2617
+ });
2618
+ }
2619
+ function getRoleById(_id) {
2620
+ return __async(this, null, function* () {
2621
+ try {
2622
+ return yield _getRoleById(_id);
2623
+ } catch (error) {
2624
+ throw error;
2625
+ }
2626
+ });
2627
+ }
2628
+ function getRoleByName(name) {
2629
+ return __async(this, null, function* () {
2630
+ try {
2631
+ return yield _getRoleByName(name);
2632
+ } catch (error) {
2633
+ throw error;
2634
+ }
2635
+ });
2636
+ }
2637
+ function updateRole(_id, value) {
2638
+ return __async(this, null, function* () {
2639
+ try {
2640
+ return yield _updateRole(_id, value);
2641
+ } catch (error) {
2642
+ throw error;
2643
+ }
2644
+ });
2645
+ }
2646
+ function deleteRole(_id) {
2647
+ return __async(this, null, function* () {
2648
+ try {
2649
+ return yield _deleteRole(_id);
2650
+ } catch (error) {
2651
+ throw error;
2652
+ }
2653
+ });
2654
+ }
2655
+ return {
2656
+ createRole,
2657
+ getRoles,
2658
+ getRoleByUserId,
2659
+ getRoleById,
2660
+ getRoleByName,
2661
+ updateRole,
2662
+ deleteRole
2663
+ };
2664
+ }
2665
+
2666
+ // src/controllers/role.controller.ts
2667
+ var import_joi5 = __toESM(require("joi"));
2668
+ var import_utils15 = require("@goweekdays/utils");
2669
+ function useRoleController() {
2670
+ const {
2671
+ createRole: _createRole,
2672
+ getRoleById: _getRoleById,
2673
+ getRoleByUserId: _getRoleByUserId,
2674
+ getRoles: _getRoles,
2675
+ updateRole: _updateRole,
2676
+ deleteRole: _deleteRole
2677
+ } = useRoleService();
2678
+ function createRole(req, res, next) {
2679
+ return __async(this, null, function* () {
2680
+ var _a, _b, _c;
2681
+ const name = (_a = req.body.name) != null ? _a : "";
2682
+ const permissions = (_b = req.body.permissions) != null ? _b : [];
2683
+ const type = (_c = req.body.type) != null ? _c : "";
2684
+ const validation = import_joi5.default.object({
2685
+ name: import_joi5.default.string().required(),
2686
+ permissions: import_joi5.default.array().items(import_joi5.default.string()).required(),
2687
+ type: import_joi5.default.string().optional().allow("", null)
2688
+ });
2689
+ const { error } = validation.validate({ name, permissions, type });
2690
+ if (error) {
2691
+ next(new import_utils15.BadRequestError(error.message));
2692
+ return;
2693
+ }
2694
+ try {
2695
+ const role = yield _createRole({ name, permissions, type });
2696
+ res.json({ message: "Successfully created role.", data: { role } });
2697
+ return;
2698
+ } catch (error2) {
2699
+ next(error2);
2700
+ }
2701
+ });
2702
+ }
2703
+ function getRoles(req, res, next) {
2704
+ return __async(this, null, function* () {
2705
+ var _a, _b, _c, _d;
2706
+ const search = (_a = req.query.search) != null ? _a : "";
2707
+ const page = parseInt((_b = req.query.page) != null ? _b : "1");
2708
+ const limit = parseInt((_c = req.query.limit) != null ? _c : "10");
2709
+ const type = (_d = req.query.type) != null ? _d : "";
2710
+ const validation = import_joi5.default.object({
2711
+ search: import_joi5.default.string().optional().allow("", null),
2712
+ page: import_joi5.default.number().required(),
2713
+ limit: import_joi5.default.number().required(),
2714
+ type: import_joi5.default.string().optional().allow("", null)
2715
+ });
2716
+ const { error } = validation.validate({ search, page, limit, type });
2717
+ if (error) {
2718
+ next(new import_utils15.BadRequestError(error.message));
2719
+ return;
2720
+ }
2721
+ try {
2722
+ const data = yield _getRoles({ search, page, limit, type });
2723
+ res.json(data);
2724
+ return;
2725
+ } catch (error2) {
2726
+ console.log(error2);
2727
+ next(error2);
2728
+ }
2729
+ });
2730
+ }
2731
+ function getRoleByUserId(req, res, next) {
2732
+ return __async(this, null, function* () {
2733
+ const userId = req.params.userId;
2734
+ const validation = import_joi5.default.object({
2735
+ userId: import_joi5.default.string().required()
2736
+ });
2737
+ const { error } = validation.validate({ userId });
2738
+ if (error) {
2739
+ next(new import_utils15.BadRequestError(error.message));
2740
+ return;
2741
+ }
2742
+ try {
2743
+ const role = yield _getRoleByUserId(userId);
2744
+ res.json({ message: "Successfully retrieved role.", data: { role } });
2745
+ return;
2746
+ } catch (error2) {
2747
+ next(error2);
2748
+ }
2749
+ });
2750
+ }
2751
+ function getRoleById(req, res, next) {
2752
+ return __async(this, null, function* () {
2753
+ const _id = req.params.id;
2754
+ const validation = import_joi5.default.object({
2755
+ _id: import_joi5.default.string().hex().required()
2756
+ });
2757
+ const { error } = validation.validate({ _id });
2758
+ if (error) {
2759
+ next(new import_utils15.BadRequestError(error.message));
2760
+ return;
2761
+ }
2762
+ try {
2763
+ const data = yield _getRoleById(_id);
2764
+ res.json(data);
2765
+ return;
2766
+ } catch (error2) {
2767
+ next(error2);
2768
+ }
2769
+ });
2770
+ }
2771
+ function updateRole(req, res, next) {
2772
+ return __async(this, null, function* () {
2773
+ var _a, _b;
2774
+ const _id = req.params.id;
2775
+ const name = (_a = req.body.name) != null ? _a : "";
2776
+ const permissions = (_b = req.body.permissions) != null ? _b : [];
2777
+ const validation = import_joi5.default.object({
2778
+ _id: import_joi5.default.string().required(),
2779
+ name: import_joi5.default.string().required(),
2780
+ permissions: import_joi5.default.array().items(import_joi5.default.string()).required()
2781
+ });
2782
+ const { error } = validation.validate({ _id, name, permissions });
2783
+ if (error) {
2784
+ next(new import_utils15.BadRequestError(error.message));
2785
+ return;
2786
+ }
2787
+ try {
2788
+ const role = yield _updateRole(_id, { name, permissions });
2789
+ res.json({ message: "Successfully updated role.", data: { role } });
2790
+ return;
2791
+ } catch (error2) {
2792
+ next(error2);
2793
+ }
2794
+ });
2795
+ }
2796
+ function deleteRole(req, res, next) {
2797
+ return __async(this, null, function* () {
2798
+ const _id = req.params.id;
2799
+ const validation = import_joi5.default.object({
2800
+ _id: import_joi5.default.string().required()
2801
+ });
2802
+ const { error } = validation.validate({ _id });
2803
+ if (error) {
2804
+ next(new import_utils15.BadRequestError(error.message));
2805
+ return;
2806
+ }
2807
+ try {
2808
+ const message = yield _deleteRole(_id);
2809
+ res.json({ message });
2810
+ return;
2811
+ } catch (error2) {
2812
+ next(error2);
2813
+ }
2814
+ });
2815
+ }
2816
+ return {
2817
+ createRole,
2818
+ getRoles,
2819
+ getRoleByUserId,
2820
+ getRoleById,
2821
+ updateRole,
2822
+ deleteRole
2823
+ };
2824
+ }
2825
+
2826
+ // src/models/entity.model.ts
2827
+ var import_mongodb13 = require("mongodb");
2828
+ var MEntity = class {
2829
+ constructor(value) {
2830
+ var _a, _b, _c, _d, _e, _f, _g;
2831
+ this._id = (_a = value._id) != null ? _a : new import_mongodb13.ObjectId();
2832
+ this.name = (_b = value.name) != null ? _b : "";
2833
+ this.username = (_c = value.username) != null ? _c : "";
2834
+ this.type = value.type;
2835
+ this.createdAt = (_d = value.createdAt) != null ? _d : (/* @__PURE__ */ new Date()).toISOString();
2836
+ this.updatedAt = (_e = value.updatedAt) != null ? _e : "";
2837
+ this.deletedAt = (_f = value.deletedAt) != null ? _f : "";
2838
+ this.status = (_g = value.status) != null ? _g : "active";
2839
+ }
2840
+ };
2841
+
2842
+ // src/repositories/entity.repository.ts
2843
+ var import_mongodb14 = require("mongodb");
2844
+ var import_utils16 = require("@goweekdays/utils");
2845
+ function useEntityRepo() {
2846
+ const db = import_utils16.useAtlas.getDb();
2847
+ if (!db) {
2848
+ throw new import_utils16.InternalServerError("Unable to connect to server.");
2849
+ }
2850
+ const collection = db.collection("entities");
2851
+ function createIndex() {
2852
+ return __async(this, null, function* () {
2853
+ try {
2854
+ yield collection.createIndex({ name: 1 });
2855
+ yield collection.createIndex({ status: 1 });
2856
+ } catch (error) {
2857
+ throw new Error("Failed to create index for entity.");
2858
+ }
2859
+ });
2860
+ }
2861
+ function createUniqueIndex() {
2862
+ return __async(this, null, function* () {
2863
+ try {
2864
+ yield collection.createIndex({ name: 1, deletedAt: 1 }, { unique: true });
2865
+ } catch (error) {
2866
+ throw new Error("Failed to create unique index on email.");
2867
+ }
2868
+ });
2869
+ }
2870
+ function createEntity(value, session) {
2871
+ return __async(this, null, function* () {
2872
+ try {
2873
+ value = new MEntity(value);
2874
+ const res = yield collection.insertOne(value, {
2875
+ session
2876
+ });
2877
+ return res.insertedId.toString();
2878
+ } catch (error) {
2879
+ import_utils16.logger.log({ level: "error", message: `${error}` });
2880
+ const isDuplicated = error.message.includes("duplicate");
2881
+ if (isDuplicated) {
2882
+ throw new import_utils16.BadRequestError("Entity name already exists.");
2883
+ }
2884
+ throw new import_utils16.InternalServerError("Failed to create entity.");
2885
+ }
2886
+ });
2887
+ }
2888
+ function getEntities() {
2889
+ return __async(this, arguments, function* ({
2890
+ search = "",
2891
+ page = 1,
2892
+ limit = 10,
2893
+ sort = {}
2894
+ } = {}) {
2895
+ page = page > 0 ? page - 1 : 0;
2896
+ const query = { status: "active" };
2897
+ sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
2898
+ if (search) {
2899
+ query.$text = { $search: search };
2900
+ }
2901
+ try {
2902
+ const items = yield collection.aggregate([
2903
+ { $match: query },
2904
+ { $sort: sort },
2905
+ { $skip: page * limit },
2906
+ { $limit: limit }
2907
+ ]).toArray();
2908
+ const length = yield collection.countDocuments(query);
2909
+ return (0, import_utils16.paginate)(items, page, limit, length);
2910
+ } catch (error) {
2911
+ import_utils16.logger.log({ level: "error", message: `${error}` });
2912
+ throw error;
2913
+ }
2914
+ });
2915
+ }
2916
+ function updateEntityFieldById() {
2917
+ return __async(this, arguments, function* ({ _id, field, value } = {}, session) {
2918
+ const allowedFields = ["name"];
2919
+ if (!allowedFields.includes(field)) {
2920
+ throw new import_utils16.BadRequestError(
2921
+ `Field "${field}" is not allowed to be updated.`
2922
+ );
2923
+ }
2924
+ try {
2925
+ _id = new import_mongodb14.ObjectId(_id);
2926
+ } catch (error) {
2927
+ throw new import_utils16.BadRequestError("Invalid ID.");
2928
+ }
2929
+ try {
2930
+ yield collection.updateOne(
2931
+ { _id },
2932
+ { $set: { [field]: value } },
2933
+ // Dynamically set the field
2934
+ { session }
2935
+ );
2936
+ return `Successfully updated entity ${field}.`;
2937
+ } catch (error) {
2938
+ throw new import_utils16.InternalServerError(`Failed to update entity ${field}.`);
2939
+ }
2940
+ });
2941
+ }
2942
+ function deleteEntity(_id) {
2943
+ return __async(this, null, function* () {
2944
+ try {
2945
+ _id = new import_mongodb14.ObjectId(_id);
2946
+ } catch (error) {
2947
+ throw new import_utils16.BadRequestError("Invalid entity ID.");
2948
+ }
2949
+ try {
2950
+ return yield collection.updateOne(
2951
+ { _id },
2952
+ { $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } }
2953
+ );
2954
+ } catch (error) {
2955
+ return Promise.reject(error);
2956
+ }
2957
+ });
2958
+ }
2959
+ return {
2960
+ createIndex,
2961
+ createUniqueIndex,
2962
+ createEntity,
2963
+ getEntities,
2964
+ updateEntityFieldById,
2965
+ deleteEntity
2966
+ };
2967
+ }
2968
+
2969
+ // src/services/entity.service.ts
2970
+ var import_utils17 = require("@goweekdays/utils");
2971
+ function useEntityService() {
2972
+ const {
2973
+ createEntity: _createEntity,
2974
+ getEntities: _getEntities,
2975
+ updateEntityFieldById: _updateEntityFieldById,
2976
+ deleteEntity: _deleteEntity
2977
+ } = useEntityRepo();
2978
+ function createEntity(value) {
2979
+ return __async(this, null, function* () {
2980
+ try {
2981
+ return yield _createEntity(value);
2982
+ } catch (error) {
2983
+ throw new import_utils17.InternalServerError();
2984
+ }
2985
+ });
2986
+ }
2987
+ function getEntities(value) {
2988
+ return __async(this, null, function* () {
2989
+ try {
2990
+ return yield _getEntities(value);
2991
+ } catch (error) {
2992
+ throw new import_utils17.InternalServerError();
2993
+ }
2994
+ });
2995
+ }
2996
+ function updateEntityFieldById(_id, field, value) {
2997
+ return __async(this, null, function* () {
2998
+ try {
2999
+ return yield _updateEntityFieldById({ _id, field, value });
3000
+ } catch (error) {
3001
+ throw new import_utils17.InternalServerError();
3002
+ }
3003
+ });
3004
+ }
3005
+ function deleteEntity(_id) {
3006
+ return __async(this, null, function* () {
3007
+ try {
3008
+ return yield _deleteEntity(_id);
3009
+ } catch (error) {
3010
+ throw error;
3011
+ }
3012
+ });
3013
+ }
3014
+ return {
3015
+ createEntity,
3016
+ getEntities,
3017
+ updateEntityFieldById,
3018
+ deleteEntity
3019
+ };
3020
+ }
3021
+
3022
+ // src/controllers/entity.controller.ts
3023
+ var import_joi6 = __toESM(require("joi"));
3024
+ var import_utils18 = require("@goweekdays/utils");
3025
+ function useEntityController() {
3026
+ const {
3027
+ createEntity: _createEntity,
3028
+ getEntities: _getEntities,
3029
+ updateEntityFieldById: _updateEntityFieldById,
3030
+ deleteEntity: _deleteEntity
3031
+ } = useEntityService();
3032
+ function createEntity(req, res, next) {
3033
+ return __async(this, null, function* () {
3034
+ const value = req.body;
3035
+ const validation = import_joi6.default.object({
3036
+ name: import_joi6.default.string().required(),
3037
+ type: import_joi6.default.string().valid(
3038
+ "strand",
3039
+ "office",
3040
+ "bureau",
3041
+ "service",
3042
+ "person"
3043
+ )
3044
+ });
3045
+ const { error } = validation.validate(value);
3046
+ if (error) {
3047
+ next(new import_utils18.BadRequestError(error.message));
3048
+ return;
3049
+ }
3050
+ try {
3051
+ const id = yield _createEntity(value);
3052
+ res.json({ message: "Successfully created entity.", id });
3053
+ return;
3054
+ } catch (error2) {
3055
+ console.log(error2);
3056
+ next(error2);
3057
+ return;
3058
+ }
3059
+ });
3060
+ }
3061
+ function getEntities(req, res, next) {
3062
+ return __async(this, null, function* () {
3063
+ var _a, _b, _c;
3064
+ const search = (_a = req.query.search) != null ? _a : "";
3065
+ const page = (_b = Number(req.query.page)) != null ? _b : 1;
3066
+ const limit = (_c = Number(req.query.limit)) != null ? _c : 10;
3067
+ const validation = import_joi6.default.object({
3068
+ search: import_joi6.default.string().allow(""),
3069
+ page: import_joi6.default.number().min(1),
3070
+ limit: import_joi6.default.number().min(1)
3071
+ });
3072
+ const { error } = validation.validate(req.query);
3073
+ if (error) {
3074
+ next(new import_utils18.BadRequestError(error.message));
3075
+ return;
3076
+ }
3077
+ try {
3078
+ const entities = yield _getEntities({
3079
+ search,
3080
+ page,
3081
+ limit
3082
+ });
3083
+ res.json(entities);
3084
+ return;
3085
+ } catch (error2) {
3086
+ next(error2);
3087
+ return;
3088
+ }
3089
+ });
3090
+ }
3091
+ function updateEntityFieldById(req, res, next) {
3092
+ return __async(this, null, function* () {
3093
+ const { id, field, value } = req.body;
3094
+ const validation = import_joi6.default.object({
3095
+ id: import_joi6.default.string().required(),
3096
+ field: import_joi6.default.string().required(),
3097
+ value: import_joi6.default.string().required()
3098
+ });
3099
+ const { error } = validation.validate({ id, field, value });
3100
+ if (error) {
3101
+ next(new import_utils18.BadRequestError(error.message));
3102
+ return;
3103
+ }
3104
+ try {
3105
+ yield _updateEntityFieldById(id, field, value);
3106
+ res.json({ message: "Entity updated." });
3107
+ return;
3108
+ } catch (error2) {
3109
+ next(error2);
3110
+ return;
3111
+ }
3112
+ });
3113
+ }
3114
+ function deleteEntity(req, res, next) {
3115
+ return __async(this, null, function* () {
3116
+ const { id } = req.params;
3117
+ const validation = import_joi6.default.object({
3118
+ id: import_joi6.default.string().required()
3119
+ });
3120
+ const { error } = validation.validate({ id });
3121
+ if (error) {
3122
+ next(new import_utils18.BadRequestError(error.message));
3123
+ return;
3124
+ }
3125
+ try {
3126
+ yield _deleteEntity(id);
3127
+ res.json({ message: "Entity deleted." });
3128
+ return;
3129
+ } catch (error2) {
3130
+ next(error2);
3131
+ return;
3132
+ }
3133
+ });
3134
+ }
3135
+ return {
3136
+ createEntity,
3137
+ getEntities,
3138
+ updateEntityFieldById,
3139
+ deleteEntity
3140
+ };
3141
+ }
3142
+
3143
+ // src/models/workflow.model.ts
3144
+ var import_mongodb15 = require("mongodb");
3145
+ var MWorkflow = class {
3146
+ constructor(value) {
3147
+ var _a, _b, _c, _d, _e, _f, _g;
3148
+ this._id = (_a = value._id) != null ? _a : new import_mongodb15.ObjectId();
3149
+ this.name = (_b = value.name) != null ? _b : "";
3150
+ this.steps = (_c = value.steps) != null ? _c : [];
3151
+ this.status = (_d = value.status) != null ? _d : "active";
3152
+ this.createdAt = (_e = value.createdAt) != null ? _e : (/* @__PURE__ */ new Date()).toISOString();
3153
+ this.updatedAt = (_f = value.updatedAt) != null ? _f : "";
3154
+ this.deletedAt = (_g = value.deletedAt) != null ? _g : "";
3155
+ }
3156
+ };
3157
+
3158
+ // src/repositories/workflow.repository.ts
3159
+ var import_mongodb16 = require("mongodb");
3160
+ var import_utils19 = require("@goweekdays/utils");
3161
+ function useWorkflowRepo() {
3162
+ const db = import_utils19.useAtlas.getDb();
3163
+ if (!db) {
3164
+ throw new import_utils19.InternalServerError("Unable to connect to server.");
3165
+ }
3166
+ const collection = db.collection("workflows");
3167
+ function createIndex() {
3168
+ return __async(this, null, function* () {
3169
+ try {
3170
+ yield collection.createIndex({ name: 1 });
3171
+ yield collection.createIndex({ status: 1 });
3172
+ } catch (error) {
3173
+ throw new Error("Failed to create index for workflow.");
3174
+ }
3175
+ });
3176
+ }
3177
+ function createUniqueIndex() {
3178
+ return __async(this, null, function* () {
3179
+ try {
3180
+ yield collection.createIndex({ name: 1, deletedAt: 1 }, { unique: true });
3181
+ } catch (error) {
3182
+ throw new Error("Failed to create unique index for workflow.");
3183
+ }
3184
+ });
3185
+ }
3186
+ function createWorkflow(value) {
3187
+ return __async(this, null, function* () {
3188
+ try {
3189
+ value = new MWorkflow(value);
3190
+ const res = yield collection.insertOne(value);
3191
+ return res.insertedId.toString();
3192
+ } catch (error) {
3193
+ const duplicated = error.message.includes("duplicate");
3194
+ if (duplicated) {
3195
+ throw new import_utils19.BadRequestError("Workflow name already exists.");
3196
+ }
3197
+ throw new import_utils19.InternalServerError("Failed to create workflow.");
3198
+ }
3199
+ });
3200
+ }
3201
+ function getWorkflows() {
3202
+ return __async(this, arguments, function* ({
3203
+ search = "",
3204
+ page = 1,
3205
+ limit = 10,
3206
+ sort = {}
3207
+ } = {}) {
3208
+ page = page > 0 ? page - 1 : 0;
3209
+ const query = { status: "active" };
3210
+ sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
3211
+ if (search) {
3212
+ query.$text = { $search: search };
3213
+ }
3214
+ try {
3215
+ const items = yield collection.aggregate([
3216
+ { $match: query },
3217
+ { $sort: sort },
3218
+ { $skip: page * limit },
3219
+ { $limit: limit }
3220
+ ]).toArray();
3221
+ const length = yield collection.countDocuments(query);
3222
+ return (0, import_utils19.paginate)(items, page, limit, length);
3223
+ } catch (error) {
3224
+ import_utils19.logger.log({ level: "error", message: `${error}` });
3225
+ throw error;
3226
+ }
3227
+ });
3228
+ }
3229
+ function getWorkflowById(_id) {
3230
+ return __async(this, null, function* () {
3231
+ try {
3232
+ _id = new import_mongodb16.ObjectId(_id);
3233
+ } catch (error) {
3234
+ throw new import_utils19.BadRequestError("Invalid workflow ID.");
3235
+ }
3236
+ try {
3237
+ return yield collection.findOne({ _id });
3238
+ } catch (error) {
3239
+ throw new import_utils19.InternalServerError("Failed to get workflow.");
3240
+ }
3241
+ });
3242
+ }
3243
+ function updateWorkflowFieldById() {
3244
+ return __async(this, arguments, function* ({ _id, field, value } = {}, session) {
3245
+ const allowedFields = ["name"];
3246
+ if (!allowedFields.includes(field)) {
3247
+ throw new import_utils19.BadRequestError(
3248
+ `Field "${field}" is not allowed to be updated.`
3249
+ );
3250
+ }
3251
+ try {
3252
+ _id = new import_mongodb16.ObjectId(_id);
3253
+ } catch (error) {
3254
+ throw new import_utils19.BadRequestError("Invalid ID.");
3255
+ }
3256
+ try {
3257
+ yield collection.updateOne(
3258
+ { _id },
3259
+ { $set: { [field]: value } },
3260
+ // Dynamically set the field
3261
+ { session }
3262
+ );
3263
+ return `Successfully updated entity ${field}.`;
3264
+ } catch (error) {
3265
+ throw new import_utils19.InternalServerError(`Failed to update entity ${field}.`);
3266
+ }
3267
+ });
3268
+ }
3269
+ function deleteWorkflow(_id) {
3270
+ return __async(this, null, function* () {
3271
+ try {
3272
+ _id = new import_mongodb16.ObjectId(_id);
3273
+ } catch (error) {
3274
+ throw new import_utils19.BadRequestError("Invalid entity ID.");
3275
+ }
3276
+ try {
3277
+ return yield collection.updateOne(
3278
+ { _id },
3279
+ { $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } }
3280
+ );
3281
+ } catch (error) {
3282
+ return Promise.reject(error);
3283
+ }
3284
+ });
3285
+ }
3286
+ return {
3287
+ createIndex,
3288
+ createUniqueIndex,
3289
+ createWorkflow,
3290
+ getWorkflows,
3291
+ getWorkflowById,
3292
+ updateWorkflowFieldById,
3293
+ deleteWorkflow
3294
+ };
3295
+ }
3296
+
3297
+ // src/services/workflow.service.ts
3298
+ function useWorkflowService() {
3299
+ const {
3300
+ createWorkflow: _createWorkflow,
3301
+ getWorkflows: _getWorkflows,
3302
+ getWorkflowById: _getWorkflowById,
3303
+ updateWorkflowFieldById: _updateWorkflowFieldById,
3304
+ deleteWorkflow: _deleteWorkflow
3305
+ } = useWorkflowRepo();
3306
+ function createWorkflow(value) {
3307
+ return __async(this, null, function* () {
3308
+ try {
3309
+ return yield _createWorkflow(value);
3310
+ } catch (error) {
3311
+ throw error;
3312
+ }
3313
+ });
3314
+ }
3315
+ function getWorkflows() {
3316
+ return __async(this, arguments, function* ({
3317
+ search = "",
3318
+ page = 1,
3319
+ limit = 10,
3320
+ sort = {}
3321
+ } = {}) {
3322
+ try {
3323
+ return yield _getWorkflows({ search, page, limit, sort });
3324
+ } catch (error) {
3325
+ throw error;
3326
+ }
3327
+ });
3328
+ }
3329
+ function getWorkflowById(_id) {
3330
+ return __async(this, null, function* () {
3331
+ try {
3332
+ return yield _getWorkflowById(_id);
3333
+ } catch (error) {
3334
+ throw error;
3335
+ }
3336
+ });
3337
+ }
3338
+ function updateWorkflowFieldById(_id, field, value) {
3339
+ return __async(this, null, function* () {
3340
+ try {
3341
+ return yield _updateWorkflowFieldById({ _id, field, value });
3342
+ } catch (error) {
3343
+ throw error;
3344
+ }
3345
+ });
3346
+ }
3347
+ function deleteWorkflow(_id) {
3348
+ return __async(this, null, function* () {
3349
+ try {
3350
+ return yield _deleteWorkflow(_id);
3351
+ } catch (error) {
3352
+ throw error;
3353
+ }
3354
+ });
3355
+ }
3356
+ return {
3357
+ createWorkflow,
3358
+ getWorkflows,
3359
+ getWorkflowById,
3360
+ updateWorkflowFieldById,
3361
+ deleteWorkflow
3362
+ };
3363
+ }
3364
+
3365
+ // src/controllers/workflow.controller.ts
3366
+ var import_joi7 = __toESM(require("joi"));
3367
+ function useWorkflowController() {
3368
+ const {
3369
+ createWorkflow: _createWorkflow,
3370
+ getWorkflows: _getWorkflows,
3371
+ getWorkflowById: _getWorkflowById,
3372
+ updateWorkflowFieldById: _updateWorkflowFieldById,
3373
+ deleteWorkflow: _deleteWorkflow
3374
+ } = useWorkflowService();
3375
+ function createWorkflow(req, res, next) {
3376
+ return __async(this, null, function* () {
3377
+ var _a, _b;
3378
+ const name = (_a = req.body.name) != null ? _a : "";
3379
+ const steps = (_b = req.body.steps) != null ? _b : [];
3380
+ const validation = import_joi7.default.object({
3381
+ name: import_joi7.default.string().required(),
3382
+ steps: import_joi7.default.array().items(
3383
+ import_joi7.default.object({
3384
+ name: import_joi7.default.string().required(),
3385
+ assignedTo: import_joi7.default.string().optional(),
3386
+ nextStep: import_joi7.default.string().optional
3387
+ })
3388
+ ).min(3).required()
3389
+ });
3390
+ const { error } = validation.validate({ name, steps });
3391
+ if (error) {
3392
+ next(error);
3393
+ return;
3394
+ }
3395
+ try {
3396
+ const id = yield _createWorkflow({ name, steps });
3397
+ res.json({ message: "Successfully created workflow.", id });
3398
+ return;
3399
+ } catch (error2) {
3400
+ next(error2);
3401
+ return;
3402
+ }
3403
+ });
3404
+ }
3405
+ function getWorkflows(req, res, next) {
3406
+ return __async(this, null, function* () {
3407
+ var _a, _b, _c;
3408
+ const search = (_a = req.query.search) != null ? _a : "";
3409
+ const page = (_b = Number(req.query.page)) != null ? _b : 1;
3410
+ const limit = (_c = Number(req.query.limit)) != null ? _c : 10;
3411
+ const validation = import_joi7.default.object({
3412
+ search: import_joi7.default.string().allow(""),
3413
+ page: import_joi7.default.number().min(1),
3414
+ limit: import_joi7.default.number().min(10)
3415
+ });
3416
+ const { error } = validation.validate(req.query);
3417
+ if (error) {
3418
+ next(error);
3419
+ return;
3420
+ }
3421
+ try {
3422
+ const workflows = yield _getWorkflows({ search, page, limit });
3423
+ res.json(workflows);
3424
+ return;
3425
+ } catch (error2) {
3426
+ next(error2);
3427
+ return;
3428
+ }
3429
+ });
3430
+ }
3431
+ function getWorkflowById(req, res, next) {
3432
+ return __async(this, null, function* () {
3433
+ var _a;
3434
+ const id = (_a = req.params.id) != null ? _a : "";
3435
+ const validation = import_joi7.default.object({
3436
+ id: import_joi7.default.string().required()
3437
+ });
3438
+ const { error } = validation.validate({ id });
3439
+ if (error) {
3440
+ next(error);
3441
+ return;
3442
+ }
3443
+ try {
3444
+ const workflow = yield _getWorkflowById(id);
3445
+ res.json(workflow);
3446
+ return;
3447
+ } catch (error2) {
3448
+ next(error2);
3449
+ return;
3450
+ }
3451
+ });
3452
+ }
3453
+ function updateWorkflowFieldById(req, res, next) {
3454
+ return __async(this, null, function* () {
3455
+ var _a, _b, _c;
3456
+ const id = (_a = req.body.id) != null ? _a : "";
3457
+ const field = (_b = req.body.field) != null ? _b : "";
3458
+ const value = (_c = req.body.value) != null ? _c : "";
3459
+ const validation = import_joi7.default.object({
3460
+ id: import_joi7.default.string().required(),
3461
+ field: import_joi7.default.string().required(),
3462
+ value: import_joi7.default.string().required()
3463
+ });
3464
+ const { error } = validation.validate({ id, field, value });
3465
+ if (error) {
3466
+ next(error);
3467
+ return;
3468
+ }
3469
+ try {
3470
+ yield _updateWorkflowFieldById(id, field, value);
3471
+ res.json({ message: "Successfully updated workflow." });
3472
+ return;
3473
+ } catch (error2) {
3474
+ next(error2);
3475
+ return;
3476
+ }
3477
+ });
3478
+ }
3479
+ function deleteWorkflow(req, res, next) {
3480
+ return __async(this, null, function* () {
3481
+ var _a;
3482
+ const id = (_a = req.body.id) != null ? _a : "";
3483
+ const validation = import_joi7.default.object({
3484
+ id: import_joi7.default.string().required()
3485
+ });
3486
+ const { error } = validation.validate({ id });
3487
+ if (error) {
3488
+ next(error);
3489
+ return;
3490
+ }
3491
+ try {
3492
+ yield _deleteWorkflow(id);
3493
+ res.json({ message: "Successfully deleted workflow." });
3494
+ return;
3495
+ } catch (error2) {
3496
+ next(error2);
3497
+ return;
3498
+ }
3499
+ });
3500
+ }
3501
+ return {
3502
+ createWorkflow,
3503
+ getWorkflows,
3504
+ getWorkflowById,
3505
+ updateWorkflowFieldById,
3506
+ deleteWorkflow
3507
+ };
3508
+ }
3509
+
3510
+ // src/models/cap-bldg-act.model.ts
3511
+ var import_mongodb17 = require("mongodb");
3512
+ var MCapBldgAct = class {
3513
+ constructor(value) {
3514
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q;
3515
+ this._id = (_a = value._id) != null ? _a : new import_mongodb17.ObjectId();
3516
+ this.title = (_b = value.title) != null ? _b : "";
3517
+ this.subject = (_c = value.subject) != null ? _c : "";
3518
+ this.PMISActivityCode = (_d = value.PMISActivityCode) != null ? _d : "";
3519
+ this.type = (_e = value.type) != null ? _e : "";
3520
+ this.strandMandateAddressed = (_f = value.strandMandateAddressed) != null ? _f : "";
3521
+ this.objectives = (_g = value.objectives) != null ? _g : [];
3522
+ this.withCPDUnits = (_h = value.withCPDUnits) != null ? _h : false;
3523
+ this.completeStaffWorkReport = (_i = value.completeStaffWorkReport) != null ? _i : "";
3524
+ this.withATC = (_j = value.withATC) != null ? _j : null;
3525
+ this.ATC = (_k = value.ATC) != null ? _k : "";
3526
+ this.conceptNote = (_l = value.conceptNote) != null ? _l : "";
3527
+ this.certOfFundAvailability = (_m = value.certOfFundAvailability) != null ? _m : "";
3528
+ this.budgetProposal = (_n = value.budgetProposal) != null ? _n : "";
3529
+ this.targets = (_o = value.targets) != null ? _o : [];
3530
+ this.PRCFormsTemplate = (_p = value.PRCFormsTemplate) != null ? _p : "";
3531
+ this.HGDGTool = (_q = value.HGDGTool) != null ? _q : "";
3532
+ this.EXECOMLeadEndorsement = (_r = value.EXECOMLeadEndorsement) != null ? _r : "";
3533
+ this.individualResults = (_s = value.individualResults) != null ? _s : [];
3534
+ this.organizationalResults = (_t = value.organizationalResults) != null ? _t : [];
3535
+ this.indicative = (_u = value.indicative) != null ? _u : "";
3536
+ this.tentative = (_v = value.tentative) != null ? _v : { month: "", day: 0 };
3537
+ this.tentativeOption = (_w = value.tentativeOption) != null ? _w : { month: "", day: 0 };
3538
+ this.tentativeYear = (_x = value.tentativeYear) != null ? _x : 0;
3539
+ this.GADAttrRate = (_y = value.GADAttrRate) != null ? _y : 0;
3540
+ this.GADAttrRateAmount = (_z = value.GADAttrRateAmount) != null ? _z : 0;
3541
+ this.NTPCO = (_A = value.NTPCO) != null ? _A : {
3542
+ teaching: 0,
3543
+ nonteaching: 0,
3544
+ teachingRelated: 0
3545
+ };
3546
+ this.NTPRO = (_B = value.NTPRO) != null ? _B : {
3547
+ teaching: 0,
3548
+ nonteaching: 0,
3549
+ teachingRelated: 0
3550
+ };
3551
+ this.NTPSDO = (_C = value.NTPSDO) != null ? _C : {
3552
+ teaching: 0,
3553
+ nonteaching: 0,
3554
+ teachingRelated: 0
3555
+ };
3556
+ this.NTPSchool = (_D = value.NTPSchool) != null ? _D : {
3557
+ teaching: 0,
3558
+ nonteaching: 0,
3559
+ teachingRelated: 0
3560
+ };
3561
+ this.withSkeletonWorkforce = (_E = value.withSkeletonWorkforce) != null ? _E : null;
3562
+ this.skeletonWorkforce = (_F = value.skeletonWorkforce) != null ? _F : "";
3563
+ this.roles = (_G = value.roles) != null ? _G : [];
3564
+ this.rolesRate = (_H = value.rolesRate) != null ? _H : [];
3565
+ this.skills = (_I = value.skills) != null ? _I : [];
3566
+ this.skillsRate = (_J = value.skillsRate) != null ? _J : [];
3567
+ this.resourceEfficiencyRate = (_K = value.resourceEfficiencyRate) != null ? _K : [];
3568
+ this.AOOR = (_L = value.AOOR) != null ? _L : [];
3569
+ this.AOOS = (_M = value.AOOS) != null ? _M : [];
3570
+ this.status = (_N = value.status) != null ? _N : "draft";
3571
+ if (value.createdBy instanceof import_mongodb17.ObjectId) {
3572
+ try {
3573
+ value.createdBy = new import_mongodb17.ObjectId(value.createdBy);
3574
+ } catch (error) {
3575
+ throw new Error("Invalid createdBy ObjectId.");
3576
+ }
3577
+ }
3578
+ this.createdBy = value.createdBy;
3579
+ this.createdAt = (_O = value.createdAt) != null ? _O : (/* @__PURE__ */ new Date()).toISOString();
3580
+ this.updatedAt = (_P = value.updatedAt) != null ? _P : "";
3581
+ this.deletedAt = (_Q = value.deletedAt) != null ? _Q : "";
3582
+ }
3583
+ };
3584
+
3585
+ // src/repositories/cap-bldg-act.repository.ts
3586
+ var import_mongodb18 = require("mongodb");
3587
+ var import_utils20 = require("@goweekdays/utils");
3588
+ function useCapBldgActRepo() {
3589
+ const db = import_utils20.useAtlas.getDb();
3590
+ if (!db) {
3591
+ throw new import_utils20.InternalServerError("Unable to connect to server.");
3592
+ }
3593
+ const collection = db.collection("cap-bldg-acts");
3594
+ function createIndex() {
3595
+ return __async(this, null, function* () {
3596
+ try {
3597
+ yield collection.createIndex({ title: 1 });
3598
+ yield collection.createIndex({ subject: 1 });
3599
+ yield collection.createIndex({ type: 1 });
3600
+ yield collection.createIndex({ status: 1 });
3601
+ } catch (error) {
3602
+ throw new Error("Failed to create index for cap-bldg-acts.");
3603
+ }
3604
+ });
3605
+ }
3606
+ function createTextIndex() {
3607
+ return __async(this, null, function* () {
3608
+ try {
3609
+ yield collection.createIndex({
3610
+ title: "text",
3611
+ subject: "text",
3612
+ type: "text"
3613
+ });
3614
+ } catch (error) {
3615
+ throw new Error("Failed to create text index on cap-bldg-acts.");
3616
+ }
3617
+ });
3618
+ }
3619
+ function createCapBldgAct(value, session) {
3620
+ return __async(this, null, function* () {
3621
+ try {
3622
+ value = new MCapBldgAct(value);
3623
+ const res = yield collection.insertOne(value, {
3624
+ session
3625
+ });
3626
+ return res.insertedId.toString();
3627
+ } catch (error) {
3628
+ import_utils20.logger.log({ level: "error", message: `${error}` });
3629
+ const isDuplicated = error.message.includes("duplicate");
3630
+ if (isDuplicated) {
3631
+ throw new import_utils20.BadRequestError("CapBldgAct name already exists.");
3632
+ }
3633
+ throw new import_utils20.InternalServerError("Failed to create CapBldgAct.");
3634
+ }
3635
+ });
3636
+ }
3637
+ function updateCapBldgActBasicInfo() {
3638
+ return __async(this, arguments, function* ({ _id, value } = {}, session) {
3639
+ try {
3640
+ _id = new import_mongodb18.ObjectId(_id);
3641
+ } catch (error) {
3642
+ throw new import_utils20.BadRequestError("Invalid CapBldgAct ID.");
3643
+ }
3644
+ try {
3645
+ yield collection.updateOne(
3646
+ { _id },
3647
+ { $set: value },
3648
+ {
3649
+ session
3650
+ }
3651
+ );
3652
+ } catch (error) {
3653
+ import_utils20.logger.log({ level: "error", message: `${error}` });
3654
+ throw new import_utils20.InternalServerError("Failed to update CapBldgAct basic info.");
3655
+ }
3656
+ });
3657
+ }
3658
+ function updateCapBldgActInitRevEval() {
3659
+ return __async(this, arguments, function* ({ _id, value } = {}, session) {
3660
+ try {
3661
+ _id = new import_mongodb18.ObjectId(_id);
3662
+ } catch (error) {
3663
+ throw new import_utils20.BadRequestError("Invalid CapBldgAct ID.");
3664
+ }
3665
+ try {
3666
+ yield collection.updateOne(
3667
+ { _id },
3668
+ { $set: value },
3669
+ {
3670
+ session
3671
+ }
3672
+ );
3673
+ } catch (error) {
3674
+ import_utils20.logger.log({ level: "error", message: `${error}` });
3675
+ throw new import_utils20.InternalServerError(
3676
+ "Failed to update CapBldgAct initial review and evaluation."
3677
+ );
3678
+ }
3679
+ });
3680
+ }
3681
+ function updateCapBldgActAssmtCriteria() {
3682
+ return __async(this, arguments, function* ({ _id, value } = {}, session) {
3683
+ try {
3684
+ _id = new import_mongodb18.ObjectId(_id);
3685
+ } catch (error) {
3686
+ throw new import_utils20.BadRequestError("Invalid CapBldgAct ID.");
3687
+ }
3688
+ try {
3689
+ yield collection.updateOne(
3690
+ { _id },
3691
+ { $set: value },
3692
+ {
3693
+ session
3694
+ }
3695
+ );
3696
+ } catch (error) {
3697
+ import_utils20.logger.log({ level: "error", message: `${error}` });
3698
+ throw new import_utils20.InternalServerError(
3699
+ "Failed to update CapBldgAct assessment criteria."
3700
+ );
3701
+ }
3702
+ });
3703
+ }
3704
+ function getById(_id) {
3705
+ return __async(this, null, function* () {
3706
+ try {
3707
+ _id = new import_mongodb18.ObjectId(_id);
3708
+ } catch (error) {
3709
+ throw new import_utils20.BadRequestError("Invalid CapBldgAct ID.");
3710
+ }
3711
+ try {
3712
+ return yield collection.findOne({ _id });
3713
+ } catch (error) {
3714
+ import_utils20.logger.log({ level: "error", message: `${error}` });
3715
+ throw new import_utils20.InternalServerError("Failed to create CapBldgAct.");
3716
+ }
3717
+ });
3718
+ }
3719
+ function getCapBldgActs() {
3720
+ return __async(this, arguments, function* ({
3721
+ search = "",
3722
+ page = 1,
3723
+ limit = 10,
3724
+ sort = {},
3725
+ status = "draft"
3726
+ } = {}) {
3727
+ page = page > 0 ? page - 1 : 0;
3728
+ const query = { status };
3729
+ if (status === "ongoing") {
3730
+ query.status = {
3731
+ $in: [
3732
+ "for-internal-review",
3733
+ "for-initial-evaluation",
3734
+ "for-endorsement",
3735
+ "for-final-review",
3736
+ "for-final-evaluation",
3737
+ "for-clearance",
3738
+ "for-signature",
3739
+ "for-approval"
3740
+ ]
3741
+ };
3742
+ }
3743
+ sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
3744
+ if (search) {
3745
+ query.$text = { $search: search };
3746
+ }
3747
+ try {
3748
+ const items = yield collection.aggregate([
3749
+ { $match: query },
3750
+ { $sort: sort },
3751
+ { $skip: page * limit },
3752
+ { $limit: limit }
3753
+ ]).toArray();
3754
+ const length = yield collection.countDocuments(query);
3755
+ return (0, import_utils20.paginate)(items, page, limit, length);
3756
+ } catch (error) {
3757
+ import_utils20.logger.log({ level: "error", message: `${error}` });
3758
+ throw error;
3759
+ }
3760
+ });
3761
+ }
3762
+ function updateCapBldgActFieldById() {
3763
+ return __async(this, arguments, function* ({ _id, field, value } = {}, session) {
3764
+ const allowedFields = [
3765
+ "completeStaffWorkReport",
3766
+ "ATC",
3767
+ "certOfFundAvailability",
3768
+ "conceptNote",
3769
+ "budgetProposal",
3770
+ "PRCFormsTemplate",
3771
+ "HGDGTool",
3772
+ "EXECOMLeadEndorsement",
3773
+ "skeletonWorkforce",
3774
+ "status"
3775
+ ];
3776
+ if (!allowedFields.includes(field)) {
3777
+ throw new import_utils20.BadRequestError(
3778
+ `Field "${field}" is not allowed to be updated.`
3779
+ );
3780
+ }
3781
+ try {
3782
+ _id = new import_mongodb18.ObjectId(_id);
3783
+ } catch (error) {
3784
+ throw new import_utils20.BadRequestError("Invalid ID.");
3785
+ }
3786
+ try {
3787
+ yield collection.updateOne(
3788
+ { _id },
3789
+ { $set: { [field]: value } },
3790
+ // Dynamically set the field
3791
+ { session }
3792
+ );
3793
+ return `Successfully updated CapBldgAct ${field}.`;
3794
+ } catch (error) {
3795
+ throw new import_utils20.InternalServerError(`Failed to update CapBldgAct ${field}.`);
3796
+ }
3797
+ });
3798
+ }
3799
+ function deleteCapBldgAct(_id) {
3800
+ return __async(this, null, function* () {
3801
+ try {
3802
+ _id = new import_mongodb18.ObjectId(_id);
3803
+ } catch (error) {
3804
+ throw new import_utils20.BadRequestError("Invalid CapBldgAct ID.");
3805
+ }
3806
+ try {
3807
+ return yield collection.updateOne(
3808
+ { _id },
3809
+ { $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } }
3810
+ );
3811
+ } catch (error) {
3812
+ return Promise.reject(error);
3813
+ }
3814
+ });
3815
+ }
3816
+ return {
3817
+ createIndex,
3818
+ createTextIndex,
3819
+ createCapBldgAct,
3820
+ getById,
3821
+ getCapBldgActs,
3822
+ updateCapBldgActFieldById,
3823
+ deleteCapBldgAct,
3824
+ updateCapBldgActBasicInfo,
3825
+ updateCapBldgActInitRevEval,
3826
+ updateCapBldgActAssmtCriteria
3827
+ };
3828
+ }
3829
+
3830
+ // src/services/cap-bldg-act.service.ts
3831
+ var import_utils21 = require("@goweekdays/utils");
3832
+ function useCapBldgActService() {
3833
+ const {
3834
+ createCapBldgAct: _createCapBldgAct,
3835
+ getCapBldgActs: _getCapBldgActs,
3836
+ getById: _getById,
3837
+ updateCapBldgActFieldById: _updateCapBldgActFieldById,
3838
+ deleteCapBldgAct: _deleteCapBldgAct,
3839
+ updateCapBldgActBasicInfo: _updateCapBldgActBasicInfo,
3840
+ updateCapBldgActInitRevEval: _updateCapBldgActInitRevEval,
3841
+ updateCapBldgActAssmtCriteria: _updateCapBldgActAssmt
3842
+ } = useCapBldgActRepo();
3843
+ function createCapBldgAct(value) {
3844
+ return __async(this, null, function* () {
3845
+ try {
3846
+ value = new MCapBldgAct(value);
3847
+ return yield _createCapBldgAct(value);
3848
+ } catch (error) {
3849
+ throw error;
3850
+ }
3851
+ });
3852
+ }
3853
+ function updateCapBldgActBasicInfo(_id, value) {
3854
+ return __async(this, null, function* () {
3855
+ try {
3856
+ return yield _updateCapBldgActBasicInfo({ _id, value });
3857
+ } catch (error) {
3858
+ throw error;
3859
+ }
3860
+ });
3861
+ }
3862
+ function updateCapBldgActInitRevEval(_id, value) {
3863
+ return __async(this, null, function* () {
3864
+ try {
3865
+ return yield _updateCapBldgActInitRevEval({ _id, value });
3866
+ } catch (error) {
3867
+ throw error;
3868
+ }
3869
+ });
3870
+ }
3871
+ function updateCapBldgActAssmtCriteria(_id, value) {
3872
+ return __async(this, null, function* () {
3873
+ try {
3874
+ return yield _updateCapBldgActAssmt({ _id, value });
3875
+ } catch (error) {
3876
+ throw error;
3877
+ }
3878
+ });
3879
+ }
3880
+ function getCapBldgActs() {
3881
+ return __async(this, arguments, function* ({
3882
+ search = "",
3883
+ page = 1,
3884
+ status = "",
3885
+ limit = 10
3886
+ } = {}) {
3887
+ try {
3888
+ return yield _getCapBldgActs({ search, page, status, limit });
3889
+ } catch (error) {
3890
+ throw error;
3891
+ }
3892
+ });
3893
+ }
3894
+ function getById(id) {
3895
+ return __async(this, null, function* () {
3896
+ try {
3897
+ return yield _getById(id);
3898
+ } catch (error) {
3899
+ throw error;
3900
+ }
3901
+ });
3902
+ }
3903
+ function updateCapBldgActFieldById() {
3904
+ return __async(this, arguments, function* ({
3905
+ _id = "",
3906
+ field = "",
3907
+ value = ""
3908
+ } = {}) {
3909
+ try {
3910
+ return yield _updateCapBldgActFieldById({ _id, field, value });
3911
+ } catch (error) {
3912
+ throw error;
3913
+ }
3914
+ });
3915
+ }
3916
+ function deleteCapBldgAct(id) {
3917
+ return __async(this, null, function* () {
3918
+ try {
3919
+ return yield _deleteCapBldgAct(id);
3920
+ } catch (error) {
3921
+ throw error;
3922
+ }
3923
+ });
3924
+ }
3925
+ const s3 = new import_utils21.useS3({
3926
+ accessKeyId: SPACES_ACCESS_KEY,
3927
+ secretAccessKey: SPACES_SECRET_KEY,
3928
+ endpoint: SPACES_ENDPOINT,
3929
+ region: SPACES_REGION,
3930
+ bucket: SPACES_BUCKET
3931
+ });
3932
+ const { createFile: _createFile, deleteFileById } = useFileRepo();
3933
+ function uploadAttachment(value, id, field) {
3934
+ return __async(this, null, function* () {
3935
+ var _a;
3936
+ const session = (_a = import_utils21.useAtlas.getClient()) == null ? void 0 : _a.startSession();
3937
+ session == null ? void 0 : session.startTransaction();
3938
+ const file = {
3939
+ name: value.originalname,
3940
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
3941
+ };
3942
+ try {
3943
+ const _id = yield _createFile(file, session);
3944
+ yield s3.uploadObject({
3945
+ key: _id,
3946
+ body: value.buffer,
3947
+ contentType: value.mimetype
3948
+ });
3949
+ yield _updateCapBldgActFieldById({ _id: id, field, value: _id }, session);
3950
+ yield session == null ? void 0 : session.commitTransaction();
3951
+ return id;
3952
+ } catch (error) {
3953
+ yield session == null ? void 0 : session.abortTransaction();
3954
+ throw error;
3955
+ } finally {
3956
+ session == null ? void 0 : session.endSession();
3957
+ }
3958
+ });
3959
+ }
3960
+ function deleteAttachment(attachment, id, field) {
3961
+ return __async(this, null, function* () {
3962
+ var _a;
3963
+ const session = (_a = import_utils21.useAtlas.getClient()) == null ? void 0 : _a.startSession();
3964
+ session == null ? void 0 : session.startTransaction();
3965
+ try {
3966
+ yield deleteFileById(attachment, session);
3967
+ yield _updateCapBldgActFieldById({ _id: id, field, value: "" }, session);
3968
+ yield s3.deleteObject(attachment);
3969
+ yield session == null ? void 0 : session.commitTransaction();
3970
+ return "Attachment successfully deleted.";
3971
+ } catch (error) {
3972
+ yield session == null ? void 0 : session.abortTransaction();
3973
+ throw error;
3974
+ } finally {
3975
+ session == null ? void 0 : session.endSession();
3976
+ }
3977
+ });
3978
+ }
3979
+ return {
3980
+ createCapBldgAct,
3981
+ getCapBldgActs,
3982
+ getById,
3983
+ updateCapBldgActFieldById,
3984
+ deleteCapBldgAct,
3985
+ updateCapBldgActBasicInfo,
3986
+ updateCapBldgActInitRevEval,
3987
+ updateCapBldgActAssmtCriteria,
3988
+ uploadAttachment,
3989
+ deleteAttachment
3990
+ };
3991
+ }
3992
+
3993
+ // src/controllers/cap-bldg-act.controller.ts
3994
+ var import_joi8 = __toESM(require("joi"));
3995
+ var import_utils22 = require("@goweekdays/utils");
3996
+ function useCapBldgActController() {
3997
+ const {
3998
+ createCapBldgAct: _createCapBldgAct,
3999
+ getCapBldgActs: _getCapBldgActs,
4000
+ getById: _getById,
4001
+ updateCapBldgActBasicInfo: _updateBasicInformation,
4002
+ updateCapBldgActInitRevEval: _updateInitRevEval,
4003
+ updateCapBldgActAssmtCriteria: _updateAssmtCriteria,
4004
+ updateCapBldgActFieldById: _updateFieldById,
4005
+ uploadAttachment: _uploadAttachment,
4006
+ deleteAttachment: _deleteAttachment
4007
+ } = useCapBldgActService();
4008
+ function createCapBldgAct(req, res, next) {
4009
+ return __async(this, null, function* () {
4010
+ const value = req.body;
4011
+ const validation = import_joi8.default.object({
4012
+ title: import_joi8.default.string().required(),
4013
+ subject: import_joi8.default.string().required(),
4014
+ PMISActivityCode: import_joi8.default.string().required(),
4015
+ type: import_joi8.default.string().required(),
4016
+ strandMandateAddressed: import_joi8.default.string().required(),
4017
+ objectives: import_joi8.default.array().items(import_joi8.default.string()).min(3).max(3).required(),
4018
+ withCPDUnits: import_joi8.default.boolean().required(),
4019
+ createdBy: import_joi8.default.string().hex().required()
4020
+ });
4021
+ const { error } = validation.validate(value);
4022
+ if (error) {
4023
+ next(new import_utils22.BadRequestError(error.message));
4024
+ return;
4025
+ }
4026
+ try {
4027
+ yield _createCapBldgAct(value);
4028
+ res.json({ message: "Successfully created CBA request." });
4029
+ return;
4030
+ } catch (error2) {
4031
+ next(error2);
4032
+ }
4033
+ });
4034
+ }
4035
+ function updateBasicInformation(req, res, next) {
4036
+ return __async(this, null, function* () {
4037
+ var _a;
4038
+ const value = req.body;
4039
+ const id = (_a = req.params.id) != null ? _a : "";
4040
+ const validation = import_joi8.default.object({
4041
+ id: import_joi8.default.string().hex().required(),
4042
+ title: import_joi8.default.string().required(),
4043
+ subject: import_joi8.default.string().required(),
4044
+ PMISActivityCode: import_joi8.default.string().required(),
4045
+ type: import_joi8.default.string().required(),
4046
+ strandMandateAddressed: import_joi8.default.string().required(),
4047
+ objectives: import_joi8.default.array().items(import_joi8.default.string()).min(3).max(3).required(),
4048
+ withCPDUnits: import_joi8.default.boolean().required()
4049
+ });
4050
+ const { error } = validation.validate(__spreadProps(__spreadValues({}, value), { id }));
4051
+ if (error) {
4052
+ next(new import_utils22.BadRequestError(error.message));
4053
+ return;
4054
+ }
4055
+ try {
4056
+ yield _updateBasicInformation(id, value);
4057
+ res.json({ message: "Successfully updated CBA basic information." });
4058
+ return;
4059
+ } catch (error2) {
4060
+ next(error2);
4061
+ }
4062
+ });
4063
+ }
4064
+ function updateInitRevEval(req, res, next) {
4065
+ return __async(this, null, function* () {
4066
+ var _a;
4067
+ const value = req.body;
4068
+ const id = (_a = req.params.id) != null ? _a : "";
4069
+ const NTP = import_joi8.default.object({
4070
+ teaching: import_joi8.default.number().required(),
4071
+ nonteaching: import_joi8.default.number().required(),
4072
+ teachingRelated: import_joi8.default.number().required()
4073
+ }).required();
4074
+ const tentative = import_joi8.default.object({
4075
+ month: import_joi8.default.string().required(),
4076
+ day: import_joi8.default.number().required()
4077
+ }).required();
4078
+ const list = import_joi8.default.array().items(import_joi8.default.string()).min(3).max(3).required();
4079
+ const validation = import_joi8.default.object({
4080
+ id: import_joi8.default.string().hex().required(),
4081
+ completeStaffWorkReport: import_joi8.default.string().required(),
4082
+ withATC: import_joi8.default.boolean().required(),
4083
+ ATC: import_joi8.default.string().required(),
4084
+ conceptNote: import_joi8.default.string().required(),
4085
+ certOfFundAvailability: import_joi8.default.string().required(),
4086
+ budgetProposal: import_joi8.default.string().required(),
4087
+ targets: list,
4088
+ PRCFormsTemplate: import_joi8.default.string().required(),
4089
+ HGDGTool: import_joi8.default.string().required(),
4090
+ EXECOMLeadEndorsement: import_joi8.default.string().required(),
4091
+ individualResults: list,
4092
+ organizationalResults: list,
4093
+ indicative: import_joi8.default.string().required(),
4094
+ tentative,
4095
+ tentativeOption: tentative,
4096
+ tentativeYear: import_joi8.default.number().required(),
4097
+ GADAttrRate: import_joi8.default.number().required(),
4098
+ GADAttrRateAmount: import_joi8.default.number().required(),
4099
+ NTPCO: NTP,
4100
+ NTPRO: NTP,
4101
+ NTPSDO: NTP,
4102
+ NTPSchool: NTP,
4103
+ withSkeletonWorkforce: import_joi8.default.boolean().required(),
4104
+ skeletonWorkforce: import_joi8.default.string().required()
4105
+ });
4106
+ const { error } = validation.validate(__spreadProps(__spreadValues({}, value), { id }));
4107
+ if (error) {
4108
+ next(new import_utils22.BadRequestError(error.message));
4109
+ return;
4110
+ }
4111
+ try {
4112
+ yield _updateInitRevEval(id, value);
4113
+ res.json({
4114
+ message: "Successfully updated CBA initial review and evaluation."
4115
+ });
4116
+ return;
4117
+ } catch (error2) {
4118
+ next(error2);
4119
+ }
4120
+ });
4121
+ }
4122
+ function updateAssmtCriteria(req, res, next) {
4123
+ return __async(this, null, function* () {
4124
+ var _a;
4125
+ const value = req.body;
4126
+ const id = (_a = req.params.id) != null ? _a : "";
4127
+ const list = import_joi8.default.array().items(import_joi8.default.string()).min(3).max(3).required();
4128
+ const listOptional = import_joi8.default.array().items(import_joi8.default.number().optional().allow(null)).optional().min(0).max(3);
4129
+ const validation = import_joi8.default.object({
4130
+ id: import_joi8.default.string().hex().required(),
4131
+ roles: list,
4132
+ rolesRate: listOptional,
4133
+ skills: list,
4134
+ skillsRate: listOptional,
4135
+ resourceEfficiencyRate: listOptional,
4136
+ AOOR: import_joi8.default.array().items(import_joi8.default.number().optional().allow(null)).optional().min(0).max(5),
4137
+ AOOS: import_joi8.default.array().items(import_joi8.default.string().optional().allow(null)).min(0).max(5)
4138
+ });
4139
+ const { error } = validation.validate(__spreadProps(__spreadValues({}, value), { id }));
4140
+ if (error) {
4141
+ next(new import_utils22.BadRequestError(error.message));
4142
+ return;
4143
+ }
4144
+ try {
4145
+ yield _updateAssmtCriteria(id, value);
4146
+ res.json({
4147
+ message: "Successfully updated CBA assessment criteria."
4148
+ });
4149
+ return;
4150
+ } catch (error2) {
4151
+ next(error2);
4152
+ }
4153
+ });
4154
+ }
4155
+ function getCapBldgActs(req, res, next) {
4156
+ return __async(this, null, function* () {
4157
+ var _a, _b;
4158
+ const search = (_a = req.query.search) != null ? _a : "";
4159
+ const page = req.query.page ? Number(req.query.page) : 1;
4160
+ const limit = req.query.limit ? Number(req.query.limit) : 10;
4161
+ const status = (_b = req.query.status) != null ? _b : "";
4162
+ const validation = import_joi8.default.object({
4163
+ search: import_joi8.default.string().allow(""),
4164
+ page: import_joi8.default.number().min(1),
4165
+ limit: import_joi8.default.number().min(1),
4166
+ status: import_joi8.default.string().allow("")
4167
+ });
4168
+ const { error } = validation.validate(req.query);
4169
+ if (error) {
4170
+ next(new import_utils22.BadRequestError(error.message));
4171
+ return;
4172
+ }
4173
+ try {
4174
+ const data = yield _getCapBldgActs({ search, page, limit, status });
4175
+ res.json(data);
4176
+ return;
4177
+ } catch (error2) {
4178
+ next(error2);
4179
+ }
4180
+ });
4181
+ }
4182
+ function getById(req, res, next) {
4183
+ return __async(this, null, function* () {
4184
+ const { id } = req.params;
4185
+ const validation = import_joi8.default.object({
4186
+ id: import_joi8.default.string().required()
4187
+ });
4188
+ const { error } = validation.validate({ id });
4189
+ if (error) {
4190
+ next(new import_utils22.BadRequestError(error.message));
4191
+ return;
4192
+ }
4193
+ try {
4194
+ const data = yield _getById(id);
4195
+ res.json(data);
4196
+ return;
4197
+ } catch (error2) {
4198
+ next(error2);
4199
+ }
4200
+ });
4201
+ }
4202
+ function updateFieldById(req, res, next) {
4203
+ return __async(this, null, function* () {
4204
+ const _id = req.params.id;
4205
+ const { field, value } = req.body;
4206
+ const validation = import_joi8.default.object({
4207
+ _id: import_joi8.default.string().hex().required(),
4208
+ field: import_joi8.default.string().valid(
4209
+ "completeStaffWorkReport",
4210
+ "ATC",
4211
+ "certOfFundAvailability",
4212
+ "conceptNote",
4213
+ "budgetProposal",
4214
+ "PRCFormsTemplate",
4215
+ "HGDGTool",
4216
+ "EXECOMLeadEndorsement",
4217
+ "skeletonWorkforce",
4218
+ "status"
4219
+ ).required(),
4220
+ value: import_joi8.default.string().required()
4221
+ });
4222
+ const { error } = validation.validate({ _id, field, value });
4223
+ if (error) {
4224
+ next(new import_utils22.BadRequestError(error.message));
4225
+ return;
4226
+ }
4227
+ try {
4228
+ const message = yield _updateFieldById({ _id, field, value });
4229
+ res.json({ message });
4230
+ } catch (error2) {
4231
+ next(error2);
4232
+ }
4233
+ });
4234
+ }
4235
+ function uploadAttachment(req, res, next) {
4236
+ return __async(this, null, function* () {
4237
+ const file = req.file;
4238
+ if (!file) {
4239
+ res.status(400).send("File is required!");
4240
+ return;
4241
+ }
4242
+ const id = req.params.id;
4243
+ const field = req.body.field;
4244
+ const validation = import_joi8.default.object({
4245
+ id: import_joi8.default.string().required(),
4246
+ field: import_joi8.default.string().required()
4247
+ });
4248
+ const { error } = validation.validate({ id, field });
4249
+ if (error) {
4250
+ next(new import_utils22.BadRequestError(error.message));
4251
+ return;
4252
+ }
4253
+ try {
4254
+ const _file = yield _uploadAttachment(file, id, field);
4255
+ res.json({ message: "Successfully uploaded attachment.", id: _file });
4256
+ return;
4257
+ } catch (error2) {
4258
+ next(error2);
4259
+ }
4260
+ });
4261
+ }
4262
+ function deleteAttachment(req, res, next) {
4263
+ return __async(this, null, function* () {
4264
+ var _a, _b;
4265
+ const id = req.params.id;
4266
+ const attachment = (_a = req.body.attachment) != null ? _a : "";
4267
+ const field = (_b = req.body.field) != null ? _b : "";
4268
+ const validation = import_joi8.default.string().required();
4269
+ const { error } = validation.validate(id);
4270
+ if (error) {
4271
+ next(new import_utils22.BadRequestError(error.message));
4272
+ }
4273
+ try {
4274
+ const message = yield _deleteAttachment(attachment, id, field);
4275
+ res.json({ message });
4276
+ return;
4277
+ } catch (error2) {
4278
+ next(error2);
4279
+ }
4280
+ });
4281
+ }
4282
+ return {
4283
+ createCapBldgAct,
4284
+ getCapBldgActs,
4285
+ getById,
4286
+ updateBasicInformation,
4287
+ updateInitRevEval,
4288
+ updateAssmtCriteria,
4289
+ updateFieldById,
4290
+ uploadAttachment,
4291
+ deleteAttachment
4292
+ };
4293
+ }
4294
+
4295
+ // src/models/comment.model.ts
4296
+ var import_mongodb19 = require("mongodb");
4297
+ var MComment = class {
4298
+ constructor(value) {
4299
+ var _a, _b, _c, _d, _e, _f, _g, _h;
4300
+ this._id = (_a = value._id) != null ? _a : new import_mongodb19.ObjectId();
4301
+ this.comment = (_b = value.comment) != null ? _b : "";
4302
+ this.type = (_c = value.type) != null ? _c : "common";
4303
+ if (typeof value.user === "string") {
4304
+ try {
4305
+ value.user = new import_mongodb19.ObjectId(value.user);
4306
+ } catch (error) {
4307
+ throw new Error("Invalid user ID.");
4308
+ }
4309
+ }
4310
+ this.user = (_d = value.user) != null ? _d : "";
4311
+ this.collection = (_e = value.collection) != null ? _e : "";
4312
+ if (typeof value.document === "string") {
4313
+ try {
4314
+ value.document = new import_mongodb19.ObjectId(value.document);
4315
+ } catch (error) {
4316
+ throw new Error("Invalid document ID.");
4317
+ }
4318
+ }
4319
+ this.document = value.document;
4320
+ this.createdAt = (_f = value.createdAt) != null ? _f : (/* @__PURE__ */ new Date()).toISOString();
4321
+ this.updatedAt = (_g = value.updatedAt) != null ? _g : "";
4322
+ this.deletedAt = (_h = value.deletedAt) != null ? _h : "";
4323
+ }
4324
+ };
4325
+
4326
+ // src/repositories/comment.repository.ts
4327
+ var import_mongodb20 = require("mongodb");
4328
+ var import_utils23 = require("@goweekdays/utils");
4329
+ function useCommentRepo() {
4330
+ const db = import_utils23.useAtlas.getDb();
4331
+ if (!db) {
4332
+ throw new Error("Database not initialized");
4333
+ }
4334
+ const collection = db.collection("comments");
4335
+ function createIndex() {
4336
+ return __async(this, null, function* () {
4337
+ try {
4338
+ yield collection.createIndex({ deletedAt: 1, document: 1 });
4339
+ } catch (error) {
4340
+ throw new Error("Failed to create index for cap-bldg-acts.");
4341
+ }
4342
+ });
4343
+ }
4344
+ function addComment(value) {
4345
+ return __async(this, null, function* () {
4346
+ try {
4347
+ value = new MComment(value);
4348
+ yield collection.insertOne(value);
4349
+ return "Comment added successfully.";
4350
+ } catch (error) {
4351
+ throw new import_utils23.InternalServerError("Failed to add comment.");
4352
+ }
4353
+ });
4354
+ }
4355
+ function getComments() {
4356
+ return __async(this, arguments, function* ({ search = "", page = 1, limit = 10, sort = {}, document = "" } = {}) {
4357
+ page = page > 0 ? page - 1 : 0;
4358
+ if (document) {
4359
+ try {
4360
+ document = new import_mongodb20.ObjectId(document);
4361
+ } catch (error) {
4362
+ throw new Error("Invalid document ID.");
4363
+ }
4364
+ }
4365
+ const query = { deletedAt: "", document };
4366
+ sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
4367
+ if (search) {
4368
+ query.$text = { $search: search };
4369
+ }
4370
+ try {
4371
+ const items = yield collection.aggregate([
4372
+ { $match: query },
4373
+ { $sort: sort },
4374
+ { $skip: page * limit },
4375
+ { $limit: limit }
4376
+ ]).toArray();
4377
+ const length = yield collection.countDocuments(query);
4378
+ return (0, import_utils23.paginate)(items, page, limit, length);
4379
+ } catch (error) {
4380
+ import_utils23.logger.log({ level: "error", message: `${error}` });
4381
+ throw error;
4382
+ }
4383
+ });
4384
+ }
4385
+ return {
4386
+ createIndex,
4387
+ addComment,
4388
+ getComments
4389
+ };
4390
+ }
4391
+
4392
+ // src/services/comment.service.ts
4393
+ function useCommentService() {
4394
+ const { addComment: _addComment, getComments: _getComments } = useCommentRepo();
4395
+ function addComment() {
4396
+ return __async(this, arguments, function* ({ comment, type, user, collection, document } = {}) {
4397
+ try {
4398
+ return yield _addComment({
4399
+ comment,
4400
+ type,
4401
+ user,
4402
+ collection,
4403
+ document
4404
+ });
4405
+ } catch (error) {
4406
+ throw error;
4407
+ }
4408
+ });
4409
+ }
4410
+ function getComments() {
4411
+ return __async(this, arguments, function* ({ page = 1, document = "" } = {}) {
4412
+ try {
4413
+ return yield _getComments({ page, document });
4414
+ } catch (error) {
4415
+ throw error;
4416
+ }
4417
+ });
4418
+ }
4419
+ return {
4420
+ addComment,
4421
+ getComments
4422
+ };
4423
+ }
4424
+
4425
+ // src/controllers/comment.controller.ts
4426
+ var import_joi9 = __toESM(require("joi"));
4427
+ var import_utils24 = require("@goweekdays/utils");
4428
+ function useCommentController() {
4429
+ const { addComment: _addComment, getComments: _getComments } = useCommentService();
4430
+ function addComment(req, res, next) {
4431
+ return __async(this, null, function* () {
4432
+ const value = req.body;
4433
+ const validation = import_joi9.default.object({
4434
+ comment: import_joi9.default.string().required(),
4435
+ type: import_joi9.default.string().valid("comment", "approve", "request-changes"),
4436
+ user: import_joi9.default.string().hex().required(),
4437
+ collection: import_joi9.default.string().required(),
4438
+ document: import_joi9.default.string().hex().required()
4439
+ });
4440
+ const { error } = validation.validate(value);
4441
+ if (error) {
4442
+ next(new import_utils24.BadRequestError(error.message));
4443
+ return;
4444
+ }
4445
+ try {
4446
+ yield _addComment({
4447
+ comment: value.comment,
4448
+ type: value.type,
4449
+ user: value.user,
4450
+ collection: value.collection,
4451
+ document: value.document
4452
+ });
4453
+ res.json({ message: "Successfully added comment." });
4454
+ return;
4455
+ } catch (error2) {
4456
+ next(error2);
4457
+ return;
4458
+ }
4459
+ });
4460
+ }
4461
+ function getComments(req, res, next) {
4462
+ return __async(this, null, function* () {
4463
+ var _a, _b;
4464
+ const page = (_a = Number(req.query.page)) != null ? _a : 1;
4465
+ const document = (_b = req.query.document) != null ? _b : "";
4466
+ const validation = import_joi9.default.object({
4467
+ page: import_joi9.default.number().min(1),
4468
+ document: import_joi9.default.string().hex().required()
4469
+ });
4470
+ const { error } = validation.validate({ page, document });
4471
+ if (error) {
4472
+ next(new import_utils24.BadRequestError(error.message));
4473
+ return;
4474
+ }
4475
+ try {
4476
+ const comments = yield _getComments({ page, document });
4477
+ res.json(comments);
4478
+ return;
4479
+ } catch (error2) {
4480
+ next(error2);
4481
+ return;
4482
+ }
4483
+ });
4484
+ }
4485
+ return {
4486
+ addComment,
4487
+ getComments
4488
+ };
4489
+ }
4490
+ // Annotate the CommonJS export names for ESM import in node:
4491
+ 0 && (module.exports = {
4492
+ ACCESS_TOKEN_EXPIRY,
4493
+ ACCESS_TOKEN_SECRET,
4494
+ APP_ACCOUNT,
4495
+ AppError,
4496
+ BadRequestError,
4497
+ DEFAULT_USER_EMAIL,
4498
+ DEFAULT_USER_FIRST_NAME,
4499
+ DEFAULT_USER_LAST_NAME,
4500
+ DEFAULT_USER_PASSWORD,
4501
+ InternalServerError,
4502
+ MAILER_EMAIL,
4503
+ MAILER_PASSWORD,
4504
+ MAILER_TRANSPORT_HOST,
4505
+ MAILER_TRANSPORT_PORT,
4506
+ MAILER_TRANSPORT_SECURE,
4507
+ MCapBldgAct,
4508
+ MComment,
4509
+ MEntity,
4510
+ MFile,
4511
+ MONGO_DB,
4512
+ MONGO_URI,
4513
+ MRole,
4514
+ MToken,
4515
+ MUser,
4516
+ MUserRole,
4517
+ MVerification,
4518
+ MWorkflow,
4519
+ NotFoundError,
4520
+ PORT,
4521
+ REDIS_HOST,
4522
+ REDIS_PASSWORD,
4523
+ REDIS_PORT,
4524
+ REFRESH_TOKEN_EXPIRY,
4525
+ REFRESH_TOKEN_SECRET,
4526
+ SECRET_KEY,
4527
+ SPACES_ACCESS_KEY,
4528
+ SPACES_BUCKET,
4529
+ SPACES_ENDPOINT,
4530
+ SPACES_REGION,
4531
+ SPACES_SECRET_KEY,
4532
+ UnauthorizedError,
4533
+ VERIFICATION_FORGET_PASSWORD_DURATION,
4534
+ VERIFICATION_USER_INVITE_DURATION,
4535
+ authMiddleware,
4536
+ comparePassword,
4537
+ compileHandlebar,
4538
+ errorHandler,
4539
+ generateToken,
4540
+ getDirectory,
4541
+ hashPassword,
4542
+ initRedisClient,
4543
+ isDev,
4544
+ logger,
4545
+ paginate,
4546
+ prependZeros,
4547
+ toObjectId,
4548
+ useAtlas,
4549
+ useAuthController,
4550
+ useAuthService,
4551
+ useCapBldgActController,
4552
+ useCapBldgActRepo,
4553
+ useCapBldgActService,
4554
+ useCommentController,
4555
+ useCommentRepo,
4556
+ useCommentService,
4557
+ useEntityController,
4558
+ useEntityRepo,
4559
+ useEntityService,
4560
+ useFileController,
4561
+ useFileRepo,
4562
+ useFileService,
4563
+ useMailer,
4564
+ useRedisClient,
4565
+ useRoleController,
4566
+ useRoleRepo,
4567
+ useRoleService,
4568
+ useS3,
4569
+ useTokenRepo,
4570
+ useUserController,
4571
+ useUserRepo,
4572
+ useUserService,
4573
+ useVerificationController,
4574
+ useVerificationRepo,
4575
+ useVerificationService,
4576
+ useWorkflowController,
4577
+ useWorkflowRepo,
4578
+ useWorkflowService
4579
+ });
4580
+ //# sourceMappingURL=index.js.map