# pulsewatch-server

**Complete uptime monitoring server** - Drop-in Express backend with monitoring engine, database, REST API, and real-time updates. **No authentication required** - integrate your own!

## 🎯 One Complete Package

This package combines everything you need for uptime monitoring:

- ✅ **Monitoring Engine** - 8 monitor types (HTTP, TCP, DNS, Ping, WebSocket, Keyword, JSON Query, Push)
- ✅ **Express Backend** - Complete REST API
- ✅ **Database Schema** - Drizzle ORM ready
- ✅ **Real-time Updates** - Socket.IO integration
- ✅ **No Authentication** - Use your own auth system

## 📦 Installation

```bash
npm install pulsewatch-server
```

### Peer Dependencies

```bash
npm install express socket.io drizzle-orm pg
```

## 🚀 Quick Start

```typescript
import express from "express";
import { createPulseWatch, createDatabase } from "pulsewatch-server";
import * as schema from "pulsewatch-server/database";

const app = express();

// Create database connection
const { db } = createDatabase({
  connectionString: process.env.DATABASE_URL,
});

// Create PulseWatch server
const pulsewatch = createPulseWatch({ app, db, schema });

// Start monitoring
await pulsewatch.start();

// Start HTTP server
pulsewatch.httpServer.listen(3000, () => {
  console.log("Server running on port 3000");
});
```

That's it! You now have a complete monitoring system with:

- REST API at `/api/monitors`
- Push endpoints at `/api/push/:token`
- Real-time updates via WebSocket at `/ws`

## 📊 Monitor Types

### 1. HTTP/HTTPS

```typescript
{
  name: "My API",
  type: "http",
  url: "https://api.example.com",
  method: "GET",
  intervalSeconds: 60
}
```

### 2. TCP Port

```typescript
{
  name: "Database",
  type: "tcp",
  host: "db.example.com",
  port: 5432
}
```

### 3. DNS

```typescript
{
  name: "DNS Check",
  type: "dns",
  host: "example.com",
  dnsRecordType: "A"
}
```

### 4. Ping

```typescript
{
  name: "Server Ping",
  type: "ping",
  host: "example.com"
}
```

### 5. WebSocket

```typescript
{
  name: "WebSocket",
  type: "websocket",
  url: "wss://example.com/socket"
}
```

### 6. Keyword Search

```typescript
{
  name: "Homepage Check",
  type: "keyword",
  url: "https://example.com",
  keyword: "Welcome"
}
```

### 7. JSON Query

```typescript
{
  name: "API Health",
  type: "json_query",
  url: "https://api.example.com/health",
  jsonQuery: "$.status",
  expectedValue: "healthy"
}
```

### 8. Push (Heartbeat)

```typescript
{
  name: "Cron Job",
  type: "push",
  intervalSeconds: 300
}
```

Then send heartbeats:

```bash
curl https://your-server.com/api/push/YOUR_TOKEN
```

## 🔌 API Endpoints

Once integrated, these endpoints are available:

```
GET    /api/monitors              - List all monitors
GET    /api/monitors/summary      - Get monitors with uptime stats
POST   /api/monitors              - Create monitor
PUT    /api/monitors/:id          - Update monitor
DELETE /api/monitors/:id          - Delete monitor
POST   /api/monitors/:id/pause    - Pause/unpause monitor
POST   /api/monitors/:id/clone    - Clone monitor
GET    /api/monitors/:id/results  - Get check results
POST   /api/push/:token           - Receive heartbeat
GET    /api/push/:token           - Receive heartbeat (GET)
GET    /api/health                - Health check
```

## 🔄 Real-time Updates

Listen for monitor updates via Socket.IO:

```typescript
import { io } from "socket.io-client";

const socket = io("http://localhost:3000", {
  path: "/ws",
});

socket.on("monitor:update", (data) => {
  console.log("Monitor update:", data);
  // {
  //   monitorId: '123',
  //   status: 'up',
  //   message: 'OK',
  //   pingMs: 145,
  //   httpStatus: 200,
  //   checkedAt: '2026-01-30T12:00:00.000Z'
  // }
});
```

## 💾 Database

The package includes a complete Drizzle ORM schema:

```typescript
import * as schema from "pulsewatch-server/database";

// Tables included:
// - monitors
// - monitorResults
// - proxies
// - notifications
// - monitorNotifications
// - statusPages
// - statusPageMonitors
```

### Run Migrations

```bash
# Install drizzle-kit
npm install -D drizzle-kit

# Generate migrations
npx drizzle-kit generate

# Push to database
npx drizzle-kit push
```

## 🔐 Adding Authentication

The package doesn't include authentication - add your own:

