@eeplatform/core 1.4.3 → 1.4.4
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/CHANGELOG.md +6 -0
- package/dist/index.d.ts +55 -1
- package/dist/index.js +694 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +702 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -1
package/dist/index.mjs
CHANGED
|
@@ -25700,7 +25700,7 @@ function useRegionService() {
|
|
|
25700
25700
|
{
|
|
25701
25701
|
id: region.toString(),
|
|
25702
25702
|
name: "Admin",
|
|
25703
|
-
type: "
|
|
25703
|
+
type: "basic-edu-ro",
|
|
25704
25704
|
permissions: ["*"],
|
|
25705
25705
|
status: "active",
|
|
25706
25706
|
default: true
|
|
@@ -26261,7 +26261,7 @@ function useDivisionService() {
|
|
|
26261
26261
|
{
|
|
26262
26262
|
id: division.toString(),
|
|
26263
26263
|
name: "Admin",
|
|
26264
|
-
type: "
|
|
26264
|
+
type: "basic-edu-sdo",
|
|
26265
26265
|
permissions: ["*"],
|
|
26266
26266
|
status: "active",
|
|
26267
26267
|
default: true
|
|
@@ -29272,6 +29272,700 @@ function useStockCardController() {
|
|
|
29272
29272
|
getSuppliers
|
|
29273
29273
|
};
|
|
29274
29274
|
}
|
|
29275
|
+
|
|
29276
|
+
// src/services/github.service.ts
|
|
29277
|
+
import { AppError as AppError16, BadRequestError as BadRequestError72 } from "@eeplatform/nodejs-utils";
|
|
29278
|
+
import { Octokit } from "@octokit/rest";
|
|
29279
|
+
import _sodium from "libsodium-wrappers";
|
|
29280
|
+
function useGitHubService() {
|
|
29281
|
+
function parseRepoUrl(url2) {
|
|
29282
|
+
const match = url2.match(/github\.com[:\/]([^\/]+)\/(.+)\.git$/);
|
|
29283
|
+
if (!match)
|
|
29284
|
+
throw new Error("Invalid GitHub repo URL");
|
|
29285
|
+
return { owner: match[1], repo: match[2] };
|
|
29286
|
+
}
|
|
29287
|
+
async function checkAdminPermission(owner, repo, octokit) {
|
|
29288
|
+
try {
|
|
29289
|
+
const { data: repoData } = await octokit.repos.get({ owner, repo });
|
|
29290
|
+
if (!repoData.permissions?.admin) {
|
|
29291
|
+
throw new BadRequestError72(
|
|
29292
|
+
"You do not have admin access to this repository."
|
|
29293
|
+
);
|
|
29294
|
+
}
|
|
29295
|
+
} catch (error) {
|
|
29296
|
+
if (error.status === 404) {
|
|
29297
|
+
throw new BadRequestError72(
|
|
29298
|
+
"Repository not found or you don't have access to it."
|
|
29299
|
+
);
|
|
29300
|
+
} else if (error.status === 401) {
|
|
29301
|
+
throw new BadRequestError72(
|
|
29302
|
+
"Invalid GitHub token or insufficient permissions."
|
|
29303
|
+
);
|
|
29304
|
+
} else if (error.message.includes("admin access")) {
|
|
29305
|
+
throw error;
|
|
29306
|
+
} else {
|
|
29307
|
+
throw new BadRequestError72(
|
|
29308
|
+
`Failed to check repository permissions: ${error.message}`
|
|
29309
|
+
);
|
|
29310
|
+
}
|
|
29311
|
+
}
|
|
29312
|
+
}
|
|
29313
|
+
async function setVariables(params) {
|
|
29314
|
+
try {
|
|
29315
|
+
const { githubToken, repoUrl, environment, type, keyValues } = params;
|
|
29316
|
+
const octokit = new Octokit({ auth: githubToken });
|
|
29317
|
+
const { owner, repo } = parseRepoUrl(repoUrl);
|
|
29318
|
+
await checkAdminPermission(owner, repo, octokit);
|
|
29319
|
+
const lines = keyValues.split(/[\n\r\s\t]+/).map((l) => l.trim()).filter(Boolean);
|
|
29320
|
+
for (const line of lines) {
|
|
29321
|
+
const equalIndex = line.indexOf("=");
|
|
29322
|
+
if (equalIndex === -1)
|
|
29323
|
+
continue;
|
|
29324
|
+
const key = line.substring(0, equalIndex).trim();
|
|
29325
|
+
const value = line.substring(equalIndex + 1).trim();
|
|
29326
|
+
if (!key || !value)
|
|
29327
|
+
continue;
|
|
29328
|
+
if (type === "secret") {
|
|
29329
|
+
const { data: publicKeyRes } = await octokit.actions.getEnvironmentPublicKey({
|
|
29330
|
+
owner,
|
|
29331
|
+
repo,
|
|
29332
|
+
environment_name: environment
|
|
29333
|
+
});
|
|
29334
|
+
try {
|
|
29335
|
+
await _sodium.ready;
|
|
29336
|
+
const sodium = _sodium;
|
|
29337
|
+
const publicKeyBase64 = publicKeyRes.key;
|
|
29338
|
+
if (!publicKeyBase64) {
|
|
29339
|
+
throw new Error("No public key received from GitHub");
|
|
29340
|
+
}
|
|
29341
|
+
const keyBytes = new Uint8Array(
|
|
29342
|
+
Buffer.from(publicKeyBase64, "base64")
|
|
29343
|
+
);
|
|
29344
|
+
const valueBytes = new Uint8Array(Buffer.from(value, "utf8"));
|
|
29345
|
+
const encryptedBytes = sodium.crypto_box_seal(valueBytes, keyBytes);
|
|
29346
|
+
const encryptedValue = Buffer.from(encryptedBytes).toString("base64");
|
|
29347
|
+
await octokit.actions.createOrUpdateEnvironmentSecret({
|
|
29348
|
+
owner,
|
|
29349
|
+
repo,
|
|
29350
|
+
environment_name: environment,
|
|
29351
|
+
secret_name: key,
|
|
29352
|
+
encrypted_value: encryptedValue,
|
|
29353
|
+
key_id: publicKeyRes.key_id
|
|
29354
|
+
});
|
|
29355
|
+
} catch (encryptionError) {
|
|
29356
|
+
throw new BadRequestError72(
|
|
29357
|
+
`Failed to encrypt secret '${key}': ${encryptionError.message}`
|
|
29358
|
+
);
|
|
29359
|
+
}
|
|
29360
|
+
} else if (type === "env") {
|
|
29361
|
+
await octokit.actions.createEnvironmentVariable({
|
|
29362
|
+
owner,
|
|
29363
|
+
repo,
|
|
29364
|
+
environment_name: environment,
|
|
29365
|
+
name: key,
|
|
29366
|
+
value
|
|
29367
|
+
});
|
|
29368
|
+
}
|
|
29369
|
+
}
|
|
29370
|
+
return `Successfully set ${lines.length} ${type} variables/secrets in environment '${environment}'`;
|
|
29371
|
+
} catch (error) {
|
|
29372
|
+
if (error instanceof AppError16)
|
|
29373
|
+
throw error;
|
|
29374
|
+
if (error.status === 422) {
|
|
29375
|
+
throw new BadRequestError72(
|
|
29376
|
+
`GitHub API validation error: ${error.message}`
|
|
29377
|
+
);
|
|
29378
|
+
} else if (error.status === 404) {
|
|
29379
|
+
throw new BadRequestError72("Environment or repository not found.");
|
|
29380
|
+
} else if (error.status === 403) {
|
|
29381
|
+
throw new BadRequestError72(
|
|
29382
|
+
"Forbidden: Insufficient permissions or rate limit exceeded."
|
|
29383
|
+
);
|
|
29384
|
+
} else if (error.message.includes("admin access") || error.message.includes("permissions")) {
|
|
29385
|
+
throw error;
|
|
29386
|
+
} else {
|
|
29387
|
+
throw new BadRequestError72(
|
|
29388
|
+
`Failed to set GitHub variables: ${error.message}`
|
|
29389
|
+
);
|
|
29390
|
+
}
|
|
29391
|
+
}
|
|
29392
|
+
}
|
|
29393
|
+
return {
|
|
29394
|
+
setVariables
|
|
29395
|
+
};
|
|
29396
|
+
}
|
|
29397
|
+
|
|
29398
|
+
// src/controllers/util.controller.ts
|
|
29399
|
+
import Joi40 from "joi";
|
|
29400
|
+
import {
|
|
29401
|
+
AppError as AppError17,
|
|
29402
|
+
BadRequestError as BadRequestError73,
|
|
29403
|
+
InternalServerError as InternalServerError27,
|
|
29404
|
+
logger as logger35
|
|
29405
|
+
} from "@eeplatform/nodejs-utils";
|
|
29406
|
+
function useUtilController() {
|
|
29407
|
+
async function healthCheck(req, res, next) {
|
|
29408
|
+
try {
|
|
29409
|
+
res.status(200).json({
|
|
29410
|
+
success: true,
|
|
29411
|
+
message: "Util service is healthy",
|
|
29412
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
29413
|
+
data: {
|
|
29414
|
+
availableEndpoints: [
|
|
29415
|
+
"POST /github/variables - Set GitHub environment variables or secrets"
|
|
29416
|
+
],
|
|
29417
|
+
keyValueFormat: "KEY=value pairs separated by newlines, spaces, or tabs"
|
|
29418
|
+
}
|
|
29419
|
+
});
|
|
29420
|
+
} catch (error) {
|
|
29421
|
+
logger35.error("Health check failed", { error: error.message });
|
|
29422
|
+
next(new InternalServerError27("Health check failed"));
|
|
29423
|
+
}
|
|
29424
|
+
}
|
|
29425
|
+
async function setGitHubVariables(req, res, next) {
|
|
29426
|
+
try {
|
|
29427
|
+
const { githubToken, repoUrl, environment, type, keyValues } = req.body;
|
|
29428
|
+
const validation = Joi40.object({
|
|
29429
|
+
githubToken: Joi40.string().required().messages({
|
|
29430
|
+
"string.empty": "GitHub token is required",
|
|
29431
|
+
"any.required": "GitHub token is required"
|
|
29432
|
+
}),
|
|
29433
|
+
repoUrl: Joi40.string().uri().required().messages({
|
|
29434
|
+
"string.empty": "Repository URL is required",
|
|
29435
|
+
"string.uri": "Repository URL must be a valid URL",
|
|
29436
|
+
"any.required": "Repository URL is required"
|
|
29437
|
+
}),
|
|
29438
|
+
environment: Joi40.string().required().messages({
|
|
29439
|
+
"string.empty": "Environment name is required",
|
|
29440
|
+
"any.required": "Environment name is required"
|
|
29441
|
+
}),
|
|
29442
|
+
type: Joi40.string().valid("env", "secret").required().messages({
|
|
29443
|
+
"any.only": 'Type must be either "env" or "secret"',
|
|
29444
|
+
"any.required": "Type is required"
|
|
29445
|
+
}),
|
|
29446
|
+
keyValues: Joi40.string().required().messages({
|
|
29447
|
+
"string.empty": "Key-value pairs are required",
|
|
29448
|
+
"any.required": "Key-value pairs are required"
|
|
29449
|
+
})
|
|
29450
|
+
});
|
|
29451
|
+
const { error } = validation.validate({
|
|
29452
|
+
githubToken,
|
|
29453
|
+
repoUrl,
|
|
29454
|
+
environment,
|
|
29455
|
+
type,
|
|
29456
|
+
keyValues
|
|
29457
|
+
});
|
|
29458
|
+
if (error) {
|
|
29459
|
+
next(new BadRequestError73(error.message));
|
|
29460
|
+
return;
|
|
29461
|
+
}
|
|
29462
|
+
const repoUrlPattern = /github\.com[:\/]([^\/]+)\/(.+)\.git$/;
|
|
29463
|
+
if (!repoUrlPattern.test(repoUrl)) {
|
|
29464
|
+
next(
|
|
29465
|
+
new BadRequestError73(
|
|
29466
|
+
"Invalid GitHub repository URL format. Expected format: https://github.com/owner/repo.git"
|
|
29467
|
+
)
|
|
29468
|
+
);
|
|
29469
|
+
return;
|
|
29470
|
+
}
|
|
29471
|
+
const lines = keyValues.split(/[\n\r\s\t]+/).map((l) => l.trim()).filter(Boolean);
|
|
29472
|
+
const invalidLines = lines.filter(
|
|
29473
|
+
(line) => !line.includes("=") || line.indexOf("=") === -1
|
|
29474
|
+
);
|
|
29475
|
+
if (invalidLines.length > 0) {
|
|
29476
|
+
next(
|
|
29477
|
+
new BadRequestError73(
|
|
29478
|
+
"Invalid key-value format. Each pair should be in format: KEY=value. Pairs can be separated by newlines, spaces, or tabs."
|
|
29479
|
+
)
|
|
29480
|
+
);
|
|
29481
|
+
return;
|
|
29482
|
+
}
|
|
29483
|
+
const githubService = useGitHubService();
|
|
29484
|
+
const result = await githubService.setVariables({
|
|
29485
|
+
githubToken,
|
|
29486
|
+
repoUrl,
|
|
29487
|
+
environment,
|
|
29488
|
+
type,
|
|
29489
|
+
keyValues
|
|
29490
|
+
});
|
|
29491
|
+
logger35.info(`GitHub variables set successfully`, {
|
|
29492
|
+
repoUrl,
|
|
29493
|
+
environment,
|
|
29494
|
+
type,
|
|
29495
|
+
count: lines.length
|
|
29496
|
+
});
|
|
29497
|
+
res.status(200).json({
|
|
29498
|
+
success: true,
|
|
29499
|
+
message: result,
|
|
29500
|
+
data: {
|
|
29501
|
+
repoUrl,
|
|
29502
|
+
environment,
|
|
29503
|
+
type,
|
|
29504
|
+
variablesSet: lines.length
|
|
29505
|
+
}
|
|
29506
|
+
});
|
|
29507
|
+
} catch (error) {
|
|
29508
|
+
logger35.error("Failed to set GitHub variables", {
|
|
29509
|
+
error: error.message,
|
|
29510
|
+
stack: error.stack
|
|
29511
|
+
});
|
|
29512
|
+
if (error instanceof AppError17) {
|
|
29513
|
+
next(error);
|
|
29514
|
+
} else {
|
|
29515
|
+
next(
|
|
29516
|
+
new InternalServerError27(
|
|
29517
|
+
`Failed to set GitHub variables: ${error.message}`
|
|
29518
|
+
)
|
|
29519
|
+
);
|
|
29520
|
+
}
|
|
29521
|
+
}
|
|
29522
|
+
}
|
|
29523
|
+
return {
|
|
29524
|
+
healthCheck,
|
|
29525
|
+
setGitHubVariables
|
|
29526
|
+
};
|
|
29527
|
+
}
|
|
29528
|
+
|
|
29529
|
+
// src/models/plantilla.model.ts
|
|
29530
|
+
import { BadRequestError as BadRequestError74 } from "@eeplatform/nodejs-utils";
|
|
29531
|
+
import Joi41 from "joi";
|
|
29532
|
+
import { ObjectId as ObjectId46 } from "mongodb";
|
|
29533
|
+
var schemaPlantilla = Joi41.object({
|
|
29534
|
+
_id: Joi41.string().hex().optional().allow(null, ""),
|
|
29535
|
+
itemNumber: Joi41.string().required(),
|
|
29536
|
+
positionTitle: Joi41.string().required(),
|
|
29537
|
+
officeAssignmentType: Joi41.string().required(),
|
|
29538
|
+
officeAssignment: Joi41.string().required(),
|
|
29539
|
+
status: Joi41.string().required(),
|
|
29540
|
+
employeeId: Joi41.string().hex().optional().allow(null, ""),
|
|
29541
|
+
createdAt: Joi41.date().iso().optional().allow(null, ""),
|
|
29542
|
+
updatedAt: Joi41.date().iso().optional().allow(null, ""),
|
|
29543
|
+
deletedAt: Joi41.date().iso().optional().allow(null, "")
|
|
29544
|
+
});
|
|
29545
|
+
function MPlantilla(data) {
|
|
29546
|
+
const { error } = schemaPlantilla.validate(data);
|
|
29547
|
+
if (error) {
|
|
29548
|
+
throw new BadRequestError74(error.message);
|
|
29549
|
+
}
|
|
29550
|
+
if (data._id && typeof data._id === "string") {
|
|
29551
|
+
try {
|
|
29552
|
+
data._id = new ObjectId46(data._id);
|
|
29553
|
+
} catch (error2) {
|
|
29554
|
+
throw new BadRequestError74("Invalid _id.");
|
|
29555
|
+
}
|
|
29556
|
+
}
|
|
29557
|
+
if (data.employeeId && typeof data.employeeId === "string") {
|
|
29558
|
+
try {
|
|
29559
|
+
data.employeeId = new ObjectId46(data.employeeId);
|
|
29560
|
+
} catch (error2) {
|
|
29561
|
+
throw new BadRequestError74("Invalid employeeId.");
|
|
29562
|
+
}
|
|
29563
|
+
}
|
|
29564
|
+
return {
|
|
29565
|
+
_id: data._id,
|
|
29566
|
+
itemNumber: data.itemNumber ?? "",
|
|
29567
|
+
positionTitle: data.positionTitle ?? "",
|
|
29568
|
+
officeAssignmentType: data.officeAssignmentType ?? "",
|
|
29569
|
+
officeAssignment: data.officeAssignment ?? "",
|
|
29570
|
+
status: data.status ?? "active",
|
|
29571
|
+
employeeId: data.employeeId,
|
|
29572
|
+
createdAt: data.createdAt ? new Date(data.createdAt) : /* @__PURE__ */ new Date(),
|
|
29573
|
+
updatedAt: data.updatedAt ? new Date(data.updatedAt) : "",
|
|
29574
|
+
deletedAt: data.deletedAt ? new Date(data.deletedAt) : ""
|
|
29575
|
+
};
|
|
29576
|
+
}
|
|
29577
|
+
|
|
29578
|
+
// src/repositories/plantilla.repository.ts
|
|
29579
|
+
import {
|
|
29580
|
+
AppError as AppError18,
|
|
29581
|
+
BadRequestError as BadRequestError75,
|
|
29582
|
+
InternalServerError as InternalServerError28,
|
|
29583
|
+
logger as logger36,
|
|
29584
|
+
makeCacheKey as makeCacheKey23,
|
|
29585
|
+
paginate as paginate19,
|
|
29586
|
+
useAtlas as useAtlas38,
|
|
29587
|
+
useCache as useCache24
|
|
29588
|
+
} from "@eeplatform/nodejs-utils";
|
|
29589
|
+
import { ObjectId as ObjectId47 } from "mongodb";
|
|
29590
|
+
function usePlantillaRepo() {
|
|
29591
|
+
const db = useAtlas38.getDb();
|
|
29592
|
+
if (!db) {
|
|
29593
|
+
throw new Error("Unable to connect to server.");
|
|
29594
|
+
}
|
|
29595
|
+
const namespace_collection = "plantillas";
|
|
29596
|
+
const collection = db.collection(namespace_collection);
|
|
29597
|
+
const { getCache, setCache, delNamespace } = useCache24(namespace_collection);
|
|
29598
|
+
async function createIndexes() {
|
|
29599
|
+
try {
|
|
29600
|
+
await collection.createIndexes([
|
|
29601
|
+
{ key: { name: 1 }, unique: true, name: "unique_name_index" },
|
|
29602
|
+
{ key: { school: 1 } },
|
|
29603
|
+
{ key: { status: 1 } }
|
|
29604
|
+
]);
|
|
29605
|
+
} catch (error) {
|
|
29606
|
+
throw new Error("Failed to create index on plantillas.");
|
|
29607
|
+
}
|
|
29608
|
+
}
|
|
29609
|
+
async function add(value, session) {
|
|
29610
|
+
try {
|
|
29611
|
+
value = MPlantilla(value);
|
|
29612
|
+
const res = await collection.insertOne(value, { session });
|
|
29613
|
+
delCachedData();
|
|
29614
|
+
return res.insertedId;
|
|
29615
|
+
} catch (error) {
|
|
29616
|
+
logger36.log({
|
|
29617
|
+
level: "error",
|
|
29618
|
+
message: error.message
|
|
29619
|
+
});
|
|
29620
|
+
if (error instanceof AppError18) {
|
|
29621
|
+
throw error;
|
|
29622
|
+
} else {
|
|
29623
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
29624
|
+
if (isDuplicated) {
|
|
29625
|
+
throw new BadRequestError75("Plantilla already exists.");
|
|
29626
|
+
}
|
|
29627
|
+
throw new Error("Failed to create plantilla.");
|
|
29628
|
+
}
|
|
29629
|
+
}
|
|
29630
|
+
}
|
|
29631
|
+
async function updateById(_id, value, session) {
|
|
29632
|
+
try {
|
|
29633
|
+
_id = new ObjectId47(_id);
|
|
29634
|
+
} catch (error) {
|
|
29635
|
+
throw new BadRequestError75("Invalid ID.");
|
|
29636
|
+
}
|
|
29637
|
+
value.updatedAt = /* @__PURE__ */ new Date();
|
|
29638
|
+
try {
|
|
29639
|
+
const res = await collection.updateOne(
|
|
29640
|
+
{ _id },
|
|
29641
|
+
{ $set: value },
|
|
29642
|
+
{ session }
|
|
29643
|
+
);
|
|
29644
|
+
delCachedData();
|
|
29645
|
+
return res;
|
|
29646
|
+
} catch (error) {
|
|
29647
|
+
logger36.log({
|
|
29648
|
+
level: "error",
|
|
29649
|
+
message: error.message
|
|
29650
|
+
});
|
|
29651
|
+
if (error instanceof AppError18) {
|
|
29652
|
+
throw error;
|
|
29653
|
+
} else {
|
|
29654
|
+
throw new Error("Failed to update plantilla.");
|
|
29655
|
+
}
|
|
29656
|
+
}
|
|
29657
|
+
}
|
|
29658
|
+
async function getAll({
|
|
29659
|
+
search = "",
|
|
29660
|
+
page = 1,
|
|
29661
|
+
limit = 10,
|
|
29662
|
+
sort = {},
|
|
29663
|
+
org = "",
|
|
29664
|
+
status = "active"
|
|
29665
|
+
} = {}) {
|
|
29666
|
+
page = page > 0 ? page - 1 : 0;
|
|
29667
|
+
const query = {
|
|
29668
|
+
status
|
|
29669
|
+
};
|
|
29670
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
29671
|
+
if (search) {
|
|
29672
|
+
query.$text = { $search: search };
|
|
29673
|
+
}
|
|
29674
|
+
if (org) {
|
|
29675
|
+
try {
|
|
29676
|
+
query.org = new ObjectId47(org);
|
|
29677
|
+
} catch (error) {
|
|
29678
|
+
throw new BadRequestError75("Invalid org ID.");
|
|
29679
|
+
}
|
|
29680
|
+
}
|
|
29681
|
+
const cacheParams = {
|
|
29682
|
+
page,
|
|
29683
|
+
limit,
|
|
29684
|
+
sort: JSON.stringify(sort)
|
|
29685
|
+
};
|
|
29686
|
+
if (search)
|
|
29687
|
+
cacheParams.search = search;
|
|
29688
|
+
if (org)
|
|
29689
|
+
cacheParams.org = org;
|
|
29690
|
+
if (status !== "active")
|
|
29691
|
+
cacheParams.status = status;
|
|
29692
|
+
const cacheKey = makeCacheKey23(namespace_collection, cacheParams);
|
|
29693
|
+
logger36.log({
|
|
29694
|
+
level: "info",
|
|
29695
|
+
message: `Cache key for getAll plantillas: ${cacheKey}`
|
|
29696
|
+
});
|
|
29697
|
+
try {
|
|
29698
|
+
const cached = await getCache(cacheKey);
|
|
29699
|
+
if (cached) {
|
|
29700
|
+
logger36.log({
|
|
29701
|
+
level: "info",
|
|
29702
|
+
message: `Cache hit for getAll plantillas: ${cacheKey}`
|
|
29703
|
+
});
|
|
29704
|
+
return cached;
|
|
29705
|
+
}
|
|
29706
|
+
const items = await collection.aggregate([
|
|
29707
|
+
{ $match: query },
|
|
29708
|
+
{ $sort: sort },
|
|
29709
|
+
{ $skip: page * limit },
|
|
29710
|
+
{ $limit: limit }
|
|
29711
|
+
]).toArray();
|
|
29712
|
+
const length = await collection.countDocuments(query);
|
|
29713
|
+
const data = paginate19(items, page, limit, length);
|
|
29714
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
29715
|
+
logger36.log({
|
|
29716
|
+
level: "info",
|
|
29717
|
+
message: `Cache set for getAll plantillas: ${cacheKey}`
|
|
29718
|
+
});
|
|
29719
|
+
}).catch((err) => {
|
|
29720
|
+
logger36.log({
|
|
29721
|
+
level: "error",
|
|
29722
|
+
message: `Failed to set cache for getAll plantillas: ${err.message}`
|
|
29723
|
+
});
|
|
29724
|
+
});
|
|
29725
|
+
return data;
|
|
29726
|
+
} catch (error) {
|
|
29727
|
+
logger36.log({ level: "error", message: `${error}` });
|
|
29728
|
+
throw error;
|
|
29729
|
+
}
|
|
29730
|
+
}
|
|
29731
|
+
async function getById(_id) {
|
|
29732
|
+
try {
|
|
29733
|
+
_id = new ObjectId47(_id);
|
|
29734
|
+
} catch (error) {
|
|
29735
|
+
throw new BadRequestError75("Invalid ID.");
|
|
29736
|
+
}
|
|
29737
|
+
const cacheKey = makeCacheKey23(namespace_collection, { _id: String(_id) });
|
|
29738
|
+
try {
|
|
29739
|
+
const cached = await getCache(cacheKey);
|
|
29740
|
+
if (cached) {
|
|
29741
|
+
logger36.log({
|
|
29742
|
+
level: "info",
|
|
29743
|
+
message: `Cache hit for getById plantilla: ${cacheKey}`
|
|
29744
|
+
});
|
|
29745
|
+
return cached;
|
|
29746
|
+
}
|
|
29747
|
+
const result = await collection.findOne({
|
|
29748
|
+
_id
|
|
29749
|
+
});
|
|
29750
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
29751
|
+
logger36.log({
|
|
29752
|
+
level: "info",
|
|
29753
|
+
message: `Cache set for plantilla by id: ${cacheKey}`
|
|
29754
|
+
});
|
|
29755
|
+
}).catch((err) => {
|
|
29756
|
+
logger36.log({
|
|
29757
|
+
level: "error",
|
|
29758
|
+
message: `Failed to set cache for plantilla by id: ${err.message}`
|
|
29759
|
+
});
|
|
29760
|
+
});
|
|
29761
|
+
return result;
|
|
29762
|
+
} catch (error) {
|
|
29763
|
+
if (error instanceof AppError18) {
|
|
29764
|
+
throw error;
|
|
29765
|
+
} else {
|
|
29766
|
+
throw new InternalServerError28("Failed to get plantilla.");
|
|
29767
|
+
}
|
|
29768
|
+
}
|
|
29769
|
+
}
|
|
29770
|
+
async function deleteById(_id, session) {
|
|
29771
|
+
try {
|
|
29772
|
+
_id = new ObjectId47(_id);
|
|
29773
|
+
} catch (error) {
|
|
29774
|
+
throw new BadRequestError75("Invalid ID.");
|
|
29775
|
+
}
|
|
29776
|
+
try {
|
|
29777
|
+
const res = await collection.updateOne(
|
|
29778
|
+
{ _id },
|
|
29779
|
+
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
|
|
29780
|
+
);
|
|
29781
|
+
delCachedData();
|
|
29782
|
+
return res;
|
|
29783
|
+
} catch (error) {
|
|
29784
|
+
logger36.log({
|
|
29785
|
+
level: "error",
|
|
29786
|
+
message: error.message
|
|
29787
|
+
});
|
|
29788
|
+
if (error instanceof AppError18) {
|
|
29789
|
+
throw error;
|
|
29790
|
+
} else {
|
|
29791
|
+
throw new InternalServerError28("Failed to delete plantilla.");
|
|
29792
|
+
}
|
|
29793
|
+
}
|
|
29794
|
+
}
|
|
29795
|
+
function delCachedData() {
|
|
29796
|
+
delNamespace().then(() => {
|
|
29797
|
+
logger36.log({
|
|
29798
|
+
level: "info",
|
|
29799
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
29800
|
+
});
|
|
29801
|
+
}).catch((err) => {
|
|
29802
|
+
logger36.log({
|
|
29803
|
+
level: "error",
|
|
29804
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
29805
|
+
});
|
|
29806
|
+
});
|
|
29807
|
+
}
|
|
29808
|
+
return {
|
|
29809
|
+
createIndexes,
|
|
29810
|
+
add,
|
|
29811
|
+
getAll,
|
|
29812
|
+
getById,
|
|
29813
|
+
updateById,
|
|
29814
|
+
deleteById
|
|
29815
|
+
};
|
|
29816
|
+
}
|
|
29817
|
+
|
|
29818
|
+
// src/controllers/plantilla.controller.ts
|
|
29819
|
+
import { BadRequestError as BadRequestError76 } from "@eeplatform/nodejs-utils";
|
|
29820
|
+
import Joi42 from "joi";
|
|
29821
|
+
function usePlantillaController() {
|
|
29822
|
+
const {
|
|
29823
|
+
add: _addPlantilla,
|
|
29824
|
+
getAll: _getAllPlantillas,
|
|
29825
|
+
getById: _getPlantillaById,
|
|
29826
|
+
updateById: _updatePlantillaById,
|
|
29827
|
+
deleteById: _deletePlantillaById
|
|
29828
|
+
} = usePlantillaRepo();
|
|
29829
|
+
async function createPlantilla(req, res, next) {
|
|
29830
|
+
const value = req.body;
|
|
29831
|
+
const validation = Joi42.object({
|
|
29832
|
+
itemNumber: Joi42.string().required(),
|
|
29833
|
+
positionTitle: Joi42.string().required(),
|
|
29834
|
+
officeAssignmentType: Joi42.string().required(),
|
|
29835
|
+
officeAssignment: Joi42.string().required(),
|
|
29836
|
+
status: Joi42.string().required(),
|
|
29837
|
+
employeeId: Joi42.string().hex().optional().allow(null, "")
|
|
29838
|
+
});
|
|
29839
|
+
const { error } = validation.validate(value);
|
|
29840
|
+
if (error) {
|
|
29841
|
+
next(new BadRequestError76(error.message));
|
|
29842
|
+
return;
|
|
29843
|
+
}
|
|
29844
|
+
try {
|
|
29845
|
+
const id = await _addPlantilla(value);
|
|
29846
|
+
res.json({ message: "Plantilla created successfully", id });
|
|
29847
|
+
return;
|
|
29848
|
+
} catch (error2) {
|
|
29849
|
+
next(error2);
|
|
29850
|
+
}
|
|
29851
|
+
}
|
|
29852
|
+
async function getAllPlantillas(req, res, next) {
|
|
29853
|
+
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
29854
|
+
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
29855
|
+
const search = req.query.search ?? "";
|
|
29856
|
+
const org = req.query.org ?? "";
|
|
29857
|
+
const isPageNumber = isFinite(page);
|
|
29858
|
+
if (!isPageNumber) {
|
|
29859
|
+
next(new BadRequestError76("Invalid page number."));
|
|
29860
|
+
return;
|
|
29861
|
+
}
|
|
29862
|
+
const isLimitNumber = isFinite(limit);
|
|
29863
|
+
if (!isLimitNumber) {
|
|
29864
|
+
next(new BadRequestError76("Invalid limit number."));
|
|
29865
|
+
return;
|
|
29866
|
+
}
|
|
29867
|
+
const validation = Joi42.object({
|
|
29868
|
+
page: Joi42.number().min(1).optional().allow("", null),
|
|
29869
|
+
limit: Joi42.number().min(1).optional().allow("", null),
|
|
29870
|
+
search: Joi42.string().optional().allow("", null),
|
|
29871
|
+
org: Joi42.string().optional().allow("", null)
|
|
29872
|
+
});
|
|
29873
|
+
const { error } = validation.validate({ page, limit, search, org });
|
|
29874
|
+
if (error) {
|
|
29875
|
+
next(new BadRequestError76(error.message));
|
|
29876
|
+
return;
|
|
29877
|
+
}
|
|
29878
|
+
try {
|
|
29879
|
+
const plantillas = await _getAllPlantillas({
|
|
29880
|
+
search,
|
|
29881
|
+
page,
|
|
29882
|
+
limit,
|
|
29883
|
+
org
|
|
29884
|
+
});
|
|
29885
|
+
res.json(plantillas);
|
|
29886
|
+
return;
|
|
29887
|
+
} catch (error2) {
|
|
29888
|
+
next(error2);
|
|
29889
|
+
}
|
|
29890
|
+
}
|
|
29891
|
+
async function getPlantillaById(req, res, next) {
|
|
29892
|
+
const id = req.params.id;
|
|
29893
|
+
const validation = Joi42.object({
|
|
29894
|
+
id: Joi42.string().hex().required()
|
|
29895
|
+
});
|
|
29896
|
+
const { error } = validation.validate({ id });
|
|
29897
|
+
if (error) {
|
|
29898
|
+
next(new BadRequestError76(error.message));
|
|
29899
|
+
return;
|
|
29900
|
+
}
|
|
29901
|
+
try {
|
|
29902
|
+
const plantilla = await _getPlantillaById(id);
|
|
29903
|
+
if (!plantilla) {
|
|
29904
|
+
next(new BadRequestError76("Plantilla not found."));
|
|
29905
|
+
return;
|
|
29906
|
+
}
|
|
29907
|
+
res.json(plantilla);
|
|
29908
|
+
return;
|
|
29909
|
+
} catch (error2) {
|
|
29910
|
+
next(error2);
|
|
29911
|
+
}
|
|
29912
|
+
}
|
|
29913
|
+
async function updatePlantilla(req, res, next) {
|
|
29914
|
+
const id = req.params.id;
|
|
29915
|
+
const value = req.body;
|
|
29916
|
+
const validation = Joi42.object({
|
|
29917
|
+
id: Joi42.string().hex().required(),
|
|
29918
|
+
employeeId: Joi42.string().hex().optional().allow(null, ""),
|
|
29919
|
+
status: Joi42.string().optional(),
|
|
29920
|
+
positionTitle: Joi42.string().optional()
|
|
29921
|
+
});
|
|
29922
|
+
const { error } = validation.validate({ id, ...value });
|
|
29923
|
+
if (error) {
|
|
29924
|
+
next(new BadRequestError76(error.message));
|
|
29925
|
+
return;
|
|
29926
|
+
}
|
|
29927
|
+
try {
|
|
29928
|
+
const result = await _updatePlantillaById(id, value);
|
|
29929
|
+
if (result.matchedCount === 0) {
|
|
29930
|
+
next(new BadRequestError76("Plantilla not found."));
|
|
29931
|
+
return;
|
|
29932
|
+
}
|
|
29933
|
+
res.json({ message: "Plantilla updated successfully" });
|
|
29934
|
+
return;
|
|
29935
|
+
} catch (error2) {
|
|
29936
|
+
next(error2);
|
|
29937
|
+
}
|
|
29938
|
+
}
|
|
29939
|
+
async function deletePlantilla(req, res, next) {
|
|
29940
|
+
const id = req.params.id;
|
|
29941
|
+
const validation = Joi42.object({
|
|
29942
|
+
id: Joi42.string().hex().required()
|
|
29943
|
+
});
|
|
29944
|
+
const { error } = validation.validate({ id });
|
|
29945
|
+
if (error) {
|
|
29946
|
+
next(new BadRequestError76(error.message));
|
|
29947
|
+
return;
|
|
29948
|
+
}
|
|
29949
|
+
try {
|
|
29950
|
+
const result = await _deletePlantillaById(id);
|
|
29951
|
+
if (result.matchedCount === 0) {
|
|
29952
|
+
next(new BadRequestError76("Plantilla not found."));
|
|
29953
|
+
return;
|
|
29954
|
+
}
|
|
29955
|
+
res.json({ message: "Plantilla deleted successfully" });
|
|
29956
|
+
return;
|
|
29957
|
+
} catch (error2) {
|
|
29958
|
+
next(error2);
|
|
29959
|
+
}
|
|
29960
|
+
}
|
|
29961
|
+
return {
|
|
29962
|
+
createPlantilla,
|
|
29963
|
+
getAllPlantillas,
|
|
29964
|
+
getPlantillaById,
|
|
29965
|
+
updatePlantilla,
|
|
29966
|
+
deletePlantilla
|
|
29967
|
+
};
|
|
29968
|
+
}
|
|
29275
29969
|
export {
|
|
29276
29970
|
ACCESS_TOKEN_EXPIRY,
|
|
29277
29971
|
ACCESS_TOKEN_SECRET,
|
|
@@ -29302,6 +29996,7 @@ export {
|
|
|
29302
29996
|
MOrder,
|
|
29303
29997
|
MOrg,
|
|
29304
29998
|
MPaymentMethod,
|
|
29999
|
+
MPlantilla,
|
|
29305
30000
|
MPromoCode,
|
|
29306
30001
|
MRegion,
|
|
29307
30002
|
MRole,
|
|
@@ -29339,6 +30034,7 @@ export {
|
|
|
29339
30034
|
schemaBuilding,
|
|
29340
30035
|
schemaBuildingUnit,
|
|
29341
30036
|
schemaDivision,
|
|
30037
|
+
schemaPlantilla,
|
|
29342
30038
|
schemaRegion,
|
|
29343
30039
|
schemaSchool,
|
|
29344
30040
|
schemaStockCard,
|
|
@@ -29363,6 +30059,7 @@ export {
|
|
|
29363
30059
|
useFileController,
|
|
29364
30060
|
useFileRepo,
|
|
29365
30061
|
useFileService,
|
|
30062
|
+
useGitHubService,
|
|
29366
30063
|
useInvoiceController,
|
|
29367
30064
|
useInvoiceModel,
|
|
29368
30065
|
useInvoiceRepo,
|
|
@@ -29381,6 +30078,8 @@ export {
|
|
|
29381
30078
|
usePaymentModel,
|
|
29382
30079
|
usePaymentRepo,
|
|
29383
30080
|
usePaypalService,
|
|
30081
|
+
usePlantillaController,
|
|
30082
|
+
usePlantillaRepo,
|
|
29384
30083
|
usePriceController,
|
|
29385
30084
|
usePriceModel,
|
|
29386
30085
|
usePriceRepo,
|
|
@@ -29403,6 +30102,7 @@ export {
|
|
|
29403
30102
|
useUserController,
|
|
29404
30103
|
useUserRepo,
|
|
29405
30104
|
useUserService,
|
|
30105
|
+
useUtilController,
|
|
29406
30106
|
useVerificationController,
|
|
29407
30107
|
useVerificationRepo,
|
|
29408
30108
|
useVerificationService,
|