From da62c2228f26f1853e93d119285afbbe33745d57 Mon Sep 17 00:00:00 2001 From: Fizer Khan Date: Fri, 5 Dec 2025 09:02:40 +0530 Subject: [PATCH] fix port issue. update readme. --- Makefile | 21 +++++++++- README.md | 55 -------------------------- apps/api/src/index.ts | 4 +- apps/workers/src/collectors/metrics.ts | 4 ++ apps/workers/src/config.ts | 3 ++ apps/workers/src/index.ts | 25 ++++++++++++ apps/workers/src/processors/alerts.ts | 4 ++ 7 files changed, 59 insertions(+), 57 deletions(-) diff --git a/Makefile b/Makefile index 0bd6a6e..f8cb60c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: help install dev build start stop logs clean \ +.PHONY: help install dev kill build start stop logs clean \ db-up db-down db-shell-postgres db-shell-redis db-shell-clickhouse db-shell-nats \ prisma-generate prisma-migrate prisma-studio \ api-dev web-dev workers-dev \ @@ -27,8 +27,27 @@ install: ## Install all dependencies # ==================== Development ==================== dev: db-up ## Start all services in development mode + @echo "" + @echo "$(CYAN)Starting NATS Console...$(RESET)" + @echo "" + @echo "$(GREEN)Services:$(RESET)" + @echo " $(CYAN)Frontend$(RESET) → http://localhost:3000" + @echo " $(CYAN)Backend$(RESET) → http://localhost:3001" + @echo " $(CYAN)Workers$(RESET) → http://localhost:3002/health" + @echo "" pnpm dev +kill: ## Kill all dev servers (ports 3000, 3001, 3002) + @echo "$(YELLOW)Killing dev servers...$(RESET)" + @-kill -9 $$(lsof -ti:3000) 2>/dev/null || true + @-kill -9 $$(lsof -ti:3001) 2>/dev/null || true + @-kill -9 $$(lsof -ti:3002) 2>/dev/null || true + @-pkill -9 -f "tsx" 2>/dev/null || true + @-pkill -9 -f "next-server" 2>/dev/null || true + @-pkill -9 -f "turbo" 2>/dev/null || true + @sleep 1 + @echo "$(GREEN)Done$(RESET)" + api-dev: ## Start API in development mode pnpm --filter @nats-console/api dev diff --git a/README.md b/README.md index 7b0a336..bbb5ec1 100644 --- a/README.md +++ b/README.md @@ -107,25 +107,6 @@ make setup && make dev --- -## Project Structure - -``` -nats-console/ -├── apps/ -│ ├── api/ # Fastify backend API -│ ├── web/ # Next.js frontend dashboard -│ └── workers/ # Background workers (metrics, alerts) -├── packages/ -│ └── shared/ # Shared types, schemas, utilities -├── examples/ # Example NATS producer/consumer apps -├── docker-compose.yml # Development infrastructure -├── docker-compose.prod.yml # Production deployment -├── Makefile -└── turbo.json -``` - ---- - ## Makefile Commands ### Development @@ -234,42 +215,6 @@ pnpm run load-test --- -## API Reference - -Base URL: `http://localhost:3001/api/v1` - -### Authentication -| Method | Endpoint | Description | -|--------|----------|-------------| -| POST | `/auth/login` | Login | -| POST | `/auth/register` | Register | -| POST | `/auth/refresh` | Refresh token | -| GET | `/auth/me` | Current user | - -### Clusters -| Method | Endpoint | Description | -|--------|----------|-------------| -| GET | `/clusters` | List clusters | -| POST | `/clusters` | Create cluster | -| GET | `/clusters/:id` | Get cluster | -| GET | `/clusters/:id/health` | Health check | - -### Streams -| Method | Endpoint | Description | -|--------|----------|-------------| -| GET | `/clusters/:id/streams` | List streams | -| POST | `/clusters/:id/streams` | Create stream | -| GET | `/clusters/:id/streams/:name/messages` | Browse messages | -| POST | `/clusters/:id/streams/:name/messages` | Publish message | - -### Consumers -| Method | Endpoint | Description | -|--------|----------|-------------| -| GET | `/clusters/:id/streams/:stream/consumers` | List consumers | -| POST | `/clusters/:id/streams/:stream/consumers` | Create consumer | - ---- - ## Contributing 1. Fork the repository diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index c9cbcf2..62b3ea5 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -40,8 +40,10 @@ const app = Fastify({ // Register plugins await app.register(cors, { - origin: config.CORS_ORIGIN.split(','), + origin: config.NODE_ENV === 'development' ? true : config.CORS_ORIGIN.split(','), credentials: true, + methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], + allowedHeaders: ['Content-Type', 'Authorization'], }); await app.register(helmet, { diff --git a/apps/workers/src/collectors/metrics.ts b/apps/workers/src/collectors/metrics.ts index c28117c..20d669c 100644 --- a/apps/workers/src/collectors/metrics.ts +++ b/apps/workers/src/collectors/metrics.ts @@ -79,6 +79,10 @@ export class MetricsCollector { logger.info('Metrics collector stopped'); } + isRunning(): boolean { + return this.streamMetricsInterval !== null || this.clusterMetricsInterval !== null; + } + private async connectToClusters(): Promise { // Get all clusters with their connections const clusters = await this.prisma.natsCluster.findMany({ diff --git a/apps/workers/src/config.ts b/apps/workers/src/config.ts index cf6ff6d..d66e13b 100644 --- a/apps/workers/src/config.ts +++ b/apps/workers/src/config.ts @@ -3,6 +3,9 @@ import { z } from 'zod'; const envSchema = z.object({ NODE_ENV: z.enum(['development', 'production', 'test']).default('development'), + // Server + PORT: z.coerce.number().default(3002), + // PostgreSQL DATABASE_URL: z.string().url(), diff --git a/apps/workers/src/index.ts b/apps/workers/src/index.ts index 7665c53..5ca36a4 100644 --- a/apps/workers/src/index.ts +++ b/apps/workers/src/index.ts @@ -1,3 +1,4 @@ +import { createServer } from 'node:http'; import pino from 'pino'; import cron from 'node-cron'; import { MetricsCollector } from './collectors/metrics'; @@ -22,10 +23,29 @@ const logger = pino({ const metricsCollector = new MetricsCollector(); const alertProcessor = new AlertProcessor(); +// Health check server +const healthServer = createServer((req, res) => { + if (req.url === '/health') { + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ + status: 'ok', + timestamp: new Date().toISOString(), + workers: { + metricsCollector: metricsCollector.isRunning(), + alertProcessor: alertProcessor.isRunning(), + }, + })); + } else { + res.writeHead(404); + res.end('Not Found'); + } +}); + // Graceful shutdown async function shutdown(signal: string): Promise { logger.info(`Received ${signal}, shutting down...`); + healthServer.close(); await metricsCollector.stop(); await alertProcessor.stop(); @@ -59,6 +79,11 @@ async function start(): Promise { // TODO: Implement cleanup (expired sessions, old data archival) }); + // Start health server + healthServer.listen(config.PORT, () => { + logger.info(`Health server listening on http://localhost:${config.PORT}/health`); + }); + logger.info('All workers started successfully'); } catch (err) { logger.error({ err }, 'Failed to start workers'); diff --git a/apps/workers/src/processors/alerts.ts b/apps/workers/src/processors/alerts.ts index 72fa4b1..582b86c 100644 --- a/apps/workers/src/processors/alerts.ts +++ b/apps/workers/src/processors/alerts.ts @@ -74,6 +74,10 @@ export class AlertProcessor { logger.info('Alert processor stopped'); } + isRunning(): boolean { + return this.processInterval !== null; + } + private async processAlerts(): Promise { try { // Get all enabled alert rules