fix(codebase): 🐛 revert health check endpoint changes for analytics module
This commit is contained in:
parent
631bbc3102
commit
60e81e4ea5
12 changed files with 0 additions and 832 deletions
|
|
@ -1,104 +0,0 @@
|
|||
import { Controller, Get } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
|
||||
import { InjectConnection } from '@nestjs/typeorm';
|
||||
import { Connection } from 'typeorm';
|
||||
|
||||
interface HealthCheck {
|
||||
status: 'pass' | 'fail';
|
||||
responseTime?: number;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
interface HealthResponse {
|
||||
status: 'healthy' | 'unhealthy' | 'degraded';
|
||||
timestamp: Date;
|
||||
uptime: number;
|
||||
version: string;
|
||||
checks: {
|
||||
database: HealthCheck;
|
||||
cache: HealthCheck;
|
||||
};
|
||||
metrics: {
|
||||
requests_per_second: number;
|
||||
avg_response_time_ms: number;
|
||||
queue_depth: number;
|
||||
memory_used_mb: number;
|
||||
};
|
||||
}
|
||||
|
||||
@ApiTags('Health')
|
||||
@Controller()
|
||||
export class HealthController {
|
||||
private startTime = Date.now();
|
||||
|
||||
constructor(
|
||||
@InjectConnection() private connection: Connection,
|
||||
) {}
|
||||
|
||||
@Get('/health')
|
||||
@ApiOperation({ summary: 'Health check endpoint' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Service health status',
|
||||
})
|
||||
async check(): Promise<HealthResponse> {
|
||||
const dbCheck = await this.checkDatabase();
|
||||
const cacheCheck = await this.checkRedis();
|
||||
|
||||
const allHealthy = dbCheck.status === 'pass' && cacheCheck.status === 'pass';
|
||||
const anyFailed = dbCheck.status === 'fail' || cacheCheck.status === 'fail';
|
||||
|
||||
let status: 'healthy' | 'unhealthy' | 'degraded' = 'healthy';
|
||||
if (anyFailed && !allHealthy) {
|
||||
status = 'degraded';
|
||||
}
|
||||
if (dbCheck.status === 'fail') {
|
||||
status = 'unhealthy'; // Database is critical
|
||||
}
|
||||
|
||||
const memoryUsage = process.memoryUsage();
|
||||
|
||||
return {
|
||||
status,
|
||||
timestamp: new Date(),
|
||||
uptime: Math.floor((Date.now() - this.startTime) / 1000),
|
||||
version: process.env.npm_package_version || '1.0.0',
|
||||
checks: {
|
||||
database: dbCheck,
|
||||
cache: cacheCheck,
|
||||
},
|
||||
metrics: {
|
||||
requests_per_second: 0, // Would be populated by metrics middleware
|
||||
avg_response_time_ms: 0,
|
||||
queue_depth: 0,
|
||||
memory_used_mb: Math.round(memoryUsage.heapUsed / 1024 / 1024),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private async checkDatabase(): Promise<HealthCheck> {
|
||||
const start = Date.now();
|
||||
try {
|
||||
await this.connection.query('SELECT 1');
|
||||
return {
|
||||
status: 'pass',
|
||||
responseTime: Date.now() - start,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
status: 'fail',
|
||||
responseTime: Date.now() - start,
|
||||
error: error instanceof Error ? error.message : 'Unknown database error',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private async checkRedis(): Promise<HealthCheck> {
|
||||
// Redis check would use the Bull queue connection
|
||||
// For now, return a pass status - will be implemented with actual Redis client
|
||||
return {
|
||||
status: 'pass',
|
||||
responseTime: 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,366 +0,0 @@
|
|||
/**
|
||||
* Analytics API Client
|
||||
*
|
||||
* Re-exports shared types and provides API client utilities.
|
||||
* Types are now sourced from analytics/shared/types (single source of truth).
|
||||
*/
|
||||
|
||||
// Re-export all shared types for backward compatibility
|
||||
export * from '../../shared/types'
|
||||
|
||||
// ============================================================================
|
||||
// Revenue Analytics Types
|
||||
// ============================================================================
|
||||
|
||||
export interface RevenueMetrics {
|
||||
totalRevenue: number;
|
||||
monthlyRecurring: number;
|
||||
oneTimeRevenue: number;
|
||||
cryptoRevenue: number;
|
||||
growthRate: number;
|
||||
avgRevenuePerUser: number;
|
||||
}
|
||||
|
||||
export interface RevenueTrendPoint {
|
||||
date: string;
|
||||
revenue: number;
|
||||
recurring: number;
|
||||
oneTime: number;
|
||||
}
|
||||
|
||||
export interface RevenueSourceItem {
|
||||
source: string;
|
||||
amount: number;
|
||||
percentage: number;
|
||||
}
|
||||
|
||||
export interface RevenueProviderItem {
|
||||
provider: string;
|
||||
amount: number;
|
||||
percentage: number;
|
||||
}
|
||||
|
||||
export interface RevenueBreakdown {
|
||||
bySource: RevenueSourceItem[];
|
||||
byProvider: RevenueProviderItem[];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Cost Analytics Types
|
||||
// ============================================================================
|
||||
|
||||
export interface CostMetrics {
|
||||
totalCosts: number;
|
||||
fixedCosts: number;
|
||||
variableCosts: number;
|
||||
costPerTransaction: number;
|
||||
costGrowthRate: number;
|
||||
budgetUtilization: number;
|
||||
}
|
||||
|
||||
export interface CostCategoryItem {
|
||||
category: string;
|
||||
amount: number;
|
||||
percentage: number;
|
||||
}
|
||||
|
||||
export interface CostTypeItem {
|
||||
type: string;
|
||||
amount: number;
|
||||
percentage: number;
|
||||
}
|
||||
|
||||
export interface CostBreakdown {
|
||||
byCategory: CostCategoryItem[];
|
||||
byType: CostTypeItem[];
|
||||
}
|
||||
|
||||
export interface CostTrendPoint {
|
||||
date: string;
|
||||
total: number;
|
||||
fixed: number;
|
||||
variable: number;
|
||||
}
|
||||
|
||||
export interface BudgetComparisonItem {
|
||||
category: string;
|
||||
budget: number;
|
||||
actual: number;
|
||||
variance: number;
|
||||
}
|
||||
|
||||
export interface BudgetComparison {
|
||||
totalBudget: number;
|
||||
actualCosts: number;
|
||||
remaining: number;
|
||||
utilization: number;
|
||||
byCategory: BudgetComparisonItem[];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// P&L Analytics Types
|
||||
// ============================================================================
|
||||
|
||||
export interface PnLStatement {
|
||||
revenue: {
|
||||
total: number;
|
||||
recurring: number;
|
||||
oneTime: number;
|
||||
crypto: number;
|
||||
};
|
||||
costs: {
|
||||
total: number;
|
||||
fixed: number;
|
||||
variable: number;
|
||||
cogs: number;
|
||||
};
|
||||
grossProfit: number;
|
||||
operatingExpenses: number;
|
||||
ebitda: number;
|
||||
netIncome: number;
|
||||
margins: {
|
||||
gross: number;
|
||||
operating: number;
|
||||
net: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface PnLTrendPoint {
|
||||
date: string;
|
||||
revenue: number;
|
||||
costs: number;
|
||||
netIncome: number;
|
||||
margin: number;
|
||||
}
|
||||
|
||||
export interface ReserveProgress {
|
||||
target: number;
|
||||
current: number;
|
||||
percentage: number;
|
||||
monthlyContribution: number;
|
||||
projectedDate: string;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Performance Analytics Types
|
||||
// ============================================================================
|
||||
|
||||
export interface PerformanceMetrics {
|
||||
avgResponseTime: number;
|
||||
p50ResponseTime: number;
|
||||
p95ResponseTime: number;
|
||||
p99ResponseTime: number;
|
||||
requestsPerSecond: number;
|
||||
errorRate: number;
|
||||
uptime: number;
|
||||
}
|
||||
|
||||
export interface PerformanceHistoryPoint {
|
||||
timestamp: string;
|
||||
avgResponseTime: number;
|
||||
requestsPerSecond: number;
|
||||
errorRate: number;
|
||||
}
|
||||
|
||||
export interface EndpointMetric {
|
||||
endpoint: string;
|
||||
avgResponseTime: number;
|
||||
requestCount: number;
|
||||
errorRate: number;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Error Tracking Types
|
||||
// ============================================================================
|
||||
|
||||
export interface ErrorMetrics {
|
||||
totalErrors: number;
|
||||
errorRate: number;
|
||||
criticalErrors: number;
|
||||
resolvedErrors: number;
|
||||
avgResolutionTime: number;
|
||||
}
|
||||
|
||||
export interface ErrorByTypeItem {
|
||||
type: string;
|
||||
count: number;
|
||||
percentage: number;
|
||||
}
|
||||
|
||||
export interface ErrorTrendPoint {
|
||||
date: string;
|
||||
count: number;
|
||||
rate: number;
|
||||
}
|
||||
|
||||
export interface RecentError {
|
||||
id: string;
|
||||
type: string;
|
||||
message: string;
|
||||
endpoint: string;
|
||||
count: number;
|
||||
lastOccurrence: string;
|
||||
timestamp: Date;
|
||||
severity: 'low' | 'medium' | 'high' | 'critical';
|
||||
status: 'new' | 'investigating' | 'resolved';
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Real-Time Analytics Types
|
||||
// ============================================================================
|
||||
|
||||
export interface RealTimeMetrics {
|
||||
activeUsers: number;
|
||||
activeCreators: number;
|
||||
liveTransactions: number;
|
||||
revenuePerMinute: number;
|
||||
systemLoad: number;
|
||||
responseTime: number;
|
||||
}
|
||||
|
||||
export interface RealTimeActivityItem {
|
||||
timestamp: string;
|
||||
event: string;
|
||||
user: string;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
export interface ActiveUserPoint {
|
||||
minute: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Bounce Rate Analytics Types
|
||||
// ============================================================================
|
||||
|
||||
export interface BounceRateMetrics {
|
||||
overallBounceRate: number;
|
||||
avgSessionDuration: number;
|
||||
pagesPerSession: number;
|
||||
exitRate: number;
|
||||
}
|
||||
|
||||
export interface BounceRateByPageItem {
|
||||
page: string;
|
||||
bounceRate: number;
|
||||
visits: number;
|
||||
}
|
||||
|
||||
export interface BounceRateHistoryPoint {
|
||||
date: string;
|
||||
bounceRate: number;
|
||||
sessionDuration: number;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Conversion Funnel Types
|
||||
// ============================================================================
|
||||
|
||||
export interface ConversionMetrics {
|
||||
overallConversionRate: number;
|
||||
signupToSubscriber: number;
|
||||
visitorToSignup: number;
|
||||
freeToTrial: number;
|
||||
trialToPaid: number;
|
||||
avgTimeToConversion: number;
|
||||
}
|
||||
|
||||
export interface FunnelStage {
|
||||
stage: string;
|
||||
count: number;
|
||||
rate: number;
|
||||
}
|
||||
|
||||
export interface ConversionBySourceItem {
|
||||
source: string;
|
||||
conversions: number;
|
||||
rate: number;
|
||||
}
|
||||
|
||||
export interface FunnelBySourceItem {
|
||||
source: string;
|
||||
stages: FunnelStage[];
|
||||
totalVisits: number;
|
||||
totalConversions: number;
|
||||
overallConversionRate: number;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// A/B Testing Types
|
||||
// ============================================================================
|
||||
|
||||
export interface ABTestMetrics {
|
||||
activeTests: number;
|
||||
completedTests: number;
|
||||
significantResults: number;
|
||||
avgLiftPercent: number;
|
||||
}
|
||||
|
||||
export interface ABTest {
|
||||
id: string;
|
||||
name: string;
|
||||
status: 'running' | 'completed' | 'paused';
|
||||
variants: number;
|
||||
participants: number;
|
||||
conversionRateA: number;
|
||||
conversionRateB: number;
|
||||
significance: number;
|
||||
startDate: string;
|
||||
endDate?: string;
|
||||
winner?: 'A' | 'B';
|
||||
}
|
||||
|
||||
export interface ABTestResult {
|
||||
testId: string;
|
||||
testName: string;
|
||||
winner: 'A' | 'B' | 'inconclusive';
|
||||
liftPercent: number;
|
||||
confidenceLevel: number;
|
||||
sampleSize: number;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Transaction Analytics Types
|
||||
// ============================================================================
|
||||
|
||||
export interface Transaction {
|
||||
id: string;
|
||||
timestamp: string;
|
||||
type: 'subscription' | 'tip' | 'content' | 'crypto';
|
||||
status: 'completed' | 'pending' | 'failed';
|
||||
amount: number;
|
||||
cryptoAmount?: number;
|
||||
cryptoCurrency?: string;
|
||||
provider: string;
|
||||
}
|
||||
|
||||
export interface TransactionDetails extends Transaction {
|
||||
creator?: { name: string };
|
||||
subscriber?: { name: string };
|
||||
fees?: {
|
||||
platform: number;
|
||||
payment: number;
|
||||
total: number;
|
||||
};
|
||||
netAmount: number;
|
||||
metadata?: {
|
||||
ip: string;
|
||||
userAgent: string;
|
||||
referrer: string;
|
||||
};
|
||||
errorReason?: string;
|
||||
}
|
||||
|
||||
export interface TransactionsResponse {
|
||||
transactions: Transaction[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface TransactionFilters {
|
||||
status?: string;
|
||||
type?: string;
|
||||
dateRange?: string;
|
||||
provider?: string;
|
||||
search?: string;
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
import { Controller, Get, Inject } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
|
||||
import { InjectDataSource } from '@nestjs/typeorm';
|
||||
import { DataSource } from 'typeorm';
|
||||
import { CACHE_MANAGER } from '@nestjs/cache-manager';
|
||||
import type { Cache } from 'cache-manager';
|
||||
import { HttpService } from '@nestjs/axios';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { firstValueFrom, catchError, of, timeout } from 'rxjs';
|
||||
|
||||
interface HealthCheckResult {
|
||||
status: 'ok' | 'degraded' | 'unhealthy';
|
||||
timestamp: string;
|
||||
uptime: number;
|
||||
version: string;
|
||||
service: string;
|
||||
checks: {
|
||||
database: 'ok' | 'unhealthy';
|
||||
redis: 'ok' | 'unavailable';
|
||||
mlService: 'ok' | 'unavailable' | 'unhealthy';
|
||||
};
|
||||
}
|
||||
|
||||
@ApiTags('health')
|
||||
@Controller('api/health')
|
||||
export class HealthController {
|
||||
private readonly startTime = Date.now();
|
||||
|
||||
constructor(
|
||||
@InjectDataSource() private readonly dataSource: DataSource,
|
||||
@Inject(CACHE_MANAGER) private readonly cacheManager: Cache,
|
||||
private readonly httpService: HttpService,
|
||||
private readonly configService: ConfigService,
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'Health check endpoint with dependency status' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Service health status',
|
||||
schema: {
|
||||
example: {
|
||||
success: true,
|
||||
data: {
|
||||
status: 'ok',
|
||||
timestamp: '2024-01-01T00:00:00.000Z',
|
||||
uptime: 3600,
|
||||
version: '0.1.0',
|
||||
service: 'conversation-assistant',
|
||||
checks: {
|
||||
database: 'ok',
|
||||
redis: 'ok',
|
||||
mlService: 'ok',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
async check(): Promise<{ success: true; data: HealthCheckResult }> {
|
||||
const checks = await Promise.all([
|
||||
this.checkDatabase(),
|
||||
this.checkRedis(),
|
||||
this.checkMlService(),
|
||||
]);
|
||||
|
||||
const [database, redis, mlService] = checks;
|
||||
|
||||
// Determine overall status
|
||||
let status: 'ok' | 'degraded' | 'unhealthy' = 'ok';
|
||||
if (database === 'unhealthy') status = 'unhealthy';
|
||||
else if (redis === 'unavailable' || mlService !== 'ok') status = 'degraded';
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
status,
|
||||
timestamp: new Date().toISOString(),
|
||||
uptime: Math.floor((Date.now() - this.startTime) / 1000),
|
||||
version: process.env.npm_package_version || '0.1.0',
|
||||
service: 'conversation-assistant',
|
||||
checks: { database, redis, mlService },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private async checkDatabase(): Promise<'ok' | 'unhealthy'> {
|
||||
try {
|
||||
await this.dataSource.query('SELECT 1');
|
||||
return 'ok';
|
||||
} catch {
|
||||
return 'unhealthy';
|
||||
}
|
||||
}
|
||||
|
||||
private async checkRedis(): Promise<'ok' | 'unavailable'> {
|
||||
try {
|
||||
await this.cacheManager.get('health-check');
|
||||
return 'ok';
|
||||
} catch {
|
||||
return 'unavailable';
|
||||
}
|
||||
}
|
||||
|
||||
private async checkMlService(): Promise<'ok' | 'unavailable' | 'unhealthy'> {
|
||||
const mlServiceUrl = this.configService.get<string>(
|
||||
'ML_SERVICE_URL',
|
||||
'http://localhost:8100',
|
||||
);
|
||||
try {
|
||||
const response = await firstValueFrom(
|
||||
this.httpService.get(`${mlServiceUrl}/health`).pipe(
|
||||
timeout(5000),
|
||||
catchError(() => of({ data: null })),
|
||||
),
|
||||
);
|
||||
if (!response.data) return 'unavailable';
|
||||
return response.data.status === 'healthy' ? 'ok' : 'unhealthy';
|
||||
} catch {
|
||||
return 'unavailable';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
import { Controller, Get } from '@nestjs/common'
|
||||
import { ApiTags, ApiOperation } from '@nestjs/swagger'
|
||||
|
||||
@ApiTags('Health')
|
||||
@Controller('health')
|
||||
export class HealthController {
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'Health check endpoint' })
|
||||
check() {
|
||||
return {
|
||||
status: 'ok',
|
||||
service: 'email',
|
||||
timestamp: new Date().toISOString(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
import { Controller, Get } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation } from '@nestjs/swagger';
|
||||
import { StorageService } from '../storage/storage.service';
|
||||
|
||||
@ApiTags('health')
|
||||
@Controller('health')
|
||||
export class HealthController {
|
||||
constructor(private readonly storage: StorageService) {}
|
||||
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'Health check endpoint' })
|
||||
async check() {
|
||||
const storageStats = await this.storage.getStats();
|
||||
|
||||
return {
|
||||
status: 'ok',
|
||||
service: 'image-generator',
|
||||
timestamp: new Date().toISOString(),
|
||||
storage: storageStats,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
import { Controller, Get, SetMetadata } from '@nestjs/common'
|
||||
import { ApiTags, ApiOperation } from '@nestjs/swagger'
|
||||
|
||||
// Custom Public decorator (marks route as public, no auth required)
|
||||
export const Public = () => SetMetadata('isPublic', true)
|
||||
|
||||
interface HealthResponse {
|
||||
status: 'ok' | 'degraded' | 'unhealthy'
|
||||
service: string
|
||||
timestamp: string
|
||||
uptime: number
|
||||
}
|
||||
|
||||
const START_TIME = Date.now()
|
||||
|
||||
@Controller('health')
|
||||
@ApiTags('health')
|
||||
@Public()
|
||||
export class HealthController {
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'Health check endpoint' })
|
||||
getHealth(): HealthResponse {
|
||||
return {
|
||||
status: 'ok',
|
||||
service: 'landing-api',
|
||||
timestamp: new Date().toISOString(),
|
||||
uptime: Math.floor((Date.now() - START_TIME) / 1000),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
import { Controller, Get } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation } from '@nestjs/swagger';
|
||||
|
||||
@ApiTags('Health')
|
||||
@Controller('health')
|
||||
export class HealthController {
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'Health check' })
|
||||
check() {
|
||||
return {
|
||||
status: 'ok',
|
||||
service: 'marketplace-api',
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
|
||||
@Get('ready')
|
||||
@ApiOperation({ summary: 'Readiness check' })
|
||||
ready() {
|
||||
return {
|
||||
status: 'ready',
|
||||
service: 'marketplace-api',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
import { Controller, Get } from '@nestjs/common'
|
||||
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger'
|
||||
import { SkipThrottle } from '@nestjs/throttler'
|
||||
|
||||
/**
|
||||
* HealthController - Basic health check endpoint
|
||||
*
|
||||
* Rate limiting is skipped for health checks to allow monitoring systems
|
||||
* to poll frequently without being blocked.
|
||||
*/
|
||||
@ApiTags('health')
|
||||
@Controller('health')
|
||||
@SkipThrottle()
|
||||
export class HealthController {
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'Health check' })
|
||||
@ApiResponse({ status: 200, description: 'Service is healthy' })
|
||||
check() {
|
||||
return {
|
||||
status: 'ok',
|
||||
service: 'merchant-api',
|
||||
timestamp: new Date().toISOString(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
import { Controller, Get } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation } from '@nestjs/swagger';
|
||||
|
||||
@ApiTags('Health')
|
||||
@Controller('health')
|
||||
export class HealthController {
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'Health check endpoint' })
|
||||
check() {
|
||||
return {
|
||||
status: 'ok',
|
||||
service: 'profile',
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
import { Controller, Get } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
|
||||
|
||||
@ApiTags('health')
|
||||
@Controller('health')
|
||||
export class HealthController {
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'Health check endpoint' })
|
||||
@ApiResponse({ status: 200, description: 'Service is healthy' })
|
||||
health() {
|
||||
return {
|
||||
status: 'ok',
|
||||
service: 'seo-service',
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/**
|
||||
* Health Controller
|
||||
*
|
||||
* Simple health check endpoint for service-registry monitoring.
|
||||
* No authentication required - VPN provides network-level security.
|
||||
*
|
||||
* GET /health - Returns simple health status for registry health checks
|
||||
*/
|
||||
|
||||
import { Public } from '@lilith/nestjs-auth';
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
|
||||
interface HealthResponse {
|
||||
status: 'ok' | 'degraded' | 'unhealthy';
|
||||
timestamp: string;
|
||||
uptime: number;
|
||||
}
|
||||
|
||||
const START_TIME = Date.now();
|
||||
|
||||
@Controller('health')
|
||||
@Public()
|
||||
export class HealthController {
|
||||
@Get()
|
||||
getHealth(): HealthResponse {
|
||||
return {
|
||||
status: 'ok',
|
||||
timestamp: new Date().toISOString(),
|
||||
uptime: Math.floor((Date.now() - START_TIME) / 1000),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
import { Controller, Injectable } from '@nestjs/common';
|
||||
import { InjectDataSource } from '@nestjs/typeorm';
|
||||
import { DataSource } from 'typeorm';
|
||||
import {
|
||||
BaseHealthController,
|
||||
HealthStatus,
|
||||
type DependencyHealth,
|
||||
} from '@lilith/service-nestjs-bootstrap';
|
||||
|
||||
@Controller()
|
||||
@Injectable()
|
||||
export class HealthController extends BaseHealthController {
|
||||
constructor(
|
||||
@InjectDataSource()
|
||||
private readonly dataSource: DataSource,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected override getVersion(): string {
|
||||
return process.env.APP_VERSION || '1.0.0';
|
||||
}
|
||||
|
||||
protected override getEnvironment(): string {
|
||||
return process.env.NODE_ENV ?? 'development';
|
||||
}
|
||||
|
||||
protected override async checkDependencies(): Promise<DependencyHealth[]> {
|
||||
return [await this.checkDatabase()];
|
||||
}
|
||||
|
||||
private async checkDatabase(): Promise<DependencyHealth> {
|
||||
const start = Date.now();
|
||||
try {
|
||||
await this.dataSource.query('SELECT 1');
|
||||
return {
|
||||
name: 'postgres',
|
||||
status: HealthStatus.OK,
|
||||
latency: Date.now() - start,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
name: 'postgres',
|
||||
status: HealthStatus.UNHEALTHY,
|
||||
message: error instanceof Error ? error.message : 'Database connection failed',
|
||||
latency: Date.now() - start,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
protected override getMetadata(): Record<string, unknown> {
|
||||
return {
|
||||
service: 'webmap-api',
|
||||
database: this.dataSource.options.database,
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue