@alacard-project/shared 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dto/index.d.ts +1 -0
- package/dist/dto/index.js +1 -0
- package/dist/dto/index.js.map +1 -1
- package/dist/dto/invoice.dto.d.ts +12 -0
- package/dist/dto/invoice.dto.js +62 -0
- package/dist/dto/invoice.dto.js.map +1 -0
- package/dist/enums/auth.enum.d.ts +2 -3
- package/dist/enums/auth.enum.js +2 -3
- package/dist/enums/auth.enum.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/resilience/circuit-breaker.service.d.ts +2 -3
- package/dist/resilience/circuit-breaker.service.js +9 -15
- package/dist/resilience/circuit-breaker.service.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/{filters/http-exception.filter.js → utils/filters.js} +3 -12
- package/dist/utils/filters.js.map +1 -0
- package/dist/{interceptors/transform.interceptor.d.ts → utils/interceptors.d.ts} +0 -1
- package/dist/{interceptors/transform.interceptor.js → utils/interceptors.js} +3 -3
- package/dist/utils/interceptors.js.map +1 -0
- package/dist/utils/tracing.utils.js +7 -0
- package/dist/utils/tracing.utils.js.map +1 -0
- package/package.json +25 -27
- package/dist/config/base-config.service.d.ts +0 -25
- package/dist/config/base-config.service.js +0 -87
- package/dist/config/base-config.service.js.map +0 -1
- package/dist/constants/logging.constants.d.ts +0 -24
- package/dist/constants/logging.constants.js +0 -28
- package/dist/constants/logging.constants.js.map +0 -1
- package/dist/constants/monitoring.constants.d.ts +0 -51
- package/dist/constants/monitoring.constants.js +0 -55
- package/dist/constants/monitoring.constants.js.map +0 -1
- package/dist/constants/tokens.constants.d.ts +0 -6
- package/dist/constants/tokens.constants.js +0 -10
- package/dist/constants/tokens.constants.js.map +0 -1
- package/dist/filters/http-exception.filter.js.map +0 -1
- package/dist/filters/index.d.ts +0 -1
- package/dist/filters/index.js +0 -18
- package/dist/filters/index.js.map +0 -1
- package/dist/interceptors/http-logging.interceptor.d.ts +0 -10
- package/dist/interceptors/http-logging.interceptor.js +0 -74
- package/dist/interceptors/http-logging.interceptor.js.map +0 -1
- package/dist/interceptors/index.d.ts +0 -2
- package/dist/interceptors/index.js +0 -19
- package/dist/interceptors/index.js.map +0 -1
- package/dist/interceptors/logging.interceptor.d.ts +0 -6
- package/dist/interceptors/logging.interceptor.js +0 -41
- package/dist/interceptors/logging.interceptor.js.map +0 -1
- package/dist/interceptors/transform.interceptor.js.map +0 -1
- package/dist/observability/index.d.ts +0 -2
- package/dist/observability/index.js +0 -19
- package/dist/observability/index.js.map +0 -1
- package/dist/observability/metrics/metrics.module.d.ts +0 -2
- package/dist/observability/metrics/metrics.module.js +0 -28
- package/dist/observability/metrics/metrics.module.js.map +0 -1
- package/dist/observability/tracing.js +0 -28
- package/dist/observability/tracing.js.map +0 -1
- package/dist/utils/logging-client.d.ts +0 -9
- package/dist/utils/logging-client.js +0 -58
- package/dist/utils/logging-client.js.map +0 -1
- package/dist/utils/prometheus.utils.d.ts +0 -9
- package/dist/utils/prometheus.utils.js +0 -66
- package/dist/utils/prometheus.utils.js.map +0 -1
- package/proto/auth.proto +0 -123
- package/proto/card.proto +0 -43
- package/proto/client.proto +0 -45
- package/proto/config.proto +0 -39
- package/proto/dbf.proto +0 -183
- package/proto/logging.proto +0 -143
- package/proto/partner.proto +0 -18
- package/proto/terminal.proto +0 -18
- package/proto/transaction.proto +0 -45
- package/proto/user.proto +0 -122
- package/src/constants/auth-config.constants.ts +0 -16
- package/src/constants/auth.constants.ts +0 -50
- package/src/constants/common.constants.ts +0 -16
- package/src/constants/env.constants.ts +0 -49
- package/src/constants/error-messages.ts +0 -10
- package/src/constants/grpc.constants.ts +0 -43
- package/src/constants/http.constants.ts +0 -11
- package/src/constants/index.ts +0 -11
- package/src/constants/logging-messages.constants.ts +0 -60
- package/src/constants/microservices.constants.ts +0 -62
- package/src/constants/queue.constants.ts +0 -8
- package/src/constants/routes.constants.ts +0 -21
- package/src/contracts/auth.contract.ts +0 -146
- package/src/contracts/config.contract.ts +0 -14
- package/src/contracts/index.ts +0 -14
- package/src/contracts/logging.contract.ts +0 -115
- package/src/contracts/token.contract.ts +0 -47
- package/src/decorators/index.ts +0 -3
- package/src/decorators/permissions.decorator.ts +0 -5
- package/src/decorators/roles.decorator.ts +0 -5
- package/src/decorators/scopes.decorator.ts +0 -4
- package/src/dto/account.dto.ts +0 -28
- package/src/dto/auth.dto.ts +0 -233
- package/src/dto/card.dto.ts +0 -64
- package/src/dto/client.dto.ts +0 -137
- package/src/dto/index.ts +0 -8
- package/src/dto/logging.dto.ts +0 -101
- package/src/dto/partner.dto.ts +0 -18
- package/src/dto/transaction.dto.ts +0 -52
- package/src/dto/user.dto.ts +0 -28
- package/src/enums/auth.enum.ts +0 -13
- package/src/enums/env.enum.ts +0 -7
- package/src/enums/error.enum.ts +0 -28
- package/src/enums/events.enum.ts +0 -22
- package/src/enums/health.enum.ts +0 -7
- package/src/enums/iam.enum.ts +0 -28
- package/src/enums/index.ts +0 -10
- package/src/enums/logging.enum.ts +0 -7
- package/src/enums/notification.enum.ts +0 -5
- package/src/enums/permission.enum.ts +0 -31
- package/src/enums/user.enum.ts +0 -27
- package/src/errors/app.error.ts +0 -33
- package/src/errors/error-map.ts +0 -105
- package/src/filters/http-exception.filter.ts +0 -49
- package/src/filters/index.ts +0 -2
- package/src/index.ts +0 -17
- package/src/interceptors/index.ts +0 -3
- package/src/interceptors/logging.interceptor.ts +0 -37
- package/src/interceptors/transform.interceptor.ts +0 -21
- package/src/observability/index.ts +0 -3
- package/src/observability/metrics/metrics.module.ts +0 -16
- package/src/observability/tracing.ts +0 -33
- package/src/resilience/circuit-breaker.service.ts +0 -46
- package/src/resilience/resilience.module.ts +0 -9
- package/src/types/auth.types.ts +0 -38
- package/src/types/common.types.ts +0 -18
- package/src/types/config.types.ts +0 -32
- package/src/types/iam.types.ts +0 -78
- package/src/types/index.ts +0 -6
- package/src/types/monitoring.types.ts +0 -77
- package/src/types/user.types.ts +0 -11
- package/src/utils/app.utils.ts +0 -52
- package/src/utils/health.utils.ts +0 -24
- package/src/utils/proto-path.ts +0 -21
- package/src/utils/user.utils.ts +0 -3
- package/tsconfig.json +0 -28
- /package/dist/{filters/http-exception.filter.d.ts → utils/filters.d.ts} +0 -0
- /package/dist/{observability/tracing.d.ts → utils/tracing.utils.d.ts} +0 -0
package/src/errors/error-map.ts
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { ErrorCode } from '../enums/error.enum';
|
|
2
|
-
|
|
3
|
-
export interface ErrorDetail {
|
|
4
|
-
message: string;
|
|
5
|
-
statusCode: number;
|
|
6
|
-
description?: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const ERROR_MAP: Record<ErrorCode, ErrorDetail> = {
|
|
10
|
-
[ErrorCode.AUTH_USER_NOT_FOUND]: {
|
|
11
|
-
message: 'User not found',
|
|
12
|
-
statusCode: 404,
|
|
13
|
-
description: 'The requested user could not be found in the system.',
|
|
14
|
-
},
|
|
15
|
-
[ErrorCode.AUTH_USER_ALREADY_EXISTS]: {
|
|
16
|
-
message: 'User already exists',
|
|
17
|
-
statusCode: 409,
|
|
18
|
-
description: 'A user with this email already exists.',
|
|
19
|
-
},
|
|
20
|
-
[ErrorCode.AUTH_USER_INACTIVE]: {
|
|
21
|
-
message: 'User is inactive',
|
|
22
|
-
statusCode: 403,
|
|
23
|
-
description: 'The user account is currently deactivated.',
|
|
24
|
-
},
|
|
25
|
-
[ErrorCode.AUTH_INVALID_PASSWORD]: {
|
|
26
|
-
message: 'Invalid password',
|
|
27
|
-
statusCode: 401,
|
|
28
|
-
description: 'The provided password does not match.',
|
|
29
|
-
},
|
|
30
|
-
[ErrorCode.AUTH_INVALID_TOKEN]: {
|
|
31
|
-
message: 'Invalid token',
|
|
32
|
-
statusCode: 401,
|
|
33
|
-
description: 'The provided authentication token is invalid or malformed.',
|
|
34
|
-
},
|
|
35
|
-
[ErrorCode.AUTH_TOKEN_EXPIRED]: {
|
|
36
|
-
message: 'Token expired',
|
|
37
|
-
statusCode: 401,
|
|
38
|
-
description: 'The authentication token has expired. Please log in again.',
|
|
39
|
-
},
|
|
40
|
-
[ErrorCode.AUTH_ACCESS_DENIED]: {
|
|
41
|
-
message: 'Access denied',
|
|
42
|
-
statusCode: 403,
|
|
43
|
-
description: 'You do not have permission to perform this action.',
|
|
44
|
-
},
|
|
45
|
-
[ErrorCode.AUTH_INSUFFICIENT_SCOPES]: {
|
|
46
|
-
message: 'Insufficient scopes',
|
|
47
|
-
statusCode: 403,
|
|
48
|
-
description: 'Your token does not have the required scopes for this resource.',
|
|
49
|
-
},
|
|
50
|
-
[ErrorCode.AUTH_INVALID_CREDENTIALS]: {
|
|
51
|
-
message: 'Invalid credentials',
|
|
52
|
-
statusCode: 401,
|
|
53
|
-
description: 'The email or password you entered is incorrect.',
|
|
54
|
-
},
|
|
55
|
-
[ErrorCode.CONFIG_NOT_FOUND]: {
|
|
56
|
-
message: 'Configuration not found',
|
|
57
|
-
statusCode: 404,
|
|
58
|
-
description: 'The requested configuration key was not found.',
|
|
59
|
-
},
|
|
60
|
-
[ErrorCode.CONFIG_LOAD_FAILED]: {
|
|
61
|
-
message: 'Configuration load failed',
|
|
62
|
-
statusCode: 500,
|
|
63
|
-
description: 'Failed to load configuration from the source.',
|
|
64
|
-
},
|
|
65
|
-
[ErrorCode.LOG_WRITE_FAILED]: {
|
|
66
|
-
message: 'Log write failed',
|
|
67
|
-
statusCode: 500,
|
|
68
|
-
description: 'Failed to write log to the destination.',
|
|
69
|
-
},
|
|
70
|
-
[ErrorCode.LOG_READ_FAILED]: {
|
|
71
|
-
message: 'Log read failed',
|
|
72
|
-
statusCode: 500,
|
|
73
|
-
description: 'Failed to read logs from the source.',
|
|
74
|
-
},
|
|
75
|
-
[ErrorCode.INTERNAL_SERVER_ERROR]: {
|
|
76
|
-
message: 'Internal server error',
|
|
77
|
-
statusCode: 500,
|
|
78
|
-
description: 'An unexpected error occurred on the server.',
|
|
79
|
-
},
|
|
80
|
-
[ErrorCode.BAD_REQUEST]: {
|
|
81
|
-
message: 'Bad request',
|
|
82
|
-
statusCode: 400,
|
|
83
|
-
description: 'The request is invalid or cannot be served.',
|
|
84
|
-
},
|
|
85
|
-
[ErrorCode.NOT_FOUND]: {
|
|
86
|
-
message: 'Resource not found',
|
|
87
|
-
statusCode: 404,
|
|
88
|
-
description: 'The requested resource could not be found.',
|
|
89
|
-
},
|
|
90
|
-
[ErrorCode.VALIDATION_ERROR]: {
|
|
91
|
-
message: 'Validation error',
|
|
92
|
-
statusCode: 422,
|
|
93
|
-
description: 'The provided data failed validation.',
|
|
94
|
-
},
|
|
95
|
-
[ErrorCode.AUTH_USER_BLOCKED]: {
|
|
96
|
-
message: 'User blocked',
|
|
97
|
-
statusCode: 403,
|
|
98
|
-
description: 'The user account has been blocked.',
|
|
99
|
-
},
|
|
100
|
-
[ErrorCode.INVALID_TOKEN]: {
|
|
101
|
-
message: 'Invalid token',
|
|
102
|
-
statusCode: 401,
|
|
103
|
-
description: 'The provided token is invalid.',
|
|
104
|
-
},
|
|
105
|
-
};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { ExceptionFilter, Catch, ArgumentsHost, HttpException, HttpStatus, Logger } from '@nestjs/common';
|
|
3
|
-
import { Request, Response } from 'express';
|
|
4
|
-
|
|
5
|
-
@Catch()
|
|
6
|
-
export class HttpExceptionFilter implements ExceptionFilter {
|
|
7
|
-
private readonly logger = new Logger(HttpExceptionFilter.name);
|
|
8
|
-
|
|
9
|
-
catch(exception: unknown, host: ArgumentsHost) {
|
|
10
|
-
const ctx = host.switchToHttp();
|
|
11
|
-
const response = ctx.getResponse<Response>();
|
|
12
|
-
const request = ctx.getRequest<Request>();
|
|
13
|
-
|
|
14
|
-
const status =
|
|
15
|
-
exception instanceof HttpException
|
|
16
|
-
? exception.getStatus()
|
|
17
|
-
: HttpStatus.INTERNAL_SERVER_ERROR;
|
|
18
|
-
|
|
19
|
-
const message =
|
|
20
|
-
exception instanceof HttpException
|
|
21
|
-
? exception.getResponse()
|
|
22
|
-
: 'Internal server error';
|
|
23
|
-
|
|
24
|
-
// Determine the actual error message string
|
|
25
|
-
const errorMessage = typeof message === 'string'
|
|
26
|
-
? message
|
|
27
|
-
: (message as any).message || message;
|
|
28
|
-
|
|
29
|
-
// Log the error
|
|
30
|
-
if (status >= 500) {
|
|
31
|
-
this.logger.error(
|
|
32
|
-
`[${request.method}] ${request.url} - ${status} - ${JSON.stringify(errorMessage)}`,
|
|
33
|
-
exception instanceof Error ? exception.stack : '',
|
|
34
|
-
);
|
|
35
|
-
} else {
|
|
36
|
-
this.logger.warn(
|
|
37
|
-
`[${request.method}] ${request.url} - ${status} - ${JSON.stringify(errorMessage)}`,
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
response.status(status).json({
|
|
42
|
-
statusCode: status,
|
|
43
|
-
timestamp: new Date().toISOString(),
|
|
44
|
-
path: request.url,
|
|
45
|
-
method: request.method,
|
|
46
|
-
error: errorMessage,
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
}
|
package/src/filters/index.ts
DELETED
package/src/index.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export * from './enums';
|
|
2
|
-
export * from './constants';
|
|
3
|
-
export * from './types';
|
|
4
|
-
export * from './contracts';
|
|
5
|
-
export * from './dto';
|
|
6
|
-
export * from './errors/app.error';
|
|
7
|
-
export * from './errors/error-map';
|
|
8
|
-
export * from './decorators';
|
|
9
|
-
export * from './utils/proto-path';
|
|
10
|
-
export * from './utils/user.utils';
|
|
11
|
-
export * from './utils/app.utils';
|
|
12
|
-
export * from './utils/health.utils';
|
|
13
|
-
export * from './filters';
|
|
14
|
-
export * from './interceptors';
|
|
15
|
-
export * from './observability';
|
|
16
|
-
export * from './resilience/resilience.module';
|
|
17
|
-
export * from './resilience/circuit-breaker.service';
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, Logger } from '@nestjs/common';
|
|
3
|
-
import { Observable } from 'rxjs';
|
|
4
|
-
import { tap } from 'rxjs/operators';
|
|
5
|
-
import { randomUUID } from 'crypto';
|
|
6
|
-
import { Request, Response } from 'express';
|
|
7
|
-
|
|
8
|
-
@Injectable()
|
|
9
|
-
export class LoggingInterceptor implements NestInterceptor {
|
|
10
|
-
private readonly logger = new Logger(LoggingInterceptor.name);
|
|
11
|
-
|
|
12
|
-
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
|
13
|
-
const httpContext = context.switchToHttp();
|
|
14
|
-
const request = httpContext.getRequest<Request>();
|
|
15
|
-
const response = httpContext.getResponse<Response>();
|
|
16
|
-
|
|
17
|
-
const userAgent = request.get('user-agent') || '';
|
|
18
|
-
const { ip, method, path: url } = request;
|
|
19
|
-
|
|
20
|
-
// Generate or retrieve Trace ID
|
|
21
|
-
const traceId = request.headers['x-request-id'] || randomUUID();
|
|
22
|
-
request.headers['x-request-id'] = traceId as string;
|
|
23
|
-
response.setHeader('x-request-id', traceId);
|
|
24
|
-
|
|
25
|
-
this.logger.log(`[${traceId}] Incoming Request: ${method} ${url} - ${userAgent} ${ip}`);
|
|
26
|
-
|
|
27
|
-
const now = Date.now();
|
|
28
|
-
return next
|
|
29
|
-
.handle()
|
|
30
|
-
.pipe(
|
|
31
|
-
tap(() => {
|
|
32
|
-
const duration = Date.now() - now;
|
|
33
|
-
this.logger.log(`[${traceId}] Response Sent: ${method} ${url} ${response.statusCode} - ${duration}ms`);
|
|
34
|
-
}),
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
|
3
|
-
import { Observable } from 'rxjs';
|
|
4
|
-
import { map } from 'rxjs/operators';
|
|
5
|
-
|
|
6
|
-
export interface Response<T> {
|
|
7
|
-
statusCode: number;
|
|
8
|
-
data: T;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
@Injectable()
|
|
12
|
-
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
|
|
13
|
-
intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
|
|
14
|
-
return next.handle().pipe(
|
|
15
|
-
map(data => ({
|
|
16
|
-
statusCode: context.switchToHttp().getResponse().statusCode,
|
|
17
|
-
data,
|
|
18
|
-
})),
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { Module } from '@nestjs/common';
|
|
3
|
-
import { PrometheusModule } from '@willsoto/nestjs-prometheus';
|
|
4
|
-
|
|
5
|
-
@Module({
|
|
6
|
-
imports: [
|
|
7
|
-
PrometheusModule.register({
|
|
8
|
-
path: '/metrics',
|
|
9
|
-
defaultMetrics: {
|
|
10
|
-
enabled: true,
|
|
11
|
-
},
|
|
12
|
-
}),
|
|
13
|
-
],
|
|
14
|
-
exports: [PrometheusModule],
|
|
15
|
-
})
|
|
16
|
-
export class MetricsModule { }
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
2
|
-
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
|
|
3
|
-
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
|
|
4
|
-
import { Logger } from '@nestjs/common';
|
|
5
|
-
|
|
6
|
-
const logger = new Logger('Tracing');
|
|
7
|
-
|
|
8
|
-
export function initTracing(serviceName: string) {
|
|
9
|
-
const otelExporterOtlpEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://jaeger:4318/v1/traces';
|
|
10
|
-
|
|
11
|
-
const traceExporter = new OTLPTraceExporter({
|
|
12
|
-
url: otelExporterOtlpEndpoint,
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
// Set service name via env var so auto-detection picks it up
|
|
16
|
-
process.env.OTEL_SERVICE_NAME = serviceName;
|
|
17
|
-
|
|
18
|
-
const sdk = new NodeSDK({
|
|
19
|
-
traceExporter,
|
|
20
|
-
instrumentations: [getNodeAutoInstrumentations()],
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
sdk.start();
|
|
24
|
-
|
|
25
|
-
logger.log(`Initialized tracing for ${serviceName} sending to ${otelExporterOtlpEndpoint}`);
|
|
26
|
-
|
|
27
|
-
process.on('SIGTERM', () => {
|
|
28
|
-
sdk.shutdown()
|
|
29
|
-
.then(() => console.log('Tracing terminated'))
|
|
30
|
-
.catch((error) => console.log('Error terminating tracing', error))
|
|
31
|
-
.finally(() => process.exit(0));
|
|
32
|
-
});
|
|
33
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { Injectable, Logger } from '@nestjs/common';
|
|
2
|
-
import CircuitBreaker = require('opossum');
|
|
3
|
-
|
|
4
|
-
@Injectable()
|
|
5
|
-
export class CircuitBreakerService {
|
|
6
|
-
private readonly logger = new Logger(CircuitBreakerService.name);
|
|
7
|
-
private readonly breakers = new Map<string, CircuitBreaker>();
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Execute an async action through a circuit breaker.
|
|
11
|
-
* @param key Unique key for the breaker (e.g., service URL)
|
|
12
|
-
* @param action The async action to execute
|
|
13
|
-
* @param options Circuit Breaker options
|
|
14
|
-
*/
|
|
15
|
-
async execute<T>(
|
|
16
|
-
key: string,
|
|
17
|
-
action: () => Promise<T>,
|
|
18
|
-
options?: CircuitBreaker.Options
|
|
19
|
-
): Promise<T> {
|
|
20
|
-
let breaker = this.breakers.get(key);
|
|
21
|
-
|
|
22
|
-
if (!breaker) {
|
|
23
|
-
const defaultOptions: CircuitBreaker.Options = {
|
|
24
|
-
timeout: 5000,
|
|
25
|
-
errorThresholdPercentage: 50,
|
|
26
|
-
resetTimeout: 10000,
|
|
27
|
-
...options,
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
// Wrap a pass-through function to allow dynamic actions
|
|
31
|
-
const passThrough = async (promiseFactory: () => Promise<T>) => promiseFactory();
|
|
32
|
-
breaker = new CircuitBreaker(passThrough, defaultOptions);
|
|
33
|
-
this.bindEvents(breaker, key);
|
|
34
|
-
this.breakers.set(key, breaker);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return breaker.fire(action) as Promise<T>;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
private bindEvents(breaker: CircuitBreaker, key: string) {
|
|
41
|
-
breaker.on('open', () => this.logger.warn(`Circuit Breaker OPEN for ${key}`));
|
|
42
|
-
breaker.on('halfOpen', () => this.logger.log(`Circuit Breaker HALF-OPEN for ${key}`));
|
|
43
|
-
breaker.on('close', () => this.logger.log(`Circuit Breaker CLOSED for ${key}`));
|
|
44
|
-
breaker.on('fallback', () => this.logger.warn(`Circuit Breaker FALLBACK for ${key}`));
|
|
45
|
-
}
|
|
46
|
-
}
|
package/src/types/auth.types.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { JsonObject, JsonValue } from './common.types';
|
|
2
|
-
import { SubjectType } from '../enums/iam.enum';
|
|
3
|
-
export interface JwtPayload extends JsonObject {
|
|
4
|
-
sub: string;
|
|
5
|
-
email?: string;
|
|
6
|
-
role: string;
|
|
7
|
-
subjectType: SubjectType;
|
|
8
|
-
scopes: string[];
|
|
9
|
-
iat?: number;
|
|
10
|
-
exp?: number;
|
|
11
|
-
iss?: string;
|
|
12
|
-
}
|
|
13
|
-
export interface JwtTokens {
|
|
14
|
-
accessToken: string;
|
|
15
|
-
refreshToken: string;
|
|
16
|
-
expiresIn: number;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface AuthenticatedRequest {
|
|
20
|
-
user: JwtPayload;
|
|
21
|
-
[key: string]: JsonValue;
|
|
22
|
-
}
|
|
23
|
-
export interface ValidateServiceTokenResponse {
|
|
24
|
-
isValid: boolean;
|
|
25
|
-
identityId?: string;
|
|
26
|
-
tokenId?: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface Session {
|
|
30
|
-
sessionId: string;
|
|
31
|
-
identityId: string;
|
|
32
|
-
ipAddress?: string;
|
|
33
|
-
userAgent?: string;
|
|
34
|
-
deviceInfo?: string;
|
|
35
|
-
createdAt: Date;
|
|
36
|
-
expiresAt: Date;
|
|
37
|
-
isRevoked?: boolean;
|
|
38
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export type JsonPrimitive = string | number | boolean | null | undefined;
|
|
2
|
-
|
|
3
|
-
export interface JsonObject {
|
|
4
|
-
[key: string]: JsonValue;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface JsonArray extends Array<JsonValue> { }
|
|
8
|
-
|
|
9
|
-
export type JsonValue =
|
|
10
|
-
| JsonPrimitive
|
|
11
|
-
| JsonObject
|
|
12
|
-
| JsonArray;
|
|
13
|
-
|
|
14
|
-
export interface Metadata {
|
|
15
|
-
[key: string]: JsonValue;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export type MetricType = 'counter' | 'gauge' | 'histogram' | 'summary';
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { Environment } from '../enums/env.enum';
|
|
2
|
-
|
|
3
|
-
export interface IBaseConfig {
|
|
4
|
-
environment: Environment;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface DbConfig {
|
|
8
|
-
url: string;
|
|
9
|
-
poolSize?: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface RedisConfig {
|
|
13
|
-
host: string;
|
|
14
|
-
port: number;
|
|
15
|
-
password?: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface BrokerConfig {
|
|
19
|
-
brokers: string[];
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface AppConfig {
|
|
23
|
-
port: number;
|
|
24
|
-
host?: string;
|
|
25
|
-
serviceName: string;
|
|
26
|
-
environment?: Environment;
|
|
27
|
-
version?: string;
|
|
28
|
-
description?: string;
|
|
29
|
-
databaseUrl?: string;
|
|
30
|
-
rabbitMqUrl?: string;
|
|
31
|
-
[key: string]: any;
|
|
32
|
-
}
|
package/src/types/iam.types.ts
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { SubjectType, IdentityStatus, UserRole, IdentifierType } from '../enums';
|
|
2
|
-
import { JsonValue } from './common.types';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Identity
|
|
6
|
-
* Core identity model for IAM service
|
|
7
|
-
*/
|
|
8
|
-
export interface Identity {
|
|
9
|
-
identityId: string;
|
|
10
|
-
subjectType: SubjectType;
|
|
11
|
-
role: UserRole;
|
|
12
|
-
status: IdentityStatus;
|
|
13
|
-
createdAt?: Date;
|
|
14
|
-
updatedAt?: Date;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Identity Attributes
|
|
19
|
-
* ABAC attributes for fine-grained access control
|
|
20
|
-
*/
|
|
21
|
-
export interface IdentityAttributes {
|
|
22
|
-
department?: string;
|
|
23
|
-
companyId?: string;
|
|
24
|
-
permissions: string[];
|
|
25
|
-
metadata?: Record<string, JsonValue>;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Policy Check Request
|
|
30
|
-
* Request structure for policy engine checks
|
|
31
|
-
*/
|
|
32
|
-
export interface PolicyCheckRequest {
|
|
33
|
-
identityId: string;
|
|
34
|
-
resource: string;
|
|
35
|
-
action: string;
|
|
36
|
-
context?: Record<string, JsonValue>;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Policy Check Response
|
|
41
|
-
*/
|
|
42
|
-
export interface PolicyCheckResponse {
|
|
43
|
-
allowed: boolean;
|
|
44
|
-
reason?: string;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Ownership Check Request
|
|
49
|
-
*/
|
|
50
|
-
export interface OwnershipCheckRequest {
|
|
51
|
-
identityId: string;
|
|
52
|
-
resourceId: string;
|
|
53
|
-
resourceType: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Scope Check Request
|
|
58
|
-
*/
|
|
59
|
-
export interface ScopeCheckRequest {
|
|
60
|
-
identityId: string;
|
|
61
|
-
scope: string;
|
|
62
|
-
context?: Record<string, JsonValue>;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Credential Model
|
|
67
|
-
* Authentication credential structure
|
|
68
|
-
*/
|
|
69
|
-
export interface Credential {
|
|
70
|
-
id: string;
|
|
71
|
-
identityId: string;
|
|
72
|
-
identifierType: IdentifierType;
|
|
73
|
-
identifierValue: string;
|
|
74
|
-
passwordHash: string;
|
|
75
|
-
status: string;
|
|
76
|
-
createdAt?: Date;
|
|
77
|
-
updatedAt?: Date;
|
|
78
|
-
}
|
package/src/types/index.ts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { MetricType } from './common.types';
|
|
2
|
-
|
|
3
|
-
export interface PrometheusMetric {
|
|
4
|
-
name: string;
|
|
5
|
-
help: string;
|
|
6
|
-
type: MetricType;
|
|
7
|
-
labelNames?: string[];
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface MetricValue {
|
|
11
|
-
value: number;
|
|
12
|
-
labels?: Record<string, string>;
|
|
13
|
-
timestamp?: number;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface ServiceMetrics {
|
|
17
|
-
serviceName: string;
|
|
18
|
-
timestamp: Date;
|
|
19
|
-
metrics: {
|
|
20
|
-
// HTTP Metrics
|
|
21
|
-
httpRequestsTotal?: number;
|
|
22
|
-
httpRequestDuration?: number;
|
|
23
|
-
httpErrorsTotal?: number;
|
|
24
|
-
|
|
25
|
-
// Database Metrics
|
|
26
|
-
dbConnectionsActive?: number;
|
|
27
|
-
dbConnectionsIdle?: number;
|
|
28
|
-
dbQueryDuration?: number;
|
|
29
|
-
dbQueriesTotal?: number;
|
|
30
|
-
|
|
31
|
-
// System Metrics
|
|
32
|
-
cpuUsage?: number;
|
|
33
|
-
memoryUsage?: number;
|
|
34
|
-
heapUsed?: number;
|
|
35
|
-
heapTotal?: number;
|
|
36
|
-
|
|
37
|
-
// Application Metrics
|
|
38
|
-
activeUsers?: number;
|
|
39
|
-
requestsPerSecond?: number;
|
|
40
|
-
errorRate?: number;
|
|
41
|
-
|
|
42
|
-
// Custom Metrics
|
|
43
|
-
[key: string]: number | undefined;
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export interface HealthCheckResult {
|
|
48
|
-
status: 'healthy' | 'unhealthy' | 'degraded';
|
|
49
|
-
checks: {
|
|
50
|
-
[component: string]: {
|
|
51
|
-
status: 'up' | 'down';
|
|
52
|
-
message?: string;
|
|
53
|
-
responseTime?: number;
|
|
54
|
-
};
|
|
55
|
-
};
|
|
56
|
-
timestamp: Date;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface GrafanaDashboard {
|
|
60
|
-
id: string;
|
|
61
|
-
title: string;
|
|
62
|
-
panels: GrafanaPanel[];
|
|
63
|
-
tags: string[];
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export interface GrafanaPanel {
|
|
67
|
-
id: number;
|
|
68
|
-
title: string;
|
|
69
|
-
type: 'graph' | 'singlestat' | 'table' | 'heatmap';
|
|
70
|
-
targets: GrafanaTarget[];
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export interface GrafanaTarget {
|
|
74
|
-
expr: string; // Prometheus query
|
|
75
|
-
legendFormat?: string;
|
|
76
|
-
refId: string;
|
|
77
|
-
}
|
package/src/types/user.types.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { Observable } from 'rxjs';
|
|
2
|
-
import { UserResponse } from '../dto/auth.dto';
|
|
3
|
-
import { GetUserByIdGrpcRequest, GetUserByEmailGrpcRequest } from '../contracts/auth.contract';
|
|
4
|
-
|
|
5
|
-
export interface IUserService {
|
|
6
|
-
getUserById(data: GetUserByIdGrpcRequest): Observable<UserResponse>;
|
|
7
|
-
getUserByEmail(data: GetUserByEmailGrpcRequest): Observable<UserResponse>;
|
|
8
|
-
createUser(data: unknown): Observable<UserResponse>;
|
|
9
|
-
updateUser(data: unknown): Observable<UserResponse>;
|
|
10
|
-
deleteUser(data: { id: string }): Observable<{ success: boolean }>;
|
|
11
|
-
}
|
package/src/utils/app.utils.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { INestApplication, ValidationPipe } from '@nestjs/common';
|
|
2
|
-
import { API_PREFIX } from '../constants/http.constants';
|
|
3
|
-
import helmet from 'helmet';
|
|
4
|
-
|
|
5
|
-
export interface AppSetupOptions {
|
|
6
|
-
corsOrigins?: string[];
|
|
7
|
-
apiPrefix?: string;
|
|
8
|
-
helmet?: boolean;
|
|
9
|
-
validation?: boolean;
|
|
10
|
-
shutdownHooks?: boolean;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function setupStandardApp(
|
|
14
|
-
app: INestApplication,
|
|
15
|
-
options: AppSetupOptions = {}
|
|
16
|
-
): void {
|
|
17
|
-
const {
|
|
18
|
-
corsOrigins = ['*'],
|
|
19
|
-
apiPrefix = API_PREFIX.V1,
|
|
20
|
-
helmet: useHelmet = true,
|
|
21
|
-
validation = true,
|
|
22
|
-
shutdownHooks = true,
|
|
23
|
-
} = options;
|
|
24
|
-
|
|
25
|
-
if (shutdownHooks) {
|
|
26
|
-
app.enableShutdownHooks();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
app.enableCors({
|
|
30
|
-
origin: corsOrigins,
|
|
31
|
-
credentials: true,
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
app.setGlobalPrefix(apiPrefix);
|
|
35
|
-
|
|
36
|
-
if (useHelmet) {
|
|
37
|
-
app.use(helmet());
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (validation) {
|
|
41
|
-
app.useGlobalPipes(
|
|
42
|
-
new ValidationPipe({
|
|
43
|
-
whitelist: true,
|
|
44
|
-
forbidNonWhitelisted: true,
|
|
45
|
-
transform: true,
|
|
46
|
-
transformOptions: {
|
|
47
|
-
enableImplicitConversion: true,
|
|
48
|
-
},
|
|
49
|
-
})
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
}
|