mirror of
https://dev.azure.com/tstanciu94/PhantomMind/_git/Bitip
synced 2025-10-13 01:52:19 +03:00
Compare commits
2 Commits
fe91e14612
...
bb19edd7e3
Author | SHA1 | Date | |
---|---|---|---|
|
bb19edd7e3 | ||
|
e53ccff95c |
@ -109,6 +109,7 @@ ENABLE_HTTPS_SECURITY=false
|
||||
- Useful for reverse proxy scenarios or hosting multiple apps on same domain
|
||||
- **Example**: `/geoip-ui`
|
||||
- **Note**: All API routes are prefixed with this path automatically
|
||||
- **Health Check**: The `/api/health` endpoint is ALWAYS available at root (`/api/health`) for Docker HEALTHCHECK compatibility, AND also at `{BASE_PATH}/api/health` for consistency
|
||||
|
||||
**`NODE_ENV`**
|
||||
|
||||
|
35
src/backend/handlers/healthHandler.ts
Normal file
35
src/backend/handlers/healthHandler.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { Request, Response } from 'express';
|
||||
import geoIPService from '../services/geoip.js';
|
||||
import logger from '../services/logger.js';
|
||||
|
||||
export const healthCheckHandler = async (
|
||||
_req: Request,
|
||||
res: Response
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const isHealthy = await geoIPService.healthCheck();
|
||||
|
||||
if (isHealthy) {
|
||||
res.json({
|
||||
status: 'healthy',
|
||||
timestamp: new Date().toISOString(),
|
||||
service: 'Bitip GeoIP Service',
|
||||
});
|
||||
} else {
|
||||
res.status(503).json({
|
||||
status: 'unhealthy',
|
||||
timestamp: new Date().toISOString(),
|
||||
service: 'Bitip GeoIP Service',
|
||||
error: 'GeoIP service health check failed',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Health check failed', error as Error);
|
||||
res.status(503).json({
|
||||
status: 'unhealthy',
|
||||
timestamp: new Date().toISOString(),
|
||||
service: 'Bitip GeoIP Service',
|
||||
error: 'Health check endpoint failed',
|
||||
});
|
||||
}
|
||||
};
|
1
src/backend/handlers/index.ts
Normal file
1
src/backend/handlers/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './healthHandler.js';
|
@ -12,6 +12,7 @@ import dynamicRateLimit from './middleware/rateLimit.js';
|
||||
import config from './services/config.js';
|
||||
import logger from './services/logger.js';
|
||||
import { generateRuntimeConfig } from './services/runtimeConfig.js';
|
||||
import { healthCheckHandler } from './handlers';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
@ -76,6 +77,9 @@ const frontendPath = path.join(__dirname, '../frontend');
|
||||
// Generate runtime configuration (env.js) at startup
|
||||
generateRuntimeConfig(frontendPath, basePath);
|
||||
|
||||
// Health check endpoint at root (always accessible for Docker HEALTHCHECK)
|
||||
app.get('/api/health', healthCheckHandler);
|
||||
|
||||
// API routes with authentication and rate limiting
|
||||
app.use(`${basePath}/api`, apiKeyAuth, dynamicRateLimit, apiRoutes);
|
||||
|
||||
|
@ -6,6 +6,7 @@ import { dirname, join } from 'path';
|
||||
import geoIPService from '../services/geoip.js';
|
||||
import logger from '../services/logger.js';
|
||||
import config from '../services/config.js';
|
||||
import { healthCheckHandler } from '../handlers';
|
||||
import {
|
||||
BatchGeoIPRequest,
|
||||
BatchGeoIPResponse,
|
||||
@ -252,34 +253,7 @@ router.post('/lookup/batch', async (req: Request, res: Response) => {
|
||||
});
|
||||
|
||||
// Health check
|
||||
router.get('/health', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const isHealthy = await geoIPService.healthCheck();
|
||||
|
||||
if (isHealthy) {
|
||||
res.json({
|
||||
status: 'healthy',
|
||||
timestamp: new Date().toISOString(),
|
||||
service: 'Bitip GeoIP Service',
|
||||
});
|
||||
} else {
|
||||
res.status(503).json({
|
||||
status: 'unhealthy',
|
||||
timestamp: new Date().toISOString(),
|
||||
service: 'Bitip GeoIP Service',
|
||||
error: 'GeoIP service health check failed',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Health check failed', error as Error);
|
||||
res.status(503).json({
|
||||
status: 'unhealthy',
|
||||
timestamp: new Date().toISOString(),
|
||||
service: 'Bitip GeoIP Service',
|
||||
error: 'Health check endpoint failed',
|
||||
});
|
||||
}
|
||||
});
|
||||
router.get('/health', healthCheckHandler);
|
||||
|
||||
// Get app version
|
||||
router.get('/version', (_req: Request, res: Response): void => {
|
||||
|
@ -15,10 +15,10 @@
|
||||
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
|
||||
crossorigin=""
|
||||
/>
|
||||
<script src="/env.js"></script>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="/env.js"></script>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
x
Reference in New Issue
Block a user