```typescript
import express from "express";
import { createPulseWatch } from "pulsewatch-server";

const app = express();

// Your auth middleware
function authMiddleware(req, res, next) {
  // Check JWT, session, API key, etc.
  if (!req.headers.authorization) {
    return res.status(401).json({ error: "Unauthorized" });
  }
  next();
}

// Protect all API routes
app.use("/api", authMiddleware);

// Add PulseWatch (now protected by your auth)
const pulsewatch = createPulseWatch({ app, db, schema });
```

## ⚙️ Configuration

### Full Configuration

```typescript
const pulsewatch = createPulseWatch({
  app, // Express app
  db, // Drizzle database instance
  schema: {
    // Database schema
    monitors,
    monitorResults,
    proxies,
    notifications,
    monitorNotifications,
  },
  socketIO: {
    // Optional Socket.IO config
    cors: { origin: "*" },
    path: "/ws",
  },
  logger: {
    // Optional logger
    error: (err, msg) => console.error(msg, err),
    warn: (msg) => console.warn(msg),
    info: (msg) => console.log(msg),
  },
});
```

## 🎯 Advanced Usage

### Use Check Functions Directly

```typescript
import { checkHttp, checkTcp } from "pulsewatch-server";

// Run checks manually
const result = await checkHttp({
  type: "http",
  url: "https://example.com",
  timeoutMs: 5000,
});

console.log(result);
// { status: 'up', message: 'OK', pingMs: 123, httpStatus: 200 }
```

### Custom Routes

```typescript
import {
  createMonitorsRouter,
  createPushRouter,
} from "pulsewatch-server/routes";

// Create routes separately
const monitorsRouter = createMonitorsRouter({ db, schema, runner });
const pushRouter = createPushRouter({ runner });

// Mount with custom paths
app.use("/monitoring/monitors", monitorsRouter);
app.use("/monitoring/push", pushRouter);
```

### Use MonitorRunner Directly

```typescript
import { MonitorRunner } from "pulsewatch-server";
import { eq, desc, inArray } from "drizzle-orm";

const runner = new MonitorRunner({
  io,
  db,
  schema,
  orm: { eq, desc, inArray },
  logger: console,
});

await runner.start();
```

## 📝 Complete Example

```typescript
import express from "express";
import { createPulseWatch, createDatabase } from "pulsewatch-server";
import * as schema from "pulsewatch-server/database";

const app = express();

// Create database
const { db, pool } = createDatabase({
  connectionString: process.env.DATABASE_URL,
  max: 20,
});

// Create PulseWatch
const pulsewatch = createPulseWatch({
  app,
  db,
  schema,
  socketIO: {
    cors: { origin: process.env.FRONTEND_URL },
    path: "/ws",
  },
  logger: console,
});

// Start monitoring
await pulsewatch.start();

// Start server
const PORT = process.env.PORT || 3000;
pulsewatch.httpServer.listen(PORT, () => {
  console.log(`PulseWatch running on port ${PORT}`);
});

// Graceful shutdown
process.on("SIGTERM", () => {
  pulsewatch.stop();
  pool.end();
  process.exit(0);
});
```

## 🌟 Features

- ✅ **8 Monitor Types** - HTTP, TCP, DNS, Ping, WebSocket, Keyword, JSON Query, Push
- ✅ **Real-time Updates** - Socket.IO for live monitoring
- ✅ **Database Included** - Complete Drizzle ORM schema
- ✅ **REST API** - Full CRUD for monitors
- ✅ **No Auth Required** - Integrate your own authentication
- ✅ **TypeScript** - Full type definitions
- ✅ **Lightweight** - Minimal dependencies
- ✅ **Flexible** - Use as-is or customize

## 📦 Exports

```typescript
// Main server
export { createPulseWatch, type PulseWatchConfig, type PulseWatchServer };

// Database
export { createDatabase, type DatabaseConfig };
export * from "./database/schema";

// Routes
export { createMonitorsRouter, createPushRouter };

// Monitor checks
export {
  checkHttp,
  checkTcp,
  checkDns,
  checkPing,
  checkWebsocket,
  checkKeyword,
  checkJsonQuery,
};

// MonitorRunner
export { MonitorRunner, type MonitorRunnerConfig };

// Types
export type { Monitor, Proxy, CheckResult, MonitorType, MonitorStatus };
```

## 🔧 Environment Variables

```env
DATABASE_URL=postgresql://user:password@localhost:5432/pulsewatch
PORT=3000
```

## 📄 License

MIT

## 🤝 Support

For issues and questions, visit [GitHub Issues](https://github.com/yourusername/pulsewatch/issues).

---

**Made with ❤️ by Abishek**

