feat: establish backend foundation

This commit is contained in:
2026-08-12 23:04:21 +03:00
parent f8dcfb71c1
commit ab21426478
24 changed files with 2313 additions and 382 deletions
@@ -0,0 +1,28 @@
import { ArgumentsHost } from '@nestjs/common';
import { HttpExceptionFilter } from './http-exception.filter';
describe('HttpExceptionFilter', () => {
it('does not expose internal error details', () => {
const status = jest.fn().mockReturnThis();
const json = jest.fn();
const filter = new HttpExceptionFilter();
const host = {
switchToHttp: () => ({
getRequest: () => ({
path: '/api/v1/health',
url: '/api/v1/health?access_token=secret',
}),
getResponse: () => ({ status, json }),
}),
} as unknown as ArgumentsHost;
filter.catch(new Error('database password: secret'), host);
expect(status).toHaveBeenCalledWith(500);
expect(json).toHaveBeenCalledWith({
statusCode: 500,
message: 'Internal server error',
path: '/api/v1/health',
});
});
});
@@ -0,0 +1,27 @@
import {
ArgumentsHost,
Catch,
ExceptionFilter,
HttpException,
HttpStatus,
} from '@nestjs/common';
import { Request, Response } from 'express';
@Catch()
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: unknown, host: ArgumentsHost): void {
const context = host.switchToHttp();
const response = context.getResponse<Response>();
const request = context.getRequest<Request>();
const status =
exception instanceof HttpException
? exception.getStatus()
: HttpStatus.INTERNAL_SERVER_ERROR;
response.status(status).json({
statusCode: status,
message: status === 500 ? 'Internal server error' : 'Request failed',
path: request.path,
});
}
}