@ifecodes/backend-template 1.1.8 → 1.4.0
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/LICENSE +201 -0
- package/README.md +423 -365
- package/bin/cli.js +1276 -836
- package/bin/lib/microservice-config.js +155 -150
- package/bin/lib/prompts.js +277 -241
- package/bin/lib/readme-generator.js +364 -335
- package/bin/lib/service-setup.js +901 -679
- package/package.json +64 -55
- package/template/base/js/.env.example +5 -5
- package/template/base/js/.eslintrc.json +10 -13
- package/template/base/js/.husky/pre-commit +1 -7
- package/template/base/js/.prettierrc +7 -7
- package/template/base/js/eslint.config.js +33 -31
- package/template/base/js/package.json +29 -28
- package/template/base/js/src/app.js +20 -15
- package/template/base/js/src/config/env.js +32 -2
- package/template/base/js/src/config/index.js +2 -2
- package/template/base/js/src/docs/index.js +5 -0
- package/template/base/js/src/docs/route-registry.js +63 -0
- package/template/base/js/src/middlewares/error-handler.middleware.js +22 -0
- package/template/base/js/src/middlewares/index.js +9 -3
- package/template/base/js/src/middlewares/method-not-allowed.middleware.js +8 -2
- package/template/base/js/src/middlewares/not-found.middleware.js +4 -1
- package/template/base/js/src/middlewares/observability.middleware.js +24 -0
- package/template/base/js/src/middlewares/root.middleware.js +7 -5
- package/template/base/js/src/middlewares/validation.middleware.js +39 -0
- package/template/base/js/src/modules/index.js +8 -8
- package/template/base/js/src/modules/v1/health/health.controller.auth.js +29 -0
- package/template/base/js/src/modules/v1/health/health.controller.js +4 -4
- package/template/base/js/src/modules/v1/health/health.route.js +70 -5
- package/template/base/js/src/modules/v1/health/index.js +1 -1
- package/template/base/js/src/modules/v1/index.js +3 -3
- package/template/base/js/src/routes.js +13 -6
- package/template/base/js/src/server.js +18 -18
- package/template/base/js/src/utils/http-error.js +27 -6
- package/template/base/js/src/utils/index.js +28 -22
- package/template/base/js/src/utils/logger.js +57 -67
- package/template/base/ts/.eslintrc.json +13 -17
- package/template/base/ts/.prettierrc +7 -7
- package/template/base/ts/eslint.config.js +33 -33
- package/template/base/ts/package.json +41 -39
- package/template/base/ts/src/app.ts +20 -15
- package/template/base/ts/src/config/db.ts +4 -4
- package/template/base/ts/src/config/env.ts +40 -10
- package/template/base/ts/src/config/index.ts +2 -2
- package/template/base/ts/src/docs/index.ts +3 -0
- package/template/base/ts/src/docs/route-registry.ts +98 -0
- package/template/base/ts/src/middlewares/error-handler.middleware.ts +26 -0
- package/template/base/ts/src/middlewares/index.ts +6 -3
- package/template/base/ts/src/middlewares/method-not-allowed.middleware.ts +23 -16
- package/template/base/ts/src/middlewares/not-found.middleware.ts +10 -8
- package/template/base/ts/src/middlewares/observability.middleware.ts +25 -0
- package/template/base/ts/src/middlewares/root.middleware.ts +16 -14
- package/template/base/ts/src/middlewares/validation.middleware.ts +46 -0
- package/template/base/ts/src/modules/index.ts +8 -8
- package/template/base/ts/src/modules/v1/health/health.controller.auth.ts +26 -0
- package/template/base/ts/src/modules/v1/health/health.controller.ts +18 -18
- package/template/base/ts/src/modules/v1/health/health.route.ts +68 -9
- package/template/base/ts/src/modules/v1/health/index.ts +1 -1
- package/template/base/ts/src/modules/v1/index.ts +8 -8
- package/template/base/ts/src/routes.ts +23 -15
- package/template/base/ts/src/server.ts +19 -19
- package/template/base/ts/src/utils/http-error.ts +63 -45
- package/template/base/ts/src/utils/index.ts +14 -11
- package/template/base/ts/src/utils/logger.ts +58 -68
- package/template/base/ts/tsconfig.json +21 -22
- package/template/features/auth/argon2/inject.js +50 -50
- package/template/features/auth/base/health-openapi.ts +62 -0
- package/template/features/auth/base/inject.js +174 -172
- package/template/features/auth/bcrypt/inject.js +40 -40
- package/template/features/auth/models/user.model.js +24 -24
- package/template/features/auth/models/user.model.ts +1 -1
- package/template/features/auth/modules/auth.controller.js +21 -21
- package/template/features/auth/modules/auth.controller.ts +28 -20
- package/template/features/auth/modules/auth.routes.js +89 -10
- package/template/features/auth/modules/auth.routes.ts +86 -11
- package/template/features/auth/modules/auth.service.js +29 -29
- package/template/features/auth/modules/auth.service.ts +38 -38
- package/template/features/auth/modules/index.js +1 -1
- package/template/features/auth/utils/hash.ts +20 -20
- package/template/features/auth/utils/jwt.js +12 -12
- package/template/features/cors/inject.js +14 -13
- package/template/features/helmet/inject.js +7 -6
- package/template/features/morgan/inject.js +8 -7
- package/template/features/rate-limit/inject.js +7 -6
- package/template/gateway/js/app.js +42 -42
- package/template/gateway/js/inject.js +33 -31
- package/template/gateway/js/server.js +19 -19
- package/template/gateway/ts/app.ts +43 -43
- package/template/gateway/ts/inject.js +33 -33
- package/template/gateway/ts/server.ts +19 -19
- package/template/microservice/docker/docker-compose.yml +5 -5
- package/template/microservice/nodocker/pm2.config.js +3 -3
|
@@ -1,45 +1,63 @@
|
|
|
1
|
-
export class HttpError extends Error {
|
|
2
|
-
public status: number;
|
|
3
|
-
|
|
4
|
-
constructor(status: number, message: string) {
|
|
5
|
-
super(message);
|
|
6
|
-
this.status = status;
|
|
7
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export class BadRequestError extends HttpError {
|
|
12
|
-
constructor(message = "Bad Request") {
|
|
13
|
-
super(400, message);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class
|
|
18
|
-
constructor(message = "
|
|
19
|
-
super(
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export class
|
|
24
|
-
constructor(message = "
|
|
25
|
-
super(
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export class
|
|
30
|
-
constructor(message = "
|
|
31
|
-
super(
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export class
|
|
36
|
-
constructor(message = "
|
|
37
|
-
super(
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export class
|
|
42
|
-
constructor(message = "
|
|
43
|
-
super(
|
|
44
|
-
}
|
|
45
|
-
}
|
|
1
|
+
export class HttpError extends Error {
|
|
2
|
+
public status: number;
|
|
3
|
+
|
|
4
|
+
constructor(status: number, message: string) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.status = status;
|
|
7
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class BadRequestError extends HttpError {
|
|
12
|
+
constructor(message = "Bad Request") {
|
|
13
|
+
super(400, message);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class UnprocessableEntityError extends HttpError {
|
|
18
|
+
constructor(message = "Unprocessable Entity") {
|
|
19
|
+
super(422, message);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class UnauthorizedError extends HttpError {
|
|
24
|
+
constructor(message = "Unauthorized") {
|
|
25
|
+
super(401, message);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class ForbiddenError extends HttpError {
|
|
30
|
+
constructor(message = "Forbidden") {
|
|
31
|
+
super(403, message);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class NotFoundError extends HttpError {
|
|
36
|
+
constructor(message = "Not Found") {
|
|
37
|
+
super(404, message);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class ConflictError extends HttpError {
|
|
42
|
+
constructor(message = "Conflict") {
|
|
43
|
+
super(409, message);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class TooManyRequestsError extends HttpError {
|
|
48
|
+
constructor(message = "Too Many Requests") {
|
|
49
|
+
super(429, message);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export class BadGatewayError extends HttpError {
|
|
54
|
+
constructor(message = "Bad Gateway") {
|
|
55
|
+
super(502, message);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export class InternalServerError extends HttpError {
|
|
60
|
+
constructor(message = "Internal Server Error") {
|
|
61
|
+
super(500, message);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
export {
|
|
2
|
-
HttpError,
|
|
3
|
-
BadRequestError,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
export {
|
|
2
|
+
HttpError,
|
|
3
|
+
BadRequestError,
|
|
4
|
+
UnprocessableEntityError,
|
|
5
|
+
UnauthorizedError,
|
|
6
|
+
ForbiddenError,
|
|
7
|
+
NotFoundError,
|
|
8
|
+
ConflictError,
|
|
9
|
+
TooManyRequestsError,
|
|
10
|
+
BadGatewayError,
|
|
11
|
+
InternalServerError,
|
|
12
|
+
} from "./http-error";
|
|
13
|
+
|
|
14
|
+
export { default as logger } from "./logger";
|
|
@@ -1,68 +1,58 @@
|
|
|
1
|
-
import { ENV } from "@/config";
|
|
2
|
-
|
|
3
|
-
// ANSI color codes for terminal output
|
|
4
|
-
const colors = {
|
|
5
|
-
reset: "\x1b[0m",
|
|
6
|
-
blue: "\x1b[34m",
|
|
7
|
-
cyan: "\x1b[36m",
|
|
8
|
-
yellow: "\x1b[33m",
|
|
9
|
-
red: "\x1b[31m",
|
|
10
|
-
bold: "\x1b[1m",
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
function format(tag: string, color: string) {
|
|
14
|
-
return `${color}${colors.bold}[${tag}]${colors.reset}`;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function getEnvironment() {
|
|
18
|
-
return ENV.NODE_ENV === "development" || ENV.NODE_ENV === "staging"
|
|
19
|
-
? "development"
|
|
20
|
-
: ENV.NODE_ENV;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (
|
|
49
|
-
console.
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (
|
|
54
|
-
console.
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
console.warn(format(tag, colors.yellow), ...args);
|
|
60
|
-
},
|
|
61
|
-
|
|
62
|
-
error(tag: string, ...args: unknown[]) {
|
|
63
|
-
if (getEnvironment() !== "development") return;
|
|
64
|
-
console.error(format(tag, colors.red), ...args);
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export default logger;
|
|
1
|
+
import { ENV } from "@/config";
|
|
2
|
+
|
|
3
|
+
// ANSI color codes for terminal output
|
|
4
|
+
const colors = {
|
|
5
|
+
reset: "\x1b[0m",
|
|
6
|
+
blue: "\x1b[34m",
|
|
7
|
+
cyan: "\x1b[36m",
|
|
8
|
+
yellow: "\x1b[33m",
|
|
9
|
+
red: "\x1b[31m",
|
|
10
|
+
bold: "\x1b[1m",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
function format(tag: string, color: string) {
|
|
14
|
+
return `${color}${colors.bold}[${tag}]${colors.reset}`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getEnvironment() {
|
|
18
|
+
return ENV.NODE_ENV === "development" || ENV.NODE_ENV === "staging"
|
|
19
|
+
? "development"
|
|
20
|
+
: ENV.NODE_ENV;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function shouldLog(level: "log" | "info" | "warn" | "error") {
|
|
24
|
+
if (level === "log") {
|
|
25
|
+
return getEnvironment() === "development";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log(
|
|
32
|
+
format("logger", colors.blue),
|
|
33
|
+
`Logger initialized for ${getEnvironment()} environment.`,
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const logger = {
|
|
37
|
+
log(tag: string, ...args: unknown[]) {
|
|
38
|
+
if (!shouldLog("log")) return;
|
|
39
|
+
console.log(format(tag, colors.blue), ...args);
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
info(tag: string, ...args: unknown[]) {
|
|
43
|
+
if (!shouldLog("info")) return;
|
|
44
|
+
console.info(format(tag, colors.cyan), ...args);
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
warn(tag: string, ...args: unknown[]) {
|
|
48
|
+
if (!shouldLog("warn")) return;
|
|
49
|
+
console.warn(format(tag, colors.yellow), ...args);
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
error(tag: string, ...args: unknown[]) {
|
|
53
|
+
if (!shouldLog("error")) return;
|
|
54
|
+
console.error(format(tag, colors.red), ...args);
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export default logger;
|
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
{
|
|
2
|
-
// Visit https://aka.ms/tsconfig to read more about this file
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"target": "ES2020",
|
|
5
|
-
"module": "CommonJS",
|
|
6
|
-
"rootDir": "src",
|
|
7
|
-
"outDir": "dist",
|
|
8
|
-
|
|
9
|
-
"strict": true,
|
|
10
|
-
"noImplicitAny": true,
|
|
11
|
-
"esModuleInterop": true,
|
|
12
|
-
"skipLibCheck": true,
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
}
|
|
1
|
+
{
|
|
2
|
+
// Visit https://aka.ms/tsconfig to read more about this file
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"target": "ES2020",
|
|
5
|
+
"module": "CommonJS",
|
|
6
|
+
"rootDir": "src",
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
|
|
9
|
+
"strict": true,
|
|
10
|
+
"noImplicitAny": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
|
|
14
|
+
"paths": {
|
|
15
|
+
"@/*": ["./src/*"]
|
|
16
|
+
},
|
|
17
|
+
"types": ["node"]
|
|
18
|
+
},
|
|
19
|
+
"include": ["src"],
|
|
20
|
+
"exclude": ["node_modules", "dist"]
|
|
21
|
+
}
|
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
export const deps = ["argon2"];
|
|
2
|
-
|
|
3
|
-
export const getFiles = (language = "typescript") => {
|
|
4
|
-
const ext = language === "javascript" ? ".js" : ".ts";
|
|
5
|
-
|
|
6
|
-
const tsContent = `import argon2 from "argon2";
|
|
7
|
-
|
|
8
|
-
const HASH_OPTIONS = {
|
|
9
|
-
type: argon2.argon2id,
|
|
10
|
-
memoryCost: 2 ** 16,
|
|
11
|
-
timeCost: 3,
|
|
12
|
-
parallelism: 1,
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const hashPassword = async (password: string): Promise<string> => {
|
|
16
|
-
return argon2.hash(password, HASH_OPTIONS);
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export const verifyPassword = async (
|
|
20
|
-
hash: string,
|
|
21
|
-
password: string,
|
|
22
|
-
): Promise<boolean> => {
|
|
23
|
-
return argon2.verify(hash, password);
|
|
24
|
-
};
|
|
25
|
-
`;
|
|
26
|
-
|
|
27
|
-
const jsContent = `const argon2 = require("argon2");
|
|
28
|
-
|
|
29
|
-
const HASH_OPTIONS = {
|
|
30
|
-
type: argon2.argon2id,
|
|
31
|
-
memoryCost: 2 ** 16,
|
|
32
|
-
timeCost: 3,
|
|
33
|
-
parallelism: 1,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
async function hashPassword(password) {
|
|
37
|
-
return argon2.hash(password, HASH_OPTIONS);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async function verifyPassword(hash, password) {
|
|
41
|
-
return argon2.verify(hash, password);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
module.exports = { hashPassword, verifyPassword };
|
|
45
|
-
`;
|
|
46
|
-
|
|
47
|
-
return {
|
|
48
|
-
[`src/utils/hash${ext}`]: language === "javascript" ? jsContent : tsContent,
|
|
49
|
-
};
|
|
50
|
-
};
|
|
1
|
+
export const deps = ["argon2"];
|
|
2
|
+
|
|
3
|
+
export const getFiles = (language = "typescript") => {
|
|
4
|
+
const ext = language === "javascript" ? ".js" : ".ts";
|
|
5
|
+
|
|
6
|
+
const tsContent = `import argon2 from "argon2";
|
|
7
|
+
|
|
8
|
+
const HASH_OPTIONS = {
|
|
9
|
+
type: argon2.argon2id,
|
|
10
|
+
memoryCost: 2 ** 16,
|
|
11
|
+
timeCost: 3,
|
|
12
|
+
parallelism: 1,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const hashPassword = async (password: string): Promise<string> => {
|
|
16
|
+
return argon2.hash(password, HASH_OPTIONS);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const verifyPassword = async (
|
|
20
|
+
hash: string,
|
|
21
|
+
password: string,
|
|
22
|
+
): Promise<boolean> => {
|
|
23
|
+
return argon2.verify(hash, password);
|
|
24
|
+
};
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
const jsContent = `const argon2 = require("argon2");
|
|
28
|
+
|
|
29
|
+
const HASH_OPTIONS = {
|
|
30
|
+
type: argon2.argon2id,
|
|
31
|
+
memoryCost: 2 ** 16,
|
|
32
|
+
timeCost: 3,
|
|
33
|
+
parallelism: 1,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
async function hashPassword(password) {
|
|
37
|
+
return argon2.hash(password, HASH_OPTIONS);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function verifyPassword(hash, password) {
|
|
41
|
+
return argon2.verify(hash, password);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = { hashPassword, verifyPassword };
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
[`src/utils/hash${ext}`]: language === "javascript" ? jsContent : tsContent,
|
|
49
|
+
};
|
|
50
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Enhanced OpenAPI spec for health endpoint when auth is enabled
|
|
2
|
+
export const healthOpenApiWithMongo = {
|
|
3
|
+
get: {
|
|
4
|
+
tags: ["Health"],
|
|
5
|
+
summary: "Health check with MongoDB status",
|
|
6
|
+
description:
|
|
7
|
+
"Returns API health, runtime metrics, and MongoDB connection status.",
|
|
8
|
+
parameters: [
|
|
9
|
+
{
|
|
10
|
+
name: "verbose",
|
|
11
|
+
in: "query",
|
|
12
|
+
required: false,
|
|
13
|
+
schema: { type: "boolean" },
|
|
14
|
+
description: "Optional verbose mode for richer diagnostics.",
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
responses: {
|
|
18
|
+
"200": {
|
|
19
|
+
description: "Healthy response",
|
|
20
|
+
content: {
|
|
21
|
+
"application/json": {
|
|
22
|
+
schema: {
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {
|
|
25
|
+
status: { type: "string", enum: ["healthy", "unhealthy"] },
|
|
26
|
+
uptime: { type: "number" },
|
|
27
|
+
timestamp: { type: "string" },
|
|
28
|
+
services: {
|
|
29
|
+
type: "object",
|
|
30
|
+
properties: {
|
|
31
|
+
mongodb: {
|
|
32
|
+
type: "string",
|
|
33
|
+
enum: ["connected", "disconnected"],
|
|
34
|
+
},
|
|
35
|
+
memory: {
|
|
36
|
+
type: "object",
|
|
37
|
+
properties: {
|
|
38
|
+
rss: { type: "number" },
|
|
39
|
+
heapUsed: { type: "number" },
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
failed: {
|
|
45
|
+
type: "array",
|
|
46
|
+
items: { type: "string" },
|
|
47
|
+
description: "List of failed services",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
"400": {
|
|
55
|
+
description: "Validation error",
|
|
56
|
+
},
|
|
57
|
+
"503": {
|
|
58
|
+
description: "Service unhealthy (when MongoDB is down)",
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
};
|