fix(health): resolve 404 on /health endpoints — restructure routes under /health prefix

Root cause: HealthController used @Controller() (empty prefix) with @Get('health')
and @Get('ready') flat routes. The global prefix exclusion for 'health' and 'ready'
was unreliable for module-scoped controllers.

Changes:
- Set @Controller('health') prefix so routes are /health, /health/ready, /health/db, /health/redis
- Update global prefix exclusion to use 'health/(.*)' wildcard pattern
- Exclude health endpoints from CSRF middleware (K8s probes don't send cookies)
- Add dedicated /health/db and /health/redis endpoints per acceptance criteria
- Expand unit tests to cover all 4 health endpoints (15 tests passing)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-10 20:55:03 +07:00
parent d36a13d536
commit a003df9a8a
4 changed files with 101 additions and 6 deletions

View File

@@ -1,4 +1,4 @@
import { type MiddlewareConsumer, Module, type NestModule } from '@nestjs/common';
import { type MiddlewareConsumer, Module, type NestModule, RequestMethod } from '@nestjs/common';
import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { CqrsModule } from '@nestjs/cqrs';
import { ScheduleModule } from '@nestjs/schedule';
@@ -94,8 +94,13 @@ export class AppModule implements NestModule {
.forRoutes('*');
// CSRF double-submit cookie (sets on GET, validates on state-changing methods)
// Exclude health endpoints — they must remain accessible without cookies
consumer
.apply(CsrfMiddleware)
.exclude(
{ path: 'health', method: RequestMethod.GET },
{ path: 'health/(.*)', method: RequestMethod.GET },
)
.forRoutes('*');
}
}